less 3.0.0-pre.2 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +88 -0
- package/.github/stale.yml +17 -0
- package/.project +17 -0
- package/.settings/org.eclipse.buildship.core.prefs +2 -0
- package/.travis.yml +22 -3
- package/.vscode/launch.json +14 -0
- package/CHANGELOG.md +27 -0
- package/Gruntfile.js +191 -86
- package/README.md +5 -7
- package/appveyor.yml +9 -10
- package/bin/lessc +37 -50
- package/dist/less.js +1357 -1269
- package/dist/less.min.js +7 -7
- package/lib/less/contexts.js +20 -16
- package/lib/less/default-options.js +65 -0
- package/lib/less/environment/abstract-file-manager.js +13 -14
- package/lib/less/environment/abstract-plugin-loader.js +45 -36
- package/lib/less/environment/environment.js +5 -0
- package/lib/less/functions/boolean.js +15 -0
- package/lib/less/functions/color.js +54 -24
- package/lib/less/functions/data-uri.js +5 -2
- package/lib/less/functions/function-registry.js +1 -1
- package/lib/less/functions/index.js +2 -1
- package/lib/less/functions/number.js +2 -2
- package/lib/less/functions/string.js +2 -2
- package/lib/less/functions/svg.js +4 -4
- package/lib/less/import-manager.js +41 -29
- package/lib/less/index.js +28 -3
- package/lib/less/less-error.js +112 -13
- package/lib/less/parse.js +18 -15
- package/lib/less/parser/parser-input.js +4 -4
- package/lib/less/parser/parser.js +208 -114
- package/lib/less/plugin-manager.js +8 -33
- package/lib/less/render.js +6 -2
- package/lib/less/source-map-builder.js +3 -0
- package/lib/less/source-map-output.js +13 -8
- package/lib/less/transform-tree.js +2 -2
- package/lib/less/tree/anonymous.js +4 -1
- package/lib/less/tree/atrule.js +7 -6
- package/lib/less/tree/call.js +25 -3
- package/lib/less/tree/color.js +2 -2
- package/lib/less/tree/debug-info.js +1 -1
- package/lib/less/tree/declaration.js +6 -5
- package/lib/less/tree/dimension.js +4 -1
- package/lib/less/tree/extend.js +2 -2
- package/lib/less/tree/import.js +17 -9
- package/lib/less/tree/index.js +3 -7
- package/lib/less/tree/js-eval-node.js +1 -1
- package/lib/less/tree/media.js +3 -14
- package/lib/less/tree/mixin-definition.js +3 -3
- package/lib/less/tree/node.js +9 -6
- package/lib/less/tree/operation.js +1 -1
- package/lib/less/tree/property.js +70 -0
- package/lib/less/tree/quoted.js +11 -10
- package/lib/less/tree/ruleset.js +115 -71
- package/lib/less/tree/selector.js +38 -23
- package/lib/less/tree/unit.js +1 -1
- package/lib/less/tree/value.js +6 -1
- package/lib/less/tree/{ruleset-call.js → variable-call.js} +5 -5
- package/lib/less/tree/variable.js +6 -6
- package/lib/less/utils.js +40 -0
- package/lib/less/visitors/extend-visitor.js +14 -14
- package/lib/less/visitors/import-visitor.js +2 -2
- package/lib/less/visitors/join-selector-visitor.js +1 -1
- package/lib/less/visitors/to-css-visitor.js +51 -84
- package/lib/less/visitors/visitor.js +15 -15
- package/lib/less-browser/bootstrap.js +21 -5
- package/lib/less-browser/cache.js +2 -2
- package/lib/less-browser/error-reporting.js +5 -5
- package/lib/less-browser/file-manager.js +27 -35
- package/lib/less-browser/index.js +12 -17
- package/lib/less-browser/plugin-loader.js +8 -45
- package/lib/less-browser/utils.js +1 -1
- package/lib/less-node/file-manager.js +99 -69
- package/lib/less-node/fs.js +1 -1
- package/lib/less-node/image-size.js +2 -2
- package/lib/less-node/index.js +7 -57
- package/lib/less-node/lessc-helper.js +38 -38
- package/lib/less-node/plugin-loader.js +18 -79
- package/lib/less-node/url-file-manager.js +1 -1
- package/lib/less-rhino/index.js +29 -44
- package/package.json +16 -9
- package/test/browser/common.js +54 -18
- package/test/browser/css/plugin/plugin.css +3 -0
- package/test/browser/jasmine-jsreporter.js +4 -4
- package/test/browser/less/plugin/plugin.js +7 -0
- package/test/browser/less/plugin/plugin.less +4 -0
- package/test/browser/less.js +11685 -13
- package/test/browser/runner-browser-options.js +6 -1
- package/test/browser/runner-filemanagerPlugin-options.js +3 -2
- package/test/browser/runner-legacy-options.js +2 -1
- package/test/browser/runner-main-options.js +0 -1
- package/test/browser/runner-modify-vars-spec.js +2 -2
- package/test/browser/test-runner-template.tmpl +38 -14
- package/test/copy-bom.js +1 -1
- package/test/css/calc.css +5 -0
- package/test/css/comments2.css +1 -1
- package/test/css/compression/compression.css +1 -1
- package/test/css/css-grid.css +11 -0
- package/test/css/debug/linenumbers-all.css +0 -1
- package/test/css/debug/linenumbers-comments.css +0 -1
- package/test/css/debug/linenumbers-mediaquery.css +0 -1
- package/test/css/functions.css +16 -3
- package/test/css/import-module.css +9 -0
- package/test/css/import.css +0 -1
- package/test/css/legacy/legacy.css +1 -1
- package/test/css/merge.css +5 -4
- package/test/css/plugin-module.css +1 -0
- package/test/css/plugin.css +20 -0
- package/test/css/property-accessors.css +49 -0
- package/test/css/{css.css → strict-math/css.css} +0 -0
- package/test/css/{mixins-args.css → strict-math/mixins-args.css} +0 -0
- package/test/css/{parens.css → strict-math/parens.css} +0 -0
- package/test/import-module/one/1.less +3 -0
- package/test/import-module/one/two/2.less +3 -0
- package/test/import-module/one/two/three/3.less +3 -0
- package/test/import-module/package.json +11 -0
- package/test/index.js +55 -49
- package/test/less/calc.less +7 -0
- package/test/less/css-grid.less +15 -0
- package/test/less/detached-rulesets.less +2 -2
- package/test/less/errors/color-invalid-hex-code.less +1 -0
- package/test/less/errors/color-invalid-hex-code.txt +1 -1
- package/test/less/errors/color-invalid-hex-code2.less +1 -0
- package/test/less/errors/color-invalid-hex-code2.txt +1 -1
- package/test/less/errors/import-missing.txt +1 -1
- package/test/less/errors/plugin/plugin-error-2.js +5 -0
- package/test/less/errors/plugin/plugin-error-3.js +5 -0
- package/test/less/errors/plugin/plugin-error.js +1 -0
- package/test/less/errors/plugin-1.less +1 -0
- package/test/less/errors/plugin-1.txt +2 -0
- package/test/less/errors/plugin-2.less +1 -0
- package/test/less/errors/plugin-2.txt +5 -0
- package/test/less/errors/plugin-3.less +1 -0
- package/test/less/errors/plugin-3.txt +5 -0
- package/test/less/functions.less +18 -0
- package/test/less/import-module.less +3 -0
- package/test/less/import.less +0 -2
- package/test/less/legacy/legacy.less +1 -1
- package/test/less/media.less +2 -2
- package/test/less/merge.less +6 -3
- package/test/less/plugin/plugin-collection.js +9 -0
- package/test/less/plugin/plugin-local.js +2 -2
- package/test/less/plugin/plugin-scope1.js +3 -0
- package/test/less/plugin/plugin-scope2.js +3 -0
- package/test/less/plugin/plugin-simple.js +7 -0
- package/test/less/plugin/plugin-tree-nodes.js +33 -31
- package/test/less/plugin-module.less +7 -0
- package/test/less/plugin.less +33 -3
- package/test/less/property-accessors.less +67 -0
- package/test/less/root-registry/file.less +1 -0
- package/test/less/root-registry/root.less +3 -0
- package/test/less/{css.less → strict-math/css.less} +0 -0
- package/test/less/{mixins-args.less → strict-math/mixins-args.less} +0 -0
- package/test/less/{parens.less → strict-math/parens.less} +0 -0
- package/test/less-bom/calc.less +7 -0
- package/test/less-bom/css-grid.less +15 -0
- package/test/less-bom/detached-rulesets.less +2 -2
- package/test/less-bom/errors/color-invalid-hex-code.less +1 -0
- package/test/less-bom/errors/color-invalid-hex-code.txt +1 -1
- package/test/less-bom/errors/color-invalid-hex-code2.less +1 -0
- package/test/less-bom/errors/color-invalid-hex-code2.txt +1 -1
- package/test/less-bom/errors/import-missing.txt +1 -1
- package/test/less-bom/errors/plugin/plugin-error-2.js +5 -0
- package/test/less-bom/errors/plugin/plugin-error-3.js +5 -0
- package/test/less-bom/errors/plugin/plugin-error.js +1 -0
- package/test/less-bom/errors/plugin-1.less +1 -0
- package/test/less-bom/errors/plugin-1.txt +2 -0
- package/test/less-bom/errors/plugin-2.less +1 -0
- package/test/less-bom/errors/plugin-2.txt +5 -0
- package/test/less-bom/errors/plugin-3.less +1 -0
- package/test/less-bom/errors/plugin-3.txt +5 -0
- package/test/less-bom/functions.less +18 -0
- package/test/less-bom/import-module.less +3 -0
- package/test/less-bom/import.less +0 -2
- package/test/less-bom/legacy/legacy.less +1 -1
- package/test/less-bom/media.less +2 -2
- package/test/less-bom/merge.less +6 -3
- package/test/less-bom/plugin/plugin-collection.js +9 -0
- package/test/less-bom/plugin/plugin-local.js +2 -2
- package/test/less-bom/plugin/plugin-scope1.js +3 -0
- package/test/less-bom/plugin/plugin-scope2.js +3 -0
- package/test/less-bom/plugin/plugin-simple.js +7 -0
- package/test/less-bom/plugin/plugin-tree-nodes.js +33 -31
- package/test/less-bom/plugin-module.less +7 -0
- package/test/less-bom/plugin.less +33 -3
- package/test/less-bom/property-accessors.less +67 -0
- package/test/less-bom/root-registry/file.less +1 -0
- package/test/less-bom/root-registry/root.less +3 -0
- package/test/less-bom/{css.less → strict-math/css.less} +0 -0
- package/test/less-bom/{mixins-args.less → strict-math/mixins-args.less} +0 -0
- package/test/less-bom/{parens.less → strict-math/parens.less} +0 -0
- package/test/less-test.js +75 -17
- package/test/modify-vars.js +1 -1
- package/test/plugins/visitor/index.js +1 -1
- package/.jscsrc +0 -73
- package/.jshintrc +0 -11
- package/lib/less/tree/alpha.js +0 -28
- package/lib/less/tree/directive.js +0 -12
- package/lib/less/tree/rule.js +0 -12
- package/test/less/errors/functions-2-alpha.less +0 -2
- package/test/less/errors/functions-2-alpha.txt +0 -3
- package/test/less-bom/errors/functions-2-alpha.less +0 -2
- package/test/less-bom/errors/functions-2-alpha.txt +0 -3
- package/test/sourcemaps/maps/import-map.map +0 -1
package/lib/less/tree/quoted.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var Node = require("./node"),
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
Variable = require("./variable"),
|
|
3
|
+
Property = require("./property");
|
|
4
4
|
|
|
5
5
|
var Quoted = function (str, content, escaped, index, currentFileInfo) {
|
|
6
6
|
this.escaped = (escaped == null) ? true : escaped;
|
|
@@ -9,7 +9,7 @@ var Quoted = function (str, content, escaped, index, currentFileInfo) {
|
|
|
9
9
|
this._index = index;
|
|
10
10
|
this._fileInfo = currentFileInfo;
|
|
11
11
|
};
|
|
12
|
-
Quoted.prototype = new
|
|
12
|
+
Quoted.prototype = new Node();
|
|
13
13
|
Quoted.prototype.type = "Quoted";
|
|
14
14
|
Quoted.prototype.genCSS = function (context, output) {
|
|
15
15
|
if (!this.escaped) {
|
|
@@ -21,17 +21,18 @@ Quoted.prototype.genCSS = function (context, output) {
|
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
23
|
Quoted.prototype.containsVariables = function() {
|
|
24
|
-
return this.value.match(
|
|
24
|
+
return this.value.match(/@\{([\w-]+)\}/);
|
|
25
25
|
};
|
|
26
26
|
Quoted.prototype.eval = function (context) {
|
|
27
27
|
var that = this, value = this.value;
|
|
28
|
-
var
|
|
29
|
-
return String(that.evaluateJavaScript(exp, context));
|
|
30
|
-
};
|
|
31
|
-
var interpolationReplacement = function (_, name) {
|
|
28
|
+
var variableReplacement = function (_, name) {
|
|
32
29
|
var v = new Variable('@' + name, that.getIndex(), that.fileInfo()).eval(context, true);
|
|
33
30
|
return (v instanceof Quoted) ? v.value : v.toCSS();
|
|
34
31
|
};
|
|
32
|
+
var propertyReplacement = function (_, name) {
|
|
33
|
+
var v = new Property('$' + name, that.getIndex(), that.fileInfo()).eval(context, true);
|
|
34
|
+
return (v instanceof Quoted) ? v.value : v.toCSS();
|
|
35
|
+
};
|
|
35
36
|
function iterativeReplace(value, regexp, replacementFnc) {
|
|
36
37
|
var evaluatedValue = value;
|
|
37
38
|
do {
|
|
@@ -40,8 +41,8 @@ Quoted.prototype.eval = function (context) {
|
|
|
40
41
|
} while (value !== evaluatedValue);
|
|
41
42
|
return evaluatedValue;
|
|
42
43
|
}
|
|
43
|
-
value = iterativeReplace(value,
|
|
44
|
-
value = iterativeReplace(value,
|
|
44
|
+
value = iterativeReplace(value, /@\{([\w-]+)\}/g, variableReplacement);
|
|
45
|
+
value = iterativeReplace(value, /\$\{([\w-]+)\}/g, propertyReplacement);
|
|
45
46
|
return new Quoted(this.quote + value + this.quote, value, this.escaped, this.getIndex(), this.fileInfo());
|
|
46
47
|
};
|
|
47
48
|
Quoted.prototype.compare = function (other) {
|
package/lib/less/tree/ruleset.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
var Node = require("./node"),
|
|
2
2
|
Declaration = require("./declaration"),
|
|
3
|
+
Keyword = require("./keyword"),
|
|
4
|
+
Comment = require("./comment"),
|
|
5
|
+
Paren = require("./paren"),
|
|
3
6
|
Selector = require("./selector"),
|
|
4
7
|
Element = require("./element"),
|
|
5
|
-
|
|
8
|
+
Anonymous = require("./anonymous"),
|
|
6
9
|
contexts = require("../contexts"),
|
|
7
10
|
globalFunctionRegistry = require("../functions/function-registry"),
|
|
8
11
|
defaultFunc = require("../functions/default"),
|
|
@@ -13,9 +16,12 @@ var Ruleset = function (selectors, rules, strictImports, visibilityInfo) {
|
|
|
13
16
|
this.selectors = selectors;
|
|
14
17
|
this.rules = rules;
|
|
15
18
|
this._lookups = {};
|
|
19
|
+
this._variables = null;
|
|
20
|
+
this._properties = null;
|
|
16
21
|
this.strictImports = strictImports;
|
|
17
22
|
this.copyVisibilityInfo(visibilityInfo);
|
|
18
23
|
this.allowRoot = true;
|
|
24
|
+
|
|
19
25
|
this.setParent(this.selectors, this);
|
|
20
26
|
this.setParent(this.rules, this);
|
|
21
27
|
|
|
@@ -23,7 +29,7 @@ var Ruleset = function (selectors, rules, strictImports, visibilityInfo) {
|
|
|
23
29
|
Ruleset.prototype = new Node();
|
|
24
30
|
Ruleset.prototype.type = "Ruleset";
|
|
25
31
|
Ruleset.prototype.isRuleset = true;
|
|
26
|
-
Ruleset.prototype.isRulesetLike = true;
|
|
32
|
+
Ruleset.prototype.isRulesetLike = function() { return true; };
|
|
27
33
|
Ruleset.prototype.accept = function (visitor) {
|
|
28
34
|
if (this.paths) {
|
|
29
35
|
this.paths = visitor.visitArray(this.paths, true);
|
|
@@ -104,20 +110,20 @@ Ruleset.prototype.eval = function (context) {
|
|
|
104
110
|
|
|
105
111
|
// Store the frames around mixin definitions,
|
|
106
112
|
// so they can be evaluated like closures when the time comes.
|
|
107
|
-
var rsRules = ruleset.rules
|
|
108
|
-
for (i = 0;
|
|
109
|
-
if (
|
|
110
|
-
rsRules[i] =
|
|
113
|
+
var rsRules = ruleset.rules;
|
|
114
|
+
for (i = 0; (rule = rsRules[i]); i++) {
|
|
115
|
+
if (rule.evalFirst) {
|
|
116
|
+
rsRules[i] = rule.eval(context);
|
|
111
117
|
}
|
|
112
118
|
}
|
|
113
119
|
|
|
114
120
|
var mediaBlockCount = (context.mediaBlocks && context.mediaBlocks.length) || 0;
|
|
115
121
|
|
|
116
122
|
// Evaluate mixin calls.
|
|
117
|
-
for (i = 0;
|
|
118
|
-
if (
|
|
119
|
-
/*jshint loopfunc:true */
|
|
120
|
-
rules =
|
|
123
|
+
for (i = 0; (rule = rsRules[i]); i++) {
|
|
124
|
+
if (rule.type === "MixinCall") {
|
|
125
|
+
/* jshint loopfunc:true */
|
|
126
|
+
rules = rule.eval(context).filter(function(r) {
|
|
121
127
|
if ((r instanceof Declaration) && r.variable) {
|
|
122
128
|
// do not pollute the scope if the variable is
|
|
123
129
|
// already there. consider returning false here
|
|
@@ -127,12 +133,11 @@ Ruleset.prototype.eval = function (context) {
|
|
|
127
133
|
return true;
|
|
128
134
|
});
|
|
129
135
|
rsRules.splice.apply(rsRules, [i, 1].concat(rules));
|
|
130
|
-
rsRuleCnt += rules.length - 1;
|
|
131
136
|
i += rules.length - 1;
|
|
132
137
|
ruleset.resetCache();
|
|
133
|
-
} else if (
|
|
134
|
-
/*jshint loopfunc:true */
|
|
135
|
-
rules =
|
|
138
|
+
} else if (rule.type === "VariableCall") {
|
|
139
|
+
/* jshint loopfunc:true */
|
|
140
|
+
rules = rule.eval(context).rules.filter(function(r) {
|
|
136
141
|
if ((r instanceof Declaration) && r.variable) {
|
|
137
142
|
// do not pollute the scope at all
|
|
138
143
|
return false;
|
|
@@ -140,31 +145,27 @@ Ruleset.prototype.eval = function (context) {
|
|
|
140
145
|
return true;
|
|
141
146
|
});
|
|
142
147
|
rsRules.splice.apply(rsRules, [i, 1].concat(rules));
|
|
143
|
-
rsRuleCnt += rules.length - 1;
|
|
144
148
|
i += rules.length - 1;
|
|
145
149
|
ruleset.resetCache();
|
|
146
150
|
}
|
|
147
151
|
}
|
|
148
152
|
|
|
149
153
|
// Evaluate everything else
|
|
150
|
-
for (i = 0;
|
|
151
|
-
rule = rsRules[i];
|
|
154
|
+
for (i = 0; (rule = rsRules[i]); i++) {
|
|
152
155
|
if (!rule.evalFirst) {
|
|
153
156
|
rsRules[i] = rule = rule.eval ? rule.eval(context) : rule;
|
|
154
157
|
}
|
|
155
158
|
}
|
|
156
159
|
|
|
157
160
|
// Evaluate everything else
|
|
158
|
-
for (i = 0;
|
|
159
|
-
rule = rsRules[i];
|
|
161
|
+
for (i = 0; (rule = rsRules[i]); i++) {
|
|
160
162
|
// for rulesets, check if it is a css guard and can be removed
|
|
161
163
|
if (rule instanceof Ruleset && rule.selectors && rule.selectors.length === 1) {
|
|
162
164
|
// check if it can be folded in (e.g. & where)
|
|
163
165
|
if (rule.selectors[0].isJustParentSelector()) {
|
|
164
166
|
rsRules.splice(i--, 1);
|
|
165
167
|
|
|
166
|
-
for (var j = 0;
|
|
167
|
-
subRule = rule.rules[j];
|
|
168
|
+
for (var j = 0; (subRule = rule.rules[j]); j++) {
|
|
168
169
|
if (subRule instanceof Node) {
|
|
169
170
|
subRule.copyVisibilityInfo(rule.visibilityInfo());
|
|
170
171
|
if (!(subRule instanceof Declaration) || !subRule.variable) {
|
|
@@ -197,7 +198,7 @@ Ruleset.prototype.evalImports = function(context) {
|
|
|
197
198
|
importRules = rules[i].eval(context);
|
|
198
199
|
if (importRules && (importRules.length || importRules.length === 0)) {
|
|
199
200
|
rules.splice.apply(rules, [i, 1].concat(importRules));
|
|
200
|
-
i+= importRules.length - 1;
|
|
201
|
+
i += importRules.length - 1;
|
|
201
202
|
} else {
|
|
202
203
|
rules.splice(i, 1, importRules);
|
|
203
204
|
}
|
|
@@ -236,6 +237,7 @@ Ruleset.prototype.matchCondition = function (args, context) {
|
|
|
236
237
|
Ruleset.prototype.resetCache = function () {
|
|
237
238
|
this._rulesets = null;
|
|
238
239
|
this._variables = null;
|
|
240
|
+
this._properties = null;
|
|
239
241
|
this._lookups = {};
|
|
240
242
|
};
|
|
241
243
|
Ruleset.prototype.variables = function () {
|
|
@@ -260,17 +262,81 @@ Ruleset.prototype.variables = function () {
|
|
|
260
262
|
}
|
|
261
263
|
return this._variables;
|
|
262
264
|
};
|
|
265
|
+
Ruleset.prototype.properties = function () {
|
|
266
|
+
if (!this._properties) {
|
|
267
|
+
this._properties = !this.rules ? {} : this.rules.reduce(function (hash, r) {
|
|
268
|
+
if (r instanceof Declaration && r.variable !== true) {
|
|
269
|
+
var name = (r.name.length === 1) && (r.name[0] instanceof Keyword) ?
|
|
270
|
+
r.name[0].value : r.name;
|
|
271
|
+
// Properties don't overwrite as they can merge
|
|
272
|
+
if (!hash['$' + name]) {
|
|
273
|
+
hash['$' + name] = [ r ];
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
hash['$' + name].push(r);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return hash;
|
|
280
|
+
}, {});
|
|
281
|
+
}
|
|
282
|
+
return this._properties;
|
|
283
|
+
};
|
|
263
284
|
Ruleset.prototype.variable = function (name) {
|
|
264
|
-
|
|
285
|
+
var decl = this.variables()[name];
|
|
286
|
+
if (decl) {
|
|
287
|
+
return this.parseValue(decl);
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
Ruleset.prototype.property = function (name) {
|
|
291
|
+
var decl = this.properties()[name];
|
|
292
|
+
if (decl) {
|
|
293
|
+
return this.parseValue(decl);
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
Ruleset.prototype.parseValue = function(toParse) {
|
|
297
|
+
var self = this;
|
|
298
|
+
function transformDeclaration(decl) {
|
|
299
|
+
if (decl.value instanceof Anonymous && !decl.parsed) {
|
|
300
|
+
this.parse.parseNode(
|
|
301
|
+
decl.value.value,
|
|
302
|
+
["value", "important"],
|
|
303
|
+
decl.value.getIndex(),
|
|
304
|
+
decl.fileInfo(),
|
|
305
|
+
function(err, result) {
|
|
306
|
+
if (err) {
|
|
307
|
+
decl.parsed = true;
|
|
308
|
+
}
|
|
309
|
+
if (result) {
|
|
310
|
+
decl.value = result[0];
|
|
311
|
+
decl.important = result[1] || '';
|
|
312
|
+
decl.parsed = true;
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
return decl;
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
return decl;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
if (!Array.isArray(toParse)) {
|
|
323
|
+
return transformDeclaration.call(self, toParse);
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
var nodes = [];
|
|
327
|
+
toParse.forEach(function(n) {
|
|
328
|
+
nodes.push(transformDeclaration.call(self, n));
|
|
329
|
+
});
|
|
330
|
+
return nodes;
|
|
331
|
+
}
|
|
265
332
|
};
|
|
266
333
|
Ruleset.prototype.rulesets = function () {
|
|
267
334
|
if (!this.rules) { return []; }
|
|
268
335
|
|
|
269
|
-
var filtRules = [], rules = this.rules,
|
|
336
|
+
var filtRules = [], rules = this.rules,
|
|
270
337
|
i, rule;
|
|
271
338
|
|
|
272
|
-
for (i = 0;
|
|
273
|
-
rule = rules[i];
|
|
339
|
+
for (i = 0; (rule = rules[i]); i++) {
|
|
274
340
|
if (rule.isRuleset) {
|
|
275
341
|
filtRules.push(rule);
|
|
276
342
|
}
|
|
@@ -336,41 +402,23 @@ Ruleset.prototype.genCSS = function (context, output) {
|
|
|
336
402
|
tabSetStr = context.compress ? '' : Array(context.tabLevel).join(" "),
|
|
337
403
|
sep;
|
|
338
404
|
|
|
339
|
-
function isRulesetLikeNode(rule) {
|
|
340
|
-
// if it has nested rules, then it should be treated like a ruleset
|
|
341
|
-
// medias and comments do not have nested rules, but should be treated like rulesets anyway
|
|
342
|
-
// some atrules and anonymous nodes are ruleset like, others are not
|
|
343
|
-
if (typeof rule.isRulesetLike === "boolean") {
|
|
344
|
-
return rule.isRulesetLike;
|
|
345
|
-
} else if (typeof rule.isRulesetLike === "function") {
|
|
346
|
-
return rule.isRulesetLike();
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
//anything else is assumed to be a rule
|
|
350
|
-
return false;
|
|
351
|
-
}
|
|
352
|
-
|
|
353
405
|
var charsetNodeIndex = 0;
|
|
354
406
|
var importNodeIndex = 0;
|
|
355
|
-
for (i = 0;
|
|
356
|
-
rule
|
|
357
|
-
|
|
358
|
-
if (rule instanceof Node) {
|
|
359
|
-
if (rule.type === "Comment") {
|
|
360
|
-
if (importNodeIndex === i) {
|
|
361
|
-
importNodeIndex++;
|
|
362
|
-
}
|
|
363
|
-
ruleNodes.push(rule);
|
|
364
|
-
} else if (rule.isCharset && rule.isCharset()) {
|
|
365
|
-
ruleNodes.splice(charsetNodeIndex, 0, rule);
|
|
366
|
-
charsetNodeIndex++;
|
|
407
|
+
for (i = 0; (rule = this.rules[i]); i++) {
|
|
408
|
+
if (rule instanceof Comment) {
|
|
409
|
+
if (importNodeIndex === i) {
|
|
367
410
|
importNodeIndex++;
|
|
368
|
-
} else if (rule.type === "Import") {
|
|
369
|
-
ruleNodes.splice(importNodeIndex, 0, rule);
|
|
370
|
-
importNodeIndex++;
|
|
371
|
-
} else {
|
|
372
|
-
ruleNodes.push(rule);
|
|
373
411
|
}
|
|
412
|
+
ruleNodes.push(rule);
|
|
413
|
+
} else if (rule.isCharset && rule.isCharset()) {
|
|
414
|
+
ruleNodes.splice(charsetNodeIndex, 0, rule);
|
|
415
|
+
charsetNodeIndex++;
|
|
416
|
+
importNodeIndex++;
|
|
417
|
+
} else if (rule.type === "Import") {
|
|
418
|
+
ruleNodes.splice(importNodeIndex, 0, rule);
|
|
419
|
+
importNodeIndex++;
|
|
420
|
+
} else {
|
|
421
|
+
ruleNodes.push(rule);
|
|
374
422
|
}
|
|
375
423
|
}
|
|
376
424
|
ruleNodes = charsetRuleNodes.concat(ruleNodes);
|
|
@@ -408,15 +456,14 @@ Ruleset.prototype.genCSS = function (context, output) {
|
|
|
408
456
|
}
|
|
409
457
|
|
|
410
458
|
// Compile rules and rulesets
|
|
411
|
-
for (i = 0;
|
|
412
|
-
rule = ruleNodes[i];
|
|
459
|
+
for (i = 0; (rule = ruleNodes[i]); i++) {
|
|
413
460
|
|
|
414
461
|
if (i + 1 === ruleNodes.length) {
|
|
415
462
|
context.lastRule = true;
|
|
416
463
|
}
|
|
417
464
|
|
|
418
465
|
var currentLastRule = context.lastRule;
|
|
419
|
-
if (
|
|
466
|
+
if (rule.isRulesetLike(rule)) {
|
|
420
467
|
context.lastRule = false;
|
|
421
468
|
}
|
|
422
469
|
|
|
@@ -428,7 +475,7 @@ Ruleset.prototype.genCSS = function (context, output) {
|
|
|
428
475
|
|
|
429
476
|
context.lastRule = currentLastRule;
|
|
430
477
|
|
|
431
|
-
if (!context.lastRule) {
|
|
478
|
+
if (!context.lastRule && rule.isVisible()) {
|
|
432
479
|
output.add(context.compress ? '' : ('\n' + tabRuleStr));
|
|
433
480
|
} else {
|
|
434
481
|
context.lastRule = false;
|
|
@@ -482,7 +529,7 @@ Ruleset.prototype.joinSelector = function (paths, context, selector) {
|
|
|
482
529
|
// our new selector path
|
|
483
530
|
newSelectorPath = [];
|
|
484
531
|
|
|
485
|
-
//construct the joined selector - if & is the first thing this will be empty,
|
|
532
|
+
// construct the joined selector - if & is the first thing this will be empty,
|
|
486
533
|
// if not newJoinedSelector will be the last set of elements in the selector
|
|
487
534
|
if (beginningPath.length > 0) {
|
|
488
535
|
newSelectorPath = utils.copyArray(beginningPath);
|
|
@@ -512,7 +559,7 @@ Ruleset.prototype.joinSelector = function (paths, context, selector) {
|
|
|
512
559
|
newSelectorPath.push(newJoinedSelector);
|
|
513
560
|
}
|
|
514
561
|
|
|
515
|
-
//put together the parent selectors after the join (e.g. the rest of the parent)
|
|
562
|
+
// put together the parent selectors after the join (e.g. the rest of the parent)
|
|
516
563
|
if (addPath.length > 1) {
|
|
517
564
|
var restOfPath = addPath.slice(1);
|
|
518
565
|
restOfPath = restOfPath.map(function (selector) {
|
|
@@ -546,9 +593,7 @@ Ruleset.prototype.joinSelector = function (paths, context, selector) {
|
|
|
546
593
|
return;
|
|
547
594
|
}
|
|
548
595
|
|
|
549
|
-
for (i = 0;
|
|
550
|
-
sel = selectors[i];
|
|
551
|
-
|
|
596
|
+
for (i = 0; (sel = selectors[i]); i++) {
|
|
552
597
|
// if the previous thing in sel is a parent this needs to join on to it
|
|
553
598
|
if (sel.length > 0) {
|
|
554
599
|
sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements));
|
|
@@ -576,12 +621,12 @@ Ruleset.prototype.joinSelector = function (paths, context, selector) {
|
|
|
576
621
|
var i, j, k, currentElements, newSelectors, selectorsMultiplied, sel, el, hadParentSelector = false, length, lastSelector;
|
|
577
622
|
function findNestedSelector(element) {
|
|
578
623
|
var maybeSelector;
|
|
579
|
-
if (element.value
|
|
624
|
+
if (!(element.value instanceof Paren)) {
|
|
580
625
|
return null;
|
|
581
626
|
}
|
|
582
627
|
|
|
583
628
|
maybeSelector = element.value.value;
|
|
584
|
-
if (maybeSelector
|
|
629
|
+
if (!(maybeSelector instanceof Selector)) {
|
|
585
630
|
return null;
|
|
586
631
|
}
|
|
587
632
|
|
|
@@ -597,8 +642,7 @@ Ruleset.prototype.joinSelector = function (paths, context, selector) {
|
|
|
597
642
|
[]
|
|
598
643
|
];
|
|
599
644
|
|
|
600
|
-
for (i = 0;
|
|
601
|
-
el = inSelector.elements[i];
|
|
645
|
+
for (i = 0; (el = inSelector.elements[i]); i++) {
|
|
602
646
|
// non parent reference elements just get added
|
|
603
647
|
if (el.value !== "&") {
|
|
604
648
|
var nestedSelector = findNestedSelector(el);
|
|
@@ -610,7 +654,7 @@ Ruleset.prototype.joinSelector = function (paths, context, selector) {
|
|
|
610
654
|
var nestedPaths = [], replaced, replacedNewSelectors = [];
|
|
611
655
|
replaced = replaceParentSelector(nestedPaths, context, nestedSelector);
|
|
612
656
|
hadParentSelector = hadParentSelector || replaced;
|
|
613
|
-
//the nestedPaths array should have only one member - replaceParentSelector does not multiply selectors
|
|
657
|
+
// the nestedPaths array should have only one member - replaceParentSelector does not multiply selectors
|
|
614
658
|
for (k = 0; k < nestedPaths.length; k++) {
|
|
615
659
|
var replacementSelector = createSelector(createParenthesis(nestedPaths[k], el), el);
|
|
616
660
|
addAllReplacementsIntoPath(newSelectors, [replacementSelector], el, inSelector, replacedNewSelectors);
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
var Node = require("./node"),
|
|
2
|
-
Element = require("./element")
|
|
2
|
+
Element = require("./element"),
|
|
3
|
+
LessError = require("../less-error");
|
|
3
4
|
|
|
4
5
|
var Selector = function (elements, extendList, condition, index, currentFileInfo, visibilityInfo) {
|
|
5
|
-
this.elements = elements;
|
|
6
6
|
this.extendList = extendList;
|
|
7
7
|
this.condition = condition;
|
|
8
|
+
this.evaldCondition = !condition;
|
|
8
9
|
this._index = index;
|
|
9
10
|
this._fileInfo = currentFileInfo;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
11
|
+
this.elements = this.getElements(elements);
|
|
12
|
+
this.mixinElements_ = undefined;
|
|
13
13
|
this.copyVisibilityInfo(visibilityInfo);
|
|
14
14
|
this.setParent(this.elements, this);
|
|
15
15
|
};
|
|
@@ -27,13 +27,32 @@ Selector.prototype.accept = function (visitor) {
|
|
|
27
27
|
}
|
|
28
28
|
};
|
|
29
29
|
Selector.prototype.createDerived = function(elements, extendList, evaldCondition) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
newSelector.evaldCondition = evaldCondition;
|
|
30
|
+
elements = this.getElements(elements);
|
|
31
|
+
var newSelector = new Selector(elements, extendList || this.extendList,
|
|
32
|
+
null, this.getIndex(), this.fileInfo(), this.visibilityInfo());
|
|
33
|
+
newSelector.evaldCondition = (evaldCondition != null) ? evaldCondition : this.evaldCondition;
|
|
34
34
|
newSelector.mediaEmpty = this.mediaEmpty;
|
|
35
35
|
return newSelector;
|
|
36
36
|
};
|
|
37
|
+
Selector.prototype.getElements = function(els) {
|
|
38
|
+
if (typeof els === "string") {
|
|
39
|
+
this.parse.parseNode(
|
|
40
|
+
els,
|
|
41
|
+
["selector"],
|
|
42
|
+
this._index,
|
|
43
|
+
this._fileInfo,
|
|
44
|
+
function(err, result) {
|
|
45
|
+
if (err) {
|
|
46
|
+
throw new LessError({
|
|
47
|
+
index: err.index,
|
|
48
|
+
message: err.message
|
|
49
|
+
}, this.parse.imports, this._fileInfo.filename);
|
|
50
|
+
}
|
|
51
|
+
els = result[0].elements;
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return els;
|
|
55
|
+
};
|
|
37
56
|
Selector.prototype.createEmptySelectors = function() {
|
|
38
57
|
var el = new Element('', '&', this._index, this._fileInfo),
|
|
39
58
|
sels = [new Selector([el], null, null, this._index, this._fileInfo)];
|
|
@@ -45,14 +64,13 @@ Selector.prototype.match = function (other) {
|
|
|
45
64
|
len = elements.length,
|
|
46
65
|
olen, i;
|
|
47
66
|
|
|
48
|
-
other.
|
|
49
|
-
|
|
50
|
-
olen = other._elements.length;
|
|
67
|
+
other = other.mixinElements();
|
|
68
|
+
olen = other.length;
|
|
51
69
|
if (olen === 0 || len < olen) {
|
|
52
70
|
return 0;
|
|
53
71
|
} else {
|
|
54
72
|
for (i = 0; i < olen; i++) {
|
|
55
|
-
if (elements[i].value !== other
|
|
73
|
+
if (elements[i].value !== other[i]) {
|
|
56
74
|
return 0;
|
|
57
75
|
}
|
|
58
76
|
}
|
|
@@ -60,9 +78,9 @@ Selector.prototype.match = function (other) {
|
|
|
60
78
|
|
|
61
79
|
return olen; // return number of matched elements
|
|
62
80
|
};
|
|
63
|
-
Selector.prototype.
|
|
64
|
-
if (this.
|
|
65
|
-
return;
|
|
81
|
+
Selector.prototype.mixinElements = function() {
|
|
82
|
+
if (this.mixinElements_) {
|
|
83
|
+
return this.mixinElements_;
|
|
66
84
|
}
|
|
67
85
|
|
|
68
86
|
var elements = this.elements.map( function(v) {
|
|
@@ -77,7 +95,7 @@ Selector.prototype.CacheElements = function() {
|
|
|
77
95
|
elements = [];
|
|
78
96
|
}
|
|
79
97
|
|
|
80
|
-
this.
|
|
98
|
+
return (this.mixinElements_ = elements);
|
|
81
99
|
};
|
|
82
100
|
Selector.prototype.isJustParentSelector = function() {
|
|
83
101
|
return !this.mediaEmpty &&
|
|
@@ -99,12 +117,9 @@ Selector.prototype.genCSS = function (context, output) {
|
|
|
99
117
|
if ((!context || !context.firstSelector) && this.elements[0].combinator.value === "") {
|
|
100
118
|
output.add(' ', this.fileInfo(), this.getIndex());
|
|
101
119
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
element = this.elements[i];
|
|
106
|
-
element.genCSS(context, output);
|
|
107
|
-
}
|
|
120
|
+
for (i = 0; i < this.elements.length; i++) {
|
|
121
|
+
element = this.elements[i];
|
|
122
|
+
element.genCSS(context, output);
|
|
108
123
|
}
|
|
109
124
|
};
|
|
110
125
|
Selector.prototype.getIsOutput = function() {
|
package/lib/less/tree/unit.js
CHANGED
|
@@ -65,7 +65,7 @@ Unit.prototype.usedUnits = function() {
|
|
|
65
65
|
var group, result = {}, mapUnit, groupName;
|
|
66
66
|
|
|
67
67
|
mapUnit = function (atomicUnit) {
|
|
68
|
-
/*jshint loopfunc:true */
|
|
68
|
+
/* jshint loopfunc:true */
|
|
69
69
|
if (group.hasOwnProperty(atomicUnit) && !result[groupName]) {
|
|
70
70
|
result[groupName] = atomicUnit;
|
|
71
71
|
}
|
package/lib/less/tree/value.js
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
var Node = require("./node");
|
|
2
2
|
|
|
3
3
|
var Value = function (value) {
|
|
4
|
-
this.value = value;
|
|
5
4
|
if (!value) {
|
|
6
5
|
throw new Error("Value requires an array argument");
|
|
7
6
|
}
|
|
7
|
+
if (!Array.isArray(value)) {
|
|
8
|
+
this.value = [ value ];
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
this.value = value;
|
|
12
|
+
}
|
|
8
13
|
};
|
|
9
14
|
Value.prototype = new Node();
|
|
10
15
|
Value.prototype.type = "Value";
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
var Node = require("./node"),
|
|
2
2
|
Variable = require("./variable");
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var VariableCall = function (variable) {
|
|
5
5
|
this.variable = variable;
|
|
6
6
|
this.allowRoot = true;
|
|
7
7
|
};
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
VariableCall.prototype = new Node();
|
|
9
|
+
VariableCall.prototype.type = "VariableCall";
|
|
10
|
+
VariableCall.prototype.eval = function (context) {
|
|
11
11
|
var detachedRuleset = new Variable(this.variable).eval(context);
|
|
12
12
|
return detachedRuleset.callEval(context);
|
|
13
13
|
};
|
|
14
|
-
module.exports =
|
|
14
|
+
module.exports = VariableCall;
|
|
@@ -16,9 +16,9 @@ Variable.prototype.eval = function (context) {
|
|
|
16
16
|
|
|
17
17
|
if (this.evaluating) {
|
|
18
18
|
throw { type: 'Name',
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
message: "Recursive variable definition for " + name,
|
|
20
|
+
filename: this.fileInfo().filename,
|
|
21
|
+
index: this.getIndex() };
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
this.evaluating = true;
|
|
@@ -38,9 +38,9 @@ Variable.prototype.eval = function (context) {
|
|
|
38
38
|
return variable;
|
|
39
39
|
} else {
|
|
40
40
|
throw { type: 'Name',
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
message: "variable " + name + " is undefined",
|
|
42
|
+
filename: this.fileInfo().filename,
|
|
43
|
+
index: this.getIndex() };
|
|
44
44
|
}
|
|
45
45
|
};
|
|
46
46
|
Variable.prototype.find = function (obj, fun) {
|
package/lib/less/utils.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* jshint proto: true */
|
|
1
2
|
module.exports = {
|
|
2
3
|
getLocation: function(index, inputStream) {
|
|
3
4
|
var n = index + 1,
|
|
@@ -25,5 +26,44 @@ module.exports = {
|
|
|
25
26
|
copy[i] = arr[i];
|
|
26
27
|
}
|
|
27
28
|
return copy;
|
|
29
|
+
},
|
|
30
|
+
clone: function (obj) {
|
|
31
|
+
var cloned = {};
|
|
32
|
+
for (var prop in obj) {
|
|
33
|
+
if (obj.hasOwnProperty(prop)) {
|
|
34
|
+
cloned[prop] = obj[prop];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return cloned;
|
|
38
|
+
},
|
|
39
|
+
defaults: function(obj1, obj2) {
|
|
40
|
+
if (!obj2._defaults || obj2._defaults !== obj1) {
|
|
41
|
+
for (var prop in obj1) {
|
|
42
|
+
if (obj1.hasOwnProperty(prop)) {
|
|
43
|
+
if (!obj2.hasOwnProperty(prop)) {
|
|
44
|
+
obj2[prop] = obj1[prop];
|
|
45
|
+
}
|
|
46
|
+
else if (Array.isArray(obj1[prop])
|
|
47
|
+
&& Array.isArray(obj2[prop])) {
|
|
48
|
+
|
|
49
|
+
obj1[prop].forEach(function(p) {
|
|
50
|
+
if (obj2[prop].indexOf(p) === -1) {
|
|
51
|
+
obj2[prop].push(p);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
obj2._defaults = obj1;
|
|
59
|
+
return obj2;
|
|
60
|
+
},
|
|
61
|
+
merge: function(obj1, obj2) {
|
|
62
|
+
for (var prop in obj2) {
|
|
63
|
+
if (obj2.hasOwnProperty(prop)) {
|
|
64
|
+
obj1[prop] = obj2[prop];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return obj1;
|
|
28
68
|
}
|
|
29
69
|
};
|