less 2.1.1 → 2.3.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/.idea/inspectionProfiles/Project_Default.xml +1 -0
- package/.idea/jsLinters/jscs.xml +4 -0
- package/.idea/jsLinters/jshint.xml +58 -4
- package/.idea/workspace.xml +451 -758
- package/.jscsrc +38 -0
- package/.jshintrc +0 -2
- package/.travis.yml +0 -1
- package/CHANGELOG.md +52 -0
- package/Gruntfile.js +37 -3
- package/bin/lessc +380 -316
- package/bower.json +1 -1
- package/dist/less.js +790 -479
- package/dist/less.min.js +7 -7
- package/lib/less/contexts.js +1 -1
- package/lib/less/data/unit-conversions.js +3 -3
- package/lib/less/environment/abstract-file-manager.js +4 -4
- package/lib/less/environment/environment.js +9 -0
- package/lib/less/functions/color-blending.js +3 -3
- package/lib/less/functions/color.js +8 -8
- package/lib/less/functions/data-uri.js +39 -31
- package/lib/less/functions/string.js +3 -1
- package/lib/less/functions/svg.js +12 -15
- package/lib/less/functions/types.js +15 -2
- package/lib/less/import-manager.js +10 -5
- package/lib/less/index.js +2 -1
- package/lib/less/parse-tree.js +8 -2
- package/lib/less/parse.js +65 -0
- package/lib/less/parser/parser-input.js +3 -2
- package/lib/less/parser/parser.js +24 -11
- package/lib/less/render.js +7 -36
- package/lib/less/source-map-output.js +3 -3
- package/lib/less/transform-tree.js +1 -1
- package/lib/less/tree/assignment.js +0 -1
- package/lib/less/tree/color.js +4 -4
- package/lib/less/tree/condition.js +1 -1
- package/lib/less/tree/debug-info.js +6 -2
- package/lib/less/tree/dimension.js +1 -1
- package/lib/less/tree/directive.js +25 -6
- package/lib/less/tree/expression.js +1 -1
- package/lib/less/tree/import.js +2 -2
- package/lib/less/tree/index.js +1 -0
- package/lib/less/tree/media.js +3 -2
- package/lib/less/tree/mixin-call.js +3 -4
- package/lib/less/tree/mixin-definition.js +4 -3
- package/lib/less/tree/quoted.js +1 -1
- package/lib/less/tree/rule.js +2 -3
- package/lib/less/tree/ruleset.js +263 -157
- package/lib/less/tree/selector.js +2 -1
- package/lib/less/tree/url.js +5 -2
- package/lib/less/tree/value.js +1 -1
- package/lib/less/tree/variable.js +1 -1
- package/lib/less/visitors/extend-visitor.js +60 -25
- package/lib/less/visitors/import-sequencer.js +20 -14
- package/lib/less/visitors/import-visitor.js +13 -10
- package/lib/less/visitors/to-css-visitor.js +37 -5
- package/lib/less-browser/add-default-options.js +5 -1
- package/lib/less-browser/bootstrap.js +10 -8
- package/lib/less-browser/cache.js +1 -1
- package/lib/less-browser/index.js +13 -12
- package/lib/less-browser/utils.js +9 -6
- package/lib/less-node/file-manager.js +51 -28
- package/lib/less-node/image-size.js +34 -0
- package/lib/less-node/index.js +3 -0
- package/lib/less-node/lessc-helper.js +3 -2
- package/lib/less-node/url-file-manager.js +2 -2
- package/lib/less-rhino/index.js +2 -4
- package/package.json +10 -7
- package/test/browser/common.js +13 -11
- package/test/browser/css/urls.css +6 -3
- package/test/browser/jasmine-jsreporter.js +2 -3
- package/test/browser/less/nested-gradient-with-svg-gradient/mixin-consumer.less +5 -0
- package/test/browser/less/nested-gradient-with-svg-gradient/svg-gradient-mixin.less +15 -0
- package/test/browser/less/urls.less +1 -0
- package/test/browser/less.js +15 -9424
- package/test/browser/runner-errors-options.js +0 -1
- package/test/browser/runner-errors-spec.js +0 -1
- package/test/browser/runner-legacy-options.js +0 -1
- package/test/browser/runner-no-js-errors-spec.js +0 -1
- package/test/browser/runner-production-options.js +0 -1
- package/test/browser/runner-relative-urls-options.js +0 -1
- package/test/browser/runner-rootpath-options.js +0 -1
- package/test/browser/runner-rootpath-relative-options.js +0 -1
- package/test/browser/runner-strict-units-options.js +0 -1
- package/test/copy-bom.js +72 -0
- package/test/css/comments.css +1 -0
- package/test/css/css-3.css +2 -0
- package/test/css/functions.css +2 -0
- package/test/css/import-interpolation.css +6 -0
- package/test/css/import-reference.css +25 -0
- package/test/css/include-path/include-path.css +6 -0
- package/test/css/mixins-important.css +6 -0
- package/test/css/selectors.css +10 -1
- package/test/css/url-args/urls.css +3 -3
- package/test/css/urls.css +12 -4
- package/test/css/variables.css +7 -1
- package/test/data/image.svg +3 -0
- package/test/index.js +14 -10
- package/test/less/comments.less +1 -0
- package/test/less/css-3.less +3 -0
- package/test/less/css-guards.less +2 -1
- package/test/less/errors/detached-ruleset-2.txt +1 -1
- package/test/less/errors/import-missing.txt +1 -1
- package/test/less/errors/parens-error-1.txt +1 -1
- package/test/less/errors/parens-error-2.txt +1 -1
- package/test/less/errors/parens-error-3.txt +1 -1
- package/test/less/errors/single-character.less +1 -0
- package/test/less/errors/single-character.txt +2 -0
- package/test/less/functions.less +5 -0
- package/test/less/import/import-interpolation.less +1 -0
- package/test/less/import/import-reference.less +38 -0
- package/test/less/import-reference.less +3 -1
- package/test/less/import.less +2 -0
- package/test/less/include-path/include-path.less +6 -0
- package/test/less/mixins-important.less +12 -0
- package/test/less/nested-gradient-with-svg-gradient/mixin-consumer.less +5 -0
- package/test/less/nested-gradient-with-svg-gradient/svg-gradient-mixin.less +15 -0
- package/test/less/selectors.less +19 -4
- package/test/less/urls.less +10 -1
- package/test/less/variables.less +17 -3
- package/test/less-bom/charsets.less +3 -0
- package/test/less-bom/colors.less +98 -0
- package/test/less-bom/comments.less +102 -0
- package/test/less-bom/comments2.less +20 -0
- package/test/less-bom/compression/compression.less +36 -0
- package/test/less-bom/css-3.less +154 -0
- package/test/less-bom/css-escapes.less +33 -0
- package/test/less-bom/css-guards.less +103 -0
- package/test/less-bom/css.less +108 -0
- package/test/less-bom/debug/import/test.less +25 -0
- package/test/less-bom/debug/linenumbers.less +33 -0
- package/test/less-bom/detached-rulesets.less +103 -0
- package/test/less-bom/empty.less +1 -0
- package/test/less-bom/errors/add-mixed-units.less +3 -0
- package/test/less-bom/errors/add-mixed-units.txt +4 -0
- package/test/less-bom/errors/add-mixed-units2.less +3 -0
- package/test/less-bom/errors/add-mixed-units2.txt +4 -0
- package/test/less-bom/errors/at-rules-undefined-var.less +4 -0
- package/test/less-bom/errors/at-rules-undefined-var.txt +4 -0
- package/test/less-bom/errors/bad-variable-declaration1.less +1 -0
- package/test/less-bom/errors/bad-variable-declaration1.txt +2 -0
- package/test/less-bom/errors/color-func-invalid-color.less +3 -0
- package/test/less-bom/errors/color-func-invalid-color.txt +4 -0
- package/test/less-bom/errors/color-invalid-hex-code.less +3 -0
- package/test/less-bom/errors/color-invalid-hex-code.txt +4 -0
- package/test/less-bom/errors/color-invalid-hex-code2.less +3 -0
- package/test/less-bom/errors/color-invalid-hex-code2.txt +4 -0
- package/test/less-bom/errors/css-guard-default-func.less +4 -0
- package/test/less-bom/errors/css-guard-default-func.txt +4 -0
- package/test/less-bom/errors/detached-ruleset-1.less +6 -0
- package/test/less-bom/errors/detached-ruleset-1.txt +4 -0
- package/test/less-bom/errors/detached-ruleset-2.less +6 -0
- package/test/less-bom/errors/detached-ruleset-2.txt +4 -0
- package/test/less-bom/errors/detached-ruleset-3.less +4 -0
- package/test/less-bom/errors/detached-ruleset-3.txt +4 -0
- package/test/less-bom/errors/detached-ruleset-4.less +5 -0
- package/test/less-bom/errors/detached-ruleset-4.txt +4 -0
- package/test/less-bom/errors/detached-ruleset-5.less +4 -0
- package/test/less-bom/errors/detached-ruleset-5.txt +3 -0
- package/test/less-bom/errors/detached-ruleset-6.less +5 -0
- package/test/less-bom/errors/detached-ruleset-6.txt +4 -0
- package/test/less-bom/errors/divide-mixed-units.less +3 -0
- package/test/less-bom/errors/divide-mixed-units.txt +4 -0
- package/test/less-bom/errors/extend-no-selector.less +3 -0
- package/test/less-bom/errors/extend-no-selector.txt +3 -0
- package/test/less-bom/errors/extend-not-at-end.less +3 -0
- package/test/less-bom/errors/extend-not-at-end.txt +3 -0
- package/test/less-bom/errors/import-malformed.less +1 -0
- package/test/less-bom/errors/import-malformed.txt +3 -0
- package/test/less-bom/errors/import-missing.less +6 -0
- package/test/less-bom/errors/import-missing.txt +3 -0
- package/test/less-bom/errors/import-no-semi.less +1 -0
- package/test/less-bom/errors/import-no-semi.txt +2 -0
- package/test/less-bom/errors/import-subfolder1.less +1 -0
- package/test/less-bom/errors/import-subfolder1.txt +3 -0
- package/test/less-bom/errors/import-subfolder2.less +1 -0
- package/test/less-bom/errors/import-subfolder2.txt +4 -0
- package/test/less-bom/errors/imports/import-subfolder1.less +1 -0
- package/test/less-bom/errors/imports/import-subfolder2.less +1 -0
- package/test/less-bom/errors/imports/import-test.less +4 -0
- package/test/less-bom/errors/imports/subfolder/mixin-not-defined.less +1 -0
- package/test/less-bom/errors/imports/subfolder/parse-error-curly-bracket.less +1 -0
- package/test/less-bom/errors/javascript-error.less +3 -0
- package/test/less-bom/errors/javascript-error.txt +4 -0
- package/test/less-bom/errors/javascript-undefined-var.less +3 -0
- package/test/less-bom/errors/javascript-undefined-var.txt +4 -0
- package/test/less-bom/errors/mixed-mixin-definition-args-1.less +6 -0
- package/test/less-bom/errors/mixed-mixin-definition-args-1.txt +4 -0
- package/test/less-bom/errors/mixed-mixin-definition-args-2.less +6 -0
- package/test/less-bom/errors/mixed-mixin-definition-args-2.txt +4 -0
- package/test/less-bom/errors/mixin-not-defined.less +11 -0
- package/test/less-bom/errors/mixin-not-defined.txt +3 -0
- package/test/less-bom/errors/mixin-not-matched.less +6 -0
- package/test/less-bom/errors/mixin-not-matched.txt +3 -0
- package/test/less-bom/errors/mixin-not-matched2.less +6 -0
- package/test/less-bom/errors/mixin-not-matched2.txt +3 -0
- package/test/less-bom/errors/mixin-not-visible-in-scope-1.less +9 -0
- package/test/less-bom/errors/mixin-not-visible-in-scope-1.txt +4 -0
- package/test/less-bom/errors/mixins-guards-default-func-1.less +9 -0
- package/test/less-bom/errors/mixins-guards-default-func-1.txt +4 -0
- package/test/less-bom/errors/mixins-guards-default-func-2.less +9 -0
- package/test/less-bom/errors/mixins-guards-default-func-2.txt +4 -0
- package/test/less-bom/errors/mixins-guards-default-func-3.less +9 -0
- package/test/less-bom/errors/mixins-guards-default-func-3.txt +4 -0
- package/test/less-bom/errors/multiple-guards-on-css-selectors.less +4 -0
- package/test/less-bom/errors/multiple-guards-on-css-selectors.txt +4 -0
- package/test/less-bom/errors/multiple-guards-on-css-selectors2.less +4 -0
- package/test/less-bom/errors/multiple-guards-on-css-selectors2.txt +4 -0
- package/test/less-bom/errors/multiply-mixed-units.less +7 -0
- package/test/less-bom/errors/multiply-mixed-units.txt +4 -0
- package/test/less-bom/errors/parens-error-1.less +3 -0
- package/test/less-bom/errors/parens-error-1.txt +4 -0
- package/test/less-bom/errors/parens-error-2.less +3 -0
- package/test/less-bom/errors/parens-error-2.txt +4 -0
- package/test/less-bom/errors/parens-error-3.less +3 -0
- package/test/less-bom/errors/parens-error-3.txt +4 -0
- package/test/less-bom/errors/parse-error-curly-bracket.less +4 -0
- package/test/less-bom/errors/parse-error-curly-bracket.txt +4 -0
- package/test/less-bom/errors/parse-error-extra-parens.less +5 -0
- package/test/less-bom/errors/parse-error-extra-parens.txt +3 -0
- package/test/less-bom/errors/parse-error-missing-bracket.less +2 -0
- package/test/less-bom/errors/parse-error-missing-bracket.txt +3 -0
- package/test/less-bom/errors/parse-error-missing-parens.less +5 -0
- package/test/less-bom/errors/parse-error-missing-parens.txt +3 -0
- package/test/less-bom/errors/parse-error-with-import.less +13 -0
- package/test/less-bom/errors/parse-error-with-import.txt +4 -0
- package/test/less-bom/errors/percentage-missing-space.less +3 -0
- package/test/less-bom/errors/percentage-missing-space.txt +4 -0
- package/test/less-bom/errors/property-asterisk-only-name.less +3 -0
- package/test/less-bom/errors/property-asterisk-only-name.txt +4 -0
- package/test/less-bom/errors/property-ie5-hack.less +3 -0
- package/test/less-bom/errors/property-ie5-hack.txt +3 -0
- package/test/less-bom/errors/property-in-root.less +4 -0
- package/test/less-bom/errors/property-in-root.txt +4 -0
- package/test/less-bom/errors/property-in-root2.less +1 -0
- package/test/less-bom/errors/property-in-root2.txt +4 -0
- package/test/less-bom/errors/property-in-root3.less +4 -0
- package/test/less-bom/errors/property-in-root3.txt +3 -0
- package/test/less-bom/errors/property-interp-not-defined.less +1 -0
- package/test/less-bom/errors/property-interp-not-defined.txt +2 -0
- package/test/less-bom/errors/recursive-variable.less +1 -0
- package/test/less-bom/errors/recursive-variable.txt +2 -0
- package/test/less-bom/errors/single-character.less +1 -0
- package/test/less-bom/errors/single-character.txt +2 -0
- package/test/less-bom/errors/svg-gradient1.less +3 -0
- package/test/less-bom/errors/svg-gradient1.txt +4 -0
- package/test/less-bom/errors/svg-gradient2.less +3 -0
- package/test/less-bom/errors/svg-gradient2.txt +4 -0
- package/test/less-bom/errors/svg-gradient3.less +3 -0
- package/test/less-bom/errors/svg-gradient3.txt +4 -0
- package/test/less-bom/errors/unit-function.less +3 -0
- package/test/less-bom/errors/unit-function.txt +4 -0
- package/test/less-bom/extend-chaining.less +91 -0
- package/test/less-bom/extend-clearfix.less +19 -0
- package/test/less-bom/extend-exact.less +46 -0
- package/test/less-bom/extend-media.less +24 -0
- package/test/less-bom/extend-nest.less +65 -0
- package/test/less-bom/extend-selector.less +99 -0
- package/test/less-bom/extend.less +81 -0
- package/test/less-bom/extract-and-length.less +133 -0
- package/test/less-bom/functions.less +201 -0
- package/test/less-bom/globalVars/extended.json +5 -0
- package/test/less-bom/globalVars/extended.less +10 -0
- package/test/less-bom/globalVars/simple.json +3 -0
- package/test/less-bom/globalVars/simple.less +3 -0
- package/test/less-bom/ie-filters.less +15 -0
- package/test/less-bom/import/deeper/deeper-2/url-import-2.less +3 -0
- package/test/less-bom/import/deeper/deeper-2/url-import.less +1 -0
- package/test/less-bom/import/deeper/import-once-test-a.less +1 -0
- package/test/less-bom/import/deeper/url-import.less +1 -0
- package/test/less-bom/import/import-and-relative-paths-test.less +17 -0
- package/test/less-bom/import/import-charset-test.less +1 -0
- package/test/less-bom/import/import-interpolation.less +2 -0
- package/test/less-bom/import/import-interpolation2.less +5 -0
- package/test/less-bom/import/import-once-test-c.less +6 -0
- package/test/less-bom/import/import-reference.less +89 -0
- package/test/less-bom/import/import-test-a.less +4 -0
- package/test/less-bom/import/import-test-b.less +8 -0
- package/test/less-bom/import/import-test-c.less +6 -0
- package/test/less-bom/import/import-test-d.css +1 -0
- package/test/less-bom/import/import-test-e.less +2 -0
- package/test/less-bom/import/import-test-f.less +5 -0
- package/test/less-bom/import/imports/font.less +8 -0
- package/test/less-bom/import/imports/logo.less +5 -0
- package/test/less-bom/import/interpolation-vars.less +6 -0
- package/test/less-bom/import/invalid-css.less +1 -0
- package/test/less-bom/import/urls.less +1 -0
- package/test/less-bom/import-inline.less +3 -0
- package/test/less-bom/import-interpolation.less +8 -0
- package/test/less-bom/import-once.less +6 -0
- package/test/less-bom/import-reference.less +23 -0
- package/test/less-bom/import.less +30 -0
- package/test/less-bom/include-path/include-path.less +6 -0
- package/test/less-bom/javascript.less +38 -0
- package/test/less-bom/lazy-eval.less +6 -0
- package/test/less-bom/legacy/legacy.less +7 -0
- package/test/less-bom/media.less +234 -0
- package/test/less-bom/merge.less +78 -0
- package/test/less-bom/mixins-args.less +215 -0
- package/test/less-bom/mixins-closure.less +26 -0
- package/test/less-bom/mixins-guards-default-func.less +195 -0
- package/test/less-bom/mixins-guards.less +271 -0
- package/test/less-bom/mixins-important.less +37 -0
- package/test/less-bom/mixins-interpolated.less +75 -0
- package/test/less-bom/mixins-named-args.less +36 -0
- package/test/less-bom/mixins-nested.less +22 -0
- package/test/less-bom/mixins-pattern.less +102 -0
- package/test/less-bom/mixins.less +145 -0
- package/test/less-bom/modifyVars/extended.json +5 -0
- package/test/less-bom/modifyVars/extended.less +11 -0
- package/test/less-bom/nested-gradient-with-svg-gradient/mixin-consumer.less +5 -0
- package/test/less-bom/nested-gradient-with-svg-gradient/svg-gradient-mixin.less +15 -0
- package/test/less-bom/no-js-errors/no-js-errors.less +3 -0
- package/test/less-bom/no-js-errors/no-js-errors.txt +4 -0
- package/test/less-bom/no-output.less +2 -0
- package/test/less-bom/operations.less +62 -0
- package/test/less-bom/parens.less +45 -0
- package/test/less-bom/property-name-interp.less +56 -0
- package/test/less-bom/rulesets.less +30 -0
- package/test/less-bom/scope.less +104 -0
- package/test/less-bom/selectors.less +174 -0
- package/test/less-bom/sourcemaps/basic.json +3 -0
- package/test/less-bom/sourcemaps/basic.less +27 -0
- package/test/less-bom/sourcemaps/imported.css +7 -0
- package/test/less-bom/static-urls/urls.less +33 -0
- package/test/less-bom/strict-units/strict-units.less +4 -0
- package/test/less-bom/strings.less +73 -0
- package/test/less-bom/url-args/urls.less +63 -0
- package/test/less-bom/urls.less +94 -0
- package/test/less-bom/variables-in-at-rules.less +20 -0
- package/test/less-bom/variables.less +119 -0
- package/test/less-bom/whitespace.less +44 -0
- package/test/less-test.js +127 -28
- package/test/modify-vars.js +6 -4
package/lib/less/contexts.js
CHANGED
|
@@ -41,6 +41,7 @@ contexts.Parse = function(options) {
|
|
|
41
41
|
};
|
|
42
42
|
|
|
43
43
|
var evalCopyProperties = [
|
|
44
|
+
'paths', // additional include paths
|
|
44
45
|
'compress', // whether to compress
|
|
45
46
|
'ieCompat', // whether to enforce IE compatibility (IE8 data-uri)
|
|
46
47
|
'strictMath', // whether math has to be within parenthesis
|
|
@@ -107,4 +108,3 @@ contexts.Eval.prototype.normalizePath = function( path ) {
|
|
|
107
108
|
};
|
|
108
109
|
|
|
109
110
|
//todo - do the same for the toCSS ?
|
|
110
|
-
|
|
@@ -53,10 +53,10 @@ abstractFileManager.prototype.pathDiff = function pathDiff(url, baseUrl) {
|
|
|
53
53
|
}
|
|
54
54
|
baseUrlDirectories = baseUrlParts.directories.slice(i);
|
|
55
55
|
urlDirectories = urlParts.directories.slice(i);
|
|
56
|
-
for(i = 0; i < baseUrlDirectories.length-1; i++) {
|
|
56
|
+
for(i = 0; i < baseUrlDirectories.length - 1; i++) {
|
|
57
57
|
diff += "../";
|
|
58
58
|
}
|
|
59
|
-
for(i = 0; i < urlDirectories.length-1; i++) {
|
|
59
|
+
for(i = 0; i < urlDirectories.length - 1; i++) {
|
|
60
60
|
diff += urlDirectories[i] + "/";
|
|
61
61
|
}
|
|
62
62
|
return diff;
|
|
@@ -81,7 +81,7 @@ abstractFileManager.prototype.extractUrlParts = function extractUrlParts(url, ba
|
|
|
81
81
|
if (baseUrl && (!urlParts[1] || urlParts[2])) {
|
|
82
82
|
baseUrlParts = baseUrl.match(urlPartsRegex);
|
|
83
83
|
if (!baseUrlParts) {
|
|
84
|
-
throw new Error("Could not parse page url - '"+baseUrl+"'");
|
|
84
|
+
throw new Error("Could not parse page url - '" + baseUrl + "'");
|
|
85
85
|
}
|
|
86
86
|
urlParts[1] = urlParts[1] || baseUrlParts[1] || "";
|
|
87
87
|
if (!urlParts[2]) {
|
|
@@ -102,7 +102,7 @@ abstractFileManager.prototype.extractUrlParts = function extractUrlParts(url, ba
|
|
|
102
102
|
|
|
103
103
|
for(i = 0; i < directories.length; i++) {
|
|
104
104
|
if (directories[i] === ".." && i > 0) {
|
|
105
|
-
directories.splice(i-1, 2);
|
|
105
|
+
directories.splice(i - 1, 2);
|
|
106
106
|
i -= 2;
|
|
107
107
|
}
|
|
108
108
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
var logger = require("../logger");
|
|
1
2
|
var environment = function(externalEnvironment, fileManagers) {
|
|
2
3
|
this.fileManagers = fileManagers || [];
|
|
3
4
|
externalEnvironment = externalEnvironment || {};
|
|
@@ -18,6 +19,14 @@ var environment = function(externalEnvironment, fileManagers) {
|
|
|
18
19
|
};
|
|
19
20
|
|
|
20
21
|
environment.prototype.getFileManager = function (filename, currentDirectory, options, environment, isSync) {
|
|
22
|
+
|
|
23
|
+
if (!filename) {
|
|
24
|
+
logger.warn("getFileManager called with no filename.. Please report this issue. continuing.");
|
|
25
|
+
}
|
|
26
|
+
if (currentDirectory == null) {
|
|
27
|
+
logger.warn("getFileManager called with null directory.. Please report this issue. continuing.");
|
|
28
|
+
}
|
|
29
|
+
|
|
21
30
|
var fileManagers = this.fileManagers;
|
|
22
31
|
if (options.pluginManager) {
|
|
23
32
|
fileManagers = [].concat(fileManagers).concat(options.pluginManager.getFileManagers());
|
|
@@ -33,9 +33,9 @@ var colorBlendModeFunctions = {
|
|
|
33
33
|
},
|
|
34
34
|
overlay: function(cb, cs) {
|
|
35
35
|
cb *= 2;
|
|
36
|
-
return (cb <= 1)
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
return (cb <= 1) ?
|
|
37
|
+
colorBlendModeFunctions.multiply(cb, cs) :
|
|
38
|
+
colorBlendModeFunctions.screen(cb - 1, cs);
|
|
39
39
|
},
|
|
40
40
|
softlight: function(cb, cs) {
|
|
41
41
|
var d = 1, e = cb;
|
|
@@ -47,7 +47,7 @@ colorFunctions = {
|
|
|
47
47
|
h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
|
|
48
48
|
if (h * 6 < 1) { return m1 + (m2 - m1) * h * 6; }
|
|
49
49
|
else if (h * 2 < 1) { return m2; }
|
|
50
|
-
else if (h * 3 < 2) { return m1 + (m2 - m1) * (2/3 - h) * 6; }
|
|
50
|
+
else if (h * 3 < 2) { return m1 + (m2 - m1) * (2 / 3 - h) * 6; }
|
|
51
51
|
else { return m1; }
|
|
52
52
|
}
|
|
53
53
|
|
|
@@ -57,9 +57,9 @@ colorFunctions = {
|
|
|
57
57
|
var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
|
|
58
58
|
var m1 = l * 2 - m2;
|
|
59
59
|
|
|
60
|
-
return colorFunctions.rgba(hue(h + 1/3) * 255,
|
|
60
|
+
return colorFunctions.rgba(hue(h + 1 / 3) * 255,
|
|
61
61
|
hue(h) * 255,
|
|
62
|
-
hue(h - 1/3) * 255,
|
|
62
|
+
hue(h - 1 / 3) * 255,
|
|
63
63
|
a);
|
|
64
64
|
},
|
|
65
65
|
|
|
@@ -127,9 +127,9 @@ colorFunctions = {
|
|
|
127
127
|
},
|
|
128
128
|
luminance: function (color) {
|
|
129
129
|
var luminance =
|
|
130
|
-
(0.2126 * color.rgb[0] / 255)
|
|
131
|
-
|
|
132
|
-
|
|
130
|
+
(0.2126 * color.rgb[0] / 255) +
|
|
131
|
+
(0.7152 * color.rgb[1] / 255) +
|
|
132
|
+
(0.0722 * color.rgb[2] / 255);
|
|
133
133
|
|
|
134
134
|
return new Dimension(luminance * color.alpha * 100, '%');
|
|
135
135
|
},
|
|
@@ -259,7 +259,7 @@ colorFunctions = {
|
|
|
259
259
|
return new Color(c.value.slice(1));
|
|
260
260
|
}
|
|
261
261
|
if ((c instanceof Color) || (c = Color.fromKeyword(c.value))) {
|
|
262
|
-
c.
|
|
262
|
+
c.value = undefined;
|
|
263
263
|
return c;
|
|
264
264
|
}
|
|
265
265
|
throw {
|
|
@@ -268,7 +268,7 @@ colorFunctions = {
|
|
|
268
268
|
};
|
|
269
269
|
},
|
|
270
270
|
tint: function(color, amount) {
|
|
271
|
-
return colorFunctions.mix(colorFunctions.rgb(255,255,255), color, amount);
|
|
271
|
+
return colorFunctions.mix(colorFunctions.rgb(255, 255, 255), color, amount);
|
|
272
272
|
},
|
|
273
273
|
shade: function(color, amount) {
|
|
274
274
|
return colorFunctions.mix(colorFunctions.rgb(0, 0, 0), color, amount);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module.exports = function(environment) {
|
|
2
|
-
var
|
|
2
|
+
var Quoted = require("../tree/quoted"),
|
|
3
3
|
URL = require("../tree/url"),
|
|
4
4
|
functionRegistry = require("./function-registry"),
|
|
5
5
|
fallback = function(functionThis, node) {
|
|
@@ -9,39 +9,44 @@ module.exports = function(environment) {
|
|
|
9
9
|
|
|
10
10
|
functionRegistry.add("data-uri", function(mimetypeNode, filePathNode) {
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
var fileManager = environment.getFileManager(filePath, this.context.currentFileInfo, this.context, environment, true);
|
|
16
|
-
|
|
17
|
-
if (!fileManager) {
|
|
18
|
-
return fallback(this, filePathNode || mimetypeNode);
|
|
12
|
+
if (!filePathNode) {
|
|
13
|
+
filePathNode = mimetypeNode;
|
|
14
|
+
mimetypeNode = null;
|
|
19
15
|
}
|
|
20
16
|
|
|
21
|
-
var
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
17
|
+
var mimetype = mimetypeNode && mimetypeNode.value;
|
|
18
|
+
var filePath = filePathNode.value;
|
|
19
|
+
var currentFileInfo = this.currentFileInfo;
|
|
20
|
+
var currentDirectory = currentFileInfo.relativeUrls ?
|
|
21
|
+
currentFileInfo.currentDirectory : currentFileInfo.entryPath;
|
|
26
22
|
|
|
27
23
|
var fragmentStart = filePath.indexOf('#');
|
|
28
24
|
var fragment = '';
|
|
29
|
-
if (fragmentStart
|
|
25
|
+
if (fragmentStart !== -1) {
|
|
30
26
|
fragment = filePath.slice(fragmentStart);
|
|
31
27
|
filePath = filePath.slice(0, fragmentStart);
|
|
32
28
|
}
|
|
33
29
|
|
|
34
|
-
var
|
|
35
|
-
|
|
30
|
+
var fileManager = environment.getFileManager(filePath, currentDirectory, this.context, environment, true);
|
|
31
|
+
|
|
32
|
+
if (!fileManager) {
|
|
33
|
+
return fallback(this, filePathNode);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
var useBase64 = false;
|
|
36
37
|
|
|
37
38
|
// detect the mimetype if not given
|
|
38
|
-
if (
|
|
39
|
+
if (!mimetypeNode) {
|
|
39
40
|
|
|
40
41
|
mimetype = environment.mimeLookup(filePath);
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
if (mimetype === "image/svg+xml") {
|
|
44
|
+
useBase64 = false;
|
|
45
|
+
} else {
|
|
46
|
+
// use base 64 unless it's an ASCII or UTF-8 format
|
|
47
|
+
var charset = environment.charsetLookup(mimetype);
|
|
48
|
+
useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0;
|
|
49
|
+
}
|
|
45
50
|
if (useBase64) { mimetype += ';base64'; }
|
|
46
51
|
}
|
|
47
52
|
else {
|
|
@@ -50,28 +55,31 @@ module.exports = function(environment) {
|
|
|
50
55
|
|
|
51
56
|
var fileSync = fileManager.loadFileSync(filePath, currentDirectory, this.context, environment);
|
|
52
57
|
if (!fileSync.contents) {
|
|
53
|
-
logger.warn("Skipped data-uri embedding because file not found");
|
|
58
|
+
logger.warn("Skipped data-uri embedding of " + filePath + " because file not found");
|
|
54
59
|
return fallback(this, filePathNode || mimetypeNode);
|
|
55
60
|
}
|
|
56
61
|
var buf = fileSync.contents;
|
|
62
|
+
if (useBase64 && !environment.encodeBase64) {
|
|
63
|
+
return fallback(this, filePathNode);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
buf = useBase64 ? environment.encodeBase64(buf) : encodeURIComponent(buf);
|
|
57
67
|
|
|
58
|
-
|
|
68
|
+
var uri = "data:" + mimetype + ',' + buf + fragment;
|
|
69
|
+
|
|
70
|
+
// IE8 cannot handle a data-uri larger than 32,768 characters. If this is exceeded
|
|
59
71
|
// and the --ieCompat flag is enabled, return a normal url() instead.
|
|
60
|
-
var
|
|
61
|
-
|
|
62
|
-
if (fileSizeInKB >= DATA_URI_MAX_KB) {
|
|
72
|
+
var DATA_URI_MAX = 32768;
|
|
73
|
+
if (uri.length >= DATA_URI_MAX) {
|
|
63
74
|
|
|
64
75
|
if (this.context.ieCompat !== false) {
|
|
65
|
-
logger.warn("Skipped data-uri embedding of
|
|
76
|
+
logger.warn("Skipped data-uri embedding of " + filePath + " because its size (" + uri.length +
|
|
77
|
+
" characters) exceeds IE8-safe " + DATA_URI_MAX + " characters!");
|
|
66
78
|
|
|
67
79
|
return fallback(this, filePathNode || mimetypeNode);
|
|
68
80
|
}
|
|
69
81
|
}
|
|
70
82
|
|
|
71
|
-
|
|
72
|
-
: encodeURIComponent(buf);
|
|
73
|
-
|
|
74
|
-
var uri = "\"data:" + mimetype + ',' + buf + fragment + "\"";
|
|
75
|
-
return new URL(new Anonymous(uri), this.index, this.currentFileInfo);
|
|
83
|
+
return new URL(new Quoted('"' + uri + '"', uri, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo);
|
|
76
84
|
});
|
|
77
85
|
};
|
|
@@ -8,7 +8,9 @@ functionRegistry.addMultiple({
|
|
|
8
8
|
return new Anonymous(str instanceof JavaScript ? str.evaluated : str.value);
|
|
9
9
|
},
|
|
10
10
|
escape: function (str) {
|
|
11
|
-
return new Anonymous(
|
|
11
|
+
return new Anonymous(
|
|
12
|
+
encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B")
|
|
13
|
+
.replace(/\(/g, "%28").replace(/\)/g, "%29"));
|
|
12
14
|
},
|
|
13
15
|
replace: function (string, pattern, replacement, flags) {
|
|
14
16
|
var result = string.value;
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
module.exports = function(environment) {
|
|
2
2
|
var Dimension = require("../tree/dimension"),
|
|
3
3
|
Color = require("../tree/color"),
|
|
4
|
-
|
|
4
|
+
Expression = require("../tree/expression"),
|
|
5
|
+
Quoted = require("../tree/quoted"),
|
|
5
6
|
URL = require("../tree/url"),
|
|
6
7
|
functionRegistry = require("./function-registry");
|
|
7
8
|
|
|
8
9
|
functionRegistry.add("svg-gradient", function(direction) {
|
|
9
10
|
|
|
10
11
|
function throwArgumentDescriptor() {
|
|
11
|
-
throw { type: "Argument",
|
|
12
|
+
throw { type: "Argument",
|
|
13
|
+
message: "svg-gradient expects direction, start_color [start_position], [color position,]...," +
|
|
14
|
+
" end_color [end_position]" };
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
if (arguments.length < 3) {
|
|
@@ -18,7 +21,6 @@ module.exports = function(environment) {
|
|
|
18
21
|
gradientDirectionSvg,
|
|
19
22
|
gradientType = "linear",
|
|
20
23
|
rectangleDimension = 'x="0" y="0" width="1" height="1"',
|
|
21
|
-
useBase64 = true,
|
|
22
24
|
renderEnv = {compress: false},
|
|
23
25
|
returner,
|
|
24
26
|
directionValue = direction.toCSS(renderEnv),
|
|
@@ -44,14 +46,15 @@ module.exports = function(environment) {
|
|
|
44
46
|
rectangleDimension = 'x="-50" y="-50" width="101" height="101"';
|
|
45
47
|
break;
|
|
46
48
|
default:
|
|
47
|
-
throw { type: "Argument", message: "svg-gradient direction must be 'to bottom', 'to right',
|
|
49
|
+
throw { type: "Argument", message: "svg-gradient direction must be 'to bottom', 'to right'," +
|
|
50
|
+
" 'to bottom right', 'to top right' or 'ellipse at center'" };
|
|
48
51
|
}
|
|
49
52
|
returner = '<?xml version="1.0" ?>' +
|
|
50
53
|
'<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%" viewBox="0 0 1 1" preserveAspectRatio="none">' +
|
|
51
54
|
'<' + gradientType + 'Gradient id="gradient" gradientUnits="userSpaceOnUse" ' + gradientDirectionSvg + '>';
|
|
52
55
|
|
|
53
56
|
for (i = 0; i < stops.length; i+= 1) {
|
|
54
|
-
if (stops[i]
|
|
57
|
+
if (stops[i] instanceof Expression) {
|
|
55
58
|
color = stops[i].value[0];
|
|
56
59
|
position = stops[i].value[1];
|
|
57
60
|
} else {
|
|
@@ -59,7 +62,7 @@ module.exports = function(environment) {
|
|
|
59
62
|
position = undefined;
|
|
60
63
|
}
|
|
61
64
|
|
|
62
|
-
if (!(color instanceof Color) || (!((i === 0 || i+1 === stops.length) && position === undefined) && !(position instanceof Dimension))) {
|
|
65
|
+
if (!(color instanceof Color) || (!((i === 0 || i + 1 === stops.length) && position === undefined) && !(position instanceof Dimension))) {
|
|
63
66
|
throwArgumentDescriptor();
|
|
64
67
|
}
|
|
65
68
|
positionValue = position ? position.toCSS(renderEnv) : i === 0 ? "0%" : "100%";
|
|
@@ -69,15 +72,9 @@ module.exports = function(environment) {
|
|
|
69
72
|
returner += '</' + gradientType + 'Gradient>' +
|
|
70
73
|
'<rect ' + rectangleDimension + ' fill="url(#gradient)" /></svg>';
|
|
71
74
|
|
|
72
|
-
|
|
73
|
-
try {
|
|
74
|
-
returner = environment.encodeBase64(returner);
|
|
75
|
-
} catch(e) {
|
|
76
|
-
useBase64 = false;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
75
|
+
returner = encodeURIComponent(returner);
|
|
79
76
|
|
|
80
|
-
returner = "
|
|
81
|
-
return new URL(new
|
|
77
|
+
returner = "data:image/svg+xml," + returner;
|
|
78
|
+
return new URL(new Quoted("'" + returner + "'", returner, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo);
|
|
82
79
|
});
|
|
83
80
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
var Keyword = require("../tree/keyword"),
|
|
2
|
+
DetachedRuleset = require("../tree/detached-ruleset"),
|
|
2
3
|
Dimension = require("../tree/dimension"),
|
|
3
4
|
Color = require("../tree/color"),
|
|
4
5
|
Quoted = require("../tree/quoted"),
|
|
@@ -11,9 +12,19 @@ var isa = function (n, Type) {
|
|
|
11
12
|
return (n instanceof Type) ? Keyword.True : Keyword.False;
|
|
12
13
|
},
|
|
13
14
|
isunit = function (n, unit) {
|
|
14
|
-
|
|
15
|
+
if (unit === undefined) {
|
|
16
|
+
throw { type: "Argument", message: "missing the required second argument to isunit." };
|
|
17
|
+
}
|
|
18
|
+
unit = typeof unit.value === "string" ? unit.value : unit;
|
|
19
|
+
if (typeof unit !== "string") {
|
|
20
|
+
throw { type: "Argument", message: "Second argument to isunit should be a unit or a string." };
|
|
21
|
+
}
|
|
22
|
+
return (n instanceof Dimension) && n.unit.is(unit) ? Keyword.True : Keyword.False;
|
|
15
23
|
};
|
|
16
24
|
functionRegistry.addMultiple({
|
|
25
|
+
isruleset: function (n) {
|
|
26
|
+
return isa(n, DetachedRuleset);
|
|
27
|
+
},
|
|
17
28
|
iscolor: function (n) {
|
|
18
29
|
return isa(n, Color);
|
|
19
30
|
},
|
|
@@ -41,7 +52,9 @@ functionRegistry.addMultiple({
|
|
|
41
52
|
isunit: isunit,
|
|
42
53
|
unit: function (val, unit) {
|
|
43
54
|
if(!(val instanceof Dimension)) {
|
|
44
|
-
throw { type: "Argument",
|
|
55
|
+
throw { type: "Argument",
|
|
56
|
+
message: "the first argument to unit must be a number" +
|
|
57
|
+
(val instanceof Operation ? ". Have you forgotten parenthesis?" : "") };
|
|
45
58
|
}
|
|
46
59
|
if (unit) {
|
|
47
60
|
if (unit instanceof Keyword) {
|
|
@@ -40,12 +40,14 @@ module.exports = function(environment) {
|
|
|
40
40
|
importManager.queue.splice(importManager.queue.indexOf(path), 1); // Remove the path from the queue
|
|
41
41
|
|
|
42
42
|
var importedEqualsRoot = fullPath === importManager.rootFilename;
|
|
43
|
-
|
|
43
|
+
if (importOptions.optional && e) {
|
|
44
|
+
callback(null, {rules:[]}, false, null);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
44
47
|
importManager.files[fullPath] = root;
|
|
45
|
-
|
|
46
48
|
if (e && !importManager.error) { importManager.error = e; }
|
|
47
|
-
|
|
48
49
|
callback(e, root, importedEqualsRoot, fullPath);
|
|
50
|
+
}
|
|
49
51
|
};
|
|
50
52
|
|
|
51
53
|
var newFileInfo = {
|
|
@@ -68,7 +70,7 @@ module.exports = function(environment) {
|
|
|
68
70
|
|
|
69
71
|
var loadFileCallback = function(loadedFile) {
|
|
70
72
|
var resolvedFilename = loadedFile.filename,
|
|
71
|
-
contents = loadedFile.contents;
|
|
73
|
+
contents = loadedFile.contents.replace(/^\uFEFF/, '');
|
|
72
74
|
|
|
73
75
|
// Pass on an updated rootpath if path of imported file is relative and file
|
|
74
76
|
// is in a (sub|sup) directory
|
|
@@ -80,7 +82,10 @@ module.exports = function(environment) {
|
|
|
80
82
|
// then rootpath should become 'less/../'
|
|
81
83
|
newFileInfo.currentDirectory = fileManager.getPath(resolvedFilename);
|
|
82
84
|
if(newFileInfo.relativeUrls) {
|
|
83
|
-
newFileInfo.rootpath = fileManager.join(
|
|
85
|
+
newFileInfo.rootpath = fileManager.join(
|
|
86
|
+
(importManager.context.rootpath || ""),
|
|
87
|
+
fileManager.pathDiff(newFileInfo.currentDirectory, newFileInfo.entryPath));
|
|
88
|
+
|
|
84
89
|
if (!fileManager.isPathAbsolute(newFileInfo.rootpath) && fileManager.alwaysMakePathsAbsolute()) {
|
|
85
90
|
newFileInfo.rootpath = fileManager.join(newFileInfo.entryPath, newFileInfo.rootpath);
|
|
86
91
|
}
|
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, 3, 1],
|
|
6
6
|
data: require('./data'),
|
|
7
7
|
tree: require('./tree'),
|
|
8
8
|
Environment: (Environment = require("./environment/environment")),
|
|
@@ -17,6 +17,7 @@ module.exports = function(environment, fileManagers) {
|
|
|
17
17
|
ParseTree: (ParseTree = require('./parse-tree')(SourceMapBuilder)),
|
|
18
18
|
ImportManager: (ImportManager = require('./import-manager')(environment)),
|
|
19
19
|
render: require("./render")(environment, ParseTree, ImportManager),
|
|
20
|
+
parse: require("./parse")(environment, ParseTree, ImportManager),
|
|
20
21
|
LessError: require('./less-error'),
|
|
21
22
|
transformTree: require('./transform-tree'),
|
|
22
23
|
utils: require('./utils'),
|
package/lib/less/parse-tree.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
var LessError = require('./less-error'),
|
|
2
|
-
transformTree = require("./transform-tree")
|
|
2
|
+
transformTree = require("./transform-tree"),
|
|
3
|
+
logger = require("./logger");
|
|
3
4
|
|
|
4
5
|
module.exports = function(SourceMapBuilder) {
|
|
5
6
|
var ParseTree = function(root, imports) {
|
|
@@ -16,8 +17,13 @@ ParseTree.prototype.toCSS = function(options) {
|
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
try {
|
|
20
|
+
var compress = Boolean(options.compress);
|
|
21
|
+
if (compress) {
|
|
22
|
+
logger.warn("The compress option has been deprecated. We recommend you use a dedicated css minifier, for instance see less-plugin-clean-css.");
|
|
23
|
+
}
|
|
24
|
+
|
|
19
25
|
var toCSSOptions = {
|
|
20
|
-
compress:
|
|
26
|
+
compress: compress,
|
|
21
27
|
dumpLineNumbers: options.dumpLineNumbers,
|
|
22
28
|
strictUnits: Boolean(options.strictUnits),
|
|
23
29
|
numPrecision: 8};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
var PromiseConstructor = typeof Promise === 'undefined' ? require('promise') : Promise,
|
|
2
|
+
contexts = require("./contexts"),
|
|
3
|
+
Parser = require('./parser/parser'),
|
|
4
|
+
PluginManager = require('./plugin-manager');
|
|
5
|
+
|
|
6
|
+
module.exports = function(environment, ParseTree, ImportManager) {
|
|
7
|
+
var parse = function (input, options, callback) {
|
|
8
|
+
options = options || {};
|
|
9
|
+
|
|
10
|
+
if (typeof(options) === 'function') {
|
|
11
|
+
callback = options;
|
|
12
|
+
options = {};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (!callback) {
|
|
16
|
+
var self = this;
|
|
17
|
+
return new PromiseConstructor(function (resolve, reject) {
|
|
18
|
+
parse.call(self, input, options, function(err, output) {
|
|
19
|
+
if (err) {
|
|
20
|
+
reject(err);
|
|
21
|
+
} else {
|
|
22
|
+
resolve(output);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
} else {
|
|
27
|
+
var context,
|
|
28
|
+
rootFileInfo,
|
|
29
|
+
pluginManager = new PluginManager(this);
|
|
30
|
+
|
|
31
|
+
pluginManager.addPlugins(options.plugins);
|
|
32
|
+
options.pluginManager = pluginManager;
|
|
33
|
+
|
|
34
|
+
context = new contexts.Parse(options);
|
|
35
|
+
|
|
36
|
+
if (options.rootFileInfo) {
|
|
37
|
+
rootFileInfo = options.rootFileInfo;
|
|
38
|
+
} else {
|
|
39
|
+
var filename = options.filename || "input";
|
|
40
|
+
var entryPath = filename.replace(/[^\/\\]*$/, "");
|
|
41
|
+
rootFileInfo = {
|
|
42
|
+
filename: filename,
|
|
43
|
+
relativeUrls: context.relativeUrls,
|
|
44
|
+
rootpath: context.rootpath || "",
|
|
45
|
+
currentDirectory: entryPath,
|
|
46
|
+
entryPath: entryPath,
|
|
47
|
+
rootFilename: filename
|
|
48
|
+
};
|
|
49
|
+
// add in a missing trailing slash
|
|
50
|
+
if (rootFileInfo.rootpath && rootFileInfo.rootpath.slice(-1) !== "/") {
|
|
51
|
+
rootFileInfo.rootpath += "/";
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
var imports = new ImportManager(context, rootFileInfo);
|
|
56
|
+
|
|
57
|
+
new Parser(context, imports, rootFileInfo)
|
|
58
|
+
.parse(input, function (e, root) {
|
|
59
|
+
if (e) { return callback(e); }
|
|
60
|
+
callback(null, root, imports, options);
|
|
61
|
+
}, options);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
return parse;
|
|
65
|
+
};
|
|
@@ -16,7 +16,8 @@ module.exports = function() {
|
|
|
16
16
|
saveStack.push( { current: current, i: parserInput.i, j: j });
|
|
17
17
|
};
|
|
18
18
|
parserInput.restore = function(possibleErrorMessage) {
|
|
19
|
-
|
|
19
|
+
|
|
20
|
+
if (parserInput.i > furthest || (parserInput.i === furthest && possibleErrorMessage && !furthestPossibleErrorMessage)) {
|
|
20
21
|
furthest = parserInput.i;
|
|
21
22
|
furthestPossibleErrorMessage = possibleErrorMessage;
|
|
22
23
|
}
|
|
@@ -238,7 +239,7 @@ module.exports = function() {
|
|
|
238
239
|
|
|
239
240
|
parserInput.end = function() {
|
|
240
241
|
var message,
|
|
241
|
-
isFinished = parserInput.i >= input.length
|
|
242
|
+
isFinished = parserInput.i >= input.length;
|
|
242
243
|
|
|
243
244
|
if (parserInput.i < furthest) {
|
|
244
245
|
message = furthestPossibleErrorMessage;
|
|
@@ -204,7 +204,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
204
204
|
// Ruleset (Selector '.class', [
|
|
205
205
|
// Rule ("color", Value ([Expression [Color #fff]]))
|
|
206
206
|
// Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
|
|
207
|
-
// Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
|
|
207
|
+
// Rule ("width", Value ([Expression [Operation " + " [Variable "@w"][Dimension 4px]]]))
|
|
208
208
|
// Ruleset (Selector [Element '>', '.child'], [...])
|
|
209
209
|
// ])
|
|
210
210
|
//
|
|
@@ -231,13 +231,17 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
231
231
|
primary: function () {
|
|
232
232
|
var mixin = this.mixin, root = [], node;
|
|
233
233
|
|
|
234
|
-
while (
|
|
234
|
+
while (true)
|
|
235
235
|
{
|
|
236
236
|
while(true) {
|
|
237
237
|
node = this.comment();
|
|
238
238
|
if (!node) { break; }
|
|
239
239
|
root.push(node);
|
|
240
240
|
}
|
|
241
|
+
// always process comments before deciding if finished
|
|
242
|
+
if (parserInput.finished) {
|
|
243
|
+
break;
|
|
244
|
+
}
|
|
241
245
|
if (parserInput.peek('}')) {
|
|
242
246
|
break;
|
|
243
247
|
}
|
|
@@ -450,7 +454,9 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
450
454
|
var rgb;
|
|
451
455
|
|
|
452
456
|
if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/))) {
|
|
453
|
-
|
|
457
|
+
// strip colons, brackets, whitespaces and other characters that should not
|
|
458
|
+
// definitely be part of color string
|
|
459
|
+
var colorCandidateString = rgb.input.match(/^#([\w]+).*/);
|
|
454
460
|
colorCandidateString = colorCandidateString[1];
|
|
455
461
|
if (!colorCandidateString.match(/^[A-Fa-f0-9]+$/)) { // verify if candidate consists only of allowed HEX characters
|
|
456
462
|
error("Invalid HEX color code");
|
|
@@ -546,8 +552,9 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
546
552
|
}
|
|
547
553
|
|
|
548
554
|
option = option && option[1];
|
|
549
|
-
if (!elements)
|
|
555
|
+
if (!elements) {
|
|
550
556
|
error("Missing target selector for :extend().");
|
|
557
|
+
}
|
|
551
558
|
extend = new(tree.Extend)(new(tree.Selector)(elements), option, index);
|
|
552
559
|
if (extendList) { extendList.push(extend); } else { extendList = [ extend ]; }
|
|
553
560
|
|
|
@@ -857,8 +864,10 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
857
864
|
|
|
858
865
|
c = this.combinator();
|
|
859
866
|
|
|
860
|
-
e = parserInput.$re(/^(?:\d+\.\d+|\d+)%/) ||
|
|
861
|
-
parserInput.$
|
|
867
|
+
e = parserInput.$re(/^(?:\d+\.\d+|\d+)%/) ||
|
|
868
|
+
parserInput.$re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) ||
|
|
869
|
+
parserInput.$char('*') || parserInput.$char('&') || this.attribute() ||
|
|
870
|
+
parserInput.$re(/^\([^&()@]+\)/) || parserInput.$re(/^[\.#:](?=@)/) ||
|
|
862
871
|
this.entities.variableCurly();
|
|
863
872
|
|
|
864
873
|
if (! e) {
|
|
@@ -1169,7 +1178,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1169
1178
|
},
|
|
1170
1179
|
|
|
1171
1180
|
importOption: function() {
|
|
1172
|
-
var opt = parserInput.$re(/^(less|css|multiple|once|inline|reference)/);
|
|
1181
|
+
var opt = parserInput.$re(/^(less|css|multiple|once|inline|reference|optional)/);
|
|
1173
1182
|
if (opt) {
|
|
1174
1183
|
return opt[1];
|
|
1175
1184
|
}
|
|
@@ -1383,15 +1392,19 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1383
1392
|
sub: function () {
|
|
1384
1393
|
var a, e;
|
|
1385
1394
|
|
|
1395
|
+
parserInput.save();
|
|
1386
1396
|
if (parserInput.$char('(')) {
|
|
1387
1397
|
a = this.addition();
|
|
1388
|
-
if (a) {
|
|
1398
|
+
if (a && parserInput.$char(')')) {
|
|
1399
|
+
parserInput.forget();
|
|
1389
1400
|
e = new(tree.Expression)([a]);
|
|
1390
|
-
expectChar(')');
|
|
1391
1401
|
e.parens = true;
|
|
1392
1402
|
return e;
|
|
1393
1403
|
}
|
|
1404
|
+
parserInput.restore("Expected ')'");
|
|
1405
|
+
return;
|
|
1394
1406
|
}
|
|
1407
|
+
parserInput.restore();
|
|
1395
1408
|
},
|
|
1396
1409
|
multiplication: function () {
|
|
1397
1410
|
var m, a, op, operation, isSpaced;
|
|
@@ -1598,8 +1611,8 @@ Parser.serializeVars = function(vars) {
|
|
|
1598
1611
|
for (var name in vars) {
|
|
1599
1612
|
if (Object.hasOwnProperty.call(vars, name)) {
|
|
1600
1613
|
var value = vars[name];
|
|
1601
|
-
s += ((name[0] === '@') ? '' : '@') + name +': '+ value +
|
|
1602
|
-
(((
|
|
1614
|
+
s += ((name[0] === '@') ? '' : '@') + name + ': ' + value +
|
|
1615
|
+
((String(value).slice(-1) === ';') ? '' : ';');
|
|
1603
1616
|
}
|
|
1604
1617
|
}
|
|
1605
1618
|
|