[Pkg-javascript-commits] [less.js] 10/14: Merge https://github.com/less/less.js into nested-parent-selector-2026-v1

Jonas Smedegaard dr at jones.dk
Mon Oct 26 23:29:17 UTC 2015


This is an automated email from the git hooks/post-receive script.

js pushed a commit to annotated tag v2.3.1
in repository less.js.

commit dc93dd54bfb0734db950a4d9c389cc1fec4bf39f
Merge: 964b991 d206167
Author: jurcovicovam <meri at meri.org>
Date:   Wed Jan 28 10:46:49 2015 +0100

    Merge https://github.com/less/less.js into nested-parent-selector-2026-v1
    
    Conflicts:
    	lib/less/parser/parser.js
    	lib/less/tree/ruleset.js

 .gitignore                                       |   1 +
 .jscsrc                                          |  38 ++
 .jshintrc                                        |   2 -
 CHANGELOG.md                                     |  18 +
 Gruntfile.js                                     |  54 +-
 bin/lessc                                        | 688 ++++++++++++-----------
 bower.json                                       |   2 +-
 dist/less.js                                     | 378 ++++++++-----
 dist/less.min.js                                 |  12 +-
 lib/less-browser/add-default-options.js          |   6 +-
 lib/less-browser/bootstrap.js                    |  18 +-
 lib/less-browser/index.js                        |  28 +-
 lib/less-browser/utils.js                        |  10 +-
 lib/less-node/file-manager.js                    |  18 +-
 lib/less-node/image-size.js                      |  48 +-
 lib/less-node/lessc-helper.js                    |   6 +-
 lib/less-node/url-file-manager.js                |   4 +-
 lib/less-rhino/index.js                          |   6 +-
 lib/less/contexts.js                             |   1 -
 lib/less/data/unit-conversions.js                |   6 +-
 lib/less/environment/abstract-file-manager.js    |   8 +-
 lib/less/functions/color-blending.js             |   6 +-
 lib/less/functions/color.js                      |  14 +-
 lib/less/functions/data-uri.js                   |  36 +-
 lib/less/functions/string.js                     |   4 +-
 lib/less/functions/svg.js                        |   9 +-
 lib/less/functions/types.js                      |   8 +-
 lib/less/import-manager.js                       |  15 +-
 lib/less/index.js                                |   2 +-
 lib/less/parse-tree.js                           |  12 +-
 lib/less/parse.js                                |   4 +
 lib/less/parser/parser.js                        |  42 +-
 lib/less/source-map-output.js                    |   6 +-
 lib/less/transform-tree.js                       |   2 +-
 lib/less/tree/assignment.js                      |   1 -
 lib/less/tree/condition.js                       |   2 +-
 lib/less/tree/debug-info.js                      |   8 +-
 lib/less/tree/dimension.js                       |   2 +-
 lib/less/tree/directive.js                       |  32 +-
 lib/less/tree/import.js                          |   2 +-
 lib/less/tree/index.js                           |   1 +
 lib/less/tree/media.js                           |   5 +-
 lib/less/tree/mixin-call.js                      |   7 +-
 lib/less/tree/mixin-definition.js                |   7 +-
 lib/less/tree/quoted.js                          |   2 +-
 lib/less/tree/rule.js                            |   5 +-
 lib/less/tree/ruleset.js                         |  77 ++-
 lib/less/tree/selector.js                        |   3 +-
 lib/less/tree/url.js                             |   2 +-
 lib/less/tree/value.js                           |   2 +-
 lib/less/tree/variable.js                        |   2 +-
 lib/less/visitors/extend-visitor.js              |  52 +-
 lib/less/visitors/import-sequencer.js            |  44 +-
 lib/less/visitors/import-visitor.js              |  23 +-
 lib/less/visitors/to-css-visitor.js              |  42 +-
 package.json                                     |  10 +-
 test/browser/common.js                           |   8 +-
 test/browser/jasmine-jsreporter.js               |   5 +-
 test/browser/runner-errors-options.js            |   1 -
 test/browser/runner-errors-spec.js               |   1 -
 test/browser/runner-legacy-options.js            |   1 -
 test/browser/runner-no-js-errors-spec.js         |   1 -
 test/browser/runner-production-options.js        |   1 -
 test/browser/runner-relative-urls-options.js     |   1 -
 test/browser/runner-rootpath-options.js          |   1 -
 test/browser/runner-rootpath-relative-options.js |   1 -
 test/browser/runner-strict-units-options.js      |   1 -
 test/copy-bom.js                                 |  72 +++
 test/css/comments.css                            |   1 +
 test/css/functions.css                           |   1 +
 test/css/import-reference.css                    |  25 +
 test/css/mixins-important.css                    |   6 +
 test/css/selectors.css                           |   2 +-
 test/css/urls.css                                |   1 +
 test/index.js                                    |  22 +-
 test/less-test.js                                | 129 +++--
 test/less/comments.less                          |   1 +
 test/less/functions.less                         |   4 +
 test/less/import-reference.less                  |   4 +-
 test/less/import.less                            |   2 +
 test/less/import/import-reference.less           |  38 ++
 test/less/mixins-important.less                  |  12 +
 test/less/selectors.less                         |   2 +-
 test/less/urls.less                              |   3 +
 test/modify-vars.js                              |  10 +-
 85 files changed, 1370 insertions(+), 830 deletions(-)

diff --cc lib/less/parser/parser.js
index 6863979,daa3b71..4617412
--- a/lib/less/parser/parser.js
+++ b/lib/less/parser/parser.js
@@@ -857,11 -864,11 +864,12 @@@ var Parser = function Parser(context, i
  
                  c = this.combinator();
  
-                 e = parserInput.$re(/^(?:\d+\.\d+|\d+)%/) || parserInput.$re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) ||
-                     parserInput.$char('*') || parserInput.$char('&') || this.attribute() || parserInput.$re(/^\([^&()@]+\)/) ||  parserInput.$re(/^[\.#](?=@)/) ||
+                 e = parserInput.$re(/^(?:\d+\.\d+|\d+)%/) ||
+                     parserInput.$re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) ||
+                     parserInput.$char('*') || parserInput.$char('&') || this.attribute() ||
 -                    parserInput.$re(/^\([^()@]+\)/) || parserInput.$re(/^[\.#:](?=@)/) || this.entities.variableCurly();
++                    parserInput.$re(/^\([^&()@]+\)/) ||  parserInput.$re(/^[\.#:](?=@)/) ||
 +                    this.entities.variableCurly();
  
- 
                  if (! e) {
                      parserInput.save();
                      if (parserInput.$char('(')) {
diff --cc lib/less/tree/ruleset.js
index 49b3d78,2c1bb8a..f1bfc4a
--- a/lib/less/tree/ruleset.js
+++ b/lib/less/tree/ruleset.js
@@@ -430,243 -462,175 +463,245 @@@ Ruleset.prototype.joinSelectors = funct
  
  Ruleset.prototype.joinSelector = function (paths, context, selector) {
  
 -    var i, j, k,
 -        hasParentSelector, newSelectors, el, sel, parentSel,
 -        newSelectorPath, afterParentJoin, newJoinedSelector,
 -        newJoinedSelectorEmpty, lastSelector, currentElements,
 -        selectorsMultiplied;
 -
 -    for (i = 0; i < selector.elements.length; i++) {
 -        el = selector.elements[i];
 -        if (el.value === '&') {
 -            hasParentSelector = true;
 -        }
 -    }
 -
 -    if (!hasParentSelector) {
 -        if (context.length > 0) {
 -            for (i = 0; i < context.length; i++) {
 -                paths.push(context[i].concat(selector));
 +    function createParenthesis(elementsToPak, originalElement) {
 +        var replacementParen, j;
 +        if (elementsToPak.length === 0) {
 +            replacementParen = new Paren(elementsToPak[0]);
 +        } else {
 +            var insideParent = [];
 +            for (j = 0; j < elementsToPak.length; j++) {
 +                insideParent.push(new Element(null, elementsToPak[j], originalElement.index, originalElement.currentFileInfo));
              }
 +            replacementParen = new Paren(new Selector(insideParent));
          }
 -        else {
 -            paths.push([selector]);
 -        }
 -        return;
 -    }
 -
 -    // The paths are [[Selector]]
 -    // The first list is a list of comma separated selectors
 -    // The inner list is a list of inheritance separated selectors
 -    // e.g.
 -    // .a, .b {
 -    //   .c {
 -    //   }
 -    // }
 -    // == [[.a] [.c]] [[.b] [.c]]
 -    //
 -
 -    // the elements from the current selector so far
 -    currentElements = [];
 -    // the current list of new selectors to add to the path.
 -    // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors
 -    // by the parents
 -    newSelectors = [[]];
 -
 -    for (i = 0; i < selector.elements.length; i++) {
 -        el = selector.elements[i];
 -        // non parent reference elements just get added
 -        if (el.value !== "&") {
 -            currentElements.push(el);
 -        } else {
 -            // the new list of selectors to add
 -            selectorsMultiplied = [];
 +        return replacementParen;
 +    }
 +
 +    function createSelector(containedElement, originalElement) {
 +        var element, selector;
 +        element = new Element(null, containedElement, originalElement.index, originalElement.currentFileInfo);
 +        selector = new Selector([element]);
 +        return selector;
 +    }
 +
 +    // replace all parent selectors inside `inSelector` by content of `context` array
 +    // resulting selectors are returned inside `paths` array
 +    // returns true if `inSelector` contained at least one parent selector
 +    function replaceParentSelector(paths, context, inSelector) {
 +        // The paths are [[Selector]]
 +        // The first list is a list of comma separated selectors
 +        // The inner list is a list of inheritance separated selectors
 +        // e.g.
 +        // .a, .b {
 +        //   .c {
 +        //   }
 +        // }
 +        // == [[.a] [.c]] [[.b] [.c]]
 +        //
 +        var i, j, k, currentElements, newSelectors, selectorsMultiplied, sel, el, hadParentSelector = false;
 +        function findNestedSelector(element) {
 +            var maybeSelector;
-             if (element.value.type !== 'Paren')
++            if (element.value.type !== 'Paren') {
 +                return null;
++            }
  
 -            // merge the current list of non parent selector elements
 -            // on to the current list of selectors to add
 -            if (currentElements.length > 0) {
 -                this.mergeElementsOnToSelectors(currentElements, newSelectors);
 +            maybeSelector = element.value.value;
-             if (maybeSelector.type !== 'Selector')
++            if (maybeSelector.type !== 'Selector') {
 +                return null;
+             }
  
 -            // loop through our current selectors
 -            for (j = 0; j < newSelectors.length; j++) {
 -                sel = newSelectors[j];
 -                // if we don't have any parent paths, the & might be in a mixin so that it can be used
 -                // whether there are parents or not
 -                if (context.length === 0) {
 -                    // the combinator used on el should now be applied to the next element instead so that
 -                    // it is not lost
 -                    if (sel.length > 0) {
 -                        sel[0].elements = sel[0].elements.slice(0);
 -                        sel[0].elements.push(new Element(el.combinator, '', el.index, el.currentFileInfo));
 +            return maybeSelector;
 +        }
 +
 +        // the elements from the current selector so far
 +        currentElements = [];
 +        // the current list of new selectors to add to the path.
 +        // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors
 +        // by the parents
 +        newSelectors = [
 +            []
 +        ];
 +
 +        for (i = 0; i < inSelector.elements.length; i++) {
 +            el = inSelector.elements[i];
 +            // non parent reference elements just get added
 +            if (el.value !== "&") {
 +                var nestedSelector = findNestedSelector(el);
 +                if (nestedSelector != null) {
 +                    // merge the current list of non parent selector elements
 +                    // on to the current list of selectors to add
 +                    mergeElementsOnToSelectors(currentElements, newSelectors);
 +
 +                    var nestedPaths = [], replaced, replacedNewSelectors = [];
 +                    replaced = replaceParentSelector(nestedPaths, context, nestedSelector);
 +                    hadParentSelector = hadParentSelector || replaced;
 +                    //the nestedPaths array should have only one member - replaceParentSelector does not multiply selectors
 +                    for (k = 0; k < nestedPaths.length; k++) {
 +                        var replacementSelector = createSelector(createParenthesis(nestedPaths[k], el), el);
 +                        addAllReplacementsIntoPath(newSelectors, [replacementSelector], el, inSelector, replacedNewSelectors);
                      }
 -                    selectorsMultiplied.push(sel);
 +                    newSelectors = replacedNewSelectors;
 +                    currentElements = [];
 +
 +                } else {
 +                    currentElements.push(el);
                  }
 -                else {
 -                    // and the parent selectors
 -                    for (k = 0; k < context.length; k++) {
 -                        parentSel = context[k];
 -                        // We need to put the current selectors
 -                        // then join the last selector's elements on to the parents selectors
 -
 -                        // our new selector path
 -                        newSelectorPath = [];
 -                        // selectors from the parent after the join
 -                        afterParentJoin = [];
 -                        newJoinedSelectorEmpty = true;
 -
 -                        //construct the joined selector - if & is the first thing this will be empty,
 -                        // if not newJoinedSelector will be the last set of elements in the selector
 +
 +            } else {
 +                hadParentSelector = true;
 +                // the new list of selectors to add
 +                selectorsMultiplied = [];
 +
 +                // merge the current list of non parent selector elements
 +                // on to the current list of selectors to add
 +                mergeElementsOnToSelectors(currentElements, newSelectors);
 +
 +                // loop through our current selectors
 +                for (j = 0; j < newSelectors.length; j++) {
 +                    sel = newSelectors[j];
 +                    // if we don't have any parent paths, the & might be in a mixin so that it can be used
 +                    // whether there are parents or not
 +                    if (context.length === 0) {
 +                        // the combinator used on el should now be applied to the next element instead so that
 +                        // it is not lost
                          if (sel.length > 0) {
 -                            newSelectorPath = sel.slice(0);
 -                            lastSelector = newSelectorPath.pop();
 -                            newJoinedSelector = selector.createDerived(lastSelector.elements.slice(0));
 -                            newJoinedSelectorEmpty = false;
 +                            sel[0].elements.push(new Element(el.combinator, '', el.index, el.currentFileInfo));
                          }
 -                        else {
 -                            newJoinedSelector = selector.createDerived([]);
 +                        selectorsMultiplied.push(sel);
 +                    }
 +                    else {
 +                        // and the parent selectors
 +                        for (k = 0; k < context.length; k++) {
 +                            // We need to put the current selectors
 +                            // then join the last selector's elements on to the parents selectors
 +                            var newSelectorPath = addReplacementIntoPath(sel, context[k], el, inSelector);
 +                            // add that to our new set of selectors
 +                            selectorsMultiplied.push(newSelectorPath);
                          }
 +                    }
 +                }
  
 -                        //put together the parent selectors after the join
 -                        if (parentSel.length > 1) {
 -                            afterParentJoin = afterParentJoin.concat(parentSel.slice(1));
 -                        }
 +                // our new selectors has been multiplied, so reset the state
 +                newSelectors = selectorsMultiplied;
 +                currentElements = [];
 +            }
 +        }
  
 -                        if (parentSel.length > 0) {
 -                            newJoinedSelectorEmpty = false;
 -
 -                            // /deep/ is a combinator that is valid without anything in front of it
 -                            // so if the & does not have a combinator that is "" or " " then
 -                            // and there is a combinator on the parent, then grab that.
 -                            // this also allows + a { & .b { .a & { ... though not sure why you would want to do that
 -                            var combinator = el.combinator,
 -                                parentEl = parentSel[0].elements[0];
 -                            if (combinator.emptyOrWhitespace && !parentEl.combinator.emptyOrWhitespace) {
 -                                combinator = parentEl.combinator;
 -                            }
 -                            // join the elements so far with the first part of the parent
 -                            newJoinedSelector.elements.push(new Element(combinator, parentEl.value, el.index, el.currentFileInfo));
 -                            newJoinedSelector.elements = newJoinedSelector.elements.concat(parentSel[0].elements.slice(1));
 -                        }
 +        // if we have any elements left over (e.g. .a& .b == .b)
 +        // add them on to all the current selectors
 +        mergeElementsOnToSelectors(currentElements, newSelectors);
  
 -                        if (!newJoinedSelectorEmpty) {
 -                            // now add the joined selector
 -                            newSelectorPath.push(newJoinedSelector);
 -                        }
 +        for (i = 0; i < newSelectors.length; i++) {
 +            if (newSelectors[i].length > 0) {
 +                paths.push(newSelectors[i]);
 +            }
 +        }
 +
 +        return hadParentSelector;
 +    }
  
 -                        // and the rest of the parent
 -                        newSelectorPath = newSelectorPath.concat(afterParentJoin);
 +    // joins selector path from `beginningPath` with selector path in `addPath`
 +    // `replacedElement` contains element that is being replaced by `addPath`
 +    // returns concatenated path
 +    function addReplacementIntoPath(beginningPath, addPath, replacedElement, originalSelector) {
 +        var newSelectorPath, lastSelector, newJoinedSelector;
 +        // our new selector path
 +        newSelectorPath = [];
  
 -                        // add that to our new set of selectors
 -                        selectorsMultiplied.push(newSelectorPath);
 -                    }
 -                }
 +        //construct the joined selector - if & is the first thing this will be empty,
 +        // if not newJoinedSelector will be the last set of elements in the selector
 +        if (beginningPath.length > 0) {
 +            newSelectorPath = beginningPath.slice(0);
 +            lastSelector = newSelectorPath.pop();
 +            newJoinedSelector = originalSelector.createDerived(lastSelector.elements.slice(0));
 +        }
 +        else {
 +            newJoinedSelector = originalSelector.createDerived([]);
 +        }
 +
 +        if (addPath.length > 0) {
 +            // /deep/ is a combinator that is valid without anything in front of it
 +            // so if the & does not have a combinator that is "" or " " then
 +            // and there is a combinator on the parent, then grab that.
 +            // this also allows + a { & .b { .a & { ... though not sure why you would want to do that
 +            var combinator = replacedElement.combinator, parentEl = addPath[0].elements[0];
 +            if (combinator.emptyOrWhitespace && !parentEl.combinator.emptyOrWhitespace) {
 +                combinator = parentEl.combinator;
              }
 +            // join the elements so far with the first part of the parent
 +            newJoinedSelector.elements.push(new Element(combinator, parentEl.value, replacedElement.index, replacedElement.currentFileInfo));
 +            newJoinedSelector.elements = newJoinedSelector.elements.concat(addPath[0].elements.slice(1));
 +        }
  
 -            // our new selectors has been multiplied, so reset the state
 -            newSelectors = selectorsMultiplied;
 -            currentElements = [];
 +        // now add the joined selector - but only if it is not empty
 +        if (newJoinedSelector.elements.length !== 0) {
 +            newSelectorPath.push(newJoinedSelector);
          }
 -    }
  
 -    // if we have any elements left over (e.g. .a& .b == .b)
 -    // add them on to all the current selectors
 -    if (currentElements.length > 0) {
 -        this.mergeElementsOnToSelectors(currentElements, newSelectors);
 +        //put together the parent selectors after the join (e.g. the rest of the parent)
 +        if (addPath.length > 1) {
 +            newSelectorPath = newSelectorPath.concat(addPath.slice(1));
 +        }
 +        return newSelectorPath;
      }
  
 -    for (i = 0; i < newSelectors.length; i++) {
 -        if (newSelectors[i].length > 0) {
 -            paths.push(newSelectors[i]);
 +    // joins selector path from `beginningPath` with every selector path in `addPaths` array
 +    // `replacedElement` contains element that is being replaced by `addPath`
 +    // returns array with all concatenated paths
 +    function addAllReplacementsIntoPath( beginningPath, addPaths, replacedElement, originalSelector, result) {
 +        var j;
 +        for (j = 0; j < beginningPath.length; j++) {
 +            var newSelectorPath = addReplacementIntoPath(beginningPath[j], addPaths, replacedElement, originalSelector);
 +            result.push(newSelectorPath);
          }
 +        return result;
      }
 -};
 -Ruleset.prototype.mergeElementsOnToSelectors = function(elements, selectors) {
 -    var i, sel;
  
 -    if (selectors.length === 0) {
 -        selectors.push([ new Selector(elements) ]);
 -        return;
 +    function mergeElementsOnToSelectors(elements, selectors) {
 +        var i, sel;
 +
 +        if (elements.length === 0) {
 +            return ;
 +        }
 +        if (selectors.length === 0) {
 +            selectors.push([ new Selector(elements) ]);
 +            return;
 +        }
 +
 +        for (i = 0; i < selectors.length; i++) {
 +            sel = selectors[i];
 +
 +            // if the previous thing in sel is a parent this needs to join on to it
 +            if (sel.length > 0) {
 +                sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements));
 +            }
 +            else {
 +                sel.push(new Selector(elements));
 +            }
 +        }
      }
  
 -    for (i = 0; i < selectors.length; i++) {
 -        sel = selectors[i];
 +    // joinSelector code follows
 +    var i, newPaths, hadParentSelector;
 +
 +    newPaths = [];
 +    hadParentSelector = replaceParentSelector(newPaths, context, selector);
  
 -        // if the previous thing in sel is a parent this needs to join on to it
 -        if (sel.length > 0) {
 -            sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements));
 +    if (!hadParentSelector) {
 +        if (context.length > 0) {
 +            newPaths = [];
 +            for (i = 0; i < context.length; i++) {
 +                newPaths.push(context[i].concat(selector));
 +            }
          }
          else {
 -            sel.push(new Selector(elements));
 +            newPaths = [[selector]];
          }
      }
 +
 +    for (i = 0; i < newPaths.length; i++) {
 +        paths.push(newPaths[i]);
 +    }
 +
  };
- module.exports = Ruleset;
+ module.exports = Ruleset;

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/less.js.git



More information about the Pkg-javascript-commits mailing list