mirror of
https://github.com/less/less.js.git
synced 2026-02-06 21:15:14 -05:00
Add Sass like extend
This commit is contained in:
@@ -85,13 +85,13 @@ var less = {
|
||||
}
|
||||
};
|
||||
|
||||
['color', 'directive', 'operation', 'dimension',
|
||||
'keyword', 'variable', 'ruleset', 'element',
|
||||
'selector', 'quoted', 'expression', 'rule',
|
||||
'call', 'url', 'alpha', 'import',
|
||||
'mixin', 'comment', 'anonymous', 'value',
|
||||
'javascript', 'assignment', 'condition', 'paren',
|
||||
'media', 'ratio', 'unicode-descriptor'
|
||||
['color', 'directive', 'operation', 'dimension',
|
||||
'keyword', 'variable', 'ruleset', 'element',
|
||||
'selector', 'quoted', 'expression', 'rule',
|
||||
'call', 'url', 'alpha', 'import',
|
||||
'mixin', 'comment', 'anonymous', 'value',
|
||||
'javascript', 'assignment', 'condition', 'paren',
|
||||
'media', 'ratio', 'unicode-descriptor', 'extend'
|
||||
].forEach(function (n) {
|
||||
require('./tree/' + n);
|
||||
});
|
||||
|
||||
@@ -526,7 +526,8 @@ less.Parser = function Parser(env) {
|
||||
var node, root = [];
|
||||
|
||||
while ((node = $(this.mixin.definition) || $(this.rule) || $(this.ruleset) ||
|
||||
$(this.mixin.call) || $(this.comment) || $(this.directive))
|
||||
$(this.mixin.call) || $(this.comment) || $(this.directive) ||
|
||||
$(this.extend))
|
||||
|| $(/^[\s\n]+/) || $(/^;+/)) {
|
||||
node && root.push(node);
|
||||
}
|
||||
@@ -803,6 +804,23 @@ less.Parser = function Parser(env) {
|
||||
if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
|
||||
return new(tree.Shorthand)(a, b);
|
||||
}
|
||||
},
|
||||
|
||||
//
|
||||
// extend
|
||||
//
|
||||
extend: function() {
|
||||
var elements = [], e, c, args, index = i, s = input.charAt(i);
|
||||
|
||||
if (s !== '+') { return }
|
||||
|
||||
while (e = $(/^\+[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
|
||||
elements.push(new(tree.Element)(c, e.slice(1), i));
|
||||
}
|
||||
|
||||
if (elements.length > 0 && ($(';') || peek('}'))) {
|
||||
return new(tree.Extend)(elements, index);
|
||||
}
|
||||
|
||||
restore();
|
||||
},
|
||||
|
||||
51
lib/less/tree/extend.js
Normal file
51
lib/less/tree/extend.js
Normal file
@@ -0,0 +1,51 @@
|
||||
(function (tree) {
|
||||
|
||||
tree.Extend = function Extend(elements, index) {
|
||||
this.selector = new(tree.Selector)(elements);
|
||||
this.index = index;
|
||||
};
|
||||
|
||||
tree.Extend.prototype.eval = function Extend_eval(env) {
|
||||
var selfSelectors = findSelfSelectors(env.selectors);
|
||||
targetValue = this.selector.elements[0].value;
|
||||
|
||||
env.frames.forEach(function(frame) {
|
||||
frame.rulesets().forEach(function(rule) {
|
||||
rule.selectors.forEach(function(selector) {
|
||||
selector.elements.forEach(function(element, idx) {
|
||||
if (element.value === targetValue) {
|
||||
selfSelectors.forEach(function(_selector) {
|
||||
rule.selectors.push(new tree.Selector(
|
||||
selector.elements
|
||||
.slice(0, idx)
|
||||
.concat(_selector.elements)
|
||||
.concat(selector.elements.slice(idx + 1))
|
||||
));
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
function findSelfSelectors(selectors) {
|
||||
var ret = [];
|
||||
|
||||
(function loop(elem, i) {
|
||||
if (selectors[i] && selectors[i].length) {
|
||||
selectors[i].forEach(function(s) {
|
||||
loop(s.elements.concat(elem), i + 1);
|
||||
});
|
||||
}
|
||||
else {
|
||||
ret.push({ elements: elem });
|
||||
}
|
||||
})([], 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
})(require('../tree'));
|
||||
@@ -23,6 +23,12 @@ tree.Ruleset.prototype = {
|
||||
// push the current ruleset to the frames stack
|
||||
env.frames.unshift(ruleset);
|
||||
|
||||
// currrent selectors
|
||||
if (!env.selectors) {
|
||||
env.selectors = [];
|
||||
}
|
||||
env.selectors.unshift(this.selectors);
|
||||
|
||||
// Evaluate imports
|
||||
if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) {
|
||||
ruleset.evalImports(env);
|
||||
@@ -59,6 +65,7 @@ tree.Ruleset.prototype = {
|
||||
|
||||
// Pop the stack
|
||||
env.frames.shift();
|
||||
env.selectors.shift();
|
||||
|
||||
if (env.mediaBlocks) {
|
||||
for(var i = mediaBlockCount; i < env.mediaBlocks.length; i++) {
|
||||
|
||||
Reference in New Issue
Block a user