less 2.6.0 → 2.7.2
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 +30 -2
- package/Gruntfile.js +2 -3
- package/README.md +2 -2
- package/appveyor.yml +1 -0
- package/bin/lessc +47 -23
- package/dist/less.js +914 -582
- package/dist/less.min.js +9 -12
- package/lib/less/environment/abstract-file-manager.js +2 -2
- package/lib/less/functions/color.js +6 -3
- package/lib/less/index.js +1 -1
- package/lib/less/parser/parser-input.js +69 -69
- package/lib/less/parser/parser.js +111 -51
- 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 +2 -1
- package/lib/less/tree/rule.js +1 -0
- package/lib/less/tree/ruleset-call.js +1 -0
- package/lib/less/tree/ruleset.js +86 -85
- package/lib/less/tree/unit.js +2 -2
- package/lib/less/visitors/extend-visitor.js +5 -5
- package/lib/less/visitors/to-css-visitor.js +20 -10
- package/lib/less-browser/error-reporting.js +10 -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 +29 -22
- package/test/browser/common.js +29 -8
- package/test/browser/less/console-errors/test-error.txt +1 -1
- package/test/browser/less.js +13 -16
- package/test/browser/runner-production-options.js +1 -1
- package/test/css/comments2.css +6 -0
- package/test/css/no-strict-math/mixins-guards.css +12 -0
- 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/comments2.less +11 -0
- 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/mixins-guards.less +25 -0
- 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/comments2.less +11 -0
- 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/mixins-guards.less +25 -0
- 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
- package/test/sourcemaps/maps/import-map.map +1 -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
|
|
|
@@ -43,6 +43,9 @@ colorFunctions = {
|
|
|
43
43
|
return colorFunctions.hsla(h, s, l, 1.0);
|
|
44
44
|
},
|
|
45
45
|
hsla: function (h, s, l, a) {
|
|
46
|
+
|
|
47
|
+
var m1, m2;
|
|
48
|
+
|
|
46
49
|
function hue(h) {
|
|
47
50
|
h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
|
|
48
51
|
if (h * 6 < 1) {
|
|
@@ -62,8 +65,8 @@ colorFunctions = {
|
|
|
62
65
|
h = (number(h) % 360) / 360;
|
|
63
66
|
s = clamp(number(s)); l = clamp(number(l)); a = clamp(number(a));
|
|
64
67
|
|
|
65
|
-
|
|
66
|
-
|
|
68
|
+
m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
|
|
69
|
+
m1 = l * 2 - m2;
|
|
67
70
|
|
|
68
71
|
return colorFunctions.rgba(hue(h + 1 / 3) * 255,
|
|
69
72
|
hue(h) * 255,
|
|
@@ -234,7 +237,7 @@ colorFunctions = {
|
|
|
234
237
|
return hsla(hsl);
|
|
235
238
|
},
|
|
236
239
|
//
|
|
237
|
-
// Copyright (c) 2006-2009 Hampton Catlin,
|
|
240
|
+
// Copyright (c) 2006-2009 Hampton Catlin, Natalie Weizenbaum, and Chris Eppstein
|
|
238
241
|
// http://sass-lang.com
|
|
239
242
|
//
|
|
240
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, 2],
|
|
6
6
|
data: require('./data'),
|
|
7
7
|
tree: require('./tree'),
|
|
8
8
|
Environment: (Environment = require("./environment/environment")),
|
|
@@ -11,6 +11,74 @@ module.exports = function() {
|
|
|
11
11
|
currentPos, // index of current chunk, in `input`
|
|
12
12
|
parserInput = {};
|
|
13
13
|
|
|
14
|
+
var CHARCODE_SPACE = 32,
|
|
15
|
+
CHARCODE_TAB = 9,
|
|
16
|
+
CHARCODE_LF = 10,
|
|
17
|
+
CHARCODE_CR = 13,
|
|
18
|
+
CHARCODE_PLUS = 43,
|
|
19
|
+
CHARCODE_COMMA = 44,
|
|
20
|
+
CHARCODE_FORWARD_SLASH = 47,
|
|
21
|
+
CHARCODE_9 = 57;
|
|
22
|
+
|
|
23
|
+
function skipWhitespace(length) {
|
|
24
|
+
var oldi = parserInput.i, oldj = j,
|
|
25
|
+
curr = parserInput.i - currentPos,
|
|
26
|
+
endIndex = parserInput.i + current.length - curr,
|
|
27
|
+
mem = (parserInput.i += length),
|
|
28
|
+
inp = input,
|
|
29
|
+
c, nextChar, comment;
|
|
30
|
+
|
|
31
|
+
for (; parserInput.i < endIndex; parserInput.i++) {
|
|
32
|
+
c = inp.charCodeAt(parserInput.i);
|
|
33
|
+
|
|
34
|
+
if (parserInput.autoCommentAbsorb && c === CHARCODE_FORWARD_SLASH) {
|
|
35
|
+
nextChar = inp.charAt(parserInput.i + 1);
|
|
36
|
+
if (nextChar === '/') {
|
|
37
|
+
comment = {index: parserInput.i, isLineComment: true};
|
|
38
|
+
var nextNewLine = inp.indexOf("\n", parserInput.i + 2);
|
|
39
|
+
if (nextNewLine < 0) {
|
|
40
|
+
nextNewLine = endIndex;
|
|
41
|
+
}
|
|
42
|
+
parserInput.i = nextNewLine;
|
|
43
|
+
comment.text = inp.substr(comment.index, parserInput.i - comment.index);
|
|
44
|
+
parserInput.commentStore.push(comment);
|
|
45
|
+
continue;
|
|
46
|
+
} else if (nextChar === '*') {
|
|
47
|
+
var nextStarSlash = inp.indexOf("*/", parserInput.i + 2);
|
|
48
|
+
if (nextStarSlash >= 0) {
|
|
49
|
+
comment = {
|
|
50
|
+
index: parserInput.i,
|
|
51
|
+
text: inp.substr(parserInput.i, nextStarSlash + 2 - parserInput.i),
|
|
52
|
+
isLineComment: false
|
|
53
|
+
};
|
|
54
|
+
parserInput.i += comment.text.length - 1;
|
|
55
|
+
parserInput.commentStore.push(comment);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if ((c !== CHARCODE_SPACE) && (c !== CHARCODE_LF) && (c !== CHARCODE_TAB) && (c !== CHARCODE_CR)) {
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
current = current.slice(length + parserInput.i - mem + curr);
|
|
68
|
+
currentPos = parserInput.i;
|
|
69
|
+
|
|
70
|
+
if (!current.length) {
|
|
71
|
+
if (j < chunks.length - 1) {
|
|
72
|
+
current = chunks[++j];
|
|
73
|
+
skipWhitespace(0); // skip space at the beginning of a chunk
|
|
74
|
+
return true; // things changed
|
|
75
|
+
}
|
|
76
|
+
parserInput.finished = true;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return oldi !== parserInput.i || oldj !== j;
|
|
80
|
+
}
|
|
81
|
+
|
|
14
82
|
parserInput.save = function() {
|
|
15
83
|
currentPos = parserInput.i;
|
|
16
84
|
saveStack.push( { current: current, i: parserInput.i, j: j });
|
|
@@ -105,78 +173,10 @@ module.exports = function() {
|
|
|
105
173
|
return null;
|
|
106
174
|
};
|
|
107
175
|
|
|
108
|
-
var CHARCODE_SPACE = 32,
|
|
109
|
-
CHARCODE_TAB = 9,
|
|
110
|
-
CHARCODE_LF = 10,
|
|
111
|
-
CHARCODE_CR = 13,
|
|
112
|
-
CHARCODE_PLUS = 43,
|
|
113
|
-
CHARCODE_COMMA = 44,
|
|
114
|
-
CHARCODE_FORWARD_SLASH = 47,
|
|
115
|
-
CHARCODE_9 = 57;
|
|
116
|
-
|
|
117
176
|
parserInput.autoCommentAbsorb = true;
|
|
118
177
|
parserInput.commentStore = [];
|
|
119
178
|
parserInput.finished = false;
|
|
120
179
|
|
|
121
|
-
var skipWhitespace = function(length) {
|
|
122
|
-
var oldi = parserInput.i, oldj = j,
|
|
123
|
-
curr = parserInput.i - currentPos,
|
|
124
|
-
endIndex = parserInput.i + current.length - curr,
|
|
125
|
-
mem = (parserInput.i += length),
|
|
126
|
-
inp = input,
|
|
127
|
-
c, nextChar, comment;
|
|
128
|
-
|
|
129
|
-
for (; parserInput.i < endIndex; parserInput.i++) {
|
|
130
|
-
c = inp.charCodeAt(parserInput.i);
|
|
131
|
-
|
|
132
|
-
if (parserInput.autoCommentAbsorb && c === CHARCODE_FORWARD_SLASH) {
|
|
133
|
-
nextChar = inp.charAt(parserInput.i + 1);
|
|
134
|
-
if (nextChar === '/') {
|
|
135
|
-
comment = {index: parserInput.i, isLineComment: true};
|
|
136
|
-
var nextNewLine = inp.indexOf("\n", parserInput.i + 2);
|
|
137
|
-
if (nextNewLine < 0) {
|
|
138
|
-
nextNewLine = endIndex;
|
|
139
|
-
}
|
|
140
|
-
parserInput.i = nextNewLine;
|
|
141
|
-
comment.text = inp.substr(comment.i, parserInput.i - comment.i);
|
|
142
|
-
parserInput.commentStore.push(comment);
|
|
143
|
-
continue;
|
|
144
|
-
} else if (nextChar === '*') {
|
|
145
|
-
var nextStarSlash = inp.indexOf("*/", parserInput.i + 2);
|
|
146
|
-
if (nextStarSlash >= 0) {
|
|
147
|
-
comment = {
|
|
148
|
-
index: parserInput.i,
|
|
149
|
-
text: inp.substr(parserInput.i, nextStarSlash + 2 - parserInput.i),
|
|
150
|
-
isLineComment: false
|
|
151
|
-
};
|
|
152
|
-
parserInput.i += comment.text.length - 1;
|
|
153
|
-
parserInput.commentStore.push(comment);
|
|
154
|
-
continue;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
break;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
if ((c !== CHARCODE_SPACE) && (c !== CHARCODE_LF) && (c !== CHARCODE_TAB) && (c !== CHARCODE_CR)) {
|
|
161
|
-
break;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
current = current.slice(length + parserInput.i - mem + curr);
|
|
166
|
-
currentPos = parserInput.i;
|
|
167
|
-
|
|
168
|
-
if (!current.length) {
|
|
169
|
-
if (j < chunks.length - 1) {
|
|
170
|
-
current = chunks[++j];
|
|
171
|
-
skipWhitespace(0); // skip space at the beginning of a chunk
|
|
172
|
-
return true; // things changed
|
|
173
|
-
}
|
|
174
|
-
parserInput.finished = true;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
return oldi !== parserInput.i || oldj !== j;
|
|
178
|
-
};
|
|
179
|
-
|
|
180
180
|
// Same as $(), but don't change the state of the parser,
|
|
181
181
|
// just return the match.
|
|
182
182
|
parserInput.peek = function(tok) {
|
|
@@ -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
|
|
@@ -41,9 +41,21 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
41
41
|
var parsers,
|
|
42
42
|
parserInput = getParserInput();
|
|
43
43
|
|
|
44
|
+
function error(msg, type) {
|
|
45
|
+
throw new LessError(
|
|
46
|
+
{
|
|
47
|
+
index: parserInput.i,
|
|
48
|
+
filename: fileInfo.filename,
|
|
49
|
+
type: type || 'Syntax',
|
|
50
|
+
message: msg
|
|
51
|
+
},
|
|
52
|
+
imports
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
44
56
|
function expect(arg, msg, index) {
|
|
45
57
|
// some older browsers return typeof 'function' for RegExp
|
|
46
|
-
var result = (
|
|
58
|
+
var result = (arg instanceof Function) ? arg.call(parsers) : parserInput.$re(arg);
|
|
47
59
|
if (result) {
|
|
48
60
|
return result;
|
|
49
61
|
}
|
|
@@ -59,18 +71,6 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
59
71
|
error(msg || "expected '" + arg + "' got '" + parserInput.currentChar() + "'");
|
|
60
72
|
}
|
|
61
73
|
|
|
62
|
-
function error(msg, type) {
|
|
63
|
-
throw new LessError(
|
|
64
|
-
{
|
|
65
|
-
index: parserInput.i,
|
|
66
|
-
filename: fileInfo.filename,
|
|
67
|
-
type: type || 'Syntax',
|
|
68
|
-
message: msg
|
|
69
|
-
},
|
|
70
|
-
imports
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
74
|
function getDebugInfo(index) {
|
|
75
75
|
var filename = fileInfo.filename;
|
|
76
76
|
|
|
@@ -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 {
|
|
@@ -325,26 +325,6 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
325
325
|
}
|
|
326
326
|
},
|
|
327
327
|
|
|
328
|
-
namedColor: function () {
|
|
329
|
-
parserInput.save();
|
|
330
|
-
var autoCommentAbsorb = parserInput.autoCommentAbsorb;
|
|
331
|
-
parserInput.autoCommentAbsorb = false;
|
|
332
|
-
var k = parserInput.$re(/^[_A-Za-z-][_A-Za-z0-9-]*/);
|
|
333
|
-
parserInput.autoCommentAbsorb = autoCommentAbsorb;
|
|
334
|
-
if (!k) {
|
|
335
|
-
parserInput.forget();
|
|
336
|
-
return ;
|
|
337
|
-
}
|
|
338
|
-
var result = tree.Color.fromKeyword(k);
|
|
339
|
-
if (!result) {
|
|
340
|
-
parserInput.restore();
|
|
341
|
-
} else {
|
|
342
|
-
parserInput.forget();
|
|
343
|
-
return result;
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
},
|
|
347
|
-
|
|
348
328
|
//
|
|
349
329
|
// A function call
|
|
350
330
|
//
|
|
@@ -390,19 +370,51 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
390
370
|
return new(tree.Call)(name, args, index, fileInfo);
|
|
391
371
|
},
|
|
392
372
|
arguments: function () {
|
|
393
|
-
var
|
|
373
|
+
var argsSemiColon = [], argsComma = [],
|
|
374
|
+
expressions = [],
|
|
375
|
+
isSemiColonSeparated, value, arg;
|
|
376
|
+
|
|
377
|
+
parserInput.save();
|
|
394
378
|
|
|
395
379
|
while (true) {
|
|
396
|
-
|
|
380
|
+
|
|
381
|
+
arg = parsers.detachedRuleset() || this.assignment() || parsers.expression();
|
|
382
|
+
|
|
397
383
|
if (!arg) {
|
|
398
384
|
break;
|
|
399
385
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
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 = [];
|
|
403
413
|
}
|
|
404
414
|
}
|
|
405
|
-
|
|
415
|
+
|
|
416
|
+
parserInput.forget();
|
|
417
|
+
return isSemiColonSeparated ? argsSemiColon : argsComma;
|
|
406
418
|
},
|
|
407
419
|
literal: function () {
|
|
408
420
|
return this.dimension() ||
|
|
@@ -482,7 +494,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
482
494
|
}
|
|
483
495
|
},
|
|
484
496
|
|
|
485
|
-
// A variable entity
|
|
497
|
+
// A variable entity using the protective {} e.g. @{var}
|
|
486
498
|
variableCurly: function () {
|
|
487
499
|
var curly, index = parserInput.i;
|
|
488
500
|
|
|
@@ -511,8 +523,24 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
511
523
|
}
|
|
512
524
|
return new(tree.Color)(rgb[1], undefined, '#' + colorCandidateString);
|
|
513
525
|
}
|
|
526
|
+
},
|
|
514
527
|
|
|
515
|
-
|
|
528
|
+
colorKeyword: function () {
|
|
529
|
+
parserInput.save();
|
|
530
|
+
var autoCommentAbsorb = parserInput.autoCommentAbsorb;
|
|
531
|
+
parserInput.autoCommentAbsorb = false;
|
|
532
|
+
var k = parserInput.$re(/^[_A-Za-z-][_A-Za-z0-9-]+/);
|
|
533
|
+
parserInput.autoCommentAbsorb = autoCommentAbsorb;
|
|
534
|
+
if (!k) {
|
|
535
|
+
parserInput.forget();
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
parserInput.restore();
|
|
539
|
+
var color = tree.Color.fromKeyword(k);
|
|
540
|
+
if (color) {
|
|
541
|
+
parserInput.$str(k);
|
|
542
|
+
return color;
|
|
543
|
+
}
|
|
516
544
|
},
|
|
517
545
|
|
|
518
546
|
//
|
|
@@ -591,7 +619,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
591
619
|
rulesetCall: function () {
|
|
592
620
|
var name;
|
|
593
621
|
|
|
594
|
-
if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^(@[\w-]+)\
|
|
622
|
+
if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^(@[\w-]+)\(\s*\)\s*;/))) {
|
|
595
623
|
return new tree.RulesetCall(name[1]);
|
|
596
624
|
}
|
|
597
625
|
},
|
|
@@ -903,7 +931,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
903
931
|
//
|
|
904
932
|
// A Rule terminator. Note that we use `peek()` to check for '}',
|
|
905
933
|
// because the `block` rule will be expecting it, but we still need to make sure
|
|
906
|
-
// it's there, if ';' was
|
|
934
|
+
// it's there, if ';' was omitted.
|
|
907
935
|
//
|
|
908
936
|
end: function () {
|
|
909
937
|
return parserInput.$char(';') || parserInput.peek('}');
|
|
@@ -1325,10 +1353,10 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1325
1353
|
},
|
|
1326
1354
|
|
|
1327
1355
|
media: function () {
|
|
1328
|
-
var features, rules, media, debugInfo;
|
|
1356
|
+
var features, rules, media, debugInfo, index = parserInput.i;
|
|
1329
1357
|
|
|
1330
1358
|
if (context.dumpLineNumbers) {
|
|
1331
|
-
debugInfo = getDebugInfo(
|
|
1359
|
+
debugInfo = getDebugInfo(index);
|
|
1332
1360
|
}
|
|
1333
1361
|
|
|
1334
1362
|
parserInput.save();
|
|
@@ -1344,7 +1372,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1344
1372
|
|
|
1345
1373
|
parserInput.forget();
|
|
1346
1374
|
|
|
1347
|
-
media = new(tree.Media)(rules, features,
|
|
1375
|
+
media = new(tree.Media)(rules, features, index, fileInfo);
|
|
1348
1376
|
if (context.dumpLineNumbers) {
|
|
1349
1377
|
media.debugInfo = debugInfo;
|
|
1350
1378
|
}
|
|
@@ -1644,12 +1672,44 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1644
1672
|
}
|
|
1645
1673
|
},
|
|
1646
1674
|
parenthesisCondition: function () {
|
|
1675
|
+
function tryConditionFollowedByParenthesis(me) {
|
|
1676
|
+
var body;
|
|
1677
|
+
parserInput.save();
|
|
1678
|
+
body = me.condition();
|
|
1679
|
+
if (!body) {
|
|
1680
|
+
parserInput.restore();
|
|
1681
|
+
return ;
|
|
1682
|
+
}
|
|
1683
|
+
if (!parserInput.$char(')')) {
|
|
1684
|
+
parserInput.restore();
|
|
1685
|
+
return ;
|
|
1686
|
+
}
|
|
1687
|
+
parserInput.forget();
|
|
1688
|
+
return body;
|
|
1689
|
+
}
|
|
1690
|
+
|
|
1647
1691
|
var body;
|
|
1692
|
+
parserInput.save();
|
|
1648
1693
|
if (!parserInput.$str("(")) {
|
|
1694
|
+
parserInput.restore();
|
|
1649
1695
|
return ;
|
|
1650
1696
|
}
|
|
1651
|
-
body =
|
|
1652
|
-
|
|
1697
|
+
body = tryConditionFollowedByParenthesis(this);
|
|
1698
|
+
if (body) {
|
|
1699
|
+
parserInput.forget();
|
|
1700
|
+
return body;
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1703
|
+
body = this.atomicCondition();
|
|
1704
|
+
if (!body) {
|
|
1705
|
+
parserInput.restore();
|
|
1706
|
+
return ;
|
|
1707
|
+
}
|
|
1708
|
+
if (!parserInput.$char(')')) {
|
|
1709
|
+
parserInput.restore("expected ')' got '" + parserInput.currentChar() + "'");
|
|
1710
|
+
return ;
|
|
1711
|
+
}
|
|
1712
|
+
parserInput.forget();
|
|
1653
1713
|
return body;
|
|
1654
1714
|
},
|
|
1655
1715
|
atomicCondition: function () {
|
|
@@ -1706,8 +1766,8 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1706
1766
|
}
|
|
1707
1767
|
|
|
1708
1768
|
var o = this.sub() || entities.dimension() ||
|
|
1709
|
-
entities.variable() ||
|
|
1710
|
-
entities.call() || entities.
|
|
1769
|
+
entities.color() || entities.variable() ||
|
|
1770
|
+
entities.call() || entities.colorKeyword();
|
|
1711
1771
|
|
|
1712
1772
|
if (negate) {
|
|
1713
1773
|
o.parensInOp = true;
|
|
@@ -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";
|
|
@@ -127,7 +128,7 @@ Definition.prototype.makeImportant = function() {
|
|
|
127
128
|
return r;
|
|
128
129
|
}
|
|
129
130
|
});
|
|
130
|
-
var result = new Definition
|
|
131
|
+
var result = new Definition(this.name, this.params, rules, this.condition, this.variadic, this.frames);
|
|
131
132
|
return result;
|
|
132
133
|
};
|
|
133
134
|
Definition.prototype.eval = function (context) {
|
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) {
|