8000 change extends to work after selector joining. refactor findMatch rea… · nullstring/less.js@59fb6cd · GitHub
[go: up one dir, main page]

Skip to content

Commit 59fb6cd

Browse files
committed
change extends to work after selector joining. refactor findMatch ready for change to support properties across nesting
1 parent bf74d88 commit 59fb6cd

File tree

5 files changed

+66
-42
lines changed

5 files changed

+66
-42
lines changed

lib/less/extend-visitor.js

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,15 @@
3434

3535
// now find every selector and apply the extends that apply to all extends
3636
// and the ones which apply to an individual extend
37-
for(i = 0; i < rulesetNode.selectors.length; i++) {
38-
var selector = rulesetNode.selectors[i];
39-
extendList = selector.extendList.slice(0).concat(allSelectorsExtendList.map(function(allSelectorsExtend) {
37+
for(i = 0; i < rulesetNode.paths.length; i++) {
38+
var selectorPath = rulesetNode.paths[i],
39+
selector = selectorPath[selectorPath.length-1];
40+
extendList = selector.extendList.slice(0).concat(allSelectorsExtendList).map(function(allSelectorsExtend) {
4041
return allSelectorsExtend.clone();
41-
}));
42+
});
4243
for(j = 0; j < extendList.length; j++) {
4344
extend = extendList[j];
44-
extend.findSelfSelectors([[selector]].concat(this.contexts.slice(0)));
45+
extend.findSelfSelectors(selectorPath);
4546
this.allExtendsStack[this.allExtendsStack.length-1].push(extend);
4647
}
4748
}
@@ -97,41 +98,53 @@
9798
var i, j, k, selector, element, allExtends = this.allExtendsStack[this.allExtendsStack.length-1], selectorsToAdd = [];
9899

99100
for(k = 0; k < allExtends.length; k++) {
100-
for(i = 0; i < rulesetNode.selectors.length; i++) {
101-
selector = rulesetNode.selectors[i];
102-
var match = this.findMatch(allExtends[k], selector);
101+
for(i = 0; i < rulesetNode.paths.length; i++) {
102+
selectorPath = rulesetNode.paths[i];
103+
var match = this.findMatch(allExtends[k], selectorPath);
103104
if (match) {
105+
selector = selectorPath[match.pathIndex];
104106
allExtends[k].selfSelectors.forEach(function(selfSelector) {
105-
var firstElement = new tree.Element(
107+
var path = selectorPath.slice(0, match.pathIndex),
108+
firstElement = new tree.Element(
106109
match.initialCombinator,
107110
selfSelector.elements[0].value,
108111
selfSelector.elements[0].index
109112
);
110-
selectorsToAdd.push(new tree.Selector(
113+
path.push(new tree.Selector(
111114
selector.elements
112115
.slice(0, match.index)
113116
.concat([firstElement])
114117
.concat(selfSelector.elements.slice(1))
115118
.concat(selector.elements.slice(match.index + match.length))
116119
));
120+
path = path.concat(selectorPath.slice(match.pathIndex + 1, selectorPath.length));
121+
selectorsToAdd.push(path);
117122
});
118123
}
119124
}
120125
}
121-
rulesetNode.selectors = rulesetNode.selectors.concat(selectorsToAdd);
122-
},
123-
findMatch: function (extend, selector) {
124-
var i, j, element, hasMatch;
125-
for(i = 0; i <= (selector.elements.length - extend.selector.elements.length); i++) {
126-
hasMatch = true;
127-
for(j = 0; j < extend.selector.elements.length; j++) {
128-
if (extend.selector.elements[j].value !== selector.elements[i+j].value) {
129-
hasMatch = false;
130-
break;
126+
rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd);
127+
},
128+
findMatch: function (extend, selectorPath) {
129+
var i, j, k, element, hasMatch, potentialMatches = [], potentialMatch;
130+
for(k = 0; k < selectorPath.length; k++) {
131+
selector = selectorPath[k];
132+
for(i = 0; i < selector.elements.length; i++) {
133+
hasMatch = true;
134+
potentialMatch = {pathIndex: k, index: i};
135+
for(j = 0; j < extend.selector.elements.length && i+j < selector.elements.length; j++) {
136+
potentialMatch.matched = j;
137+
if (extend.selector.elements[j].value !== selector.elements[i+j].value ||
138+
(j > 0 && extend.selector.elements[j].combinator.value !== selector.elements[i+j].combinator.value)) {
139+
potentialMatch = null;
140+
break;
141+
}
142+
}
143+
if (potentialMatch && potentialMatch.matched+1 === extend.selector.elements.length) {
144+
potentialMatch.initialCombinator = selector.elements[i].combinator;
145+
potentialMatch.length = extend.selector.elements.length;
146+
return potentialMatch;
131147
}
132-
}
133-
if (hasMatch) {
134-
return {index: i, initialCombinator: selector.elements[i].combinator, length: extend.selector.elements.length};
135148
}
136149
}
137150
return null;

lib/less/parser.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,10 +406,10 @@ less.Parser = function Parser(env) {
406406
try {
407407
var evaldRoot = evaluate.call(this, evalEnv);
408408

409-
new(tree.processExtendsVisitor)()
409+
new(tree.joinSelectorVisitor)()
410410
.run(evaldRoot);
411411

412-
new(tree.joinSelectorVisitor)()
412+
new(tree.processExtendsVisitor)()
413413
.run(evaldRoot);
414414

415415
var css = evaldRoot.toCSS({

lib/less/tree/extend.js

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,13 @@ tree.Extend.prototype = {
1818
return new(tree.Extend)(this.selector, this.option, this.index);
1919
},
2020
findSelfSelectors: function (selectors) {
21-
var selfSelectors = [];
21+
var selfElements = [];
2222

23-
// multiplies out the selectors, e.g.
24-
// [[.a],[.b,.c]] => [.a.b,.a.c]
25-
(function loop(elem, i) {
26-
if (selectors[i] && selectors[i].length) {
27-
selectors[i].forEach(function(s) {
28-
loop(s.elements.concat(elem), i + 1);
29-
});
30-
}
31-
else {
32-
selfSelectors.push({ elements: elem });
33-
}
34-
})([], 0);
23+
for(i = 0; i < selectors.length; i++) {
24+
selfElements = selfElements.concat(selectors[i].elements);
25+
}
3526

36-
this.selfSelectors = selfSelectors;
27+
this.selfSelectors = [{ elements: selfElements }];
3728
}
3829
};
3930

test/css/extend.css

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,17 @@ div.ext7,
3535
}
3636
.ext8.ext9,
3737
.foo {
38-
result: pick-up-both;
38+
result: add-foo;
39+
}
40+
.ext8 .ext9,
41+
.ext8 + .ext9,
42+
.ext8 > .ext9,
43+
.bar {
44+
result: bar-matched;
3945
}
4046
.ext8.nomatch {
4147
result: none;
4248
}
49+
.ext8 .ext9 {
50+
result: match-nested;
51+
}

test/less/extend.less

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,21 @@ div.ext5,
3838
}
3939

4040
.ext8.ext9 {
41-
result: pick-up-both;
41+
result: add-foo;
42+
}
43+
.ext8 .ext9,
44+
.ext8 + .ext9,
45+
.ext8 > .ext9 {
46+
result: bar-matched;
4247
}
4348
.ext8.nomatch {
4449
result: none;
4550
}
51+
.ext8 {
52+
.ext9 {
53+
result: match-nested;
54+
}
55+
}
4656

47-
.foo:extend(.ext8.ext9 all) {}
57+
.foo:extend(.ext8.ext9 all) {}
58+
.bar:extend(.ext8 .ext9 all) {}

0 commit comments

Comments
 (0)
0