less 3.0.0-pre.2 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +88 -0
- package/.github/stale.yml +17 -0
- package/.project +17 -0
- package/.settings/org.eclipse.buildship.core.prefs +2 -0
- package/.travis.yml +22 -3
- package/.vscode/launch.json +14 -0
- package/CHANGELOG.md +27 -0
- package/Gruntfile.js +191 -86
- package/README.md +5 -7
- package/appveyor.yml +9 -10
- package/bin/lessc +37 -50
- package/dist/less.js +1357 -1269
- package/dist/less.min.js +7 -7
- package/lib/less/contexts.js +20 -16
- package/lib/less/default-options.js +65 -0
- package/lib/less/environment/abstract-file-manager.js +13 -14
- package/lib/less/environment/abstract-plugin-loader.js +45 -36
- package/lib/less/environment/environment.js +5 -0
- package/lib/less/functions/boolean.js +15 -0
- package/lib/less/functions/color.js +54 -24
- package/lib/less/functions/data-uri.js +5 -2
- package/lib/less/functions/function-registry.js +1 -1
- package/lib/less/functions/index.js +2 -1
- package/lib/less/functions/number.js +2 -2
- package/lib/less/functions/string.js +2 -2
- package/lib/less/functions/svg.js +4 -4
- package/lib/less/import-manager.js +41 -29
- package/lib/less/index.js +28 -3
- package/lib/less/less-error.js +112 -13
- package/lib/less/parse.js +18 -15
- package/lib/less/parser/parser-input.js +4 -4
- package/lib/less/parser/parser.js +208 -114
- package/lib/less/plugin-manager.js +8 -33
- package/lib/less/render.js +6 -2
- package/lib/less/source-map-builder.js +3 -0
- package/lib/less/source-map-output.js +13 -8
- package/lib/less/transform-tree.js +2 -2
- package/lib/less/tree/anonymous.js +4 -1
- package/lib/less/tree/atrule.js +7 -6
- package/lib/less/tree/call.js +25 -3
- package/lib/less/tree/color.js +2 -2
- package/lib/less/tree/debug-info.js +1 -1
- package/lib/less/tree/declaration.js +6 -5
- package/lib/less/tree/dimension.js +4 -1
- package/lib/less/tree/extend.js +2 -2
- package/lib/less/tree/import.js +17 -9
- package/lib/less/tree/index.js +3 -7
- package/lib/less/tree/js-eval-node.js +1 -1
- package/lib/less/tree/media.js +3 -14
- package/lib/less/tree/mixin-definition.js +3 -3
- package/lib/less/tree/node.js +9 -6
- package/lib/less/tree/operation.js +1 -1
- package/lib/less/tree/property.js +70 -0
- package/lib/less/tree/quoted.js +11 -10
- package/lib/less/tree/ruleset.js +115 -71
- package/lib/less/tree/selector.js +38 -23
- package/lib/less/tree/unit.js +1 -1
- package/lib/less/tree/value.js +6 -1
- package/lib/less/tree/{ruleset-call.js → variable-call.js} +5 -5
- package/lib/less/tree/variable.js +6 -6
- package/lib/less/utils.js +40 -0
- package/lib/less/visitors/extend-visitor.js +14 -14
- package/lib/less/visitors/import-visitor.js +2 -2
- package/lib/less/visitors/join-selector-visitor.js +1 -1
- package/lib/less/visitors/to-css-visitor.js +51 -84
- package/lib/less/visitors/visitor.js +15 -15
- package/lib/less-browser/bootstrap.js +21 -5
- package/lib/less-browser/cache.js +2 -2
- package/lib/less-browser/error-reporting.js +5 -5
- package/lib/less-browser/file-manager.js +27 -35
- package/lib/less-browser/index.js +12 -17
- package/lib/less-browser/plugin-loader.js +8 -45
- package/lib/less-browser/utils.js +1 -1
- package/lib/less-node/file-manager.js +99 -69
- package/lib/less-node/fs.js +1 -1
- package/lib/less-node/image-size.js +2 -2
- package/lib/less-node/index.js +7 -57
- package/lib/less-node/lessc-helper.js +38 -38
- package/lib/less-node/plugin-loader.js +18 -79
- package/lib/less-node/url-file-manager.js +1 -1
- package/lib/less-rhino/index.js +29 -44
- package/package.json +16 -9
- package/test/browser/common.js +54 -18
- package/test/browser/css/plugin/plugin.css +3 -0
- package/test/browser/jasmine-jsreporter.js +4 -4
- package/test/browser/less/plugin/plugin.js +7 -0
- package/test/browser/less/plugin/plugin.less +4 -0
- package/test/browser/less.js +11685 -13
- package/test/browser/runner-browser-options.js +6 -1
- package/test/browser/runner-filemanagerPlugin-options.js +3 -2
- package/test/browser/runner-legacy-options.js +2 -1
- package/test/browser/runner-main-options.js +0 -1
- package/test/browser/runner-modify-vars-spec.js +2 -2
- package/test/browser/test-runner-template.tmpl +38 -14
- package/test/copy-bom.js +1 -1
- package/test/css/calc.css +5 -0
- package/test/css/comments2.css +1 -1
- package/test/css/compression/compression.css +1 -1
- package/test/css/css-grid.css +11 -0
- package/test/css/debug/linenumbers-all.css +0 -1
- package/test/css/debug/linenumbers-comments.css +0 -1
- package/test/css/debug/linenumbers-mediaquery.css +0 -1
- package/test/css/functions.css +16 -3
- package/test/css/import-module.css +9 -0
- package/test/css/import.css +0 -1
- package/test/css/legacy/legacy.css +1 -1
- package/test/css/merge.css +5 -4
- package/test/css/plugin-module.css +1 -0
- package/test/css/plugin.css +20 -0
- package/test/css/property-accessors.css +49 -0
- package/test/css/{css.css → strict-math/css.css} +0 -0
- package/test/css/{mixins-args.css → strict-math/mixins-args.css} +0 -0
- package/test/css/{parens.css → strict-math/parens.css} +0 -0
- package/test/import-module/one/1.less +3 -0
- package/test/import-module/one/two/2.less +3 -0
- package/test/import-module/one/two/three/3.less +3 -0
- package/test/import-module/package.json +11 -0
- package/test/index.js +55 -49
- package/test/less/calc.less +7 -0
- package/test/less/css-grid.less +15 -0
- package/test/less/detached-rulesets.less +2 -2
- package/test/less/errors/color-invalid-hex-code.less +1 -0
- package/test/less/errors/color-invalid-hex-code.txt +1 -1
- package/test/less/errors/color-invalid-hex-code2.less +1 -0
- package/test/less/errors/color-invalid-hex-code2.txt +1 -1
- package/test/less/errors/import-missing.txt +1 -1
- package/test/less/errors/plugin/plugin-error-2.js +5 -0
- package/test/less/errors/plugin/plugin-error-3.js +5 -0
- package/test/less/errors/plugin/plugin-error.js +1 -0
- package/test/less/errors/plugin-1.less +1 -0
- package/test/less/errors/plugin-1.txt +2 -0
- package/test/less/errors/plugin-2.less +1 -0
- package/test/less/errors/plugin-2.txt +5 -0
- package/test/less/errors/plugin-3.less +1 -0
- package/test/less/errors/plugin-3.txt +5 -0
- package/test/less/functions.less +18 -0
- package/test/less/import-module.less +3 -0
- package/test/less/import.less +0 -2
- package/test/less/legacy/legacy.less +1 -1
- package/test/less/media.less +2 -2
- package/test/less/merge.less +6 -3
- package/test/less/plugin/plugin-collection.js +9 -0
- package/test/less/plugin/plugin-local.js +2 -2
- package/test/less/plugin/plugin-scope1.js +3 -0
- package/test/less/plugin/plugin-scope2.js +3 -0
- package/test/less/plugin/plugin-simple.js +7 -0
- package/test/less/plugin/plugin-tree-nodes.js +33 -31
- package/test/less/plugin-module.less +7 -0
- package/test/less/plugin.less +33 -3
- package/test/less/property-accessors.less +67 -0
- package/test/less/root-registry/file.less +1 -0
- package/test/less/root-registry/root.less +3 -0
- package/test/less/{css.less → strict-math/css.less} +0 -0
- package/test/less/{mixins-args.less → strict-math/mixins-args.less} +0 -0
- package/test/less/{parens.less → strict-math/parens.less} +0 -0
- package/test/less-bom/calc.less +7 -0
- package/test/less-bom/css-grid.less +15 -0
- package/test/less-bom/detached-rulesets.less +2 -2
- package/test/less-bom/errors/color-invalid-hex-code.less +1 -0
- package/test/less-bom/errors/color-invalid-hex-code.txt +1 -1
- package/test/less-bom/errors/color-invalid-hex-code2.less +1 -0
- package/test/less-bom/errors/color-invalid-hex-code2.txt +1 -1
- package/test/less-bom/errors/import-missing.txt +1 -1
- package/test/less-bom/errors/plugin/plugin-error-2.js +5 -0
- package/test/less-bom/errors/plugin/plugin-error-3.js +5 -0
- package/test/less-bom/errors/plugin/plugin-error.js +1 -0
- package/test/less-bom/errors/plugin-1.less +1 -0
- package/test/less-bom/errors/plugin-1.txt +2 -0
- package/test/less-bom/errors/plugin-2.less +1 -0
- package/test/less-bom/errors/plugin-2.txt +5 -0
- package/test/less-bom/errors/plugin-3.less +1 -0
- package/test/less-bom/errors/plugin-3.txt +5 -0
- package/test/less-bom/functions.less +18 -0
- package/test/less-bom/import-module.less +3 -0
- package/test/less-bom/import.less +0 -2
- package/test/less-bom/legacy/legacy.less +1 -1
- package/test/less-bom/media.less +2 -2
- package/test/less-bom/merge.less +6 -3
- package/test/less-bom/plugin/plugin-collection.js +9 -0
- package/test/less-bom/plugin/plugin-local.js +2 -2
- package/test/less-bom/plugin/plugin-scope1.js +3 -0
- package/test/less-bom/plugin/plugin-scope2.js +3 -0
- package/test/less-bom/plugin/plugin-simple.js +7 -0
- package/test/less-bom/plugin/plugin-tree-nodes.js +33 -31
- package/test/less-bom/plugin-module.less +7 -0
- package/test/less-bom/plugin.less +33 -3
- package/test/less-bom/property-accessors.less +67 -0
- package/test/less-bom/root-registry/file.less +1 -0
- package/test/less-bom/root-registry/root.less +3 -0
- package/test/less-bom/{css.less → strict-math/css.less} +0 -0
- package/test/less-bom/{mixins-args.less → strict-math/mixins-args.less} +0 -0
- package/test/less-bom/{parens.less → strict-math/parens.less} +0 -0
- package/test/less-test.js +75 -17
- package/test/modify-vars.js +1 -1
- package/test/plugins/visitor/index.js +1 -1
- package/.jscsrc +0 -73
- package/.jshintrc +0 -11
- package/lib/less/tree/alpha.js +0 -28
- package/lib/less/tree/directive.js +0 -12
- package/lib/less/tree/rule.js +0 -12
- package/test/less/errors/functions-2-alpha.less +0 -2
- package/test/less/errors/functions-2-alpha.txt +0 -3
- package/test/less-bom/errors/functions-2-alpha.less +0 -2
- package/test/less-bom/errors/functions-2-alpha.txt +0 -3
- package/test/sourcemaps/maps/import-map.map +0 -1
package/lib/less/contexts.js
CHANGED
|
@@ -40,18 +40,18 @@ contexts.Parse = function(options) {
|
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
var evalCopyProperties = [
|
|
43
|
-
'paths',
|
|
44
|
-
'compress',
|
|
45
|
-
'ieCompat',
|
|
46
|
-
'strictMath',
|
|
47
|
-
'strictUnits',
|
|
48
|
-
'sourceMap',
|
|
49
|
-
'importMultiple',
|
|
50
|
-
'urlArgs',
|
|
51
|
-
'javascriptEnabled'
|
|
52
|
-
'pluginManager',
|
|
53
|
-
'importantScope'
|
|
54
|
-
|
|
43
|
+
'paths', // additional include paths
|
|
44
|
+
'compress', // whether to compress
|
|
45
|
+
'ieCompat', // whether to enforce IE compatibility (IE8 data-uri)
|
|
46
|
+
'strictMath', // whether math has to be within parenthesis
|
|
47
|
+
'strictUnits', // whether units need to evaluate correctly
|
|
48
|
+
'sourceMap', // whether to output a source map
|
|
49
|
+
'importMultiple', // whether we are currently importing multiple copies
|
|
50
|
+
'urlArgs', // whether to add args into url tokens
|
|
51
|
+
'javascriptEnabled', // option - whether Inline JavaScript is enabled. if undefined, defaults to false
|
|
52
|
+
'pluginManager', // Used as the plugin manager for the session
|
|
53
|
+
'importantScope' // used to bubble up !important statements
|
|
54
|
+
];
|
|
55
55
|
|
|
56
56
|
contexts.Eval = function(options, frames) {
|
|
57
57
|
copyFromOriginal(options, this, evalCopyProperties);
|
|
@@ -73,7 +73,11 @@ contexts.Eval.prototype.outOfParenthesis = function () {
|
|
|
73
73
|
this.parensStack.pop();
|
|
74
74
|
};
|
|
75
75
|
|
|
76
|
+
contexts.Eval.prototype.mathOn = true;
|
|
76
77
|
contexts.Eval.prototype.isMathOn = function () {
|
|
78
|
+
if (!this.mathOn) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
77
81
|
return this.strictMath ? (this.parensStack && this.parensStack.length) : true;
|
|
78
82
|
};
|
|
79
83
|
|
|
@@ -83,13 +87,13 @@ contexts.Eval.prototype.isPathRelative = function (path) {
|
|
|
83
87
|
|
|
84
88
|
contexts.Eval.prototype.normalizePath = function( path ) {
|
|
85
89
|
var
|
|
86
|
-
|
|
87
|
-
|
|
90
|
+
segments = path.split("/").reverse(),
|
|
91
|
+
segment;
|
|
88
92
|
|
|
89
93
|
path = [];
|
|
90
94
|
while (segments.length !== 0 ) {
|
|
91
95
|
segment = segments.pop();
|
|
92
|
-
switch( segment ) {
|
|
96
|
+
switch ( segment ) {
|
|
93
97
|
case ".":
|
|
94
98
|
break;
|
|
95
99
|
case "..":
|
|
@@ -108,4 +112,4 @@ contexts.Eval.prototype.normalizePath = function( path ) {
|
|
|
108
112
|
return path.join("/");
|
|
109
113
|
};
|
|
110
114
|
|
|
111
|
-
//todo - do the same for the toCSS ?
|
|
115
|
+
// todo - do the same for the toCSS ?
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Export a new default each time
|
|
2
|
+
module.exports = function() {
|
|
3
|
+
return {
|
|
4
|
+
/* Outputs a makefile import dependency list to stdout. */
|
|
5
|
+
depends: false,
|
|
6
|
+
|
|
7
|
+
/* Compress using less built-in compression.
|
|
8
|
+
* This does an okay job but does not utilise all the tricks of
|
|
9
|
+
* dedicated css compression. */
|
|
10
|
+
compress: false,
|
|
11
|
+
|
|
12
|
+
/* Runs the less parser and just reports errors without any output. */
|
|
13
|
+
lint: false,
|
|
14
|
+
|
|
15
|
+
/* Sets available include paths.
|
|
16
|
+
* If the file in an @import rule does not exist at that exact location,
|
|
17
|
+
* less will look for it at the location(s) passed to this option.
|
|
18
|
+
* You might use this for instance to specify a path to a library which
|
|
19
|
+
* you want to be referenced simply and relatively in the less files. */
|
|
20
|
+
paths: [],
|
|
21
|
+
|
|
22
|
+
/* color output in the terminal */
|
|
23
|
+
color: true,
|
|
24
|
+
|
|
25
|
+
/* The strictImports controls whether the compiler will allow an @import inside of either
|
|
26
|
+
* @media blocks or (a later addition) other selector blocks.
|
|
27
|
+
* See: https://github.com/less/less.js/issues/656 */
|
|
28
|
+
strictImports: false,
|
|
29
|
+
|
|
30
|
+
/* Allow Imports from Insecure HTTPS Hosts */
|
|
31
|
+
insecure: false,
|
|
32
|
+
|
|
33
|
+
/* Allows you to add a path to every generated import and url in your css.
|
|
34
|
+
* This does not affect less import statements that are processed, just ones
|
|
35
|
+
* that are left in the output css. */
|
|
36
|
+
rootpath: '',
|
|
37
|
+
|
|
38
|
+
/* By default URLs are kept as-is, so if you import a file in a sub-directory
|
|
39
|
+
* that references an image, exactly the same URL will be output in the css.
|
|
40
|
+
* This option allows you to re-write URL's in imported files so that the
|
|
41
|
+
* URL is always relative to the base imported file */
|
|
42
|
+
relativeUrls: false,
|
|
43
|
+
|
|
44
|
+
/* Compatibility with IE8. Used for limiting data-uri length */
|
|
45
|
+
ieCompat: false, // true until 3.0
|
|
46
|
+
|
|
47
|
+
/* Without this option on, Less will try and process all math in your css */
|
|
48
|
+
strictMath: false,
|
|
49
|
+
|
|
50
|
+
/* Without this option, less attempts to guess at the output unit when it does maths. */
|
|
51
|
+
strictUnits: false,
|
|
52
|
+
|
|
53
|
+
/* Effectively the declaration is put at the top of your base Less file,
|
|
54
|
+
* meaning it can be used but it also can be overridden if this variable
|
|
55
|
+
* is defined in the file. */
|
|
56
|
+
globalVars: null,
|
|
57
|
+
|
|
58
|
+
/* As opposed to the global variable option, this puts the declaration at the
|
|
59
|
+
* end of your base file, meaning it will override anything defined in your Less file. */
|
|
60
|
+
modifyVars: null,
|
|
61
|
+
|
|
62
|
+
/* This option allows you to specify a argument to go on to every URL. */
|
|
63
|
+
urlArgs: ''
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -35,7 +35,7 @@ abstractFileManager.prototype.alwaysMakePathsAbsolute = function() {
|
|
|
35
35
|
abstractFileManager.prototype.isPathAbsolute = function(filename) {
|
|
36
36
|
return (/^(?:[a-z-]+:|\/|\\|#)/i).test(filename);
|
|
37
37
|
};
|
|
38
|
-
// TODO: pull out
|
|
38
|
+
// TODO: pull out / replace?
|
|
39
39
|
abstractFileManager.prototype.join = function(basePath, laterPath) {
|
|
40
40
|
if (!basePath) {
|
|
41
41
|
return laterPath;
|
|
@@ -76,7 +76,7 @@ abstractFileManager.prototype.extractUrlParts = function extractUrlParts(url, ba
|
|
|
76
76
|
|
|
77
77
|
var urlPartsRegex = /^((?:[a-z-]+:)?\/{2}(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i,
|
|
78
78
|
urlParts = url.match(urlPartsRegex),
|
|
79
|
-
returner = {}, directories = [], i, baseUrlParts;
|
|
79
|
+
returner = {}, rawDirectories = [], directories = [], i, baseUrlParts;
|
|
80
80
|
|
|
81
81
|
if (!urlParts) {
|
|
82
82
|
throw new Error("Could not parse sheet href - '" + url + "'");
|
|
@@ -95,27 +95,26 @@ abstractFileManager.prototype.extractUrlParts = function extractUrlParts(url, ba
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
if (urlParts[3]) {
|
|
98
|
-
|
|
98
|
+
rawDirectories = urlParts[3].replace(/\\/g, "/").split("/");
|
|
99
99
|
|
|
100
|
-
//
|
|
101
|
-
for (i = 0; i <
|
|
102
|
-
if (directories[i] === ".") {
|
|
103
|
-
directories.splice(i, 1);
|
|
104
|
-
i -= 1;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
100
|
+
// collapse '..' and skip '.'
|
|
101
|
+
for (i = 0; i < rawDirectories.length; i++) {
|
|
107
102
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
103
|
+
if (rawDirectories[i] === "..") {
|
|
104
|
+
directories.pop();
|
|
105
|
+
}
|
|
106
|
+
else if (rawDirectories[i] !== ".") {
|
|
107
|
+
directories.push(rawDirectories[i]);
|
|
112
108
|
}
|
|
109
|
+
|
|
113
110
|
}
|
|
114
111
|
}
|
|
115
112
|
|
|
116
113
|
returner.hostPart = urlParts[1];
|
|
117
114
|
returner.directories = directories;
|
|
115
|
+
returner.rawPath = (urlParts[1] || "") + rawDirectories.join("/");
|
|
118
116
|
returner.path = (urlParts[1] || "") + directories.join("/");
|
|
117
|
+
returner.filename = urlParts[4];
|
|
119
118
|
returner.fileUrl = returner.path + (urlParts[4] || "");
|
|
120
119
|
returner.url = returner.fileUrl + (urlParts[5] || "");
|
|
121
120
|
return returner;
|
|
@@ -12,13 +12,12 @@ function error(msg, type) {
|
|
|
12
12
|
}
|
|
13
13
|
);
|
|
14
14
|
}
|
|
15
|
-
AbstractPluginLoader.prototype.evalPlugin = function(contents, context, pluginOptions, fileInfo) {
|
|
15
|
+
AbstractPluginLoader.prototype.evalPlugin = function(contents, context, imports, pluginOptions, fileInfo) {
|
|
16
16
|
|
|
17
17
|
var loader,
|
|
18
18
|
registry,
|
|
19
19
|
pluginObj,
|
|
20
20
|
localModule,
|
|
21
|
-
localExports,
|
|
22
21
|
pluginManager,
|
|
23
22
|
filename;
|
|
24
23
|
|
|
@@ -32,13 +31,21 @@ AbstractPluginLoader.prototype.evalPlugin = function(contents, context, pluginOp
|
|
|
32
31
|
filename = fileInfo.filename;
|
|
33
32
|
}
|
|
34
33
|
}
|
|
34
|
+
var shortname = (new this.less.FileManager()).extractUrlParts(filename).filename;
|
|
35
|
+
|
|
35
36
|
if (filename) {
|
|
36
37
|
pluginObj = pluginManager.get(filename);
|
|
37
38
|
|
|
38
39
|
if (pluginObj) {
|
|
39
|
-
this.trySetOptions(pluginObj, filename, pluginOptions);
|
|
40
|
-
|
|
41
|
-
pluginObj.use
|
|
40
|
+
this.trySetOptions(pluginObj, filename, shortname, pluginOptions);
|
|
41
|
+
try {
|
|
42
|
+
if (pluginObj.use) {
|
|
43
|
+
pluginObj.use.call(this.context, pluginObj);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
e.message = 'Error during @plugin call';
|
|
48
|
+
return new this.less.LessError(e, imports, filename);
|
|
42
49
|
}
|
|
43
50
|
return pluginObj;
|
|
44
51
|
}
|
|
@@ -48,52 +55,54 @@ AbstractPluginLoader.prototype.evalPlugin = function(contents, context, pluginOp
|
|
|
48
55
|
pluginManager: pluginManager,
|
|
49
56
|
fileInfo: fileInfo
|
|
50
57
|
};
|
|
51
|
-
localExports = localModule.exports;
|
|
52
58
|
registry = functionRegistry.create();
|
|
53
59
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
60
|
+
var registerPlugin = function(obj) {
|
|
61
|
+
pluginObj = obj;
|
|
62
|
+
};
|
|
57
63
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
64
|
+
try {
|
|
65
|
+
loader = new Function("module", "require", "registerPlugin", "functions", "tree", "less", "fileInfo", contents);
|
|
66
|
+
loader(localModule, this.require, registerPlugin, registry, this.less.tree, this.less, fileInfo);
|
|
67
|
+
} catch (e) {
|
|
68
|
+
return new this.less.LessError(e, imports, filename);
|
|
69
|
+
}
|
|
61
70
|
|
|
62
|
-
|
|
71
|
+
if (!pluginObj) {
|
|
72
|
+
pluginObj = localModule.exports;
|
|
73
|
+
}
|
|
74
|
+
pluginObj = this.validatePlugin(pluginObj, filename, shortname);
|
|
63
75
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
76
|
+
if (pluginObj) {
|
|
77
|
+
// Run on first load
|
|
78
|
+
pluginManager.addPlugin(pluginObj, fileInfo.filename, registry);
|
|
79
|
+
pluginObj.functions = registry.getLocalFunctions();
|
|
80
|
+
pluginObj.imports = imports;
|
|
81
|
+
pluginObj.filename = filename;
|
|
68
82
|
|
|
69
|
-
|
|
83
|
+
this.trySetOptions(pluginObj, filename, shortname, pluginOptions);
|
|
70
84
|
|
|
71
|
-
|
|
85
|
+
// Run every @plugin call
|
|
86
|
+
try {
|
|
72
87
|
if (pluginObj.use) {
|
|
73
|
-
pluginObj.use(this.
|
|
88
|
+
pluginObj.use.call(this.context, pluginObj);
|
|
74
89
|
}
|
|
75
90
|
}
|
|
76
|
-
|
|
77
|
-
|
|
91
|
+
catch (e) {
|
|
92
|
+
e.message = 'Error during @plugin call';
|
|
93
|
+
return new this.less.LessError(e, imports, filename);
|
|
78
94
|
}
|
|
79
95
|
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return new this.less.LessError({
|
|
84
|
-
message: "Plugin evaluation error: '" + e.name + ': ' + e.message.replace(/["]/g, "'") + "'" ,
|
|
85
|
-
filename: filename,
|
|
86
|
-
line: this.line,
|
|
87
|
-
col: this.column
|
|
88
|
-
});
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
return new this.less.LessError({ message: "Not a valid plugin" });
|
|
89
99
|
}
|
|
90
100
|
|
|
91
101
|
return pluginObj;
|
|
92
102
|
|
|
93
103
|
};
|
|
94
104
|
|
|
95
|
-
AbstractPluginLoader.prototype.trySetOptions = function(plugin, filename, options) {
|
|
96
|
-
var name = require('path').basename(filename);
|
|
105
|
+
AbstractPluginLoader.prototype.trySetOptions = function(plugin, filename, name, options) {
|
|
97
106
|
if (options) {
|
|
98
107
|
if (!plugin.setOptions) {
|
|
99
108
|
error("Options have been provided but the plugin " + name + " does not support any options.");
|
|
@@ -102,21 +111,21 @@ AbstractPluginLoader.prototype.trySetOptions = function(plugin, filename, option
|
|
|
102
111
|
try {
|
|
103
112
|
plugin.setOptions(options);
|
|
104
113
|
}
|
|
105
|
-
catch(e) {
|
|
114
|
+
catch (e) {
|
|
106
115
|
error("Error setting options on plugin " + name + '\n' + e.message);
|
|
107
116
|
return null;
|
|
108
117
|
}
|
|
109
118
|
}
|
|
110
119
|
};
|
|
111
120
|
|
|
112
|
-
AbstractPluginLoader.prototype.validatePlugin = function(plugin, filename) {
|
|
121
|
+
AbstractPluginLoader.prototype.validatePlugin = function(plugin, filename, name) {
|
|
113
122
|
if (plugin) {
|
|
114
123
|
// support plugins being a function
|
|
115
124
|
// so that the plugin can be more usable programmatically
|
|
116
125
|
if (typeof plugin === "function") {
|
|
117
126
|
plugin = new plugin();
|
|
118
127
|
}
|
|
119
|
-
|
|
128
|
+
|
|
120
129
|
if (plugin.minVersion) {
|
|
121
130
|
if (this.compareVersion(plugin.minVersion, this.less.version) < 0) {
|
|
122
131
|
error("Plugin " + name + " requires version " + this.versionToString(plugin.minVersion));
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @todo Document why this abstraction exists, and the relationship between
|
|
3
|
+
* environment, file managers, and plugin manager
|
|
4
|
+
*/
|
|
5
|
+
|
|
1
6
|
var logger = require("../logger");
|
|
2
7
|
var environment = function(externalEnvironment, fileManagers) {
|
|
3
8
|
this.fileManagers = fileManagers || [];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
|
|
2
|
+
var functionRegistry = require("./function-registry"),
|
|
3
|
+
Anonymous = require("../tree/anonymous"),
|
|
4
|
+
Keyword = require("../tree/keyword");
|
|
5
|
+
|
|
6
|
+
functionRegistry.addMultiple({
|
|
7
|
+
boolean: function(condition) {
|
|
8
|
+
return condition ? Keyword.True : Keyword.False;
|
|
9
|
+
},
|
|
10
|
+
|
|
11
|
+
'if': function(condition, trueValue, falseValue) {
|
|
12
|
+
return condition ? trueValue
|
|
13
|
+
: (falseValue || new Anonymous);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
@@ -266,43 +266,73 @@ colorFunctions = {
|
|
|
266
266
|
greyscale: function (color) {
|
|
267
267
|
return colorFunctions.desaturate(color, new Dimension(100));
|
|
268
268
|
},
|
|
269
|
-
contrast: function (color,
|
|
270
|
-
// Return which of `color1` and `color2` has the greatest contrast with `color`
|
|
271
|
-
// according to the standard WCAG contrast ratio calculation.
|
|
272
|
-
// http://www.w3.org/TR/WCAG20/#contrast-ratiodef
|
|
273
|
-
// The threshold param is no longer used, in line with SASS.
|
|
269
|
+
contrast: function (color, dark, light, threshold) {
|
|
274
270
|
// filter: contrast(3.2);
|
|
275
271
|
// should be kept as is, so check for color
|
|
276
272
|
if (!color.rgb) {
|
|
277
273
|
return null;
|
|
278
274
|
}
|
|
279
|
-
if (typeof
|
|
280
|
-
|
|
275
|
+
if (typeof light === 'undefined') {
|
|
276
|
+
light = colorFunctions.rgba(255, 255, 255, 1.0);
|
|
281
277
|
}
|
|
282
|
-
if (typeof
|
|
283
|
-
|
|
278
|
+
if (typeof dark === 'undefined') {
|
|
279
|
+
dark = colorFunctions.rgba(0, 0, 0, 1.0);
|
|
284
280
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
if (luma > luma1) {
|
|
291
|
-
contrast1 = (luma + 0.05) / (luma1 + 0.05);
|
|
292
|
-
} else {
|
|
293
|
-
contrast1 = (luma1 + 0.05) / (luma + 0.05);
|
|
281
|
+
// Figure out which is actually light and dark:
|
|
282
|
+
if (dark.luma() > light.luma()) {
|
|
283
|
+
var t = light;
|
|
284
|
+
light = dark;
|
|
285
|
+
dark = t;
|
|
294
286
|
}
|
|
295
|
-
if (
|
|
296
|
-
|
|
287
|
+
if (typeof threshold === 'undefined') {
|
|
288
|
+
threshold = 0.43;
|
|
297
289
|
} else {
|
|
298
|
-
|
|
290
|
+
threshold = number(threshold);
|
|
299
291
|
}
|
|
300
|
-
if (
|
|
301
|
-
return
|
|
292
|
+
if (color.luma() < threshold) {
|
|
293
|
+
return light;
|
|
302
294
|
} else {
|
|
303
|
-
return
|
|
295
|
+
return dark;
|
|
304
296
|
}
|
|
305
297
|
},
|
|
298
|
+
// Changes made in 2.7.0 - Reverted in 3.0.0
|
|
299
|
+
// contrast: function (color, color1, color2, threshold) {
|
|
300
|
+
// // Return which of `color1` and `color2` has the greatest contrast with `color`
|
|
301
|
+
// // according to the standard WCAG contrast ratio calculation.
|
|
302
|
+
// // http://www.w3.org/TR/WCAG20/#contrast-ratiodef
|
|
303
|
+
// // The threshold param is no longer used, in line with SASS.
|
|
304
|
+
// // filter: contrast(3.2);
|
|
305
|
+
// // should be kept as is, so check for color
|
|
306
|
+
// if (!color.rgb) {
|
|
307
|
+
// return null;
|
|
308
|
+
// }
|
|
309
|
+
// if (typeof color1 === 'undefined') {
|
|
310
|
+
// color1 = colorFunctions.rgba(0, 0, 0, 1.0);
|
|
311
|
+
// }
|
|
312
|
+
// if (typeof color2 === 'undefined') {
|
|
313
|
+
// color2 = colorFunctions.rgba(255, 255, 255, 1.0);
|
|
314
|
+
// }
|
|
315
|
+
// var contrast1, contrast2;
|
|
316
|
+
// var luma = color.luma();
|
|
317
|
+
// var luma1 = color1.luma();
|
|
318
|
+
// var luma2 = color2.luma();
|
|
319
|
+
// // Calculate contrast ratios for each color
|
|
320
|
+
// if (luma > luma1) {
|
|
321
|
+
// contrast1 = (luma + 0.05) / (luma1 + 0.05);
|
|
322
|
+
// } else {
|
|
323
|
+
// contrast1 = (luma1 + 0.05) / (luma + 0.05);
|
|
324
|
+
// }
|
|
325
|
+
// if (luma > luma2) {
|
|
326
|
+
// contrast2 = (luma + 0.05) / (luma2 + 0.05);
|
|
327
|
+
// } else {
|
|
328
|
+
// contrast2 = (luma2 + 0.05) / (luma + 0.05);
|
|
329
|
+
// }
|
|
330
|
+
// if (contrast1 > contrast2) {
|
|
331
|
+
// return color1;
|
|
332
|
+
// } else {
|
|
333
|
+
// return color2;
|
|
334
|
+
// }
|
|
335
|
+
// },
|
|
306
336
|
argb: function (color) {
|
|
307
337
|
return new Anonymous(color.toARGB());
|
|
308
338
|
},
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
module.exports = function(environment) {
|
|
2
2
|
var Quoted = require("../tree/quoted"),
|
|
3
3
|
URL = require("../tree/url"),
|
|
4
|
+
utils = require('../utils'),
|
|
4
5
|
functionRegistry = require("./function-registry"),
|
|
5
6
|
fallback = function(functionThis, node) {
|
|
6
7
|
return new URL(node, functionThis.index, functionThis.currentFileInfo).eval(functionThis.context);
|
|
@@ -26,8 +27,10 @@ module.exports = function(environment) {
|
|
|
26
27
|
fragment = filePath.slice(fragmentStart);
|
|
27
28
|
filePath = filePath.slice(0, fragmentStart);
|
|
28
29
|
}
|
|
30
|
+
var context = utils.clone(this.context);
|
|
31
|
+
context.rawBuffer = true;
|
|
29
32
|
|
|
30
|
-
var fileManager = environment.getFileManager(filePath, currentDirectory,
|
|
33
|
+
var fileManager = environment.getFileManager(filePath, currentDirectory, context, environment, true);
|
|
31
34
|
|
|
32
35
|
if (!fileManager) {
|
|
33
36
|
return fallback(this, filePathNode);
|
|
@@ -53,7 +56,7 @@ module.exports = function(environment) {
|
|
|
53
56
|
useBase64 = /;base64$/.test(mimetype);
|
|
54
57
|
}
|
|
55
58
|
|
|
56
|
-
var fileSync = fileManager.loadFileSync(filePath, currentDirectory,
|
|
59
|
+
var fileSync = fileManager.loadFileSync(filePath, currentDirectory, context, environment);
|
|
57
60
|
if (!fileSync.contents) {
|
|
58
61
|
logger.warn("Skipped data-uri embedding of " + filePath + " because file not found");
|
|
59
62
|
return fallback(this, filePathNode || mimetypeNode);
|
|
@@ -5,7 +5,7 @@ var Dimension = require("../tree/dimension"),
|
|
|
5
5
|
|
|
6
6
|
var minMax = function (isMin, args) {
|
|
7
7
|
args = Array.prototype.slice.call(args);
|
|
8
|
-
switch(args.length) {
|
|
8
|
+
switch (args.length) {
|
|
9
9
|
case 0: throw { type: "Argument", message: "one or more arguments required" };
|
|
10
10
|
}
|
|
11
11
|
var i, j, current, currentUnified, referenceUnified, unit, unitStatic, unitClone,
|
|
@@ -27,7 +27,7 @@ var minMax = function (isMin, args) {
|
|
|
27
27
|
j = values[""] !== undefined && unit !== "" && unit === unitStatic ? values[""] : values[unit];
|
|
28
28
|
if (j === undefined) {
|
|
29
29
|
if (unitStatic !== undefined && unit !== unitStatic) {
|
|
30
|
-
throw{ type: "Argument", message: "incompatible types" };
|
|
30
|
+
throw { type: "Argument", message: "incompatible types" };
|
|
31
31
|
}
|
|
32
32
|
values[unit] = order.length;
|
|
33
33
|
order.push(current);
|
|
@@ -19,12 +19,12 @@ functionRegistry.addMultiple({
|
|
|
19
19
|
result = result.replace(new RegExp(pattern.value, flags ? flags.value : ''), replacement);
|
|
20
20
|
return new Quoted(string.quote || '', result, string.escaped);
|
|
21
21
|
},
|
|
22
|
-
'%': function (string /* arg, arg,
|
|
22
|
+
'%': function (string /* arg, arg, ... */) {
|
|
23
23
|
var args = Array.prototype.slice.call(arguments, 1),
|
|
24
24
|
result = string.value;
|
|
25
25
|
|
|
26
26
|
for (var i = 0; i < args.length; i++) {
|
|
27
|
-
/*jshint loopfunc:true */
|
|
27
|
+
/* jshint loopfunc:true */
|
|
28
28
|
result = result.replace(/%[sda]/i, function(token) {
|
|
29
29
|
var value = ((args[i].type === "Quoted") &&
|
|
30
30
|
token.match(/s/i)) ? args[i].value : args[i].toCSS();
|
|
@@ -15,12 +15,12 @@ module.exports = function(environment) {
|
|
|
15
15
|
renderEnv = {compress: false},
|
|
16
16
|
returner,
|
|
17
17
|
directionValue = direction.toCSS(renderEnv),
|
|
18
|
-
|
|
18
|
+
i, color, position, positionValue, alpha;
|
|
19
19
|
|
|
20
20
|
function throwArgumentDescriptor() {
|
|
21
21
|
throw { type: "Argument",
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
message: "svg-gradient expects direction, start_color [start_position], [color position,]...," +
|
|
23
|
+
" end_color [end_position] or direction, color list" };
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
if (arguments.length == 2) {
|
|
@@ -61,7 +61,7 @@ module.exports = function(environment) {
|
|
|
61
61
|
'<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%" viewBox="0 0 1 1" preserveAspectRatio="none">' +
|
|
62
62
|
'<' + gradientType + 'Gradient id="gradient" gradientUnits="userSpaceOnUse" ' + gradientDirectionSvg + '>';
|
|
63
63
|
|
|
64
|
-
for (i = 0; i < stops.length; i+= 1) {
|
|
64
|
+
for (i = 0; i < stops.length; i += 1) {
|
|
65
65
|
if (stops[i] instanceof Expression) {
|
|
66
66
|
color = stops[i].value[0];
|
|
67
67
|
position = stops[i].value[1];
|