less 2.2.2 → 2.6.0
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.
- checksums.yaml +7 -0
- data/Changelog.md +17 -0
- data/Gemfile +7 -3
- data/README.md +29 -13
- data/bin/lessc +3 -1
- data/less.gemspec +2 -6
- data/lib/less/defaults.rb +3 -3
- data/lib/less/java_script/rhino_context.rb +17 -27
- data/lib/less/java_script/v8_context.rb +11 -11
- data/lib/less/js/.gitattributes +10 -0
- data/lib/less/js/.gitignore +24 -0
- data/lib/less/js/.jshintrc +11 -0
- data/lib/less/js/.npmignore +1 -0
- data/lib/less/js/.travis.yml +8 -0
- data/lib/less/js/CHANGELOG.md +299 -0
- data/lib/less/js/CONTRIBUTING.md +50 -0
- data/lib/less/js/Gruntfile.js +298 -0
- data/lib/less/js/README.md +43 -12
- data/lib/less/js/benchmark/benchmark.less +194 -194
- data/lib/less/js/benchmark/less-benchmark.js +9 -10
- data/lib/less/js/bin/lessc +310 -37
- data/lib/less/js/bower.json +18 -0
- data/lib/less/js/build/README.md +51 -0
- data/lib/less/js/build/amd.js +1 -1
- data/lib/less/js/build/browser-header.js +4 -0
- data/lib/less/js/build/build.yml +162 -0
- data/lib/less/js/build/require-rhino.js +7 -2
- data/lib/less/js/build/rhino-header.js +4 -0
- data/lib/less/js/build/rhino-modules.js +131 -0
- data/lib/less/js/build/tasks/.gitkeep +1 -0
- data/lib/less/js/build.gradle +347 -0
- data/lib/less/js/dist/less-1.3.1.js +4011 -0
- data/lib/less/js/dist/less-1.3.1.min.js +9 -0
- data/lib/less/js/dist/less-1.3.2.js +4401 -0
- data/lib/less/js/dist/less-1.3.2.min.js +9 -0
- data/lib/less/js/dist/less-1.3.3.js +4413 -0
- data/lib/less/js/dist/less-1.3.3.min.js +9 -0
- data/lib/less/js/dist/less-1.4.0-beta.js +5830 -0
- data/lib/less/js/dist/less-1.4.0-beta.min.js +11 -0
- data/lib/less/js/dist/less-1.4.0.js +5830 -0
- data/lib/less/js/dist/less-1.4.0.min.js +11 -0
- data/lib/less/js/dist/less-1.4.1.js +5837 -0
- data/lib/less/js/dist/less-1.4.1.min.js +11 -0
- data/lib/less/js/dist/less-1.4.2.js +5837 -0
- data/lib/less/js/dist/less-1.4.2.min.js +11 -0
- data/lib/less/js/dist/less-1.5.0.js +6914 -0
- data/lib/less/js/dist/less-1.5.0.min.js +13 -0
- data/lib/less/js/dist/less-1.5.1.js +6941 -0
- data/lib/less/js/dist/less-1.5.1.min.js +13 -0
- data/lib/less/js/dist/less-1.6.0.js +7485 -0
- data/lib/less/js/dist/less-1.6.0.min.js +16 -0
- data/lib/less/js/dist/less-1.6.1.js +7513 -0
- data/lib/less/js/dist/less-1.6.1.min.js +16 -0
- data/lib/less/js/dist/less-1.6.2.js +7624 -0
- data/lib/less/js/dist/less-1.6.2.min.js +16 -0
- data/lib/less/js/dist/less-1.6.3.js +7627 -0
- data/lib/less/js/dist/less-1.6.3.min.js +16 -0
- data/lib/less/js/dist/less-1.7.0.js +7921 -0
- data/lib/less/js/dist/less-1.7.0.min.js +16 -0
- data/lib/less/js/dist/less-rhino-1.3.1.js +3725 -0
- data/lib/less/js/dist/less-rhino-1.3.2.js +3990 -0
- data/lib/less/js/dist/less-rhino-1.3.3.js +4002 -0
- data/lib/less/js/dist/less-rhino-1.4.0.js +4273 -0
- data/lib/less/js/dist/less-rhino-1.5.1.js +6831 -0
- data/lib/less/js/dist/less-rhino-1.6.2.js +9017 -0
- data/lib/less/js/dist/less-rhino-1.6.3.js +9020 -0
- data/lib/less/js/dist/less-rhino-1.7.0.js +9301 -0
- data/lib/less/js/dist/lessc-rhino-1.6.2.js +449 -0
- data/lib/less/js/dist/lessc-rhino-1.6.3.js +449 -0
- data/lib/less/js/dist/lessc-rhino-1.7.0.js +449 -0
- data/lib/less/js/gradle/wrapper/gradle-wrapper.jar +0 -0
- data/lib/less/js/gradle/wrapper/gradle-wrapper.properties +6 -0
- data/lib/less/js/gradlew +164 -0
- data/lib/less/js/gradlew.bat +90 -0
- data/lib/less/js/lib/less/browser.js +547 -250
- data/lib/less/js/lib/less/encoder.js +4 -0
- data/lib/less/js/lib/less/env.js +136 -0
- data/lib/less/js/lib/less/extend-visitor.js +416 -0
- data/lib/less/js/lib/less/functions.js +576 -36
- data/lib/less/js/lib/less/import-visitor.js +142 -0
- data/lib/less/js/lib/less/index.js +187 -83
- data/lib/less/js/lib/less/join-selector-visitor.js +44 -0
- data/lib/less/js/lib/less/lessc_helper.js +82 -0
- data/lib/less/js/lib/less/parser.js +1286 -523
- data/lib/less/js/lib/less/rhino.js +415 -29
- data/lib/less/js/lib/less/source-map-output.js +141 -0
- data/lib/less/js/lib/less/to-css-visitor.js +240 -0
- data/lib/less/js/lib/less/tree/alpha.js +17 -5
- data/lib/less/js/lib/less/tree/anonymous.js +25 -4
- data/lib/less/js/lib/less/tree/assignment.js +17 -5
- data/lib/less/js/lib/less/tree/call.js +36 -13
- data/lib/less/js/lib/less/tree/color.js +119 -31
- data/lib/less/js/lib/less/tree/comment.js +18 -4
- data/lib/less/js/lib/less/tree/condition.js +35 -28
- data/lib/less/js/lib/less/tree/detached-ruleset.js +20 -0
- data/lib/less/js/lib/less/tree/dimension.js +291 -16
- data/lib/less/js/lib/less/tree/directive.js +56 -22
- data/lib/less/js/lib/less/tree/element.js +78 -17
- data/lib/less/js/lib/less/tree/expression.js +39 -8
- data/lib/less/js/lib/less/tree/extend.js +53 -0
- data/lib/less/js/lib/less/tree/import.js +81 -36
- data/lib/less/js/lib/less/tree/javascript.js +17 -10
- data/lib/less/js/lib/less/tree/keyword.js +8 -3
- data/lib/less/js/lib/less/tree/media.js +70 -27
- data/lib/less/js/lib/less/tree/mixin.js +250 -70
- data/lib/less/js/lib/less/tree/negative.js +24 -0
- data/lib/less/js/lib/less/tree/operation.js +38 -13
- data/lib/less/js/lib/less/tree/paren.js +9 -2
- data/lib/less/js/lib/less/tree/quoted.js +29 -10
- data/lib/less/js/lib/less/tree/rule.js +77 -29
- data/lib/less/js/lib/less/tree/ruleset-call.js +16 -0
- data/lib/less/js/lib/less/tree/ruleset.js +445 -107
- data/lib/less/js/lib/less/tree/selector.js +117 -30
- data/lib/less/js/lib/less/tree/unicode-descriptor.js +15 -0
- data/lib/less/js/lib/less/tree/url.js +43 -15
- data/lib/less/js/lib/less/tree/value.js +16 -6
- data/lib/less/js/lib/less/tree/variable.js +26 -8
- data/lib/less/js/lib/less/tree.js +82 -2
- data/lib/less/js/lib/less/visitor.js +146 -0
- data/lib/less/js/lib/source-map/source-map-0.1.31.js +1933 -0
- data/lib/less/js/lib/source-map/source-map-footer.js +4 -0
- data/lib/less/js/lib/source-map/source-map-header.js +3 -0
- data/lib/less/js/package.json +86 -11
- data/lib/less/js/test/browser/common.js +201 -0
- data/lib/less/js/test/browser/css/global-vars/simple.css +3 -0
- data/lib/less/js/test/browser/css/modify-vars/simple.css +8 -0
- data/lib/less/js/test/browser/css/postProcessor/postProcessor.css +4 -0
- data/lib/less/js/test/browser/css/relative-urls/urls.css +35 -0
- data/lib/less/js/test/browser/css/rootpath/urls.css +35 -0
- data/lib/less/js/test/browser/css/rootpath-relative/urls.css +35 -0
- data/lib/less/js/test/browser/css/urls.css +53 -0
- data/lib/less/js/test/browser/es5.js +27 -0
- data/lib/less/js/test/browser/jasmine-html.js +681 -0
- data/lib/less/js/test/browser/jasmine.css +82 -0
- data/lib/less/js/test/browser/jasmine.js +2600 -0
- data/lib/less/js/test/browser/less/console-errors/test-error.less +3 -0
- data/lib/less/js/test/browser/less/console-errors/test-error.txt +2 -0
- data/lib/less/js/test/browser/less/global-vars/simple.less +3 -0
- data/lib/less/js/test/browser/less/imports/urls.less +4 -0
- data/lib/less/js/test/browser/less/imports/urls2.less +4 -0
- data/lib/less/js/test/browser/less/modify-vars/imports/simple2.less +4 -0
- data/lib/less/js/test/browser/less/modify-vars/simple.less +8 -0
- data/lib/less/js/test/browser/less/postProcessor/postProcessor.less +4 -0
- data/lib/less/js/test/browser/less/relative-urls/urls.less +33 -0
- data/lib/less/js/test/browser/less/rootpath/urls.less +33 -0
- data/lib/less/js/test/browser/less/rootpath-relative/urls.less +33 -0
- data/lib/less/js/test/browser/less/urls.less +57 -0
- data/lib/less/js/test/browser/phantom-runner.js +150 -0
- data/lib/less/js/test/browser/runner-browser-options.js +42 -0
- data/lib/less/js/test/browser/runner-browser-spec.js +12 -0
- data/lib/less/js/test/browser/runner-console-errors.js +5 -0
- data/lib/less/js/test/browser/runner-errors-options.js +5 -0
- data/lib/less/js/test/browser/runner-errors-spec.js +4 -0
- data/lib/less/js/test/browser/runner-global-vars-options.js +4 -0
- data/lib/less/js/test/browser/runner-global-vars-spec.js +3 -0
- data/lib/less/js/test/browser/runner-legacy-options.js +4 -0
- data/lib/less/js/test/browser/runner-legacy-spec.js +3 -0
- data/lib/less/js/test/browser/runner-main-options.js +15 -0
- data/lib/less/js/test/browser/runner-main-spec.js +3 -0
- data/lib/less/js/test/browser/runner-modify-vars-options.js +2 -0
- data/lib/less/js/test/browser/runner-modify-vars-spec.js +43 -0
- data/lib/less/js/test/browser/runner-no-js-errors-options.js +4 -0
- data/lib/less/js/test/browser/runner-no-js-errors-spec.js +4 -0
- data/lib/less/js/test/browser/runner-postProcessor-options.js +4 -0
- data/lib/less/js/test/browser/runner-postProcessor.js +3 -0
- data/lib/less/js/test/browser/runner-production-options.js +3 -0
- data/lib/less/js/test/browser/runner-production-spec.js +5 -0
- data/lib/less/js/test/browser/runner-relative-urls-options.js +3 -0
- data/lib/less/js/test/browser/runner-relative-urls-spec.js +3 -0
- data/lib/less/js/test/browser/runner-rootpath-options.js +3 -0
- data/lib/less/js/test/browser/runner-rootpath-relative-options.js +4 -0
- data/lib/less/js/test/browser/runner-rootpath-relative-spec.js +3 -0
- data/lib/less/js/test/browser/runner-rootpath-spec.js +3 -0
- data/lib/less/js/test/browser/test-runner-template.tmpl +47 -0
- data/lib/less/js/test/css/charsets.css +1 -0
- data/lib/less/js/test/css/colors.css +29 -0
- data/lib/less/js/test/css/comments.css +15 -2
- data/lib/less/js/test/css/compression/compression.css +3 -0
- data/lib/less/js/test/css/css-3.css +73 -2
- data/lib/less/js/test/css/css-escapes.css +4 -0
- data/lib/less/js/test/css/css-guards.css +37 -0
- data/lib/less/js/test/css/css.css +20 -14
- data/lib/less/js/test/css/debug/linenumbers-all.css +49 -0
- data/lib/less/js/test/css/debug/linenumbers-comments.css +40 -0
- data/lib/less/js/test/css/debug/linenumbers-mediaquery.css +40 -0
- data/lib/less/js/test/css/detached-rulesets.css +71 -0
- data/lib/less/js/test/css/empty.css +0 -0
- data/lib/less/js/test/css/extend-chaining.css +81 -0
- data/lib/less/js/test/css/extend-clearfix.css +19 -0
- data/lib/less/js/test/css/extend-exact.css +37 -0
- data/lib/less/js/test/css/extend-media.css +24 -0
- data/lib/less/js/test/css/extend-nest.css +57 -0
- data/lib/less/js/test/css/extend-selector.css +80 -0
- data/lib/less/js/test/css/extend.css +76 -0
- data/lib/less/js/test/css/extract-and-length.css +133 -0
- data/lib/less/js/test/css/functions.css +117 -2
- data/lib/less/js/test/css/globalVars/extended.css +12 -0
- data/lib/less/js/test/css/globalVars/simple.css +6 -0
- data/lib/less/js/test/css/ie-filters.css +7 -3
- data/lib/less/js/test/css/import-inline.css +5 -0
- data/lib/less/js/test/css/import-interpolation.css +6 -0
- data/lib/less/js/test/css/import-once.css +15 -0
- data/lib/less/js/test/css/import-reference.css +68 -0
- data/lib/less/js/test/css/import.css +23 -10
- data/lib/less/js/test/css/javascript.css +3 -2
- data/lib/less/js/test/css/legacy/legacy.css +7 -0
- data/lib/less/js/test/css/media.css +141 -1
- data/lib/less/js/test/css/merge.css +34 -0
- data/lib/less/js/test/css/mixins-args.css +41 -4
- data/lib/less/js/test/css/mixins-guards-default-func.css +129 -0
- data/lib/less/js/test/css/mixins-guards.css +24 -0
- data/lib/less/js/test/css/mixins-important.css +28 -0
- data/lib/less/js/test/css/mixins-interpolated.css +39 -0
- data/lib/less/js/test/css/mixins-named-args.css +27 -0
- data/lib/less/js/test/css/mixins-pattern.css +4 -0
- data/lib/less/js/test/css/mixins.css +70 -0
- data/lib/less/js/test/css/modifyVars/extended.css +9 -0
- data/lib/less/js/test/css/no-output.css +0 -0
- data/lib/less/js/test/css/parens.css +21 -5
- data/lib/less/js/test/css/property-name-interp.css +20 -0
- data/lib/less/js/test/css/scope.css +23 -0
- data/lib/less/js/test/css/selectors.css +84 -0
- data/lib/less/js/test/css/static-urls/urls.css +45 -0
- data/lib/less/js/test/css/strings.css +5 -2
- data/lib/less/js/test/css/url-args/urls.css +56 -0
- data/lib/less/js/test/css/urls.css +71 -0
- data/lib/less/js/test/css/variables-in-at-rules.css +18 -0
- data/lib/less/js/test/css/variables.css +22 -4
- data/lib/less/js/test/css/whitespace.css +4 -0
- data/lib/less/js/test/data/data-uri-fail.png +0 -0
- data/lib/less/js/test/data/image.jpg +1 -0
- data/lib/less/js/test/data/page.html +1 -0
- data/lib/less/js/test/index.js +45 -0
- data/lib/less/js/test/less/charsets.less +3 -0
- data/lib/less/js/test/less/colors.less +37 -4
- data/lib/less/js/test/less/comments.less +21 -3
- data/lib/less/js/test/less/compression/compression.less +36 -0
- data/lib/less/js/test/less/css-3.less +70 -6
- data/lib/less/js/test/less/css-escapes.less +6 -1
- data/lib/less/js/test/less/css-guards.less +102 -0
- data/lib/less/js/test/less/css.less +23 -15
- data/lib/less/js/test/less/debug/import/test.less +25 -0
- data/lib/less/js/test/less/debug/linenumbers.less +33 -0
- data/lib/less/js/test/less/detached-rulesets.less +103 -0
- data/lib/less/js/test/less/empty.less +0 -0
- data/lib/less/js/test/less/errors/add-mixed-units.less +3 -0
- data/lib/less/js/test/less/errors/add-mixed-units.txt +4 -0
- data/lib/less/js/test/less/errors/add-mixed-units2.less +3 -0
- data/lib/less/js/test/less/errors/add-mixed-units2.txt +4 -0
- data/lib/less/js/test/less/errors/at-rules-undefined-var.less +4 -0
- data/lib/less/js/test/less/errors/at-rules-undefined-var.txt +4 -0
- data/lib/less/js/test/less/errors/bad-variable-declaration1.less +1 -0
- data/lib/less/js/test/less/errors/bad-variable-declaration1.txt +2 -0
- data/lib/less/js/test/less/errors/color-func-invalid-color.less +3 -0
- data/lib/less/js/test/less/errors/color-func-invalid-color.txt +4 -0
- data/lib/less/js/test/less/errors/comment-in-selector.less +1 -0
- data/lib/less/js/test/less/errors/comment-in-selector.txt +2 -0
- data/lib/less/js/test/less/errors/css-guard-default-func.less +4 -0
- data/lib/less/js/test/less/errors/css-guard-default-func.txt +4 -0
- data/lib/less/js/test/less/errors/detached-ruleset-1.less +6 -0
- data/lib/less/js/test/less/errors/detached-ruleset-1.txt +4 -0
- data/lib/less/js/test/less/errors/detached-ruleset-2.less +6 -0
- data/lib/less/js/test/less/errors/detached-ruleset-2.txt +4 -0
- data/lib/less/js/test/less/errors/detached-ruleset-3.less +4 -0
- data/lib/less/js/test/less/errors/detached-ruleset-3.txt +4 -0
- data/lib/less/js/test/less/errors/detached-ruleset-4.less +5 -0
- data/lib/less/js/test/less/errors/detached-ruleset-4.txt +3 -0
- data/lib/less/js/test/less/errors/detached-ruleset-5.less +4 -0
- data/lib/less/js/test/less/errors/detached-ruleset-5.txt +3 -0
- data/lib/less/js/test/less/errors/detached-ruleset-6.less +5 -0
- data/lib/less/js/test/less/errors/detached-ruleset-6.txt +4 -0
- data/lib/less/js/test/less/errors/divide-mixed-units.less +3 -0
- data/lib/less/js/test/less/errors/divide-mixed-units.txt +4 -0
- data/lib/less/js/test/less/errors/extend-no-selector.less +3 -0
- data/lib/less/js/test/less/errors/extend-no-selector.txt +3 -0
- data/lib/less/js/test/less/errors/extend-not-at-end.less +3 -0
- data/lib/less/js/test/less/errors/extend-not-at-end.txt +3 -0
- data/lib/less/js/test/less/errors/import-missing.less +6 -0
- data/lib/less/js/test/less/errors/import-missing.txt +3 -0
- data/lib/less/js/test/less/errors/import-no-semi.less +1 -0
- data/lib/less/js/test/less/errors/import-no-semi.txt +2 -0
- data/lib/less/js/test/less/errors/import-subfolder1.less +1 -0
- data/lib/less/js/test/less/errors/import-subfolder1.txt +3 -0
- data/lib/less/js/test/less/errors/import-subfolder2.less +1 -0
- data/lib/less/js/test/less/errors/import-subfolder2.txt +4 -0
- data/lib/less/js/test/less/errors/imports/import-subfolder1.less +1 -0
- data/lib/less/js/test/less/errors/imports/import-subfolder2.less +1 -0
- data/lib/less/js/test/less/errors/imports/import-test.less +4 -0
- data/lib/less/js/test/less/errors/imports/subfolder/mixin-not-defined.less +1 -0
- data/lib/less/js/test/less/errors/imports/subfolder/parse-error-curly-bracket.less +1 -0
- data/lib/less/js/test/less/errors/javascript-error.less +3 -0
- data/lib/less/js/test/less/errors/javascript-error.txt +4 -0
- data/lib/less/js/test/less/errors/javascript-undefined-var.less +3 -0
- data/lib/less/js/test/less/errors/javascript-undefined-var.txt +4 -0
- data/lib/less/js/test/less/errors/mixed-mixin-definition-args-1.less +6 -0
- data/lib/less/js/test/less/errors/mixed-mixin-definition-args-1.txt +4 -0
- data/lib/less/js/test/less/errors/mixed-mixin-definition-args-2.less +6 -0
- data/lib/less/js/test/less/errors/mixed-mixin-definition-args-2.txt +4 -0
- data/lib/less/js/test/less/errors/mixin-not-defined.less +11 -0
- data/lib/less/js/test/less/errors/mixin-not-defined.txt +3 -0
- data/lib/less/js/test/less/errors/mixin-not-matched.less +6 -0
- data/lib/less/js/test/less/errors/mixin-not-matched.txt +3 -0
- data/lib/less/js/test/less/errors/mixin-not-matched2.less +6 -0
- data/lib/less/js/test/less/errors/mixin-not-matched2.txt +3 -0
- data/lib/less/js/test/less/errors/mixin-not-visible-in-scope-1.less +9 -0
- data/lib/less/js/test/less/errors/mixin-not-visible-in-scope-1.txt +4 -0
- data/lib/less/js/test/less/errors/mixins-guards-default-func-1.less +9 -0
- data/lib/less/js/test/less/errors/mixins-guards-default-func-1.txt +4 -0
- data/lib/less/js/test/less/errors/mixins-guards-default-func-2.less +9 -0
- data/lib/less/js/test/less/errors/mixins-guards-default-func-2.txt +4 -0
- data/lib/less/js/test/less/errors/mixins-guards-default-func-3.less +9 -0
- data/lib/less/js/test/less/errors/mixins-guards-default-func-3.txt +4 -0
- data/lib/less/js/test/less/errors/multiple-guards-on-css-selectors.less +4 -0
- data/lib/less/js/test/less/errors/multiple-guards-on-css-selectors.txt +4 -0
- data/lib/less/js/test/less/errors/multiple-guards-on-css-selectors2.less +4 -0
- data/lib/less/js/test/less/errors/multiple-guards-on-css-selectors2.txt +4 -0
- data/lib/less/js/test/less/errors/multiply-mixed-units.less +7 -0
- data/lib/less/js/test/less/errors/multiply-mixed-units.txt +4 -0
- data/lib/less/js/test/less/errors/parens-error-1.less +3 -0
- data/lib/less/js/test/less/errors/parens-error-1.txt +4 -0
- data/lib/less/js/test/less/errors/parens-error-2.less +3 -0
- data/lib/less/js/test/less/errors/parens-error-2.txt +4 -0
- data/lib/less/js/test/less/errors/parens-error-3.less +3 -0
- data/lib/less/js/test/less/errors/parens-error-3.txt +4 -0
- data/lib/less/js/test/less/errors/parse-error-curly-bracket.less +4 -0
- data/lib/less/js/test/less/errors/parse-error-curly-bracket.txt +4 -0
- data/lib/less/js/test/less/errors/parse-error-extra-parens.less +5 -0
- data/lib/less/js/test/less/errors/parse-error-extra-parens.txt +3 -0
- data/lib/less/js/test/less/errors/parse-error-missing-bracket.less +2 -0
- data/lib/less/js/test/less/errors/parse-error-missing-bracket.txt +3 -0
- data/lib/less/js/test/less/errors/parse-error-missing-parens.less +5 -0
- data/lib/less/js/test/less/errors/parse-error-missing-parens.txt +3 -0
- data/lib/less/js/test/less/errors/parse-error-with-import.less +13 -0
- data/lib/less/js/test/less/errors/parse-error-with-import.txt +4 -0
- data/lib/less/js/test/less/errors/percentage-missing-space.less +3 -0
- data/lib/less/js/test/less/errors/percentage-missing-space.txt +4 -0
- data/lib/less/js/test/less/errors/property-asterisk-only-name.less +3 -0
- data/lib/less/js/test/less/errors/property-asterisk-only-name.txt +4 -0
- data/lib/less/js/test/less/errors/property-ie5-hack.less +3 -0
- data/lib/less/js/test/less/errors/property-ie5-hack.txt +4 -0
- data/lib/less/js/test/less/errors/property-in-root.less +4 -0
- data/lib/less/js/test/less/errors/property-in-root.txt +4 -0
- data/lib/less/js/test/less/errors/property-in-root2.less +1 -0
- data/lib/less/js/test/less/errors/property-in-root2.txt +4 -0
- data/lib/less/js/test/less/errors/property-in-root3.less +4 -0
- data/lib/less/js/test/less/errors/property-in-root3.txt +3 -0
- data/lib/less/js/test/less/errors/property-interp-not-defined.less +1 -0
- data/lib/less/js/test/less/errors/property-interp-not-defined.txt +2 -0
- data/lib/less/js/test/less/errors/recursive-variable.less +1 -0
- data/lib/less/js/test/less/errors/recursive-variable.txt +2 -0
- data/lib/less/js/test/less/errors/svg-gradient1.less +3 -0
- data/lib/less/js/test/less/errors/svg-gradient1.txt +4 -0
- data/lib/less/js/test/less/errors/svg-gradient2.less +3 -0
- data/lib/less/js/test/less/errors/svg-gradient2.txt +4 -0
- data/lib/less/js/test/less/errors/svg-gradient3.less +3 -0
- data/lib/less/js/test/less/errors/svg-gradient3.txt +4 -0
- data/lib/less/js/test/less/errors/unit-function.less +3 -0
- data/lib/less/js/test/less/errors/unit-function.txt +4 -0
- data/lib/less/js/test/less/extend-chaining.less +91 -0
- data/lib/less/js/test/less/extend-clearfix.less +19 -0
- data/lib/less/js/test/less/extend-exact.less +46 -0
- data/lib/less/js/test/less/extend-media.less +24 -0
- data/lib/less/js/test/less/extend-nest.less +65 -0
- data/lib/less/js/test/less/extend-selector.less +99 -0
- data/lib/less/js/test/less/extend.less +81 -0
- data/lib/less/js/test/less/extract-and-length.less +133 -0
- data/lib/less/js/test/less/functions.less +130 -6
- data/lib/less/js/test/less/globalVars/extended.json +5 -0
- data/lib/less/js/test/less/globalVars/extended.less +10 -0
- data/lib/less/js/test/less/globalVars/simple.json +3 -0
- data/lib/less/js/test/less/globalVars/simple.less +3 -0
- data/lib/less/js/test/less/ie-filters.less +7 -0
- data/lib/less/js/test/less/import/deeper/import-once-test-a.less +1 -0
- data/lib/less/js/test/less/import/import-and-relative-paths-test.less +17 -0
- data/lib/less/js/test/less/import/import-charset-test.less +1 -0
- data/lib/less/js/test/less/import/import-interpolation.less +1 -0
- data/lib/less/js/test/less/import/import-interpolation2.less +5 -0
- data/lib/less/js/test/less/import/import-once-test-c.less +6 -0
- data/lib/less/js/test/less/import/import-reference.less +51 -0
- data/lib/less/js/test/less/import/import-test-a.less +1 -0
- data/lib/less/js/test/less/import/import-test-c.less +0 -1
- data/lib/less/js/test/less/import/import-test-f.less +5 -0
- data/lib/less/js/test/less/import/imports/font.less +8 -0
- data/lib/less/js/test/less/import/imports/logo.less +5 -0
- data/lib/less/js/test/less/import/invalid-css.less +1 -0
- data/lib/less/js/test/less/import/urls.less +1 -0
- data/lib/less/js/test/less/import-inline.less +2 -0
- data/lib/less/js/test/less/import-interpolation.less +8 -0
- data/lib/less/js/test/less/import-once.less +6 -0
- data/lib/less/js/test/less/import-reference.less +21 -0
- data/lib/less/js/test/less/import.less +13 -3
- data/lib/less/js/test/less/javascript.less +5 -3
- data/lib/less/js/test/less/legacy/legacy.less +7 -0
- data/lib/less/js/test/less/media.less +158 -3
- data/lib/less/js/test/less/merge.less +78 -0
- data/lib/less/js/test/less/mixins-args.less +93 -15
- data/lib/less/js/test/less/mixins-guards-default-func.less +195 -0
- data/lib/less/js/test/less/mixins-guards.less +65 -0
- data/lib/less/js/test/less/mixins-important.less +8 -1
- data/lib/less/js/test/less/mixins-interpolated.less +69 -0
- data/lib/less/js/test/less/mixins-named-args.less +36 -0
- data/lib/less/js/test/less/mixins-nested.less +2 -2
- data/lib/less/js/test/less/mixins-pattern.less +4 -1
- data/lib/less/js/test/less/mixins.less +74 -0
- data/lib/less/js/test/less/modifyVars/extended.json +5 -0
- data/lib/less/js/test/less/modifyVars/extended.less +11 -0
- data/lib/less/js/test/less/no-js-errors/no-js-errors.less +3 -0
- data/lib/less/js/test/less/no-js-errors/no-js-errors.txt +4 -0
- data/lib/less/js/test/less/no-output.less +2 -0
- data/lib/less/js/test/less/operations.less +27 -27
- data/lib/less/js/test/less/parens.less +24 -5
- data/lib/less/js/test/less/property-name-interp.less +53 -0
- data/lib/less/js/test/less/scope.less +73 -1
- data/lib/less/js/test/less/selectors.less +101 -0
- data/lib/less/js/test/less/sourcemaps/basic.json +3 -0
- data/lib/less/js/test/less/sourcemaps/basic.less +27 -0
- data/lib/less/js/test/less/sourcemaps/imported.css +7 -0
- data/lib/less/js/test/less/static-urls/urls.less +33 -0
- data/lib/less/js/test/less/strings.less +7 -1
- data/lib/less/js/test/less/url-args/urls.less +63 -0
- data/lib/less/js/test/less/urls.less +72 -0
- data/lib/less/js/test/less/variables-in-at-rules.less +20 -0
- data/lib/less/js/test/less/variables.less +42 -13
- data/lib/less/js/test/less/whitespace.less +7 -0
- data/lib/less/js/test/less-test.js +251 -65
- data/lib/less/js/test/rhino/test-header.js +15 -0
- data/lib/less/js/test/sourcemaps/basic.json +1 -0
- data/lib/less/js/test/sourcemaps/index.html +17 -0
- data/lib/less/loader.rb +191 -27
- data/lib/less/parser.rb +47 -8
- data/lib/less/version.rb +2 -2
- data/spec/less/loader_spec.rb +45 -0
- data/spec/less/parser_spec.rb +43 -17
- data/spec/less/some/some.css +0 -0
- data/spec/less/some/some.less +4 -0
- metadata +352 -57
- data/lib/less/js/CHANGELOG +0 -41
- data/lib/less/js/Makefile +0 -75
- data/lib/less/js/build/ecma-5.js +0 -120
- data/lib/less/js/build/header.js +0 -7
- data/lib/less/js/lib/less/cssmin.js +0 -355
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
(function (tree) {
|
|
2
|
+
|
|
3
|
+
var parseCopyProperties = [
|
|
4
|
+
'paths', // option - unmodified - paths to search for imports on
|
|
5
|
+
'optimization', // option - optimization level (for the chunker)
|
|
6
|
+
'files', // list of files that have been imported, used for import-once
|
|
7
|
+
'contents', // map - filename to contents of all the files
|
|
8
|
+
'contentsIgnoredChars', // map - filename to lines at the begining of each file to ignore
|
|
9
|
+
'relativeUrls', // option - whether to adjust URL's to be relative
|
|
10
|
+
'rootpath', // option - rootpath to append to URL's
|
|
11
|
+
'strictImports', // option -
|
|
12
|
+
'insecure', // option - whether to allow imports from insecure ssl hosts
|
|
13
|
+
'dumpLineNumbers', // option - whether to dump line numbers
|
|
14
|
+
'compress', // option - whether to compress
|
|
15
|
+
'processImports', // option - whether to process imports. if false then imports will not be imported
|
|
16
|
+
'syncImport', // option - whether to import synchronously
|
|
17
|
+
'javascriptEnabled',// option - whether JavaScript is enabled. if undefined, defaults to true
|
|
18
|
+
'mime', // browser only - mime type for sheet import
|
|
19
|
+
'useFileCache', // browser only - whether to use the per file session cache
|
|
20
|
+
'currentFileInfo' // information about the current file - for error reporting and importing and making urls relative etc.
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
//currentFileInfo = {
|
|
24
|
+
// 'relativeUrls' - option - whether to adjust URL's to be relative
|
|
25
|
+
// 'filename' - full resolved filename of current file
|
|
26
|
+
// 'rootpath' - path to append to normal URLs for this node
|
|
27
|
+
// 'currentDirectory' - path to the current file, absolute
|
|
28
|
+
// 'rootFilename' - filename of the base file
|
|
29
|
+
// 'entryPath' - absolute path to the entry file
|
|
30
|
+
// 'reference' - whether the file should not be output and only output parts that are referenced
|
|
31
|
+
|
|
32
|
+
tree.parseEnv = function(options) {
|
|
33
|
+
copyFromOriginal(options, this, parseCopyProperties);
|
|
34
|
+
|
|
35
|
+
if (!this.contents) { this.contents = {}; }
|
|
36
|
+
if (!this.contentsIgnoredChars) { this.contentsIgnoredChars = {}; }
|
|
37
|
+
if (!this.files) { this.files = {}; }
|
|
38
|
+
|
|
39
|
+
if (!this.currentFileInfo) {
|
|
40
|
+
var filename = (options && options.filename) || "input";
|
|
41
|
+
var entryPath = filename.replace(/[^\/\\]*$/, "");
|
|
42
|
+
if (options) {
|
|
43
|
+
options.filename = null;
|
|
44
|
+
}
|
|
45
|
+
this.currentFileInfo = {
|
|
46
|
+
filename: filename,
|
|
47
|
+
relativeUrls: this.relativeUrls,
|
|
48
|
+
rootpath: (options && options.rootpath) || "",
|
|
49
|
+
currentDirectory: entryPath,
|
|
50
|
+
entryPath: entryPath,
|
|
51
|
+
rootFilename: filename
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
var evalCopyProperties = [
|
|
57
|
+
'silent', // whether to swallow errors and warnings
|
|
58
|
+
'verbose', // whether to log more activity
|
|
59
|
+
'compress', // whether to compress
|
|
60
|
+
'yuicompress', // whether to compress with the outside tool yui compressor
|
|
61
|
+
'ieCompat', // whether to enforce IE compatibility (IE8 data-uri)
|
|
62
|
+
'strictMath', // whether math has to be within parenthesis
|
|
63
|
+
'strictUnits', // whether units need to evaluate correctly
|
|
64
|
+
'cleancss', // whether to compress with clean-css
|
|
65
|
+
'sourceMap', // whether to output a source map
|
|
66
|
+
'importMultiple', // whether we are currently importing multiple copies
|
|
67
|
+
'urlArgs' // whether to add args into url tokens
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
tree.evalEnv = function(options, frames) {
|
|
71
|
+
copyFromOriginal(options, this, evalCopyProperties);
|
|
72
|
+
|
|
73
|
+
this.frames = frames || [];
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
tree.evalEnv.prototype.inParenthesis = function () {
|
|
77
|
+
if (!this.parensStack) {
|
|
78
|
+
this.parensStack = [];
|
|
79
|
+
}
|
|
80
|
+
this.parensStack.push(true);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
tree.evalEnv.prototype.outOfParenthesis = function () {
|
|
84
|
+
this.parensStack.pop();
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
tree.evalEnv.prototype.isMathOn = function () {
|
|
88
|
+
return this.strictMath ? (this.parensStack && this.parensStack.length) : true;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
tree.evalEnv.prototype.isPathRelative = function (path) {
|
|
92
|
+
return !/^(?:[a-z-]+:|\/)/.test(path);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
tree.evalEnv.prototype.normalizePath = function( path ) {
|
|
96
|
+
var
|
|
97
|
+
segments = path.split("/").reverse(),
|
|
98
|
+
segment;
|
|
99
|
+
|
|
100
|
+
path = [];
|
|
101
|
+
while (segments.length !== 0 ) {
|
|
102
|
+
segment = segments.pop();
|
|
103
|
+
switch( segment ) {
|
|
104
|
+
case ".":
|
|
105
|
+
break;
|
|
106
|
+
case "..":
|
|
107
|
+
if ((path.length === 0) || (path[path.length - 1] === "..")) {
|
|
108
|
+
path.push( segment );
|
|
109
|
+
} else {
|
|
110
|
+
path.pop();
|
|
111
|
+
}
|
|
112
|
+
break;
|
|
113
|
+
default:
|
|
114
|
+
path.push( segment );
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return path.join("/");
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
//todo - do the same for the toCSS env
|
|
123
|
+
//tree.toCSSEnv = function (options) {
|
|
124
|
+
//};
|
|
125
|
+
|
|
126
|
+
var copyFromOriginal = function(original, destination, propertiesToCopy) {
|
|
127
|
+
if (!original) { return; }
|
|
128
|
+
|
|
129
|
+
for(var i = 0; i < propertiesToCopy.length; i++) {
|
|
130
|
+
if (original.hasOwnProperty(propertiesToCopy[i])) {
|
|
131
|
+
destination[propertiesToCopy[i]] = original[propertiesToCopy[i]];
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
})(require('./tree'));
|
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
(function (tree) {
|
|
2
|
+
/*jshint loopfunc:true */
|
|
3
|
+
|
|
4
|
+
tree.extendFinderVisitor = function() {
|
|
5
|
+
this._visitor = new tree.visitor(this);
|
|
6
|
+
this.contexts = [];
|
|
7
|
+
this.allExtendsStack = [[]];
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
tree.extendFinderVisitor.prototype = {
|
|
11
|
+
run: function (root) {
|
|
12
|
+
root = this._visitor.visit(root);
|
|
13
|
+
root.allExtends = this.allExtendsStack[0];
|
|
14
|
+
return root;
|
|
15
|
+
},
|
|
16
|
+
visitRule: function (ruleNode, visitArgs) {
|
|
17
|
+
visitArgs.visitDeeper = false;
|
|
18
|
+
},
|
|
19
|
+
visitMixinDefinition: function (mixinDefinitionNode, visitArgs) {
|
|
20
|
+
visitArgs.visitDeeper = false;
|
|
21
|
+
},
|
|
22
|
+
visitRuleset: function (rulesetNode, visitArgs) {
|
|
23
|
+
if (rulesetNode.root) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
var i, j, extend, allSelectorsExtendList = [], extendList;
|
|
28
|
+
|
|
29
|
+
// get &:extend(.a); rules which apply to all selectors in this ruleset
|
|
30
|
+
var rules = rulesetNode.rules, ruleCnt = rules ? rules.length : 0;
|
|
31
|
+
for(i = 0; i < ruleCnt; i++) {
|
|
32
|
+
if (rulesetNode.rules[i] instanceof tree.Extend) {
|
|
33
|
+
allSelectorsExtendList.push(rules[i]);
|
|
34
|
+
rulesetNode.extendOnEveryPath = true;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// now find every selector and apply the extends that apply to all extends
|
|
39
|
+
// and the ones which apply to an individual extend
|
|
40
|
+
var paths = rulesetNode.paths;
|
|
41
|
+
for(i = 0; i < paths.length; i++) {
|
|
42
|
+
var selectorPath = paths[i],
|
|
43
|
+
selector = selectorPath[selectorPath.length - 1],
|
|
44
|
+
selExtendList = selector.extendList;
|
|
45
|
+
|
|
46
|
+
extendList = selExtendList ? selExtendList.slice(0).concat(allSelectorsExtendList)
|
|
47
|
+
: allSelectorsExtendList;
|
|
48
|
+
|
|
49
|
+
if (extendList) {
|
|
50
|
+
extendList = extendList.map(function(allSelectorsExtend) {
|
|
51
|
+
return allSelectorsExtend.clone();
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
for(j = 0; j < extendList.length; j++) {
|
|
56
|
+
this.foundExtends = true;
|
|
57
|
+
extend = extendList[j];
|
|
58
|
+
extend.findSelfSelectors(selectorPath);
|
|
59
|
+
extend.ruleset = rulesetNode;
|
|
60
|
+
if (j === 0) { extend.firstExtendOnThisSelectorPath = true; }
|
|
61
|
+
this.allExtendsStack[this.allExtendsStack.length-1].push(extend);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
this.contexts.push(rulesetNode.selectors);
|
|
66
|
+
},
|
|
67
|
+
visitRulesetOut: function (rulesetNode) {
|
|
68
|
+
if (!rulesetNode.root) {
|
|
69
|
+
this.contexts.length = this.contexts.length - 1;
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
visitMedia: function (mediaNode, visitArgs) {
|
|
73
|
+
mediaNode.allExtends = [];
|
|
74
|
+
this.allExtendsStack.push(mediaNode.allExtends);
|
|
75
|
+
},
|
|
76
|
+
visitMediaOut: function (mediaNode) {
|
|
77
|
+
this.allExtendsStack.length = this.allExtendsStack.length - 1;
|
|
78
|
+
},
|
|
79
|
+
visitDirective: function (directiveNode, visitArgs) {
|
|
80
|
+
directiveNode.allExtends = [];
|
|
81
|
+
this.allExtendsStack.push(directiveNode.allExtends);
|
|
82
|
+
},
|
|
83
|
+
visitDirectiveOut: function (directiveNode) {
|
|
84
|
+
this.allExtendsStack.length = this.allExtendsStack.length - 1;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
tree.processExtendsVisitor = function() {
|
|
89
|
+
this._visitor = new tree.visitor(this);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
tree.processExtendsVisitor.prototype = {
|
|
93
|
+
run: function(root) {
|
|
94
|
+
var extendFinder = new tree.extendFinderVisitor();
|
|
95
|
+
extendFinder.run(root);
|
|
96
|
+
if (!extendFinder.foundExtends) { return root; }
|
|
97
|
+
root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends));
|
|
98
|
+
this.allExtendsStack = [root.allExtends];
|
|
99
|
+
return this._visitor.visit(root);
|
|
100
|
+
},
|
|
101
|
+
doExtendChaining: function (extendsList, extendsListTarget, iterationCount) {
|
|
102
|
+
//
|
|
103
|
+
// chaining is different from normal extension.. if we extend an extend then we are not just copying, altering and pasting
|
|
104
|
+
// the selector we would do normally, but we are also adding an extend with the same target selector
|
|
105
|
+
// this means this new extend can then go and alter other extends
|
|
106
|
+
//
|
|
107
|
+
// this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors
|
|
108
|
+
// this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already processed if
|
|
109
|
+
// we look at each selector at a time, as is done in visitRuleset
|
|
110
|
+
|
|
111
|
+
var extendIndex, targetExtendIndex, matches, extendsToAdd = [], newSelector, extendVisitor = this, selectorPath, extend, targetExtend, newExtend;
|
|
112
|
+
|
|
113
|
+
iterationCount = iterationCount || 0;
|
|
114
|
+
|
|
115
|
+
//loop through comparing every extend with every target extend.
|
|
116
|
+
// a target extend is the one on the ruleset we are looking at copy/edit/pasting in place
|
|
117
|
+
// e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one
|
|
118
|
+
// and the second is the target.
|
|
119
|
+
// the seperation into two lists allows us to process a subset of chains with a bigger set, as is the
|
|
120
|
+
// case when processing media queries
|
|
121
|
+
for(extendIndex = 0; extendIndex < extendsList.length; extendIndex++){
|
|
122
|
+
for(targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++){
|
|
123
|
+
|
|
124
|
+
extend = extendsList[extendIndex];
|
|
125
|
+
targetExtend = extendsListTarget[targetExtendIndex];
|
|
126
|
+
|
|
127
|
+
// look for circular references
|
|
128
|
+
if( extend.parent_ids.indexOf( targetExtend.object_id ) >= 0 ){ continue; }
|
|
129
|
+
|
|
130
|
+
// find a match in the target extends self selector (the bit before :extend)
|
|
131
|
+
selectorPath = [targetExtend.selfSelectors[0]];
|
|
132
|
+
matches = extendVisitor.findMatch(extend, selectorPath);
|
|
133
|
+
|
|
134
|
+
if (matches.length) {
|
|
135
|
+
|
|
136
|
+
// we found a match, so for each self selector..
|
|
137
|
+
extend.selfSelectors.forEach(function(selfSelector) {
|
|
138
|
+
|
|
139
|
+
// process the extend as usual
|
|
140
|
+
newSelector = extendVisitor.extendSelector(matches, selectorPath, selfSelector);
|
|
141
|
+
|
|
142
|
+
// but now we create a new extend from it
|
|
143
|
+
newExtend = new(tree.Extend)(targetExtend.selector, targetExtend.option, 0);
|
|
144
|
+
newExtend.selfSelectors = newSelector;
|
|
145
|
+
|
|
146
|
+
// add the extend onto the list of extends for that selector
|
|
147
|
+
newSelector[newSelector.length-1].extendList = [newExtend];
|
|
148
|
+
|
|
149
|
+
// record that we need to add it.
|
|
150
|
+
extendsToAdd.push(newExtend);
|
|
151
|
+
newExtend.ruleset = targetExtend.ruleset;
|
|
152
|
+
|
|
153
|
+
//remember its parents for circular references
|
|
154
|
+
newExtend.parent_ids = newExtend.parent_ids.concat(targetExtend.parent_ids, extend.parent_ids);
|
|
155
|
+
|
|
156
|
+
// only process the selector once.. if we have :extend(.a,.b) then multiple
|
|
157
|
+
// extends will look at the same selector path, so when extending
|
|
158
|
+
// we know that any others will be duplicates in terms of what is added to the css
|
|
159
|
+
if (targetExtend.firstExtendOnThisSelectorPath) {
|
|
160
|
+
newExtend.firstExtendOnThisSelectorPath = true;
|
|
161
|
+
targetExtend.ruleset.paths.push(newSelector);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (extendsToAdd.length) {
|
|
169
|
+
// try to detect circular references to stop a stack overflow.
|
|
170
|
+
// may no longer be needed.
|
|
171
|
+
this.extendChainCount++;
|
|
172
|
+
if (iterationCount > 100) {
|
|
173
|
+
var selectorOne = "{unable to calculate}";
|
|
174
|
+
var selectorTwo = "{unable to calculate}";
|
|
175
|
+
try
|
|
176
|
+
{
|
|
177
|
+
selectorOne = extendsToAdd[0].selfSelectors[0].toCSS();
|
|
178
|
+
selectorTwo = extendsToAdd[0].selector.toCSS();
|
|
179
|
+
}
|
|
180
|
+
catch(e) {}
|
|
181
|
+
throw {message: "extend circular reference detected. One of the circular extends is currently:"+selectorOne+":extend(" + selectorTwo+")"};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// now process the new extends on the existing rules so that we can handle a extending b extending c ectending d extending e...
|
|
185
|
+
return extendsToAdd.concat(extendVisitor.doExtendChaining(extendsToAdd, extendsListTarget, iterationCount+1));
|
|
186
|
+
} else {
|
|
187
|
+
return extendsToAdd;
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
visitRule: function (ruleNode, visitArgs) {
|
|
191
|
+
visitArgs.visitDeeper = false;
|
|
192
|
+
},
|
|
193
|
+
visitMixinDefinition: function (mixinDefinitionNode, visitArgs) {
|
|
194
|
+
visitArgs.visitDeeper = false;
|
|
195
|
+
},
|
|
196
|
+
visitSelector: function (selectorNode, visitArgs) {
|
|
197
|
+
visitArgs.visitDeeper = false;
|
|
198
|
+
},
|
|
199
|
+
visitRuleset: function (rulesetNode, visitArgs) {
|
|
200
|
+
if (rulesetNode.root) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
var matches, pathIndex, extendIndex, allExtends = this.allExtendsStack[this.allExtendsStack.length-1], selectorsToAdd = [], extendVisitor = this, selectorPath;
|
|
204
|
+
|
|
205
|
+
// look at each selector path in the ruleset, find any extend matches and then copy, find and replace
|
|
206
|
+
|
|
207
|
+
for(extendIndex = 0; extendIndex < allExtends.length; extendIndex++) {
|
|
208
|
+
for(pathIndex = 0; pathIndex < rulesetNode.paths.length; pathIndex++) {
|
|
209
|
+
selectorPath = rulesetNode.paths[pathIndex];
|
|
210
|
+
|
|
211
|
+
// extending extends happens initially, before the main pass
|
|
212
|
+
if (rulesetNode.extendOnEveryPath) { continue; }
|
|
213
|
+
var extendList = selectorPath[selectorPath.length-1].extendList;
|
|
214
|
+
if (extendList && extendList.length) { continue; }
|
|
215
|
+
|
|
216
|
+
matches = this.findMatch(allExtends[extendIndex], selectorPath);
|
|
217
|
+
|
|
218
|
+
if (matches.length) {
|
|
219
|
+
|
|
220
|
+
allExtends[extendIndex].selfSelectors.forEach(function(selfSelector) {
|
|
221
|
+
selectorsToAdd.push(extendVisitor.extendSelector(matches, selectorPath, selfSelector));
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd);
|
|
227
|
+
},
|
|
228
|
+
findMatch: function (extend, haystackSelectorPath) {
|
|
229
|
+
//
|
|
230
|
+
// look through the haystack selector path to try and find the needle - extend.selector
|
|
231
|
+
// returns an array of selector matches that can then be replaced
|
|
232
|
+
//
|
|
233
|
+
var haystackSelectorIndex, hackstackSelector, hackstackElementIndex, haystackElement,
|
|
234
|
+
targetCombinator, i,
|
|
235
|
+
extendVisitor = this,
|
|
236
|
+
needleElements = extend.selector.elements,
|
|
237
|
+
potentialMatches = [], potentialMatch, matches = [];
|
|
238
|
+
|
|
239
|
+
// loop through the haystack elements
|
|
240
|
+
for(haystackSelectorIndex = 0; haystackSelectorIndex < haystackSelectorPath.length; haystackSelectorIndex++) {
|
|
241
|
+
hackstackSelector = haystackSelectorPath[haystackSelectorIndex];
|
|
242
|
+
|
|
243
|
+
for(hackstackElementIndex = 0; hackstackElementIndex < hackstackSelector.elements.length; hackstackElementIndex++) {
|
|
244
|
+
|
|
245
|
+
haystackElement = hackstackSelector.elements[hackstackElementIndex];
|
|
246
|
+
|
|
247
|
+
// if we allow elements before our match we can add a potential match every time. otherwise only at the first element.
|
|
248
|
+
if (extend.allowBefore || (haystackSelectorIndex === 0 && hackstackElementIndex === 0)) {
|
|
249
|
+
potentialMatches.push({pathIndex: haystackSelectorIndex, index: hackstackElementIndex, matched: 0, initialCombinator: haystackElement.combinator});
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
for(i = 0; i < potentialMatches.length; i++) {
|
|
253
|
+
potentialMatch = potentialMatches[i];
|
|
254
|
+
|
|
255
|
+
// selectors add " " onto the first element. When we use & it joins the selectors together, but if we don't
|
|
256
|
+
// then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to work out
|
|
257
|
+
// what the resulting combinator will be
|
|
258
|
+
targetCombinator = haystackElement.combinator.value;
|
|
259
|
+
if (targetCombinator === '' && hackstackElementIndex === 0) {
|
|
260
|
+
targetCombinator = ' ';
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// if we don't match, null our match to indicate failure
|
|
264
|
+
if (!extendVisitor.isElementValuesEqual(needleElements[potentialMatch.matched].value, haystackElement.value) ||
|
|
265
|
+
(potentialMatch.matched > 0 && needleElements[potentialMatch.matched].combinator.value !== targetCombinator)) {
|
|
266
|
+
potentialMatch = null;
|
|
267
|
+
} else {
|
|
268
|
+
potentialMatch.matched++;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// if we are still valid and have finished, test whether we have elements after and whether these are allowed
|
|
272
|
+
if (potentialMatch) {
|
|
273
|
+
potentialMatch.finished = potentialMatch.matched === needleElements.length;
|
|
274
|
+
if (potentialMatch.finished &&
|
|
275
|
+
(!extend.allowAfter && (hackstackElementIndex+1 < hackstackSelector.elements.length || haystackSelectorIndex+1 < haystackSelectorPath.length))) {
|
|
276
|
+
potentialMatch = null;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
// if null we remove, if not, we are still valid, so either push as a valid match or continue
|
|
280
|
+
if (potentialMatch) {
|
|
281
|
+
if (potentialMatch.finished) {
|
|
282
|
+
potentialMatch.length = needleElements.length;
|
|
283
|
+
potentialMatch.endPathIndex = haystackSelectorIndex;
|
|
284
|
+
potentialMatch.endPathElementIndex = hackstackElementIndex + 1; // index after end of match
|
|
285
|
+
potentialMatches.length = 0; // we don't allow matches to overlap, so start matching again
|
|
286
|
+
matches.push(potentialMatch);
|
|
287
|
+
}
|
|
288
|
+
} else {
|
|
289
|
+
potentialMatches.splice(i, 1);
|
|
290
|
+
i--;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return matches;
|
|
296
|
+
},
|
|
297
|
+
isElementValuesEqual: function(elementValue1, elementValue2) {
|
|
298
|
+
if (typeof elementValue1 === "string" || typeof elementValue2 === "string") {
|
|
299
|
+
return elementValue1 === elementValue2;
|
|
300
|
+
}
|
|
301
|
+
if (elementValue1 instanceof tree.Attribute) {
|
|
302
|
+
if (elementValue1.op !== elementValue2.op || elementValue1.key !== elementValue2.key) {
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
if (!elementValue1.value || !elementValue2.value) {
|
|
306
|
+
if (elementValue1.value || elementValue2.value) {
|
|
307
|
+
return false;
|
|
308
|
+
}
|
|
309
|
+
return true;
|
|
310
|
+
}
|
|
311
|
+
elementValue1 = elementValue1.value.value || elementValue1.value;
|
|
312
|
+
elementValue2 = elementValue2.value.value || elementValue2.value;
|
|
313
|
+
return elementValue1 === elementValue2;
|
|
314
|
+
}
|
|
315
|
+
elementValue1 = elementValue1.value;
|
|
316
|
+
elementValue2 = elementValue2.value;
|
|
317
|
+
if (elementValue1 instanceof tree.Selector) {
|
|
318
|
+
if (!(elementValue2 instanceof tree.Selector) || elementValue1.elements.length !== elementValue2.elements.length) {
|
|
319
|
+
return false;
|
|
320
|
+
}
|
|
321
|
+
for(var i = 0; i <elementValue1.elements.length; i++) {
|
|
322
|
+
if (elementValue1.elements[i].combinator.value !== elementValue2.elements[i].combinator.value) {
|
|
323
|
+
if (i !== 0 || (elementValue1.elements[i].combinator.value || ' ') !== (elementValue2.elements[i].combinator.value || ' ')) {
|
|
324
|
+
return false;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
if (!this.isElementValuesEqual(elementValue1.elements[i].value, elementValue2.elements[i].value)) {
|
|
328
|
+
return false;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return true;
|
|
332
|
+
}
|
|
333
|
+
return false;
|
|
334
|
+
},
|
|
335
|
+
extendSelector:function (matches, selectorPath, replacementSelector) {
|
|
336
|
+
|
|
337
|
+
//for a set of matches, replace each match with the replacement selector
|
|
338
|
+
|
|
339
|
+
var currentSelectorPathIndex = 0,
|
|
340
|
+
currentSelectorPathElementIndex = 0,
|
|
341
|
+
path = [],
|
|
342
|
+
matchIndex,
|
|
343
|
+
selector,
|
|
344
|
+
firstElement,
|
|
345
|
+
match,
|
|
346
|
+
newElements;
|
|
347
|
+
|
|
348
|
+
for (matchIndex = 0; matchIndex < matches.length; matchIndex++) {
|
|
349
|
+
match = matches[matchIndex];
|
|
350
|
+
selector = selectorPath[match.pathIndex];
|
|
351
|
+
firstElement = new tree.Element(
|
|
352
|
+
match.initialCombinator,
|
|
353
|
+
replacementSelector.elements[0].value,
|
|
354
|
+
replacementSelector.elements[0].index,
|
|
355
|
+
replacementSelector.elements[0].currentFileInfo
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
if (match.pathIndex > currentSelectorPathIndex && currentSelectorPathElementIndex > 0) {
|
|
359
|
+
path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex));
|
|
360
|
+
currentSelectorPathElementIndex = 0;
|
|
361
|
+
currentSelectorPathIndex++;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
newElements = selector.elements
|
|
365
|
+
.slice(currentSelectorPathElementIndex, match.index)
|
|
366
|
+
.concat([firstElement])
|
|
367
|
+
.concat(replacementSelector.elements.slice(1));
|
|
368
|
+
|
|
369
|
+
if (currentSelectorPathIndex === match.pathIndex && matchIndex > 0) {
|
|
370
|
+
path[path.length - 1].elements =
|
|
371
|
+
path[path.length - 1].elements.concat(newElements);
|
|
372
|
+
} else {
|
|
373
|
+
path = path.concat(selectorPath.slice(currentSelectorPathIndex, match.pathIndex));
|
|
374
|
+
|
|
375
|
+
path.push(new tree.Selector(
|
|
376
|
+
newElements
|
|
377
|
+
));
|
|
378
|
+
}
|
|
379
|
+
currentSelectorPathIndex = match.endPathIndex;
|
|
380
|
+
currentSelectorPathElementIndex = match.endPathElementIndex;
|
|
381
|
+
if (currentSelectorPathElementIndex >= selectorPath[currentSelectorPathIndex].elements.length) {
|
|
382
|
+
currentSelectorPathElementIndex = 0;
|
|
383
|
+
currentSelectorPathIndex++;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
if (currentSelectorPathIndex < selectorPath.length && currentSelectorPathElementIndex > 0) {
|
|
388
|
+
path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex));
|
|
389
|
+
currentSelectorPathIndex++;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
path = path.concat(selectorPath.slice(currentSelectorPathIndex, selectorPath.length));
|
|
393
|
+
|
|
394
|
+
return path;
|
|
395
|
+
},
|
|
396
|
+
visitRulesetOut: function (rulesetNode) {
|
|
397
|
+
},
|
|
398
|
+
visitMedia: function (mediaNode, visitArgs) {
|
|
399
|
+
var newAllExtends = mediaNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]);
|
|
400
|
+
newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, mediaNode.allExtends));
|
|
401
|
+
this.allExtendsStack.push(newAllExtends);
|
|
402
|
+
},
|
|
403
|
+
visitMediaOut: function (mediaNode) {
|
|
404
|
+
this.allExtendsStack.length = this.allExtendsStack.length - 1;
|
|
405
|
+
},
|
|
406
|
+
visitDirective: function (directiveNode, visitArgs) {
|
|
407
|
+
var newAllExtends = directiveNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]);
|
|
408
|
+
newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, directiveNode.allExtends));
|
|
409
|
+
this.allExtendsStack.push(newAllExtends);
|
|
410
|
+
},
|
|
411
|
+
visitDirectiveOut: function (directiveNode) {
|
|
412
|
+
this.allExtendsStack.length = this.allExtendsStack.length - 1;
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
})(require('./tree'));
|