mirror of
https://github.com/less/less.js.git
synced 2026-05-01 03:00:22 -04:00
change extends to work after selector joining. refactor findMatch ready for change to support properties across nesting
This commit is contained in:
@@ -34,14 +34,15 @@
|
||||
|
||||
// now find every selector and apply the extends that apply to all extends
|
||||
// and the ones which apply to an individual extend
|
||||
for(i = 0; i < rulesetNode.selectors.length; i++) {
|
||||
var selector = rulesetNode.selectors[i];
|
||||
extendList = selector.extendList.slice(0).concat(allSelectorsExtendList.map(function(allSelectorsExtend) {
|
||||
for(i = 0; i < rulesetNode.paths.length; i++) {
|
||||
var selectorPath = rulesetNode.paths[i],
|
||||
selector = selectorPath[selectorPath.length-1];
|
||||
extendList = selector.extendList.slice(0).concat(allSelectorsExtendList).map(function(allSelectorsExtend) {
|
||||
return allSelectorsExtend.clone();
|
||||
}));
|
||||
});
|
||||
for(j = 0; j < extendList.length; j++) {
|
||||
extend = extendList[j];
|
||||
extend.findSelfSelectors([[selector]].concat(this.contexts.slice(0)));
|
||||
extend.findSelfSelectors(selectorPath);
|
||||
this.allExtendsStack[this.allExtendsStack.length-1].push(extend);
|
||||
}
|
||||
}
|
||||
@@ -97,41 +98,53 @@
|
||||
var i, j, k, selector, element, allExtends = this.allExtendsStack[this.allExtendsStack.length-1], selectorsToAdd = [];
|
||||
|
||||
for(k = 0; k < allExtends.length; k++) {
|
||||
for(i = 0; i < rulesetNode.selectors.length; i++) {
|
||||
selector = rulesetNode.selectors[i];
|
||||
var match = this.findMatch(allExtends[k], selector);
|
||||
for(i = 0; i < rulesetNode.paths.length; i++) {
|
||||
selectorPath = rulesetNode.paths[i];
|
||||
var match = this.findMatch(allExtends[k], selectorPath);
|
||||
if (match) {
|
||||
selector = selectorPath[match.pathIndex];
|
||||
allExtends[k].selfSelectors.forEach(function(selfSelector) {
|
||||
var firstElement = new tree.Element(
|
||||
var path = selectorPath.slice(0, match.pathIndex),
|
||||
firstElement = new tree.Element(
|
||||
match.initialCombinator,
|
||||
selfSelector.elements[0].value,
|
||||
selfSelector.elements[0].index
|
||||
);
|
||||
selectorsToAdd.push(new tree.Selector(
|
||||
path.push(new tree.Selector(
|
||||
selector.elements
|
||||
.slice(0, match.index)
|
||||
.concat([firstElement])
|
||||
.concat(selfSelector.elements.slice(1))
|
||||
.concat(selector.elements.slice(match.index + match.length))
|
||||
));
|
||||
path = path.concat(selectorPath.slice(match.pathIndex + 1, selectorPath.length));
|
||||
selectorsToAdd.push(path);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
rulesetNode.selectors = rulesetNode.selectors.concat(selectorsToAdd);
|
||||
rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd);
|
||||
},
|
||||
findMatch: function (extend, selector) {
|
||||
var i, j, element, hasMatch;
|
||||
for(i = 0; i <= (selector.elements.length - extend.selector.elements.length); i++) {
|
||||
hasMatch = true;
|
||||
for(j = 0; j < extend.selector.elements.length; j++) {
|
||||
if (extend.selector.elements[j].value !== selector.elements[i+j].value) {
|
||||
hasMatch = false;
|
||||
break;
|
||||
findMatch: function (extend, selectorPath) {
|
||||
var i, j, k, element, hasMatch, potentialMatches = [], potentialMatch;
|
||||
for(k = 0; k < selectorPath.length; k++) {
|
||||
selector = selectorPath[k];
|
||||
for(i = 0; i < selector.elements.length; i++) {
|
||||
hasMatch = true;
|
||||
potentialMatch = {pathIndex: k, index: i};
|
||||
for(j = 0; j < extend.selector.elements.length && i+j < selector.elements.length; j++) {
|
||||
potentialMatch.matched = j;
|
||||
if (extend.selector.elements[j].value !== selector.elements[i+j].value ||
|
||||
(j > 0 && extend.selector.elements[j].combinator.value !== selector.elements[i+j].combinator.value)) {
|
||||
potentialMatch = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (potentialMatch && potentialMatch.matched+1 === extend.selector.elements.length) {
|
||||
potentialMatch.initialCombinator = selector.elements[i].combinator;
|
||||
potentialMatch.length = extend.selector.elements.length;
|
||||
return potentialMatch;
|
||||
}
|
||||
}
|
||||
if (hasMatch) {
|
||||
return {index: i, initialCombinator: selector.elements[i].combinator, length: extend.selector.elements.length};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -406,10 +406,10 @@ less.Parser = function Parser(env) {
|
||||
try {
|
||||
var evaldRoot = evaluate.call(this, evalEnv);
|
||||
|
||||
new(tree.processExtendsVisitor)()
|
||||
new(tree.joinSelectorVisitor)()
|
||||
.run(evaldRoot);
|
||||
|
||||
new(tree.joinSelectorVisitor)()
|
||||
new(tree.processExtendsVisitor)()
|
||||
.run(evaldRoot);
|
||||
|
||||
var css = evaldRoot.toCSS({
|
||||
|
||||
@@ -18,22 +18,13 @@ tree.Extend.prototype = {
|
||||
return new(tree.Extend)(this.selector, this.option, this.index);
|
||||
},
|
||||
findSelfSelectors: function (selectors) {
|
||||
var selfSelectors = [];
|
||||
var selfElements = [];
|
||||
|
||||
// multiplies out the selectors, e.g.
|
||||
// [[.a],[.b,.c]] => [.a.b,.a.c]
|
||||
(function loop(elem, i) {
|
||||
if (selectors[i] && selectors[i].length) {
|
||||
selectors[i].forEach(function(s) {
|
||||
loop(s.elements.concat(elem), i + 1);
|
||||
});
|
||||
}
|
||||
else {
|
||||
selfSelectors.push({ elements: elem });
|
||||
}
|
||||
})([], 0);
|
||||
for(i = 0; i < selectors.length; i++) {
|
||||
selfElements = selfElements.concat(selectors[i].elements);
|
||||
}
|
||||
|
||||
this.selfSelectors = selfSelectors;
|
||||
this.selfSelectors = [{ elements: selfElements }];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -35,8 +35,17 @@ div.ext7,
|
||||
}
|
||||
.ext8.ext9,
|
||||
.foo {
|
||||
result: pick-up-both;
|
||||
result: add-foo;
|
||||
}
|
||||
.ext8 .ext9,
|
||||
.ext8 + .ext9,
|
||||
.ext8 > .ext9,
|
||||
.bar {
|
||||
result: bar-matched;
|
||||
}
|
||||
.ext8.nomatch {
|
||||
result: none;
|
||||
}
|
||||
.ext8 .ext9 {
|
||||
result: match-nested;
|
||||
}
|
||||
|
||||
@@ -38,10 +38,21 @@ div.ext5,
|
||||
}
|
||||
|
||||
.ext8.ext9 {
|
||||
result: pick-up-both;
|
||||
result: add-foo;
|
||||
}
|
||||
.ext8 .ext9,
|
||||
.ext8 + .ext9,
|
||||
.ext8 > .ext9 {
|
||||
result: bar-matched;
|
||||
}
|
||||
.ext8.nomatch {
|
||||
result: none;
|
||||
}
|
||||
.ext8 {
|
||||
.ext9 {
|
||||
result: match-nested;
|
||||
}
|
||||
}
|
||||
|
||||
.foo:extend(.ext8.ext9 all) {}
|
||||
.foo:extend(.ext8.ext9 all) {}
|
||||
.bar:extend(.ext8 .ext9 all) {}
|
||||
Reference in New Issue
Block a user