less 4.4.1 → 4.5.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/Gruntfile.js +16 -17
- package/bin/lessc +35 -40
- package/dist/less.js +125 -186
- package/dist/less.min.js +2 -2
- package/dist/less.min.js.map +1 -1
- package/lib/less/contexts.js +0 -1
- package/lib/less/contexts.js.map +1 -1
- package/lib/less/default-options.js +22 -3
- package/lib/less/default-options.js.map +1 -1
- package/lib/less/less-error.js +2 -1
- package/lib/less/less-error.js.map +1 -1
- package/lib/less/parse-tree.js +58 -1
- package/lib/less/parse-tree.js.map +1 -1
- package/lib/less/parser/parser-input.js +2 -19
- package/lib/less/parser/parser-input.js.map +1 -1
- package/lib/less/parser/parser.js +8 -14
- package/lib/less/parser/parser.js.map +1 -1
- package/lib/less/source-map-output.js +1 -1
- package/lib/less/source-map-output.js.map +1 -1
- package/lib/less/tree/debug-info.js +29 -0
- package/lib/less/tree/debug-info.js.map +1 -1
- package/lib/less/tree/nested-at-rule.js +1 -1
- package/lib/less/tree/nested-at-rule.js.map +1 -1
- package/lib/less-node/lessc-helper.js +8 -7
- package/lib/less-node/lessc-helper.js.map +1 -1
- package/package.json +10 -5
- package/scripts/coverage-lines.js +207 -0
- package/scripts/coverage-report.js +158 -0
- package/scripts/postinstall.js +61 -0
- package/test/browser/common.js +22 -1
- package/test/browser/generator/runner.config.js +20 -24
- package/test/browser/generator/template.js +14 -3
- package/test/browser/runner-browser-options.js +5 -5
- package/test/index.js +293 -98
- package/test/less-test.js +453 -94
- package/test/sourcemaps/comprehensive.json +1 -0
- package/test/sourcemaps/sourcemaps-basepath.json +1 -0
- package/test/sourcemaps/sourcemaps-include-source.json +1 -0
- package/test/sourcemaps/sourcemaps-rootpath.json +1 -0
- package/test/sourcemaps/sourcemaps-url.json +1 -0
- package/test.less +1 -0
- package/tsconfig.json +20 -20
- package/lib/less/parser/chunker.js +0 -148
- package/lib/less/parser/chunker.js.map +0 -1
- package/test/browser/runner-legacy-options.js +0 -6
- package/test/browser/runner-legacy-spec.js +0 -3
package/Gruntfile.js
CHANGED
|
@@ -4,7 +4,7 @@ var resolve = require('resolve');
|
|
|
4
4
|
var path = require('path');
|
|
5
5
|
|
|
6
6
|
var testFolder = path.relative(process.cwd(), path.dirname(resolve.sync('@less/test-data')));
|
|
7
|
-
var lessFolder =
|
|
7
|
+
var lessFolder = testFolder;
|
|
8
8
|
|
|
9
9
|
module.exports = function(grunt) {
|
|
10
10
|
grunt.option("stack", true);
|
|
@@ -85,8 +85,7 @@ module.exports = function(grunt) {
|
|
|
85
85
|
"relative-urls",
|
|
86
86
|
"rewrite-urls",
|
|
87
87
|
"browser",
|
|
88
|
-
"no-js-errors"
|
|
89
|
-
"legacy"
|
|
88
|
+
"no-js-errors"
|
|
90
89
|
];
|
|
91
90
|
|
|
92
91
|
function makeJob(testName) {
|
|
@@ -214,7 +213,7 @@ module.exports = function(grunt) {
|
|
|
214
213
|
command: "node build/rollup.js --browser --out=./tmp/browser/less.min.js"
|
|
215
214
|
},
|
|
216
215
|
test: {
|
|
217
|
-
command: 'ts-node test/test-es6.ts && node test/index.js'
|
|
216
|
+
command: 'npx ts-node test/test-es6.ts && node test/index.js'
|
|
218
217
|
},
|
|
219
218
|
generatebrowser: {
|
|
220
219
|
command: 'node test/browser/generator/generate.js'
|
|
@@ -230,35 +229,35 @@ module.exports = function(grunt) {
|
|
|
230
229
|
command: [
|
|
231
230
|
// @TODO: make this more thorough
|
|
232
231
|
// CURRENT OPTIONS
|
|
233
|
-
`node bin/lessc --ie-compat ${lessFolder}/
|
|
232
|
+
`node bin/lessc --ie-compat ${lessFolder}/tests-unit/lazy-eval/lazy-eval.less tmp/lazy-eval.css`,
|
|
234
233
|
// --math
|
|
235
|
-
`node bin/lessc --math=always ${lessFolder}/
|
|
236
|
-
`node bin/lessc --math=parens-division ${lessFolder}/
|
|
237
|
-
`node bin/lessc --math=parens ${lessFolder}/
|
|
238
|
-
`node bin/lessc --math=strict ${lessFolder}/
|
|
239
|
-
`node bin/lessc --math=strict-legacy ${lessFolder}/
|
|
234
|
+
`node bin/lessc --math=always ${lessFolder}/tests-unit/lazy-eval/lazy-eval.less tmp/lazy-eval.css`,
|
|
235
|
+
`node bin/lessc --math=parens-division ${lessFolder}/tests-unit/lazy-eval/lazy-eval.less tmp/lazy-eval.css`,
|
|
236
|
+
`node bin/lessc --math=parens ${lessFolder}/tests-unit/lazy-eval/lazy-eval.less tmp/lazy-eval.css`,
|
|
237
|
+
`node bin/lessc --math=strict ${lessFolder}/tests-unit/lazy-eval/lazy-eval.less tmp/lazy-eval.css`,
|
|
238
|
+
`node bin/lessc --math=strict-legacy ${lessFolder}/tests-unit/lazy-eval/lazy-eval.less tmp/lazy-eval.css`,
|
|
240
239
|
|
|
241
240
|
// DEPRECATED OPTIONS
|
|
242
241
|
// --strict-math
|
|
243
|
-
`node bin/lessc --strict-math=on ${lessFolder}/
|
|
242
|
+
`node bin/lessc --strict-math=on ${lessFolder}/tests-unit/lazy-eval/lazy-eval.less tmp/lazy-eval.css`
|
|
244
243
|
].join(" && ")
|
|
245
244
|
},
|
|
246
245
|
plugin: {
|
|
247
246
|
command: [
|
|
248
|
-
`node bin/lessc --clean-css="--s1 --advanced" ${lessFolder}/
|
|
247
|
+
`node bin/lessc --clean-css="--s1 --advanced" ${lessFolder}/tests-unit/lazy-eval/lazy-eval.less tmp/lazy-eval.css`,
|
|
249
248
|
"cd lib",
|
|
250
|
-
`node ../bin/lessc --clean-css="--s1 --advanced" ../${lessFolder}/
|
|
251
|
-
`node ../bin/lessc --source-map=lazy-eval.css.map --autoprefix ../${lessFolder}/
|
|
249
|
+
`node ../bin/lessc --clean-css="--s1 --advanced" ../${lessFolder}/tests-unit/lazy-eval/lazy-eval.less ../tmp/lazy-eval.css`,
|
|
250
|
+
`node ../bin/lessc --source-map=lazy-eval.css.map --autoprefix ../${lessFolder}/tests-unit/lazy-eval/lazy-eval.less ../tmp/lazy-eval.css`,
|
|
252
251
|
"cd ..",
|
|
253
252
|
// Test multiple plugins
|
|
254
|
-
`node bin/lessc --plugin=clean-css="--s1 --advanced" --plugin=autoprefix="ie 11,Edge >= 13,Chrome >= 47,Firefox >= 45,iOS >= 9.2,Safari >= 9" ${lessFolder}/
|
|
253
|
+
`node bin/lessc --plugin=clean-css="--s1 --advanced" --plugin=autoprefix="ie 11,Edge >= 13,Chrome >= 47,Firefox >= 45,iOS >= 9.2,Safari >= 9" ${lessFolder}/tests-unit/lazy-eval/lazy-eval.less tmp/lazy-eval.css`
|
|
255
254
|
].join(" && ")
|
|
256
255
|
},
|
|
257
256
|
"sourcemap-test": {
|
|
258
257
|
// quoted value doesn't seem to get picked up by time-grunt, or isn't output, at least; maybe just "sourcemap" is fine?
|
|
259
258
|
command: [
|
|
260
|
-
`node bin/lessc --source-map=test/sourcemaps/maps/import-map.map ${lessFolder}/
|
|
261
|
-
`node bin/lessc --source-map ${lessFolder}/sourcemaps/basic.less test/sourcemaps/basic.css`
|
|
259
|
+
`node bin/lessc --source-map=test/sourcemaps/maps/import-map.map ${lessFolder}/tests-unit/import/import.less test/sourcemaps/import.css`,
|
|
260
|
+
`node bin/lessc --source-map ${lessFolder}/tests-config/sourcemaps/basic.less test/sourcemaps/basic.css`
|
|
262
261
|
].join(" && ")
|
|
263
262
|
}
|
|
264
263
|
},
|
package/bin/lessc
CHANGED
|
@@ -98,53 +98,48 @@ function render() {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
if (options.sourceMap) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
if (!sourceMapOptions.sourceMapFullFilename) {
|
|
104
|
-
if (!output && !sourceMapFileInline) {
|
|
105
|
-
console.error('the sourcemap option only has an optional filename if the css filename is given');
|
|
106
|
-
console.error('consider adding --source-map-map-inline which embeds the sourcemap into the css');
|
|
107
|
-
process.exitCode = 1;
|
|
108
|
-
return;
|
|
109
|
-
} // its in the same directory, so always just the basename
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (output) {
|
|
113
|
-
sourceMapOptions.sourceMapOutputFilename = path.basename(output);
|
|
114
|
-
sourceMapOptions.sourceMapFullFilename = ''.concat(output, '.map');
|
|
115
|
-
} // its in the same directory, so always just the basename
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
if ('sourceMapFullFilename' in sourceMapOptions) {
|
|
119
|
-
sourceMapOptions.sourceMapFilename = path.basename(sourceMapOptions.sourceMapFullFilename);
|
|
120
|
-
}
|
|
121
|
-
} else if (options.sourceMap && !sourceMapFileInline) {
|
|
122
|
-
var mapFilename = path.resolve(process.cwd(), sourceMapOptions.sourceMapFullFilename);
|
|
123
|
-
var mapDir = path.dirname(mapFilename);
|
|
124
|
-
var outputDir = path.dirname(output); // find the path from the map to the output file
|
|
125
|
-
|
|
126
|
-
// eslint-disable-next-line max-len
|
|
127
|
-
sourceMapOptions.sourceMapOutputFilename = path.join(path.relative(mapDir, outputDir), path.basename(output)); // make the sourcemap filename point to the sourcemap relative to the css file output directory
|
|
128
|
-
|
|
129
|
-
sourceMapOptions.sourceMapFilename = path.join(path.relative(outputDir, mapDir), path.basename(sourceMapOptions.sourceMapFullFilename));
|
|
130
|
-
}
|
|
131
|
-
|
|
101
|
+
// Validate conflicting options
|
|
132
102
|
if (sourceMapOptions.sourceMapURL && sourceMapOptions.disableSourcemapAnnotation) {
|
|
133
103
|
console.error('You cannot provide flag --source-map-url with --source-map-no-annotation.');
|
|
134
104
|
console.error('Please remove one of those flags.');
|
|
135
105
|
process.exitcode = 1;
|
|
136
106
|
return;
|
|
137
107
|
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (sourceMapOptions.sourceMapBasepath === undefined) {
|
|
141
|
-
sourceMapOptions.sourceMapBasepath = input ? path.dirname(input) : process.cwd();
|
|
142
|
-
}
|
|
143
108
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
sourceMapOptions.
|
|
109
|
+
// Handle explicit sourceMapFullFilename (from --source-map=filename)
|
|
110
|
+
// Normalization of other options (sourceMapBasepath, sourceMapRootpath, etc.)
|
|
111
|
+
// is handled automatically in parse-tree.js
|
|
112
|
+
if (sourceMapOptions.sourceMapFullFilename && !sourceMapFileInline) {
|
|
113
|
+
var mapFilename = path.resolve(process.cwd(), sourceMapOptions.sourceMapFullFilename);
|
|
114
|
+
var mapDir = path.dirname(mapFilename);
|
|
115
|
+
|
|
116
|
+
if (output) {
|
|
117
|
+
var outputDir = path.dirname(output);
|
|
118
|
+
// Set sourceMapOutputFilename relative to map directory
|
|
119
|
+
sourceMapOptions.sourceMapOutputFilename = path.join(
|
|
120
|
+
path.relative(mapDir, outputDir),
|
|
121
|
+
path.basename(output)
|
|
122
|
+
);
|
|
123
|
+
// Set sourceMapFilename relative to output directory (for sourceMappingURL comment)
|
|
124
|
+
sourceMapOptions.sourceMapFilename = path.join(
|
|
125
|
+
path.relative(outputDir, mapDir),
|
|
126
|
+
path.basename(sourceMapOptions.sourceMapFullFilename)
|
|
127
|
+
);
|
|
128
|
+
} else {
|
|
129
|
+
// No output filename, just use basename
|
|
130
|
+
sourceMapOptions.sourceMapOutputFilename = path.basename(output || 'output.css');
|
|
131
|
+
sourceMapOptions.sourceMapFilename = path.basename(sourceMapOptions.sourceMapFullFilename);
|
|
132
|
+
}
|
|
133
|
+
} else if (!sourceMapOptions.sourceMapFullFilename && output && !sourceMapFileInline) {
|
|
134
|
+
// No explicit sourcemap filename, derive from output
|
|
135
|
+
sourceMapOptions.sourceMapOutputFilename = path.basename(output);
|
|
136
|
+
sourceMapOptions.sourceMapFullFilename = ''.concat(output, '.map');
|
|
137
|
+
} else if (!output && !sourceMapFileInline) {
|
|
138
|
+
console.error('the sourcemap option only has an optional filename if the css filename is given');
|
|
139
|
+
console.error('consider adding --source-map-map-inline which embeds the sourcemap into the css');
|
|
140
|
+
process.exitCode = 1;
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
148
143
|
}
|
|
149
144
|
|
|
150
145
|
if (!input) {
|
package/dist/less.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Less - Leaner CSS v4.
|
|
2
|
+
* Less - Leaner CSS v4.5.1
|
|
3
3
|
* http://lesscss.org
|
|
4
4
|
*
|
|
5
5
|
* Copyright (c) 2009-2025, Alexis Sellier <self@cloudhead.net>
|
|
@@ -35,9 +35,28 @@
|
|
|
35
35
|
paths: [],
|
|
36
36
|
/* color output in the terminal */
|
|
37
37
|
color: true,
|
|
38
|
-
|
|
39
|
-
* @
|
|
40
|
-
*
|
|
38
|
+
/**
|
|
39
|
+
* @deprecated This option has confusing behavior and may be removed in a future version.
|
|
40
|
+
*
|
|
41
|
+
* When true, prevents @import statements for .less files from being evaluated inside
|
|
42
|
+
* selector blocks (rulesets). The imports are silently ignored and not output.
|
|
43
|
+
*
|
|
44
|
+
* Behavior:
|
|
45
|
+
* - @import at root level: Always processed
|
|
46
|
+
* - @import inside @-rules (@media, @supports, etc.): Processed (these are not selector blocks)
|
|
47
|
+
* - @import inside selector blocks (.class, #id, etc.): NOT processed (silently ignored)
|
|
48
|
+
*
|
|
49
|
+
* When false (default): All @import statements are processed regardless of context.
|
|
50
|
+
*
|
|
51
|
+
* Note: Despite the name "strict", this option does NOT throw an error when imports
|
|
52
|
+
* are used in selector blocks - it silently ignores them. This is confusing
|
|
53
|
+
* behavior that may catch users off guard.
|
|
54
|
+
*
|
|
55
|
+
* Note: Only affects .less file imports. CSS imports (url(...) or .css files) are
|
|
56
|
+
* always output as CSS @import statements regardless of this setting.
|
|
57
|
+
*
|
|
58
|
+
* @see https://github.com/less/less.js/issues/656
|
|
59
|
+
*/
|
|
41
60
|
strictImports: false,
|
|
42
61
|
/* Allow Imports from Insecure HTTPS Hosts */
|
|
43
62
|
insecure: false,
|
|
@@ -1237,6 +1256,8 @@
|
|
|
1237
1256
|
var filename = e.filename || currentFilename;
|
|
1238
1257
|
this.message = e.message;
|
|
1239
1258
|
this.stack = e.stack;
|
|
1259
|
+
// Set type early so it's always available, even if fileContentMap is missing
|
|
1260
|
+
this.type = e.type || 'Syntax';
|
|
1240
1261
|
if (fileContentMap && filename) {
|
|
1241
1262
|
var input = fileContentMap.contents[filename];
|
|
1242
1263
|
var loc = getLocation(e.index, input);
|
|
@@ -1244,7 +1265,6 @@
|
|
|
1244
1265
|
var col = loc.column;
|
|
1245
1266
|
var callLine = e.call && getLocation(e.call, input).line;
|
|
1246
1267
|
var lines = input ? input.split('\n') : '';
|
|
1247
|
-
this.type = e.type || 'Syntax';
|
|
1248
1268
|
this.filename = filename;
|
|
1249
1269
|
this.index = e.index;
|
|
1250
1270
|
this.line = typeof line === 'number' ? line + 1 : null;
|
|
@@ -1520,7 +1540,6 @@
|
|
|
1520
1540
|
'dumpLineNumbers',
|
|
1521
1541
|
'compress',
|
|
1522
1542
|
'syncImport',
|
|
1523
|
-
'chunkInput',
|
|
1524
1543
|
'mime',
|
|
1525
1544
|
'useFileCache',
|
|
1526
1545
|
// context
|
|
@@ -2728,151 +2747,6 @@
|
|
|
2728
2747
|
ToCSSVisitor: ToCSSVisitor
|
|
2729
2748
|
};
|
|
2730
2749
|
|
|
2731
|
-
// Split the input into chunks.
|
|
2732
|
-
function chunker (input, fail) {
|
|
2733
|
-
var len = input.length;
|
|
2734
|
-
var level = 0;
|
|
2735
|
-
var parenLevel = 0;
|
|
2736
|
-
var lastOpening;
|
|
2737
|
-
var lastOpeningParen;
|
|
2738
|
-
var lastMultiComment;
|
|
2739
|
-
var lastMultiCommentEndBrace;
|
|
2740
|
-
var chunks = [];
|
|
2741
|
-
var emitFrom = 0;
|
|
2742
|
-
var chunkerCurrentIndex;
|
|
2743
|
-
var currentChunkStartIndex;
|
|
2744
|
-
var cc;
|
|
2745
|
-
var cc2;
|
|
2746
|
-
var matched;
|
|
2747
|
-
function emitChunk(force) {
|
|
2748
|
-
var len = chunkerCurrentIndex - emitFrom;
|
|
2749
|
-
if (((len < 512) && !force) || !len) {
|
|
2750
|
-
return;
|
|
2751
|
-
}
|
|
2752
|
-
chunks.push(input.slice(emitFrom, chunkerCurrentIndex + 1));
|
|
2753
|
-
emitFrom = chunkerCurrentIndex + 1;
|
|
2754
|
-
}
|
|
2755
|
-
for (chunkerCurrentIndex = 0; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
|
|
2756
|
-
cc = input.charCodeAt(chunkerCurrentIndex);
|
|
2757
|
-
if (((cc >= 97) && (cc <= 122)) || (cc < 34)) {
|
|
2758
|
-
// a-z or whitespace
|
|
2759
|
-
continue;
|
|
2760
|
-
}
|
|
2761
|
-
switch (cc) {
|
|
2762
|
-
case 40: // (
|
|
2763
|
-
parenLevel++;
|
|
2764
|
-
lastOpeningParen = chunkerCurrentIndex;
|
|
2765
|
-
continue;
|
|
2766
|
-
case 41: // )
|
|
2767
|
-
if (--parenLevel < 0) {
|
|
2768
|
-
return fail('missing opening `(`', chunkerCurrentIndex);
|
|
2769
|
-
}
|
|
2770
|
-
continue;
|
|
2771
|
-
case 59: // ;
|
|
2772
|
-
if (!parenLevel) {
|
|
2773
|
-
emitChunk();
|
|
2774
|
-
}
|
|
2775
|
-
continue;
|
|
2776
|
-
case 123: // {
|
|
2777
|
-
level++;
|
|
2778
|
-
lastOpening = chunkerCurrentIndex;
|
|
2779
|
-
continue;
|
|
2780
|
-
case 125: // }
|
|
2781
|
-
if (--level < 0) {
|
|
2782
|
-
return fail('missing opening `{`', chunkerCurrentIndex);
|
|
2783
|
-
}
|
|
2784
|
-
if (!level && !parenLevel) {
|
|
2785
|
-
emitChunk();
|
|
2786
|
-
}
|
|
2787
|
-
continue;
|
|
2788
|
-
case 92: // \
|
|
2789
|
-
if (chunkerCurrentIndex < len - 1) {
|
|
2790
|
-
chunkerCurrentIndex++;
|
|
2791
|
-
continue;
|
|
2792
|
-
}
|
|
2793
|
-
return fail('unescaped `\\`', chunkerCurrentIndex);
|
|
2794
|
-
case 34:
|
|
2795
|
-
case 39:
|
|
2796
|
-
case 96: // ", ' and `
|
|
2797
|
-
matched = 0;
|
|
2798
|
-
currentChunkStartIndex = chunkerCurrentIndex;
|
|
2799
|
-
for (chunkerCurrentIndex = chunkerCurrentIndex + 1; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
|
|
2800
|
-
cc2 = input.charCodeAt(chunkerCurrentIndex);
|
|
2801
|
-
if (cc2 > 96) {
|
|
2802
|
-
continue;
|
|
2803
|
-
}
|
|
2804
|
-
if (cc2 == cc) {
|
|
2805
|
-
matched = 1;
|
|
2806
|
-
break;
|
|
2807
|
-
}
|
|
2808
|
-
if (cc2 == 92) { // \
|
|
2809
|
-
if (chunkerCurrentIndex == len - 1) {
|
|
2810
|
-
return fail('unescaped `\\`', chunkerCurrentIndex);
|
|
2811
|
-
}
|
|
2812
|
-
chunkerCurrentIndex++;
|
|
2813
|
-
}
|
|
2814
|
-
}
|
|
2815
|
-
if (matched) {
|
|
2816
|
-
continue;
|
|
2817
|
-
}
|
|
2818
|
-
return fail("unmatched `".concat(String.fromCharCode(cc), "`"), currentChunkStartIndex);
|
|
2819
|
-
case 47: // /, check for comment
|
|
2820
|
-
if (parenLevel || (chunkerCurrentIndex == len - 1)) {
|
|
2821
|
-
continue;
|
|
2822
|
-
}
|
|
2823
|
-
cc2 = input.charCodeAt(chunkerCurrentIndex + 1);
|
|
2824
|
-
if (cc2 == 47) {
|
|
2825
|
-
// //, find lnfeed
|
|
2826
|
-
for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
|
|
2827
|
-
cc2 = input.charCodeAt(chunkerCurrentIndex);
|
|
2828
|
-
if ((cc2 <= 13) && ((cc2 == 10) || (cc2 == 13))) {
|
|
2829
|
-
break;
|
|
2830
|
-
}
|
|
2831
|
-
}
|
|
2832
|
-
}
|
|
2833
|
-
else if (cc2 == 42) {
|
|
2834
|
-
// /*, find */
|
|
2835
|
-
lastMultiComment = currentChunkStartIndex = chunkerCurrentIndex;
|
|
2836
|
-
for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len - 1; chunkerCurrentIndex++) {
|
|
2837
|
-
cc2 = input.charCodeAt(chunkerCurrentIndex);
|
|
2838
|
-
if (cc2 == 125) {
|
|
2839
|
-
lastMultiCommentEndBrace = chunkerCurrentIndex;
|
|
2840
|
-
}
|
|
2841
|
-
if (cc2 != 42) {
|
|
2842
|
-
continue;
|
|
2843
|
-
}
|
|
2844
|
-
if (input.charCodeAt(chunkerCurrentIndex + 1) == 47) {
|
|
2845
|
-
break;
|
|
2846
|
-
}
|
|
2847
|
-
}
|
|
2848
|
-
if (chunkerCurrentIndex == len - 1) {
|
|
2849
|
-
return fail('missing closing `*/`', currentChunkStartIndex);
|
|
2850
|
-
}
|
|
2851
|
-
chunkerCurrentIndex++;
|
|
2852
|
-
}
|
|
2853
|
-
continue;
|
|
2854
|
-
case 42: // *, check for unmatched */
|
|
2855
|
-
if ((chunkerCurrentIndex < len - 1) && (input.charCodeAt(chunkerCurrentIndex + 1) == 47)) {
|
|
2856
|
-
return fail('unmatched `/*`', chunkerCurrentIndex);
|
|
2857
|
-
}
|
|
2858
|
-
continue;
|
|
2859
|
-
}
|
|
2860
|
-
}
|
|
2861
|
-
if (level !== 0) {
|
|
2862
|
-
if ((lastMultiComment > lastOpening) && (lastMultiCommentEndBrace > lastMultiComment)) {
|
|
2863
|
-
return fail('missing closing `}` or `*/`', lastOpening);
|
|
2864
|
-
}
|
|
2865
|
-
else {
|
|
2866
|
-
return fail('missing closing `}`', lastOpening);
|
|
2867
|
-
}
|
|
2868
|
-
}
|
|
2869
|
-
else if (parenLevel !== 0) {
|
|
2870
|
-
return fail('missing closing `)`', lastOpeningParen);
|
|
2871
|
-
}
|
|
2872
|
-
emitChunk(true);
|
|
2873
|
-
return chunks;
|
|
2874
|
-
}
|
|
2875
|
-
|
|
2876
2750
|
var getParserInput = (function () {
|
|
2877
2751
|
var // Less input string
|
|
2878
2752
|
input;
|
|
@@ -3187,25 +3061,10 @@
|
|
|
3187
3061
|
// Is the first char of the dimension 0-9, '.', '+' or '-'
|
|
3188
3062
|
return (c > CHARCODE_9 || c < CHARCODE_PLUS) || c === CHARCODE_FORWARD_SLASH || c === CHARCODE_COMMA;
|
|
3189
3063
|
};
|
|
3190
|
-
parserInput.start = function (str
|
|
3064
|
+
parserInput.start = function (str) {
|
|
3191
3065
|
input = str;
|
|
3192
3066
|
parserInput.i = j = currentPos = furthest = 0;
|
|
3193
|
-
|
|
3194
|
-
// it might actually make things slower in node at least)
|
|
3195
|
-
// and it is a non-perfect parse - it can't recognise
|
|
3196
|
-
// unquoted urls, meaning it can't distinguish comments
|
|
3197
|
-
// meaning comments with quotes or {}() in them get 'counted'
|
|
3198
|
-
// and then lead to parse errors.
|
|
3199
|
-
// In addition if the chunking chunks in the wrong place we might
|
|
3200
|
-
// not be able to parse a parser statement in one go
|
|
3201
|
-
// this is officially deprecated but can be switched on via an option
|
|
3202
|
-
// in the case it causes too much performance issues.
|
|
3203
|
-
if (chunkInput) {
|
|
3204
|
-
chunks = chunker(str, failFunction);
|
|
3205
|
-
}
|
|
3206
|
-
else {
|
|
3207
|
-
chunks = [str];
|
|
3208
|
-
}
|
|
3067
|
+
chunks = [str];
|
|
3209
3068
|
current = chunks[0];
|
|
3210
3069
|
skipWhitespace(0);
|
|
3211
3070
|
};
|
|
@@ -3392,12 +3251,7 @@
|
|
|
3392
3251
|
var returnNodes = [];
|
|
3393
3252
|
var parser = parserInput;
|
|
3394
3253
|
try {
|
|
3395
|
-
parser.start(str
|
|
3396
|
-
callback({
|
|
3397
|
-
message: msg,
|
|
3398
|
-
index: index + currentIndex
|
|
3399
|
-
});
|
|
3400
|
-
});
|
|
3254
|
+
parser.start(str);
|
|
3401
3255
|
for (var x = 0, p = void 0; (p = parseList[x]); x++) {
|
|
3402
3256
|
result = parsers[p]();
|
|
3403
3257
|
returnNodes.push(result || null);
|
|
@@ -3470,14 +3324,7 @@
|
|
|
3470
3324
|
// with the `root` property set to true, so no `{}` are
|
|
3471
3325
|
// output. The callback is called when the input is parsed.
|
|
3472
3326
|
try {
|
|
3473
|
-
parserInput.start(str
|
|
3474
|
-
throw new LessError({
|
|
3475
|
-
index: index,
|
|
3476
|
-
type: 'Parse',
|
|
3477
|
-
message: msg,
|
|
3478
|
-
filename: fileInfo.filename
|
|
3479
|
-
}, imports);
|
|
3480
|
-
});
|
|
3327
|
+
parserInput.start(str);
|
|
3481
3328
|
tree.Node.prototype.parse = this;
|
|
3482
3329
|
root = new tree.Ruleset(null, this.parsers.primary());
|
|
3483
3330
|
tree.Node.prototype.rootNode = root;
|
|
@@ -5083,6 +4930,9 @@
|
|
|
5083
4930
|
if (!parserInput.$char(',')) {
|
|
5084
4931
|
break;
|
|
5085
4932
|
}
|
|
4933
|
+
else if (!features[features.length - 1].noSpacing) {
|
|
4934
|
+
features[features.length - 1].noSpacing = false;
|
|
4935
|
+
}
|
|
5086
4936
|
}
|
|
5087
4937
|
else {
|
|
5088
4938
|
e = entities.variable() || entities.mixinLookup();
|
|
@@ -5091,6 +4941,9 @@
|
|
|
5091
4941
|
if (!parserInput.$char(',')) {
|
|
5092
4942
|
break;
|
|
5093
4943
|
}
|
|
4944
|
+
else if (!features[features.length - 1].noSpacing) {
|
|
4945
|
+
features[features.length - 1].noSpacing = false;
|
|
4946
|
+
}
|
|
5094
4947
|
}
|
|
5095
4948
|
}
|
|
5096
4949
|
} while (e);
|
|
@@ -6008,9 +5861,25 @@
|
|
|
6008
5861
|
}
|
|
6009
5862
|
});
|
|
6010
5863
|
|
|
5864
|
+
/**
|
|
5865
|
+
* @deprecated The dumpLineNumbers option is deprecated. Use sourcemaps instead.
|
|
5866
|
+
* This will be removed in a future version.
|
|
5867
|
+
*
|
|
5868
|
+
* @param {Object} ctx - Context object with debugInfo
|
|
5869
|
+
* @returns {string} Debug info as CSS comment
|
|
5870
|
+
*/
|
|
6011
5871
|
function asComment(ctx) {
|
|
6012
5872
|
return "/* line ".concat(ctx.debugInfo.lineNumber, ", ").concat(ctx.debugInfo.fileName, " */\n");
|
|
6013
5873
|
}
|
|
5874
|
+
/**
|
|
5875
|
+
* @deprecated The dumpLineNumbers option is deprecated. Use sourcemaps instead.
|
|
5876
|
+
* This function generates Sass-compatible debug info using @media -sass-debug-info syntax.
|
|
5877
|
+
* This format had short-lived usage and is no longer recommended.
|
|
5878
|
+
* This will be removed in a future version.
|
|
5879
|
+
*
|
|
5880
|
+
* @param {Object} ctx - Context object with debugInfo
|
|
5881
|
+
* @returns {string} Sass-compatible debug info as @media query
|
|
5882
|
+
*/
|
|
6014
5883
|
function asMediaQuery(ctx) {
|
|
6015
5884
|
var filenameWithProtocol = ctx.debugInfo.fileName;
|
|
6016
5885
|
if (!/^[a-z]+:\/\//i.test(filenameWithProtocol)) {
|
|
@@ -6023,6 +5892,19 @@
|
|
|
6023
5892
|
return "\\".concat(a);
|
|
6024
5893
|
}), "}line{font-family:\\00003").concat(ctx.debugInfo.lineNumber, "}}\n");
|
|
6025
5894
|
}
|
|
5895
|
+
/**
|
|
5896
|
+
* Generates debug information (line numbers) for CSS output.
|
|
5897
|
+
*
|
|
5898
|
+
* @param {Object} context - Context object with dumpLineNumbers option
|
|
5899
|
+
* @param {Object} ctx - Context object with debugInfo
|
|
5900
|
+
* @param {string} [lineSeparator] - Separator between comment and media query (for 'all' mode)
|
|
5901
|
+
* @returns {string} Debug info string
|
|
5902
|
+
*
|
|
5903
|
+
* @deprecated The dumpLineNumbers option is deprecated. Use sourcemaps instead.
|
|
5904
|
+
* All modes ('comments', 'mediaquery', 'all') are deprecated and will be removed in a future version.
|
|
5905
|
+
* The 'mediaquery' and 'all' modes generate Sass-compatible @media -sass-debug-info output
|
|
5906
|
+
* which had short-lived usage and is no longer recommended.
|
|
5907
|
+
*/
|
|
6026
5908
|
function debugInfo(context, ctx, lineSeparator) {
|
|
6027
5909
|
var result = '';
|
|
6028
5910
|
if (context.dumpLineNumbers && !context.compress) {
|
|
@@ -7168,7 +7050,7 @@
|
|
|
7168
7050
|
var expr, paren;
|
|
7169
7051
|
for (var index = 0; index < exprValues.length; ++index) {
|
|
7170
7052
|
expr = exprValues[index];
|
|
7171
|
-
if (expr.type === 'Keyword' && index + 1 < exprValues.length) {
|
|
7053
|
+
if (expr.type === 'Keyword' && index + 1 < exprValues.length && (expr.noSpacing || expr.noSpacing == null)) {
|
|
7172
7054
|
paren = exprValues[index + 1];
|
|
7173
7055
|
if (paren.type === 'Paren' && paren.noSpacing) {
|
|
7174
7056
|
exprValues[index] = new Expression([expr, paren]);
|
|
@@ -10648,7 +10530,7 @@
|
|
|
10648
10530
|
if (options.sourceMapFilename) {
|
|
10649
10531
|
this._sourceMapFilename = options.sourceMapFilename.replace(/\\/g, '/');
|
|
10650
10532
|
}
|
|
10651
|
-
this._outputFilename = options.outputFilename;
|
|
10533
|
+
this._outputFilename = options.outputFilename ? options.outputFilename.replace(/\\/g, '/') : options.outputFilename;
|
|
10652
10534
|
this.sourceMapURL = options.sourceMapURL;
|
|
10653
10535
|
if (options.sourceMapBasepath) {
|
|
10654
10536
|
this._sourceMapBasepath = options.sourceMapBasepath.replace(/\\/g, '/');
|
|
@@ -10867,12 +10749,69 @@
|
|
|
10867
10749
|
}
|
|
10868
10750
|
var toCSSOptions = {
|
|
10869
10751
|
compress: compress,
|
|
10752
|
+
// @deprecated The dumpLineNumbers option is deprecated. Use sourcemaps instead. All modes will be removed in a future version.
|
|
10870
10753
|
dumpLineNumbers: options.dumpLineNumbers,
|
|
10871
10754
|
strictUnits: Boolean(options.strictUnits),
|
|
10872
10755
|
numPrecision: 8
|
|
10873
10756
|
};
|
|
10874
10757
|
if (options.sourceMap) {
|
|
10875
|
-
|
|
10758
|
+
// Normalize sourceMap option: if it's just true, convert to object
|
|
10759
|
+
if (options.sourceMap === true) {
|
|
10760
|
+
options.sourceMap = {};
|
|
10761
|
+
}
|
|
10762
|
+
var sourceMapOpts = options.sourceMap;
|
|
10763
|
+
// Set sourceMapInputFilename if not set and filename is available
|
|
10764
|
+
if (!sourceMapOpts.sourceMapInputFilename && options.filename) {
|
|
10765
|
+
sourceMapOpts.sourceMapInputFilename = options.filename;
|
|
10766
|
+
}
|
|
10767
|
+
// Default sourceMapBasepath to the input file's directory if not set
|
|
10768
|
+
// This matches the behavior documented and implemented in bin/lessc
|
|
10769
|
+
if (sourceMapOpts.sourceMapBasepath === undefined && options.filename) {
|
|
10770
|
+
// Get directory from filename using string manipulation (works cross-platform)
|
|
10771
|
+
var lastSlash = Math.max(options.filename.lastIndexOf('/'), options.filename.lastIndexOf('\\'));
|
|
10772
|
+
if (lastSlash >= 0) {
|
|
10773
|
+
sourceMapOpts.sourceMapBasepath = options.filename.substring(0, lastSlash);
|
|
10774
|
+
}
|
|
10775
|
+
else {
|
|
10776
|
+
// No directory separator found, use current directory
|
|
10777
|
+
sourceMapOpts.sourceMapBasepath = '.';
|
|
10778
|
+
}
|
|
10779
|
+
}
|
|
10780
|
+
// Handle sourceMapFullFilename (CLI-specific: --source-map=filename)
|
|
10781
|
+
// This is converted to sourceMapFilename and sourceMapOutputFilename
|
|
10782
|
+
if (sourceMapOpts.sourceMapFullFilename && !sourceMapOpts.sourceMapFileInline) {
|
|
10783
|
+
// This case is handled by lessc before calling render
|
|
10784
|
+
// We just need to ensure sourceMapFilename is set if sourceMapFullFilename is provided
|
|
10785
|
+
if (!sourceMapOpts.sourceMapFilename && !sourceMapOpts.sourceMapURL) {
|
|
10786
|
+
// Extract just the basename for the sourceMappingURL comment
|
|
10787
|
+
var mapBase = sourceMapOpts.sourceMapFullFilename.split(/[/\\]/).pop();
|
|
10788
|
+
sourceMapOpts.sourceMapFilename = mapBase;
|
|
10789
|
+
}
|
|
10790
|
+
}
|
|
10791
|
+
else if (!sourceMapOpts.sourceMapFilename && !sourceMapOpts.sourceMapURL) {
|
|
10792
|
+
// If sourceMapFilename is not set and sourceMapURL is not set,
|
|
10793
|
+
// derive it from the output filename (if available) or input filename
|
|
10794
|
+
if (sourceMapOpts.sourceMapOutputFilename) {
|
|
10795
|
+
// Use output filename + .map
|
|
10796
|
+
sourceMapOpts.sourceMapFilename = sourceMapOpts.sourceMapOutputFilename + '.map';
|
|
10797
|
+
}
|
|
10798
|
+
else if (options.filename) {
|
|
10799
|
+
// Fallback to input filename + .css.map
|
|
10800
|
+
var inputBase = options.filename.replace(/\.[^/.]+$/, '');
|
|
10801
|
+
sourceMapOpts.sourceMapFilename = inputBase + '.css.map';
|
|
10802
|
+
}
|
|
10803
|
+
}
|
|
10804
|
+
// Default sourceMapOutputFilename if not set
|
|
10805
|
+
if (!sourceMapOpts.sourceMapOutputFilename) {
|
|
10806
|
+
if (options.filename) {
|
|
10807
|
+
var inputBase = options.filename.replace(/\.[^/.]+$/, '');
|
|
10808
|
+
sourceMapOpts.sourceMapOutputFilename = inputBase + '.css';
|
|
10809
|
+
}
|
|
10810
|
+
else {
|
|
10811
|
+
sourceMapOpts.sourceMapOutputFilename = 'output.css';
|
|
10812
|
+
}
|
|
10813
|
+
}
|
|
10814
|
+
sourceMapBuilder = new SourceMapBuilder(sourceMapOpts);
|
|
10876
10815
|
result.css = sourceMapBuilder.toCSS(evaldRoot, toCSSOptions, this.imports);
|
|
10877
10816
|
}
|
|
10878
10817
|
else {
|
|
@@ -11189,7 +11128,7 @@
|
|
|
11189
11128
|
return render;
|
|
11190
11129
|
}
|
|
11191
11130
|
|
|
11192
|
-
var version = "4.
|
|
11131
|
+
var version = "4.5.1";
|
|
11193
11132
|
|
|
11194
11133
|
function parseNodeVersion(version) {
|
|
11195
11134
|
var match = version.match(/^v(\d{1,2})\.(\d{1,2})\.(\d{1,2})(?:-([0-9A-Za-z-.]+))?(?:\+([0-9A-Za-z-.]+))?$/); // eslint-disable-line max-len
|