less 2.6.1 → 2.7.3
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/.travis.yml +3 -2
- package/CHANGELOG.md +26 -1
- package/Gruntfile.js +2 -3
- package/README.md +1 -1
- package/appveyor.yml +1 -0
- package/bin/lessc +47 -23
- package/dist/less.js +678 -374
- package/dist/less.min.js +9 -13
- package/lib/less/environment/abstract-file-manager.js +2 -2
- package/lib/less/functions/color.js +1 -1
- package/lib/less/index.js +1 -1
- package/lib/less/parser/parser-input.js +2 -2
- package/lib/less/parser/parser.js +45 -13
- package/lib/less/tree/anonymous.js +1 -1
- package/lib/less/tree/call.js +7 -4
- package/lib/less/tree/comment.js +2 -0
- package/lib/less/tree/directive.js +1 -0
- package/lib/less/tree/extend.js +1 -0
- package/lib/less/tree/import.js +1 -0
- package/lib/less/tree/media.js +1 -0
- package/lib/less/tree/mixin-call.js +1 -0
- package/lib/less/tree/mixin-definition.js +1 -0
- package/lib/less/tree/rule.js +1 -0
- package/lib/less/tree/ruleset-call.js +1 -0
- package/lib/less/tree/ruleset.js +1 -0
- package/lib/less/visitors/extend-visitor.js +5 -5
- package/lib/less/visitors/to-css-visitor.js +20 -10
- package/lib/less-browser/index.js +48 -25
- package/lib/less-node/file-manager.js +1 -1
- package/lib/less-node/lessc-helper.js +2 -2
- package/lib/source-map/source-map-0.1.31.js +1 -1
- package/package.json +25 -18
- package/test/browser/common.js +29 -8
- package/test/browser/less/console-errors/test-error.txt +1 -1
- package/test/browser/less.js +13 -17
- package/test/browser/runner-production-options.js +1 -1
- package/test/css/no-strict-math/no-sm-operations.css +3 -0
- package/test/css/operations.css +1 -1
- package/test/css/plugin.css +5 -0
- package/test/less/comments.less +1 -1
- package/test/less/errors/detached-ruleset-3.txt +1 -1
- package/test/less/errors/functions-1.less +2 -0
- package/test/less/errors/functions-1.txt +3 -0
- package/test/less/errors/functions-10-keyword.less +2 -0
- package/test/less/errors/functions-10-keyword.txt +3 -0
- package/test/less/errors/functions-11-operation.less +2 -0
- package/test/less/errors/functions-11-operation.txt +3 -0
- package/test/less/errors/functions-12-quoted.less +2 -0
- package/test/less/errors/functions-12-quoted.txt +3 -0
- package/test/less/errors/functions-13-selector.less +2 -0
- package/test/less/errors/functions-13-selector.txt +3 -0
- package/test/less/errors/functions-14-url.less +2 -0
- package/test/less/errors/functions-14-url.txt +3 -0
- package/test/less/errors/functions-15-value.less +2 -0
- package/test/less/errors/functions-15-value.txt +3 -0
- package/test/less/errors/functions-2-alpha.less +2 -0
- package/test/less/errors/functions-2-alpha.txt +3 -0
- package/test/less/errors/functions-3-assignment.less +2 -0
- package/test/less/errors/functions-3-assignment.txt +3 -0
- package/test/less/errors/functions-4-call.less +2 -0
- package/test/less/errors/functions-4-call.txt +3 -0
- package/test/less/errors/functions-5-color-2.less +1 -0
- package/test/less/errors/functions-5-color-2.txt +2 -0
- package/test/less/errors/functions-5-color.less +2 -0
- package/test/less/errors/functions-5-color.txt +3 -0
- package/test/less/errors/functions-6-condition.less +2 -0
- package/test/less/errors/functions-6-condition.txt +3 -0
- package/test/less/errors/functions-7-dimension.less +2 -0
- package/test/less/errors/functions-7-dimension.txt +3 -0
- package/test/less/errors/functions-8-element.less +2 -0
- package/test/less/errors/functions-8-element.txt +3 -0
- package/test/less/errors/functions-9-expression.less +2 -0
- package/test/less/errors/functions-9-expression.txt +3 -0
- package/test/less/errors/property-in-root.txt +1 -1
- package/test/less/errors/property-in-root2.txt +1 -1
- package/test/less/errors/property-in-root3.txt +1 -1
- package/test/less/errors/root-func-undefined-1.less +1 -0
- package/test/less/errors/root-func-undefined-1.txt +2 -0
- package/test/less/errors/root-func-undefined-2.less +2 -0
- package/test/less/errors/root-func-undefined-2.txt +3 -0
- package/test/less/extend-chaining.less +1 -1
- package/test/less/merge.less +4 -4
- package/test/less/mixins-guards.less +1 -1
- package/test/less/no-strict-math/no-sm-operations.less +4 -1
- package/test/less/operations.less +1 -1
- package/test/less/plugin/plugin-tree-nodes.js +80 -0
- package/test/less/plugin.less +8 -0
- package/test/less-bom/comments.less +1 -1
- package/test/less-bom/errors/detached-ruleset-3.txt +1 -1
- package/test/less-bom/errors/functions-1.less +2 -0
- package/test/less-bom/errors/functions-1.txt +3 -0
- package/test/less-bom/errors/functions-10-keyword.less +2 -0
- package/test/less-bom/errors/functions-10-keyword.txt +3 -0
- package/test/less-bom/errors/functions-11-operation.less +2 -0
- package/test/less-bom/errors/functions-11-operation.txt +3 -0
- package/test/less-bom/errors/functions-12-quoted.less +2 -0
- package/test/less-bom/errors/functions-12-quoted.txt +3 -0
- package/test/less-bom/errors/functions-13-selector.less +2 -0
- package/test/less-bom/errors/functions-13-selector.txt +3 -0
- package/test/less-bom/errors/functions-14-url.less +2 -0
- package/test/less-bom/errors/functions-14-url.txt +3 -0
- package/test/less-bom/errors/functions-15-value.less +2 -0
- package/test/less-bom/errors/functions-15-value.txt +3 -0
- package/test/less-bom/errors/functions-2-alpha.less +2 -0
- package/test/less-bom/errors/functions-2-alpha.txt +3 -0
- package/test/less-bom/errors/functions-3-assignment.less +2 -0
- package/test/less-bom/errors/functions-3-assignment.txt +3 -0
- package/test/less-bom/errors/functions-4-call.less +2 -0
- package/test/less-bom/errors/functions-4-call.txt +3 -0
- package/test/less-bom/errors/functions-5-color-2.less +1 -0
- package/test/less-bom/errors/functions-5-color-2.txt +2 -0
- package/test/less-bom/errors/functions-5-color.less +2 -0
- package/test/less-bom/errors/functions-5-color.txt +3 -0
- package/test/less-bom/errors/functions-6-condition.less +2 -0
- package/test/less-bom/errors/functions-6-condition.txt +3 -0
- package/test/less-bom/errors/functions-7-dimension.less +2 -0
- package/test/less-bom/errors/functions-7-dimension.txt +3 -0
- package/test/less-bom/errors/functions-8-element.less +2 -0
- package/test/less-bom/errors/functions-8-element.txt +3 -0
- package/test/less-bom/errors/functions-9-expression.less +2 -0
- package/test/less-bom/errors/functions-9-expression.txt +3 -0
- package/test/less-bom/errors/property-in-root.txt +1 -1
- package/test/less-bom/errors/property-in-root2.txt +1 -1
- package/test/less-bom/errors/property-in-root3.txt +1 -1
- package/test/less-bom/errors/root-func-undefined-1.less +1 -0
- package/test/less-bom/errors/root-func-undefined-1.txt +2 -0
- package/test/less-bom/errors/root-func-undefined-2.less +2 -0
- package/test/less-bom/errors/root-func-undefined-2.txt +3 -0
- package/test/less-bom/extend-chaining.less +1 -1
- package/test/less-bom/merge.less +4 -4
- package/test/less-bom/mixins-guards.less +1 -1
- package/test/less-bom/no-strict-math/no-sm-operations.less +4 -1
- package/test/less-bom/operations.less +1 -1
- package/test/less-bom/plugin/plugin-tree-nodes.js +80 -0
- package/test/less-bom/plugin.less +8 -0
|
@@ -67,13 +67,13 @@ abstractFileManager.prototype.pathDiff = function pathDiff(url, baseUrl) {
|
|
|
67
67
|
};
|
|
68
68
|
// helper function, not part of API
|
|
69
69
|
abstractFileManager.prototype.extractUrlParts = function extractUrlParts(url, baseUrl) {
|
|
70
|
-
// urlParts[1] = protocol
|
|
70
|
+
// urlParts[1] = protocol://hostname/ OR /
|
|
71
71
|
// urlParts[2] = / if path relative to host base
|
|
72
72
|
// urlParts[3] = directories
|
|
73
73
|
// urlParts[4] = filename
|
|
74
74
|
// urlParts[5] = parameters
|
|
75
75
|
|
|
76
|
-
var urlPartsRegex = /^((?:[a-z-]+:)
|
|
76
|
+
var urlPartsRegex = /^((?:[a-z-]+:)?\/{2}(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i,
|
|
77
77
|
urlParts = url.match(urlPartsRegex),
|
|
78
78
|
returner = {}, directories = [], i, baseUrlParts;
|
|
79
79
|
|
|
@@ -237,7 +237,7 @@ colorFunctions = {
|
|
|
237
237
|
return hsla(hsl);
|
|
238
238
|
},
|
|
239
239
|
//
|
|
240
|
-
// Copyright (c) 2006-2009 Hampton Catlin,
|
|
240
|
+
// Copyright (c) 2006-2009 Hampton Catlin, Natalie Weizenbaum, and Chris Eppstein
|
|
241
241
|
// http://sass-lang.com
|
|
242
242
|
//
|
|
243
243
|
mix: function (color1, color2, weight) {
|
package/lib/less/index.js
CHANGED
|
@@ -2,7 +2,7 @@ module.exports = function(environment, fileManagers) {
|
|
|
2
2
|
var SourceMapOutput, SourceMapBuilder, ParseTree, ImportManager, Environment;
|
|
3
3
|
|
|
4
4
|
var less = {
|
|
5
|
-
version: [2,
|
|
5
|
+
version: [2, 7, 3],
|
|
6
6
|
data: require('./data'),
|
|
7
7
|
tree: require('./tree'),
|
|
8
8
|
Environment: (Environment = require("./environment/environment")),
|
|
@@ -40,7 +40,7 @@ module.exports = function() {
|
|
|
40
40
|
nextNewLine = endIndex;
|
|
41
41
|
}
|
|
42
42
|
parserInput.i = nextNewLine;
|
|
43
|
-
comment.text = inp.substr(comment.
|
|
43
|
+
comment.text = inp.substr(comment.index, parserInput.i - comment.index);
|
|
44
44
|
parserInput.commentStore.push(comment);
|
|
45
45
|
continue;
|
|
46
46
|
} else if (nextChar === '*') {
|
|
@@ -217,7 +217,7 @@ module.exports = function() {
|
|
|
217
217
|
input = str;
|
|
218
218
|
parserInput.i = j = currentPos = furthest = 0;
|
|
219
219
|
|
|
220
|
-
// chunking
|
|
220
|
+
// chunking apparently makes things quicker (but my tests indicate
|
|
221
221
|
// it might actually make things slower in node at least)
|
|
222
222
|
// and it is a non-perfect parse - it can't recognise
|
|
223
223
|
// unquoted urls, meaning it can't distinguish comments
|
|
@@ -261,7 +261,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
261
261
|
}
|
|
262
262
|
|
|
263
263
|
node = mixin.definition() || this.rule() || this.ruleset() ||
|
|
264
|
-
mixin.call() || this.rulesetCall() || this.directive();
|
|
264
|
+
mixin.call() || this.rulesetCall() || this.entities.call() || this.directive();
|
|
265
265
|
if (node) {
|
|
266
266
|
root.push(node);
|
|
267
267
|
} else {
|
|
@@ -370,19 +370,51 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
370
370
|
return new(tree.Call)(name, args, index, fileInfo);
|
|
371
371
|
},
|
|
372
372
|
arguments: function () {
|
|
373
|
-
var
|
|
373
|
+
var argsSemiColon = [], argsComma = [],
|
|
374
|
+
expressions = [],
|
|
375
|
+
isSemiColonSeparated, value, arg;
|
|
376
|
+
|
|
377
|
+
parserInput.save();
|
|
374
378
|
|
|
375
379
|
while (true) {
|
|
376
|
-
|
|
380
|
+
|
|
381
|
+
arg = parsers.detachedRuleset() || this.assignment() || parsers.expression();
|
|
382
|
+
|
|
377
383
|
if (!arg) {
|
|
378
384
|
break;
|
|
379
385
|
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
386
|
+
|
|
387
|
+
value = arg;
|
|
388
|
+
|
|
389
|
+
if (arg.value && arg.value.length == 1) {
|
|
390
|
+
value = arg.value[0];
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
if (value) {
|
|
394
|
+
expressions.push(value);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
argsComma.push(value);
|
|
398
|
+
|
|
399
|
+
if (parserInput.$char(',')) {
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if (parserInput.$char(';') || isSemiColonSeparated) {
|
|
404
|
+
|
|
405
|
+
isSemiColonSeparated = true;
|
|
406
|
+
|
|
407
|
+
if (expressions.length > 1) {
|
|
408
|
+
value = new(tree.Value)(expressions);
|
|
409
|
+
}
|
|
410
|
+
argsSemiColon.push(value);
|
|
411
|
+
|
|
412
|
+
expressions = [];
|
|
383
413
|
}
|
|
384
414
|
}
|
|
385
|
-
|
|
415
|
+
|
|
416
|
+
parserInput.forget();
|
|
417
|
+
return isSemiColonSeparated ? argsSemiColon : argsComma;
|
|
386
418
|
},
|
|
387
419
|
literal: function () {
|
|
388
420
|
return this.dimension() ||
|
|
@@ -462,7 +494,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
462
494
|
}
|
|
463
495
|
},
|
|
464
496
|
|
|
465
|
-
// A variable entity
|
|
497
|
+
// A variable entity using the protective {} e.g. @{var}
|
|
466
498
|
variableCurly: function () {
|
|
467
499
|
var curly, index = parserInput.i;
|
|
468
500
|
|
|
@@ -497,7 +529,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
497
529
|
parserInput.save();
|
|
498
530
|
var autoCommentAbsorb = parserInput.autoCommentAbsorb;
|
|
499
531
|
parserInput.autoCommentAbsorb = false;
|
|
500
|
-
var k = parserInput.$re(/^[
|
|
532
|
+
var k = parserInput.$re(/^[_A-Za-z-][_A-Za-z0-9-]+/);
|
|
501
533
|
parserInput.autoCommentAbsorb = autoCommentAbsorb;
|
|
502
534
|
if (!k) {
|
|
503
535
|
parserInput.forget();
|
|
@@ -899,7 +931,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
899
931
|
//
|
|
900
932
|
// A Rule terminator. Note that we use `peek()` to check for '}',
|
|
901
933
|
// because the `block` rule will be expecting it, but we still need to make sure
|
|
902
|
-
// it's there, if ';' was
|
|
934
|
+
// it's there, if ';' was omitted.
|
|
903
935
|
//
|
|
904
936
|
end: function () {
|
|
905
937
|
return parserInput.$char(';') || parserInput.peek('}');
|
|
@@ -1321,10 +1353,10 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1321
1353
|
},
|
|
1322
1354
|
|
|
1323
1355
|
media: function () {
|
|
1324
|
-
var features, rules, media, debugInfo;
|
|
1356
|
+
var features, rules, media, debugInfo, index = parserInput.i;
|
|
1325
1357
|
|
|
1326
1358
|
if (context.dumpLineNumbers) {
|
|
1327
|
-
debugInfo = getDebugInfo(
|
|
1359
|
+
debugInfo = getDebugInfo(index);
|
|
1328
1360
|
}
|
|
1329
1361
|
|
|
1330
1362
|
parserInput.save();
|
|
@@ -1340,7 +1372,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1340
1372
|
|
|
1341
1373
|
parserInput.forget();
|
|
1342
1374
|
|
|
1343
|
-
media = new(tree.Media)(rules, features,
|
|
1375
|
+
media = new(tree.Media)(rules, features, index, fileInfo);
|
|
1344
1376
|
if (context.dumpLineNumbers) {
|
|
1345
1377
|
media.debugInfo = debugInfo;
|
|
1346
1378
|
}
|
|
@@ -6,7 +6,7 @@ var Anonymous = function (value, index, currentFileInfo, mapLines, rulesetLike,
|
|
|
6
6
|
this.mapLines = mapLines;
|
|
7
7
|
this.currentFileInfo = currentFileInfo;
|
|
8
8
|
this.rulesetLike = (typeof rulesetLike === 'undefined') ? false : rulesetLike;
|
|
9
|
-
|
|
9
|
+
this.allowRoot = true;
|
|
10
10
|
this.copyVisibilityInfo(visibilityInfo);
|
|
11
11
|
};
|
|
12
12
|
Anonymous.prototype = new Node();
|
package/lib/less/tree/call.js
CHANGED
|
@@ -31,18 +31,21 @@ Call.prototype.eval = function (context) {
|
|
|
31
31
|
var args = this.args.map(function (a) { return a.eval(context); }),
|
|
32
32
|
result, funcCaller = new FunctionCaller(this.name, context, this.index, this.currentFileInfo);
|
|
33
33
|
|
|
34
|
-
if (funcCaller.isValid()) {
|
|
34
|
+
if (funcCaller.isValid()) {
|
|
35
35
|
try {
|
|
36
36
|
result = funcCaller.call(args);
|
|
37
|
-
if (result != null) {
|
|
38
|
-
return result;
|
|
39
|
-
}
|
|
40
37
|
} catch (e) {
|
|
41
38
|
throw { type: e.type || "Runtime",
|
|
42
39
|
message: "error evaluating function `" + this.name + "`" +
|
|
43
40
|
(e.message ? ': ' + e.message : ''),
|
|
44
41
|
index: this.index, filename: this.currentFileInfo.filename };
|
|
45
42
|
}
|
|
43
|
+
|
|
44
|
+
if (result != null) {
|
|
45
|
+
result.index = this.index;
|
|
46
|
+
result.currentFileInfo = this.currentFileInfo;
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
return new Call(this.name, args, this.index, this.currentFileInfo);
|
package/lib/less/tree/comment.js
CHANGED
|
@@ -4,7 +4,9 @@ var Node = require("./node"),
|
|
|
4
4
|
var Comment = function (value, isLineComment, index, currentFileInfo) {
|
|
5
5
|
this.value = value;
|
|
6
6
|
this.isLineComment = isLineComment;
|
|
7
|
+
this.index = index;
|
|
7
8
|
this.currentFileInfo = currentFileInfo;
|
|
9
|
+
this.allowRoot = true;
|
|
8
10
|
};
|
|
9
11
|
Comment.prototype = new Node();
|
|
10
12
|
Comment.prototype.type = "Comment";
|
|
@@ -23,6 +23,7 @@ var Directive = function (name, value, rules, index, currentFileInfo, debugInfo,
|
|
|
23
23
|
this.debugInfo = debugInfo;
|
|
24
24
|
this.isRooted = isRooted || false;
|
|
25
25
|
this.copyVisibilityInfo(visibilityInfo);
|
|
26
|
+
this.allowRoot = true;
|
|
26
27
|
};
|
|
27
28
|
|
|
28
29
|
Directive.prototype = new Node();
|
package/lib/less/tree/extend.js
CHANGED
|
@@ -9,6 +9,7 @@ var Extend = function Extend(selector, option, index, currentFileInfo, visibilit
|
|
|
9
9
|
this.parent_ids = [this.object_id];
|
|
10
10
|
this.currentFileInfo = currentFileInfo || {};
|
|
11
11
|
this.copyVisibilityInfo(visibilityInfo);
|
|
12
|
+
this.allowRoot = true;
|
|
12
13
|
|
|
13
14
|
switch(option) {
|
|
14
15
|
case "all":
|
package/lib/less/tree/import.js
CHANGED
|
@@ -23,6 +23,7 @@ var Import = function (path, features, options, index, currentFileInfo, visibili
|
|
|
23
23
|
this.path = path;
|
|
24
24
|
this.features = features;
|
|
25
25
|
this.currentFileInfo = currentFileInfo;
|
|
26
|
+
this.allowRoot = true;
|
|
26
27
|
|
|
27
28
|
if (this.options.less !== undefined || this.options.inline) {
|
|
28
29
|
this.css = !this.options.less || this.options.inline;
|
package/lib/less/tree/media.js
CHANGED
|
@@ -15,6 +15,7 @@ var Media = function (value, features, index, currentFileInfo, visibilityInfo) {
|
|
|
15
15
|
this.rules = [new Ruleset(selectors, value)];
|
|
16
16
|
this.rules[0].allowImports = true;
|
|
17
17
|
this.copyVisibilityInfo(visibilityInfo);
|
|
18
|
+
this.allowRoot = true;
|
|
18
19
|
};
|
|
19
20
|
Media.prototype = new Directive();
|
|
20
21
|
Media.prototype.type = "Media";
|
|
@@ -9,6 +9,7 @@ var MixinCall = function (elements, args, index, currentFileInfo, important) {
|
|
|
9
9
|
this.index = index;
|
|
10
10
|
this.currentFileInfo = currentFileInfo;
|
|
11
11
|
this.important = important;
|
|
12
|
+
this.allowRoot = true;
|
|
12
13
|
};
|
|
13
14
|
MixinCall.prototype = new Node();
|
|
14
15
|
MixinCall.prototype.type = "MixinCall";
|
|
@@ -27,6 +27,7 @@ var Definition = function (name, params, rules, condition, variadic, frames, vis
|
|
|
27
27
|
this.optionalParameters = optionalParameters;
|
|
28
28
|
this.frames = frames;
|
|
29
29
|
this.copyVisibilityInfo(visibilityInfo);
|
|
30
|
+
this.allowRoot = true;
|
|
30
31
|
};
|
|
31
32
|
Definition.prototype = new Ruleset();
|
|
32
33
|
Definition.prototype.type = "MixinDefinition";
|
package/lib/less/tree/rule.js
CHANGED
|
@@ -12,6 +12,7 @@ var Rule = function (name, value, important, merge, index, currentFileInfo, inli
|
|
|
12
12
|
this.inline = inline || false;
|
|
13
13
|
this.variable = (variable !== undefined) ? variable
|
|
14
14
|
: (name.charAt && (name.charAt(0) === '@'));
|
|
15
|
+
this.allowRoot = true;
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
function evalName(context, name) {
|
package/lib/less/tree/ruleset.js
CHANGED
|
@@ -14,6 +14,7 @@ var Ruleset = function (selectors, rules, strictImports, visibilityInfo) {
|
|
|
14
14
|
this._lookups = {};
|
|
15
15
|
this.strictImports = strictImports;
|
|
16
16
|
this.copyVisibilityInfo(visibilityInfo);
|
|
17
|
+
this.allowRoot = true;
|
|
17
18
|
};
|
|
18
19
|
Ruleset.prototype = new Node();
|
|
19
20
|
Ruleset.prototype.type = "Ruleset";
|
|
@@ -95,7 +95,7 @@ var ProcessExtendsVisitor = function() {
|
|
|
95
95
|
ProcessExtendsVisitor.prototype = {
|
|
96
96
|
run: function(root) {
|
|
97
97
|
var extendFinder = new ExtendFinderVisitor();
|
|
98
|
-
this.
|
|
98
|
+
this.extendIndices = {};
|
|
99
99
|
extendFinder.run(root);
|
|
100
100
|
if (!extendFinder.foundExtends) { return root; }
|
|
101
101
|
root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends));
|
|
@@ -105,7 +105,7 @@ ProcessExtendsVisitor.prototype = {
|
|
|
105
105
|
return newRoot;
|
|
106
106
|
},
|
|
107
107
|
checkExtendsForNonMatched: function(extendList) {
|
|
108
|
-
var
|
|
108
|
+
var indices = this.extendIndices;
|
|
109
109
|
extendList.filter(function(extend) {
|
|
110
110
|
return !extend.hasFoundMatches && extend.parent_ids.length == 1;
|
|
111
111
|
}).forEach(function(extend) {
|
|
@@ -115,8 +115,8 @@ ProcessExtendsVisitor.prototype = {
|
|
|
115
115
|
}
|
|
116
116
|
catch(_) {}
|
|
117
117
|
|
|
118
|
-
if (!
|
|
119
|
-
|
|
118
|
+
if (!indices[extend.index + ' ' + selector]) {
|
|
119
|
+
indices[extend.index + ' ' + selector] = true;
|
|
120
120
|
logger.warn("extend '" + selector + "' has no matches");
|
|
121
121
|
}
|
|
122
122
|
});
|
|
@@ -140,7 +140,7 @@ ProcessExtendsVisitor.prototype = {
|
|
|
140
140
|
// a target extend is the one on the ruleset we are looking at copy/edit/pasting in place
|
|
141
141
|
// e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one
|
|
142
142
|
// and the second is the target.
|
|
143
|
-
// the
|
|
143
|
+
// the separation into two lists allows us to process a subset of chains with a bigger set, as is the
|
|
144
144
|
// case when processing media queries
|
|
145
145
|
for (extendIndex = 0; extendIndex < extendsList.length; extendIndex++) {
|
|
146
146
|
for (targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++) {
|
|
@@ -144,7 +144,6 @@ ToCSSVisitor.prototype = {
|
|
|
144
144
|
} else {
|
|
145
145
|
return this.visitDirectiveWithoutBody(directiveNode, visitArgs);
|
|
146
146
|
}
|
|
147
|
-
return directiveNode;
|
|
148
147
|
},
|
|
149
148
|
|
|
150
149
|
visitDirectiveWithBody: function(directiveNode, visitArgs) {
|
|
@@ -199,13 +198,24 @@ ToCSSVisitor.prototype = {
|
|
|
199
198
|
return directiveNode;
|
|
200
199
|
},
|
|
201
200
|
|
|
202
|
-
|
|
203
|
-
|
|
201
|
+
checkValidNodes: function(rules, isRoot) {
|
|
202
|
+
if (!rules) {
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
|
|
204
206
|
for (var i = 0; i < rules.length; i++) {
|
|
205
|
-
ruleNode = rules[i];
|
|
206
|
-
if (ruleNode instanceof tree.Rule && !ruleNode.variable) {
|
|
207
|
-
throw { message: "
|
|
208
|
-
index: ruleNode.index, filename: ruleNode.currentFileInfo
|
|
207
|
+
var ruleNode = rules[i];
|
|
208
|
+
if (isRoot && ruleNode instanceof tree.Rule && !ruleNode.variable) {
|
|
209
|
+
throw { message: "Properties must be inside selector blocks. They cannot be in the root",
|
|
210
|
+
index: ruleNode.index, filename: ruleNode.currentFileInfo && ruleNode.currentFileInfo.filename};
|
|
211
|
+
}
|
|
212
|
+
if (ruleNode instanceof tree.Call) {
|
|
213
|
+
throw { message: "Function '" + ruleNode.name + "' is undefined",
|
|
214
|
+
index: ruleNode.index, filename: ruleNode.currentFileInfo && ruleNode.currentFileInfo.filename};
|
|
215
|
+
}
|
|
216
|
+
if (ruleNode.type && !ruleNode.allowRoot) {
|
|
217
|
+
throw { message: ruleNode.type + " node returned by a function is not valid here",
|
|
218
|
+
index: ruleNode.index, filename: ruleNode.currentFileInfo && ruleNode.currentFileInfo.filename};
|
|
209
219
|
}
|
|
210
220
|
}
|
|
211
221
|
},
|
|
@@ -213,9 +223,9 @@ ToCSSVisitor.prototype = {
|
|
|
213
223
|
visitRuleset: function (rulesetNode, visitArgs) {
|
|
214
224
|
//at this point rulesets are nested into each other
|
|
215
225
|
var rule, rulesets = [];
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
226
|
+
|
|
227
|
+
this.checkValidNodes(rulesetNode.rules, rulesetNode.firstRoot);
|
|
228
|
+
|
|
219
229
|
if (! rulesetNode.root) {
|
|
220
230
|
//remove invisible paths
|
|
221
231
|
this._compileRulesetPaths(rulesetNode);
|
|
@@ -225,34 +225,57 @@ module.exports = function(window, options) {
|
|
|
225
225
|
fileManager.clearFileCache();
|
|
226
226
|
}
|
|
227
227
|
return new Promise(function (resolve, reject) {
|
|
228
|
-
var startTime, endTime, totalMilliseconds;
|
|
228
|
+
var startTime, endTime, totalMilliseconds, remainingSheets;
|
|
229
229
|
startTime = endTime = new Date();
|
|
230
230
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
}
|
|
237
|
-
if (webInfo.local) {
|
|
238
|
-
less.logger.info("loading " + sheet.href + " from cache.");
|
|
239
|
-
} else {
|
|
240
|
-
less.logger.info("rendered " + sheet.href + " successfully.");
|
|
241
|
-
}
|
|
242
|
-
browser.createCSS(window.document, css, sheet);
|
|
243
|
-
less.logger.info("css for " + sheet.href + " generated in " + (new Date() - endTime) + 'ms');
|
|
244
|
-
if (webInfo.remaining === 0) {
|
|
245
|
-
totalMilliseconds = new Date() - startTime;
|
|
246
|
-
less.logger.info("less has finished. css generated in " + totalMilliseconds + 'ms');
|
|
247
|
-
resolve({
|
|
248
|
-
startTime: startTime,
|
|
249
|
-
endTime: endTime,
|
|
250
|
-
totalMilliseconds: totalMilliseconds,
|
|
251
|
-
sheets: less.sheets.length
|
|
252
|
-
});
|
|
253
|
-
}
|
|
231
|
+
// Set counter for remaining unprocessed sheets
|
|
232
|
+
remainingSheets = less.sheets.length;
|
|
233
|
+
|
|
234
|
+
if (remainingSheets === 0) {
|
|
235
|
+
|
|
254
236
|
endTime = new Date();
|
|
255
|
-
|
|
237
|
+
totalMilliseconds = endTime - startTime;
|
|
238
|
+
less.logger.info("Less has finished and no sheets were loaded.");
|
|
239
|
+
resolve({
|
|
240
|
+
startTime: startTime,
|
|
241
|
+
endTime: endTime,
|
|
242
|
+
totalMilliseconds: totalMilliseconds,
|
|
243
|
+
sheets: less.sheets.length
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
} else {
|
|
247
|
+
// Relies on less.sheets array, callback seems to be guaranteed to be called for every element of the array
|
|
248
|
+
loadStyleSheets(function (e, css, _, sheet, webInfo) {
|
|
249
|
+
if (e) {
|
|
250
|
+
errors.add(e, e.href || sheet.href);
|
|
251
|
+
reject(e);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
if (webInfo.local) {
|
|
255
|
+
less.logger.info("Loading " + sheet.href + " from cache.");
|
|
256
|
+
} else {
|
|
257
|
+
less.logger.info("Rendered " + sheet.href + " successfully.");
|
|
258
|
+
}
|
|
259
|
+
browser.createCSS(window.document, css, sheet);
|
|
260
|
+
less.logger.info("CSS for " + sheet.href + " generated in " + (new Date() - endTime) + 'ms');
|
|
261
|
+
|
|
262
|
+
// Count completed sheet
|
|
263
|
+
remainingSheets--;
|
|
264
|
+
|
|
265
|
+
// Check if the last remaining sheet was processed and then call the promise
|
|
266
|
+
if (remainingSheets === 0) {
|
|
267
|
+
totalMilliseconds = new Date() - startTime;
|
|
268
|
+
less.logger.info("Less has finished. CSS generated in " + totalMilliseconds + 'ms');
|
|
269
|
+
resolve({
|
|
270
|
+
startTime: startTime,
|
|
271
|
+
endTime: endTime,
|
|
272
|
+
totalMilliseconds: totalMilliseconds,
|
|
273
|
+
sheets: less.sheets.length
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
endTime = new Date();
|
|
277
|
+
}, reload, modifyVars);
|
|
278
|
+
}
|
|
256
279
|
|
|
257
280
|
loadStyles(modifyVars);
|
|
258
281
|
});
|
|
@@ -38,7 +38,7 @@ FileManager.prototype.loadFile = function(filename, currentDirectory, options, e
|
|
|
38
38
|
if (options.paths) { paths.push.apply(paths, options.paths); }
|
|
39
39
|
if (!isAbsoluteFilename && paths.indexOf('.') === -1) { paths.push('.'); }
|
|
40
40
|
|
|
41
|
-
// promise is
|
|
41
|
+
// promise is guaranteed to be asyncronous
|
|
42
42
|
// which helps as it allows the file handle
|
|
43
43
|
// to be closed before it continues with the next file
|
|
44
44
|
return new PromiseConstructor(function(fulfill, reject) {
|
|
@@ -15,8 +15,8 @@ var lessc_helper = {
|
|
|
15
15
|
'red' : [31, 39],
|
|
16
16
|
'grey' : [90, 39]
|
|
17
17
|
};
|
|
18
|
-
return '\
|
|
19
|
-
'\
|
|
18
|
+
return '\x1b[' + styles[style][0] + 'm' + str +
|
|
19
|
+
'\x1b[' + styles[style][1] + 'm';
|
|
20
20
|
},
|
|
21
21
|
|
|
22
22
|
//Print command line options
|
|
@@ -1338,7 +1338,7 @@ define('source-map/source-map-consumer', ['require', 'exports', 'module' , 'sou
|
|
|
1338
1338
|
/**
|
|
1339
1339
|
* Returns the original source content. The only argument is the url of the
|
|
1340
1340
|
* original source file. Returns null if no original source content is
|
|
1341
|
-
*
|
|
1341
|
+
* available.
|
|
1342
1342
|
*/
|
|
1343
1343
|
SourceMapConsumer.prototype.sourceContentFor =
|
|
1344
1344
|
function SourceMapConsumer_sourceContentFor(aSource) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "less",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.3",
|
|
4
4
|
"description": "Leaner CSS",
|
|
5
5
|
"homepage": "http://lesscss.org",
|
|
6
6
|
"author": {
|
|
@@ -17,6 +17,10 @@
|
|
|
17
17
|
"type": "git",
|
|
18
18
|
"url": "https://github.com/less/less.js.git"
|
|
19
19
|
},
|
|
20
|
+
"master": {
|
|
21
|
+
"url": "https://github.com/less/less.js/blob/master/",
|
|
22
|
+
"raw": "https://raw.githubusercontent.com/less/less.js/master/"
|
|
23
|
+
},
|
|
20
24
|
"license": "Apache-2.0",
|
|
21
25
|
"bin": {
|
|
22
26
|
"lessc": "./bin/lessc"
|
|
@@ -30,7 +34,7 @@
|
|
|
30
34
|
},
|
|
31
35
|
"browser": "./dist/less.js",
|
|
32
36
|
"engines": {
|
|
33
|
-
"node": ">=0.
|
|
37
|
+
"node": ">=0.12"
|
|
34
38
|
},
|
|
35
39
|
"scripts": {
|
|
36
40
|
"test": "grunt test"
|
|
@@ -38,28 +42,29 @@
|
|
|
38
42
|
"optionalDependencies": {
|
|
39
43
|
"errno": "^0.1.1",
|
|
40
44
|
"graceful-fs": "^4.1.2",
|
|
41
|
-
"image-size": "~0.
|
|
45
|
+
"image-size": "~0.5.0",
|
|
42
46
|
"mime": "^1.2.11",
|
|
43
47
|
"mkdirp": "^0.5.0",
|
|
44
48
|
"promise": "^7.1.1",
|
|
45
|
-
"
|
|
46
|
-
"
|
|
49
|
+
"source-map": "^0.5.3",
|
|
50
|
+
"request": "2.81.0"
|
|
47
51
|
},
|
|
48
52
|
"devDependencies": {
|
|
49
|
-
"diff": "^2.2.
|
|
50
|
-
"grunt": "
|
|
53
|
+
"diff": "^2.2.2",
|
|
54
|
+
"grunt": "~0.4.5",
|
|
55
|
+
"grunt-browserify": "^5.0.0",
|
|
51
56
|
"grunt-contrib-clean": "^1.0.0",
|
|
52
|
-
"grunt-contrib-concat": "^1.0.
|
|
53
|
-
"grunt-contrib-connect": "^0.
|
|
54
|
-
"grunt-contrib-jasmine": "^1.0.
|
|
57
|
+
"grunt-contrib-concat": "^1.0.1",
|
|
58
|
+
"grunt-contrib-connect": "^1.0.2",
|
|
59
|
+
"grunt-contrib-jasmine": "^1.0.3",
|
|
55
60
|
"grunt-contrib-jshint": "^1.0.0",
|
|
56
|
-
"grunt-contrib-uglify": "^0.
|
|
57
|
-
"grunt-jscs": "^2.
|
|
58
|
-
"grunt-
|
|
59
|
-
"grunt-
|
|
60
|
-
"jit-grunt": "^0.
|
|
61
|
-
"
|
|
62
|
-
"grunt
|
|
61
|
+
"grunt-contrib-uglify": "^1.0.1",
|
|
62
|
+
"grunt-jscs": "^2.8.0",
|
|
63
|
+
"grunt-saucelabs": "^8.6.2",
|
|
64
|
+
"grunt-shell": "^1.3.0",
|
|
65
|
+
"jit-grunt": "^0.10.0",
|
|
66
|
+
"phantomjs-prebuilt": "^2.1.7",
|
|
67
|
+
"time-grunt": "^1.3.0"
|
|
63
68
|
},
|
|
64
69
|
"keywords": [
|
|
65
70
|
"compile less",
|
|
@@ -85,5 +90,7 @@
|
|
|
85
90
|
"stylesheet",
|
|
86
91
|
"variables in css",
|
|
87
92
|
"css less"
|
|
88
|
-
]
|
|
93
|
+
],
|
|
94
|
+
"rawcurrent": "https://raw.github.com/less/less.js/v",
|
|
95
|
+
"sourcearchive": "https://github.com/less/less.js/archive/v"
|
|
89
96
|
}
|
package/test/browser/common.js
CHANGED
|
@@ -6,19 +6,40 @@ jasmine.getEnv().addReporter(new jasmine.JSReporter2());
|
|
|
6
6
|
|
|
7
7
|
var logMessages = [];
|
|
8
8
|
window.less = window.less || {};
|
|
9
|
+
|
|
10
|
+
var logLevel_debug = 4,
|
|
11
|
+
logLevel_info = 3,
|
|
12
|
+
logLevel_warn = 2,
|
|
13
|
+
logLevel_error = 1;
|
|
14
|
+
|
|
15
|
+
// The amount of logging in the javascript console.
|
|
16
|
+
// 3 - Debug, information and errors
|
|
17
|
+
// 2 - Information and errors
|
|
18
|
+
// 1 - Errors
|
|
19
|
+
// 0 - None
|
|
20
|
+
// Defaults to 2
|
|
21
|
+
|
|
9
22
|
less.loggers = [
|
|
10
23
|
{
|
|
11
|
-
|
|
12
|
-
|
|
24
|
+
debug: function(msg) {
|
|
25
|
+
if (less.options.logLevel >= logLevel_debug) {
|
|
26
|
+
logMessages.push(msg);
|
|
27
|
+
}
|
|
13
28
|
},
|
|
14
|
-
|
|
15
|
-
|
|
29
|
+
info: function(msg) {
|
|
30
|
+
if (less.options.logLevel >= logLevel_info) {
|
|
31
|
+
logMessages.push(msg);
|
|
32
|
+
}
|
|
16
33
|
},
|
|
17
|
-
warn: function
|
|
18
|
-
|
|
34
|
+
warn: function(msg) {
|
|
35
|
+
if (less.options.logLevel >= logLevel_warn) {
|
|
36
|
+
logMessages.push(msg);
|
|
37
|
+
}
|
|
19
38
|
},
|
|
20
|
-
error: function
|
|
21
|
-
|
|
39
|
+
error: function(msg) {
|
|
40
|
+
if (less.options.logLevel >= logLevel_error) {
|
|
41
|
+
logMessages.push(msg);
|
|
42
|
+
}
|
|
22
43
|
}
|
|
23
44
|
}
|
|
24
45
|
];
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
less: OperationError: Can't
|
|
1
|
+
less: OperationError: Can't subtract or divide a color from a number in {pathhref}console-errors/test-error.less on line null, column 0:
|
|
2
2
|
1 prop: (3 / #fff);
|