[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