less 1.2.21 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -3
- data/.gitmodules +6 -0
- data/Gemfile +3 -0
- data/README.md +39 -46
- data/Rakefile +5 -50
- data/bin/lessc +1 -100
- data/less.gemspec +21 -125
- data/lib/less.rb +11 -30
- data/{LICENSE → lib/less/js/LICENSE} +1 -1
- data/lib/less/js/Makefile +56 -0
- data/lib/less/js/README.md +20 -0
- data/lib/less/js/benchmark/benchmark.less +3979 -0
- data/lib/less/js/benchmark/less-benchmark.js +49 -0
- data/lib/less/js/bin/lessc +105 -0
- data/lib/less/js/build/ecma-5.js +120 -0
- data/lib/less/js/build/header.js +7 -0
- data/lib/less/js/build/require.js +7 -0
- data/lib/less/js/dist/less-1.0.44.js +2655 -0
- data/lib/less/js/dist/less-1.1.0.js +2695 -0
- data/lib/less/js/dist/less-1.1.0.min.js +16 -0
- data/lib/less/js/dist/less-1.1.1.js +2710 -0
- data/lib/less/js/dist/less-1.1.1.min.js +16 -0
- data/lib/less/js/dist/less-1.1.2.js +2712 -0
- data/lib/less/js/dist/less-1.1.2.min.js +16 -0
- data/lib/less/js/dist/less-1.1.3.js +2721 -0
- data/lib/less/js/dist/less-1.1.3.min.js +16 -0
- data/lib/less/js/lib/less/browser.js +369 -0
- data/lib/less/js/lib/less/functions.js +174 -0
- data/lib/less/js/lib/less/index.js +137 -0
- data/lib/less/js/lib/less/parser.js +1098 -0
- data/lib/less/js/lib/less/tree.js +13 -0
- data/lib/less/js/lib/less/tree/alpha.js +17 -0
- data/lib/less/js/lib/less/tree/anonymous.js +13 -0
- data/lib/less/js/lib/less/tree/call.js +45 -0
- data/lib/less/js/lib/less/tree/color.js +98 -0
- data/lib/less/js/lib/less/tree/comment.js +14 -0
- data/lib/less/js/lib/less/tree/dimension.js +34 -0
- data/lib/less/js/lib/less/tree/directive.js +33 -0
- data/lib/less/js/lib/less/tree/element.js +32 -0
- data/lib/less/js/lib/less/tree/expression.js +23 -0
- data/lib/less/js/lib/less/tree/import.js +77 -0
- data/lib/less/js/lib/less/tree/javascript.js +51 -0
- data/lib/less/js/lib/less/tree/keyword.js +9 -0
- data/lib/less/js/lib/less/tree/mixin.js +106 -0
- data/lib/less/js/lib/less/tree/operation.js +32 -0
- data/lib/less/js/lib/less/tree/quoted.js +29 -0
- data/lib/less/js/lib/less/tree/rule.js +38 -0
- data/lib/less/js/lib/less/tree/ruleset.js +179 -0
- data/lib/less/js/lib/less/tree/selector.js +28 -0
- data/lib/less/js/lib/less/tree/url.js +25 -0
- data/lib/less/js/lib/less/tree/value.js +24 -0
- data/lib/less/js/lib/less/tree/variable.js +24 -0
- data/lib/less/js/package.json +13 -0
- data/lib/less/js/test/css/colors.css +42 -0
- data/lib/less/js/test/css/comments.css +52 -0
- data/lib/less/js/test/css/css-3.css +42 -0
- data/lib/less/js/test/css/css-escapes.css +20 -0
- data/lib/less/js/test/css/css.css +82 -0
- data/lib/less/js/test/css/functions.css +30 -0
- data/{spec → lib/less/js/test}/css/import.css +4 -2
- data/lib/less/js/test/css/javascript.css +22 -0
- data/lib/less/js/test/css/lazy-eval.css +3 -0
- data/lib/less/js/test/css/media.css +21 -0
- data/lib/less/js/test/css/mixins-args.css +61 -0
- data/lib/less/js/test/css/mixins-closure.css +9 -0
- data/lib/less/js/test/css/mixins-nested.css +14 -0
- data/lib/less/js/test/css/mixins-pattern.css +49 -0
- data/lib/less/js/test/css/mixins.css +50 -0
- data/{spec → lib/less/js/test}/css/operations.css +20 -2
- data/{spec → lib/less/js/test}/css/parens.css +0 -0
- data/lib/less/js/test/css/rulesets.css +29 -0
- data/{spec → lib/less/js/test}/css/scope.css +6 -2
- data/lib/less/js/test/css/selectors.css +32 -0
- data/lib/less/js/test/css/strings.css +38 -0
- data/lib/less/js/test/css/variables.css +24 -0
- data/lib/less/js/test/css/whitespace.css +36 -0
- data/lib/less/js/test/less-test.js +75 -0
- data/{spec → lib/less/js/test}/less/colors.less +13 -2
- data/{spec → lib/less/js/test}/less/comments.less +19 -2
- data/{spec → lib/less/js/test}/less/css-3.less +4 -1
- data/lib/less/js/test/less/css-escapes.less +28 -0
- data/{spec → lib/less/js/test}/less/css.less +10 -18
- data/lib/less/js/test/less/functions.less +35 -0
- data/{spec → lib/less/js/test}/less/import.less +1 -1
- data/{spec → lib/less/js/test}/less/import/import-test-a.less +0 -0
- data/{spec → lib/less/js/test}/less/import/import-test-b.less +0 -0
- data/{spec → lib/less/js/test}/less/import/import-test-c.less +0 -0
- data/{spec → lib/less/js/test}/less/import/import-test-d.css +0 -0
- data/lib/less/js/test/less/javascript.less +27 -0
- data/{spec → lib/less/js/test}/less/lazy-eval.less +0 -0
- data/lib/less/js/test/less/media.less +25 -0
- data/lib/less/js/test/less/mixins-args.less +118 -0
- data/lib/less/js/test/less/mixins-closure.less +26 -0
- data/lib/less/js/test/less/mixins-nested.less +22 -0
- data/lib/less/js/test/less/mixins-pattern.less +96 -0
- data/{spec → lib/less/js/test}/less/mixins.less +8 -4
- data/{spec → lib/less/js/test}/less/operations.less +19 -0
- data/{spec → lib/less/js/test}/less/parens.less +0 -0
- data/{spec → lib/less/js/test}/less/rulesets.less +2 -2
- data/{spec → lib/less/js/test}/less/scope.less +1 -1
- data/{spec → lib/less/js/test}/less/selectors.less +1 -1
- data/lib/less/js/test/less/strings.less +49 -0
- data/lib/less/js/test/less/variables.less +50 -0
- data/{spec → lib/less/js/test}/less/whitespace.less +3 -0
- data/lib/less/loader.rb +67 -0
- data/lib/less/parser.rb +46 -0
- data/lib/less/version.rb +3 -0
- data/spec/less/one/one.less +1 -0
- data/spec/less/parser_spec.rb +30 -0
- data/spec/less/two/two.less +1 -0
- data/spec/spec_helper.rb +2 -7
- metadata +156 -106
- data/CHANGELOG +0 -62
- data/VERSION +0 -1
- data/lib/less/command.rb +0 -110
- data/lib/less/engine.rb +0 -52
- data/lib/less/engine/grammar/common.tt +0 -29
- data/lib/less/engine/grammar/entity.tt +0 -144
- data/lib/less/engine/grammar/less.tt +0 -341
- data/lib/less/engine/nodes.rb +0 -9
- data/lib/less/engine/nodes/element.rb +0 -281
- data/lib/less/engine/nodes/entity.rb +0 -79
- data/lib/less/engine/nodes/function.rb +0 -93
- data/lib/less/engine/nodes/literal.rb +0 -171
- data/lib/less/engine/nodes/property.rb +0 -232
- data/lib/less/engine/nodes/ruleset.rb +0 -12
- data/lib/less/engine/nodes/selector.rb +0 -44
- data/lib/less/ext.rb +0 -60
- data/spec/command_spec.rb +0 -102
- data/spec/css/accessors.css +0 -18
- data/spec/css/big.css +0 -3768
- data/spec/css/colors.css +0 -14
- data/spec/css/comments.css +0 -9
- data/spec/css/css-3.css +0 -21
- data/spec/css/css.css +0 -50
- data/spec/css/dash-prefix.css +0 -12
- data/spec/css/functions.css +0 -6
- data/spec/css/import-with-extra-paths.css +0 -8
- data/spec/css/import-with-partial-in-extra-path.css +0 -6
- data/spec/css/lazy-eval.css +0 -1
- data/spec/css/mixins-args.css +0 -32
- data/spec/css/mixins.css +0 -28
- data/spec/css/rulesets.css +0 -17
- data/spec/css/selectors.css +0 -13
- data/spec/css/strings.css +0 -12
- data/spec/css/variables.css +0 -8
- data/spec/css/whitespace.css +0 -7
- data/spec/engine_spec.rb +0 -127
- data/spec/less/accessors.less +0 -20
- data/spec/less/big.less +0 -1264
- data/spec/less/dash-prefix.less +0 -21
- data/spec/less/exceptions/mixed-units-error.less +0 -3
- data/spec/less/exceptions/name-error-1.0.less +0 -3
- data/spec/less/exceptions/syntax-error-1.0.less +0 -3
- data/spec/less/extra_import_path/extra.less +0 -1
- data/spec/less/extra_import_path/import/import-test-a.css +0 -1
- data/spec/less/extra_import_path/import/import-test-a.less +0 -4
- data/spec/less/functions.less +0 -6
- data/spec/less/hidden.less +0 -25
- data/spec/less/import-with-extra-paths.less +0 -4
- data/spec/less/literal-css.less +0 -11
- data/spec/less/mixins-args.less +0 -59
- data/spec/less/strings.less +0 -14
- data/spec/less/variables.less +0 -29
- data/spec/spec.css +0 -50
@@ -0,0 +1,106 @@
|
|
1
|
+
(function (tree) {
|
2
|
+
|
3
|
+
tree.mixin = {};
|
4
|
+
tree.mixin.Call = function (elements, args, index) {
|
5
|
+
this.selector = new(tree.Selector)(elements);
|
6
|
+
this.arguments = args;
|
7
|
+
this.index = index;
|
8
|
+
};
|
9
|
+
tree.mixin.Call.prototype = {
|
10
|
+
eval: function (env) {
|
11
|
+
var mixins, args, rules = [], match = false;
|
12
|
+
|
13
|
+
for (var i = 0; i < env.frames.length; i++) {
|
14
|
+
if ((mixins = env.frames[i].find(this.selector)).length > 0) {
|
15
|
+
args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
|
16
|
+
for (var m = 0; m < mixins.length; m++) {
|
17
|
+
if (mixins[m].match(args, env)) {
|
18
|
+
try {
|
19
|
+
Array.prototype.push.apply(
|
20
|
+
rules, mixins[m].eval(env, this.arguments).rules);
|
21
|
+
match = true;
|
22
|
+
} catch (e) {
|
23
|
+
throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
if (match) {
|
28
|
+
return rules;
|
29
|
+
} else {
|
30
|
+
throw { message: 'No matching definition was found for `' +
|
31
|
+
this.selector.toCSS().trim() + '(' +
|
32
|
+
this.arguments.map(function (a) {
|
33
|
+
return a.toCSS();
|
34
|
+
}).join(', ') + ")`",
|
35
|
+
index: this.index };
|
36
|
+
}
|
37
|
+
}
|
38
|
+
}
|
39
|
+
throw { message: this.selector.toCSS().trim() + " is undefined",
|
40
|
+
index: this.index };
|
41
|
+
}
|
42
|
+
};
|
43
|
+
|
44
|
+
tree.mixin.Definition = function (name, params, rules) {
|
45
|
+
this.name = name;
|
46
|
+
this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
|
47
|
+
this.params = params;
|
48
|
+
this.arity = params.length;
|
49
|
+
this.rules = rules;
|
50
|
+
this._lookups = {};
|
51
|
+
this.required = params.reduce(function (count, p) {
|
52
|
+
if (!p.name || (p.name && !p.value)) { return count + 1 }
|
53
|
+
else { return count }
|
54
|
+
}, 0);
|
55
|
+
this.parent = tree.Ruleset.prototype;
|
56
|
+
this.frames = [];
|
57
|
+
};
|
58
|
+
tree.mixin.Definition.prototype = {
|
59
|
+
toCSS: function () { return "" },
|
60
|
+
variable: function (name) { return this.parent.variable.call(this, name) },
|
61
|
+
variables: function () { return this.parent.variables.call(this) },
|
62
|
+
find: function () { return this.parent.find.apply(this, arguments) },
|
63
|
+
rulesets: function () { return this.parent.rulesets.apply(this) },
|
64
|
+
|
65
|
+
eval: function (env, args) {
|
66
|
+
var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
|
67
|
+
|
68
|
+
for (var i = 0, val; i < this.params.length; i++) {
|
69
|
+
if (this.params[i].name) {
|
70
|
+
if (val = (args && args[i]) || this.params[i].value) {
|
71
|
+
frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
|
72
|
+
} else {
|
73
|
+
throw { message: "wrong number of arguments for " + this.name +
|
74
|
+
' (' + args.length + ' for ' + this.arity + ')' };
|
75
|
+
}
|
76
|
+
}
|
77
|
+
}
|
78
|
+
for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
|
79
|
+
_arguments.push(args[i] || this.params[i].value);
|
80
|
+
}
|
81
|
+
frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
|
82
|
+
|
83
|
+
return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
|
84
|
+
frames: [this, frame].concat(this.frames, env.frames)
|
85
|
+
});
|
86
|
+
},
|
87
|
+
match: function (args, env) {
|
88
|
+
var argsLength = (args && args.length) || 0, len;
|
89
|
+
|
90
|
+
if (argsLength < this.required) { return false }
|
91
|
+
if ((this.required > 0) && (argsLength > this.params.length)) { return false }
|
92
|
+
|
93
|
+
len = Math.min(argsLength, this.arity);
|
94
|
+
|
95
|
+
for (var i = 0; i < len; i++) {
|
96
|
+
if (!this.params[i].name) {
|
97
|
+
if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
|
98
|
+
return false;
|
99
|
+
}
|
100
|
+
}
|
101
|
+
}
|
102
|
+
return true;
|
103
|
+
}
|
104
|
+
};
|
105
|
+
|
106
|
+
})(require('less/tree'));
|
@@ -0,0 +1,32 @@
|
|
1
|
+
(function (tree) {
|
2
|
+
|
3
|
+
tree.Operation = function (op, operands) {
|
4
|
+
this.op = op.trim();
|
5
|
+
this.operands = operands;
|
6
|
+
};
|
7
|
+
tree.Operation.prototype.eval = function (env) {
|
8
|
+
var a = this.operands[0].eval(env),
|
9
|
+
b = this.operands[1].eval(env),
|
10
|
+
temp;
|
11
|
+
|
12
|
+
if (a instanceof tree.Dimension && b instanceof tree.Color) {
|
13
|
+
if (this.op === '*' || this.op === '+') {
|
14
|
+
temp = b, b = a, a = temp;
|
15
|
+
} else {
|
16
|
+
throw { name: "OperationError",
|
17
|
+
message: "Can't substract or divide a color from a number" };
|
18
|
+
}
|
19
|
+
}
|
20
|
+
return a.operate(this.op, b);
|
21
|
+
};
|
22
|
+
|
23
|
+
tree.operate = function (op, a, b) {
|
24
|
+
switch (op) {
|
25
|
+
case '+': return a + b;
|
26
|
+
case '-': return a - b;
|
27
|
+
case '*': return a * b;
|
28
|
+
case '/': return a / b;
|
29
|
+
}
|
30
|
+
};
|
31
|
+
|
32
|
+
})(require('less/tree'));
|
@@ -0,0 +1,29 @@
|
|
1
|
+
(function (tree) {
|
2
|
+
|
3
|
+
tree.Quoted = function (str, content, escaped, i) {
|
4
|
+
this.escaped = escaped;
|
5
|
+
this.value = content || '';
|
6
|
+
this.quote = str.charAt(0);
|
7
|
+
this.index = i;
|
8
|
+
};
|
9
|
+
tree.Quoted.prototype = {
|
10
|
+
toCSS: function () {
|
11
|
+
if (this.escaped) {
|
12
|
+
return this.value;
|
13
|
+
} else {
|
14
|
+
return this.quote + this.value + this.quote;
|
15
|
+
}
|
16
|
+
},
|
17
|
+
eval: function (env) {
|
18
|
+
var that = this;
|
19
|
+
var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
|
20
|
+
return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
|
21
|
+
}).replace(/@\{([\w-]+)\}/g, function (_, name) {
|
22
|
+
var v = new(tree.Variable)('@' + name, that.index).eval(env);
|
23
|
+
return v.value || v.toCSS();
|
24
|
+
});
|
25
|
+
return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
|
26
|
+
}
|
27
|
+
};
|
28
|
+
|
29
|
+
})(require('less/tree'));
|
@@ -0,0 +1,38 @@
|
|
1
|
+
(function (tree) {
|
2
|
+
|
3
|
+
tree.Rule = function (name, value, important, index) {
|
4
|
+
this.name = name;
|
5
|
+
this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
|
6
|
+
this.important = important ? ' ' + important.trim() : '';
|
7
|
+
this.index = index;
|
8
|
+
|
9
|
+
if (name.charAt(0) === '@') {
|
10
|
+
this.variable = true;
|
11
|
+
} else { this.variable = false }
|
12
|
+
};
|
13
|
+
tree.Rule.prototype.toCSS = function (env) {
|
14
|
+
if (this.variable) { return "" }
|
15
|
+
else {
|
16
|
+
return this.name + (env.compress ? ':' : ': ') +
|
17
|
+
this.value.toCSS(env) +
|
18
|
+
this.important + ";";
|
19
|
+
}
|
20
|
+
};
|
21
|
+
|
22
|
+
tree.Rule.prototype.eval = function (context) {
|
23
|
+
return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index);
|
24
|
+
};
|
25
|
+
|
26
|
+
tree.Shorthand = function (a, b) {
|
27
|
+
this.a = a;
|
28
|
+
this.b = b;
|
29
|
+
};
|
30
|
+
|
31
|
+
tree.Shorthand.prototype = {
|
32
|
+
toCSS: function (env) {
|
33
|
+
return this.a.toCSS(env) + "/" + this.b.toCSS(env);
|
34
|
+
},
|
35
|
+
eval: function () { return this }
|
36
|
+
};
|
37
|
+
|
38
|
+
})(require('less/tree'));
|
@@ -0,0 +1,179 @@
|
|
1
|
+
(function (tree) {
|
2
|
+
|
3
|
+
tree.Ruleset = function (selectors, rules) {
|
4
|
+
this.selectors = selectors;
|
5
|
+
this.rules = rules;
|
6
|
+
this._lookups = {};
|
7
|
+
};
|
8
|
+
tree.Ruleset.prototype = {
|
9
|
+
eval: function (env) {
|
10
|
+
var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
|
11
|
+
|
12
|
+
ruleset.root = this.root;
|
13
|
+
|
14
|
+
// push the current ruleset to the frames stack
|
15
|
+
env.frames.unshift(ruleset);
|
16
|
+
|
17
|
+
// Evaluate imports
|
18
|
+
if (ruleset.root) {
|
19
|
+
for (var i = 0; i < ruleset.rules.length; i++) {
|
20
|
+
if (ruleset.rules[i] instanceof tree.Import) {
|
21
|
+
Array.prototype.splice
|
22
|
+
.apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
// Store the frames around mixin definitions,
|
28
|
+
// so they can be evaluated like closures when the time comes.
|
29
|
+
for (var i = 0; i < ruleset.rules.length; i++) {
|
30
|
+
if (ruleset.rules[i] instanceof tree.mixin.Definition) {
|
31
|
+
ruleset.rules[i].frames = env.frames.slice(0);
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
// Evaluate mixin calls.
|
36
|
+
for (var i = 0; i < ruleset.rules.length; i++) {
|
37
|
+
if (ruleset.rules[i] instanceof tree.mixin.Call) {
|
38
|
+
Array.prototype.splice
|
39
|
+
.apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
// Evaluate everything else
|
44
|
+
for (var i = 0, rule; i < ruleset.rules.length; i++) {
|
45
|
+
rule = ruleset.rules[i];
|
46
|
+
|
47
|
+
if (! (rule instanceof tree.mixin.Definition)) {
|
48
|
+
ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
// Pop the stack
|
53
|
+
env.frames.shift();
|
54
|
+
|
55
|
+
return ruleset;
|
56
|
+
},
|
57
|
+
match: function (args) {
|
58
|
+
return !args || args.length === 0;
|
59
|
+
},
|
60
|
+
variables: function () {
|
61
|
+
if (this._variables) { return this._variables }
|
62
|
+
else {
|
63
|
+
return this._variables = this.rules.reduce(function (hash, r) {
|
64
|
+
if (r instanceof tree.Rule && r.variable === true) {
|
65
|
+
hash[r.name] = r;
|
66
|
+
}
|
67
|
+
return hash;
|
68
|
+
}, {});
|
69
|
+
}
|
70
|
+
},
|
71
|
+
variable: function (name) {
|
72
|
+
return this.variables()[name];
|
73
|
+
},
|
74
|
+
rulesets: function () {
|
75
|
+
if (this._rulesets) { return this._rulesets }
|
76
|
+
else {
|
77
|
+
return this._rulesets = this.rules.filter(function (r) {
|
78
|
+
return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
|
79
|
+
});
|
80
|
+
}
|
81
|
+
},
|
82
|
+
find: function (selector, self) {
|
83
|
+
self = self || this;
|
84
|
+
var rules = [], rule, match,
|
85
|
+
key = selector.toCSS();
|
86
|
+
|
87
|
+
if (key in this._lookups) { return this._lookups[key] }
|
88
|
+
|
89
|
+
this.rulesets().forEach(function (rule) {
|
90
|
+
if (rule !== self) {
|
91
|
+
for (var j = 0; j < rule.selectors.length; j++) {
|
92
|
+
if (match = selector.match(rule.selectors[j])) {
|
93
|
+
if (selector.elements.length > 1) {
|
94
|
+
Array.prototype.push.apply(rules, rule.find(
|
95
|
+
new(tree.Selector)(selector.elements.slice(1)), self));
|
96
|
+
} else {
|
97
|
+
rules.push(rule);
|
98
|
+
}
|
99
|
+
break;
|
100
|
+
}
|
101
|
+
}
|
102
|
+
}
|
103
|
+
});
|
104
|
+
return this._lookups[key] = rules;
|
105
|
+
},
|
106
|
+
//
|
107
|
+
// Entry point for code generation
|
108
|
+
//
|
109
|
+
// `context` holds an array of arrays.
|
110
|
+
//
|
111
|
+
toCSS: function (context, env) {
|
112
|
+
var css = [], // The CSS output
|
113
|
+
rules = [], // node.Rule instances
|
114
|
+
rulesets = [], // node.Ruleset instances
|
115
|
+
paths = [], // Current selectors
|
116
|
+
selector, // The fully rendered selector
|
117
|
+
rule;
|
118
|
+
|
119
|
+
if (! this.root) {
|
120
|
+
if (context.length === 0) {
|
121
|
+
paths = this.selectors.map(function (s) { return [s] });
|
122
|
+
} else {
|
123
|
+
for (var s = 0; s < this.selectors.length; s++) {
|
124
|
+
for (var c = 0; c < context.length; c++) {
|
125
|
+
paths.push(context[c].concat([this.selectors[s]]));
|
126
|
+
}
|
127
|
+
}
|
128
|
+
}
|
129
|
+
}
|
130
|
+
|
131
|
+
// Compile rules and rulesets
|
132
|
+
for (var i = 0; i < this.rules.length; i++) {
|
133
|
+
rule = this.rules[i];
|
134
|
+
|
135
|
+
if (rule.rules || (rule instanceof tree.Directive)) {
|
136
|
+
rulesets.push(rule.toCSS(paths, env));
|
137
|
+
} else if (rule instanceof tree.Comment) {
|
138
|
+
if (!rule.silent) {
|
139
|
+
if (this.root) {
|
140
|
+
rulesets.push(rule.toCSS(env));
|
141
|
+
} else {
|
142
|
+
rules.push(rule.toCSS(env));
|
143
|
+
}
|
144
|
+
}
|
145
|
+
} else {
|
146
|
+
if (rule.toCSS && !rule.variable) {
|
147
|
+
rules.push(rule.toCSS(env));
|
148
|
+
} else if (rule.value && !rule.variable) {
|
149
|
+
rules.push(rule.value.toString());
|
150
|
+
}
|
151
|
+
}
|
152
|
+
}
|
153
|
+
|
154
|
+
rulesets = rulesets.join('');
|
155
|
+
|
156
|
+
// If this is the root node, we don't render
|
157
|
+
// a selector, or {}.
|
158
|
+
// Otherwise, only output if this ruleset has rules.
|
159
|
+
if (this.root) {
|
160
|
+
css.push(rules.join(env.compress ? '' : '\n'));
|
161
|
+
} else {
|
162
|
+
if (rules.length > 0) {
|
163
|
+
selector = paths.map(function (p) {
|
164
|
+
return p.map(function (s) {
|
165
|
+
return s.toCSS(env);
|
166
|
+
}).join('').trim();
|
167
|
+
}).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
|
168
|
+
css.push(selector,
|
169
|
+
(env.compress ? '{' : ' {\n ') +
|
170
|
+
rules.join(env.compress ? '' : '\n ') +
|
171
|
+
(env.compress ? '}' : '\n}\n'));
|
172
|
+
}
|
173
|
+
}
|
174
|
+
css.push(rulesets);
|
175
|
+
|
176
|
+
return css.join('') + (env.compress ? '\n' : '');
|
177
|
+
}
|
178
|
+
};
|
179
|
+
})(require('less/tree'));
|
@@ -0,0 +1,28 @@
|
|
1
|
+
(function (tree) {
|
2
|
+
|
3
|
+
tree.Selector = function (elements) {
|
4
|
+
this.elements = elements;
|
5
|
+
if (this.elements[0].combinator.value === "") {
|
6
|
+
this.elements[0].combinator.value = ' ';
|
7
|
+
}
|
8
|
+
};
|
9
|
+
tree.Selector.prototype.match = function (other) {
|
10
|
+
if (this.elements[0].value === other.elements[0].value) {
|
11
|
+
return true;
|
12
|
+
} else {
|
13
|
+
return false;
|
14
|
+
}
|
15
|
+
};
|
16
|
+
tree.Selector.prototype.toCSS = function (env) {
|
17
|
+
if (this._css) { return this._css }
|
18
|
+
|
19
|
+
return this._css = this.elements.map(function (e) {
|
20
|
+
if (typeof(e) === 'string') {
|
21
|
+
return ' ' + e.trim();
|
22
|
+
} else {
|
23
|
+
return e.toCSS(env);
|
24
|
+
}
|
25
|
+
}).join('');
|
26
|
+
};
|
27
|
+
|
28
|
+
})(require('less/tree'));
|
@@ -0,0 +1,25 @@
|
|
1
|
+
(function (tree) {
|
2
|
+
|
3
|
+
tree.URL = function (val, paths) {
|
4
|
+
if (val.data) {
|
5
|
+
this.attrs = val;
|
6
|
+
} else {
|
7
|
+
// Add the base path if the URL is relative and we are in the browser
|
8
|
+
if (!/^(?:https?:\/|file:\/|data:\/)?\//.test(val.value) && paths.length > 0 && typeof(window) !== 'undefined') {
|
9
|
+
val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
|
10
|
+
}
|
11
|
+
this.value = val;
|
12
|
+
this.paths = paths;
|
13
|
+
}
|
14
|
+
};
|
15
|
+
tree.URL.prototype = {
|
16
|
+
toCSS: function () {
|
17
|
+
return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
|
18
|
+
: this.value.toCSS()) + ")";
|
19
|
+
},
|
20
|
+
eval: function (ctx) {
|
21
|
+
return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
|
22
|
+
}
|
23
|
+
};
|
24
|
+
|
25
|
+
})(require('less/tree'));
|