Implement parent selector

This commit is contained in:
James Foster
2011-05-20 07:55:02 +08:00
committed by Alexis Sellier
parent 4255610958
commit afd599dcb5
5 changed files with 101 additions and 7 deletions

View File

@@ -790,6 +790,10 @@ less.Parser = function Parser(env) {
e = $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) || $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
if (e) { return new(tree.Element)(c, e) }
if (c.value && c.value[0] === '&') {
return new(tree.Element)(c, null);
}
},
//
@@ -804,10 +808,18 @@ less.Parser = function Parser(env) {
combinator: function () {
var match, c = input.charAt(i);
if (c === '>' || c === '&' || c === '+' || c === '~') {
if (c === '>' || c === '+' || c === '~') {
i++;
while (input.charAt(i) === ' ') { i++ }
return new(tree.Combinator)(c);
} else if (c === '&') {
match = '&';
i++;
if(input.charAt(i) === ' ') {
match = '& ';
}
while (input.charAt(i) === ' ') { i++ }
return new(tree.Combinator)(match);
} else if (c === ':' && input.charAt(i + 1) === ':') {
i += 2;
while (input.charAt(i) === ' ') { i++ }

View File

@@ -3,7 +3,7 @@
tree.Element = function (combinator, value) {
this.combinator = combinator instanceof tree.Combinator ?
combinator : new(tree.Combinator)(combinator);
this.value = value.trim();
this.value = value ? value.trim() : "";
};
tree.Element.prototype.toCSS = function (env) {
return this.combinator.toCSS(env || {}) + this.value;
@@ -12,6 +12,8 @@ tree.Element.prototype.toCSS = function (env) {
tree.Combinator = function (value) {
if (value === ' ') {
this.value = ' ';
} else if (value === '& ') {
this.value = '& ';
} else {
this.value = value ? value.trim() : "";
}
@@ -21,6 +23,7 @@ tree.Combinator.prototype.toCSS = function (env) {
'' : '',
' ' : ' ',
'&' : '',
'& ' : ' ',
':' : ' :',
'::': '::',
'+' : env.compress ? '+' : ' + ',

View File

@@ -120,11 +120,7 @@ tree.Ruleset.prototype = {
if (context.length === 0) {
paths = this.selectors.map(function (s) { return [s] });
} else {
for (var s = 0; s < this.selectors.length; s++) {
for (var c = 0; c < context.length; c++) {
paths.push(context[c].concat([this.selectors[s]]));
}
}
this.joinSelectors( paths, context, this.selectors );
}
}
@@ -174,6 +170,44 @@ tree.Ruleset.prototype = {
css.push(rulesets);
return css.join('') + (env.compress ? '\n' : '');
},
joinSelectors: function( paths, context, selectors ) {
for (var s = 0; s < selectors.length; s++) {
this.joinSelector(paths, context, selectors[s]);
}
},
joinSelector: function( paths, context, selector ) {
var before = [], after = [], beforeElements = [], afterElements = [], hasParentSelector = false, el;
for (var i = 0; i < selector.elements.length; i++) {
el = selector.elements[i];
if (el.combinator.value[0] === '&') {
hasParentSelector = true;
}
if(!hasParentSelector) {
beforeElements.push(el);
} else {
afterElements.push(el);
}
}
if(!hasParentSelector) {
afterElements = beforeElements;
beforeElements = [];
}
if(beforeElements.length > 0) {
before.push(new (tree.Selector)(beforeElements));
}
if(afterElements.length > 0) {
after.push(new (tree.Selector)(afterElements));
}
for (var c = 0; c < context.length; c++) {
paths.push(before.concat(context[c]).concat(after));
}
}
};
})(require('less/tree'));

View File

@@ -30,3 +30,24 @@ td {
td, input {
line-height: 1em;
}
a {
color: red;
}
a:hover {
color: blue;
}
div a {
color: green;
}
p a span {
color: yellow;
}
.foo .bar .qux, .foo .baz .qux {
display: block;
}
.qux .foo .bar, .qux .foo .baz {
display: inline;
}
.qux .foo .bar .biz, .qux .foo .baz .biz {
display: none;
}

View File

@@ -22,3 +22,27 @@ td {
td, input {
line-height: 1em;
}
a {
color: red;
&:hover { color: blue; }
div & { color: green; }
p & span { color: yellow; }
}
.foo {
.bar, .baz {
& .qux {
display: block;
}
.qux & {
display: inline;
}
.qux & .biz {
display: none;
}
}
}