[Pkg-javascript-commits] [less.js] 01/14: Working but extremly ugly version. Desperately needs clean up.

Jonas Smedegaard dr at jones.dk
Mon Oct 26 23:29:15 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 b5711dbb1364e7d70e83fd8078036cebb5641bb3
Author: jurcovicovam <meri at meri.org>
Date:   Sun Jan 18 11:47:23 2015 +0100

    Working but extremly ugly version. Desperately needs clean up.
---
 lib/less/parser/parser.js |   4 +-
 lib/less/tree/ruleset.js  | 350 +++++++++++++++++++++++++++-------------------
 test/less/selectors.less  |  14 +-
 3 files changed, 219 insertions(+), 149 deletions(-)

diff --git a/lib/less/parser/parser.js b/lib/less/parser/parser.js
index f1cf119..61a1d4f 100644
--- a/lib/less/parser/parser.js
+++ b/lib/less/parser/parser.js
@@ -858,9 +858,11 @@ var Parser = function Parser(context, imports, fileInfo) {
                 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(/^[\.#](?=@)/) ||
+                    parserInput.$char('*') || parserInput.$char('&') || this.attribute() || parserInput.$re(/^\([^&()@]+\)/) ||  parserInput.$re(/^[\.#](?=@)/) ||
+                    //parserInput.$char('*') || parserInput.$char('&') || this.attribute() || parserInput.$re(/^\([^()@]+\)/) || parserInput.$re(/^[\.#](?=@)/) ||
                     this.entities.variableCurly();
 
+
                 if (! e) {
                     parserInput.save();
                     if (parserInput.$char('(')) {
diff --git a/lib/less/tree/ruleset.js b/lib/less/tree/ruleset.js
index aa86214..b087723 100644
--- a/lib/less/tree/ruleset.js
+++ b/lib/less/tree/ruleset.js
@@ -2,6 +2,7 @@ var Node = require("./node"),
     Rule = require("./rule"),
     Selector = require("./selector"),
     Element = require("./element"),
+    Paren = require("./paren"),
     contexts = require("../contexts"),
     defaultFunc = require("../functions/default"),
     getDebugInfo = require("./debug-info");
@@ -426,162 +427,229 @@ Ruleset.prototype.joinSelectors = function (paths, context, selectors) {
         this.joinSelector(paths, context, selectors[s]);
     }
 };
-Ruleset.prototype.joinSelector = function (paths, context, selector) {
+function replaceNextPartMeri(attachToPrefix, replacement, appender, originalSelector) {
+    var newSelectorPath, afterParentJoin, lastSelector, newJoinedSelectorEmpty, newJoinedSelector;
+    // 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
+  if (attachToPrefix.length > 0) {
+    newSelectorPath = attachToPrefix.slice(0);
+    lastSelector = newSelectorPath.pop();
+    newJoinedSelector = originalSelector.createDerived(lastSelector.elements.slice(0));
+    newJoinedSelectorEmpty = false;
+  }
+  else {
+    newJoinedSelector = originalSelector.createDerived([]);
+  }
+
+  //put together the parent selectors after the join
+  if (replacement.length > 1) {
+    afterParentJoin = afterParentJoin.concat(replacement.slice(1));
+  }
+
+  if (replacement.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 = appender.combinator,
+      parentEl = replacement[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, appender.index, appender.currentFileInfo));
+    newJoinedSelector.elements = newJoinedSelector.elements.concat(replacement[0].elements.slice(1));
+  }
+
+  if (!newJoinedSelectorEmpty) {
+    // now add the joined selector
+    newSelectorPath.push(newJoinedSelector);
+  }
+
+  // and the rest of the parent
+  newSelectorPath = newSelectorPath.concat(afterParentJoin);
+  return newSelectorPath;
+}
+function replaceInnerParentSelector(paths, context, selector) {
+  var i, j, k, currentElements, newSelectors, selectorsMultiplied, parentSel, sel, el, encounteredParentSelector = false;
+  function findNestedSelector(element) {
+    var maybeSelector;
+    if (element.value.type !== 'Paren')
+      return null;
+
+    maybeSelector = element.value.value;
+    if (maybeSelector.type !== 'Selector')
+      return null;
+
+    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 < selector.elements.length; i++) {
+    el = selector.elements[i];
+    // non parent reference elements just get added
+    if (el.value !== "&") {
+      var nestedSelector = findNestedSelector(el);
+        if (nestedSelector != null) {
+          selectorsMultiplied = [];
+          // merge the current list of non parent selector elements
+          // on to the current list of selectors to add
+          this.mergeElementsOnToSelectors(currentElements, newSelectors);
+
+          var nestedPathsWtf = [], replaced;
+          replaced = replaceInnerParentSelector.call(this, nestedPathsWtf, context, nestedSelector);
+          encounteredParentSelector = encounteredParentSelector || replaced;
+          for (k = 0; k < nestedPathsWtf.length; k++) {
+
+            var replacementParen = new Paren(nestedPathsWtf[0][0]);
+            var replacementElement = new Element(null, replacementParen, el.index, el.currentFileInfo);
+            var replacementSelector = new Selector([replacementElement]);
+            var replacements = [replacementSelector];
+            //replaceNextPartMeri(attachToPrefix, replacement, appender, originalSelector)
+            for (j = 0; j < newSelectors.length; j++) {
+              sel = newSelectors[j];
+              var entirelyNewSelectorPath = replaceNextPartMeri(sel, replacements, el, selector);
+              selectorsMultiplied.push(entirelyNewSelectorPath); // this causes cucle
+            }
+            newSelectors = selectorsMultiplied;
+            currentElements = [];
+          }
 
-    var i, j, k,
-        hasParentSelector, newSelectors, el, sel, parentSel,
-        newSelectorPath, afterParentJoin, newJoinedSelector,
-        newJoinedSelectorEmpty, lastSelector, currentElements,
-        selectorsMultiplied;
+      } else {
+        currentElements.push(el);
+      }
 
-    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));
-            }
+    } else {
+      encounteredParentSelector = 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
+      this.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) {
+            sel[0].elements = sel[0].elements.slice(0);
+            sel[0].elements.push(new Element(el.combinator, '', el.index, el.currentFileInfo));
+          }
+          selectorsMultiplied.push(sel);
         }
         else {
-            paths.push([selector]);
+          // 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
+            var newSelectorPath = replaceNextPartMeri(sel, parentSel, el, selector);
+            // add that to our new set of selectors
+            selectorsMultiplied.push(newSelectorPath);
+          }
         }
-        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 = [];
-
-            // 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);
-            }
+      }
 
-            // 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));
-                    }
-                    selectorsMultiplied.push(sel);
-                }
-                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
-                        if (sel.length > 0) {
-                            newSelectorPath = sel.slice(0);
-                            lastSelector = newSelectorPath.pop();
-                            newJoinedSelector = selector.createDerived(lastSelector.elements.slice(0));
-                            newJoinedSelectorEmpty = false;
-                        }
-                        else {
-                            newJoinedSelector = selector.createDerived([]);
-                        }
-
-                        //put together the parent selectors after the join
-                        if (parentSel.length > 1) {
-                            afterParentJoin = afterParentJoin.concat(parentSel.slice(1));
-                        }
-
-                        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 (!newJoinedSelectorEmpty) {
-                            // now add the joined selector
-                            newSelectorPath.push(newJoinedSelector);
-                        }
-
-                        // and the rest of the parent
-                        newSelectorPath = newSelectorPath.concat(afterParentJoin);
+      // our new selectors has been multiplied, so reset the state
+      newSelectors = selectorsMultiplied;
+      currentElements = [];
+    }
+  }
 
-                        // add that to our new set of selectors
-                        selectorsMultiplied.push(newSelectorPath);
-                    }
-                }
-            }
+  // if we have any elements left over (e.g. .a& .b == .b)
+  // add them on to all the current selectors
+  this.mergeElementsOnToSelectors(currentElements, newSelectors);
 
-            // our new selectors has been multiplied, so reset the state
-            newSelectors = selectorsMultiplied;
-            currentElements = [];
-        }
+  for (i = 0; i < newSelectors.length; i++) {
+    if (newSelectors[i].length > 0) {
+      paths.push(newSelectors[i]);
     }
+  }
 
-    // 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);
-    }
+  return encounteredParentSelector;
+}
+Ruleset.prototype.joinSelector = function (paths, context, selector) {
+
+  var i, hasParentSelector, el;
+
+  for (i = 0; i < selector.elements.length; i++) {
+    el = selector.elements[i];
+    if (el.value === '&') {
+      hasParentSelector = true;
+    }
+  }
+
+  if (false) {
+    if (context.length > 0) {
+      console.log('context: full');
+      for (i = 0; i < context.length; i++) {
+        paths.push(context[i].concat(selector));
+      }
+    }
+   else {
+       console.log('context: empty');
+       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]]
+  //
+  var newPaths = [];
+  var encounteredParentSelector = replaceInnerParentSelector.call(this, newPaths, context, selector);
+
+  if (true && !encounteredParentSelector) {
+    newPaths = [];
+    if (context.length > 0) {
+      console.log('context: full');
+      for (i = 0; i < context.length; i++) {
+        newPaths.push(context[i].concat(selector));
+      }
+    }
+    else {
+      console.log('context: empty');
+      newPaths.push([selector]);
+    }
+  }
+  for (i = 0; i < newPaths.length; i++) {
+    paths.push(newPaths[i]);
+  }
 
-    for (i = 0; i < newSelectors.length; i++) {
-        if (newSelectors[i].length > 0) {
-            paths.push(newSelectors[i]);
-        }
-    }
 };
 Ruleset.prototype.mergeElementsOnToSelectors = function(elements, selectors) {
     var i, sel;
 
+    if (elements.length === 0) {
+      return ;
+    }
     if (selectors.length === 0) {
         selectors.push([ new Selector(elements) ]);
         return;
diff --git a/test/less/selectors.less b/test/less/selectors.less
index 42aa29e..ccc57da 100644
--- a/test/less/selectors.less
+++ b/test/less/selectors.less
@@ -126,13 +126,13 @@ a {
     selector: interpolated;
 }
 .test {
-  &:nth-child(@{num}) {
-    selector: interpolated;
-  }
-  &:nth-child(odd):not(:nth-child(3)) {
-    color: #ff0000;
-  }
-}
+   &:nth-child(@{num}) {
+     selector: interpolated;
+   }
+   &:nth-child(odd):not(:nth-child(3)) {
+     color: #ff0000;
+   }
+ }
 [prop],
 [prop=10%],
 [prop="value@{num}"],

-- 
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