less 3.9.0 → 3.10.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/.DS_Store +0 -0
- package/.eslintignore +4 -1
- package/.eslintrc.json +69 -87
- package/CHANGELOG.md +7 -0
- package/Gruntfile.js +336 -330
- package/bin/lessc +13110 -481
- package/dist/less.cjs.js +12571 -0
- package/dist/less.js +12878 -11507
- package/dist/less.min.js +7 -14
- package/dist/less.min.js.map +1 -0
- package/index.js +1 -1
- package/lib/less/constants.js +12 -12
- package/lib/less/contexts.js +93 -95
- package/lib/less/data/colors.js +1 -1
- package/lib/less/data/index.js +4 -4
- package/lib/less/data/unit-conversions.js +1 -1
- package/lib/less/default-options.js +53 -58
- package/lib/less/environment/abstract-file-manager.js +114 -110
- package/lib/less/environment/abstract-plugin-loader.js +139 -141
- package/lib/less/environment/environment-api.js +1 -1
- package/lib/less/environment/environment.js +44 -41
- package/lib/less/environment/file-manager-api.js +1 -1
- package/lib/less/functions/boolean.js +10 -12
- package/lib/less/functions/color-blending.js +20 -10
- package/lib/less/functions/color.js +63 -49
- package/lib/less/functions/data-uri.js +25 -39
- package/lib/less/functions/default.js +5 -7
- package/lib/less/functions/function-caller.js +42 -39
- package/lib/less/functions/function-registry.js +3 -3
- package/lib/less/functions/index.js +28 -16
- package/lib/less/functions/list.js +34 -28
- package/lib/less/functions/math-helper.js +4 -5
- package/lib/less/functions/math.js +8 -9
- package/lib/less/functions/number.js +26 -18
- package/lib/less/functions/string.js +13 -13
- package/lib/less/functions/svg.js +25 -25
- package/lib/less/functions/types.js +23 -27
- package/lib/less/import-manager.js +140 -138
- package/lib/less/index.js +72 -35
- package/lib/less/less-error.js +29 -30
- package/lib/less/logger.js +4 -4
- package/lib/less/parse-tree.js +53 -47
- package/lib/less/parse.js +23 -25
- package/lib/less/parser/chunker.js +17 -7
- package/lib/less/parser/parser-input.js +100 -93
- package/lib/less/parser/parser.js +310 -170
- package/lib/less/plugin-manager.js +146 -133
- package/lib/less/render.js +10 -13
- package/lib/less/source-map-builder.js +62 -57
- package/lib/less/source-map-output.js +118 -112
- package/lib/less/transform-tree.js +21 -18
- package/lib/less/tree/anonymous.js +35 -27
- package/lib/less/tree/assignment.js +29 -23
- package/lib/less/tree/atrule.js +150 -121
- package/lib/less/tree/attribute.js +32 -25
- package/lib/less/tree/call.js +87 -79
- package/lib/less/tree/color.js +202 -185
- package/lib/less/tree/combinator.js +25 -19
- package/lib/less/tree/comment.js +27 -21
- package/lib/less/tree/condition.js +41 -35
- package/lib/less/tree/debug-info.js +13 -17
- package/lib/less/tree/declaration.js +101 -88
- package/lib/less/tree/detached-ruleset.js +27 -20
- package/lib/less/tree/dimension.js +142 -124
- package/lib/less/tree/element.js +67 -58
- package/lib/less/tree/expression.js +66 -57
- package/lib/less/tree/extend.js +61 -53
- package/lib/less/tree/import.js +144 -141
- package/lib/less/tree/index.js +52 -40
- package/lib/less/tree/javascript.js +29 -25
- package/lib/less/tree/js-eval-node.js +50 -53
- package/lib/less/tree/keyword.js +15 -8
- package/lib/less/tree/media.js +137 -124
- package/lib/less/tree/mixin-call.js +178 -149
- package/lib/less/tree/mixin-definition.js +198 -178
- package/lib/less/tree/namespace-value.js +75 -67
- package/lib/less/tree/negative.js +24 -18
- package/lib/less/tree/node.js +138 -117
- package/lib/less/tree/operation.js +57 -49
- package/lib/less/tree/paren.js +20 -14
- package/lib/less/tree/property.js +65 -58
- package/lib/less/tree/quoted.js +62 -53
- package/lib/less/tree/ruleset.js +739 -680
- package/lib/less/tree/selector.js +129 -114
- package/lib/less/tree/unicode-descriptor.js +10 -6
- package/lib/less/tree/unit.js +117 -97
- package/lib/less/tree/url.js +54 -47
- package/lib/less/tree/value.js +38 -33
- package/lib/less/tree/variable-call.js +41 -34
- package/lib/less/tree/variable.js +58 -51
- package/lib/less/utils.js +110 -108
- package/lib/less/visitors/extend-visitor.js +157 -114
- package/lib/less/visitors/import-sequencer.js +47 -43
- package/lib/less/visitors/import-visitor.js +22 -23
- package/lib/less/visitors/index.js +14 -9
- package/lib/less/visitors/join-selector-visitor.js +32 -26
- package/lib/less/visitors/set-tree-visibility-visitor.js +37 -30
- package/lib/less/visitors/to-css-visitor.js +60 -57
- package/lib/less/visitors/visitor.js +44 -35
- package/lib/less-browser/add-default-options.js +4 -4
- package/lib/less-browser/bootstrap.js +11 -9
- package/lib/less-browser/browser.js +13 -12
- package/lib/less-browser/cache.js +9 -9
- package/lib/less-browser/error-reporting.js +27 -27
- package/lib/less-browser/file-manager.js +37 -35
- package/lib/less-browser/image-size.js +3 -3
- package/lib/less-browser/index.js +78 -73
- package/lib/less-browser/log-listener.js +6 -7
- package/lib/less-browser/plugin-loader.js +15 -13
- package/lib/less-browser/utils.js +20 -20
- package/lib/less-node/environment.js +4 -2
- package/lib/less-node/file-manager.js +128 -127
- package/lib/less-node/fs.js +2 -2
- package/lib/less-node/image-size.js +19 -18
- package/lib/less-node/index.js +16 -12
- package/lib/less-node/lessc-helper.js +4 -5
- package/lib/less-node/plugin-loader.js +41 -40
- package/lib/less-node/url-file-manager.js +41 -48
- package/lib/lessc.js +557 -0
- package/package.json +21 -11
- package/test/.DS_Store +0 -0
- package/test/browser/common.js +34 -30
- package/test/browser/css/urls.css +0 -3
- package/test/browser/less/plugin/plugin.js +4 -7
- package/test/browser/less/urls.less +0 -3
- package/test/browser/less.min.js +11 -0
- package/test/browser/less.min.js.map +1 -0
- package/test/browser/onload.js +13 -0
- package/test/browser/runner-browser-options.js +0 -5
- package/test/browser/test-runner-template.tmpl +39 -52
- package/test/browser/vendor/boot.js +148 -0
- package/test/browser/{jasmine-jsreporter.js → vendor/jasmine-jsreporter.js} +0 -0
- package/test/copy-bom.js +2 -1
- package/test/css/.DS_Store +0 -0
- package/test/css/functions-each.css +10 -0
- package/test/css/math/.DS_Store +0 -0
- package/test/css/namespacing/namespacing-1.css +4 -0
- package/test/css/urls.css +0 -1
- package/test/index.js +2 -5
- package/test/less/.DS_Store +0 -0
- package/test/less/colors.less +1 -1
- package/test/less/errors/color-func-invalid-color-2.less +2 -0
- package/test/less/errors/color-func-invalid-color-2.txt +3 -0
- package/test/less/functions-each.less +32 -0
- package/test/less/math/.DS_Store +0 -0
- package/test/less/namespacing/namespacing-1.less +10 -0
- package/test/less/urls.less +0 -1
- package/test/less-test.js +20 -11
- package/test/modify-vars.js +11 -2
- package/.travis.yml +0 -33
- package/appveyor.yml +0 -32
- package/browser.js +0 -1
- package/test/browser/less.js +0 -12956
- package/test/less-bom/3rd-party/bootstrap4.less +0 -1
- package/test/less-bom/3rd-party/uikit.less +0 -1
- package/test/less-bom/calc.less +0 -30
- package/test/less-bom/charsets.less +0 -3
- package/test/less-bom/colors.less +0 -116
- package/test/less-bom/comments.less +0 -102
- package/test/less-bom/comments2.less +0 -31
- package/test/less-bom/compression/compression.less +0 -36
- package/test/less-bom/css-3.less +0 -153
- package/test/less-bom/css-escapes.less +0 -42
- package/test/less-bom/css-grid.less +0 -30
- package/test/less-bom/css-guards.less +0 -103
- package/test/less-bom/debug/import/test.less +0 -25
- package/test/less-bom/debug/linenumbers.less +0 -33
- package/test/less-bom/detached-rulesets.less +0 -112
- package/test/less-bom/directives-bubling.less +0 -142
- package/test/less-bom/empty.less +0 -1
- package/test/less-bom/errors/add-mixed-units.less +0 -3
- package/test/less-bom/errors/add-mixed-units.txt +0 -4
- package/test/less-bom/errors/add-mixed-units2.less +0 -3
- package/test/less-bom/errors/add-mixed-units2.txt +0 -4
- package/test/less-bom/errors/at-rules-undefined-var.less +0 -4
- package/test/less-bom/errors/at-rules-undefined-var.txt +0 -4
- package/test/less-bom/errors/at-rules-unmatching-block.less +0 -4
- package/test/less-bom/errors/at-rules-unmatching-block.txt +0 -3
- package/test/less-bom/errors/bad-variable-declaration1.less +0 -1
- package/test/less-bom/errors/bad-variable-declaration1.txt +0 -2
- package/test/less-bom/errors/color-func-invalid-color.less +0 -3
- package/test/less-bom/errors/color-func-invalid-color.txt +0 -4
- package/test/less-bom/errors/css-guard-default-func.less +0 -4
- package/test/less-bom/errors/css-guard-default-func.txt +0 -4
- package/test/less-bom/errors/custom-property-unmatched-block-1.less +0 -6
- package/test/less-bom/errors/custom-property-unmatched-block-1.txt +0 -4
- package/test/less-bom/errors/custom-property-unmatched-block-2.less +0 -6
- package/test/less-bom/errors/custom-property-unmatched-block-2.txt +0 -4
- package/test/less-bom/errors/custom-property-unmatched-block-3.less +0 -6
- package/test/less-bom/errors/custom-property-unmatched-block-3.txt +0 -4
- package/test/less-bom/errors/detached-ruleset-1.less +0 -6
- package/test/less-bom/errors/detached-ruleset-1.txt +0 -4
- package/test/less-bom/errors/detached-ruleset-2.less +0 -6
- package/test/less-bom/errors/detached-ruleset-2.txt +0 -4
- package/test/less-bom/errors/detached-ruleset-3.less +0 -4
- package/test/less-bom/errors/detached-ruleset-3.txt +0 -4
- package/test/less-bom/errors/detached-ruleset-5.less +0 -4
- package/test/less-bom/errors/detached-ruleset-5.txt +0 -3
- package/test/less-bom/errors/detached-ruleset-6.less +0 -5
- package/test/less-bom/errors/detached-ruleset-6.txt +0 -4
- package/test/less-bom/errors/divide-mixed-units.less +0 -3
- package/test/less-bom/errors/divide-mixed-units.txt +0 -4
- package/test/less-bom/errors/extend-no-selector.less +0 -3
- package/test/less-bom/errors/extend-no-selector.txt +0 -3
- package/test/less-bom/errors/extend-not-at-end.less +0 -3
- package/test/less-bom/errors/extend-not-at-end.txt +0 -3
- package/test/less-bom/errors/functions-1.less +0 -2
- package/test/less-bom/errors/functions-1.txt +0 -3
- package/test/less-bom/errors/functions-10-keyword.less +0 -2
- package/test/less-bom/errors/functions-10-keyword.txt +0 -3
- package/test/less-bom/errors/functions-11-operation.less +0 -2
- package/test/less-bom/errors/functions-11-operation.txt +0 -3
- package/test/less-bom/errors/functions-12-quoted.less +0 -2
- package/test/less-bom/errors/functions-12-quoted.txt +0 -3
- package/test/less-bom/errors/functions-13-selector.less +0 -2
- package/test/less-bom/errors/functions-13-selector.txt +0 -3
- package/test/less-bom/errors/functions-14-url.less +0 -2
- package/test/less-bom/errors/functions-14-url.txt +0 -3
- package/test/less-bom/errors/functions-15-value.less +0 -2
- package/test/less-bom/errors/functions-15-value.txt +0 -3
- package/test/less-bom/errors/functions-3-assignment.less +0 -2
- package/test/less-bom/errors/functions-3-assignment.txt +0 -3
- package/test/less-bom/errors/functions-4-call.less +0 -2
- package/test/less-bom/errors/functions-4-call.txt +0 -3
- package/test/less-bom/errors/functions-5-color-2.less +0 -1
- package/test/less-bom/errors/functions-5-color-2.txt +0 -2
- package/test/less-bom/errors/functions-5-color.less +0 -2
- package/test/less-bom/errors/functions-5-color.txt +0 -3
- package/test/less-bom/errors/functions-6-condition.less +0 -2
- package/test/less-bom/errors/functions-6-condition.txt +0 -3
- package/test/less-bom/errors/functions-7-dimension.less +0 -2
- package/test/less-bom/errors/functions-7-dimension.txt +0 -3
- package/test/less-bom/errors/functions-8-element.less +0 -2
- package/test/less-bom/errors/functions-8-element.txt +0 -3
- package/test/less-bom/errors/functions-9-expression.less +0 -2
- package/test/less-bom/errors/functions-9-expression.txt +0 -3
- package/test/less-bom/errors/import-malformed.less +0 -1
- package/test/less-bom/errors/import-malformed.txt +0 -3
- package/test/less-bom/errors/import-missing.less +0 -6
- package/test/less-bom/errors/import-missing.txt +0 -3
- package/test/less-bom/errors/import-no-semi.less +0 -1
- package/test/less-bom/errors/import-no-semi.txt +0 -2
- package/test/less-bom/errors/import-subfolder1.less +0 -1
- package/test/less-bom/errors/import-subfolder1.txt +0 -3
- package/test/less-bom/errors/import-subfolder2.less +0 -1
- package/test/less-bom/errors/import-subfolder2.txt +0 -4
- package/test/less-bom/errors/imports/import-subfolder1.less +0 -1
- package/test/less-bom/errors/imports/import-subfolder2.less +0 -1
- package/test/less-bom/errors/imports/import-test.less +0 -4
- package/test/less-bom/errors/imports/subfolder/mixin-not-defined.less +0 -1
- package/test/less-bom/errors/imports/subfolder/parse-error-curly-bracket.less +0 -1
- package/test/less-bom/errors/javascript-error.less +0 -3
- package/test/less-bom/errors/javascript-error.txt +0 -4
- package/test/less-bom/errors/javascript-undefined-var.less +0 -3
- package/test/less-bom/errors/javascript-undefined-var.txt +0 -4
- package/test/less-bom/errors/mixed-mixin-definition-args-1.less +0 -6
- package/test/less-bom/errors/mixed-mixin-definition-args-1.txt +0 -4
- package/test/less-bom/errors/mixed-mixin-definition-args-2.less +0 -6
- package/test/less-bom/errors/mixed-mixin-definition-args-2.txt +0 -4
- package/test/less-bom/errors/mixin-not-defined-2.less +0 -7
- package/test/less-bom/errors/mixin-not-defined-2.txt +0 -4
- package/test/less-bom/errors/mixin-not-defined.less +0 -11
- package/test/less-bom/errors/mixin-not-defined.txt +0 -3
- package/test/less-bom/errors/mixin-not-matched.less +0 -6
- package/test/less-bom/errors/mixin-not-matched.txt +0 -3
- package/test/less-bom/errors/mixin-not-matched2.less +0 -6
- package/test/less-bom/errors/mixin-not-matched2.txt +0 -3
- package/test/less-bom/errors/mixin-not-visible-in-scope-1.less +0 -9
- package/test/less-bom/errors/mixin-not-visible-in-scope-1.txt +0 -4
- package/test/less-bom/errors/mixins-guards-cond-expected.less +0 -5
- package/test/less-bom/errors/mixins-guards-cond-expected.txt +0 -3
- package/test/less-bom/errors/mixins-guards-default-func-1.less +0 -9
- package/test/less-bom/errors/mixins-guards-default-func-1.txt +0 -4
- package/test/less-bom/errors/mixins-guards-default-func-2.less +0 -9
- package/test/less-bom/errors/mixins-guards-default-func-2.txt +0 -4
- package/test/less-bom/errors/mixins-guards-default-func-3.less +0 -9
- package/test/less-bom/errors/mixins-guards-default-func-3.txt +0 -4
- package/test/less-bom/errors/multiple-guards-on-css-selectors.less +0 -4
- package/test/less-bom/errors/multiple-guards-on-css-selectors.txt +0 -4
- package/test/less-bom/errors/multiple-guards-on-css-selectors2.less +0 -4
- package/test/less-bom/errors/multiple-guards-on-css-selectors2.txt +0 -4
- package/test/less-bom/errors/multiply-mixed-units.less +0 -7
- package/test/less-bom/errors/multiply-mixed-units.txt +0 -4
- package/test/less-bom/errors/namespacing-2.less +0 -7
- package/test/less-bom/errors/namespacing-2.txt +0 -4
- package/test/less-bom/errors/namespacing-3.less +0 -8
- package/test/less-bom/errors/namespacing-3.txt +0 -4
- package/test/less-bom/errors/namespacing-4.less +0 -7
- package/test/less-bom/errors/namespacing-4.txt +0 -4
- package/test/less-bom/errors/parens-error-1.less +0 -3
- package/test/less-bom/errors/parens-error-1.txt +0 -4
- package/test/less-bom/errors/parens-error-2.less +0 -3
- package/test/less-bom/errors/parens-error-2.txt +0 -4
- package/test/less-bom/errors/parens-error-3.less +0 -3
- package/test/less-bom/errors/parens-error-3.txt +0 -4
- package/test/less-bom/errors/parse-error-curly-bracket.less +0 -4
- package/test/less-bom/errors/parse-error-curly-bracket.txt +0 -4
- package/test/less-bom/errors/parse-error-media-no-block-1.less +0 -5
- package/test/less-bom/errors/parse-error-media-no-block-1.txt +0 -3
- package/test/less-bom/errors/parse-error-media-no-block-2.less +0 -1
- package/test/less-bom/errors/parse-error-media-no-block-2.txt +0 -2
- package/test/less-bom/errors/parse-error-media-no-block-3.less +0 -4
- package/test/less-bom/errors/parse-error-media-no-block-3.txt +0 -3
- package/test/less-bom/errors/parse-error-missing-bracket.less +0 -2
- package/test/less-bom/errors/parse-error-missing-bracket.txt +0 -3
- package/test/less-bom/errors/parse-error-missing-parens.less +0 -5
- package/test/less-bom/errors/parse-error-missing-parens.txt +0 -3
- package/test/less-bom/errors/parse-error-with-import.less +0 -13
- package/test/less-bom/errors/parse-error-with-import.txt +0 -4
- package/test/less-bom/errors/percentage-missing-space.less +0 -3
- package/test/less-bom/errors/percentage-missing-space.txt +0 -4
- package/test/less-bom/errors/percentage-non-number-argument.less +0 -3
- package/test/less-bom/errors/percentage-non-number-argument.txt +0 -4
- package/test/less-bom/errors/plugin/plugin-error-2.js +0 -5
- package/test/less-bom/errors/plugin/plugin-error-3.js +0 -5
- package/test/less-bom/errors/plugin/plugin-error.js +0 -1
- package/test/less-bom/errors/plugin-1.less +0 -1
- package/test/less-bom/errors/plugin-1.txt +0 -2
- package/test/less-bom/errors/plugin-2.less +0 -1
- package/test/less-bom/errors/plugin-2.txt +0 -5
- package/test/less-bom/errors/plugin-3.less +0 -1
- package/test/less-bom/errors/plugin-3.txt +0 -5
- package/test/less-bom/errors/property-asterisk-only-name.less +0 -3
- package/test/less-bom/errors/property-asterisk-only-name.txt +0 -4
- package/test/less-bom/errors/property-ie5-hack.less +0 -3
- package/test/less-bom/errors/property-ie5-hack.txt +0 -3
- package/test/less-bom/errors/property-in-root.less +0 -4
- package/test/less-bom/errors/property-in-root.txt +0 -4
- package/test/less-bom/errors/property-in-root2.less +0 -1
- package/test/less-bom/errors/property-in-root2.txt +0 -4
- package/test/less-bom/errors/property-in-root3.less +0 -4
- package/test/less-bom/errors/property-in-root3.txt +0 -3
- package/test/less-bom/errors/property-interp-not-defined.less +0 -1
- package/test/less-bom/errors/property-interp-not-defined.txt +0 -2
- package/test/less-bom/errors/recursive-variable.less +0 -1
- package/test/less-bom/errors/recursive-variable.txt +0 -2
- package/test/less-bom/errors/root-func-undefined-1.less +0 -1
- package/test/less-bom/errors/root-func-undefined-1.txt +0 -2
- package/test/less-bom/errors/root-func-undefined-2.less +0 -2
- package/test/less-bom/errors/root-func-undefined-2.txt +0 -3
- package/test/less-bom/errors/single-character.less +0 -1
- package/test/less-bom/errors/single-character.txt +0 -2
- package/test/less-bom/errors/svg-gradient1.less +0 -3
- package/test/less-bom/errors/svg-gradient1.txt +0 -4
- package/test/less-bom/errors/svg-gradient2.less +0 -3
- package/test/less-bom/errors/svg-gradient2.txt +0 -4
- package/test/less-bom/errors/svg-gradient3.less +0 -3
- package/test/less-bom/errors/svg-gradient3.txt +0 -4
- package/test/less-bom/errors/svg-gradient4.less +0 -4
- package/test/less-bom/errors/svg-gradient4.txt +0 -4
- package/test/less-bom/errors/svg-gradient5.less +0 -4
- package/test/less-bom/errors/svg-gradient5.txt +0 -4
- package/test/less-bom/errors/svg-gradient6.less +0 -4
- package/test/less-bom/errors/svg-gradient6.txt +0 -4
- package/test/less-bom/errors/unit-function.less +0 -3
- package/test/less-bom/errors/unit-function.txt +0 -4
- package/test/less-bom/extend-chaining.less +0 -91
- package/test/less-bom/extend-clearfix.less +0 -19
- package/test/less-bom/extend-exact.less +0 -46
- package/test/less-bom/extend-media.less +0 -24
- package/test/less-bom/extend-nest.less +0 -65
- package/test/less-bom/extend-selector.less +0 -110
- package/test/less-bom/extend.less +0 -81
- package/test/less-bom/extract-and-length.less +0 -146
- package/test/less-bom/filemanagerPlugin/colors.test +0 -1
- package/test/less-bom/filemanagerPlugin/filemanager.less +0 -4
- package/test/less-bom/functions-each.less +0 -131
- package/test/less-bom/functions.less +0 -279
- package/test/less-bom/globalVars/extended.json +0 -5
- package/test/less-bom/globalVars/extended.less +0 -10
- package/test/less-bom/globalVars/simple.json +0 -3
- package/test/less-bom/globalVars/simple.less +0 -3
- package/test/less-bom/ie-filters.less +0 -15
- package/test/less-bom/import/css-import.less +0 -1
- package/test/less-bom/import/deeper/deeper-2/url-import-2.less +0 -3
- package/test/less-bom/import/deeper/deeper-2/url-import.less +0 -1
- package/test/less-bom/import/deeper/import-once-test-a.less +0 -1
- package/test/less-bom/import/deeper/url-import.less +0 -1
- package/test/less-bom/import/import-and-relative-paths-test.less +0 -17
- package/test/less-bom/import/import-charset-test.less +0 -1
- package/test/less-bom/import/import-inline-invalid-css.less +0 -1
- package/test/less-bom/import/import-interpolation.less +0 -2
- package/test/less-bom/import/import-interpolation2.less +0 -5
- package/test/less-bom/import/import-once-test-c.less +0 -6
- package/test/less-bom/import/import-reference.less +0 -98
- package/test/less-bom/import/import-test-a.less +0 -5
- package/test/less-bom/import/import-test-b.less +0 -8
- package/test/less-bom/import/import-test-c.less +0 -6
- package/test/less-bom/import/import-test-d.css +0 -1
- package/test/less-bom/import/import-test-e.less +0 -2
- package/test/less-bom/import/import-test-f.less +0 -5
- package/test/less-bom/import/imports/font.less +0 -8
- package/test/less-bom/import/imports/logo.less +0 -6
- package/test/less-bom/import/interpolation-vars.less +0 -6
- package/test/less-bom/import/invalid-css.less +0 -1
- package/test/less-bom/import/urls.less +0 -1
- package/test/less-bom/import-inline.less +0 -3
- package/test/less-bom/import-interpolation.less +0 -8
- package/test/less-bom/import-module.less +0 -3
- package/test/less-bom/import-once.less +0 -6
- package/test/less-bom/import-reference-issues/appender-reference-1968.less +0 -6
- package/test/less-bom/import-reference-issues/global-scope-import.less +0 -13
- package/test/less-bom/import-reference-issues/global-scope-nested.less +0 -3
- package/test/less-bom/import-reference-issues/mixin-1968.less +0 -8
- package/test/less-bom/import-reference-issues/multiple-import-nested.less +0 -12
- package/test/less-bom/import-reference-issues/multiple-import.less +0 -10
- package/test/less-bom/import-reference-issues/simple-mixin.css +0 -3
- package/test/less-bom/import-reference-issues/simple-ruleset-2162.less +0 -3
- package/test/less-bom/import-reference-issues.less +0 -50
- package/test/less-bom/import-reference.less +0 -26
- package/test/less-bom/import.less +0 -29
- package/test/less-bom/include-path/include-path.less +0 -8
- package/test/less-bom/include-path-string/include-path-string.less +0 -3
- package/test/less-bom/javascript.less +0 -39
- package/test/less-bom/lazy-eval.less +0 -6
- package/test/less-bom/legacy/legacy.less +0 -21
- package/test/less-bom/math/parens-division/media-math.less +0 -9
- package/test/less-bom/math/parens-division/mixins-args.less +0 -264
- package/test/less-bom/math/parens-division/new-division.less +0 -17
- package/test/less-bom/math/parens-division/parens.less +0 -46
- package/test/less-bom/math/strict/css.less +0 -108
- package/test/less-bom/math/strict/media-math.less +0 -9
- package/test/less-bom/math/strict/mixins-args.less +0 -264
- package/test/less-bom/math/strict/parens.less +0 -46
- package/test/less-bom/math/strict-legacy/css.less +0 -108
- package/test/less-bom/math/strict-legacy/media-math.less +0 -9
- package/test/less-bom/math/strict-legacy/mixins-args.less +0 -263
- package/test/less-bom/math/strict-legacy/parens.less +0 -50
- package/test/less-bom/media.less +0 -241
- package/test/less-bom/merge.less +0 -81
- package/test/less-bom/mixins-closure.less +0 -26
- package/test/less-bom/mixins-guards-default-func.less +0 -195
- package/test/less-bom/mixins-guards.less +0 -358
- package/test/less-bom/mixins-important.less +0 -53
- package/test/less-bom/mixins-interpolated.less +0 -75
- package/test/less-bom/mixins-named-args.less +0 -36
- package/test/less-bom/mixins-nested.less +0 -22
- package/test/less-bom/mixins-pattern.less +0 -102
- package/test/less-bom/mixins.less +0 -145
- package/test/less-bom/modifyVars/extended.json +0 -5
- package/test/less-bom/modifyVars/extended.less +0 -11
- package/test/less-bom/namespacing/imports/a-better-bootstrap.less +0 -13
- package/test/less-bom/namespacing/imports/library.less +0 -14
- package/test/less-bom/namespacing/namespacing-1.less +0 -42
- package/test/less-bom/namespacing/namespacing-2.less +0 -27
- package/test/less-bom/namespacing/namespacing-3.less +0 -28
- package/test/less-bom/namespacing/namespacing-4.less +0 -33
- package/test/less-bom/namespacing/namespacing-5.less +0 -32
- package/test/less-bom/namespacing/namespacing-6.less +0 -26
- package/test/less-bom/namespacing/namespacing-7.less +0 -48
- package/test/less-bom/namespacing/namespacing-functions.less +0 -11
- package/test/less-bom/namespacing/namespacing-media.less +0 -26
- package/test/less-bom/namespacing/namespacing-operations.less +0 -15
- package/test/less-bom/nested-gradient-with-svg-gradient/mixin-consumer.less +0 -5
- package/test/less-bom/nested-gradient-with-svg-gradient/svg-gradient-mixin.less +0 -15
- package/test/less-bom/no-js-errors/no-js-errors.less +0 -3
- package/test/less-bom/no-js-errors/no-js-errors.txt +0 -4
- package/test/less-bom/no-output.less +0 -2
- package/test/less-bom/no-strict-math/mixins-guards.less +0 -25
- package/test/less-bom/no-strict-math/no-sm-operations.less +0 -16
- package/test/less-bom/operations.less +0 -63
- package/test/less-bom/parse-interpolation.less +0 -53
- package/test/less-bom/permissive-parse.less +0 -50
- package/test/less-bom/plugin/plugin-collection.js +0 -9
- package/test/less-bom/plugin/plugin-global.js +0 -9
- package/test/less-bom/plugin/plugin-local.js +0 -14
- package/test/less-bom/plugin/plugin-preeval.js +0 -27
- package/test/less-bom/plugin/plugin-scope1.js +0 -3
- package/test/less-bom/plugin/plugin-scope2.js +0 -3
- package/test/less-bom/plugin/plugin-set-options-v2.js +0 -33
- package/test/less-bom/plugin/plugin-set-options-v3.js +0 -31
- package/test/less-bom/plugin/plugin-set-options.js +0 -32
- package/test/less-bom/plugin/plugin-simple.js +0 -7
- package/test/less-bom/plugin/plugin-transitive.js +0 -6
- package/test/less-bom/plugin/plugin-transitive.less +0 -5
- package/test/less-bom/plugin/plugin-tree-nodes.js +0 -82
- package/test/less-bom/plugin-module.less +0 -7
- package/test/less-bom/plugin-preeval.less +0 -15
- package/test/less-bom/plugin.less +0 -142
- package/test/less-bom/postProcessorPlugin/postProcessor.less +0 -4
- package/test/less-bom/preProcessorPlugin/preProcessor.less +0 -3
- package/test/less-bom/property-accessors.less +0 -67
- package/test/less-bom/property-name-interp.less +0 -56
- package/test/less-bom/rewrite-urls-all/folder/file.less +0 -8
- package/test/less-bom/rewrite-urls-all/rewrite-urls-all.less +0 -11
- package/test/less-bom/rewrite-urls-local/folder/file.less +0 -8
- package/test/less-bom/rewrite-urls-local/rewrite-urls-local.less +0 -11
- package/test/less-bom/root-registry/file.less +0 -1
- package/test/less-bom/root-registry/root.less +0 -3
- package/test/less-bom/rootpath-rewrite-urls-all/folder/file.less +0 -8
- package/test/less-bom/rootpath-rewrite-urls-all/rootpath-rewrite-urls-all.less +0 -11
- package/test/less-bom/rootpath-rewrite-urls-local/folder/file.less +0 -8
- package/test/less-bom/rootpath-rewrite-urls-local/rootpath-rewrite-urls-local.less +0 -11
- package/test/less-bom/rulesets.less +0 -30
- package/test/less-bom/scope.less +0 -104
- package/test/less-bom/selectors.less +0 -184
- package/test/less-bom/sourcemaps/basic.json +0 -3
- package/test/less-bom/sourcemaps/basic.less +0 -27
- package/test/less-bom/sourcemaps/custom-props.less +0 -8
- package/test/less-bom/sourcemaps/imported.css +0 -7
- package/test/less-bom/sourcemaps-empty/empty.less +0 -1
- package/test/less-bom/sourcemaps-empty/var-defs.less +0 -1
- package/test/less-bom/static-urls/urls.less +0 -33
- package/test/less-bom/strict-units/strict-units.less +0 -4
- package/test/less-bom/strings.less +0 -73
- package/test/less-bom/url-args/urls.less +0 -63
- package/test/less-bom/urls.less +0 -94
- package/test/less-bom/variables-in-at-rules.less +0 -20
- package/test/less-bom/variables.less +0 -127
- package/test/less-bom/visitorPlugin/visitor.less +0 -4
- package/test/less-bom/whitespace.less +0 -44
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import LessError from '../less-error';
|
|
2
|
+
import tree from '../tree';
|
|
3
|
+
import visitors from '../visitors';
|
|
4
|
+
import getParserInput from './parser-input';
|
|
5
|
+
import * as utils from '../utils';
|
|
6
|
+
import functionRegistry from '../functions/function-registry';
|
|
7
7
|
|
|
8
8
|
//
|
|
9
9
|
// less.js - parser
|
|
@@ -38,9 +38,9 @@ var LessError = require('../less-error'),
|
|
|
38
38
|
// It also takes care of moving all the indices forwards.
|
|
39
39
|
//
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
const Parser = function Parser(context, imports, fileInfo) {
|
|
42
|
+
let parsers;
|
|
43
|
+
const parserInput = getParserInput();
|
|
44
44
|
|
|
45
45
|
function error(msg, type) {
|
|
46
46
|
throw new LessError(
|
|
@@ -56,13 +56,13 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
56
56
|
|
|
57
57
|
function expect(arg, msg) {
|
|
58
58
|
// some older browsers return typeof 'function' for RegExp
|
|
59
|
-
|
|
59
|
+
const result = (arg instanceof Function) ? arg.call(parsers) : parserInput.$re(arg);
|
|
60
60
|
if (result) {
|
|
61
61
|
return result;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
error(msg || (typeof arg === 'string'
|
|
65
|
-
?
|
|
65
|
+
? `expected '${arg}' got '${parserInput.currentChar()}'`
|
|
66
66
|
: 'unexpected token'));
|
|
67
67
|
}
|
|
68
68
|
|
|
@@ -71,11 +71,11 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
71
71
|
if (parserInput.$char(arg)) {
|
|
72
72
|
return arg;
|
|
73
73
|
}
|
|
74
|
-
error(msg ||
|
|
74
|
+
error(msg || `expected '${arg}' got '${parserInput.currentChar()}'`);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
function getDebugInfo(index) {
|
|
78
|
-
|
|
78
|
+
const filename = fileInfo.filename;
|
|
79
79
|
|
|
80
80
|
return {
|
|
81
81
|
lineNumber: utils.getLocation(index, parserInput.getInput()).line + 1,
|
|
@@ -92,8 +92,9 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
92
92
|
* @param {Object} fileInfo - fileInfo to attach to created nodes
|
|
93
93
|
*/
|
|
94
94
|
function parseNode(str, parseList, currentIndex, fileInfo, callback) {
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
let result;
|
|
96
|
+
const returnNodes = [];
|
|
97
|
+
const parser = parserInput;
|
|
97
98
|
|
|
98
99
|
try {
|
|
99
100
|
parser.start(str, false, function fail(msg, index) {
|
|
@@ -102,7 +103,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
102
103
|
index: index + currentIndex
|
|
103
104
|
});
|
|
104
105
|
});
|
|
105
|
-
for (
|
|
106
|
+
for (let x = 0, p, i; (p = parseList[x]); x++) {
|
|
106
107
|
i = parser.i;
|
|
107
108
|
result = parsers[p]();
|
|
108
109
|
if (result) {
|
|
@@ -115,7 +116,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
115
116
|
}
|
|
116
117
|
}
|
|
117
118
|
|
|
118
|
-
|
|
119
|
+
const endInfo = parser.end();
|
|
119
120
|
if (endInfo.isFinished) {
|
|
120
121
|
callback(null, returnNodes);
|
|
121
122
|
}
|
|
@@ -129,15 +130,15 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
129
130
|
}, imports, fileInfo.filename);
|
|
130
131
|
}
|
|
131
132
|
}
|
|
132
|
-
|
|
133
|
+
|
|
133
134
|
//
|
|
134
135
|
// The Parser
|
|
135
136
|
//
|
|
136
137
|
return {
|
|
137
|
-
parserInput
|
|
138
|
-
imports
|
|
139
|
-
fileInfo
|
|
140
|
-
parseNode
|
|
138
|
+
parserInput,
|
|
139
|
+
imports,
|
|
140
|
+
fileInfo,
|
|
141
|
+
parseNode,
|
|
141
142
|
//
|
|
142
143
|
// Parse an input string into an abstract syntax tree,
|
|
143
144
|
// @param str A string containing 'less' markup
|
|
@@ -145,15 +146,20 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
145
146
|
// @param [additionalData] An optional map which can contains vars - a map (key, value) of variables to apply
|
|
146
147
|
//
|
|
147
148
|
parse: function (str, callback, additionalData) {
|
|
148
|
-
|
|
149
|
+
let root;
|
|
150
|
+
let error = null;
|
|
151
|
+
let globalVars;
|
|
152
|
+
let modifyVars;
|
|
153
|
+
let ignored;
|
|
154
|
+
let preText = '';
|
|
149
155
|
|
|
150
|
-
globalVars = (additionalData && additionalData.globalVars) ? Parser.serializeVars(additionalData.globalVars)
|
|
151
|
-
modifyVars = (additionalData && additionalData.modifyVars) ?
|
|
156
|
+
globalVars = (additionalData && additionalData.globalVars) ? `${Parser.serializeVars(additionalData.globalVars)}\n` : '';
|
|
157
|
+
modifyVars = (additionalData && additionalData.modifyVars) ? `\n${Parser.serializeVars(additionalData.modifyVars)}` : '';
|
|
152
158
|
|
|
153
159
|
if (context.pluginManager) {
|
|
154
|
-
|
|
155
|
-
for (
|
|
156
|
-
str = preProcessors[i].process(str, { context
|
|
160
|
+
const preProcessors = context.pluginManager.getPreProcessors();
|
|
161
|
+
for (let i = 0; i < preProcessors.length; i++) {
|
|
162
|
+
str = preProcessors[i].process(str, { context, imports, fileInfo });
|
|
157
163
|
}
|
|
158
164
|
}
|
|
159
165
|
|
|
@@ -176,7 +182,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
176
182
|
try {
|
|
177
183
|
parserInput.start(str, context.chunkInput, function fail(msg, index) {
|
|
178
184
|
throw new LessError({
|
|
179
|
-
index
|
|
185
|
+
index,
|
|
180
186
|
type: 'Parse',
|
|
181
187
|
message: msg,
|
|
182
188
|
filename: fileInfo.filename
|
|
@@ -202,10 +208,10 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
202
208
|
// showing the line where the parse error occurred.
|
|
203
209
|
// We split it up into two parts (the part which parsed,
|
|
204
210
|
// and the part which didn't), so we can color them differently.
|
|
205
|
-
|
|
211
|
+
const endInfo = parserInput.end();
|
|
206
212
|
if (!endInfo.isFinished) {
|
|
207
213
|
|
|
208
|
-
|
|
214
|
+
let message = endInfo.furthestPossibleErrorMessage;
|
|
209
215
|
|
|
210
216
|
if (!message) {
|
|
211
217
|
message = 'Unrecognised input';
|
|
@@ -220,13 +226,13 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
220
226
|
|
|
221
227
|
error = new LessError({
|
|
222
228
|
type: 'Parse',
|
|
223
|
-
message
|
|
229
|
+
message,
|
|
224
230
|
index: endInfo.furthest,
|
|
225
231
|
filename: fileInfo.filename
|
|
226
232
|
}, imports);
|
|
227
233
|
}
|
|
228
234
|
|
|
229
|
-
|
|
235
|
+
const finish = e => {
|
|
230
236
|
e = error || e || imports.error;
|
|
231
237
|
|
|
232
238
|
if (e) {
|
|
@@ -295,7 +301,9 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
295
301
|
// block rule: at the root level.
|
|
296
302
|
//
|
|
297
303
|
primary: function () {
|
|
298
|
-
|
|
304
|
+
const mixin = this.mixin;
|
|
305
|
+
let root = [];
|
|
306
|
+
let node;
|
|
299
307
|
|
|
300
308
|
while (true) {
|
|
301
309
|
while (true) {
|
|
@@ -322,7 +330,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
322
330
|
if (node) {
|
|
323
331
|
root.push(node);
|
|
324
332
|
} else {
|
|
325
|
-
|
|
333
|
+
let foundSemiColon = false;
|
|
326
334
|
while (parserInput.$char(';')) {
|
|
327
335
|
foundSemiColon = true;
|
|
328
336
|
}
|
|
@@ -339,7 +347,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
339
347
|
// where the current structure allows it
|
|
340
348
|
comment: function () {
|
|
341
349
|
if (parserInput.commentStore.length) {
|
|
342
|
-
|
|
350
|
+
const comment = parserInput.commentStore.shift();
|
|
343
351
|
return new(tree.Comment)(comment.text, comment.isLineComment, comment.index, fileInfo);
|
|
344
352
|
}
|
|
345
353
|
},
|
|
@@ -357,7 +365,9 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
357
365
|
// "milky way" 'he\'s the one!'
|
|
358
366
|
//
|
|
359
367
|
quoted: function (forceEscaped) {
|
|
360
|
-
|
|
368
|
+
let str;
|
|
369
|
+
const index = parserInput.i;
|
|
370
|
+
let isEscaped = false;
|
|
361
371
|
|
|
362
372
|
parserInput.save();
|
|
363
373
|
if (parserInput.$char('~')) {
|
|
@@ -383,7 +393,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
383
393
|
// black border-collapse
|
|
384
394
|
//
|
|
385
395
|
keyword: function () {
|
|
386
|
-
|
|
396
|
+
const k = parserInput.$char('%') || parserInput.$re(/^\[?(?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+\]?/);
|
|
387
397
|
if (k) {
|
|
388
398
|
return tree.Color.fromKeyword(k) || new(tree.Keyword)(k);
|
|
389
399
|
}
|
|
@@ -397,7 +407,10 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
397
407
|
// The arguments are parsed with the `entities.arguments` parser.
|
|
398
408
|
//
|
|
399
409
|
call: function () {
|
|
400
|
-
|
|
410
|
+
let name;
|
|
411
|
+
let args;
|
|
412
|
+
let func;
|
|
413
|
+
const index = parserInput.i;
|
|
401
414
|
|
|
402
415
|
// http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18
|
|
403
416
|
if (parserInput.peek(/^url\(/i)) {
|
|
@@ -430,7 +443,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
430
443
|
}
|
|
431
444
|
|
|
432
445
|
parserInput.forget();
|
|
433
|
-
|
|
446
|
+
|
|
434
447
|
return new(tree.Call)(name, args, index, fileInfo);
|
|
435
448
|
},
|
|
436
449
|
|
|
@@ -455,9 +468,9 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
455
468
|
|
|
456
469
|
function f(parse, stop) {
|
|
457
470
|
return {
|
|
458
|
-
parse
|
|
459
|
-
stop
|
|
460
|
-
|
|
471
|
+
parse, // parsing function
|
|
472
|
+
stop // when true - stop after parse() and return its result,
|
|
473
|
+
// otherwise continue for plain args
|
|
461
474
|
};
|
|
462
475
|
}
|
|
463
476
|
|
|
@@ -467,9 +480,10 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
467
480
|
},
|
|
468
481
|
|
|
469
482
|
arguments: function (prevArgs) {
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
483
|
+
let argsComma = prevArgs || [];
|
|
484
|
+
const argsSemiColon = [];
|
|
485
|
+
let isSemiColonSeparated;
|
|
486
|
+
let value;
|
|
473
487
|
|
|
474
488
|
parserInput.save();
|
|
475
489
|
|
|
@@ -519,7 +533,8 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
519
533
|
//
|
|
520
534
|
|
|
521
535
|
assignment: function () {
|
|
522
|
-
|
|
536
|
+
let key;
|
|
537
|
+
let value;
|
|
523
538
|
parserInput.save();
|
|
524
539
|
key = parserInput.$re(/^\w+(?=\s?=)/i);
|
|
525
540
|
if (!key) {
|
|
@@ -547,7 +562,8 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
547
562
|
// to be enclosed within a string, so it can't be parsed as an Expression.
|
|
548
563
|
//
|
|
549
564
|
url: function () {
|
|
550
|
-
|
|
565
|
+
let value;
|
|
566
|
+
const index = parserInput.i;
|
|
551
567
|
|
|
552
568
|
parserInput.autoCommentAbsorb = false;
|
|
553
569
|
|
|
@@ -578,14 +594,16 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
578
594
|
// see `parsers.variable`.
|
|
579
595
|
//
|
|
580
596
|
variable: function () {
|
|
581
|
-
|
|
597
|
+
let ch;
|
|
598
|
+
let name;
|
|
599
|
+
const index = parserInput.i;
|
|
582
600
|
|
|
583
601
|
parserInput.save();
|
|
584
602
|
if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^@@?[\w-]+/))) {
|
|
585
603
|
ch = parserInput.currentChar();
|
|
586
604
|
if (ch === '(' || ch === '[' && !parserInput.prevChar().match(/^\s/)) {
|
|
587
605
|
// this may be a VariableCall lookup
|
|
588
|
-
|
|
606
|
+
const result = parsers.variableCall(name);
|
|
589
607
|
if (result) {
|
|
590
608
|
parserInput.forget();
|
|
591
609
|
return result;
|
|
@@ -599,10 +617,11 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
599
617
|
|
|
600
618
|
// A variable entity using the protective {} e.g. @{var}
|
|
601
619
|
variableCurly: function () {
|
|
602
|
-
|
|
620
|
+
let curly;
|
|
621
|
+
const index = parserInput.i;
|
|
603
622
|
|
|
604
623
|
if (parserInput.currentChar() === '@' && (curly = parserInput.$re(/^@\{([\w-]+)\}/))) {
|
|
605
|
-
return new(tree.Variable)(
|
|
624
|
+
return new(tree.Variable)(`@${curly[1]}`, index, fileInfo);
|
|
606
625
|
}
|
|
607
626
|
},
|
|
608
627
|
//
|
|
@@ -611,7 +630,8 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
611
630
|
// background-color: $color
|
|
612
631
|
//
|
|
613
632
|
property: function () {
|
|
614
|
-
|
|
633
|
+
let name;
|
|
634
|
+
const index = parserInput.i;
|
|
615
635
|
|
|
616
636
|
if (parserInput.currentChar() === '$' && (name = parserInput.$re(/^\$[\w-]+/))) {
|
|
617
637
|
return new(tree.Property)(name, index, fileInfo);
|
|
@@ -620,10 +640,11 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
620
640
|
|
|
621
641
|
// A property entity useing the protective {} e.g. ${prop}
|
|
622
642
|
propertyCurly: function () {
|
|
623
|
-
|
|
643
|
+
let curly;
|
|
644
|
+
const index = parserInput.i;
|
|
624
645
|
|
|
625
646
|
if (parserInput.currentChar() === '$' && (curly = parserInput.$re(/^\$\{([\w-]+)\}/))) {
|
|
626
|
-
return new(tree.Property)(
|
|
647
|
+
return new(tree.Property)(`$${curly[1]}`, index, fileInfo);
|
|
627
648
|
}
|
|
628
649
|
},
|
|
629
650
|
//
|
|
@@ -634,25 +655,30 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
634
655
|
// `rgb` and `hsl` colors are parsed through the `entities.call` parser.
|
|
635
656
|
//
|
|
636
657
|
color: function () {
|
|
637
|
-
|
|
658
|
+
let rgb;
|
|
659
|
+
parserInput.save();
|
|
638
660
|
|
|
639
|
-
if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})
|
|
640
|
-
|
|
661
|
+
if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})([\w.#\[])?/))) {
|
|
662
|
+
if (!rgb[2]) {
|
|
663
|
+
parserInput.forget();
|
|
664
|
+
return new(tree.Color)(rgb[1], undefined, rgb[0]);
|
|
665
|
+
}
|
|
641
666
|
}
|
|
667
|
+
parserInput.restore();
|
|
642
668
|
},
|
|
643
669
|
|
|
644
670
|
colorKeyword: function () {
|
|
645
671
|
parserInput.save();
|
|
646
|
-
|
|
672
|
+
const autoCommentAbsorb = parserInput.autoCommentAbsorb;
|
|
647
673
|
parserInput.autoCommentAbsorb = false;
|
|
648
|
-
|
|
674
|
+
const k = parserInput.$re(/^[_A-Za-z-][_A-Za-z0-9-]+/);
|
|
649
675
|
parserInput.autoCommentAbsorb = autoCommentAbsorb;
|
|
650
676
|
if (!k) {
|
|
651
677
|
parserInput.forget();
|
|
652
678
|
return;
|
|
653
679
|
}
|
|
654
680
|
parserInput.restore();
|
|
655
|
-
|
|
681
|
+
const color = tree.Color.fromKeyword(k);
|
|
656
682
|
if (color) {
|
|
657
683
|
parserInput.$str(k);
|
|
658
684
|
return color;
|
|
@@ -669,7 +695,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
669
695
|
return;
|
|
670
696
|
}
|
|
671
697
|
|
|
672
|
-
|
|
698
|
+
const value = parserInput.$re(/^([+-]?\d*\.?\d+)(%|[a-z_]+)?/i);
|
|
673
699
|
if (value) {
|
|
674
700
|
return new(tree.Dimension)(value[1], value[2]);
|
|
675
701
|
}
|
|
@@ -681,7 +707,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
681
707
|
// U+0?? or U+00A1-00A9
|
|
682
708
|
//
|
|
683
709
|
unicodeDescriptor: function () {
|
|
684
|
-
|
|
710
|
+
let ud;
|
|
685
711
|
|
|
686
712
|
ud = parserInput.$re(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/);
|
|
687
713
|
if (ud) {
|
|
@@ -695,12 +721,13 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
695
721
|
// `window.location.href`
|
|
696
722
|
//
|
|
697
723
|
javascript: function () {
|
|
698
|
-
|
|
724
|
+
let js;
|
|
725
|
+
const index = parserInput.i;
|
|
699
726
|
|
|
700
727
|
parserInput.save();
|
|
701
728
|
|
|
702
|
-
|
|
703
|
-
|
|
729
|
+
const escape = parserInput.$char('~');
|
|
730
|
+
const jsQuote = parserInput.$char('`');
|
|
704
731
|
|
|
705
732
|
if (!jsQuote) {
|
|
706
733
|
parserInput.restore();
|
|
@@ -722,7 +749,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
722
749
|
// @fink:
|
|
723
750
|
//
|
|
724
751
|
variable: function () {
|
|
725
|
-
|
|
752
|
+
let name;
|
|
726
753
|
|
|
727
754
|
if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^(@[\w-]+)\s*:/))) { return name[1]; }
|
|
728
755
|
},
|
|
@@ -736,8 +763,11 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
736
763
|
// color: @fink[@color];
|
|
737
764
|
//
|
|
738
765
|
variableCall: function (parsedName) {
|
|
739
|
-
|
|
740
|
-
|
|
766
|
+
let lookups;
|
|
767
|
+
let important;
|
|
768
|
+
const i = parserInput.i;
|
|
769
|
+
const inValue = !!parsedName;
|
|
770
|
+
let name = parsedName;
|
|
741
771
|
|
|
742
772
|
parserInput.save();
|
|
743
773
|
|
|
@@ -759,7 +789,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
759
789
|
important = true;
|
|
760
790
|
}
|
|
761
791
|
|
|
762
|
-
|
|
792
|
+
const call = new tree.VariableCall(name, i, fileInfo);
|
|
763
793
|
if (!inValue && parsers.end()) {
|
|
764
794
|
parserInput.forget();
|
|
765
795
|
return call;
|
|
@@ -777,7 +807,12 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
777
807
|
// extend syntax - used to extend selectors
|
|
778
808
|
//
|
|
779
809
|
extend: function(isRule) {
|
|
780
|
-
|
|
810
|
+
let elements;
|
|
811
|
+
let e;
|
|
812
|
+
const index = parserInput.i;
|
|
813
|
+
let option;
|
|
814
|
+
let extendList;
|
|
815
|
+
let extend;
|
|
781
816
|
|
|
782
817
|
if (!parserInput.$str(isRule ? '&:extend(' : ':extend(')) {
|
|
783
818
|
return;
|
|
@@ -847,8 +882,13 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
847
882
|
// selector for now.
|
|
848
883
|
//
|
|
849
884
|
call: function (inValue, getLookup) {
|
|
850
|
-
|
|
851
|
-
|
|
885
|
+
const s = parserInput.currentChar();
|
|
886
|
+
let important = false;
|
|
887
|
+
let lookups;
|
|
888
|
+
const index = parserInput.i;
|
|
889
|
+
let elements;
|
|
890
|
+
let args;
|
|
891
|
+
let hasParens;
|
|
852
892
|
|
|
853
893
|
if (s !== '.' && s !== '#') { return; }
|
|
854
894
|
|
|
@@ -883,7 +923,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
883
923
|
|
|
884
924
|
if (inValue || parsers.end()) {
|
|
885
925
|
parserInput.forget();
|
|
886
|
-
|
|
926
|
+
const mixin = new(tree.mixin.Call)(elements, args, index, fileInfo, !lookups && important);
|
|
887
927
|
if (lookups) {
|
|
888
928
|
return new tree.NamespaceValue(mixin, lookups, important);
|
|
889
929
|
}
|
|
@@ -900,8 +940,12 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
900
940
|
* (Start with . or # and can have > )
|
|
901
941
|
*/
|
|
902
942
|
elements: function() {
|
|
903
|
-
|
|
904
|
-
|
|
943
|
+
let elements;
|
|
944
|
+
let e;
|
|
945
|
+
let c;
|
|
946
|
+
let elem;
|
|
947
|
+
let elemIndex;
|
|
948
|
+
const re = /^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/;
|
|
905
949
|
while (true) {
|
|
906
950
|
elemIndex = parserInput.i;
|
|
907
951
|
e = parserInput.$re(re);
|
|
@@ -920,11 +964,19 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
920
964
|
return elements;
|
|
921
965
|
},
|
|
922
966
|
args: function (isCall) {
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
967
|
+
const entities = parsers.entities;
|
|
968
|
+
const returner = { args:null, variadic: false };
|
|
969
|
+
let expressions = [];
|
|
970
|
+
const argsSemiColon = [];
|
|
971
|
+
const argsComma = [];
|
|
972
|
+
let isSemiColonSeparated;
|
|
973
|
+
let expressionContainsNamed;
|
|
974
|
+
let name;
|
|
975
|
+
let nameLoop;
|
|
976
|
+
let value;
|
|
977
|
+
let arg;
|
|
978
|
+
let expand;
|
|
979
|
+
let hasSep = true;
|
|
928
980
|
|
|
929
981
|
parserInput.save();
|
|
930
982
|
|
|
@@ -954,7 +1006,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
954
1006
|
arg.throwAwayComments();
|
|
955
1007
|
}
|
|
956
1008
|
value = arg;
|
|
957
|
-
|
|
1009
|
+
let val = null;
|
|
958
1010
|
|
|
959
1011
|
if (isCall) {
|
|
960
1012
|
// Variable
|
|
@@ -1008,7 +1060,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1008
1060
|
expressions.push(value);
|
|
1009
1061
|
}
|
|
1010
1062
|
|
|
1011
|
-
argsComma.push({ name:nameLoop, value
|
|
1063
|
+
argsComma.push({ name:nameLoop, value, expand });
|
|
1012
1064
|
|
|
1013
1065
|
if (parserInput.$char(',')) {
|
|
1014
1066
|
hasSep = true;
|
|
@@ -1027,7 +1079,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1027
1079
|
if (expressions.length > 1) {
|
|
1028
1080
|
value = new(tree.Value)(expressions);
|
|
1029
1081
|
}
|
|
1030
|
-
argsSemiColon.push({ name
|
|
1082
|
+
argsSemiColon.push({ name, value, expand });
|
|
1031
1083
|
|
|
1032
1084
|
name = null;
|
|
1033
1085
|
expressions = [];
|
|
@@ -1059,7 +1111,12 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1059
1111
|
// the `{...}` block.
|
|
1060
1112
|
//
|
|
1061
1113
|
definition: function () {
|
|
1062
|
-
|
|
1114
|
+
let name;
|
|
1115
|
+
let params = [];
|
|
1116
|
+
let match;
|
|
1117
|
+
let ruleset;
|
|
1118
|
+
let cond;
|
|
1119
|
+
let variadic = false;
|
|
1063
1120
|
if ((parserInput.currentChar() !== '.' && parserInput.currentChar() !== '#') ||
|
|
1064
1121
|
parserInput.peek(/^[^{]*\}/)) {
|
|
1065
1122
|
return;
|
|
@@ -1071,7 +1128,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1071
1128
|
if (match) {
|
|
1072
1129
|
name = match[1];
|
|
1073
1130
|
|
|
1074
|
-
|
|
1131
|
+
const argInfo = this.args(false);
|
|
1075
1132
|
params = argInfo.args;
|
|
1076
1133
|
variadic = argInfo.variadic;
|
|
1077
1134
|
|
|
@@ -1105,12 +1162,14 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1105
1162
|
},
|
|
1106
1163
|
|
|
1107
1164
|
ruleLookups: function() {
|
|
1108
|
-
|
|
1165
|
+
let rule;
|
|
1166
|
+
let args;
|
|
1167
|
+
const lookups = [];
|
|
1109
1168
|
|
|
1110
1169
|
if (parserInput.currentChar() !== '[') {
|
|
1111
1170
|
return;
|
|
1112
1171
|
}
|
|
1113
|
-
|
|
1172
|
+
|
|
1114
1173
|
while (true) {
|
|
1115
1174
|
parserInput.save();
|
|
1116
1175
|
args = null;
|
|
@@ -1135,7 +1194,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1135
1194
|
return;
|
|
1136
1195
|
}
|
|
1137
1196
|
|
|
1138
|
-
|
|
1197
|
+
const name = parserInput.$re(/^(?:[@$]{0,2})[_a-zA-Z0-9-]*/);
|
|
1139
1198
|
|
|
1140
1199
|
if (!parserInput.$char(']')) {
|
|
1141
1200
|
parserInput.restore();
|
|
@@ -1155,7 +1214,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1155
1214
|
// and can be found inside a rule's value.
|
|
1156
1215
|
//
|
|
1157
1216
|
entity: function () {
|
|
1158
|
-
|
|
1217
|
+
const entities = this.entities;
|
|
1159
1218
|
|
|
1160
1219
|
return this.comment() || entities.literal() || entities.variable() || entities.url() ||
|
|
1161
1220
|
entities.property() || entities.call() || entities.keyword() || this.mixin.call(true) ||
|
|
@@ -1177,17 +1236,17 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1177
1236
|
// alpha(opacity=88)
|
|
1178
1237
|
//
|
|
1179
1238
|
ieAlpha: function () {
|
|
1180
|
-
|
|
1239
|
+
let value;
|
|
1181
1240
|
|
|
1182
1241
|
// http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18
|
|
1183
1242
|
if (!parserInput.$re(/^opacity=/i)) { return; }
|
|
1184
1243
|
value = parserInput.$re(/^\d+/);
|
|
1185
1244
|
if (!value) {
|
|
1186
1245
|
value = expect(parsers.entities.variable, 'Could not parse alpha');
|
|
1187
|
-
value =
|
|
1246
|
+
value = `@{${value.name.slice(1)}}`;
|
|
1188
1247
|
}
|
|
1189
1248
|
expectChar(')');
|
|
1190
|
-
return new tree.Quoted('',
|
|
1249
|
+
return new tree.Quoted('', `alpha(opacity=${value})`);
|
|
1191
1250
|
},
|
|
1192
1251
|
|
|
1193
1252
|
//
|
|
@@ -1203,7 +1262,10 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1203
1262
|
// and an element name, such as a tag a class, or `*`.
|
|
1204
1263
|
//
|
|
1205
1264
|
element: function () {
|
|
1206
|
-
|
|
1265
|
+
let e;
|
|
1266
|
+
let c;
|
|
1267
|
+
let v;
|
|
1268
|
+
const index = parserInput.i;
|
|
1207
1269
|
|
|
1208
1270
|
c = this.combinator();
|
|
1209
1271
|
|
|
@@ -1240,11 +1302,11 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1240
1302
|
// we deal with this in *combinator.js*.
|
|
1241
1303
|
//
|
|
1242
1304
|
combinator: function () {
|
|
1243
|
-
|
|
1305
|
+
let c = parserInput.currentChar();
|
|
1244
1306
|
|
|
1245
1307
|
if (c === '/') {
|
|
1246
1308
|
parserInput.save();
|
|
1247
|
-
|
|
1309
|
+
const slashedCombinator = parserInput.$re(/^\/[a-z]+\//i);
|
|
1248
1310
|
if (slashedCombinator) {
|
|
1249
1311
|
parserInput.forget();
|
|
1250
1312
|
return new(tree.Combinator)(slashedCombinator);
|
|
@@ -1276,7 +1338,14 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1276
1338
|
// Selectors are made out of one or more Elements, see above.
|
|
1277
1339
|
//
|
|
1278
1340
|
selector: function (isLess) {
|
|
1279
|
-
|
|
1341
|
+
const index = parserInput.i;
|
|
1342
|
+
let elements;
|
|
1343
|
+
let extendList;
|
|
1344
|
+
let c;
|
|
1345
|
+
let e;
|
|
1346
|
+
let allExtends;
|
|
1347
|
+
let when;
|
|
1348
|
+
let condition;
|
|
1280
1349
|
isLess = isLess !== false;
|
|
1281
1350
|
while ((isLess && (extendList = this.extend())) || (isLess && (when = parserInput.$str('when'))) || (e = this.element())) {
|
|
1282
1351
|
if (when) {
|
|
@@ -1308,7 +1377,8 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1308
1377
|
if (allExtends) { error('Extend must be used to extend a selector, it cannot be used on its own'); }
|
|
1309
1378
|
},
|
|
1310
1379
|
selectors: function () {
|
|
1311
|
-
|
|
1380
|
+
let s;
|
|
1381
|
+
let selectors;
|
|
1312
1382
|
while (true) {
|
|
1313
1383
|
s = this.selector();
|
|
1314
1384
|
if (!s) {
|
|
@@ -1334,8 +1404,10 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1334
1404
|
attribute: function () {
|
|
1335
1405
|
if (!parserInput.$char('[')) { return; }
|
|
1336
1406
|
|
|
1337
|
-
|
|
1338
|
-
|
|
1407
|
+
const entities = this.entities;
|
|
1408
|
+
let key;
|
|
1409
|
+
let val;
|
|
1410
|
+
let op;
|
|
1339
1411
|
|
|
1340
1412
|
if (!(key = entities.variableCurly())) {
|
|
1341
1413
|
key = expect(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/);
|
|
@@ -1356,14 +1428,14 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1356
1428
|
// It's a wrapper around the `primary` rule, with added `{}`.
|
|
1357
1429
|
//
|
|
1358
1430
|
block: function () {
|
|
1359
|
-
|
|
1431
|
+
let content;
|
|
1360
1432
|
if (parserInput.$char('{') && (content = this.primary()) && parserInput.$char('}')) {
|
|
1361
1433
|
return content;
|
|
1362
1434
|
}
|
|
1363
1435
|
},
|
|
1364
1436
|
|
|
1365
1437
|
blockRuleset: function() {
|
|
1366
|
-
|
|
1438
|
+
let block = this.block();
|
|
1367
1439
|
|
|
1368
1440
|
if (block) {
|
|
1369
1441
|
block = new tree.Ruleset(null, block);
|
|
@@ -1372,7 +1444,9 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1372
1444
|
},
|
|
1373
1445
|
|
|
1374
1446
|
detachedRuleset: function() {
|
|
1375
|
-
|
|
1447
|
+
let argInfo;
|
|
1448
|
+
let params;
|
|
1449
|
+
let variadic;
|
|
1376
1450
|
|
|
1377
1451
|
parserInput.save();
|
|
1378
1452
|
if (parserInput.$re(/^[.#]\(/)) {
|
|
@@ -1390,7 +1464,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1390
1464
|
return;
|
|
1391
1465
|
}
|
|
1392
1466
|
}
|
|
1393
|
-
|
|
1467
|
+
const blockRuleset = this.blockRuleset();
|
|
1394
1468
|
if (blockRuleset) {
|
|
1395
1469
|
parserInput.forget();
|
|
1396
1470
|
if (params) {
|
|
@@ -1405,7 +1479,9 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1405
1479
|
// div, .class, body > p {...}
|
|
1406
1480
|
//
|
|
1407
1481
|
ruleset: function () {
|
|
1408
|
-
|
|
1482
|
+
let selectors;
|
|
1483
|
+
let rules;
|
|
1484
|
+
let debugInfo;
|
|
1409
1485
|
|
|
1410
1486
|
parserInput.save();
|
|
1411
1487
|
|
|
@@ -1417,7 +1493,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1417
1493
|
|
|
1418
1494
|
if (selectors && (rules = this.block())) {
|
|
1419
1495
|
parserInput.forget();
|
|
1420
|
-
|
|
1496
|
+
const ruleset = new(tree.Ruleset)(selectors, rules, context.strictImports);
|
|
1421
1497
|
if (context.dumpLineNumbers) {
|
|
1422
1498
|
ruleset.debugInfo = debugInfo;
|
|
1423
1499
|
}
|
|
@@ -1427,8 +1503,14 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1427
1503
|
}
|
|
1428
1504
|
},
|
|
1429
1505
|
declaration: function () {
|
|
1430
|
-
|
|
1431
|
-
|
|
1506
|
+
let name;
|
|
1507
|
+
let value;
|
|
1508
|
+
const index = parserInput.i;
|
|
1509
|
+
let hasDR;
|
|
1510
|
+
const c = parserInput.currentChar();
|
|
1511
|
+
let important;
|
|
1512
|
+
let merge;
|
|
1513
|
+
let isVariable;
|
|
1432
1514
|
|
|
1433
1515
|
if (c === '.' || c === '#' || c === '&' || c === ':') { return; }
|
|
1434
1516
|
|
|
@@ -1464,7 +1546,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1464
1546
|
if (value) {
|
|
1465
1547
|
parserInput.forget();
|
|
1466
1548
|
// anonymous values absorb the end ';' which is required for them to work
|
|
1467
|
-
return new
|
|
1549
|
+
return new(tree.Declaration)(name, value, false, merge, index, fileInfo);
|
|
1468
1550
|
}
|
|
1469
1551
|
|
|
1470
1552
|
if (!value) {
|
|
@@ -1481,7 +1563,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1481
1563
|
|
|
1482
1564
|
if (value && (this.end() || hasDR)) {
|
|
1483
1565
|
parserInput.forget();
|
|
1484
|
-
return new
|
|
1566
|
+
return new(tree.Declaration)(name, value, important, merge, index, fileInfo);
|
|
1485
1567
|
}
|
|
1486
1568
|
else {
|
|
1487
1569
|
parserInput.restore();
|
|
@@ -1491,8 +1573,8 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1491
1573
|
}
|
|
1492
1574
|
},
|
|
1493
1575
|
anonymousValue: function () {
|
|
1494
|
-
|
|
1495
|
-
|
|
1576
|
+
const index = parserInput.i;
|
|
1577
|
+
const match = parserInput.$re(/^([^.#@\$+\/'"*`(;{}-]*);/);
|
|
1496
1578
|
if (match) {
|
|
1497
1579
|
return new(tree.Anonymous)(match[1], index);
|
|
1498
1580
|
}
|
|
@@ -1507,12 +1589,16 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1507
1589
|
* math is allowed.
|
|
1508
1590
|
*/
|
|
1509
1591
|
permissiveValue: function (untilTokens) {
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1592
|
+
let i;
|
|
1593
|
+
let e;
|
|
1594
|
+
let done;
|
|
1595
|
+
let value;
|
|
1596
|
+
const tok = untilTokens || ';';
|
|
1597
|
+
const index = parserInput.i;
|
|
1598
|
+
const result = [];
|
|
1513
1599
|
|
|
1514
1600
|
function testCurrentChar() {
|
|
1515
|
-
|
|
1601
|
+
const char = parserInput.currentChar();
|
|
1516
1602
|
if (typeof tok === 'string') {
|
|
1517
1603
|
return char === tok;
|
|
1518
1604
|
} else {
|
|
@@ -1536,7 +1622,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1536
1622
|
} while (e);
|
|
1537
1623
|
|
|
1538
1624
|
done = testCurrentChar();
|
|
1539
|
-
|
|
1625
|
+
|
|
1540
1626
|
if (value.length > 0) {
|
|
1541
1627
|
value = new(tree.Expression)(value);
|
|
1542
1628
|
if (done) {
|
|
@@ -1551,18 +1637,18 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1551
1637
|
}
|
|
1552
1638
|
}
|
|
1553
1639
|
parserInput.save();
|
|
1554
|
-
|
|
1640
|
+
|
|
1555
1641
|
value = parserInput.$parseUntil(tok);
|
|
1556
1642
|
|
|
1557
1643
|
if (value) {
|
|
1558
1644
|
if (typeof value === 'string') {
|
|
1559
|
-
error(
|
|
1645
|
+
error(`Expected '${value}'`, 'Parse');
|
|
1560
1646
|
}
|
|
1561
1647
|
if (value.length === 1 && value[0] === ' ') {
|
|
1562
1648
|
parserInput.forget();
|
|
1563
1649
|
return new tree.Anonymous('', index);
|
|
1564
1650
|
}
|
|
1565
|
-
|
|
1651
|
+
let item;
|
|
1566
1652
|
for (i = 0; i < value.length; i++) {
|
|
1567
1653
|
item = value[i];
|
|
1568
1654
|
if (Array.isArray(item)) {
|
|
@@ -1574,7 +1660,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1574
1660
|
item = item.trim();
|
|
1575
1661
|
}
|
|
1576
1662
|
// Treat like quoted values, but replace vars like unquoted expressions
|
|
1577
|
-
|
|
1663
|
+
const quote = new tree.Quoted('\'', item, true, index, fileInfo);
|
|
1578
1664
|
quote.variableRegex = /@([\w-]+)/g;
|
|
1579
1665
|
quote.propRegex = /\$([\w-]+)/g;
|
|
1580
1666
|
result.push(quote);
|
|
@@ -1597,12 +1683,14 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1597
1683
|
// stored in `import`, which we pass to the Import constructor.
|
|
1598
1684
|
//
|
|
1599
1685
|
'import': function () {
|
|
1600
|
-
|
|
1686
|
+
let path;
|
|
1687
|
+
let features;
|
|
1688
|
+
const index = parserInput.i;
|
|
1601
1689
|
|
|
1602
|
-
|
|
1690
|
+
const dir = parserInput.$re(/^@import?\s+/);
|
|
1603
1691
|
|
|
1604
1692
|
if (dir) {
|
|
1605
|
-
|
|
1693
|
+
const options = (dir ? this.importOptions() : null) || {};
|
|
1606
1694
|
|
|
1607
1695
|
if ((path = this.entities.quoted() || this.entities.url())) {
|
|
1608
1696
|
features = this.mediaFeatures();
|
|
@@ -1622,7 +1710,10 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1622
1710
|
},
|
|
1623
1711
|
|
|
1624
1712
|
importOptions: function() {
|
|
1625
|
-
|
|
1713
|
+
let o;
|
|
1714
|
+
const options = {};
|
|
1715
|
+
let optionName;
|
|
1716
|
+
let value;
|
|
1626
1717
|
|
|
1627
1718
|
// list of options, surrounded by parens
|
|
1628
1719
|
if (!parserInput.$char('(')) { return null; }
|
|
@@ -1650,14 +1741,17 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1650
1741
|
},
|
|
1651
1742
|
|
|
1652
1743
|
importOption: function() {
|
|
1653
|
-
|
|
1744
|
+
const opt = parserInput.$re(/^(less|css|multiple|once|inline|reference|optional)/);
|
|
1654
1745
|
if (opt) {
|
|
1655
1746
|
return opt[1];
|
|
1656
1747
|
}
|
|
1657
1748
|
},
|
|
1658
1749
|
|
|
1659
1750
|
mediaFeature: function () {
|
|
1660
|
-
|
|
1751
|
+
const entities = this.entities;
|
|
1752
|
+
const nodes = [];
|
|
1753
|
+
let e;
|
|
1754
|
+
let p;
|
|
1661
1755
|
parserInput.save();
|
|
1662
1756
|
do {
|
|
1663
1757
|
e = entities.keyword() || entities.variable() || entities.mixinLookup();
|
|
@@ -1687,7 +1781,9 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1687
1781
|
},
|
|
1688
1782
|
|
|
1689
1783
|
mediaFeatures: function () {
|
|
1690
|
-
|
|
1784
|
+
const entities = this.entities;
|
|
1785
|
+
const features = [];
|
|
1786
|
+
let e;
|
|
1691
1787
|
do {
|
|
1692
1788
|
e = this.mediaFeature();
|
|
1693
1789
|
if (e) {
|
|
@@ -1706,7 +1802,11 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1706
1802
|
},
|
|
1707
1803
|
|
|
1708
1804
|
media: function () {
|
|
1709
|
-
|
|
1805
|
+
let features;
|
|
1806
|
+
let rules;
|
|
1807
|
+
let media;
|
|
1808
|
+
let debugInfo;
|
|
1809
|
+
const index = parserInput.i;
|
|
1710
1810
|
|
|
1711
1811
|
if (context.dumpLineNumbers) {
|
|
1712
1812
|
debugInfo = getDebugInfo(index);
|
|
@@ -1743,9 +1843,11 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1743
1843
|
// @plugin (args) "lib";
|
|
1744
1844
|
//
|
|
1745
1845
|
plugin: function () {
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1846
|
+
let path;
|
|
1847
|
+
let args;
|
|
1848
|
+
let options;
|
|
1849
|
+
const index = parserInput.i;
|
|
1850
|
+
const dir = parserInput.$re(/^@plugin?\s+/);
|
|
1749
1851
|
|
|
1750
1852
|
if (dir) {
|
|
1751
1853
|
args = this.pluginArgs();
|
|
@@ -1782,7 +1884,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1782
1884
|
parserInput.restore();
|
|
1783
1885
|
return null;
|
|
1784
1886
|
}
|
|
1785
|
-
|
|
1887
|
+
const args = parserInput.$re(/^\s*([^\);]+)\)\s*/);
|
|
1786
1888
|
if (args[1]) {
|
|
1787
1889
|
parserInput.forget();
|
|
1788
1890
|
return args[1].trim();
|
|
@@ -1799,8 +1901,16 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1799
1901
|
// @charset "utf-8";
|
|
1800
1902
|
//
|
|
1801
1903
|
atrule: function () {
|
|
1802
|
-
|
|
1803
|
-
|
|
1904
|
+
const index = parserInput.i;
|
|
1905
|
+
let name;
|
|
1906
|
+
let value;
|
|
1907
|
+
let rules;
|
|
1908
|
+
let nonVendorSpecificName;
|
|
1909
|
+
let hasIdentifier;
|
|
1910
|
+
let hasExpression;
|
|
1911
|
+
let hasUnknown;
|
|
1912
|
+
let hasBlock = true;
|
|
1913
|
+
let isRooted = true;
|
|
1804
1914
|
|
|
1805
1915
|
if (parserInput.currentChar() !== '@') { return; }
|
|
1806
1916
|
|
|
@@ -1817,7 +1927,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1817
1927
|
|
|
1818
1928
|
nonVendorSpecificName = name;
|
|
1819
1929
|
if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) {
|
|
1820
|
-
nonVendorSpecificName =
|
|
1930
|
+
nonVendorSpecificName = `@${name.slice(name.indexOf('-', 2) + 1)}`;
|
|
1821
1931
|
}
|
|
1822
1932
|
|
|
1823
1933
|
switch (nonVendorSpecificName) {
|
|
@@ -1848,19 +1958,19 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1848
1958
|
if (hasIdentifier) {
|
|
1849
1959
|
value = this.entity();
|
|
1850
1960
|
if (!value) {
|
|
1851
|
-
error(
|
|
1961
|
+
error(`expected ${name} identifier`);
|
|
1852
1962
|
}
|
|
1853
1963
|
} else if (hasExpression) {
|
|
1854
1964
|
value = this.expression();
|
|
1855
1965
|
if (!value) {
|
|
1856
|
-
error(
|
|
1966
|
+
error(`expected ${name} expression`);
|
|
1857
1967
|
}
|
|
1858
1968
|
} else if (hasUnknown) {
|
|
1859
1969
|
value = this.permissiveValue(/^[{;]/);
|
|
1860
1970
|
hasBlock = (parserInput.currentChar() === '{');
|
|
1861
1971
|
if (!value) {
|
|
1862
1972
|
if (!hasBlock && parserInput.currentChar() !== ';') {
|
|
1863
|
-
error(name
|
|
1973
|
+
error(`${name} rule is missing block or ending semi-colon`);
|
|
1864
1974
|
}
|
|
1865
1975
|
}
|
|
1866
1976
|
else if (!value.value) {
|
|
@@ -1874,7 +1984,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1874
1984
|
|
|
1875
1985
|
if (rules || (!hasBlock && value && parserInput.$char(';'))) {
|
|
1876
1986
|
parserInput.forget();
|
|
1877
|
-
return new
|
|
1987
|
+
return new(tree.AtRule)(name, value, rules, index, fileInfo,
|
|
1878
1988
|
context.dumpLineNumbers ? getDebugInfo(index) : null,
|
|
1879
1989
|
isRooted
|
|
1880
1990
|
);
|
|
@@ -1892,7 +2002,9 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1892
2002
|
// and before the `;`.
|
|
1893
2003
|
//
|
|
1894
2004
|
value: function () {
|
|
1895
|
-
|
|
2005
|
+
let e;
|
|
2006
|
+
const expressions = [];
|
|
2007
|
+
const index = parserInput.i;
|
|
1896
2008
|
|
|
1897
2009
|
do {
|
|
1898
2010
|
e = this.expression();
|
|
@@ -1912,7 +2024,8 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1912
2024
|
}
|
|
1913
2025
|
},
|
|
1914
2026
|
sub: function () {
|
|
1915
|
-
|
|
2027
|
+
let a;
|
|
2028
|
+
let e;
|
|
1916
2029
|
|
|
1917
2030
|
parserInput.save();
|
|
1918
2031
|
if (parserInput.$char('(')) {
|
|
@@ -1929,7 +2042,11 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1929
2042
|
parserInput.restore();
|
|
1930
2043
|
},
|
|
1931
2044
|
multiplication: function () {
|
|
1932
|
-
|
|
2045
|
+
let m;
|
|
2046
|
+
let a;
|
|
2047
|
+
let op;
|
|
2048
|
+
let operation;
|
|
2049
|
+
let isSpaced;
|
|
1933
2050
|
m = this.operand();
|
|
1934
2051
|
if (m) {
|
|
1935
2052
|
isSpaced = parserInput.isWhitespace(-1);
|
|
@@ -1958,7 +2075,11 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1958
2075
|
}
|
|
1959
2076
|
},
|
|
1960
2077
|
addition: function () {
|
|
1961
|
-
|
|
2078
|
+
let m;
|
|
2079
|
+
let a;
|
|
2080
|
+
let op;
|
|
2081
|
+
let operation;
|
|
2082
|
+
let isSpaced;
|
|
1962
2083
|
m = this.multiplication();
|
|
1963
2084
|
if (m) {
|
|
1964
2085
|
isSpaced = parserInput.isWhitespace(-1);
|
|
@@ -1981,7 +2102,10 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1981
2102
|
}
|
|
1982
2103
|
},
|
|
1983
2104
|
conditions: function () {
|
|
1984
|
-
|
|
2105
|
+
let a;
|
|
2106
|
+
let b;
|
|
2107
|
+
const index = parserInput.i;
|
|
2108
|
+
let condition;
|
|
1985
2109
|
|
|
1986
2110
|
a = this.condition(true);
|
|
1987
2111
|
if (a) {
|
|
@@ -1999,7 +2123,9 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
1999
2123
|
}
|
|
2000
2124
|
},
|
|
2001
2125
|
condition: function (needsParens) {
|
|
2002
|
-
|
|
2126
|
+
let result;
|
|
2127
|
+
let logical;
|
|
2128
|
+
let next;
|
|
2003
2129
|
function or() {
|
|
2004
2130
|
return parserInput.$str('or');
|
|
2005
2131
|
}
|
|
@@ -2020,9 +2146,12 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
2020
2146
|
return result;
|
|
2021
2147
|
},
|
|
2022
2148
|
conditionAnd: function (needsParens) {
|
|
2023
|
-
|
|
2149
|
+
let result;
|
|
2150
|
+
let logical;
|
|
2151
|
+
let next;
|
|
2152
|
+
const self = this;
|
|
2024
2153
|
function insideCondition() {
|
|
2025
|
-
|
|
2154
|
+
const cond = self.negatedCondition(needsParens) || self.parenthesisCondition(needsParens);
|
|
2026
2155
|
if (!cond && !needsParens) {
|
|
2027
2156
|
return self.atomicCondition(needsParens);
|
|
2028
2157
|
}
|
|
@@ -2049,7 +2178,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
2049
2178
|
},
|
|
2050
2179
|
negatedCondition: function (needsParens) {
|
|
2051
2180
|
if (parserInput.$str('not')) {
|
|
2052
|
-
|
|
2181
|
+
const result = this.parenthesisCondition(needsParens);
|
|
2053
2182
|
if (result) {
|
|
2054
2183
|
result.negate = !result.negate;
|
|
2055
2184
|
}
|
|
@@ -2058,7 +2187,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
2058
2187
|
},
|
|
2059
2188
|
parenthesisCondition: function (needsParens) {
|
|
2060
2189
|
function tryConditionFollowedByParenthesis(me) {
|
|
2061
|
-
|
|
2190
|
+
let body;
|
|
2062
2191
|
parserInput.save();
|
|
2063
2192
|
body = me.condition(needsParens);
|
|
2064
2193
|
if (!body) {
|
|
@@ -2073,7 +2202,7 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
2073
2202
|
return body;
|
|
2074
2203
|
}
|
|
2075
2204
|
|
|
2076
|
-
|
|
2205
|
+
let body;
|
|
2077
2206
|
parserInput.save();
|
|
2078
2207
|
if (!parserInput.$str('(')) {
|
|
2079
2208
|
parserInput.restore();
|
|
@@ -2091,14 +2220,19 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
2091
2220
|
return ;
|
|
2092
2221
|
}
|
|
2093
2222
|
if (!parserInput.$char(')')) {
|
|
2094
|
-
parserInput.restore(
|
|
2223
|
+
parserInput.restore(`expected ')' got '${parserInput.currentChar()}'`);
|
|
2095
2224
|
return ;
|
|
2096
2225
|
}
|
|
2097
2226
|
parserInput.forget();
|
|
2098
2227
|
return body;
|
|
2099
2228
|
},
|
|
2100
2229
|
atomicCondition: function (needsParens) {
|
|
2101
|
-
|
|
2230
|
+
const entities = this.entities;
|
|
2231
|
+
const index = parserInput.i;
|
|
2232
|
+
let a;
|
|
2233
|
+
let b;
|
|
2234
|
+
let c;
|
|
2235
|
+
let op;
|
|
2102
2236
|
|
|
2103
2237
|
function cond() {
|
|
2104
2238
|
return this.addition() || entities.keyword() || entities.quoted() || entities.mixinLookup();
|
|
@@ -2149,13 +2283,14 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
2149
2283
|
// such as a Color, or a Variable
|
|
2150
2284
|
//
|
|
2151
2285
|
operand: function () {
|
|
2152
|
-
|
|
2286
|
+
const entities = this.entities;
|
|
2287
|
+
let negate;
|
|
2153
2288
|
|
|
2154
2289
|
if (parserInput.peek(/^-[@\$\(]/)) {
|
|
2155
2290
|
negate = parserInput.$char('-');
|
|
2156
2291
|
}
|
|
2157
2292
|
|
|
2158
|
-
|
|
2293
|
+
let o = this.sub() || entities.dimension() ||
|
|
2159
2294
|
entities.color() || entities.variable() ||
|
|
2160
2295
|
entities.property() || entities.call() ||
|
|
2161
2296
|
entities.quoted(true) || entities.colorKeyword() ||
|
|
@@ -2177,7 +2312,10 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
2177
2312
|
// @var * 2
|
|
2178
2313
|
//
|
|
2179
2314
|
expression: function () {
|
|
2180
|
-
|
|
2315
|
+
const entities = [];
|
|
2316
|
+
let e;
|
|
2317
|
+
let delim;
|
|
2318
|
+
const index = parserInput.i;
|
|
2181
2319
|
|
|
2182
2320
|
do {
|
|
2183
2321
|
e = this.comment();
|
|
@@ -2202,17 +2340,20 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
2202
2340
|
}
|
|
2203
2341
|
},
|
|
2204
2342
|
property: function () {
|
|
2205
|
-
|
|
2343
|
+
const name = parserInput.$re(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/);
|
|
2206
2344
|
if (name) {
|
|
2207
2345
|
return name[1];
|
|
2208
2346
|
}
|
|
2209
2347
|
},
|
|
2210
2348
|
ruleProperty: function () {
|
|
2211
|
-
|
|
2349
|
+
let name = [];
|
|
2350
|
+
const index = [];
|
|
2351
|
+
let s;
|
|
2352
|
+
let k;
|
|
2212
2353
|
|
|
2213
2354
|
parserInput.save();
|
|
2214
2355
|
|
|
2215
|
-
|
|
2356
|
+
const simpleProperty = parserInput.$re(/^([_a-zA-Z0-9-]+)\s*:/);
|
|
2216
2357
|
if (simpleProperty) {
|
|
2217
2358
|
name = [new(tree.Keyword)(simpleProperty[1])];
|
|
2218
2359
|
parserInput.forget();
|
|
@@ -2220,8 +2361,8 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
2220
2361
|
}
|
|
2221
2362
|
|
|
2222
2363
|
function match(re) {
|
|
2223
|
-
|
|
2224
|
-
|
|
2364
|
+
const i = parserInput.i;
|
|
2365
|
+
const chunk = parserInput.$re(re);
|
|
2225
2366
|
if (chunk) {
|
|
2226
2367
|
index.push(i);
|
|
2227
2368
|
return name.push(chunk[1]);
|
|
@@ -2249,8 +2390,8 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
2249
2390
|
name[k] = (s.charAt(0) !== '@' && s.charAt(0) !== '$') ?
|
|
2250
2391
|
new(tree.Keyword)(s) :
|
|
2251
2392
|
(s.charAt(0) === '@' ?
|
|
2252
|
-
new(tree.Variable)(
|
|
2253
|
-
new(tree.Property)(
|
|
2393
|
+
new(tree.Variable)(`@${s.slice(2, -1)}`, index[k], fileInfo) :
|
|
2394
|
+
new(tree.Property)(`$${s.slice(2, -1)}`, index[k], fileInfo));
|
|
2254
2395
|
}
|
|
2255
2396
|
return name;
|
|
2256
2397
|
}
|
|
@@ -2259,18 +2400,17 @@ var Parser = function Parser(context, imports, fileInfo) {
|
|
|
2259
2400
|
}
|
|
2260
2401
|
};
|
|
2261
2402
|
};
|
|
2262
|
-
Parser.serializeVars =
|
|
2263
|
-
|
|
2403
|
+
Parser.serializeVars = vars => {
|
|
2404
|
+
let s = '';
|
|
2264
2405
|
|
|
2265
|
-
for (
|
|
2406
|
+
for (const name in vars) {
|
|
2266
2407
|
if (Object.hasOwnProperty.call(vars, name)) {
|
|
2267
|
-
|
|
2268
|
-
s += ((name[0] === '@') ? '' : '@') + name
|
|
2269
|
-
((String(value).slice(-1) === ';') ? '' : ';');
|
|
2408
|
+
const value = vars[name];
|
|
2409
|
+
s += `${((name[0] === '@') ? '' : '@') + name}: ${value}${(String(value).slice(-1) === ';') ? '' : ';'}`;
|
|
2270
2410
|
}
|
|
2271
2411
|
}
|
|
2272
2412
|
|
|
2273
2413
|
return s;
|
|
2274
2414
|
};
|
|
2275
2415
|
|
|
2276
|
-
|
|
2416
|
+
export default Parser;
|