From 92054291894973d4e4a0d2d6951c2a01a40e9c82 Mon Sep 17 00:00:00 2001 From: Timo Tijhof Date: Thu, 18 Jan 2024 23:51:14 +0600 Subject: [PATCH] test: Remove unused lessjs 1.x fixtures Change-Id: I7f7d58913ea23170561105821ad35b6ae0c557d4 --- test/Fixtures/lessjs (1.5)/css/a.css | 6 - test/Fixtures/lessjs (1.5)/css/charsets.css | 1 - test/Fixtures/lessjs (1.5)/css/colors.css | 80 - test/Fixtures/lessjs (1.5)/css/comments.css | 69 - .../css/compression/compression.css | 3 - test/Fixtures/lessjs (1.5)/css/css-3.css | 125 - .../Fixtures/lessjs (1.5)/css/css-escapes.css | 24 - test/Fixtures/lessjs (1.5)/css/css-guards.css | 18 - test/Fixtures/lessjs (1.5)/css/css.css | 95 - .../css/debug/linenumbers-all.css | 43 - .../css/debug/linenumbers-comments.css | 35 - .../css/debug/linenumbers-mediaquery.css | 35 - .../lessjs (1.5)/css/extend-chaining.css | 81 - .../lessjs (1.5)/css/extend-clearfix.css | 19 - .../lessjs (1.5)/css/extend-exact.css | 37 - .../lessjs (1.5)/css/extend-media.css | 24 - .../Fixtures/lessjs (1.5)/css/extend-nest.css | 57 - .../lessjs (1.5)/css/extend-selector.css | 80 - test/Fixtures/lessjs (1.5)/css/extend.css | 76 - .../lessjs (1.5)/css/extract-and-length.css | 133 - test/Fixtures/lessjs (1.5)/css/functions.css | 139 - test/Fixtures/lessjs (1.5)/css/ie-filters.css | 9 - .../lessjs (1.5)/css/import-inline.css | 5 - .../lessjs (1.5)/css/import-interpolation.css | 6 - .../Fixtures/lessjs (1.5)/css/import-once.css | 15 - .../lessjs (1.5)/css/import-reference.css | 55 - test/Fixtures/lessjs (1.5)/css/import.css | 36 - test/Fixtures/lessjs (1.5)/css/javascript.css | 23 - test/Fixtures/lessjs (1.5)/css/lazy-eval.css | 3 - .../lessjs (1.5)/css/legacy/legacy.css | 7 - test/Fixtures/lessjs (1.5)/css/media.css | 219 - test/Fixtures/lessjs (1.5)/css/merge.css | 22 - .../Fixtures/lessjs (1.5)/css/mixins-args.css | 113 - .../lessjs (1.5)/css/mixins-closure.css | 9 - .../lessjs (1.5)/css/mixins-guards.css | 82 - .../lessjs (1.5)/css/mixins-important.css | 45 - .../lessjs (1.5)/css/mixins-named-args.css | 27 - .../lessjs (1.5)/css/mixins-nested.css | 14 - .../lessjs (1.5)/css/mixins-pattern.css | 47 - test/Fixtures/lessjs (1.5)/css/mixins.css | 141 - test/Fixtures/lessjs (1.5)/css/no-output.css | 0 test/Fixtures/lessjs (1.5)/css/operations.css | 49 - test/Fixtures/lessjs (1.5)/css/parens.css | 33 - test/Fixtures/lessjs (1.5)/css/rulesets.css | 33 - test/Fixtures/lessjs (1.5)/css/scope.css | 35 - test/Fixtures/lessjs (1.5)/css/selectors.css | 142 - .../lessjs (1.5)/css/static-urls/urls.css | 41 - test/Fixtures/lessjs (1.5)/css/strings.css | 43 - test/Fixtures/lessjs (1.5)/css/urls.css | 63 - test/Fixtures/lessjs (1.5)/css/variables.css | 45 - test/Fixtures/lessjs (1.5)/css/whitespace.css | 42 - .../lessjs (1.5)/data/data-uri-fail.png | Bin 52420 -> 0 bytes test/Fixtures/lessjs (1.5)/data/image.jpg | 1 - test/Fixtures/lessjs (1.5)/data/page.html | 1 - test/Fixtures/lessjs (1.5)/expected/a.css | 13 - .../lessjs (1.5)/expected/charsets.css | 1 - .../Fixtures/lessjs (1.5)/expected/colors.css | 80 - .../lessjs (1.5)/expected/comments.css | 69 - test/Fixtures/lessjs (1.5)/expected/css-3.css | 125 - .../lessjs (1.5)/expected/css-escapes.css | 24 - .../lessjs (1.5)/expected/css-guards.css | 18 - test/Fixtures/lessjs (1.5)/expected/css.css | 95 - .../lessjs (1.5)/expected/extend-chaining.css | 81 - .../lessjs (1.5)/expected/extend-clearfix.css | 19 - .../lessjs (1.5)/expected/extend-exact.css | 37 - .../lessjs (1.5)/expected/extend-media.css | 24 - .../lessjs (1.5)/expected/extend-nest.css | 57 - .../lessjs (1.5)/expected/extend-selector.css | 80 - .../Fixtures/lessjs (1.5)/expected/extend.css | 76 - .../expected/extract-and-length.css | 133 - .../lessjs (1.5)/expected/functions.css | 139 - .../lessjs (1.5)/expected/ie-filters.css | 9 - .../lessjs (1.5)/expected/import-inline.css | 5 - .../expected/import-interpolation.css | 6 - .../lessjs (1.5)/expected/import-once.css | 15 - .../expected/import-reference.css | 55 - .../Fixtures/lessjs (1.5)/expected/import.css | 36 - .../lessjs (1.5)/expected/javascript.css | 20 - .../lessjs (1.5)/expected/lazy-eval.css | 3 - test/Fixtures/lessjs (1.5)/expected/media.css | 219 - test/Fixtures/lessjs (1.5)/expected/merge.css | 22 - .../lessjs (1.5)/expected/mixins-args.css | 113 - .../lessjs (1.5)/expected/mixins-closure.css | 9 - .../lessjs (1.5)/expected/mixins-guards.css | 82 - .../expected/mixins-important.css | 45 - .../expected/mixins-named-args.css | 27 - .../lessjs (1.5)/expected/mixins-nested.css | 14 - .../lessjs (1.5)/expected/mixins-pattern.css | 47 - .../Fixtures/lessjs (1.5)/expected/mixins.css | 141 - .../lessjs (1.5)/expected/no-output.css | 1 - .../lessjs (1.5)/expected/operations.css | 49 - .../Fixtures/lessjs (1.5)/expected/parens.css | 33 - .../lessjs (1.5)/expected/rulesets.css | 33 - test/Fixtures/lessjs (1.5)/expected/scope.css | 35 - .../lessjs (1.5)/expected/selectors.css | 142 - .../lessjs (1.5)/expected/strings.css | 43 - test/Fixtures/lessjs (1.5)/expected/urls.css | 63 - .../lessjs (1.5)/expected/variables.css | 45 - .../lessjs (1.5)/expected/whitespace.css | 42 - test/Fixtures/lessjs (1.5)/less/a.less | 17 - test/Fixtures/lessjs (1.5)/less/charsets.less | 3 - test/Fixtures/lessjs (1.5)/less/colors.less | 92 - test/Fixtures/lessjs (1.5)/less/comments.less | 83 - .../less/compression/compression.less | 32 - test/Fixtures/lessjs (1.5)/less/css-3.less | 125 - .../lessjs (1.5)/less/css-escapes.less | 33 - .../lessjs (1.5)/less/css-guards.less | 64 - test/Fixtures/lessjs (1.5)/less/css.less | 108 - .../lessjs (1.5)/less/debug/import/test.less | 25 - .../lessjs (1.5)/less/debug/linenumbers.less | 23 - .../less/errors/add-mixed-units.less | 3 - .../less/errors/add-mixed-units.txt | 2 - .../less/errors/add-mixed-units2.less | 3 - .../less/errors/add-mixed-units2.txt | 2 - .../errors/bad-variable-declaration1.less | 1 - .../less/errors/bad-variable-declaration1.txt | 2 - .../less/errors/color-func-invalid-color.less | 3 - .../less/errors/color-func-invalid-color.txt | 4 - .../less/errors/color-operation-error.less | 3 - .../less/errors/color-operation-error.txt | 2 - .../less/errors/comment-in-selector.less | 1 - .../less/errors/comment-in-selector.txt | 2 - .../less/errors/divide-mixed-units.less | 3 - .../less/errors/divide-mixed-units.txt | 4 - .../less/errors/extend-no-selector.less | 3 - .../less/errors/extend-no-selector.txt | 3 - .../less/errors/extend-not-at-end.less | 3 - .../less/errors/extend-not-at-end.txt | 3 - .../less/errors/import-missing.less | 6 - .../less/errors/import-missing.txt | 3 - .../less/errors/import-no-semi.less | 1 - .../less/errors/import-no-semi.txt | 2 - .../less/errors/import-subfolder1.less | 1 - .../less/errors/import-subfolder1.txt | 3 - .../less/errors/import-subfolder2.less | 1 - .../less/errors/import-subfolder2.txt | 2 - .../errors/imports/import-subfolder1.less | 1 - .../errors/imports/import-subfolder2.less | 1 - .../less/errors/imports/import-test.less | 4 - .../imports/subfolder/mixin-not-defined.less | 1 - .../subfolder/parse-error-curly-bracket.less | 1 - .../less/errors/javascript-error.less | 3 - .../less/errors/javascript-error.txt | 4 - .../errors/mixed-mixin-definition-args-1.less | 6 - .../errors/mixed-mixin-definition-args-1.txt | 4 - .../errors/mixed-mixin-definition-args-2.less | 6 - .../errors/mixed-mixin-definition-args-2.txt | 4 - .../less/errors/mixin-not-defined.less | 11 - .../less/errors/mixin-not-defined.txt | 3 - .../less/errors/mixin-not-matched.less | 6 - .../less/errors/mixin-not-matched.txt | 3 - .../less/errors/mixin-not-matched2.less | 6 - .../less/errors/mixin-not-matched2.txt | 3 - .../multiple-guards-on-css-selectors.less | 4 - .../multiple-guards-on-css-selectors.txt | 4 - .../less/errors/multiply-mixed-units.less | 7 - .../less/errors/multiply-mixed-units.txt | 4 - .../less/errors/parens-error-1.less | 3 - .../less/errors/parens-error-1.txt | 4 - .../less/errors/parens-error-2.less | 3 - .../less/errors/parens-error-2.txt | 4 - .../less/errors/parens-error-3.less | 3 - .../less/errors/parens-error-3.txt | 4 - .../errors/parse-error-curly-bracket.less | 1 - .../less/errors/parse-error-curly-bracket.txt | 2 - .../errors/parse-error-missing-bracket.less | 2 - .../errors/parse-error-missing-bracket.txt | 3 - .../less/errors/parse-error-with-import.less | 13 - .../less/errors/parse-error-with-import.txt | 4 - .../less/errors/property-ie5-hack.less | 3 - .../less/errors/property-ie5-hack.txt | 4 - .../less/errors/property-in-root.less | 4 - .../less/errors/property-in-root.txt | 4 - .../less/errors/property-in-root2.less | 1 - .../less/errors/property-in-root2.txt | 4 - .../less/errors/property-in-root3.less | 4 - .../less/errors/property-in-root3.txt | 3 - .../less/errors/recursive-variable.less | 1 - .../less/errors/recursive-variable.txt | 2 - .../less/errors/svg-gradient1.less | 3 - .../less/errors/svg-gradient1.txt | 4 - .../less/errors/svg-gradient2.less | 3 - .../less/errors/svg-gradient2.txt | 4 - .../less/errors/svg-gradient3.less | 3 - .../less/errors/svg-gradient3.txt | 4 - .../less/errors/unit-function.less | 3 - .../less/errors/unit-function.txt | 4 - .../lessjs (1.5)/less/extend-chaining.less | 91 - .../lessjs (1.5)/less/extend-clearfix.less | 19 - .../lessjs (1.5)/less/extend-exact.less | 46 - .../lessjs (1.5)/less/extend-media.less | 24 - .../lessjs (1.5)/less/extend-nest.less | 65 - .../lessjs (1.5)/less/extend-selector.less | 99 - test/Fixtures/lessjs (1.5)/less/extend.less | 81 - .../lessjs (1.5)/less/extract-and-length.less | 133 - .../Fixtures/lessjs (1.5)/less/functions.less | 153 - .../lessjs (1.5)/less/ie-filters.less | 15 - .../lessjs (1.5)/less/import-inline.less | 2 - .../less/import-interpolation.less | 8 - .../lessjs (1.5)/less/import-once.less | 6 - .../lessjs (1.5)/less/import-reference.less | 18 - test/Fixtures/lessjs (1.5)/less/import.less | 21 - .../import/deeper/import-once-test-a.less | 1 - .../import-and-relative-paths-test.less | 6 - .../less/import/import-charset-test.less | 1 - .../less/import/import-interpolation.less | 1 - .../less/import/import-interpolation2.less | 5 - .../less/import/import-once-test-c.less | 6 - .../less/import/import-reference.less | 43 - .../less/import/import-test-a.less | 3 - .../less/import/import-test-b.less | 8 - .../less/import/import-test-c.less | 6 - .../less/import/import-test-d.css | 1 - .../less/import/import-test-e.less | 2 - .../less/import/import-test-f.less | 5 - .../less/import/imports/font.less | 8 - .../less/import/imports/logo.less | 5 - .../lessjs (1.5)/less/import/invalid-css.less | 1 - .../lessjs (1.5)/less/import/urls.less | 1 - .../lessjs (1.5)/less/javascript.less | 29 - .../Fixtures/lessjs (1.5)/less/lazy-eval.less | 6 - .../lessjs (1.5)/less/legacy/legacy.less | 7 - test/Fixtures/lessjs (1.5)/less/media.less | 234 - test/Fixtures/lessjs (1.5)/less/merge.less | 51 - .../lessjs (1.5)/less/mixins-args.less | 215 - .../lessjs (1.5)/less/mixins-closure.less | 26 - .../lessjs (1.5)/less/mixins-guards.less | 153 - .../lessjs (1.5)/less/mixins-important.less | 25 - .../lessjs (1.5)/less/mixins-named-args.less | 36 - .../lessjs (1.5)/less/mixins-nested.less | 22 - .../lessjs (1.5)/less/mixins-pattern.less | 99 - test/Fixtures/lessjs (1.5)/less/mixins.less | 141 - .../less/no-js-errors/no-js-errors.less | 3 - .../less/no-js-errors/no-js-errors.txt | 4 - .../Fixtures/lessjs (1.5)/less/no-output.less | 2 - .../lessjs (1.5)/less/operations.less | 62 - test/Fixtures/lessjs (1.5)/less/parens.less | 41 - test/Fixtures/lessjs (1.5)/less/rulesets.less | 30 - test/Fixtures/lessjs (1.5)/less/scope.less | 79 - .../Fixtures/lessjs (1.5)/less/selectors.less | 144 - .../lessjs (1.5)/less/sourcemaps/basic.less | 27 - .../lessjs (1.5)/less/sourcemaps/imported.css | 7 - .../lessjs (1.5)/less/static-urls/urls.less | 33 - test/Fixtures/lessjs (1.5)/less/strings.less | 57 - test/Fixtures/lessjs (1.5)/less/urls.less | 67 - .../Fixtures/lessjs (1.5)/less/variables.less | 83 - .../lessjs (1.5)/less/whitespace.less | 44 - test/Fixtures/lessjs (1.6)/css/charsets.css | 1 - test/Fixtures/lessjs (1.6)/css/colors.css | 87 - test/Fixtures/lessjs (1.6)/css/comments.css | 69 - .../css/compression/compression.css | 3 - test/Fixtures/lessjs (1.6)/css/css-3.css | 129 - .../Fixtures/lessjs (1.6)/css/css-escapes.css | 24 - test/Fixtures/lessjs (1.6)/css/css-guards.css | 37 - test/Fixtures/lessjs (1.6)/css/css.css | 95 - .../css/debug/linenumbers-all.css | 49 - .../css/debug/linenumbers-comments.css | 40 - .../css/debug/linenumbers-mediaquery.css | 40 - test/Fixtures/lessjs (1.6)/css/empty.css | 0 .../lessjs (1.6)/css/extend-chaining.css | 81 - .../lessjs (1.6)/css/extend-clearfix.css | 19 - .../lessjs (1.6)/css/extend-exact.css | 37 - .../lessjs (1.6)/css/extend-media.css | 24 - .../Fixtures/lessjs (1.6)/css/extend-nest.css | 57 - .../lessjs (1.6)/css/extend-selector.css | 80 - test/Fixtures/lessjs (1.6)/css/extend.css | 76 - .../lessjs (1.6)/css/extract-and-length.css | 133 - test/Fixtures/lessjs (1.6)/css/functions.css | 141 - .../lessjs (1.6)/css/globalVars/extended.css | 12 - .../lessjs (1.6)/css/globalVars/simple.css | 6 - test/Fixtures/lessjs (1.6)/css/ie-filters.css | 9 - .../lessjs (1.6)/css/import-inline.css | 5 - .../lessjs (1.6)/css/import-interpolation.css | 6 - .../Fixtures/lessjs (1.6)/css/import-once.css | 15 - .../lessjs (1.6)/css/import-reference.css | 49 - test/Fixtures/lessjs (1.6)/css/import.css | 36 - test/Fixtures/lessjs (1.6)/css/javascript.css | 23 - test/Fixtures/lessjs (1.6)/css/lazy-eval.css | 3 - .../lessjs (1.6)/css/legacy/legacy.css | 7 - test/Fixtures/lessjs (1.6)/css/media.css | 219 - test/Fixtures/lessjs (1.6)/css/merge.css | 26 - .../Fixtures/lessjs (1.6)/css/mixins-args.css | 113 - .../lessjs (1.6)/css/mixins-closure.css | 9 - .../css/mixins-guards-default-func.css | 129 - .../lessjs (1.6)/css/mixins-guards.css | 82 - .../lessjs (1.6)/css/mixins-important.css | 45 - .../lessjs (1.6)/css/mixins-interpolated.css | 39 - .../lessjs (1.6)/css/mixins-named-args.css | 27 - .../lessjs (1.6)/css/mixins-nested.css | 14 - .../lessjs (1.6)/css/mixins-pattern.css | 47 - test/Fixtures/lessjs (1.6)/css/mixins.css | 141 - .../lessjs (1.6)/css/modifyVars/extended.css | 9 - test/Fixtures/lessjs (1.6)/css/no-output.css | 0 test/Fixtures/lessjs (1.6)/css/operations.css | 49 - test/Fixtures/lessjs (1.6)/css/parens.css | 36 - .../lessjs (1.6)/css/property-name-interp.css | 20 - test/Fixtures/lessjs (1.6)/css/rulesets.css | 33 - test/Fixtures/lessjs (1.6)/css/scope.css | 35 - test/Fixtures/lessjs (1.6)/css/selectors.css | 153 - .../lessjs (1.6)/css/static-urls/urls.css | 45 - test/Fixtures/lessjs (1.6)/css/strings.css | 43 - .../lessjs (1.6)/css/url-args/urls.css | 56 - test/Fixtures/lessjs (1.6)/css/urls.css | 71 - test/Fixtures/lessjs (1.6)/css/variables.css | 45 - test/Fixtures/lessjs (1.6)/css/whitespace.css | 42 - .../lessjs (1.6)/data/data-uri-fail.png | Bin 52420 -> 0 bytes test/Fixtures/lessjs (1.6)/data/image.jpg | 1 - test/Fixtures/lessjs (1.6)/data/page.html | 1 - .../lessjs (1.6)/expected/charsets.css | 1 - .../Fixtures/lessjs (1.6)/expected/colors.css | 87 - .../lessjs (1.6)/expected/comments.css | 69 - test/Fixtures/lessjs (1.6)/expected/css-3.css | 129 - .../lessjs (1.6)/expected/css-escapes.css | 24 - .../lessjs (1.6)/expected/css-guards.css | 37 - test/Fixtures/lessjs (1.6)/expected/css.css | 95 - test/Fixtures/lessjs (1.6)/expected/empty.css | 1 - .../lessjs (1.6)/expected/extend-chaining.css | 81 - .../lessjs (1.6)/expected/extend-clearfix.css | 19 - .../lessjs (1.6)/expected/extend-exact.css | 37 - .../lessjs (1.6)/expected/extend-media.css | 24 - .../lessjs (1.6)/expected/extend-nest.css | 57 - .../lessjs (1.6)/expected/extend-selector.css | 80 - .../Fixtures/lessjs (1.6)/expected/extend.css | 76 - .../expected/extract-and-length.css | 133 - .../lessjs (1.6)/expected/functions.css | 141 - .../lessjs (1.6)/expected/ie-filters.css | 9 - .../lessjs (1.6)/expected/import-inline.css | 5 - .../expected/import-interpolation.css | 6 - .../lessjs (1.6)/expected/import-once.css | 15 - .../expected/import-reference.css | 49 - .../Fixtures/lessjs (1.6)/expected/import.css | 36 - .../lessjs (1.6)/expected/javascript.css | 20 - .../lessjs (1.6)/expected/lazy-eval.css | 3 - test/Fixtures/lessjs (1.6)/expected/media.css | 219 - test/Fixtures/lessjs (1.6)/expected/merge.css | 26 - .../lessjs (1.6)/expected/mixins-args.css | 113 - .../lessjs (1.6)/expected/mixins-closure.css | 9 - .../expected/mixins-guards-default-func.css | 129 - .../lessjs (1.6)/expected/mixins-guards.css | 82 - .../expected/mixins-important.css | 45 - .../expected/mixins-interpolated.css | 39 - .../expected/mixins-named-args.css | 27 - .../lessjs (1.6)/expected/mixins-nested.css | 14 - .../lessjs (1.6)/expected/mixins-pattern.css | 47 - .../Fixtures/lessjs (1.6)/expected/mixins.css | 141 - .../lessjs (1.6)/expected/no-output.css | 1 - .../lessjs (1.6)/expected/operations.css | 49 - .../Fixtures/lessjs (1.6)/expected/parens.css | 36 - .../expected/property-name-interp.css | 20 - .../lessjs (1.6)/expected/rulesets.css | 33 - test/Fixtures/lessjs (1.6)/expected/scope.css | 35 - .../lessjs (1.6)/expected/selectors.css | 153 - .../lessjs (1.6)/expected/strings.css | 43 - test/Fixtures/lessjs (1.6)/expected/urls.css | 71 - .../lessjs (1.6)/expected/variables.css | 45 - .../lessjs (1.6)/expected/whitespace.css | 42 - test/Fixtures/lessjs (1.6)/less/charsets.less | 3 - test/Fixtures/lessjs (1.6)/less/colors.less | 98 - test/Fixtures/lessjs (1.6)/less/comments.less | 83 - .../less/compression/compression.less | 36 - test/Fixtures/lessjs (1.6)/less/css-3.less | 129 - .../lessjs (1.6)/less/css-escapes.less | 33 - .../lessjs (1.6)/less/css-guards.less | 99 - test/Fixtures/lessjs (1.6)/less/css.less | 108 - .../lessjs (1.6)/less/debug/import/test.less | 25 - .../lessjs (1.6)/less/debug/linenumbers.less | 33 - test/Fixtures/lessjs (1.6)/less/empty.less | 0 .../less/errors/add-mixed-units.less | 3 - .../less/errors/add-mixed-units.txt | 4 - .../less/errors/add-mixed-units2.less | 3 - .../less/errors/add-mixed-units2.txt | 4 - .../errors/bad-variable-declaration1.less | 1 - .../less/errors/bad-variable-declaration1.txt | 2 - .../less/errors/color-func-invalid-color.less | 3 - .../less/errors/color-func-invalid-color.txt | 4 - .../less/errors/comment-in-selector.less | 1 - .../less/errors/comment-in-selector.txt | 2 - .../less/errors/css-guard-default-func.less | 4 - .../less/errors/css-guard-default-func.txt | 4 - .../less/errors/divide-mixed-units.less | 3 - .../less/errors/divide-mixed-units.txt | 4 - .../less/errors/extend-no-selector.less | 3 - .../less/errors/extend-no-selector.txt | 3 - .../less/errors/extend-not-at-end.less | 3 - .../less/errors/extend-not-at-end.txt | 3 - .../less/errors/import-missing.less | 6 - .../less/errors/import-missing.txt | 3 - .../less/errors/import-no-semi.less | 1 - .../less/errors/import-no-semi.txt | 2 - .../less/errors/import-subfolder1.less | 1 - .../less/errors/import-subfolder1.txt | 3 - .../less/errors/import-subfolder2.less | 1 - .../less/errors/import-subfolder2.txt | 4 - .../errors/imports/import-subfolder1.less | 1 - .../errors/imports/import-subfolder2.less | 1 - .../less/errors/imports/import-test.less | 4 - .../imports/subfolder/mixin-not-defined.less | 1 - .../subfolder/parse-error-curly-bracket.less | 1 - .../less/errors/javascript-error.less | 3 - .../less/errors/javascript-error.txt | 4 - .../less/errors/javascript-undefined-var.less | 3 - .../less/errors/javascript-undefined-var.txt | 4 - .../errors/mixed-mixin-definition-args-1.less | 6 - .../errors/mixed-mixin-definition-args-1.txt | 4 - .../errors/mixed-mixin-definition-args-2.less | 6 - .../errors/mixed-mixin-definition-args-2.txt | 4 - .../less/errors/mixin-not-defined.less | 11 - .../less/errors/mixin-not-defined.txt | 3 - .../less/errors/mixin-not-matched.less | 6 - .../less/errors/mixin-not-matched.txt | 3 - .../less/errors/mixin-not-matched2.less | 6 - .../less/errors/mixin-not-matched2.txt | 3 - .../errors/mixins-guards-default-func-1.less | 9 - .../errors/mixins-guards-default-func-1.txt | 4 - .../errors/mixins-guards-default-func-2.less | 9 - .../errors/mixins-guards-default-func-2.txt | 4 - .../errors/mixins-guards-default-func-3.less | 9 - .../errors/mixins-guards-default-func-3.txt | 4 - .../multiple-guards-on-css-selectors.less | 4 - .../multiple-guards-on-css-selectors.txt | 4 - .../multiple-guards-on-css-selectors2.less | 4 - .../multiple-guards-on-css-selectors2.txt | 4 - .../less/errors/multiply-mixed-units.less | 7 - .../less/errors/multiply-mixed-units.txt | 4 - .../less/errors/parens-error-1.less | 3 - .../less/errors/parens-error-1.txt | 4 - .../less/errors/parens-error-2.less | 3 - .../less/errors/parens-error-2.txt | 4 - .../less/errors/parens-error-3.less | 3 - .../less/errors/parens-error-3.txt | 4 - .../errors/parse-error-curly-bracket.less | 4 - .../less/errors/parse-error-curly-bracket.txt | 4 - .../less/errors/parse-error-extra-parens.less | 5 - .../less/errors/parse-error-extra-parens.txt | 3 - .../errors/parse-error-missing-bracket.less | 2 - .../errors/parse-error-missing-bracket.txt | 3 - .../errors/parse-error-missing-parens.less | 5 - .../errors/parse-error-missing-parens.txt | 3 - .../less/errors/parse-error-with-import.less | 13 - .../less/errors/parse-error-with-import.txt | 4 - .../errors/property-asterisk-only-name.less | 3 - .../errors/property-asterisk-only-name.txt | 4 - .../less/errors/property-ie5-hack.less | 3 - .../less/errors/property-ie5-hack.txt | 4 - .../less/errors/property-in-root.less | 4 - .../less/errors/property-in-root.txt | 4 - .../less/errors/property-in-root2.less | 1 - .../less/errors/property-in-root2.txt | 4 - .../less/errors/property-in-root3.less | 4 - .../less/errors/property-in-root3.txt | 3 - .../errors/property-interp-not-defined.less | 1 - .../errors/property-interp-not-defined.txt | 2 - .../less/errors/recursive-variable.less | 1 - .../less/errors/recursive-variable.txt | 2 - .../less/errors/svg-gradient1.less | 3 - .../less/errors/svg-gradient1.txt | 4 - .../less/errors/svg-gradient2.less | 3 - .../less/errors/svg-gradient2.txt | 4 - .../less/errors/svg-gradient3.less | 3 - .../less/errors/svg-gradient3.txt | 4 - .../less/errors/unit-function.less | 3 - .../less/errors/unit-function.txt | 4 - .../lessjs (1.6)/less/extend-chaining.less | 91 - .../lessjs (1.6)/less/extend-clearfix.less | 19 - .../lessjs (1.6)/less/extend-exact.less | 46 - .../lessjs (1.6)/less/extend-media.less | 24 - .../lessjs (1.6)/less/extend-nest.less | 65 - .../lessjs (1.6)/less/extend-selector.less | 99 - test/Fixtures/lessjs (1.6)/less/extend.less | 81 - .../lessjs (1.6)/less/extract-and-length.less | 133 - .../Fixtures/lessjs (1.6)/less/functions.less | 155 - .../less/globalVars/extended.json | 5 - .../less/globalVars/extended.less | 10 - .../lessjs (1.6)/less/globalVars/simple.json | 3 - .../lessjs (1.6)/less/globalVars/simple.less | 3 - .../lessjs (1.6)/less/ie-filters.less | 15 - .../lessjs (1.6)/less/import-inline.less | 2 - .../less/import-interpolation.less | 8 - .../lessjs (1.6)/less/import-once.less | 6 - .../lessjs (1.6)/less/import-reference.less | 18 - test/Fixtures/lessjs (1.6)/less/import.less | 21 - .../import/deeper/import-once-test-a.less | 1 - .../import-and-relative-paths-test.less | 17 - .../less/import/import-charset-test.less | 1 - .../less/import/import-interpolation.less | 1 - .../less/import/import-interpolation2.less | 5 - .../less/import/import-once-test-c.less | 6 - .../less/import/import-reference.less | 43 - .../less/import/import-test-a.less | 3 - .../less/import/import-test-b.less | 8 - .../less/import/import-test-c.less | 6 - .../less/import/import-test-d.css | 1 - .../less/import/import-test-e.less | 2 - .../less/import/import-test-f.less | 5 - .../less/import/imports/font.less | 8 - .../less/import/imports/logo.less | 5 - .../lessjs (1.6)/less/import/invalid-css.less | 1 - .../lessjs (1.6)/less/import/urls.less | 1 - .../lessjs (1.6)/less/javascript.less | 29 - .../Fixtures/lessjs (1.6)/less/lazy-eval.less | 6 - .../lessjs (1.6)/less/legacy/legacy.less | 7 - test/Fixtures/lessjs (1.6)/less/media.less | 234 - test/Fixtures/lessjs (1.6)/less/merge.less | 59 - .../lessjs (1.6)/less/mixins-args.less | 215 - .../lessjs (1.6)/less/mixins-closure.less | 26 - .../less/mixins-guards-default-func.less | 195 - .../lessjs (1.6)/less/mixins-guards.less | 153 - .../lessjs (1.6)/less/mixins-important.less | 25 - .../less/mixins-interpolated.less | 69 - .../lessjs (1.6)/less/mixins-named-args.less | 36 - .../lessjs (1.6)/less/mixins-nested.less | 22 - .../lessjs (1.6)/less/mixins-pattern.less | 99 - test/Fixtures/lessjs (1.6)/less/mixins.less | 141 - .../less/modifyVars/extended.json | 5 - .../less/modifyVars/extended.less | 11 - .../less/no-js-errors/no-js-errors.less | 3 - .../less/no-js-errors/no-js-errors.txt | 4 - .../Fixtures/lessjs (1.6)/less/no-output.less | 2 - .../lessjs (1.6)/less/operations.less | 62 - test/Fixtures/lessjs (1.6)/less/parens.less | 45 - .../less/property-name-interp.less | 53 - test/Fixtures/lessjs (1.6)/less/rulesets.less | 30 - test/Fixtures/lessjs (1.6)/less/scope.less | 79 - .../Fixtures/lessjs (1.6)/less/selectors.less | 156 - .../lessjs (1.6)/less/sourcemaps/basic.json | 3 - .../lessjs (1.6)/less/sourcemaps/basic.less | 27 - .../lessjs (1.6)/less/sourcemaps/imported.css | 7 - .../lessjs (1.6)/less/static-urls/urls.less | 33 - test/Fixtures/lessjs (1.6)/less/strings.less | 57 - .../lessjs (1.6)/less/url-args/urls.less | 63 - test/Fixtures/lessjs (1.6)/less/urls.less | 72 - .../Fixtures/lessjs (1.6)/less/variables.less | 83 - .../lessjs (1.6)/less/whitespace.less | 44 - test/assets/less-1.6.3.js | 7640 ---------------- test/assets/less-1.7.0.js | 7936 ---------------- test/assets/less-1.7.1.js | 7936 ---------------- test/assets/less-1.7.5.js | 8023 ----------------- 537 files changed, 49664 deletions(-) delete mode 100644 test/Fixtures/lessjs (1.5)/css/a.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/charsets.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/colors.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/comments.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/compression/compression.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/css-3.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/css-escapes.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/css-guards.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/css.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/debug/linenumbers-all.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/debug/linenumbers-comments.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/debug/linenumbers-mediaquery.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/extend-chaining.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/extend-clearfix.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/extend-exact.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/extend-media.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/extend-nest.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/extend-selector.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/extend.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/extract-and-length.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/functions.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/ie-filters.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/import-inline.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/import-interpolation.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/import-once.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/import-reference.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/import.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/javascript.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/lazy-eval.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/legacy/legacy.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/media.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/merge.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/mixins-args.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/mixins-closure.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/mixins-guards.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/mixins-important.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/mixins-named-args.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/mixins-nested.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/mixins-pattern.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/mixins.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/no-output.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/operations.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/parens.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/rulesets.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/scope.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/selectors.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/static-urls/urls.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/strings.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/urls.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/variables.css delete mode 100644 test/Fixtures/lessjs (1.5)/css/whitespace.css delete mode 100644 test/Fixtures/lessjs (1.5)/data/data-uri-fail.png delete mode 100644 test/Fixtures/lessjs (1.5)/data/image.jpg delete mode 100644 test/Fixtures/lessjs (1.5)/data/page.html delete mode 100644 test/Fixtures/lessjs (1.5)/expected/a.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/charsets.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/colors.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/comments.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/css-3.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/css-escapes.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/css-guards.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/css.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/extend-chaining.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/extend-clearfix.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/extend-exact.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/extend-media.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/extend-nest.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/extend-selector.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/extend.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/extract-and-length.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/functions.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/ie-filters.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/import-inline.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/import-interpolation.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/import-once.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/import-reference.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/import.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/javascript.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/lazy-eval.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/media.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/merge.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/mixins-args.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/mixins-closure.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/mixins-guards.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/mixins-important.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/mixins-named-args.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/mixins-nested.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/mixins-pattern.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/mixins.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/no-output.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/operations.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/parens.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/rulesets.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/scope.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/selectors.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/strings.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/urls.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/variables.css delete mode 100644 test/Fixtures/lessjs (1.5)/expected/whitespace.css delete mode 100644 test/Fixtures/lessjs (1.5)/less/a.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/charsets.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/colors.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/comments.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/compression/compression.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/css-3.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/css-escapes.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/css-guards.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/css.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/debug/import/test.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/debug/linenumbers.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/add-mixed-units.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/add-mixed-units.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/add-mixed-units2.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/add-mixed-units2.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/bad-variable-declaration1.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/bad-variable-declaration1.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/color-func-invalid-color.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/color-func-invalid-color.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/color-operation-error.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/color-operation-error.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/comment-in-selector.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/comment-in-selector.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/divide-mixed-units.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/divide-mixed-units.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/extend-no-selector.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/extend-no-selector.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/extend-not-at-end.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/extend-not-at-end.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/import-missing.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/import-missing.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/import-no-semi.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/import-no-semi.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/import-subfolder1.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/import-subfolder1.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/import-subfolder2.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/import-subfolder2.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/imports/import-subfolder1.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/imports/import-subfolder2.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/imports/import-test.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/imports/subfolder/mixin-not-defined.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/imports/subfolder/parse-error-curly-bracket.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/javascript-error.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/javascript-error.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/mixed-mixin-definition-args-1.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/mixed-mixin-definition-args-1.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/mixed-mixin-definition-args-2.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/mixed-mixin-definition-args-2.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/mixin-not-defined.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/mixin-not-defined.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/mixin-not-matched.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/mixin-not-matched.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/mixin-not-matched2.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/mixin-not-matched2.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/multiple-guards-on-css-selectors.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/multiple-guards-on-css-selectors.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/multiply-mixed-units.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/multiply-mixed-units.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/parens-error-1.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/parens-error-1.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/parens-error-2.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/parens-error-2.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/parens-error-3.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/parens-error-3.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/parse-error-curly-bracket.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/parse-error-curly-bracket.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/parse-error-missing-bracket.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/parse-error-missing-bracket.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/parse-error-with-import.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/parse-error-with-import.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/property-ie5-hack.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/property-ie5-hack.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/property-in-root.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/property-in-root.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/property-in-root2.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/property-in-root2.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/property-in-root3.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/property-in-root3.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/recursive-variable.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/recursive-variable.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/svg-gradient1.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/svg-gradient1.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/svg-gradient2.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/svg-gradient2.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/svg-gradient3.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/svg-gradient3.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/unit-function.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/errors/unit-function.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/extend-chaining.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/extend-clearfix.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/extend-exact.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/extend-media.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/extend-nest.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/extend-selector.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/extend.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/extract-and-length.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/functions.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/ie-filters.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/import-inline.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/import-interpolation.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/import-once.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/import-reference.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/import.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/import/deeper/import-once-test-a.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/import/import-and-relative-paths-test.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/import/import-charset-test.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/import/import-interpolation.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/import/import-interpolation2.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/import/import-once-test-c.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/import/import-reference.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/import/import-test-a.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/import/import-test-b.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/import/import-test-c.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/import/import-test-d.css delete mode 100644 test/Fixtures/lessjs (1.5)/less/import/import-test-e.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/import/import-test-f.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/import/imports/font.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/import/imports/logo.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/import/invalid-css.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/import/urls.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/javascript.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/lazy-eval.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/legacy/legacy.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/media.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/merge.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/mixins-args.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/mixins-closure.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/mixins-guards.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/mixins-important.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/mixins-named-args.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/mixins-nested.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/mixins-pattern.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/mixins.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/no-js-errors/no-js-errors.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/no-js-errors/no-js-errors.txt delete mode 100644 test/Fixtures/lessjs (1.5)/less/no-output.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/operations.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/parens.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/rulesets.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/scope.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/selectors.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/sourcemaps/basic.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/sourcemaps/imported.css delete mode 100644 test/Fixtures/lessjs (1.5)/less/static-urls/urls.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/strings.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/urls.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/variables.less delete mode 100644 test/Fixtures/lessjs (1.5)/less/whitespace.less delete mode 100644 test/Fixtures/lessjs (1.6)/css/charsets.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/colors.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/comments.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/compression/compression.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/css-3.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/css-escapes.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/css-guards.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/css.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/debug/linenumbers-all.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/debug/linenumbers-comments.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/debug/linenumbers-mediaquery.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/empty.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/extend-chaining.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/extend-clearfix.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/extend-exact.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/extend-media.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/extend-nest.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/extend-selector.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/extend.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/extract-and-length.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/functions.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/globalVars/extended.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/globalVars/simple.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/ie-filters.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/import-inline.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/import-interpolation.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/import-once.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/import-reference.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/import.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/javascript.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/lazy-eval.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/legacy/legacy.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/media.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/merge.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/mixins-args.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/mixins-closure.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/mixins-guards-default-func.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/mixins-guards.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/mixins-important.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/mixins-interpolated.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/mixins-named-args.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/mixins-nested.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/mixins-pattern.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/mixins.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/modifyVars/extended.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/no-output.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/operations.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/parens.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/property-name-interp.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/rulesets.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/scope.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/selectors.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/static-urls/urls.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/strings.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/url-args/urls.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/urls.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/variables.css delete mode 100644 test/Fixtures/lessjs (1.6)/css/whitespace.css delete mode 100644 test/Fixtures/lessjs (1.6)/data/data-uri-fail.png delete mode 100644 test/Fixtures/lessjs (1.6)/data/image.jpg delete mode 100644 test/Fixtures/lessjs (1.6)/data/page.html delete mode 100644 test/Fixtures/lessjs (1.6)/expected/charsets.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/colors.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/comments.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/css-3.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/css-escapes.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/css-guards.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/css.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/empty.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/extend-chaining.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/extend-clearfix.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/extend-exact.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/extend-media.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/extend-nest.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/extend-selector.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/extend.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/extract-and-length.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/functions.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/ie-filters.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/import-inline.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/import-interpolation.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/import-once.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/import-reference.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/import.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/javascript.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/lazy-eval.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/media.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/merge.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/mixins-args.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/mixins-closure.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/mixins-guards-default-func.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/mixins-guards.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/mixins-important.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/mixins-interpolated.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/mixins-named-args.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/mixins-nested.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/mixins-pattern.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/mixins.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/no-output.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/operations.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/parens.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/property-name-interp.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/rulesets.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/scope.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/selectors.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/strings.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/urls.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/variables.css delete mode 100644 test/Fixtures/lessjs (1.6)/expected/whitespace.css delete mode 100644 test/Fixtures/lessjs (1.6)/less/charsets.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/colors.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/comments.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/compression/compression.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/css-3.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/css-escapes.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/css-guards.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/css.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/debug/import/test.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/debug/linenumbers.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/empty.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/add-mixed-units.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/add-mixed-units.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/add-mixed-units2.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/add-mixed-units2.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/bad-variable-declaration1.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/bad-variable-declaration1.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/color-func-invalid-color.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/color-func-invalid-color.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/comment-in-selector.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/comment-in-selector.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/css-guard-default-func.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/css-guard-default-func.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/divide-mixed-units.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/divide-mixed-units.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/extend-no-selector.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/extend-no-selector.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/extend-not-at-end.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/extend-not-at-end.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/import-missing.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/import-missing.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/import-no-semi.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/import-no-semi.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/import-subfolder1.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/import-subfolder1.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/import-subfolder2.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/import-subfolder2.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/imports/import-subfolder1.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/imports/import-subfolder2.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/imports/import-test.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/imports/subfolder/mixin-not-defined.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/imports/subfolder/parse-error-curly-bracket.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/javascript-error.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/javascript-error.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/javascript-undefined-var.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/javascript-undefined-var.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/mixed-mixin-definition-args-1.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/mixed-mixin-definition-args-1.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/mixed-mixin-definition-args-2.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/mixed-mixin-definition-args-2.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/mixin-not-defined.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/mixin-not-defined.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/mixin-not-matched.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/mixin-not-matched.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/mixin-not-matched2.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/mixin-not-matched2.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-1.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-1.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-2.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-2.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-3.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-3.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/multiple-guards-on-css-selectors.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/multiple-guards-on-css-selectors.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/multiple-guards-on-css-selectors2.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/multiple-guards-on-css-selectors2.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/multiply-mixed-units.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/multiply-mixed-units.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/parens-error-1.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/parens-error-1.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/parens-error-2.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/parens-error-2.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/parens-error-3.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/parens-error-3.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/parse-error-curly-bracket.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/parse-error-curly-bracket.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/parse-error-extra-parens.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/parse-error-extra-parens.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/parse-error-missing-bracket.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/parse-error-missing-bracket.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/parse-error-missing-parens.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/parse-error-missing-parens.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/parse-error-with-import.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/parse-error-with-import.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/property-asterisk-only-name.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/property-asterisk-only-name.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/property-ie5-hack.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/property-ie5-hack.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/property-in-root.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/property-in-root.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/property-in-root2.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/property-in-root2.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/property-in-root3.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/property-in-root3.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/property-interp-not-defined.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/property-interp-not-defined.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/recursive-variable.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/recursive-variable.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/svg-gradient1.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/svg-gradient1.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/svg-gradient2.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/svg-gradient2.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/svg-gradient3.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/svg-gradient3.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/unit-function.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/errors/unit-function.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/extend-chaining.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/extend-clearfix.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/extend-exact.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/extend-media.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/extend-nest.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/extend-selector.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/extend.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/extract-and-length.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/functions.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/globalVars/extended.json delete mode 100644 test/Fixtures/lessjs (1.6)/less/globalVars/extended.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/globalVars/simple.json delete mode 100644 test/Fixtures/lessjs (1.6)/less/globalVars/simple.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/ie-filters.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/import-inline.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/import-interpolation.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/import-once.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/import-reference.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/import.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/import/deeper/import-once-test-a.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/import/import-and-relative-paths-test.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/import/import-charset-test.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/import/import-interpolation.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/import/import-interpolation2.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/import/import-once-test-c.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/import/import-reference.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/import/import-test-a.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/import/import-test-b.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/import/import-test-c.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/import/import-test-d.css delete mode 100644 test/Fixtures/lessjs (1.6)/less/import/import-test-e.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/import/import-test-f.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/import/imports/font.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/import/imports/logo.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/import/invalid-css.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/import/urls.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/javascript.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/lazy-eval.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/legacy/legacy.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/media.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/merge.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/mixins-args.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/mixins-closure.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/mixins-guards-default-func.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/mixins-guards.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/mixins-important.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/mixins-interpolated.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/mixins-named-args.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/mixins-nested.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/mixins-pattern.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/mixins.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/modifyVars/extended.json delete mode 100644 test/Fixtures/lessjs (1.6)/less/modifyVars/extended.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/no-js-errors/no-js-errors.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/no-js-errors/no-js-errors.txt delete mode 100644 test/Fixtures/lessjs (1.6)/less/no-output.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/operations.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/parens.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/property-name-interp.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/rulesets.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/scope.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/selectors.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/sourcemaps/basic.json delete mode 100644 test/Fixtures/lessjs (1.6)/less/sourcemaps/basic.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/sourcemaps/imported.css delete mode 100644 test/Fixtures/lessjs (1.6)/less/static-urls/urls.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/strings.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/url-args/urls.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/urls.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/variables.less delete mode 100644 test/Fixtures/lessjs (1.6)/less/whitespace.less delete mode 100644 test/assets/less-1.6.3.js delete mode 100644 test/assets/less-1.7.0.js delete mode 100644 test/assets/less-1.7.1.js delete mode 100644 test/assets/less-1.7.5.js diff --git a/test/Fixtures/lessjs (1.5)/css/a.css b/test/Fixtures/lessjs (1.5)/css/a.css deleted file mode 100644 index bdeeac44..00000000 --- a/test/Fixtures/lessjs (1.5)/css/a.css +++ /dev/null @@ -1,6 +0,0 @@ -.mixin { - font-weight: bold; -} -body { - font-weight: bold; -} diff --git a/test/Fixtures/lessjs (1.5)/css/charsets.css b/test/Fixtures/lessjs (1.5)/css/charsets.css deleted file mode 100644 index 9f44090c..00000000 --- a/test/Fixtures/lessjs (1.5)/css/charsets.css +++ /dev/null @@ -1 +0,0 @@ -@charset "UTF-8"; diff --git a/test/Fixtures/lessjs (1.5)/css/colors.css b/test/Fixtures/lessjs (1.5)/css/colors.css deleted file mode 100644 index 16956772..00000000 --- a/test/Fixtures/lessjs (1.5)/css/colors.css +++ /dev/null @@ -1,80 +0,0 @@ -#yelow #short { - color: #fea; -} -#yelow #long { - color: #ffeeaa; -} -#yelow #rgba { - color: rgba(255, 238, 170, 0.1); -} -#yelow #argb { - color: #1affeeaa; -} -#blue #short { - color: #00f; -} -#blue #long { - color: #0000ff; -} -#blue #rgba { - color: rgba(0, 0, 255, 0.1); -} -#blue #argb { - color: #1a0000ff; -} -#alpha #hsla { - color: rgba(61, 45, 41, 0.6); -} -#overflow .a { - color: #000000; -} -#overflow .b { - color: #ffffff; -} -#overflow .c { - color: #ffffff; -} -#overflow .d { - color: #00ff00; -} -#grey { - color: #c8c8c8; -} -#333333 { - color: #333333; -} -#808080 { - color: #808080; -} -#00ff00 { - color: #00ff00; -} -.lightenblue { - color: #3333ff; -} -.darkenblue { - color: #0000cc; -} -.unknowncolors { - color: blue2; - border: 2px solid superred; -} -.transparent { - color: transparent; - background-color: rgba(0, 0, 0, 0); -} -#alpha #fromvar { - opacity: 0.7; -} -#alpha #short { - opacity: 1; -} -#alpha #long { - opacity: 1; -} -#alpha #rgba { - opacity: 0.2; -} -#alpha #hsl { - opacity: 1; -} diff --git a/test/Fixtures/lessjs (1.5)/css/comments.css b/test/Fixtures/lessjs (1.5)/css/comments.css deleted file mode 100644 index b85f5b4f..00000000 --- a/test/Fixtures/lessjs (1.5)/css/comments.css +++ /dev/null @@ -1,69 +0,0 @@ -/******************\ -* * -* Comment Header * -* * -\******************/ -/* - - Comment - -*/ -/* - * Comment Test - * - * - cloudhead (http://cloudhead.net) - * - */ -/* Colors - * ------ - * #EDF8FC (background blue) - * #166C89 (darkest blue) - * - * Text: - * #333 (standard text) // A comment within a comment! - * #1F9EC9 (standard link) - * - */ -/* @group Variables -------------------- */ -#comments, -.comments { - /**/ - color: red; - /* A C-style comment */ - /* A C-style comment */ - background-color: orange; - font-size: 12px; - /* lost comment */ - content: "content"; - border: 1px solid black; - padding: 0; - margin: 2em; -} -/* commented out - #more-comments { - color: grey; - } -*/ -.selector, -.lots, -.comments { - color: #808080, /* blue */ #ffa500; - -webkit-border-radius: 2px /* webkit only */; - -moz-border-radius: 8px /* moz only with operation */; -} -.test { - color: 1px; -} -#last { - color: #0000ff; -} -/* */ -/* { */ -/* */ -/* */ -/* */ -#div { - color: #A33; -} -/* } */ diff --git a/test/Fixtures/lessjs (1.5)/css/compression/compression.css b/test/Fixtures/lessjs (1.5)/css/compression/compression.css deleted file mode 100644 index 8d6786e5..00000000 --- a/test/Fixtures/lessjs (1.5)/css/compression/compression.css +++ /dev/null @@ -1,3 +0,0 @@ -#colours{color1:#fea;color2:#fea;color3:rgba(255,238,170,0.1);string:"#ffeeaa";/*! but not this type - Note preserved whitespace - */}dimensions{val:.1px;val:0;val:4cm;val:.2;val:5;angles-must-have-unit:0deg;durations-must-have-unit:0s;length-doesnt-have-unit:0;width:auto\9}@page{marks:none;@top-left-corner{vertical-align:top}@top-left{vertical-align:top}} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/css/css-3.css b/test/Fixtures/lessjs (1.5)/css/css-3.css deleted file mode 100644 index 93b0a001..00000000 --- a/test/Fixtures/lessjs (1.5)/css/css-3.css +++ /dev/null @@ -1,125 +0,0 @@ -.comma-delimited { - text-shadow: -1px -1px 1px #ff0000, 6px 5px 5px #ffff00; - -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset, 0pt 4px 6px rgba(255, 255, 255, 0.4) inset; - -webkit-transform: rotate(-0.0000000001deg); -} -@font-face { - font-family: Headline; - unicode-range: U+??????, U+0???, U+0-7F, U+A5; -} -.other { - -moz-transform: translate(0, 11em) rotate(-90deg); - transform: rotateX(45deg); -} -.item[data-cra_zy-attr1b-ut3=bold] { - font-weight: bold; -} -p:not([class*="lead"]) { - color: black; -} -input[type="text"].class#id[attr=32]:not(1) { - color: white; -} -div#id.class[a=1][b=2].class:not(1) { - color: white; -} -ul.comma > li:not(:only-child)::after { - color: white; -} -ol.comma > li:nth-last-child(2)::after { - color: white; -} -li:nth-child(4n+1), -li:nth-child(-5n), -li:nth-child(-n+2) { - color: white; -} -a[href^="http://"] { - color: black; -} -a[href$="http://"] { - color: black; -} -form[data-disabled] { - color: black; -} -p::before { - color: black; -} -#issue322 { - -webkit-animation: anim2 7s infinite ease-in-out; -} -@-webkit-keyframes frames { - 0% { - border: 1px; - } - 5.5% { - border: 2px; - } - 100% { - border: 3px; - } -} -@keyframes fontbulger1 { - to { - font-size: 15px; - } - from, - to { - font-size: 12px; - } - 0%, - 100% { - font-size: 12px; - } -} -.units { - font: 1.2rem/2rem; - font: 8vw/9vw; - font: 10vh/12vh; - font: 12vm/15vm; - font: 12vmin/15vmin; - font: 1.2ch/1.5ch; -} -@supports ( box-shadow: 2px 2px 2px black ) or - ( -moz-box-shadow: 2px 2px 2px black ) { - .outline { - box-shadow: 2px 2px 2px black; - -moz-box-shadow: 2px 2px 2px black; - } -} -@-x-document url-prefix(""github.com"") { - h1 { - color: red; - } -} -@viewport { - font-size: 10px; -} -@namespace foo url(http://www.example.com); -foo|h1 { - color: blue; -} -foo|* { - color: yellow; -} -|h1 { - color: red; -} -*|h1 { - color: green; -} -h1 { - color: green; -} -.upper-test { - UpperCaseProperties: allowed; -} -@host { - div { - display: block; - } -} -::distributed(input::placeholder) { - color: #b3b3b3; -} diff --git a/test/Fixtures/lessjs (1.5)/css/css-escapes.css b/test/Fixtures/lessjs (1.5)/css/css-escapes.css deleted file mode 100644 index 4d343aa6..00000000 --- a/test/Fixtures/lessjs (1.5)/css/css-escapes.css +++ /dev/null @@ -1,24 +0,0 @@ -.escape\|random\|char { - color: red; -} -.mixin\!tUp { - font-weight: bold; -} -.\34 04 { - background: red; -} -.\34 04 strong { - color: #ff00ff; - font-weight: bold; -} -.trailingTest\+ { - color: red; -} -/* This hideous test of hideousness checks for the selector "blockquote" with various permutations of hex escapes */ -\62\6c\6f \63 \6B \0071 \000075o\74 e { - color: silver; -} -[ng\:cloak], -ng\:form { - display: none; -} diff --git a/test/Fixtures/lessjs (1.5)/css/css-guards.css b/test/Fixtures/lessjs (1.5)/css/css-guards.css deleted file mode 100644 index dbb27dae..00000000 --- a/test/Fixtures/lessjs (1.5)/css/css-guards.css +++ /dev/null @@ -1,18 +0,0 @@ -.light { - color: green; -} -.see-the { - color: orange; -} -.hide-the { - color: green; -} -.multiple-conditions-1 { - color: red; -} -.inheritance .test { - color: black; -} -.inheritance:hover { - color: pink; -} diff --git a/test/Fixtures/lessjs (1.5)/css/css.css b/test/Fixtures/lessjs (1.5)/css/css.css deleted file mode 100644 index 41567d8d..00000000 --- a/test/Fixtures/lessjs (1.5)/css/css.css +++ /dev/null @@ -1,95 +0,0 @@ -@charset "utf-8"; -div { - color: black; -} -div { - width: 99%; -} -* { - min-width: 45em; -} -h1, -h2 > a > p, -h3 { - color: none; -} -div.class { - color: blue; -} -div#id { - color: green; -} -.class#id { - color: purple; -} -.one.two.three { - color: grey; -} -@media print { - * { - font-size: 3em; - } -} -@media screen { - * { - font-size: 10px; - } -} -@font-face { - font-family: 'Garamond Pro'; -} -a:hover, -a:link { - color: #999; -} -p, -p:first-child { - text-transform: none; -} -q:lang(no) { - quotes: none; -} -p + h1 { - font-size: 2.2em; -} -#shorthands { - border: 1px solid #000; - font: 12px/16px Arial; - font: 100%/16px Arial; - margin: 1px 0; - padding: 0 auto; -} -#more-shorthands { - margin: 0; - padding: 1px 0 2px 0; - font: normal small / 20px 'Trebuchet MS', Verdana, sans-serif; - font: 0/0 a; - border-radius: 0.5px; -} -.misc { - -moz-border-radius: 2px; - display: -moz-inline-stack; - width: .1em; - background-color: #009998; - background: -webkit-gradient(linear, left top, left bottom, from(#ff0000), to(#0000ff)); - margin: ; - filter: alpha(opacity=100); - width: auto\9; -} -.misc .nested-multiple { - multiple-semi-colons: yes; -} -#important { - color: red !important; - width: 100%!important; - height: 20px ! important; -} -@font-face { - font-family: font-a; -} -@font-face { - font-family: font-b; -} -.æøå { - margin: 0; -} diff --git a/test/Fixtures/lessjs (1.5)/css/debug/linenumbers-all.css b/test/Fixtures/lessjs (1.5)/css/debug/linenumbers-all.css deleted file mode 100644 index c6fb355b..00000000 --- a/test/Fixtures/lessjs (1.5)/css/debug/linenumbers-all.css +++ /dev/null @@ -1,43 +0,0 @@ -@charset "UTF-8"; -/* line 3, {pathimport}test.less */ -@media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000033}} -/* @charset "ISO-8859-1"; */ -/* line 23, {pathimport}test.less */ -@media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\0000323}} -.tst3 { - color: grey; -} -/* line 15, {path}linenumbers.less */ -@media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\0000315}} -.test1 { - color: black; -} -/* line 6, {path}linenumbers.less */ -@media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\000036}} -.test2 { - color: red; -} -@media all { - /* line 5, {pathimport}test.less */ - @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000035}} - .tst { - color: black; - } -} -@media all and screen { - /* line 7, {pathimport}test.less */ - @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000037}} - .tst { - color: red; - } - /* line 9, {pathimport}test.less */ - @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000039}} - .tst .tst3 { - color: white; - } -} -/* line 18, {pathimport}test.less */ -@media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\0000318}} -.tst2 { - color: white; -} diff --git a/test/Fixtures/lessjs (1.5)/css/debug/linenumbers-comments.css b/test/Fixtures/lessjs (1.5)/css/debug/linenumbers-comments.css deleted file mode 100644 index 9c48baa9..00000000 --- a/test/Fixtures/lessjs (1.5)/css/debug/linenumbers-comments.css +++ /dev/null @@ -1,35 +0,0 @@ -@charset "UTF-8"; -/* line 3, {pathimport}test.less */ -/* @charset "ISO-8859-1"; */ -/* line 23, {pathimport}test.less */ -.tst3 { - color: grey; -} -/* line 15, {path}linenumbers.less */ -.test1 { - color: black; -} -/* line 6, {path}linenumbers.less */ -.test2 { - color: red; -} -@media all { - /* line 5, {pathimport}test.less */ - .tst { - color: black; - } -} -@media all and screen { - /* line 7, {pathimport}test.less */ - .tst { - color: red; - } - /* line 9, {pathimport}test.less */ - .tst .tst3 { - color: white; - } -} -/* line 18, {pathimport}test.less */ -.tst2 { - color: white; -} diff --git a/test/Fixtures/lessjs (1.5)/css/debug/linenumbers-mediaquery.css b/test/Fixtures/lessjs (1.5)/css/debug/linenumbers-mediaquery.css deleted file mode 100644 index 3fdbbafc..00000000 --- a/test/Fixtures/lessjs (1.5)/css/debug/linenumbers-mediaquery.css +++ /dev/null @@ -1,35 +0,0 @@ -@charset "UTF-8"; -@media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000033}} -/* @charset "ISO-8859-1"; */ -@media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\0000323}} -.tst3 { - color: grey; -} -@media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\0000315}} -.test1 { - color: black; -} -@media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\000036}} -.test2 { - color: red; -} -@media all { - @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000035}} - .tst { - color: black; - } -} -@media all and screen { - @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000037}} - .tst { - color: red; - } - @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000039}} - .tst .tst3 { - color: white; - } -} -@media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\0000318}} -.tst2 { - color: white; -} diff --git a/test/Fixtures/lessjs (1.5)/css/extend-chaining.css b/test/Fixtures/lessjs (1.5)/css/extend-chaining.css deleted file mode 100644 index 820e134f..00000000 --- a/test/Fixtures/lessjs (1.5)/css/extend-chaining.css +++ /dev/null @@ -1,81 +0,0 @@ -.a, -.b, -.c { - color: black; -} -.f, -.e, -.d { - color: black; -} -.g.h, -.i.j.h, -.k.j.h { - color: black; -} -.i.j, -.k.j { - color: white; -} -.l, -.m, -.n, -.o, -.p, -.q, -.r, -.s, -.t { - color: black; -} -.u, -.v.u.v { - color: black; -} -.w, -.v.w.v { - color: black; -} -.x, -.y, -.z { - color: x; -} -.y, -.z, -.x { - color: y; -} -.z, -.x, -.y { - color: z; -} -.va, -.vb, -.vc { - color: black; -} -.vb, -.vc { - color: white; -} -@media tv { - .ma, - .mb, - .mc { - color: black; - } - .md, - .ma, - .mb, - .mc { - color: white; - } -} -@media tv and plasma { - .me, - .mf { - background: red; - } -} diff --git a/test/Fixtures/lessjs (1.5)/css/extend-clearfix.css b/test/Fixtures/lessjs (1.5)/css/extend-clearfix.css deleted file mode 100644 index 966892a2..00000000 --- a/test/Fixtures/lessjs (1.5)/css/extend-clearfix.css +++ /dev/null @@ -1,19 +0,0 @@ -.clearfix, -.foo, -.bar { - *zoom: 1; -} -.clearfix:after, -.foo:after, -.bar:after { - content: ''; - display: block; - clear: both; - height: 0; -} -.foo { - color: red; -} -.bar { - color: blue; -} diff --git a/test/Fixtures/lessjs (1.5)/css/extend-exact.css b/test/Fixtures/lessjs (1.5)/css/extend-exact.css deleted file mode 100644 index beff4133..00000000 --- a/test/Fixtures/lessjs (1.5)/css/extend-exact.css +++ /dev/null @@ -1,37 +0,0 @@ -.replace.replace .replace, -.c.replace + .replace .replace, -.replace.replace .c, -.c.replace + .replace .c, -.rep_ace { - prop: copy-paste-replace; -} -.a .b .c { - prop: not_effected; -} -.a, -.effected { - prop: is_effected; -} -.a .b { - prop: not_effected; -} -.a .b.c { - prop: not_effected; -} -.c .b .a, -.a .b .a, -.c .a .a, -.a .a .a, -.c .b .c, -.a .b .c, -.c .a .c, -.a .a .c { - prop: not_effected; -} -.e.e, -.dbl { - prop: extend-double; -} -.e.e:hover { - hover: not-extended; -} diff --git a/test/Fixtures/lessjs (1.5)/css/extend-media.css b/test/Fixtures/lessjs (1.5)/css/extend-media.css deleted file mode 100644 index 23bd7b85..00000000 --- a/test/Fixtures/lessjs (1.5)/css/extend-media.css +++ /dev/null @@ -1,24 +0,0 @@ -.ext1 .ext2, -.all .ext2 { - background: black; -} -@media tv { - .ext1 .ext3, - .tv-lowres .ext3, - .all .ext3 { - color: white; - } - .tv-lowres { - background: blue; - } -} -@media tv and hires { - .ext1 .ext4, - .tv-hires .ext4, - .all .ext4 { - color: green; - } - .tv-hires { - background: red; - } -} diff --git a/test/Fixtures/lessjs (1.5)/css/extend-nest.css b/test/Fixtures/lessjs (1.5)/css/extend-nest.css deleted file mode 100644 index 2c3905d9..00000000 --- a/test/Fixtures/lessjs (1.5)/css/extend-nest.css +++ /dev/null @@ -1,57 +0,0 @@ -.sidebar, -.sidebar2, -.type1 .sidebar3, -.type2.sidebar4 { - width: 300px; - background: red; -} -.sidebar .box, -.sidebar2 .box, -.type1 .sidebar3 .box, -.type2.sidebar4 .box { - background: #FFF; - border: 1px solid #000; - margin: 10px 0; -} -.sidebar2 { - background: blue; -} -.type1 .sidebar3 { - background: green; -} -.type2.sidebar4 { - background: red; -} -.button, -.submit { - color: black; -} -.button:hover, -.submit:hover { - color: white; -} -.button2 :hover { - nested: white; -} -.button2 :hover { - notnested: black; -} -.amp-test-h, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e.amp-test-g { - test: extended by masses of selectors; -} diff --git a/test/Fixtures/lessjs (1.5)/css/extend-selector.css b/test/Fixtures/lessjs (1.5)/css/extend-selector.css deleted file mode 100644 index da47254b..00000000 --- a/test/Fixtures/lessjs (1.5)/css/extend-selector.css +++ /dev/null @@ -1,80 +0,0 @@ -.error, -.badError { - border: 1px #f00; - background: #fdd; -} -.error.intrusion, -.badError.intrusion { - font-size: 1.3em; - font-weight: bold; -} -.intrusion .error, -.intrusion .badError { - display: none; -} -.badError { - border-width: 3px; -} -.foo .bar, -.foo .baz, -.ext1 .ext2 .bar, -.ext1 .ext2 .baz, -.ext3 .bar, -.ext3 .baz, -.ext4 .bar, -.ext4 .baz { - display: none; -} -div.ext5, -.ext6 > .ext5, -div.ext7, -.ext6 > .ext7 { - width: 100px; -} -.ext, -.a .c, -.b .c { - test: 1; -} -.a, -.b { - test: 2; -} -.a .c, -.b .c { - test: 3; -} -.a .c .d, -.b .c .d { - test: 4; -} -.replace.replace .replace, -.c.replace + .replace .replace, -.replace.replace .c, -.c.replace + .replace .c, -.rep_ace.rep_ace .rep_ace, -.c.rep_ace + .rep_ace .rep_ace, -.rep_ace.rep_ace .c, -.c.rep_ace + .rep_ace .c { - prop: copy-paste-replace; -} -.attributes [data="test"], -.attributes .attributes .attribute-test { - extend: attributes; -} -.attributes [data], -.attributes .attributes .attribute-test2 { - extend: attributes2; -} -.attributes [data="test3"], -.attributes .attributes .attribute-test { - extend: attributes2; -} -.header .header-nav, -.footer .footer-nav { - background: red; -} -.header .header-nav:before, -.footer .footer-nav:before { - background: blue; -} diff --git a/test/Fixtures/lessjs (1.5)/css/extend.css b/test/Fixtures/lessjs (1.5)/css/extend.css deleted file mode 100644 index 2895641a..00000000 --- a/test/Fixtures/lessjs (1.5)/css/extend.css +++ /dev/null @@ -1,76 +0,0 @@ -.error, -.badError { - border: 1px #f00; - background: #fdd; -} -.error.intrusion, -.badError.intrusion { - font-size: 1.3em; - font-weight: bold; -} -.intrusion .error, -.intrusion .badError { - display: none; -} -.badError { - border-width: 3px; -} -.foo .bar, -.foo .baz, -.ext1 .ext2 .bar, -.ext1 .ext2 .baz, -.ext3 .bar, -.ext3 .baz, -.foo .ext3, -.ext4 .bar, -.ext4 .baz, -.foo .ext4 { - display: none; -} -div.ext5, -.ext6 > .ext5, -div.ext7, -.ext6 > .ext7 { - width: 100px; -} -.ext8.ext9, -.fuu { - result: add-foo; -} -.ext8 .ext9, -.ext8 + .ext9, -.ext8 > .ext9, -.buu, -.zap, -.zoo { - result: bar-matched; -} -.ext8.nomatch { - result: none; -} -.ext8 .ext9, -.buu { - result: match-nested-bar; -} -.ext8.ext9, -.fuu { - result: match-nested-foo; -} -.aa, -.cc { - color: black; -} -.aa .dd, -.aa .ee { - background: red; -} -.bb, -.cc, -.ee, -.ff { - background: red; -} -.bb .bb, -.ff .ff { - color: black; -} diff --git a/test/Fixtures/lessjs (1.5)/css/extract-and-length.css b/test/Fixtures/lessjs (1.5)/css/extract-and-length.css deleted file mode 100644 index f550e201..00000000 --- a/test/Fixtures/lessjs (1.5)/css/extract-and-length.css +++ /dev/null @@ -1,133 +0,0 @@ -.multiunit { - length: 6; - extract: abc "abc" 1 1px 1% #112233; -} -.incorrect-index { - v1: extract(a b c, 5); - v2: extract(a, b, c, -2); -} -.scalar { - var-value: variable; - var-length: 1; - ill-index: extract(variable, 2); - name-value: name; - string-value: "string"; - number-value: 12345678; - color-value: #0000ff; - rgba-value: rgba(80, 160, 240, 0.67); - empty-value: ; - name-length: 1; - string-length: 1; - number-length: 1; - color-length: 1; - rgba-length: 1; - empty-length: 1; -} -.mixin-arguments-1 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-2 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-3 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-4 { - length: 0; - extract: extract(, 2) | extract(, 1); -} -.mixin-arguments-2 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-3 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-4 { - length: 3; - extract: c | b; -} -.mixin-arguments-2 { - length: 4; - extract: 3 | 2 | 1; -} -.mixin-arguments-3 { - length: 4; - extract: 3 | 2 | 1; -} -.mixin-arguments-4 { - length: 3; - extract: 3 | 2; -} -.md-space-comma { - length-1: 3; - extract-1: 1 2 3; - length-2: 3; - extract-2: 2; -} -.md-space-comma-as-args-2 { - length: 3; - extract: "x" "y" "z" | 1 2 3 | a b c; -} -.md-space-comma-as-args-3 { - length: 3; - extract: "x" "y" "z" | 1 2 3 | a b c; -} -.md-space-comma-as-args-4 { - length: 2; - extract: "x" "y" "z" | 1 2 3; -} -.md-cat-space-comma { - length-1: 3; - extract-1: 1 2 3; - length-2: 3; - extract-2: 2; -} -.md-cat-space-comma-as-args-2 { - length: 3; - extract: "x" "y" "z" | 1 2 3 | a b c; -} -.md-cat-space-comma-as-args-3 { - length: 3; - extract: "x" "y" "z" | 1 2 3 | a b c; -} -.md-cat-space-comma-as-args-4 { - length: 2; - extract: "x" "y" "z" | 1 2 3; -} -.md-cat-comma-space { - length-1: 3; - extract-1: 1, 2, 3; - length-2: 3; - extract-2: 2; -} -.md-cat-comma-space-as-args-1 { - length: 3; - extract: "x", "y", "z" | 1, 2, 3 | a, b, c; -} -.md-cat-comma-space-as-args-2 { - length: 3; - extract: "x", "y", "z" | 1, 2, 3 | a, b, c; -} -.md-cat-comma-space-as-args-3 { - length: 3; - extract: "x", "y", "z" | 1, 2, 3 | a, b, c; -} -.md-cat-comma-space-as-args-4 { - length: 0; - extract: extract(, 2) | extract(, 1); -} -.md-3D { - length-1: 2; - extract-1: a b c d, 1 2 3 4; - length-2: 2; - extract-2: 5 6 7 8; - length-3: 4; - extract-3: 7; - length-4: 1; - extract-4: 8; -} diff --git a/test/Fixtures/lessjs (1.5)/css/functions.css b/test/Fixtures/lessjs (1.5)/css/functions.css deleted file mode 100644 index 24891512..00000000 --- a/test/Fixtures/lessjs (1.5)/css/functions.css +++ /dev/null @@ -1,139 +0,0 @@ -#functions { - color: _color("evil red"); - width: increment(15); - height: undefined("self"); - border-width: add(2, 3); - variable: increment(10); - background: linear-gradient(#000000, #ffffff); -} -#built-in { - escaped: -Some::weird(#thing, y); - lighten: #ffcccc; - darken: #330000; - saturate: #203c31; - desaturate: #29332f; - greyscale: #2e2e2e; - hsl-clamp: #ffffff; - spin-p: #bf6a40; - spin-n: #bf4055; - luma-white: 100%; - luma-black: 0%; - luma-black-alpha: 0%; - luma-red: 21%; - luma-green: 72%; - luma-blue: 7%; - luma-yellow: 93%; - luma-cyan: 79%; - luma-white-alpha: 50%; - contrast-filter: contrast(30%); - saturate-filter: saturate(5%); - contrast-white: #000000; - contrast-black: #ffffff; - contrast-red: #ffffff; - contrast-green: #000000; - contrast-blue: #ffffff; - contrast-yellow: #000000; - contrast-cyan: #000000; - contrast-light: #111111; - contrast-dark: #eeeeee; - contrast-wrongorder: #111111; - contrast-light-thresh: #111111; - contrast-dark-thresh: #eeeeee; - contrast-high-thresh: #eeeeee; - contrast-low-thresh: #111111; - contrast-light-thresh-per: #111111; - contrast-dark-thresh-per: #eeeeee; - contrast-high-thresh-per: #eeeeee; - contrast-low-thresh-per: #111111; - format: "rgb(32, 128, 64)"; - format-string: "hello world"; - format-multiple: "hello earth 2"; - format-url-encode: "red is %23ff0000"; - eformat: rgb(32, 128, 64); - unitless: 12; - unit: 14em; - hue: 98; - saturation: 12%; - lightness: 95%; - hsvhue: 98; - hsvsaturation: 12%; - hsvvalue: 95%; - red: 255; - green: 255; - blue: 255; - rounded: 11; - rounded-two: 10.67; - roundedpx: 3px; - roundedpx-three: 3.333px; - rounded-percentage: 10%; - ceil: 11px; - floor: 12px; - sqrt: 5px; - pi: 3.141592653589793; - mod: 2m; - abs: 4%; - tan: 0.9004040442978399; - sin: 0.17364817766693033; - cos: 0.8438539587324921; - atan: 0.1rad; - atan: 34.00000000000001deg; - atan: 45.00000000000001deg; - pow: 64px; - pow: 64; - pow: 27; - min: 0; - min: min("junk", 5); - min: 3pt; - max: 3; - max: max(8%, 1cm); - percentage: 20%; - color: #ff0011; - tint: #898989; - tint-full: #ffffff; - tint-percent: #898989; - shade: #686868; - shade-full: #000000; - shade-percent: #686868; - fade-out: rgba(255, 0, 0, 0.95); - fade-in: rgba(255, 0, 0, 0.9500000000000001); - hsv: #4d2926; - hsva: rgba(77, 40, 38, 0.2); - mix: #ff3300; - mix-0: #ffff00; - mix-100: #ff0000; - mix-weightless: #ff8000; - mixt: rgba(255, 0, 0, 0.5); -} -#built-in .is-a { - color: true; - color1: true; - color2: true; - color3: true; - keyword: true; - number: true; - string: true; - pixel: true; - percent: true; - em: true; - cat: true; -} -#alpha { - alpha: rgba(153, 94, 51, 0.6); - alpha2: 0.5; - alpha3: 0; -} -#blendmodes { - multiply: #ed0000; - screen: #f600f6; - overlay: #ed0000; - softlight: #ff0000; - hardlight: #0000ed; - difference: #f600f6; - exclusion: #f600f6; - average: #7b007b; - negation: #d73131; -} -#extract-and-length { - extract: 3 2 1 C B A; - length: 6; -} diff --git a/test/Fixtures/lessjs (1.5)/css/ie-filters.css b/test/Fixtures/lessjs (1.5)/css/ie-filters.css deleted file mode 100644 index 007aa536..00000000 --- a/test/Fixtures/lessjs (1.5)/css/ie-filters.css +++ /dev/null @@ -1,9 +0,0 @@ -.nav { - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=20); - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#333333", endColorstr="#000000", GradientType=0); -} -.evalTest1 { - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=30); - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=5); -} diff --git a/test/Fixtures/lessjs (1.5)/css/import-inline.css b/test/Fixtures/lessjs (1.5)/css/import-inline.css deleted file mode 100644 index f198d3c1..00000000 --- a/test/Fixtures/lessjs (1.5)/css/import-inline.css +++ /dev/null @@ -1,5 +0,0 @@ -this isn't very valid CSS. -@media (min-width: 600px) { - #css { color: yellow; } - -} diff --git a/test/Fixtures/lessjs (1.5)/css/import-interpolation.css b/test/Fixtures/lessjs (1.5)/css/import-interpolation.css deleted file mode 100644 index 16b7a150..00000000 --- a/test/Fixtures/lessjs (1.5)/css/import-interpolation.css +++ /dev/null @@ -1,6 +0,0 @@ -body { - width: 100%; -} -.a { - var: test; -} diff --git a/test/Fixtures/lessjs (1.5)/css/import-once.css b/test/Fixtures/lessjs (1.5)/css/import-once.css deleted file mode 100644 index 2f86b3b3..00000000 --- a/test/Fixtures/lessjs (1.5)/css/import-once.css +++ /dev/null @@ -1,15 +0,0 @@ -#import { - color: #ff0000; -} -body { - width: 100%; -} -.test-f { - height: 10px; -} -body { - width: 100%; -} -.test-f { - height: 10px; -} diff --git a/test/Fixtures/lessjs (1.5)/css/import-reference.css b/test/Fixtures/lessjs (1.5)/css/import-reference.css deleted file mode 100644 index c2d055a7..00000000 --- a/test/Fixtures/lessjs (1.5)/css/import-reference.css +++ /dev/null @@ -1,55 +0,0 @@ -/* - The media statement above is invalid (no selector) - We should ban invalid media queries with properties and no selector? -*/ -.visible { - color: red; -} -.visible .c { - color: green; -} -.visible { - color: green; -} -.visible:hover { - color: green; -} -.visible { - color: green; -} -.only-with-visible + .visible, -.visible + .only-with-visible, -.visible + .visible { - color: green; -} -.only-with-visible + .visible .sub, -.visible + .only-with-visible .sub, -.visible + .visible .sub { - color: green; -} -.b { - color: red; - color: green; -} -.b .c { - color: green; -} -.b:hover { - color: green; -} -.b { - color: green; -} -.b + .b { - color: green; -} -.b + .b .sub { - color: green; -} -.y { - pulled-in: yes; -} -/* comment pulled in */ -.visible { - extend: test; -} diff --git a/test/Fixtures/lessjs (1.5)/css/import.css b/test/Fixtures/lessjs (1.5)/css/import.css deleted file mode 100644 index a3749181..00000000 --- a/test/Fixtures/lessjs (1.5)/css/import.css +++ /dev/null @@ -1,36 +0,0 @@ -@import url(http://fonts.googleapis.com/css?family=Open+Sans); -@import url(/absolute/something.css) screen and (color) and (max-width: 600px); -@import url("//ha.com/file.css") (min-width: 100px); -#import-test { - height: 10px; - color: #ff0000; - width: 10px; - height: 30%; -} -@media screen and (max-width: 600px) { - body { - width: 100%; - } -} -#import { - color: #ff0000; -} -.mixin { - height: 10px; - color: #ff0000; -} -@media screen and (max-width: 601px) { - #css { - color: yellow; - } -} -@media screen and (max-width: 602px) { - body { - width: 100%; - } -} -@media screen and (max-width: 603px) { - #css { - color: yellow; - } -} diff --git a/test/Fixtures/lessjs (1.5)/css/javascript.css b/test/Fixtures/lessjs (1.5)/css/javascript.css deleted file mode 100644 index 8268ab33..00000000 --- a/test/Fixtures/lessjs (1.5)/css/javascript.css +++ /dev/null @@ -1,23 +0,0 @@ -.eval { - js: 42; - js: 2; - js: "hello world"; - js: 1, 2, 3; - title: "string"; - ternary: true; - multiline: 2; -} -.scope { - var: 42; - escaped: 7px; -} -.vars { - width: 8; -} -.escape-interpol { - width: hello world; -} -.arrays { - ary: "1, 2, 3"; - ary1: "1, 2, 3"; -} diff --git a/test/Fixtures/lessjs (1.5)/css/lazy-eval.css b/test/Fixtures/lessjs (1.5)/css/lazy-eval.css deleted file mode 100644 index 1adfb8f3..00000000 --- a/test/Fixtures/lessjs (1.5)/css/lazy-eval.css +++ /dev/null @@ -1,3 +0,0 @@ -.lazy-eval { - width: 100%; -} diff --git a/test/Fixtures/lessjs (1.5)/css/legacy/legacy.css b/test/Fixtures/lessjs (1.5)/css/legacy/legacy.css deleted file mode 100644 index 2f9bb80b..00000000 --- a/test/Fixtures/lessjs (1.5)/css/legacy/legacy.css +++ /dev/null @@ -1,7 +0,0 @@ -@media (-o-min-device-pixel-ratio: 2/1) { - .test-math-and-units { - font: ignores 0/0 rules; - test-division: 7em; - simple: 2px; - } -} diff --git a/test/Fixtures/lessjs (1.5)/css/media.css b/test/Fixtures/lessjs (1.5)/css/media.css deleted file mode 100644 index 607f0e44..00000000 --- a/test/Fixtures/lessjs (1.5)/css/media.css +++ /dev/null @@ -1,219 +0,0 @@ -@media print { - .class { - color: blue; - } - .class .sub { - width: 42; - } - .top, - header > h1 { - color: #444444; - } -} -@media screen { - body { - max-width: 480; - } -} -@media all and (device-aspect-ratio: 16 / 9) { - body { - max-width: 800px; - } -} -@media all and (orientation: portrait) { - aside { - float: none; - } -} -@media handheld and (min-width: 42), screen and (min-width: 20em) { - body { - max-width: 480px; - } -} -@media print { - body { - padding: 20px; - } - body header { - background-color: red; - } -} -@media print and (orientation: landscape) { - body { - margin-left: 20px; - } -} -@media screen { - .sidebar { - width: 300px; - } -} -@media screen and (orientation: landscape) { - .sidebar { - width: 500px; - } -} -@media a and b { - .first .second .third { - width: 300px; - } - .first .second .fourth { - width: 3; - } -} -@media a and b and c { - .first .second .third { - width: 500px; - } -} -@media a, b and c { - body { - width: 95%; - } -} -@media a and x, b and c and x, a and y, b and c and y { - body { - width: 100%; - } -} -.a { - background: black; -} -@media handheld { - .a { - background: white; - } -} -@media handheld and (max-width: 100px) { - .a { - background: red; - } -} -.b { - background: black; -} -@media handheld { - .b { - background: white; - } -} -@media handheld and (max-width: 200px) { - .b { - background: red; - } -} -@media only screen and (max-width: 200px) { - body { - width: 480px; - } -} -@media print { - @page :left { - margin: 0.5cm; - } - @page :right { - margin: 0.5cm; - } - @page Test:first { - margin: 1cm; - } - @page :first { - size: 8.5in 11in; - - @top-left { - margin: 1cm; - } - @top-left-corner { - margin: 1cm; - } - @top-center { - margin: 1cm; - } - @top-right { - margin: 1cm; - } - @top-right-corner { - margin: 1cm; - } - @bottom-left { - margin: 1cm; - } - @bottom-left-corner { - margin: 1cm; - } - @bottom-center { - margin: 1cm; - } - @bottom-right { - margin: 1cm; - } - @bottom-right-corner { - margin: 1cm; - } - @left-top { - margin: 1cm; - } - @left-middle { - margin: 1cm; - } - @left-bottom { - margin: 1cm; - } - @right-top { - margin: 1cm; - } - @right-middle { - content: "Page " counter(page); - } - @right-bottom { - margin: 1cm; - } - } -} -@media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: 2/1), (min-resolution: 2dppx), (min-resolution: 128dpcm) { - .b { - background: red; - } -} -body { - background: red; -} -@media (max-width: 500px) { - body { - background: green; - } -} -@media (max-width: 1000px) { - body { - background: red; - background: blue; - } -} -@media (max-width: 1000px) and (max-width: 500px) { - body { - background: green; - } -} -@media (max-width: 1200px) { - /* a comment */ -} -@media (max-width: 1200px) and (max-width: 900px) { - body { - font-size: 11px; - } -} -@media (min-width: 480px) { - .nav-justified > li { - display: table-cell; - } -} -@media (min-width: 768px) and (min-width: 480px) { - .menu > li { - display: table-cell; - } -} -@media all and tv { - .all-and-tv-variables { - var: all-and-tv; - } -} diff --git a/test/Fixtures/lessjs (1.5)/css/merge.css b/test/Fixtures/lessjs (1.5)/css/merge.css deleted file mode 100644 index 4cf8c579..00000000 --- a/test/Fixtures/lessjs (1.5)/css/merge.css +++ /dev/null @@ -1,22 +0,0 @@ -.test1 { - transform: rotate(90deg), skew(30deg), scale(2, 4); -} -.test2 { - transform: rotate(90deg), skew(30deg); - transform: scaleX(45deg); -} -.test3 { - transform: scaleX(45deg); - background: url(data://img1.png); -} -.test4 { - transform: rotate(90deg), skew(30deg); - transform: scale(2, 4) !important; -} -.test5 { - transform: rotate(90deg), skew(30deg); - transform: scale(2, 4) !important; -} -.test6 { - transform: scale(2, 4); -} diff --git a/test/Fixtures/lessjs (1.5)/css/mixins-args.css b/test/Fixtures/lessjs (1.5)/css/mixins-args.css deleted file mode 100644 index 724613ad..00000000 --- a/test/Fixtures/lessjs (1.5)/css/mixins-args.css +++ /dev/null @@ -1,113 +0,0 @@ -#hidden { - color: transparent; -} -#hidden1 { - color: transparent; -} -.two-args { - color: blue; - width: 10px; - height: 99%; - border: 2px dotted #000000; -} -.one-arg { - width: 15px; - height: 49%; -} -.no-parens { - width: 5px; - height: 49%; -} -.no-args { - width: 5px; - height: 49%; -} -.var-args { - width: 45; - height: 17%; -} -.multi-mix { - width: 10px; - height: 29%; - margin: 4; - padding: 5; -} -body { - padding: 30px; - color: #ff0000; -} -.scope-mix { - width: 8; -} -.content { - width: 600px; -} -.content .column { - margin: 600px; -} -#same-var-name { - radius: 5px; -} -#var-inside { - width: 10px; -} -.arguments { - border: 1px solid #000000; - width: 1px; -} -.arguments2 { - border: 0px; - width: 0px; -} -.arguments3 { - border: 0px; - width: 0px; -} -.arguments4 { - border: 0 1 2 3 4; - rest: 1 2 3 4; - width: 0; -} -.edge-case { - border: "{"; - width: "{"; -} -.slash-vs-math { - border-radius: 0.4px; - border-radius: 0.5px; - border-radius: 6px; -} -.comma-vs-semi-colon { - one: a; - two: b, c; - one: d, e; - two: f; - one: g; - one: h; - one: i; - one: j; - one: k; - two: l; - one: m, n; - one: o, p; - two: q; - one: r, s; - two: t; -} -#named-conflict { - four: a, 11, 12, 13; - four: a, 21, 22, 23; -} -.test-mixin-default-arg { - defaults: 1px 1px 1px; - defaults: 2px 2px 2px; -} -.selector { - margin: 2, 2, 2, 2; -} -.selector2 { - margin: 2, 2, 2, 2; -} -.selector3 { - margin: 4; -} diff --git a/test/Fixtures/lessjs (1.5)/css/mixins-closure.css b/test/Fixtures/lessjs (1.5)/css/mixins-closure.css deleted file mode 100644 index b1021b6f..00000000 --- a/test/Fixtures/lessjs (1.5)/css/mixins-closure.css +++ /dev/null @@ -1,9 +0,0 @@ -.class { - width: 99px; -} -.overwrite { - width: 99px; -} -.nested .class { - width: 5px; -} diff --git a/test/Fixtures/lessjs (1.5)/css/mixins-guards.css b/test/Fixtures/lessjs (1.5)/css/mixins-guards.css deleted file mode 100644 index 25e6f287..00000000 --- a/test/Fixtures/lessjs (1.5)/css/mixins-guards.css +++ /dev/null @@ -1,82 +0,0 @@ -.light1 { - color: white; - margin: 1px; -} -.light2 { - color: black; - margin: 1px; -} -.max1 { - width: 6; -} -.max2 { - width: 8; -} -.glob1 { - margin: auto auto; -} -.ops1 { - height: gt-or-eq; - height: lt-or-eq; - height: lt-or-eq-alias; -} -.ops2 { - height: gt-or-eq; - height: not-eq; -} -.ops3 { - height: lt-or-eq; - height: lt-or-eq-alias; - height: not-eq; -} -.default1 { - content: default; -} -.test1 { - content: "true."; -} -.test2 { - content: "false."; -} -.test3 { - content: "false."; -} -.test4 { - content: "false."; -} -.test5 { - content: "false."; -} -.bool1 { - content: true and true; - content: true; - content: false, true; - content: false and true and true, true; - content: false, true and true; - content: false, false, true; - content: false, true and true and true, false; - content: not false; - content: not false and false, not false; -} -.equality-units { - test: pass; -} -.colorguardtest { - content: is #ff0000; - content: is not #0000ff its #ff0000; - content: is not #0000ff its #800080; -} -.stringguardtest { - content: is theme1; - content: is not theme2; - content: is theme1 no quotes; -} -#tryNumberPx { - catch: all; - declare: 4; - declare: 4px; -} -.call-lock-mixin .call-inner-lock-mixin { - a: 1; - x: 1; -} diff --git a/test/Fixtures/lessjs (1.5)/css/mixins-important.css b/test/Fixtures/lessjs (1.5)/css/mixins-important.css deleted file mode 100644 index b100af7f..00000000 --- a/test/Fixtures/lessjs (1.5)/css/mixins-important.css +++ /dev/null @@ -1,45 +0,0 @@ -.class { - border: 1; - boxer: 1; - border-width: 1; - border: 2 !important; - boxer: 2 !important; - border-width: 2 !important; - border: 3; - boxer: 3; - border-width: 3; - border: 4 !important; - boxer: 4 !important; - border-width: 4 !important; - border: 5; - boxer: 5; - border-width: 5; - border: 0 !important; - boxer: 0 !important; - border-width: 0 !important; - border: 9 !important; - border: 9; - boxer: 9; - border-width: 9; -} -.class .inner { - test: 1; -} -.class .inner { - test: 2 !important; -} -.class .inner { - test: 3; -} -.class .inner { - test: 4 !important; -} -.class .inner { - test: 5; -} -.class .inner { - test: 0 !important; -} -.class .inner { - test: 9; -} diff --git a/test/Fixtures/lessjs (1.5)/css/mixins-named-args.css b/test/Fixtures/lessjs (1.5)/css/mixins-named-args.css deleted file mode 100644 index e460aa10..00000000 --- a/test/Fixtures/lessjs (1.5)/css/mixins-named-args.css +++ /dev/null @@ -1,27 +0,0 @@ -.named-arg { - color: blue; - width: 5px; - height: 99%; - args: 1px 100%; - text-align: center; -} -.class { - width: 5px; - height: 19%; - args: 1px 20%; -} -.all-args-wrong-args { - width: 10px; - height: 9%; - args: 2px 10%; -} -.named-args2 { - width: 15px; - height: 49%; - color: #646464; -} -.named-args3 { - width: 5px; - height: 29%; - color: #123456; -} diff --git a/test/Fixtures/lessjs (1.5)/css/mixins-nested.css b/test/Fixtures/lessjs (1.5)/css/mixins-nested.css deleted file mode 100644 index 6378c475..00000000 --- a/test/Fixtures/lessjs (1.5)/css/mixins-nested.css +++ /dev/null @@ -1,14 +0,0 @@ -.class .inner { - height: 300; -} -.class .inner .innest { - width: 30; - border-width: 60; -} -.class2 .inner { - height: 600; -} -.class2 .inner .innest { - width: 60; - border-width: 120; -} diff --git a/test/Fixtures/lessjs (1.5)/css/mixins-pattern.css b/test/Fixtures/lessjs (1.5)/css/mixins-pattern.css deleted file mode 100644 index 8b828335..00000000 --- a/test/Fixtures/lessjs (1.5)/css/mixins-pattern.css +++ /dev/null @@ -1,47 +0,0 @@ -.zero { - variadic: true; - zero: 0; - one: 1; - two: 2; - three: 3; -} -.one { - variadic: true; - one: 1; - one-req: 1; - two: 2; - three: 3; -} -.two { - variadic: true; - two: 2; - three: 3; -} -.three { - variadic: true; - three-req: 3; - three: 3; -} -.left { - left: 1; -} -.right { - right: 1; -} -.border-right { - color: black; - border-right: 4px; -} -.border-left { - color: black; - border-left: 4px; -} -.only-right { - right: 33; -} -.only-left { - left: 33; -} -.left-right { - both: 330; -} diff --git a/test/Fixtures/lessjs (1.5)/css/mixins.css b/test/Fixtures/lessjs (1.5)/css/mixins.css deleted file mode 100644 index 32097f97..00000000 --- a/test/Fixtures/lessjs (1.5)/css/mixins.css +++ /dev/null @@ -1,141 +0,0 @@ -.mixin { - border: 1px solid black; -} -.mixout { - border-color: orange; -} -.borders { - border-style: dashed; -} -#namespace .borders { - border-style: dotted; -} -#namespace .biohazard { - content: "death"; -} -#namespace .biohazard .man { - color: transparent; -} -#theme > .mixin { - background-color: grey; -} -#container { - color: black; - border: 1px solid black; - border-color: orange; - background-color: grey; -} -#header .milk { - color: white; - border: 1px solid black; - background-color: grey; -} -#header #cookie { - border-style: dashed; -} -#header #cookie .chips { - border-style: dotted; -} -#header #cookie .chips .calories { - color: black; - border: 1px solid black; - border-color: orange; - background-color: grey; -} -.secure-zone { - color: transparent; -} -.direct { - border-style: dotted; -} -.bo, -.bar { - width: 100%; -} -.bo { - border: 1px; -} -.ar.bo.ca { - color: black; -} -.jo.ki { - background: none; -} -.amp.support { - color: orange; -} -.amp.support .higher { - top: 0px; -} -.amp.support.deeper { - height: auto; -} -.extended { - width: 100%; - border: 1px; - background: none; - color: orange; - top: 0px; - height: auto; -} -.extended .higher { - top: 0px; -} -.extended.deeper { - height: auto; -} -.do .re .mi .fa .sol .la .si { - color: cyan; -} -.mutli-selector-parents { - color: cyan; -} -.foo .bar { - width: 100%; -} -.underParents { - color: red; -} -.parent .underParents { - color: red; -} -* + h1 { - margin-top: 25px; -} -legend + h1 { - margin-top: 0; -} -h1 + * { - margin-top: 10px; -} -* + h2 { - margin-top: 20px; -} -legend + h2 { - margin-top: 0; -} -h2 + * { - margin-top: 8px; -} -* + h3 { - margin-top: 15px; -} -legend + h3 { - margin-top: 0; -} -h3 + * { - margin-top: 5px; -} -.error { - background-image: "/a.png"; - background-position: center center; -} -.test-rec .recursion { - color: black; -} -.button { - padding-left: 44px; -} -.button.large { - padding-left: 40em; -} diff --git a/test/Fixtures/lessjs (1.5)/css/no-output.css b/test/Fixtures/lessjs (1.5)/css/no-output.css deleted file mode 100644 index e69de29b..00000000 diff --git a/test/Fixtures/lessjs (1.5)/css/operations.css b/test/Fixtures/lessjs (1.5)/css/operations.css deleted file mode 100644 index fb9e0aff..00000000 --- a/test/Fixtures/lessjs (1.5)/css/operations.css +++ /dev/null @@ -1,49 +0,0 @@ -#operations { - color: #111111; - height: 9px; - width: 3em; - substraction: 0; - division: 1; -} -#operations .spacing { - height: 9px; - width: 3em; -} -.with-variables { - height: 16em; - width: 24em; - size: 1cm; -} -.with-functions { - color: #646464; - color: #ff8080; - color: #c94a4a; -} -.negative { - height: 0px; - width: 4px; -} -.shorthands { - padding: -1px 2px 0 -4px; -} -.rem-dimensions { - font-size: 5.5rem; -} -.colors { - color: #123; - border-color: #334455; - background-color: #000000; -} -.colors .other { - color: #222222; - border-color: #222222; -} -.negations { - variable: -4px; - variable1: 0px; - variable2: 0px; - variable3: 8px; - variable4: 0px; - paren: -4px; - paren2: 16px; -} diff --git a/test/Fixtures/lessjs (1.5)/css/parens.css b/test/Fixtures/lessjs (1.5)/css/parens.css deleted file mode 100644 index 015a4147..00000000 --- a/test/Fixtures/lessjs (1.5)/css/parens.css +++ /dev/null @@ -1,33 +0,0 @@ -.parens { - border: 2px solid #000000; - margin: 1px 3px 16 3; - width: 36; - padding: 2px 36px; -} -.more-parens { - padding: 8 4 4 4px; - width-all: 96; - width-first: 96; - width-keep: 96; - height-keep: 113; - height-all: 113; - height-parts: 113; - margin-keep: 12; - margin-parts: 12; - margin-all: 12; - border-radius-keep: 5px; - border-radius-parts: 1.1428571428571428px; - border-radius-all: 5px; -} -.negative { - neg-var: -1; - neg-var-paren: -1; -} -.nested-parens { - width: 71; - height: 6; -} -.mixed-units { - margin: 2px 4em 1 5pc; - padding: 6px 1em 2px 2; -} diff --git a/test/Fixtures/lessjs (1.5)/css/rulesets.css b/test/Fixtures/lessjs (1.5)/css/rulesets.css deleted file mode 100644 index 408c76aa..00000000 --- a/test/Fixtures/lessjs (1.5)/css/rulesets.css +++ /dev/null @@ -1,33 +0,0 @@ -#first > .one { - font-size: 2em; -} -#first > .one > #second .two > #deux { - width: 50%; -} -#first > .one > #second .two > #deux #third { - height: 100%; -} -#first > .one > #second .two > #deux #third:focus { - color: black; -} -#first > .one > #second .two > #deux #third:focus #fifth > #sixth .seventh #eighth + #ninth { - color: purple; -} -#first > .one > #second .two > #deux #fourth, -#first > .one > #second .two > #deux #five, -#first > .one > #second .two > #deux #six { - color: #110000; -} -#first > .one > #second .two > #deux #fourth .seven, -#first > .one > #second .two > #deux #five .seven, -#first > .one > #second .two > #deux #six .seven, -#first > .one > #second .two > #deux #fourth .eight > #nine, -#first > .one > #second .two > #deux #five .eight > #nine, -#first > .one > #second .two > #deux #six .eight > #nine { - border: 1px solid black; -} -#first > .one > #second .two > #deux #fourth #ten, -#first > .one > #second .two > #deux #five #ten, -#first > .one > #second .two > #deux #six #ten { - color: red; -} diff --git a/test/Fixtures/lessjs (1.5)/css/scope.css b/test/Fixtures/lessjs (1.5)/css/scope.css deleted file mode 100644 index baa05523..00000000 --- a/test/Fixtures/lessjs (1.5)/css/scope.css +++ /dev/null @@ -1,35 +0,0 @@ -.tiny-scope { - color: #998899; -} -.scope1 { - color: #0000ff; - border-color: #000000; -} -.scope1 .scope2 { - color: #0000ff; -} -.scope1 .scope2 .scope3 { - color: #ff0000; - border-color: #000000; - background-color: #ffffff; -} -.scope { - scoped-val: #008000; -} -.heightIsSet { - height: 1024px; -} -.useHeightInMixinCall { - mixin-height: 1024px; -} -.imported { - exists: true; -} -.testImported { - exists: true; -} -#allAreUsedHere { - default: 'top level'; - scope: 'top level'; - sub-scope-only: 'inside'; -} diff --git a/test/Fixtures/lessjs (1.5)/css/selectors.css b/test/Fixtures/lessjs (1.5)/css/selectors.css deleted file mode 100644 index 51055047..00000000 --- a/test/Fixtures/lessjs (1.5)/css/selectors.css +++ /dev/null @@ -1,142 +0,0 @@ -h1 a:hover, -h2 a:hover, -h3 a:hover, -h1 p:hover, -h2 p:hover, -h3 p:hover { - color: red; -} -#all { - color: blue; -} -#the { - color: blue; -} -#same { - color: blue; -} -ul, -li, -div, -q, -blockquote, -textarea { - margin: 0; -} -td { - margin: 0; - padding: 0; -} -td, -input { - line-height: 1em; -} -a { - color: red; -} -a:hover { - color: blue; -} -div a { - color: green; -} -p a span { - color: yellow; -} -.foo .bar .qux, -.foo .baz .qux { - display: block; -} -.qux .foo .bar, -.qux .foo .baz { - display: inline; -} -.qux.foo .bar, -.qux.foo .baz { - display: inline-block; -} -.qux .foo .bar .biz, -.qux .foo .baz .biz { - display: none; -} -.a.b.c { - color: red; -} -.c .b.a { - color: red; -} -.foo .p.bar { - color: red; -} -.foo.p.bar { - color: red; -} -.foo + .foo { - background: amber; -} -.foo + .foo { - background: amber; -} -.foo + .foo, -.foo + .bar, -.bar + .foo, -.bar + .bar { - background: amber; -} -.foo a > .foo a, -.foo a > .bar a, -.foo a > .foo b, -.foo a > .bar b, -.bar a > .foo a, -.bar a > .bar a, -.bar a > .foo b, -.bar a > .bar b, -.foo b > .foo a, -.foo b > .bar a, -.foo b > .foo b, -.foo b > .bar b, -.bar b > .foo a, -.bar b > .bar a, -.bar b > .foo b, -.bar b > .bar b { - background: amber; -} -.other ::fnord { - color: #ff0000; -} -.other::fnord { - color: #ff0000; -} -.other ::bnord { - color: #ff0000; -} -.other::bnord { - color: #ff0000; -} -.blood { - color: red; -} -.bloodred { - color: green; -} -#blood.blood.red.black { - color: black; -} -:nth-child(3) { - selector: interpolated; -} -.test:nth-child(odd):not(:nth-child(3)) { - color: #ff0000; -} -[prop], -[prop=10%], -[prop="value3"], -[prop*="val3"], -[|prop~="val3"], -[*|prop$="val3"], -[ns|prop^="val3"], -[3^="val3"], -[3=3], -[3] { - attributes: yes; -} diff --git a/test/Fixtures/lessjs (1.5)/css/static-urls/urls.css b/test/Fixtures/lessjs (1.5)/css/static-urls/urls.css deleted file mode 100644 index 95f04fbb..00000000 --- a/test/Fixtures/lessjs (1.5)/css/static-urls/urls.css +++ /dev/null @@ -1,41 +0,0 @@ -@import "css/background.css"; -@import "folder (1)/import-test-d.css"; -@font-face { - src: url("/fonts/garamond-pro.ttf"); - src: local(Futura-Medium), url(folder\ \(1\)/fonts.svg#MyGeometricModern) format("svg"); -} -#shorthands { - background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; -} -#misc { - background-image: url(folder\ \(1\)/images/image.jpg); -} -#data-uri { - background: url(data:image/png;charset=utf-8;base64, - kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ - k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U - kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700); -} -#svg-data-uri { - background: transparent url('data:image/svg+xml, '); -} -.comma-delimited { - background: url(folder\ \(1\)/bg.jpg) no-repeat, url(folder\ \(1\)/bg.png) repeat-x top left, url(folder\ \(1\)/bg); -} -.values { - url: url('folder (1)/Trebuchet'); -} -#logo { - width: 100px; - height: 100px; - background: url('assets/logo.png'); -} -@font-face { - font-family: xecret; - src: url('assets/xecret.ttf'); -} -#secret { - font-family: xecret, sans-serif; -} diff --git a/test/Fixtures/lessjs (1.5)/css/strings.css b/test/Fixtures/lessjs (1.5)/css/strings.css deleted file mode 100644 index cd6d6020..00000000 --- a/test/Fixtures/lessjs (1.5)/css/strings.css +++ /dev/null @@ -1,43 +0,0 @@ -#strings { - background-image: url("http://son-of-a-banana.com"); - quotes: "~" "~"; - content: "#*%:&^,)!.(~*})"; - empty: ""; - brackets: "{" "}"; - escapes: "\"hello\" \\world"; - escapes2: "\"llo"; -} -#comments { - content: "/* hello */ // not-so-secret"; -} -#single-quote { - quotes: "'" "'"; - content: '""#!&""'; - empty: ''; - semi-colon: ';'; -} -#escaped { - filter: DX.Transform.MS.BS.filter(opacity=50); -} -#one-line { - image: url(http://tooks.com); -} -#crazy { - image: url(http://), "}", url("http://}"); -} -#interpolation { - url: "http://lesscss.org/dev/image.jpg"; - url2: "http://lesscss.org/image-256.jpg"; - url3: "http://lesscss.org#445566"; - url4: "http://lesscss.org/hello"; - url5: "http://lesscss.org/54.4px"; -} -.mix-mul-class { - color: #0000ff; - color: #ff0000; - color: #000000; - color: #ffa500; -} -.watermark { - family: Univers, Arial, Verdana, San-Serif; -} diff --git a/test/Fixtures/lessjs (1.5)/css/urls.css b/test/Fixtures/lessjs (1.5)/css/urls.css deleted file mode 100644 index 492f5bc1..00000000 --- a/test/Fixtures/lessjs (1.5)/css/urls.css +++ /dev/null @@ -1,63 +0,0 @@ -@import "css/background.css"; -@import "import/import-test-d.css"; -@import "file.css"; -@font-face { - src: url("/fonts/garamond-pro.ttf"); - src: local(Futura-Medium), url(fonts.svg#MyGeometricModern) format("svg"); -} -#shorthands { - background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; - background: url("img.jpg") center / 100px; - background: #ffffff url(image.png) center / 1px 100px repeat-x scroll content-box padding-box; -} -#misc { - background-image: url(images/image.jpg); -} -#data-uri { - background: url(data:image/png;charset=utf-8;base64, - kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ - k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U - kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700); - background-image: url("http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700"); -} -#svg-data-uri { - background: transparent url('data:image/svg+xml, '); -} -.comma-delimited { - background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg); -} -.values { - url: url('Trebuchet'); -} -#logo { - width: 100px; - height: 100px; - background: url('import/assets/logo.png'); -} -@font-face { - font-family: xecret; - src: url('import/assets/xecret.ttf'); -} -#secret { - font-family: xecret, sans-serif; -} -#data-uri { - uri: url('data:image/jpeg;base64,bm90IGFjdHVhbGx5IGEganBlZyBmaWxlCg=='); -} -#data-uri-guess { - uri: url('data:image/jpeg;base64,bm90IGFjdHVhbGx5IGEganBlZyBmaWxlCg=='); -} -#data-uri-ascii { - uri-1: url('data:text/html,%3Ch1%3EThis%20page%20is%20100%25%20Awesome.%3C%2Fh1%3E%0A'); - uri-2: url('data:text/html,%3Ch1%3EThis%20page%20is%20100%25%20Awesome.%3C%2Fh1%3E%0A'); -} -#data-uri-toobig { - uri: url('../data/data-uri-fail.png'); -} -#svg-functions { - background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhZGllbnQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjwvbGluZWFyR3JhZGllbnQ+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkaWVudCkiIC8+PC9zdmc+'); - background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhZGllbnQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIvPjxzdG9wIG9mZnNldD0iMyUiIHN0b3AtY29sb3I9IiNmZmE1MDAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIGZpbGw9InVybCgjZ3JhZGllbnQpIiAvPjwvc3ZnPg=='); - background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhZGllbnQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIxJSIgc3RvcC1jb2xvcj0iI2M0YzRjNCIvPjxzdG9wIG9mZnNldD0iMyUiIHN0b3AtY29sb3I9IiNmZmE1MDAiLz48c3RvcCBvZmZzZXQ9IjUlIiBzdG9wLWNvbG9yPSIjMDA4MDAwIi8+PHN0b3Agb2Zmc2V0PSI5NSUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIGZpbGw9InVybCgjZ3JhZGllbnQpIiAvPjwvc3ZnPg=='); -} diff --git a/test/Fixtures/lessjs (1.5)/css/variables.css b/test/Fixtures/lessjs (1.5)/css/variables.css deleted file mode 100644 index f8d8518b..00000000 --- a/test/Fixtures/lessjs (1.5)/css/variables.css +++ /dev/null @@ -1,45 +0,0 @@ -.variables { - width: 14cm; -} -.variables { - height: 24px; - color: #888888; - font-family: "Trebuchet MS", Verdana, sans-serif; - quotes: "~" "~"; -} -.redef { - zero: 0; -} -.redef .inition { - three: 3; -} -.values { - minus-one: -1; - font-family: 'Trebuchet', 'Trebuchet', 'Trebuchet'; - color: #888888 !important; - multi: something 'A', B, C, 'Trebuchet'; -} -.variable-names { - name: 'hello'; -} -.alpha { - filter: alpha(opacity=42); -} -.testPollution { - a: 'no-pollution'; -} -.units { - width: 1px; - same-unit-as-previously: 1px; - square-pixel-divided: 1px; - odd-unit: 2; - percentage: 500%; - pixels: 500px; - conversion-metric-a: 30mm; - conversion-metric-b: 3cm; - conversion-imperial: 3in; - custom-unit: 420octocats; - custom-unit-cancelling: 18dogs; - mix-units: 2px; - invalid-units: 1px; -} diff --git a/test/Fixtures/lessjs (1.5)/css/whitespace.css b/test/Fixtures/lessjs (1.5)/css/whitespace.css deleted file mode 100644 index 74c9b65e..00000000 --- a/test/Fixtures/lessjs (1.5)/css/whitespace.css +++ /dev/null @@ -1,42 +0,0 @@ -.whitespace { - color: white; -} -.whitespace { - color: white; -} -.whitespace { - color: white; -} -.whitespace { - color: white; -} -.whitespace { - color: white ; -} -.white, -.space, -.mania { - color: white; -} -.no-semi-column { - color: #ffffff; -} -.no-semi-column { - color: white; - white-space: pre; -} -.no-semi-column { - border: 2px solid #ffffff; -} -.newlines { - background: the, - great, - wall; - border: 2px - solid - black; -} -.sel .newline_ws .tab_ws { - color: white; - background-position: 45 -23; -} diff --git a/test/Fixtures/lessjs (1.5)/data/data-uri-fail.png b/test/Fixtures/lessjs (1.5)/data/data-uri-fail.png deleted file mode 100644 index f91b59fb314c105c5d290775cd5395bc6140caf7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52420 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 zbiv&This page is 100% Awesome. diff --git a/test/Fixtures/lessjs (1.5)/expected/a.css b/test/Fixtures/lessjs (1.5)/expected/a.css deleted file mode 100644 index a45a62e9..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/a.css +++ /dev/null @@ -1,13 +0,0 @@ -.mixin { - width: 10; - height: 20; - color: red !important; - background: #000; -} -.test { - width: 10; - height: 20; - color: red !important; - background: #000; - color: blue; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/charsets.css b/test/Fixtures/lessjs (1.5)/expected/charsets.css deleted file mode 100644 index 9f44090c..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/charsets.css +++ /dev/null @@ -1 +0,0 @@ -@charset "UTF-8"; diff --git a/test/Fixtures/lessjs (1.5)/expected/colors.css b/test/Fixtures/lessjs (1.5)/expected/colors.css deleted file mode 100644 index 16956772..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/colors.css +++ /dev/null @@ -1,80 +0,0 @@ -#yelow #short { - color: #fea; -} -#yelow #long { - color: #ffeeaa; -} -#yelow #rgba { - color: rgba(255, 238, 170, 0.1); -} -#yelow #argb { - color: #1affeeaa; -} -#blue #short { - color: #00f; -} -#blue #long { - color: #0000ff; -} -#blue #rgba { - color: rgba(0, 0, 255, 0.1); -} -#blue #argb { - color: #1a0000ff; -} -#alpha #hsla { - color: rgba(61, 45, 41, 0.6); -} -#overflow .a { - color: #000000; -} -#overflow .b { - color: #ffffff; -} -#overflow .c { - color: #ffffff; -} -#overflow .d { - color: #00ff00; -} -#grey { - color: #c8c8c8; -} -#333333 { - color: #333333; -} -#808080 { - color: #808080; -} -#00ff00 { - color: #00ff00; -} -.lightenblue { - color: #3333ff; -} -.darkenblue { - color: #0000cc; -} -.unknowncolors { - color: blue2; - border: 2px solid superred; -} -.transparent { - color: transparent; - background-color: rgba(0, 0, 0, 0); -} -#alpha #fromvar { - opacity: 0.7; -} -#alpha #short { - opacity: 1; -} -#alpha #long { - opacity: 1; -} -#alpha #rgba { - opacity: 0.2; -} -#alpha #hsl { - opacity: 1; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/comments.css b/test/Fixtures/lessjs (1.5)/expected/comments.css deleted file mode 100644 index b7670230..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/comments.css +++ /dev/null @@ -1,69 +0,0 @@ -/******************\ -* * -* Comment Header * -* * -\******************/ -/* - - Comment - -*/ -/* - * Comment Test - * - * - cloudhead (http://cloudhead.net) - * - */ -/* Colors - * ------ - * #EDF8FC (background blue) - * #166C89 (darkest blue) - * - * Text: - * #333 (standard text) // A comment within a comment! - * #1F9EC9 (standard link) - * - */ -/* @group Variables -------------------- */ -#comments, -.comments { - /**/ - color: red; - /* A C-style comment */ - /* A C-style comment */ - background-color: orange; - font-size: 12px; - /* lost comment */ - content: "content"; - border: 1px solid black; - padding: 0; - margin: 2em; -} -/* commented out - #more-comments { - color: grey; - } -*/ -.selector, -.lots, -.comments { - color: #808080, /* blue */ #ffa500; - -webkit-border-radius: 2px /* webkit only */; - -moz-border-radius: 8px /* moz only with operation */; -} -.test { - color: 1px; -} -#last { - color: blue; -} -/* */ -/* { */ -/* */ -/* */ -/* */ -#div { - color: #A33; -} -/* } */ diff --git a/test/Fixtures/lessjs (1.5)/expected/css-3.css b/test/Fixtures/lessjs (1.5)/expected/css-3.css deleted file mode 100644 index 93b0a001..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/css-3.css +++ /dev/null @@ -1,125 +0,0 @@ -.comma-delimited { - text-shadow: -1px -1px 1px #ff0000, 6px 5px 5px #ffff00; - -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset, 0pt 4px 6px rgba(255, 255, 255, 0.4) inset; - -webkit-transform: rotate(-0.0000000001deg); -} -@font-face { - font-family: Headline; - unicode-range: U+??????, U+0???, U+0-7F, U+A5; -} -.other { - -moz-transform: translate(0, 11em) rotate(-90deg); - transform: rotateX(45deg); -} -.item[data-cra_zy-attr1b-ut3=bold] { - font-weight: bold; -} -p:not([class*="lead"]) { - color: black; -} -input[type="text"].class#id[attr=32]:not(1) { - color: white; -} -div#id.class[a=1][b=2].class:not(1) { - color: white; -} -ul.comma > li:not(:only-child)::after { - color: white; -} -ol.comma > li:nth-last-child(2)::after { - color: white; -} -li:nth-child(4n+1), -li:nth-child(-5n), -li:nth-child(-n+2) { - color: white; -} -a[href^="http://"] { - color: black; -} -a[href$="http://"] { - color: black; -} -form[data-disabled] { - color: black; -} -p::before { - color: black; -} -#issue322 { - -webkit-animation: anim2 7s infinite ease-in-out; -} -@-webkit-keyframes frames { - 0% { - border: 1px; - } - 5.5% { - border: 2px; - } - 100% { - border: 3px; - } -} -@keyframes fontbulger1 { - to { - font-size: 15px; - } - from, - to { - font-size: 12px; - } - 0%, - 100% { - font-size: 12px; - } -} -.units { - font: 1.2rem/2rem; - font: 8vw/9vw; - font: 10vh/12vh; - font: 12vm/15vm; - font: 12vmin/15vmin; - font: 1.2ch/1.5ch; -} -@supports ( box-shadow: 2px 2px 2px black ) or - ( -moz-box-shadow: 2px 2px 2px black ) { - .outline { - box-shadow: 2px 2px 2px black; - -moz-box-shadow: 2px 2px 2px black; - } -} -@-x-document url-prefix(""github.com"") { - h1 { - color: red; - } -} -@viewport { - font-size: 10px; -} -@namespace foo url(http://www.example.com); -foo|h1 { - color: blue; -} -foo|* { - color: yellow; -} -|h1 { - color: red; -} -*|h1 { - color: green; -} -h1 { - color: green; -} -.upper-test { - UpperCaseProperties: allowed; -} -@host { - div { - display: block; - } -} -::distributed(input::placeholder) { - color: #b3b3b3; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/css-escapes.css b/test/Fixtures/lessjs (1.5)/expected/css-escapes.css deleted file mode 100644 index 4d343aa6..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/css-escapes.css +++ /dev/null @@ -1,24 +0,0 @@ -.escape\|random\|char { - color: red; -} -.mixin\!tUp { - font-weight: bold; -} -.\34 04 { - background: red; -} -.\34 04 strong { - color: #ff00ff; - font-weight: bold; -} -.trailingTest\+ { - color: red; -} -/* This hideous test of hideousness checks for the selector "blockquote" with various permutations of hex escapes */ -\62\6c\6f \63 \6B \0071 \000075o\74 e { - color: silver; -} -[ng\:cloak], -ng\:form { - display: none; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/css-guards.css b/test/Fixtures/lessjs (1.5)/expected/css-guards.css deleted file mode 100644 index dbb27dae..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/css-guards.css +++ /dev/null @@ -1,18 +0,0 @@ -.light { - color: green; -} -.see-the { - color: orange; -} -.hide-the { - color: green; -} -.multiple-conditions-1 { - color: red; -} -.inheritance .test { - color: black; -} -.inheritance:hover { - color: pink; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/css.css b/test/Fixtures/lessjs (1.5)/expected/css.css deleted file mode 100644 index 24040ff3..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/css.css +++ /dev/null @@ -1,95 +0,0 @@ -@charset "utf-8"; -div { - color: black; -} -div { - width: 99%; -} -* { - min-width: 45em; -} -h1, -h2 > a > p, -h3 { - color: none; -} -div.class { - color: blue; -} -div#id { - color: green; -} -.class#id { - color: purple; -} -.one.two.three { - color: grey; -} -@media print { - * { - font-size: 3em; - } -} -@media screen { - * { - font-size: 10px; - } -} -@font-face { - font-family: 'Garamond Pro'; -} -a:hover, -a:link { - color: #999; -} -p, -p:first-child { - text-transform: none; -} -q:lang(no) { - quotes: none; -} -p + h1 { - font-size: 2.2em; -} -#shorthands { - border: 1px solid #000; - font: 12px/16px Arial; - font: 100%/16px Arial; - margin: 1px 0; - padding: 0 auto; -} -#more-shorthands { - margin: 0; - padding: 1px 0 2px 0; - font: normal small / 20px 'Trebuchet MS', Verdana, sans-serif; - font: 0/0 a; - border-radius: 0.5px; -} -.misc { - -moz-border-radius: 2px; - display: -moz-inline-stack; - width: .1em; - background-color: #009998; - background: -webkit-gradient(linear, left top, left bottom, from(#ff0000), to(#0000ff)); - margin: ; - filter: alpha(opacity=100); - width: auto\9; -} -.misc .nested-multiple { - multiple-semi-colons: yes; -} -#important { - color: red !important; - width: 100% !important; - height: 20px !important; -} -@font-face { - font-family: font-a; -} -@font-face { - font-family: font-b; -} -.æøå { - margin: 0; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/extend-chaining.css b/test/Fixtures/lessjs (1.5)/expected/extend-chaining.css deleted file mode 100644 index 820e134f..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/extend-chaining.css +++ /dev/null @@ -1,81 +0,0 @@ -.a, -.b, -.c { - color: black; -} -.f, -.e, -.d { - color: black; -} -.g.h, -.i.j.h, -.k.j.h { - color: black; -} -.i.j, -.k.j { - color: white; -} -.l, -.m, -.n, -.o, -.p, -.q, -.r, -.s, -.t { - color: black; -} -.u, -.v.u.v { - color: black; -} -.w, -.v.w.v { - color: black; -} -.x, -.y, -.z { - color: x; -} -.y, -.z, -.x { - color: y; -} -.z, -.x, -.y { - color: z; -} -.va, -.vb, -.vc { - color: black; -} -.vb, -.vc { - color: white; -} -@media tv { - .ma, - .mb, - .mc { - color: black; - } - .md, - .ma, - .mb, - .mc { - color: white; - } -} -@media tv and plasma { - .me, - .mf { - background: red; - } -} diff --git a/test/Fixtures/lessjs (1.5)/expected/extend-clearfix.css b/test/Fixtures/lessjs (1.5)/expected/extend-clearfix.css deleted file mode 100644 index 966892a2..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/extend-clearfix.css +++ /dev/null @@ -1,19 +0,0 @@ -.clearfix, -.foo, -.bar { - *zoom: 1; -} -.clearfix:after, -.foo:after, -.bar:after { - content: ''; - display: block; - clear: both; - height: 0; -} -.foo { - color: red; -} -.bar { - color: blue; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/extend-exact.css b/test/Fixtures/lessjs (1.5)/expected/extend-exact.css deleted file mode 100644 index beff4133..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/extend-exact.css +++ /dev/null @@ -1,37 +0,0 @@ -.replace.replace .replace, -.c.replace + .replace .replace, -.replace.replace .c, -.c.replace + .replace .c, -.rep_ace { - prop: copy-paste-replace; -} -.a .b .c { - prop: not_effected; -} -.a, -.effected { - prop: is_effected; -} -.a .b { - prop: not_effected; -} -.a .b.c { - prop: not_effected; -} -.c .b .a, -.a .b .a, -.c .a .a, -.a .a .a, -.c .b .c, -.a .b .c, -.c .a .c, -.a .a .c { - prop: not_effected; -} -.e.e, -.dbl { - prop: extend-double; -} -.e.e:hover { - hover: not-extended; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/extend-media.css b/test/Fixtures/lessjs (1.5)/expected/extend-media.css deleted file mode 100644 index 23bd7b85..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/extend-media.css +++ /dev/null @@ -1,24 +0,0 @@ -.ext1 .ext2, -.all .ext2 { - background: black; -} -@media tv { - .ext1 .ext3, - .tv-lowres .ext3, - .all .ext3 { - color: white; - } - .tv-lowres { - background: blue; - } -} -@media tv and hires { - .ext1 .ext4, - .tv-hires .ext4, - .all .ext4 { - color: green; - } - .tv-hires { - background: red; - } -} diff --git a/test/Fixtures/lessjs (1.5)/expected/extend-nest.css b/test/Fixtures/lessjs (1.5)/expected/extend-nest.css deleted file mode 100644 index 2c3905d9..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/extend-nest.css +++ /dev/null @@ -1,57 +0,0 @@ -.sidebar, -.sidebar2, -.type1 .sidebar3, -.type2.sidebar4 { - width: 300px; - background: red; -} -.sidebar .box, -.sidebar2 .box, -.type1 .sidebar3 .box, -.type2.sidebar4 .box { - background: #FFF; - border: 1px solid #000; - margin: 10px 0; -} -.sidebar2 { - background: blue; -} -.type1 .sidebar3 { - background: green; -} -.type2.sidebar4 { - background: red; -} -.button, -.submit { - color: black; -} -.button:hover, -.submit:hover { - color: white; -} -.button2 :hover { - nested: white; -} -.button2 :hover { - notnested: black; -} -.amp-test-h, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e.amp-test-g { - test: extended by masses of selectors; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/extend-selector.css b/test/Fixtures/lessjs (1.5)/expected/extend-selector.css deleted file mode 100644 index da47254b..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/extend-selector.css +++ /dev/null @@ -1,80 +0,0 @@ -.error, -.badError { - border: 1px #f00; - background: #fdd; -} -.error.intrusion, -.badError.intrusion { - font-size: 1.3em; - font-weight: bold; -} -.intrusion .error, -.intrusion .badError { - display: none; -} -.badError { - border-width: 3px; -} -.foo .bar, -.foo .baz, -.ext1 .ext2 .bar, -.ext1 .ext2 .baz, -.ext3 .bar, -.ext3 .baz, -.ext4 .bar, -.ext4 .baz { - display: none; -} -div.ext5, -.ext6 > .ext5, -div.ext7, -.ext6 > .ext7 { - width: 100px; -} -.ext, -.a .c, -.b .c { - test: 1; -} -.a, -.b { - test: 2; -} -.a .c, -.b .c { - test: 3; -} -.a .c .d, -.b .c .d { - test: 4; -} -.replace.replace .replace, -.c.replace + .replace .replace, -.replace.replace .c, -.c.replace + .replace .c, -.rep_ace.rep_ace .rep_ace, -.c.rep_ace + .rep_ace .rep_ace, -.rep_ace.rep_ace .c, -.c.rep_ace + .rep_ace .c { - prop: copy-paste-replace; -} -.attributes [data="test"], -.attributes .attributes .attribute-test { - extend: attributes; -} -.attributes [data], -.attributes .attributes .attribute-test2 { - extend: attributes2; -} -.attributes [data="test3"], -.attributes .attributes .attribute-test { - extend: attributes2; -} -.header .header-nav, -.footer .footer-nav { - background: red; -} -.header .header-nav:before, -.footer .footer-nav:before { - background: blue; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/extend.css b/test/Fixtures/lessjs (1.5)/expected/extend.css deleted file mode 100644 index 2895641a..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/extend.css +++ /dev/null @@ -1,76 +0,0 @@ -.error, -.badError { - border: 1px #f00; - background: #fdd; -} -.error.intrusion, -.badError.intrusion { - font-size: 1.3em; - font-weight: bold; -} -.intrusion .error, -.intrusion .badError { - display: none; -} -.badError { - border-width: 3px; -} -.foo .bar, -.foo .baz, -.ext1 .ext2 .bar, -.ext1 .ext2 .baz, -.ext3 .bar, -.ext3 .baz, -.foo .ext3, -.ext4 .bar, -.ext4 .baz, -.foo .ext4 { - display: none; -} -div.ext5, -.ext6 > .ext5, -div.ext7, -.ext6 > .ext7 { - width: 100px; -} -.ext8.ext9, -.fuu { - result: add-foo; -} -.ext8 .ext9, -.ext8 + .ext9, -.ext8 > .ext9, -.buu, -.zap, -.zoo { - result: bar-matched; -} -.ext8.nomatch { - result: none; -} -.ext8 .ext9, -.buu { - result: match-nested-bar; -} -.ext8.ext9, -.fuu { - result: match-nested-foo; -} -.aa, -.cc { - color: black; -} -.aa .dd, -.aa .ee { - background: red; -} -.bb, -.cc, -.ee, -.ff { - background: red; -} -.bb .bb, -.ff .ff { - color: black; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/extract-and-length.css b/test/Fixtures/lessjs (1.5)/expected/extract-and-length.css deleted file mode 100644 index f550e201..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/extract-and-length.css +++ /dev/null @@ -1,133 +0,0 @@ -.multiunit { - length: 6; - extract: abc "abc" 1 1px 1% #112233; -} -.incorrect-index { - v1: extract(a b c, 5); - v2: extract(a, b, c, -2); -} -.scalar { - var-value: variable; - var-length: 1; - ill-index: extract(variable, 2); - name-value: name; - string-value: "string"; - number-value: 12345678; - color-value: #0000ff; - rgba-value: rgba(80, 160, 240, 0.67); - empty-value: ; - name-length: 1; - string-length: 1; - number-length: 1; - color-length: 1; - rgba-length: 1; - empty-length: 1; -} -.mixin-arguments-1 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-2 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-3 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-4 { - length: 0; - extract: extract(, 2) | extract(, 1); -} -.mixin-arguments-2 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-3 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-4 { - length: 3; - extract: c | b; -} -.mixin-arguments-2 { - length: 4; - extract: 3 | 2 | 1; -} -.mixin-arguments-3 { - length: 4; - extract: 3 | 2 | 1; -} -.mixin-arguments-4 { - length: 3; - extract: 3 | 2; -} -.md-space-comma { - length-1: 3; - extract-1: 1 2 3; - length-2: 3; - extract-2: 2; -} -.md-space-comma-as-args-2 { - length: 3; - extract: "x" "y" "z" | 1 2 3 | a b c; -} -.md-space-comma-as-args-3 { - length: 3; - extract: "x" "y" "z" | 1 2 3 | a b c; -} -.md-space-comma-as-args-4 { - length: 2; - extract: "x" "y" "z" | 1 2 3; -} -.md-cat-space-comma { - length-1: 3; - extract-1: 1 2 3; - length-2: 3; - extract-2: 2; -} -.md-cat-space-comma-as-args-2 { - length: 3; - extract: "x" "y" "z" | 1 2 3 | a b c; -} -.md-cat-space-comma-as-args-3 { - length: 3; - extract: "x" "y" "z" | 1 2 3 | a b c; -} -.md-cat-space-comma-as-args-4 { - length: 2; - extract: "x" "y" "z" | 1 2 3; -} -.md-cat-comma-space { - length-1: 3; - extract-1: 1, 2, 3; - length-2: 3; - extract-2: 2; -} -.md-cat-comma-space-as-args-1 { - length: 3; - extract: "x", "y", "z" | 1, 2, 3 | a, b, c; -} -.md-cat-comma-space-as-args-2 { - length: 3; - extract: "x", "y", "z" | 1, 2, 3 | a, b, c; -} -.md-cat-comma-space-as-args-3 { - length: 3; - extract: "x", "y", "z" | 1, 2, 3 | a, b, c; -} -.md-cat-comma-space-as-args-4 { - length: 0; - extract: extract(, 2) | extract(, 1); -} -.md-3D { - length-1: 2; - extract-1: a b c d, 1 2 3 4; - length-2: 2; - extract-2: 5 6 7 8; - length-3: 4; - extract-3: 7; - length-4: 1; - extract-4: 8; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/functions.css b/test/Fixtures/lessjs (1.5)/expected/functions.css deleted file mode 100644 index 3d24d3d9..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/functions.css +++ /dev/null @@ -1,139 +0,0 @@ -#functions { - color: _color("evil red"); - width: increment(15); - height: undefined("self"); - border-width: add(2, 3); - variable: increment(10); - background: linear-gradient(#000000, #ffffff); -} -#built-in { - escaped: -Some::weird(#thing, y); - lighten: #ffcccc; - darken: #330000; - saturate: #203c31; - desaturate: #29332f; - greyscale: #2e2e2e; - hsl-clamp: #ffffff; - spin-p: #bf6a40; - spin-n: #bf4055; - luma-white: 100%; - luma-black: 0%; - luma-black-alpha: 0%; - luma-red: 21%; - luma-green: 72%; - luma-blue: 7%; - luma-yellow: 93%; - luma-cyan: 79%; - luma-white-alpha: 50%; - contrast-filter: contrast(30%); - saturate-filter: saturate(5%); - contrast-white: #000000; - contrast-black: #ffffff; - contrast-red: #ffffff; - contrast-green: #000000; - contrast-blue: #ffffff; - contrast-yellow: #000000; - contrast-cyan: #000000; - contrast-light: #111111; - contrast-dark: #eeeeee; - contrast-wrongorder: #111111; - contrast-light-thresh: #111111; - contrast-dark-thresh: #eeeeee; - contrast-high-thresh: #eeeeee; - contrast-low-thresh: #111111; - contrast-light-thresh-per: #111111; - contrast-dark-thresh-per: #eeeeee; - contrast-high-thresh-per: #eeeeee; - contrast-low-thresh-per: #111111; - format: "rgb(32, 128, 64)"; - format-string: "hello world"; - format-multiple: "hello earth 2"; - format-url-encode: "red is %23ff0000"; - eformat: rgb(32, 128, 64); - unitless: 12; - unit: 14em; - hue: 98; - saturation: 12%; - lightness: 95%; - hsvhue: 98; - hsvsaturation: 12%; - hsvvalue: 95%; - red: 255; - green: 255; - blue: 255; - rounded: 11; - rounded-two: 10.67; - roundedpx: 3px; - roundedpx-three: 3.333px; - rounded-percentage: 10%; - ceil: 11px; - floor: 12px; - sqrt: 5px; - pi: 3.141592653589793; - mod: 2m; - abs: 4%; - tan: 0.9004041504844098; - sin: 0.1736481914174355; - cos: 0.8438539587324921; - atan: 0.1rad; - atan: 34deg; - atan: 44.99999640000029deg; - pow: 64px; - pow: 64; - pow: 27; - min: 0; - min: min("junk", 5); - min: 3pt; - max: 3; - max: max(8%, 1cm); - percentage: 20%; - color: #ff0011; - tint: #898989; - tint-full: #ffffff; - tint-percent: #898989; - shade: #686868; - shade-full: #000000; - shade-percent: #686868; - fade-out: rgba(255, 0, 0, 0.95); - fade-in: rgba(255, 0, 0, 0.9500000000000001); - hsv: #4d2926; - hsva: rgba(77, 40, 38, 0.2); - mix: #ff3300; - mix-0: #ffff00; - mix-100: #ff0000; - mix-weightless: #ff8000; - mixt: rgba(255, 0, 0, 0.5); -} -#built-in .is-a { - color: true; - color1: true; - color2: true; - color3: true; - keyword: true; - number: true; - string: true; - pixel: true; - percent: true; - em: true; - cat: true; -} -#alpha { - alpha: rgba(153, 94, 51, 0.6); - alpha2: 0.5; - alpha3: 0; -} -#blendmodes { - multiply: #ed0000; - screen: #f600f6; - overlay: #ed0000; - softlight: #fa0000; - hardlight: #0000ed; - difference: #f600f6; - exclusion: #f600f6; - average: #7b007b; - negation: #d73131; -} -#extract-and-length { - extract: 3 2 1 C B A; - length: 6; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/ie-filters.css b/test/Fixtures/lessjs (1.5)/expected/ie-filters.css deleted file mode 100644 index 007aa536..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/ie-filters.css +++ /dev/null @@ -1,9 +0,0 @@ -.nav { - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=20); - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#333333", endColorstr="#000000", GradientType=0); -} -.evalTest1 { - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=30); - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=5); -} diff --git a/test/Fixtures/lessjs (1.5)/expected/import-inline.css b/test/Fixtures/lessjs (1.5)/expected/import-inline.css deleted file mode 100644 index f198d3c1..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/import-inline.css +++ /dev/null @@ -1,5 +0,0 @@ -this isn't very valid CSS. -@media (min-width: 600px) { - #css { color: yellow; } - -} diff --git a/test/Fixtures/lessjs (1.5)/expected/import-interpolation.css b/test/Fixtures/lessjs (1.5)/expected/import-interpolation.css deleted file mode 100644 index 16b7a150..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/import-interpolation.css +++ /dev/null @@ -1,6 +0,0 @@ -body { - width: 100%; -} -.a { - var: test; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/import-once.css b/test/Fixtures/lessjs (1.5)/expected/import-once.css deleted file mode 100644 index 2f86b3b3..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/import-once.css +++ /dev/null @@ -1,15 +0,0 @@ -#import { - color: #ff0000; -} -body { - width: 100%; -} -.test-f { - height: 10px; -} -body { - width: 100%; -} -.test-f { - height: 10px; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/import-reference.css b/test/Fixtures/lessjs (1.5)/expected/import-reference.css deleted file mode 100644 index c2d055a7..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/import-reference.css +++ /dev/null @@ -1,55 +0,0 @@ -/* - The media statement above is invalid (no selector) - We should ban invalid media queries with properties and no selector? -*/ -.visible { - color: red; -} -.visible .c { - color: green; -} -.visible { - color: green; -} -.visible:hover { - color: green; -} -.visible { - color: green; -} -.only-with-visible + .visible, -.visible + .only-with-visible, -.visible + .visible { - color: green; -} -.only-with-visible + .visible .sub, -.visible + .only-with-visible .sub, -.visible + .visible .sub { - color: green; -} -.b { - color: red; - color: green; -} -.b .c { - color: green; -} -.b:hover { - color: green; -} -.b { - color: green; -} -.b + .b { - color: green; -} -.b + .b .sub { - color: green; -} -.y { - pulled-in: yes; -} -/* comment pulled in */ -.visible { - extend: test; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/import.css b/test/Fixtures/lessjs (1.5)/expected/import.css deleted file mode 100644 index a3749181..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/import.css +++ /dev/null @@ -1,36 +0,0 @@ -@import url(http://fonts.googleapis.com/css?family=Open+Sans); -@import url(/absolute/something.css) screen and (color) and (max-width: 600px); -@import url("//ha.com/file.css") (min-width: 100px); -#import-test { - height: 10px; - color: #ff0000; - width: 10px; - height: 30%; -} -@media screen and (max-width: 600px) { - body { - width: 100%; - } -} -#import { - color: #ff0000; -} -.mixin { - height: 10px; - color: #ff0000; -} -@media screen and (max-width: 601px) { - #css { - color: yellow; - } -} -@media screen and (max-width: 602px) { - body { - width: 100%; - } -} -@media screen and (max-width: 603px) { - #css { - color: yellow; - } -} diff --git a/test/Fixtures/lessjs (1.5)/expected/javascript.css b/test/Fixtures/lessjs (1.5)/expected/javascript.css deleted file mode 100644 index ba09e148..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/javascript.css +++ /dev/null @@ -1,20 +0,0 @@ -.eval { - js: /* Sorry, can not do JavaScript evaluation in PHP... :( */; - title: /* Sorry, can not do JavaScript evaluation in PHP... :( */; - ternary: /* Sorry, can not do JavaScript evaluation in PHP... :( */; - multiline: /* Sorry, can not do JavaScript evaluation in PHP... :( */; -} -.scope { - var: /* Sorry, can not do JavaScript evaluation in PHP... :( */; - escaped: /* Sorry, can not do JavaScript evaluation in PHP... :( */; -} -.vars { - width: /* Sorry, can not do JavaScript evaluation in PHP... :( */; -} -.escape-interpol { - width: /* Sorry, can not do JavaScript evaluation in PHP... :( */; -} -.arrays { - ary: /* Sorry, can not do JavaScript evaluation in PHP... :( */; - ary1: /* Sorry, can not do JavaScript evaluation in PHP... :( */; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/lazy-eval.css b/test/Fixtures/lessjs (1.5)/expected/lazy-eval.css deleted file mode 100644 index 1adfb8f3..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/lazy-eval.css +++ /dev/null @@ -1,3 +0,0 @@ -.lazy-eval { - width: 100%; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/media.css b/test/Fixtures/lessjs (1.5)/expected/media.css deleted file mode 100644 index 607f0e44..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/media.css +++ /dev/null @@ -1,219 +0,0 @@ -@media print { - .class { - color: blue; - } - .class .sub { - width: 42; - } - .top, - header > h1 { - color: #444444; - } -} -@media screen { - body { - max-width: 480; - } -} -@media all and (device-aspect-ratio: 16 / 9) { - body { - max-width: 800px; - } -} -@media all and (orientation: portrait) { - aside { - float: none; - } -} -@media handheld and (min-width: 42), screen and (min-width: 20em) { - body { - max-width: 480px; - } -} -@media print { - body { - padding: 20px; - } - body header { - background-color: red; - } -} -@media print and (orientation: landscape) { - body { - margin-left: 20px; - } -} -@media screen { - .sidebar { - width: 300px; - } -} -@media screen and (orientation: landscape) { - .sidebar { - width: 500px; - } -} -@media a and b { - .first .second .third { - width: 300px; - } - .first .second .fourth { - width: 3; - } -} -@media a and b and c { - .first .second .third { - width: 500px; - } -} -@media a, b and c { - body { - width: 95%; - } -} -@media a and x, b and c and x, a and y, b and c and y { - body { - width: 100%; - } -} -.a { - background: black; -} -@media handheld { - .a { - background: white; - } -} -@media handheld and (max-width: 100px) { - .a { - background: red; - } -} -.b { - background: black; -} -@media handheld { - .b { - background: white; - } -} -@media handheld and (max-width: 200px) { - .b { - background: red; - } -} -@media only screen and (max-width: 200px) { - body { - width: 480px; - } -} -@media print { - @page :left { - margin: 0.5cm; - } - @page :right { - margin: 0.5cm; - } - @page Test:first { - margin: 1cm; - } - @page :first { - size: 8.5in 11in; - - @top-left { - margin: 1cm; - } - @top-left-corner { - margin: 1cm; - } - @top-center { - margin: 1cm; - } - @top-right { - margin: 1cm; - } - @top-right-corner { - margin: 1cm; - } - @bottom-left { - margin: 1cm; - } - @bottom-left-corner { - margin: 1cm; - } - @bottom-center { - margin: 1cm; - } - @bottom-right { - margin: 1cm; - } - @bottom-right-corner { - margin: 1cm; - } - @left-top { - margin: 1cm; - } - @left-middle { - margin: 1cm; - } - @left-bottom { - margin: 1cm; - } - @right-top { - margin: 1cm; - } - @right-middle { - content: "Page " counter(page); - } - @right-bottom { - margin: 1cm; - } - } -} -@media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: 2/1), (min-resolution: 2dppx), (min-resolution: 128dpcm) { - .b { - background: red; - } -} -body { - background: red; -} -@media (max-width: 500px) { - body { - background: green; - } -} -@media (max-width: 1000px) { - body { - background: red; - background: blue; - } -} -@media (max-width: 1000px) and (max-width: 500px) { - body { - background: green; - } -} -@media (max-width: 1200px) { - /* a comment */ -} -@media (max-width: 1200px) and (max-width: 900px) { - body { - font-size: 11px; - } -} -@media (min-width: 480px) { - .nav-justified > li { - display: table-cell; - } -} -@media (min-width: 768px) and (min-width: 480px) { - .menu > li { - display: table-cell; - } -} -@media all and tv { - .all-and-tv-variables { - var: all-and-tv; - } -} diff --git a/test/Fixtures/lessjs (1.5)/expected/merge.css b/test/Fixtures/lessjs (1.5)/expected/merge.css deleted file mode 100644 index 4cf8c579..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/merge.css +++ /dev/null @@ -1,22 +0,0 @@ -.test1 { - transform: rotate(90deg), skew(30deg), scale(2, 4); -} -.test2 { - transform: rotate(90deg), skew(30deg); - transform: scaleX(45deg); -} -.test3 { - transform: scaleX(45deg); - background: url(data://img1.png); -} -.test4 { - transform: rotate(90deg), skew(30deg); - transform: scale(2, 4) !important; -} -.test5 { - transform: rotate(90deg), skew(30deg); - transform: scale(2, 4) !important; -} -.test6 { - transform: scale(2, 4); -} diff --git a/test/Fixtures/lessjs (1.5)/expected/mixins-args.css b/test/Fixtures/lessjs (1.5)/expected/mixins-args.css deleted file mode 100644 index 724613ad..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/mixins-args.css +++ /dev/null @@ -1,113 +0,0 @@ -#hidden { - color: transparent; -} -#hidden1 { - color: transparent; -} -.two-args { - color: blue; - width: 10px; - height: 99%; - border: 2px dotted #000000; -} -.one-arg { - width: 15px; - height: 49%; -} -.no-parens { - width: 5px; - height: 49%; -} -.no-args { - width: 5px; - height: 49%; -} -.var-args { - width: 45; - height: 17%; -} -.multi-mix { - width: 10px; - height: 29%; - margin: 4; - padding: 5; -} -body { - padding: 30px; - color: #ff0000; -} -.scope-mix { - width: 8; -} -.content { - width: 600px; -} -.content .column { - margin: 600px; -} -#same-var-name { - radius: 5px; -} -#var-inside { - width: 10px; -} -.arguments { - border: 1px solid #000000; - width: 1px; -} -.arguments2 { - border: 0px; - width: 0px; -} -.arguments3 { - border: 0px; - width: 0px; -} -.arguments4 { - border: 0 1 2 3 4; - rest: 1 2 3 4; - width: 0; -} -.edge-case { - border: "{"; - width: "{"; -} -.slash-vs-math { - border-radius: 0.4px; - border-radius: 0.5px; - border-radius: 6px; -} -.comma-vs-semi-colon { - one: a; - two: b, c; - one: d, e; - two: f; - one: g; - one: h; - one: i; - one: j; - one: k; - two: l; - one: m, n; - one: o, p; - two: q; - one: r, s; - two: t; -} -#named-conflict { - four: a, 11, 12, 13; - four: a, 21, 22, 23; -} -.test-mixin-default-arg { - defaults: 1px 1px 1px; - defaults: 2px 2px 2px; -} -.selector { - margin: 2, 2, 2, 2; -} -.selector2 { - margin: 2, 2, 2, 2; -} -.selector3 { - margin: 4; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/mixins-closure.css b/test/Fixtures/lessjs (1.5)/expected/mixins-closure.css deleted file mode 100644 index b1021b6f..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/mixins-closure.css +++ /dev/null @@ -1,9 +0,0 @@ -.class { - width: 99px; -} -.overwrite { - width: 99px; -} -.nested .class { - width: 5px; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/mixins-guards.css b/test/Fixtures/lessjs (1.5)/expected/mixins-guards.css deleted file mode 100644 index 25e6f287..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/mixins-guards.css +++ /dev/null @@ -1,82 +0,0 @@ -.light1 { - color: white; - margin: 1px; -} -.light2 { - color: black; - margin: 1px; -} -.max1 { - width: 6; -} -.max2 { - width: 8; -} -.glob1 { - margin: auto auto; -} -.ops1 { - height: gt-or-eq; - height: lt-or-eq; - height: lt-or-eq-alias; -} -.ops2 { - height: gt-or-eq; - height: not-eq; -} -.ops3 { - height: lt-or-eq; - height: lt-or-eq-alias; - height: not-eq; -} -.default1 { - content: default; -} -.test1 { - content: "true."; -} -.test2 { - content: "false."; -} -.test3 { - content: "false."; -} -.test4 { - content: "false."; -} -.test5 { - content: "false."; -} -.bool1 { - content: true and true; - content: true; - content: false, true; - content: false and true and true, true; - content: false, true and true; - content: false, false, true; - content: false, true and true and true, false; - content: not false; - content: not false and false, not false; -} -.equality-units { - test: pass; -} -.colorguardtest { - content: is #ff0000; - content: is not #0000ff its #ff0000; - content: is not #0000ff its #800080; -} -.stringguardtest { - content: is theme1; - content: is not theme2; - content: is theme1 no quotes; -} -#tryNumberPx { - catch: all; - declare: 4; - declare: 4px; -} -.call-lock-mixin .call-inner-lock-mixin { - a: 1; - x: 1; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/mixins-important.css b/test/Fixtures/lessjs (1.5)/expected/mixins-important.css deleted file mode 100644 index b100af7f..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/mixins-important.css +++ /dev/null @@ -1,45 +0,0 @@ -.class { - border: 1; - boxer: 1; - border-width: 1; - border: 2 !important; - boxer: 2 !important; - border-width: 2 !important; - border: 3; - boxer: 3; - border-width: 3; - border: 4 !important; - boxer: 4 !important; - border-width: 4 !important; - border: 5; - boxer: 5; - border-width: 5; - border: 0 !important; - boxer: 0 !important; - border-width: 0 !important; - border: 9 !important; - border: 9; - boxer: 9; - border-width: 9; -} -.class .inner { - test: 1; -} -.class .inner { - test: 2 !important; -} -.class .inner { - test: 3; -} -.class .inner { - test: 4 !important; -} -.class .inner { - test: 5; -} -.class .inner { - test: 0 !important; -} -.class .inner { - test: 9; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/mixins-named-args.css b/test/Fixtures/lessjs (1.5)/expected/mixins-named-args.css deleted file mode 100644 index e460aa10..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/mixins-named-args.css +++ /dev/null @@ -1,27 +0,0 @@ -.named-arg { - color: blue; - width: 5px; - height: 99%; - args: 1px 100%; - text-align: center; -} -.class { - width: 5px; - height: 19%; - args: 1px 20%; -} -.all-args-wrong-args { - width: 10px; - height: 9%; - args: 2px 10%; -} -.named-args2 { - width: 15px; - height: 49%; - color: #646464; -} -.named-args3 { - width: 5px; - height: 29%; - color: #123456; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/mixins-nested.css b/test/Fixtures/lessjs (1.5)/expected/mixins-nested.css deleted file mode 100644 index 6378c475..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/mixins-nested.css +++ /dev/null @@ -1,14 +0,0 @@ -.class .inner { - height: 300; -} -.class .inner .innest { - width: 30; - border-width: 60; -} -.class2 .inner { - height: 600; -} -.class2 .inner .innest { - width: 60; - border-width: 120; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/mixins-pattern.css b/test/Fixtures/lessjs (1.5)/expected/mixins-pattern.css deleted file mode 100644 index 8b828335..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/mixins-pattern.css +++ /dev/null @@ -1,47 +0,0 @@ -.zero { - variadic: true; - zero: 0; - one: 1; - two: 2; - three: 3; -} -.one { - variadic: true; - one: 1; - one-req: 1; - two: 2; - three: 3; -} -.two { - variadic: true; - two: 2; - three: 3; -} -.three { - variadic: true; - three-req: 3; - three: 3; -} -.left { - left: 1; -} -.right { - right: 1; -} -.border-right { - color: black; - border-right: 4px; -} -.border-left { - color: black; - border-left: 4px; -} -.only-right { - right: 33; -} -.only-left { - left: 33; -} -.left-right { - both: 330; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/mixins.css b/test/Fixtures/lessjs (1.5)/expected/mixins.css deleted file mode 100644 index 32097f97..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/mixins.css +++ /dev/null @@ -1,141 +0,0 @@ -.mixin { - border: 1px solid black; -} -.mixout { - border-color: orange; -} -.borders { - border-style: dashed; -} -#namespace .borders { - border-style: dotted; -} -#namespace .biohazard { - content: "death"; -} -#namespace .biohazard .man { - color: transparent; -} -#theme > .mixin { - background-color: grey; -} -#container { - color: black; - border: 1px solid black; - border-color: orange; - background-color: grey; -} -#header .milk { - color: white; - border: 1px solid black; - background-color: grey; -} -#header #cookie { - border-style: dashed; -} -#header #cookie .chips { - border-style: dotted; -} -#header #cookie .chips .calories { - color: black; - border: 1px solid black; - border-color: orange; - background-color: grey; -} -.secure-zone { - color: transparent; -} -.direct { - border-style: dotted; -} -.bo, -.bar { - width: 100%; -} -.bo { - border: 1px; -} -.ar.bo.ca { - color: black; -} -.jo.ki { - background: none; -} -.amp.support { - color: orange; -} -.amp.support .higher { - top: 0px; -} -.amp.support.deeper { - height: auto; -} -.extended { - width: 100%; - border: 1px; - background: none; - color: orange; - top: 0px; - height: auto; -} -.extended .higher { - top: 0px; -} -.extended.deeper { - height: auto; -} -.do .re .mi .fa .sol .la .si { - color: cyan; -} -.mutli-selector-parents { - color: cyan; -} -.foo .bar { - width: 100%; -} -.underParents { - color: red; -} -.parent .underParents { - color: red; -} -* + h1 { - margin-top: 25px; -} -legend + h1 { - margin-top: 0; -} -h1 + * { - margin-top: 10px; -} -* + h2 { - margin-top: 20px; -} -legend + h2 { - margin-top: 0; -} -h2 + * { - margin-top: 8px; -} -* + h3 { - margin-top: 15px; -} -legend + h3 { - margin-top: 0; -} -h3 + * { - margin-top: 5px; -} -.error { - background-image: "/a.png"; - background-position: center center; -} -.test-rec .recursion { - color: black; -} -.button { - padding-left: 44px; -} -.button.large { - padding-left: 40em; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/no-output.css b/test/Fixtures/lessjs (1.5)/expected/no-output.css deleted file mode 100644 index 8b137891..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/no-output.css +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/Fixtures/lessjs (1.5)/expected/operations.css b/test/Fixtures/lessjs (1.5)/expected/operations.css deleted file mode 100644 index fb9e0aff..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/operations.css +++ /dev/null @@ -1,49 +0,0 @@ -#operations { - color: #111111; - height: 9px; - width: 3em; - substraction: 0; - division: 1; -} -#operations .spacing { - height: 9px; - width: 3em; -} -.with-variables { - height: 16em; - width: 24em; - size: 1cm; -} -.with-functions { - color: #646464; - color: #ff8080; - color: #c94a4a; -} -.negative { - height: 0px; - width: 4px; -} -.shorthands { - padding: -1px 2px 0 -4px; -} -.rem-dimensions { - font-size: 5.5rem; -} -.colors { - color: #123; - border-color: #334455; - background-color: #000000; -} -.colors .other { - color: #222222; - border-color: #222222; -} -.negations { - variable: -4px; - variable1: 0px; - variable2: 0px; - variable3: 8px; - variable4: 0px; - paren: -4px; - paren2: 16px; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/parens.css b/test/Fixtures/lessjs (1.5)/expected/parens.css deleted file mode 100644 index 627d70b3..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/parens.css +++ /dev/null @@ -1,33 +0,0 @@ -.parens { - border: 2px solid #000000; - margin: 1px 3px 16 3; - width: 36; - padding: 2px 36px; -} -.more-parens { - padding: 8 4 4 4px; - width-all: 96; - width-first: 96; - width-keep: 96; - height-keep: 113; - height-all: 113; - height-parts: 113; - margin-keep: 12; - margin-parts: 12; - margin-all: 12; - border-radius-keep: 5px; - border-radius-parts: 1.142857142857143px; - border-radius-all: 5px; -} -.negative { - neg-var: -1; - neg-var-paren: -1; -} -.nested-parens { - width: 71; - height: 6; -} -.mixed-units { - margin: 2px 4em 1 5pc; - padding: 6px 1em 2px 2; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/rulesets.css b/test/Fixtures/lessjs (1.5)/expected/rulesets.css deleted file mode 100644 index 408c76aa..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/rulesets.css +++ /dev/null @@ -1,33 +0,0 @@ -#first > .one { - font-size: 2em; -} -#first > .one > #second .two > #deux { - width: 50%; -} -#first > .one > #second .two > #deux #third { - height: 100%; -} -#first > .one > #second .two > #deux #third:focus { - color: black; -} -#first > .one > #second .two > #deux #third:focus #fifth > #sixth .seventh #eighth + #ninth { - color: purple; -} -#first > .one > #second .two > #deux #fourth, -#first > .one > #second .two > #deux #five, -#first > .one > #second .two > #deux #six { - color: #110000; -} -#first > .one > #second .two > #deux #fourth .seven, -#first > .one > #second .two > #deux #five .seven, -#first > .one > #second .two > #deux #six .seven, -#first > .one > #second .two > #deux #fourth .eight > #nine, -#first > .one > #second .two > #deux #five .eight > #nine, -#first > .one > #second .two > #deux #six .eight > #nine { - border: 1px solid black; -} -#first > .one > #second .two > #deux #fourth #ten, -#first > .one > #second .two > #deux #five #ten, -#first > .one > #second .two > #deux #six #ten { - color: red; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/scope.css b/test/Fixtures/lessjs (1.5)/expected/scope.css deleted file mode 100644 index baa05523..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/scope.css +++ /dev/null @@ -1,35 +0,0 @@ -.tiny-scope { - color: #998899; -} -.scope1 { - color: #0000ff; - border-color: #000000; -} -.scope1 .scope2 { - color: #0000ff; -} -.scope1 .scope2 .scope3 { - color: #ff0000; - border-color: #000000; - background-color: #ffffff; -} -.scope { - scoped-val: #008000; -} -.heightIsSet { - height: 1024px; -} -.useHeightInMixinCall { - mixin-height: 1024px; -} -.imported { - exists: true; -} -.testImported { - exists: true; -} -#allAreUsedHere { - default: 'top level'; - scope: 'top level'; - sub-scope-only: 'inside'; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/selectors.css b/test/Fixtures/lessjs (1.5)/expected/selectors.css deleted file mode 100644 index 7dd6139d..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/selectors.css +++ /dev/null @@ -1,142 +0,0 @@ -h1 a:hover, -h2 a:hover, -h3 a:hover, -h1 p:hover, -h2 p:hover, -h3 p:hover { - color: red; -} -#all { - color: blue; -} -#the { - color: blue; -} -#same { - color: blue; -} -ul, -li, -div, -q, -blockquote, -textarea { - margin: 0; -} -td { - margin: 0; - padding: 0; -} -td, -input { - line-height: 1em; -} -a { - color: red; -} -a:hover { - color: blue; -} -div a { - color: green; -} -p a span { - color: yellow; -} -.foo .bar .qux, -.foo .baz .qux { - display: block; -} -.qux .foo .bar, -.qux .foo .baz { - display: inline; -} -.qux.foo .bar, -.qux.foo .baz { - display: inline-block; -} -.qux .foo .bar .biz, -.qux .foo .baz .biz { - display: none; -} -.a.b.c { - color: red; -} -.c .b.a { - color: red; -} -.foo .p.bar { - color: red; -} -.foo.p.bar { - color: red; -} -.foo + .foo { - background: amber; -} -.foo + .foo { - background: amber; -} -.foo + .foo, -.foo + .bar, -.bar + .foo, -.bar + .bar { - background: amber; -} -.foo a > .foo a, -.foo a > .bar a, -.foo a > .foo b, -.foo a > .bar b, -.bar a > .foo a, -.bar a > .bar a, -.bar a > .foo b, -.bar a > .bar b, -.foo b > .foo a, -.foo b > .bar a, -.foo b > .foo b, -.foo b > .bar b, -.bar b > .foo a, -.bar b > .bar a, -.bar b > .foo b, -.bar b > .bar b { - background: amber; -} -.other ::fnord { - color: red; -} -.other::fnord { - color: red; -} -.other ::bnord { - color: red; -} -.other::bnord { - color: red; -} -.blood { - color: red; -} -.bloodred { - color: green; -} -#blood.blood.red.black { - color: black; -} -:nth-child(3) { - selector: interpolated; -} -.test:nth-child(odd):not(:nth-child(3)) { - color: #ff0000; -} -[prop], -[prop=10%], -[prop="value3"], -[prop*="val3"], -[|prop~="val3"], -[*|prop$="val3"], -[ns|prop^="val3"], -[3^="val3"], -[3=3], -[3] { - attributes: yes; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/strings.css b/test/Fixtures/lessjs (1.5)/expected/strings.css deleted file mode 100644 index cd6d6020..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/strings.css +++ /dev/null @@ -1,43 +0,0 @@ -#strings { - background-image: url("http://son-of-a-banana.com"); - quotes: "~" "~"; - content: "#*%:&^,)!.(~*})"; - empty: ""; - brackets: "{" "}"; - escapes: "\"hello\" \\world"; - escapes2: "\"llo"; -} -#comments { - content: "/* hello */ // not-so-secret"; -} -#single-quote { - quotes: "'" "'"; - content: '""#!&""'; - empty: ''; - semi-colon: ';'; -} -#escaped { - filter: DX.Transform.MS.BS.filter(opacity=50); -} -#one-line { - image: url(http://tooks.com); -} -#crazy { - image: url(http://), "}", url("http://}"); -} -#interpolation { - url: "http://lesscss.org/dev/image.jpg"; - url2: "http://lesscss.org/image-256.jpg"; - url3: "http://lesscss.org#445566"; - url4: "http://lesscss.org/hello"; - url5: "http://lesscss.org/54.4px"; -} -.mix-mul-class { - color: #0000ff; - color: #ff0000; - color: #000000; - color: #ffa500; -} -.watermark { - family: Univers, Arial, Verdana, San-Serif; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/urls.css b/test/Fixtures/lessjs (1.5)/expected/urls.css deleted file mode 100644 index 9ef41981..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/urls.css +++ /dev/null @@ -1,63 +0,0 @@ -@import "css/background.css"; -@import "import/import-test-d.css"; -@import "file.css"; -@font-face { - src: url("/fonts/garamond-pro.ttf"); - src: local(Futura-Medium), url(fonts.svg#MyGeometricModern) format("svg"); -} -#shorthands { - background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; - background: url("img.jpg") center / 100px; - background: #ffffff url(image.png) center / 1px 100px repeat-x scroll content-box padding-box; -} -#misc { - background-image: url(images/image.jpg); -} -#data-uri { - background: url(data:image/png;charset=utf-8;base64, - kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ - k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U - kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700); - background-image: url("http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700"); -} -#svg-data-uri { - background: transparent url('data:image/svg+xml, '); -} -.comma-delimited { - background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg); -} -.values { - url: url('Trebuchet'); -} -#logo { - width: 100px; - height: 100px; - background: url('import/assets/logo.png'); -} -@font-face { - font-family: xecret; - src: url('import/assets/xecret.ttf'); -} -#secret { - font-family: xecret, sans-serif; -} -#data-uri { - uri: url("data:image/jpeg;base64,bm90IGFjdHVhbGx5IGEganBlZyBmaWxlCg=="); -} -#data-uri-guess { - uri: url("data:image/jpeg;base64,bm90IGFjdHVhbGx5IGEganBlZyBmaWxlCg=="); -} -#data-uri-ascii { - uri-1: url("data:text/html,%3Ch1%3EThis%20page%20is%20100%25%20Awesome.%3C%2Fh1%3E%0A"); - uri-2: url("data:text/html,%3Ch1%3EThis%20page%20is%20100%25%20Awesome.%3C%2Fh1%3E%0A"); -} -#data-uri-toobig { - uri: url('../data/data-uri-fail.png'); -} -#svg-functions { - background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhZGllbnQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjwvbGluZWFyR3JhZGllbnQ+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkaWVudCkiIC8+PC9zdmc+'); - background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhZGllbnQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIvPjxzdG9wIG9mZnNldD0iMyUiIHN0b3AtY29sb3I9IiNmZmE1MDAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIGZpbGw9InVybCgjZ3JhZGllbnQpIiAvPjwvc3ZnPg=='); - background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhZGllbnQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIxJSIgc3RvcC1jb2xvcj0iI2M0YzRjNCIvPjxzdG9wIG9mZnNldD0iMyUiIHN0b3AtY29sb3I9IiNmZmE1MDAiLz48c3RvcCBvZmZzZXQ9IjUlIiBzdG9wLWNvbG9yPSIjMDA4MDAwIi8+PHN0b3Agb2Zmc2V0PSI5NSUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIGZpbGw9InVybCgjZ3JhZGllbnQpIiAvPjwvc3ZnPg=='); -} diff --git a/test/Fixtures/lessjs (1.5)/expected/variables.css b/test/Fixtures/lessjs (1.5)/expected/variables.css deleted file mode 100644 index d671bf81..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/variables.css +++ /dev/null @@ -1,45 +0,0 @@ -.variables { - width: 14cm; -} -.variables { - height: 24px; - color: #888888; - font-family: "Trebuchet MS", Verdana, sans-serif; - quotes: "~" "~"; -} -.redef { - zero: 0; -} -.redef .inition { - three: 3; -} -.values { - minus-one: -1; - font-family: 'Trebuchet', 'Trebuchet', 'Trebuchet'; - color: #888888 !important; - multi: something 'A', B, C, 'Trebuchet'; -} -.variable-names { - name: 'hello'; -} -.alpha { - filter: alpha(opacity=42); -} -.testPollution { - a: 'no-pollution'; -} -.units { - width: 1px; - same-unit-as-previously: 1px; - square-pixel-divided: 1px; - odd-unit: 2; - percentage: 500%; - pixels: 500px; - conversion-metric-a: 30mm; - conversion-metric-b: 3cm; - conversion-imperial: 3.000000551181103in; - custom-unit: 420octocats; - custom-unit-cancelling: 18dogs; - mix-units: 2px; - invalid-units: 1px; -} diff --git a/test/Fixtures/lessjs (1.5)/expected/whitespace.css b/test/Fixtures/lessjs (1.5)/expected/whitespace.css deleted file mode 100644 index bafbd90b..00000000 --- a/test/Fixtures/lessjs (1.5)/expected/whitespace.css +++ /dev/null @@ -1,42 +0,0 @@ -.whitespace { - color: white; -} -.whitespace { - color: white; -} -.whitespace { - color: white; -} -.whitespace { - color: white; -} -.whitespace { - color: white; -} -.white, -.space, -.mania { - color: white; -} -.no-semi-column { - color: white; -} -.no-semi-column { - color: white; - white-space: pre; -} -.no-semi-column { - border: 2px solid #ffffff; -} -.newlines { - background: the, - great, - wall; - border: 2px - solid - black; -} -.sel .newline_ws .tab_ws { - color: white; - background-position: 45 -23; -} diff --git a/test/Fixtures/lessjs (1.5)/less/a.less b/test/Fixtures/lessjs (1.5)/less/a.less deleted file mode 100644 index 28867995..00000000 --- a/test/Fixtures/lessjs (1.5)/less/a.less +++ /dev/null @@ -1,17 +0,0 @@ - -@var : blue; -@color: color; - -.mixin{ - @color: @var; - width:10; - width:10; - height:20; - color:red !important; - background:#000; - } - -.test{ - .mixin; - color:blue; - } diff --git a/test/Fixtures/lessjs (1.5)/less/charsets.less b/test/Fixtures/lessjs (1.5)/less/charsets.less deleted file mode 100644 index 550d40e9..00000000 --- a/test/Fixtures/lessjs (1.5)/less/charsets.less +++ /dev/null @@ -1,3 +0,0 @@ -@charset "UTF-8"; - -@import "import/import-charset-test"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/colors.less b/test/Fixtures/lessjs (1.5)/less/colors.less deleted file mode 100644 index 656ca636..00000000 --- a/test/Fixtures/lessjs (1.5)/less/colors.less +++ /dev/null @@ -1,92 +0,0 @@ -#yelow { - #short { - color: #fea; - } - #long { - color: #ffeeaa; - } - #rgba { - color: rgba(255, 238, 170, 0.1); - } - #argb { - color: argb(rgba(255, 238, 170, 0.1)); - } -} - -#blue { - #short { - color: #00f; - } - #long { - color: #0000ff; - } - #rgba { - color: rgba(0, 0, 255, 0.1); - } - #argb { - color: argb(rgba(0, 0, 255, 0.1)); - } -} - -#alpha #hsla { - color: hsla(11, 20%, 20%, 0.6); -} - -#overflow { - .a { color: (#111111 - #444444); } // #000000 - .b { color: (#eee + #fff); } // #ffffff - .c { color: (#aaa * 3); } // #ffffff - .d { color: (#00ee00 + #009900); } // #00ff00 -} - -#grey { - color: rgb(200, 200, 200); -} - -#333333 { - color: rgb(20%, 20%, 20%); -} - -#808080 { - color: hsl(50, 0%, 50%); -} - -#00ff00 { - color: hsl(120, 100%, 50%); -} - -.lightenblue { - color: lighten(blue, 10%); -} - -.darkenblue { - color: darken(blue, 10%); -} - -.unknowncolors { - color: blue2; - border: 2px solid superred; -} - -.transparent { - color: transparent; - background-color: rgba(0, 0, 0, 0); -} -#alpha { - @colorvar: rgba(150, 200, 150, 0.7); - #fromvar { - opacity: alpha(@colorvar); - } - #short { - opacity: alpha(#aaa); - } - #long { - opacity: alpha(#bababa); - } - #rgba { - opacity: alpha(rgba(50, 120, 95, 0.2)); - } - #hsl { - opacity: alpha(hsl(120, 100%, 50%)); - } -} diff --git a/test/Fixtures/lessjs (1.5)/less/comments.less b/test/Fixtures/lessjs (1.5)/less/comments.less deleted file mode 100644 index 7859911e..00000000 --- a/test/Fixtures/lessjs (1.5)/less/comments.less +++ /dev/null @@ -1,83 +0,0 @@ -/******************\ -* * -* Comment Header * -* * -\******************/ - -/* - - Comment - -*/ - -/* - * Comment Test - * - * - cloudhead (http://cloudhead.net) - * - */ - -//////////////// -@var: "content"; -//////////////// - -/* Colors - * ------ - * #EDF8FC (background blue) - * #166C89 (darkest blue) - * - * Text: - * #333 (standard text) // A comment within a comment! - * #1F9EC9 (standard link) - * - */ - -/* @group Variables -------------------- */ -#comments /* boo *//* boo again*/, -//.commented_out1 -//.commented_out2 -//.commented_out3 -.comments //end of comments1 -//end of comments2 -{ - /**/ // An empty comment - color: red; /* A C-style comment */ /* A C-style comment */ - background-color: orange; // A little comment - font-size: 12px; - - /* lost comment */ content: @var; - - border: 1px solid black; - - // padding & margin // - padding: 0; // }{ '" - margin: 2em; -} // - -/* commented out - #more-comments { - color: grey; - } -*/ - -.selector /* .with */, .lots, /* of */ .comments { - color: grey, /* blue */ orange; - -webkit-border-radius: 2px /* webkit only */; - -moz-border-radius: (2px * 4) /* moz only with operation */; -} - -.mixin_def_with_colors(@a: white, // in - @b: 1px //put in @b - causes problems! ---> - ) // the - when (@a = white) { - .test { - color: @b; - } -} -.mixin_def_with_colors(); - -#last { color: blue } -// - -/* *//* { *//* *//* *//* */#div { color:#A33; }/* } */ diff --git a/test/Fixtures/lessjs (1.5)/less/compression/compression.less b/test/Fixtures/lessjs (1.5)/less/compression/compression.less deleted file mode 100644 index e6a0fe79..00000000 --- a/test/Fixtures/lessjs (1.5)/less/compression/compression.less +++ /dev/null @@ -1,32 +0,0 @@ -#colours { - color1: #fea; - color2: #ffeeaa; - color3: rgba(255, 238, 170, 0.1); - @color1: #fea; - string: "@{color1}"; - /* comments are stripped */ - // both types! - /*! but not this type - Note preserved whitespace - */ -} -dimensions { - val: 0.1px; - val: 0em; - val: 4cm; - val: 0.2; - val: 5; - angles-must-have-unit: 0deg; - durations-must-have-unit: 0s; - length-doesnt-have-unit: 0px; - width: auto\9; -} -@page { - marks: none; -@top-left-corner { - vertical-align: top; -} -@top-left { - vertical-align: top; -} -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/css-3.less b/test/Fixtures/lessjs (1.5)/less/css-3.less deleted file mode 100644 index c31a6eb2..00000000 --- a/test/Fixtures/lessjs (1.5)/less/css-3.less +++ /dev/null @@ -1,125 +0,0 @@ -.comma-delimited { - text-shadow: -1px -1px 1px red, 6px 5px 5px yellow; - -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset, - 0pt 4px 6px rgba(255, 255, 255, 0.4) inset; - -webkit-transform: rotate(-0.0000000001deg); -} -@font-face { - font-family: Headline; - unicode-range: U+??????, U+0???, U+0-7F, U+A5; -} -.other { - -moz-transform: translate(0, 11em) rotate(-90deg); - transform: rotateX(45deg); -} -.item[data-cra_zy-attr1b-ut3=bold] { - font-weight: bold; -} -p:not([class*="lead"]) { - color: black; -} - -input[type="text"].class#id[attr=32]:not(1) { - color: white; -} - -div#id.class[a=1][b=2].class:not(1) { - color: white; -} - -ul.comma > li:not(:only-child)::after { - color: white; -} - -ol.comma > li:nth-last-child(2)::after { - color: white; -} - -li:nth-child(4n+1), -li:nth-child(-5n), -li:nth-child(-n+2) { - color: white; -} - -a[href^="http://"] { - color: black; -} - -a[href$="http://"] { - color: black; -} - -form[data-disabled] { - color: black; -} - -p::before { - color: black; -} - -#issue322 { - -webkit-animation: anim2 7s infinite ease-in-out; -} - -@-webkit-keyframes frames { - 0% { border: 1px } - 5.5% { border: 2px } - 100% { border: 3px } -} - -@keyframes fontbulger1 { - to { - font-size: 15px; - } - from,to { - font-size: 12px; - } - 0%,100% { - font-size: 12px; - } -} - -.units { - font: 1.2rem/2rem; - font: 8vw/9vw; - font: 10vh/12vh; - font: 12vm/15vm; - font: 12vmin/15vmin; - font: 1.2ch/1.5ch; -} - -@supports ( box-shadow: 2px 2px 2px black ) or - ( -moz-box-shadow: 2px 2px 2px black ) { - .outline { - box-shadow: 2px 2px 2px black; - -moz-box-shadow: 2px 2px 2px black; - } -} - -@-x-document url-prefix(""github.com"") { - h1 { - color: red; - } -} - -@viewport { - font-size: 10px; -} -@namespace foo url(http://www.example.com); - -foo|h1 { color: blue; } -foo|* { color: yellow; } -|h1 { color: red; } -*|h1 { color: green; } -h1 { color: green; } -.upper-test { - UpperCaseProperties: allowed; -} -@host { - div { - display: block; - } -} -::distributed(input::placeholder) { - color: #b3b3b3; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/css-escapes.less b/test/Fixtures/lessjs (1.5)/less/css-escapes.less deleted file mode 100644 index 6a4b2830..00000000 --- a/test/Fixtures/lessjs (1.5)/less/css-escapes.less +++ /dev/null @@ -1,33 +0,0 @@ -@ugly: fuchsia; - -.escape\|random\|char { - color: red; -} - -.mixin\!tUp { - font-weight: bold; -} - -// class="404" -.\34 04 { - background: red; - - strong { - color: @ugly; - .mixin\!tUp; - } -} - -.trailingTest\+ { - color: red; -} - -/* This hideous test of hideousness checks for the selector "blockquote" with various permutations of hex escapes */ -\62\6c\6f \63 \6B \0071 \000075o\74 e { - color: silver; -} - -[ng\:cloak], -ng\:form { - display: none; -} diff --git a/test/Fixtures/lessjs (1.5)/less/css-guards.less b/test/Fixtures/lessjs (1.5)/less/css-guards.less deleted file mode 100644 index 41fbfbf5..00000000 --- a/test/Fixtures/lessjs (1.5)/less/css-guards.less +++ /dev/null @@ -1,64 +0,0 @@ - -.light when (lightness(@a) > 50%) { - color: green; -} -.dark when (lightness(@a) < 50%) { - color: orange; -} -@a: #ddd; - -.see-the { - @a: #444; // this mirrors what mixins do - they evaluate guards at the point of execution - .light(); - .dark(); -} - -.hide-the { - .light(); - .dark(); -} - -.multiple-conditions-1 when (@b = 1), (@c = 2), (@d = 3) { - color: red; -} - -.multiple-conditions-2 when (@b = 1), (@c = 2), (@d = 2) { - color: blue; -} - -@b: 2; -@c: 3; -@d: 3; - -.inheritance when (@b = 2) { - .test { - color: black; - } - &:hover { - color: pink; - } - .hideme when (@b = 1) { - color: green; - } - & when (@b = 1) { - hideme: green; - } -} - -.hideme when (@b = 1) { - .test { - color: black; - } - &:hover { - color: pink; - } - .hideme when (@b = 1) { - color: green; - } -} - -& when (@b = 1) { - .hideme { - color: red; - } -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/css.less b/test/Fixtures/lessjs (1.5)/less/css.less deleted file mode 100644 index 766bdd4d..00000000 --- a/test/Fixtures/lessjs (1.5)/less/css.less +++ /dev/null @@ -1,108 +0,0 @@ -@charset "utf-8"; -div { color: black; } -div { width: 99%; } - -* { - min-width: 45em; -} - -h1, h2 > a > p, h3 { - color: none; -} - -div.class { - color: blue; -} - -div#id { - color: green; -} - -.class#id { - color: purple; -} - -.one.two.three { - color: grey; -} - -@media print { - * { - font-size: 3em; - } -} - -@media screen { - * { - font-size: 10px; - } -} - -@font-face { - font-family: 'Garamond Pro'; -} - -a:hover, a:link { - color: #999; -} - -p, p:first-child { - text-transform: none; -} - -q:lang(no) { - quotes: none; -} - -p + h1 { - font-size: +2.2em; -} - -#shorthands { - border: 1px solid #000; - font: 12px/16px Arial; - font: 100%/16px Arial; - margin: 1px 0; - padding: 0 auto; -} - -#more-shorthands { - margin: 0; - padding: 1px 0 2px 0; - font: normal small/20px 'Trebuchet MS', Verdana, sans-serif; - font: 0/0 a; - border-radius: 5px / 10px; -} - -.misc { - -moz-border-radius: 2px; - display: -moz-inline-stack; - width: .1em; - background-color: #009998; - background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue)); - margin: ; - .nested-multiple { - multiple-semi-colons: yes;;;;;; - }; - filter: alpha(opacity=100); - width: auto\9; -} - -#important { - color: red !important; - width: 100%!important; - height: 20px ! important; -} - -.def-font(@name) { - @font-face { - font-family: @name - } -} - -.def-font(font-a); -.def-font(font-b); - -.æøå { - margin: 0; -} diff --git a/test/Fixtures/lessjs (1.5)/less/debug/import/test.less b/test/Fixtures/lessjs (1.5)/less/debug/import/test.less deleted file mode 100644 index 795082f5..00000000 --- a/test/Fixtures/lessjs (1.5)/less/debug/import/test.less +++ /dev/null @@ -1,25 +0,0 @@ -@charset "ISO-8859-1"; - -.mixin_import1() { - @media all { - .tst { - color: black; - @media screen { - color: red; - .tst3 { - color: white; - } - } - } - } -} - -.mixin_import2() { - .tst2 { - color: white; - } -} - -.tst3 { - color: grey; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/debug/linenumbers.less b/test/Fixtures/lessjs (1.5)/less/debug/linenumbers.less deleted file mode 100644 index 172ba028..00000000 --- a/test/Fixtures/lessjs (1.5)/less/debug/linenumbers.less +++ /dev/null @@ -1,23 +0,0 @@ -@charset "UTF-8"; - -@import "import/test.less"; - -.start() { - .test2 { - color: red; - } -} - -.mix() { - color: black; -} - -.test1 { - .mix(); -} - -.start(); - -.mixin_import1(); - -.mixin_import2(); \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/add-mixed-units.less b/test/Fixtures/lessjs (1.5)/less/errors/add-mixed-units.less deleted file mode 100644 index 9b708de9..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/add-mixed-units.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - error: (1px + 3em); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/add-mixed-units.txt b/test/Fixtures/lessjs (1.5)/less/errors/add-mixed-units.txt deleted file mode 100644 index b5553618..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/add-mixed-units.txt +++ /dev/null @@ -1,2 +0,0 @@ -SyntaxError: Incompatible units. Change the units or use the unit function. Bad units: 'px' and 'em'. in {path}add-mixed-units.less on line null, column 0: -1 error: (1px + 3em); diff --git a/test/Fixtures/lessjs (1.5)/less/errors/add-mixed-units2.less b/test/Fixtures/lessjs (1.5)/less/errors/add-mixed-units2.less deleted file mode 100644 index 26631160..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/add-mixed-units2.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - error: ((1px * 2px) + (3em * 3px)); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/add-mixed-units2.txt b/test/Fixtures/lessjs (1.5)/less/errors/add-mixed-units2.txt deleted file mode 100644 index cc65a760..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/add-mixed-units2.txt +++ /dev/null @@ -1,2 +0,0 @@ -SyntaxError: Incompatible units. Change the units or use the unit function. Bad units: 'px*px' and 'em*px'. in {path}add-mixed-units2.less on line null, column 0: -1 error: ((1px * 2px) + (3em * 3px)); diff --git a/test/Fixtures/lessjs (1.5)/less/errors/bad-variable-declaration1.less b/test/Fixtures/lessjs (1.5)/less/errors/bad-variable-declaration1.less deleted file mode 100644 index c2dc6ac0..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/bad-variable-declaration1.less +++ /dev/null @@ -1 +0,0 @@ -@@demo: "hi"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/bad-variable-declaration1.txt b/test/Fixtures/lessjs (1.5)/less/errors/bad-variable-declaration1.txt deleted file mode 100644 index 5ae9d4a4..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/bad-variable-declaration1.txt +++ /dev/null @@ -1,2 +0,0 @@ -ParseError: Unrecognised input in {path}bad-variable-declaration1.less on line 1, column 1: -1 @@demo: "hi"; diff --git a/test/Fixtures/lessjs (1.5)/less/errors/color-func-invalid-color.less b/test/Fixtures/lessjs (1.5)/less/errors/color-func-invalid-color.less deleted file mode 100644 index 5a1edd01..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/color-func-invalid-color.less +++ /dev/null @@ -1,3 +0,0 @@ -.test { - color: color("NOT A COLOR"); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/color-func-invalid-color.txt b/test/Fixtures/lessjs (1.5)/less/errors/color-func-invalid-color.txt deleted file mode 100644 index 08990c30..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/color-func-invalid-color.txt +++ /dev/null @@ -1,4 +0,0 @@ -ArgumentError: error evaluating function `color`: argument must be a color keyword or 3/6 digit hex e.g. #FFF in {path}color-func-invalid-color.less on line 2, column 10: -1 .test { -2 color: color("NOT A COLOR"); -3 } diff --git a/test/Fixtures/lessjs (1.5)/less/errors/color-operation-error.less b/test/Fixtures/lessjs (1.5)/less/errors/color-operation-error.less deleted file mode 100644 index 7c60c004..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/color-operation-error.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - prop: (3 / #fff); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/color-operation-error.txt b/test/Fixtures/lessjs (1.5)/less/errors/color-operation-error.txt deleted file mode 100644 index 1b3f889f..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/color-operation-error.txt +++ /dev/null @@ -1,2 +0,0 @@ -OperationError: Can't substract or divide a color from a number in {path}color-operation-error.less on line null, column 0: -1 prop: (3 / #fff); diff --git a/test/Fixtures/lessjs (1.5)/less/errors/comment-in-selector.less b/test/Fixtures/lessjs (1.5)/less/errors/comment-in-selector.less deleted file mode 100644 index a7d26396..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/comment-in-selector.less +++ /dev/null @@ -1 +0,0 @@ -#gaga /* Comment */ span { color: red } \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/comment-in-selector.txt b/test/Fixtures/lessjs (1.5)/less/errors/comment-in-selector.txt deleted file mode 100644 index e48f878c..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/comment-in-selector.txt +++ /dev/null @@ -1,2 +0,0 @@ -ParseError: Unrecognised input in {path}comment-in-selector.less on line 1, column 21: -1 #gaga /* Comment */ span { color: red } diff --git a/test/Fixtures/lessjs (1.5)/less/errors/divide-mixed-units.less b/test/Fixtures/lessjs (1.5)/less/errors/divide-mixed-units.less deleted file mode 100644 index d228b7c4..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/divide-mixed-units.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - error: (1px / 3em); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/divide-mixed-units.txt b/test/Fixtures/lessjs (1.5)/less/errors/divide-mixed-units.txt deleted file mode 100644 index c189d2aa..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/divide-mixed-units.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: Multiple units in dimension. Correct the units or use the unit function. Bad unit: px/em in {path}divide-mixed-units.less on line 2, column 3: -1 .a { -2 error: (1px / 3em); -3 } diff --git a/test/Fixtures/lessjs (1.5)/less/errors/extend-no-selector.less b/test/Fixtures/lessjs (1.5)/less/errors/extend-no-selector.less deleted file mode 100644 index 84689ef3..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/extend-no-selector.less +++ /dev/null @@ -1,3 +0,0 @@ -:extend(.a all) { - property: red; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/extend-no-selector.txt b/test/Fixtures/lessjs (1.5)/less/errors/extend-no-selector.txt deleted file mode 100644 index bd2e3cd7..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/extend-no-selector.txt +++ /dev/null @@ -1,3 +0,0 @@ -SyntaxError: Extend must be used to extend a selector, it cannot be used on its own in {path}extend-no-selector.less on line 1, column 17: -1 :extend(.a all) { -2 property: red; diff --git a/test/Fixtures/lessjs (1.5)/less/errors/extend-not-at-end.less b/test/Fixtures/lessjs (1.5)/less/errors/extend-not-at-end.less deleted file mode 100644 index 90ee512c..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/extend-not-at-end.less +++ /dev/null @@ -1,3 +0,0 @@ -.a:extend(.b all).c { - property: red; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/extend-not-at-end.txt b/test/Fixtures/lessjs (1.5)/less/errors/extend-not-at-end.txt deleted file mode 100644 index 32ebedfc..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/extend-not-at-end.txt +++ /dev/null @@ -1,3 +0,0 @@ -SyntaxError: Extend can only be used at the end of selector in {path}extend-not-at-end.less on line 1, column 21: -1 .a:extend(.b all).c { -2 property: red; diff --git a/test/Fixtures/lessjs (1.5)/less/errors/import-missing.less b/test/Fixtures/lessjs (1.5)/less/errors/import-missing.less deleted file mode 100644 index 5ce8e4d9..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/import-missing.less +++ /dev/null @@ -1,6 +0,0 @@ -.a { - color: green; - // tests line number for import reference is correct -} - -@import "file-does-not-exist.less"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/import-missing.txt b/test/Fixtures/lessjs (1.5)/less/errors/import-missing.txt deleted file mode 100644 index 488d154a..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/import-missing.txt +++ /dev/null @@ -1,3 +0,0 @@ -FileError: '{pathhref}file-does-not-exist.less' wasn't found{404status} in {path}import-missing.less on line 6, column 1: -5 -6 @import "file-does-not-exist.less"; diff --git a/test/Fixtures/lessjs (1.5)/less/errors/import-no-semi.less b/test/Fixtures/lessjs (1.5)/less/errors/import-no-semi.less deleted file mode 100644 index bf2c7f65..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/import-no-semi.less +++ /dev/null @@ -1 +0,0 @@ -@import "this-statement-is-invalid.less" \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/import-no-semi.txt b/test/Fixtures/lessjs (1.5)/less/errors/import-no-semi.txt deleted file mode 100644 index 8b3f795c..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/import-no-semi.txt +++ /dev/null @@ -1,2 +0,0 @@ -ParseError: Unrecognised input in {path}import-no-semi.less on line 1, column 1: -1 @import "this-statement-is-invalid.less" diff --git a/test/Fixtures/lessjs (1.5)/less/errors/import-subfolder1.less b/test/Fixtures/lessjs (1.5)/less/errors/import-subfolder1.less deleted file mode 100644 index 4280673b..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/import-subfolder1.less +++ /dev/null @@ -1 +0,0 @@ -@import "imports/import-subfolder1.less"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/import-subfolder1.txt b/test/Fixtures/lessjs (1.5)/less/errors/import-subfolder1.txt deleted file mode 100644 index 97629276..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/import-subfolder1.txt +++ /dev/null @@ -1,3 +0,0 @@ -NameError: .mixin-not-defined is undefined in {path}mixin-not-defined.less on line 11, column 1: -10 -11 .mixin-not-defined(); diff --git a/test/Fixtures/lessjs (1.5)/less/errors/import-subfolder2.less b/test/Fixtures/lessjs (1.5)/less/errors/import-subfolder2.less deleted file mode 100644 index a6b9b9ce..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/import-subfolder2.less +++ /dev/null @@ -1 +0,0 @@ -@import "imports/import-subfolder2.less"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/import-subfolder2.txt b/test/Fixtures/lessjs (1.5)/less/errors/import-subfolder2.txt deleted file mode 100644 index 7d514efc..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/import-subfolder2.txt +++ /dev/null @@ -1,2 +0,0 @@ -ParseError: missing opening `{` in {path}parse-error-curly-bracket.less on line 1, column 2: -1 }} diff --git a/test/Fixtures/lessjs (1.5)/less/errors/imports/import-subfolder1.less b/test/Fixtures/lessjs (1.5)/less/errors/imports/import-subfolder1.less deleted file mode 100644 index 24ec0532..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/imports/import-subfolder1.less +++ /dev/null @@ -1 +0,0 @@ -@import "subfolder/mixin-not-defined.less"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/imports/import-subfolder2.less b/test/Fixtures/lessjs (1.5)/less/errors/imports/import-subfolder2.less deleted file mode 100644 index 6058ad14..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/imports/import-subfolder2.less +++ /dev/null @@ -1 +0,0 @@ -@import "subfolder/parse-error-curly-bracket.less"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/imports/import-test.less b/test/Fixtures/lessjs (1.5)/less/errors/imports/import-test.less deleted file mode 100644 index a91ae054..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/imports/import-test.less +++ /dev/null @@ -1,4 +0,0 @@ -.someclass -{ - font-weight: bold; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/imports/subfolder/mixin-not-defined.less b/test/Fixtures/lessjs (1.5)/less/errors/imports/subfolder/mixin-not-defined.less deleted file mode 100644 index 2bb2d091..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/imports/subfolder/mixin-not-defined.less +++ /dev/null @@ -1 +0,0 @@ -@import "../../mixin-not-defined.less"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/imports/subfolder/parse-error-curly-bracket.less b/test/Fixtures/lessjs (1.5)/less/errors/imports/subfolder/parse-error-curly-bracket.less deleted file mode 100644 index f37fa9d0..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/imports/subfolder/parse-error-curly-bracket.less +++ /dev/null @@ -1 +0,0 @@ -@import "../../parse-error-curly-bracket.less"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/javascript-error.less b/test/Fixtures/lessjs (1.5)/less/errors/javascript-error.less deleted file mode 100644 index 9cffb9ff..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/javascript-error.less +++ /dev/null @@ -1,3 +0,0 @@ -.scope { - var: `this.foo.toJS()`; -} diff --git a/test/Fixtures/lessjs (1.5)/less/errors/javascript-error.txt b/test/Fixtures/lessjs (1.5)/less/errors/javascript-error.txt deleted file mode 100644 index 3c83a966..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/javascript-error.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: JavaScript evaluation error: 'TypeError: Cannot call method 'toJS' of undefined' in {path}javascript-error.less on line 2, column 27: -1 .scope { -2 var: `this.foo.toJS()`; -3 } diff --git a/test/Fixtures/lessjs (1.5)/less/errors/mixed-mixin-definition-args-1.less b/test/Fixtures/lessjs (1.5)/less/errors/mixed-mixin-definition-args-1.less deleted file mode 100644 index 9b0e23af..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/mixed-mixin-definition-args-1.less +++ /dev/null @@ -1,6 +0,0 @@ -.mixin(@a : 4, @b : 3, @c: 2) { - will: fail; -} -.mixin-test { - .mixin(@a: 5; @b: 6, @c: 7); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/mixed-mixin-definition-args-1.txt b/test/Fixtures/lessjs (1.5)/less/errors/mixed-mixin-definition-args-1.txt deleted file mode 100644 index a07f5e9d..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/mixed-mixin-definition-args-1.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: Cannot mix ; and , as delimiter types in {path}mixed-mixin-definition-args-1.less on line 5, column 30: -4 .mixin-test { -5 .mixin(@a: 5; @b: 6, @c: 7); -6 } diff --git a/test/Fixtures/lessjs (1.5)/less/errors/mixed-mixin-definition-args-2.less b/test/Fixtures/lessjs (1.5)/less/errors/mixed-mixin-definition-args-2.less deleted file mode 100644 index c9709427..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/mixed-mixin-definition-args-2.less +++ /dev/null @@ -1,6 +0,0 @@ -.mixin(@a : 4, @b : 3, @c: 2) { - will: fail; -} -.mixin-test { - .mixin(@a: 5, @b: 6; @c: 7); -} diff --git a/test/Fixtures/lessjs (1.5)/less/errors/mixed-mixin-definition-args-2.txt b/test/Fixtures/lessjs (1.5)/less/errors/mixed-mixin-definition-args-2.txt deleted file mode 100644 index fa00183b..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/mixed-mixin-definition-args-2.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: Cannot mix ; and , as delimiter types in {path}mixed-mixin-definition-args-2.less on line 5, column 26: -4 .mixin-test { -5 .mixin(@a: 5, @b: 6; @c: 7); -6 } diff --git a/test/Fixtures/lessjs (1.5)/less/errors/mixin-not-defined.less b/test/Fixtures/lessjs (1.5)/less/errors/mixin-not-defined.less deleted file mode 100644 index e2dad5ce..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/mixin-not-defined.less +++ /dev/null @@ -1,11 +0,0 @@ - -.error-is-further-on() { -} - -.pad-here-to-reproduce-error-in() { -} - -.the-import-subfolder-test() { -} - -.mixin-not-defined(); \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/mixin-not-defined.txt b/test/Fixtures/lessjs (1.5)/less/errors/mixin-not-defined.txt deleted file mode 100644 index 97629276..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/mixin-not-defined.txt +++ /dev/null @@ -1,3 +0,0 @@ -NameError: .mixin-not-defined is undefined in {path}mixin-not-defined.less on line 11, column 1: -10 -11 .mixin-not-defined(); diff --git a/test/Fixtures/lessjs (1.5)/less/errors/mixin-not-matched.less b/test/Fixtures/lessjs (1.5)/less/errors/mixin-not-matched.less deleted file mode 100644 index be0d6b1a..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/mixin-not-matched.less +++ /dev/null @@ -1,6 +0,0 @@ -@saxofon:trumpete; - -.mixin(saxofon) { -} - -.mixin(@saxofon); \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/mixin-not-matched.txt b/test/Fixtures/lessjs (1.5)/less/errors/mixin-not-matched.txt deleted file mode 100644 index 57df9772..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/mixin-not-matched.txt +++ /dev/null @@ -1,3 +0,0 @@ -RuntimeError: No matching definition was found for `.mixin(trumpete)` in {path}mixin-not-matched.less on line 6, column 1: -5 -6 .mixin(@saxofon); diff --git a/test/Fixtures/lessjs (1.5)/less/errors/mixin-not-matched2.less b/test/Fixtures/lessjs (1.5)/less/errors/mixin-not-matched2.less deleted file mode 100644 index 14f44bf3..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/mixin-not-matched2.less +++ /dev/null @@ -1,6 +0,0 @@ -@saxofon:trumpete; - -.mixin(@a, @b) { -} - -.mixin(@a: @saxofon); \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/mixin-not-matched2.txt b/test/Fixtures/lessjs (1.5)/less/errors/mixin-not-matched2.txt deleted file mode 100644 index dceedaf0..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/mixin-not-matched2.txt +++ /dev/null @@ -1,3 +0,0 @@ -RuntimeError: No matching definition was found for `.mixin(@a:trumpete)` in {path}mixin-not-matched2.less on line 6, column 1: -5 -6 .mixin(@a: @saxofon); diff --git a/test/Fixtures/lessjs (1.5)/less/errors/multiple-guards-on-css-selectors.less b/test/Fixtures/lessjs (1.5)/less/errors/multiple-guards-on-css-selectors.less deleted file mode 100644 index 4eabb60a..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/multiple-guards-on-css-selectors.less +++ /dev/null @@ -1,4 +0,0 @@ -@ie8: true; -.a when (@ie8 = true), -.b { -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/multiple-guards-on-css-selectors.txt b/test/Fixtures/lessjs (1.5)/less/errors/multiple-guards-on-css-selectors.txt deleted file mode 100644 index 3d23e26b..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/multiple-guards-on-css-selectors.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: Guards are only currently allowed on a single selector. in {path}multiple-guards-on-css-selectors.less on line 3, column 1: -2 .a when (@ie8 = true), -3 .b { -4 } diff --git a/test/Fixtures/lessjs (1.5)/less/errors/multiply-mixed-units.less b/test/Fixtures/lessjs (1.5)/less/errors/multiply-mixed-units.less deleted file mode 100644 index ff983a85..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/multiply-mixed-units.less +++ /dev/null @@ -1,7 +0,0 @@ -/* Test */ -#blah { - // blah -} -.a { - error: (1px * 1em); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/multiply-mixed-units.txt b/test/Fixtures/lessjs (1.5)/less/errors/multiply-mixed-units.txt deleted file mode 100644 index 9ed834f1..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/multiply-mixed-units.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: Multiple units in dimension. Correct the units or use the unit function. Bad unit: em*px in {path}multiply-mixed-units.less on line 6, column 3: -5 .a { -6 error: (1px * 1em); -7 } diff --git a/test/Fixtures/lessjs (1.5)/less/errors/parens-error-1.less b/test/Fixtures/lessjs (1.5)/less/errors/parens-error-1.less deleted file mode 100644 index 7c8ec10e..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/parens-error-1.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - something: (12 (13 + 5 -23) + 5); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/parens-error-1.txt b/test/Fixtures/lessjs (1.5)/less/errors/parens-error-1.txt deleted file mode 100644 index 6fc40ac0..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/parens-error-1.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: expected ')' got '(' in {path}parens-error-1.less on line 2, column 18: -1 .a { -2 something: (12 (13 + 5 -23) + 5); -3 } diff --git a/test/Fixtures/lessjs (1.5)/less/errors/parens-error-2.less b/test/Fixtures/lessjs (1.5)/less/errors/parens-error-2.less deleted file mode 100644 index 4a392b8e..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/parens-error-2.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - something: (12 * (13 + 5 -23)); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/parens-error-2.txt b/test/Fixtures/lessjs (1.5)/less/errors/parens-error-2.txt deleted file mode 100644 index cee5c52d..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/parens-error-2.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: expected ')' got '-' in {path}parens-error-2.less on line 2, column 28: -1 .a { -2 something: (12 * (13 + 5 -23)); -3 } diff --git a/test/Fixtures/lessjs (1.5)/less/errors/parens-error-3.less b/test/Fixtures/lessjs (1.5)/less/errors/parens-error-3.less deleted file mode 100644 index 9e6d5405..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/parens-error-3.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - something: (12 + (13 + 10 -23)); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/parens-error-3.txt b/test/Fixtures/lessjs (1.5)/less/errors/parens-error-3.txt deleted file mode 100644 index 3280ef04..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/parens-error-3.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: expected ')' got '-' in {path}parens-error-3.less on line 2, column 29: -1 .a { -2 something: (12 + (13 + 10 -23)); -3 } diff --git a/test/Fixtures/lessjs (1.5)/less/errors/parse-error-curly-bracket.less b/test/Fixtures/lessjs (1.5)/less/errors/parse-error-curly-bracket.less deleted file mode 100644 index a2950a11..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/parse-error-curly-bracket.less +++ /dev/null @@ -1 +0,0 @@ -}} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/parse-error-curly-bracket.txt b/test/Fixtures/lessjs (1.5)/less/errors/parse-error-curly-bracket.txt deleted file mode 100644 index 7d514efc..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/parse-error-curly-bracket.txt +++ /dev/null @@ -1,2 +0,0 @@ -ParseError: missing opening `{` in {path}parse-error-curly-bracket.less on line 1, column 2: -1 }} diff --git a/test/Fixtures/lessjs (1.5)/less/errors/parse-error-missing-bracket.less b/test/Fixtures/lessjs (1.5)/less/errors/parse-error-missing-bracket.less deleted file mode 100644 index 144a6edf..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/parse-error-missing-bracket.less +++ /dev/null @@ -1,2 +0,0 @@ -body { - background-color: #fff; diff --git a/test/Fixtures/lessjs (1.5)/less/errors/parse-error-missing-bracket.txt b/test/Fixtures/lessjs (1.5)/less/errors/parse-error-missing-bracket.txt deleted file mode 100644 index 0005f464..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/parse-error-missing-bracket.txt +++ /dev/null @@ -1,3 +0,0 @@ -ParseError: missing closing `}` in {path}parse-error-missing-bracket.less on line 3, column 1: -2 background-color: #fff; -3 diff --git a/test/Fixtures/lessjs (1.5)/less/errors/parse-error-with-import.less b/test/Fixtures/lessjs (1.5)/less/errors/parse-error-with-import.less deleted file mode 100644 index 6be3de85..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/parse-error-with-import.less +++ /dev/null @@ -1,13 +0,0 @@ -@import 'import/import-test.less'; - -body -{ - font-family: arial, sans-serif; -} - -nonsense; - -.clickable -{ - cursor: pointer; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/parse-error-with-import.txt b/test/Fixtures/lessjs (1.5)/less/errors/parse-error-with-import.txt deleted file mode 100644 index 07732c92..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/parse-error-with-import.txt +++ /dev/null @@ -1,4 +0,0 @@ -ParseError: Unrecognised input in {path}parse-error-with-import.less on line 8, column 9: -7 -8 nonsense; -9 diff --git a/test/Fixtures/lessjs (1.5)/less/errors/property-ie5-hack.less b/test/Fixtures/lessjs (1.5)/less/errors/property-ie5-hack.less deleted file mode 100644 index 51bf6e39..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/property-ie5-hack.less +++ /dev/null @@ -1,3 +0,0 @@ -.test { - display/*/: block; /*sorry for IE5*/ -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/property-ie5-hack.txt b/test/Fixtures/lessjs (1.5)/less/errors/property-ie5-hack.txt deleted file mode 100644 index e42ef90e..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/property-ie5-hack.txt +++ /dev/null @@ -1,4 +0,0 @@ -ParseError: Unrecognised input in {path}property-ie5-hack.less on line 2, column 3: -1 .test { -2 display/*/: block; /*sorry for IE5*/ -3 } diff --git a/test/Fixtures/lessjs (1.5)/less/errors/property-in-root.less b/test/Fixtures/lessjs (1.5)/less/errors/property-in-root.less deleted file mode 100644 index 8fed4be3..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/property-in-root.less +++ /dev/null @@ -1,4 +0,0 @@ -.a() { - prop:1; -} -.a(); \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/property-in-root.txt b/test/Fixtures/lessjs (1.5)/less/errors/property-in-root.txt deleted file mode 100644 index 04b27766..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/property-in-root.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: properties must be inside selector blocks, they cannot be in the root. in {path}property-in-root.less on line 2, column 3: -1 .a() { -2 prop:1; -3 } diff --git a/test/Fixtures/lessjs (1.5)/less/errors/property-in-root2.less b/test/Fixtures/lessjs (1.5)/less/errors/property-in-root2.less deleted file mode 100644 index ce8656d1..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/property-in-root2.less +++ /dev/null @@ -1 +0,0 @@ -@import "property-in-root"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/property-in-root2.txt b/test/Fixtures/lessjs (1.5)/less/errors/property-in-root2.txt deleted file mode 100644 index 04b27766..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/property-in-root2.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: properties must be inside selector blocks, they cannot be in the root. in {path}property-in-root.less on line 2, column 3: -1 .a() { -2 prop:1; -3 } diff --git a/test/Fixtures/lessjs (1.5)/less/errors/property-in-root3.less b/test/Fixtures/lessjs (1.5)/less/errors/property-in-root3.less deleted file mode 100644 index 056c2f72..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/property-in-root3.less +++ /dev/null @@ -1,4 +0,0 @@ -prop:1; -.a { - prop:1; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/property-in-root3.txt b/test/Fixtures/lessjs (1.5)/less/errors/property-in-root3.txt deleted file mode 100644 index 68ef9454..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/property-in-root3.txt +++ /dev/null @@ -1,3 +0,0 @@ -SyntaxError: properties must be inside selector blocks, they cannot be in the root. in {path}property-in-root3.less on line 1, column 1: -1 prop:1; -2 .a { diff --git a/test/Fixtures/lessjs (1.5)/less/errors/recursive-variable.less b/test/Fixtures/lessjs (1.5)/less/errors/recursive-variable.less deleted file mode 100644 index c1ca75f1..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/recursive-variable.less +++ /dev/null @@ -1 +0,0 @@ -@bodyColor: darken(@bodyColor, 30%); \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/recursive-variable.txt b/test/Fixtures/lessjs (1.5)/less/errors/recursive-variable.txt deleted file mode 100644 index eb616e7d..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/recursive-variable.txt +++ /dev/null @@ -1,2 +0,0 @@ -NameError: Recursive variable definition for @bodyColor in {path}recursive-variable.less on line 1, column 20: -1 @bodyColor: darken(@bodyColor, 30%); diff --git a/test/Fixtures/lessjs (1.5)/less/errors/svg-gradient1.less b/test/Fixtures/lessjs (1.5)/less/errors/svg-gradient1.less deleted file mode 100644 index c069ff72..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/svg-gradient1.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - a: svg-gradient(horizontal, black, white); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/svg-gradient1.txt b/test/Fixtures/lessjs (1.5)/less/errors/svg-gradient1.txt deleted file mode 100644 index ec662fe6..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/svg-gradient1.txt +++ /dev/null @@ -1,4 +0,0 @@ -ArgumentError: error evaluating function `svg-gradient`: svg-gradient direction must be 'to bottom', 'to right', 'to bottom right', 'to top right' or 'ellipse at center' in {path}svg-gradient1.less on line 2, column 6: -1 .a { -2 a: svg-gradient(horizontal, black, white); -3 } diff --git a/test/Fixtures/lessjs (1.5)/less/errors/svg-gradient2.less b/test/Fixtures/lessjs (1.5)/less/errors/svg-gradient2.less deleted file mode 100644 index ff14ef11..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/svg-gradient2.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - a: svg-gradient(to bottom, black, orange, 45%, white); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/svg-gradient2.txt b/test/Fixtures/lessjs (1.5)/less/errors/svg-gradient2.txt deleted file mode 100644 index 7004115f..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/svg-gradient2.txt +++ /dev/null @@ -1,4 +0,0 @@ -ArgumentError: error evaluating function `svg-gradient`: svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position] in {path}svg-gradient2.less on line 2, column 6: -1 .a { -2 a: svg-gradient(to bottom, black, orange, 45%, white); -3 } diff --git a/test/Fixtures/lessjs (1.5)/less/errors/svg-gradient3.less b/test/Fixtures/lessjs (1.5)/less/errors/svg-gradient3.less deleted file mode 100644 index 8f185246..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/svg-gradient3.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - a: svg-gradient(black, orange); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/svg-gradient3.txt b/test/Fixtures/lessjs (1.5)/less/errors/svg-gradient3.txt deleted file mode 100644 index eb0b483e..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/svg-gradient3.txt +++ /dev/null @@ -1,4 +0,0 @@ -ArgumentError: error evaluating function `svg-gradient`: svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position] in {path}svg-gradient3.less on line 2, column 6: -1 .a { -2 a: svg-gradient(black, orange); -3 } diff --git a/test/Fixtures/lessjs (1.5)/less/errors/unit-function.less b/test/Fixtures/lessjs (1.5)/less/errors/unit-function.less deleted file mode 100644 index 119e9818..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/unit-function.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - font-size: unit(80/16,rem); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/errors/unit-function.txt b/test/Fixtures/lessjs (1.5)/less/errors/unit-function.txt deleted file mode 100644 index baf90f42..00000000 --- a/test/Fixtures/lessjs (1.5)/less/errors/unit-function.txt +++ /dev/null @@ -1,4 +0,0 @@ -ArgumentError: error evaluating function `unit`: the first argument to unit must be a number. Have you forgotten parenthesis? in {path}unit-function.less on line 2, column 14: -1 .a { -2 font-size: unit(80/16,rem); -3 } diff --git a/test/Fixtures/lessjs (1.5)/less/extend-chaining.less b/test/Fixtures/lessjs (1.5)/less/extend-chaining.less deleted file mode 100644 index aad221ea..00000000 --- a/test/Fixtures/lessjs (1.5)/less/extend-chaining.less +++ /dev/null @@ -1,91 +0,0 @@ -//very simple chaining -.a { - color: black; -} -.b:extend(.a) {} -.c:extend(.b) {} - -//very simple chaining, ordering not important - -.d:extend(.e) {} -.e:extend(.f) {} -.f { - color: black; -} - -//extend with all - -.g.h { - color: black; -} -.i.j:extend(.g all) { - color: white; -} -.k:extend(.i all) {} - -//extend multi-chaining - -.l { - color: black; -} -.m:extend(.l){} -.n:extend(.m){} -.o:extend(.n){} -.p:extend(.o){} -.q:extend(.p){} -.r:extend(.q){} -.s:extend(.r){} -.t:extend(.s){} - -// self referencing is ignored - -.u {color: black;} -.v.u.v:extend(.u all){} - -// circular reference because the new extend product will match the existing extend - -.w:extend(.w) {color: black;} -.v.w.v:extend(.w all){} - -// classic circular references - -.x:extend(.z) { - color: x; -} -.y:extend(.x) { - color: y; -} -.z:extend(.y) { - color: z; -} - -//very simple chaining, but with the extend inside the ruleset -.va { - color: black; -} -.vb { - &:extend(.va); - color: white; -} -.vc { - &:extend(.vb); -} - -// media queries - dont extend outside, do extend inside - -@media tv { - .ma:extend(.a,.b,.c,.d,.e,.f,.g,.h,.i,.j,.k,.l,.m,.n,.o,.p,.q,.r,.s,.t,.u,.v,.w,.x,.y,.z,.md) { - color: black; - } - .md { - color: white; - } - @media plasma { - .me, .mf { - &:extend(.mb,.md); - background: red; - } - } -} -.mb:extend(.ma) {}; -.mc:extend(.mb) {}; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/extend-clearfix.less b/test/Fixtures/lessjs (1.5)/less/extend-clearfix.less deleted file mode 100644 index 82445dfa..00000000 --- a/test/Fixtures/lessjs (1.5)/less/extend-clearfix.less +++ /dev/null @@ -1,19 +0,0 @@ -.clearfix { - *zoom: 1; - &:after { - content: ''; - display: block; - clear: both; - height: 0; - } -} - -.foo { - &:extend(.clearfix all); - color: red; -} - -.bar { - &:extend(.clearfix all); - color: blue; -} diff --git a/test/Fixtures/lessjs (1.5)/less/extend-exact.less b/test/Fixtures/lessjs (1.5)/less/extend-exact.less deleted file mode 100644 index 41dc4130..00000000 --- a/test/Fixtures/lessjs (1.5)/less/extend-exact.less +++ /dev/null @@ -1,46 +0,0 @@ -.replace.replace, -.c.replace + .replace { - .replace, - .c { - prop: copy-paste-replace; - } -} -.rep_ace:extend(.replace.replace .replace) {} - -.a .b .c { - prop: not_effected; -} - -.a { - prop: is_effected; - .b { - prop: not_effected; - } - .b.c { - prop: not_effected; - } -} - -.c, .a { - .b, .a { - .a, .c { - prop: not_effected; - } - } -} - -.effected { - &:extend(.a); - &:extend(.b); - &:extend(.c); -} - -.e { - && { - prop: extend-double; - &:hover { - hover: not-extended; - } - } -} -.dbl:extend(.e.e) {} diff --git a/test/Fixtures/lessjs (1.5)/less/extend-media.less b/test/Fixtures/lessjs (1.5)/less/extend-media.less deleted file mode 100644 index 1b22c3fa..00000000 --- a/test/Fixtures/lessjs (1.5)/less/extend-media.less +++ /dev/null @@ -1,24 +0,0 @@ -.ext1 .ext2 { - background: black; -} - -@media tv { - .ext1 .ext3 { - color: white; - } - .tv-lowres :extend(.ext1 all) { - background: blue; - } - @media hires { - .ext1 .ext4 { - color: green; - } - .tv-hires :extend(.ext1 all) { - background: red; - } - } -} - -.all:extend(.ext1 all) { - -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/extend-nest.less b/test/Fixtures/lessjs (1.5)/less/extend-nest.less deleted file mode 100644 index 9d4d27bb..00000000 --- a/test/Fixtures/lessjs (1.5)/less/extend-nest.less +++ /dev/null @@ -1,65 +0,0 @@ -.sidebar { - width: 300px; - background: red; - - .box { - background: #FFF; - border: 1px solid #000; - margin: 10px 0; - } -} - -.sidebar2 { - &:extend(.sidebar all); - background: blue; -} - -.type1 { - .sidebar3 { - &:extend(.sidebar all); - background: green; - } -} - -.type2 { - &.sidebar4 { - &:extend(.sidebar all); - background: red; - } -} - -.button { - color: black; - &:hover { - color: white; - } -} -.submit { - &:extend(.button); - &:hover:extend(.button:hover) {} -} - -.nomatch { - &:hover:extend(.button :hover) {} -} - -.button2 { - :hover { - nested: white; - } -} -.button2 :hover { - notnested: black; -} - -.nomatch :extend(.button2:hover) {} - -.amp-test-a, -.amp-test-b { - .amp-test-c &.amp-test-d&.amp-test-e { - .amp-test-f&+&.amp-test-g:extend(.amp-test-h) {} - } -} -.amp-test-h { - test: extended by masses of selectors; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/extend-selector.less b/test/Fixtures/lessjs (1.5)/less/extend-selector.less deleted file mode 100644 index c7588ee0..00000000 --- a/test/Fixtures/lessjs (1.5)/less/extend-selector.less +++ /dev/null @@ -1,99 +0,0 @@ -.error { - border: 1px #f00; - background: #fdd; -} -.error.intrusion { - font-size: 1.3em; - font-weight: bold; -} -.intrusion .error { - display: none; -} -.badError:extend(.error all) { - border-width: 3px; -} - -.foo .bar, .foo .baz { - display: none; -} - -.ext1 .ext2 - :extend(.foo all) { -} - -.ext3:extend(.foo all), -.ext4:extend(.foo all) { -} - -div.ext5, -.ext6 > .ext5 { - width: 100px; -} - -.should-not-exist-in-output, -.ext7:extend(.ext5 all) { -} - -.ext { - test: 1; -} -// same as -// .a .c:extend(.ext all) -// .b .c:extend(.ext all) -// .a .c .d -// .b .c .d -.a, .b { - test: 2; - .c:extend(.ext all) { - test: 3; - .d { - test: 4; - } - } -} - -.replace.replace, -.c.replace + .replace { - .replace, - .c { - prop: copy-paste-replace; - } -} -.rep_ace:extend(.replace all) {} - -.attributes { - [data="test"] { - extend: attributes; - } - .attribute-test { - &:extend([data="test"] all); - } - [data] { - extend: attributes2; - } - .attribute-test2 { - &:extend([data] all); //you could argue it should match [data="test"]... not for now though... - } - @attr-data: "test3"; - [data=@{attr-data}] { - extend: attributes2; - } - .attribute-test { - &:extend([data="test3"] all); - } -} - -.header { - .header-nav { - background: red; - &:before { - background: blue; - } - } -} - -.footer { - .footer-nav { - &:extend( .header .header-nav all ); - } -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/extend.less b/test/Fixtures/lessjs (1.5)/less/extend.less deleted file mode 100644 index 1db5d431..00000000 --- a/test/Fixtures/lessjs (1.5)/less/extend.less +++ /dev/null @@ -1,81 +0,0 @@ -.error { - border: 1px #f00; - background: #fdd; -} -.error.intrusion { - font-size: 1.3em; - font-weight: bold; -} -.intrusion .error { - display: none; -} -.badError { - &:extend(.error all); - border-width: 3px; -} - -.foo .bar, .foo .baz { - display: none; -} - -.ext1 .ext2 { - &:extend(.foo all); -} - -.ext3, -.ext4 { - &:extend(.foo all); - &:extend(.bar all); -} - -div.ext5, -.ext6 > .ext5 { - width: 100px; -} - -.ext7 { - &:extend(.ext5 all); -} - -.ext8.ext9 { - result: add-foo; -} -.ext8 .ext9, -.ext8 + .ext9, -.ext8 > .ext9 { - result: bar-matched; -} -.ext8.nomatch { - result: none; -} -.ext8 { - .ext9 { - result: match-nested-bar; - } -} -.ext8 { - &.ext9 { - result: match-nested-foo; - } -} - -.fuu:extend(.ext8.ext9 all) {} -.buu:extend(.ext8 .ext9 all) {} -.zap:extend(.ext8 + .ext9 all) {} -.zoo:extend(.ext8 > .ext9 all) {} - -.aa { - color: black; - .dd { - background: red; - } -} -.bb { - background: red; - .bb { - color: black; - } -} -.cc:extend(.aa,.bb) {} -.ee:extend(.dd all,.bb) {} -.ff:extend(.dd,.bb all) {} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/extract-and-length.less b/test/Fixtures/lessjs (1.5)/less/extract-and-length.less deleted file mode 100644 index d81e118f..00000000 --- a/test/Fixtures/lessjs (1.5)/less/extract-and-length.less +++ /dev/null @@ -1,133 +0,0 @@ - -// simple array/list: - -.multiunit { - @v: abc "abc" 1 1px 1% #123; - length: length(@v); - extract: extract(@v, 1) extract(@v, 2) extract(@v, 3) extract(@v, 4) extract(@v, 5) extract(@v, 6); -} - -.incorrect-index { - @v1: a b c; - @v2: a, b, c; - v1: extract(@v1, 5); - v2: extract(@v2, -2); -} - -.scalar { - @var: variable; - var-value: extract(@var, 1); - var-length: length(@var); - ill-index: extract(@var, 2); - - name-value: extract(name, 1); - string-value: extract("string", 1); - number-value: extract(12345678, 1); - color-value: extract(blue, 1); - rgba-value: extract(rgba(80, 160, 240, 0.67), 1); - empty-value: extract(~'', 1); - - name-length: length(name); - string-length: length("string"); - number-length: length(12345678); - color-length: length(blue); - rgba-length: length(rgba(80, 160, 240, 0.67)); - empty-length: length(~''); -} - -.mixin-arguments { - .mixin-args(a b c d); - .mixin-args(a, b, c, d); - .mixin-args(1; 2; 3; 4); -} - -.mixin-args(@value) { - &-1 { - length: length(@value); - extract: extract(@value, 3) ~"|" extract(@value, 2) ~"|" extract(@value, 1); - } -} - -.mixin-args(...) { - &-2 { - length: length(@arguments); - extract: extract(@arguments, 3) ~"|" extract(@arguments, 2) ~"|" extract(@arguments, 1); - } -} - -.mixin-args(@values...) { - &-3 { - length: length(@values); - extract: extract(@values, 3) ~"|" extract(@values, 2) ~"|" extract(@values, 1); - } -} - -.mixin-args(@head, @tail...) { - &-4 { - length: length(@tail); - extract: extract(@tail, 2) ~"|" extract(@tail, 1); - } -} - -// "multidimensional" array/list - -.md-space-comma { - @v: a b c, 1 2 3, "x" "y" "z"; - length-1: length(@v); - extract-1: extract(@v, 2); - length-2: length(extract(@v, 2)); - extract-2: extract(extract(@v, 2), 2); - - &-as-args {.mixin-args(a b c, 1 2 3, "x" "y" "z")} -} - -.md-cat-space-comma { - @a: a b c; - @b: 1 2 3; - @c: "x" "y" "z"; - @v: @a, @b, @c; - length-1: length(@v); - extract-1: extract(@v, 2); - length-2: length(extract(@v, 2)); - extract-2: extract(extract(@v, 2), 2); - - &-as-args {.mixin-args(@a, @b, @c)} -} - -.md-cat-comma-space { - @a: a, b, c; - @b: 1, 2, 3; - @c: "x", "y", "z"; - @v: @a @b @c; - length-1: length(@v); - extract-1: extract(@v, 2); - length-2: length(extract(@v, 2)); - extract-2: extract(extract(@v, 2), 2); - - &-as-args {.mixin-args(@a @b @c)} -} - -.md-3D { - @a: a b c d, 1 2 3 4; - @b: 5 6 7 8, e f g h; - .3D(@a, @b); - - .3D(...) { - - @v1: @arguments; - length-1: length(@v1); - extract-1: extract(@v1, 1); - - @v2: extract(@v1, 2); - length-2: length(@v2); - extract-2: extract(@v2, 1); - - @v3: extract(@v2, 1); - length-3: length(@v3); - extract-3: extract(@v3, 3); - - @v4: extract(@v3, 4); - length-4: length(@v4); - extract-4: extract(@v4, 1); - } -} diff --git a/test/Fixtures/lessjs (1.5)/less/functions.less b/test/Fixtures/lessjs (1.5)/less/functions.less deleted file mode 100644 index b50a0da5..00000000 --- a/test/Fixtures/lessjs (1.5)/less/functions.less +++ /dev/null @@ -1,153 +0,0 @@ -#functions { - @var: 10; - @colors: #000, #fff; - color: _color("evil red"); // #660000 - width: increment(15); - height: undefined("self"); - border-width: add(2, 3); - variable: increment(@var); - background: linear-gradient(@colors); -} - -#built-in { - @r: 32; - escaped: e("-Some::weird(#thing, y)"); - lighten: lighten(#ff0000, 40%); - darken: darken(#ff0000, 40%); - saturate: saturate(#29332f, 20%); - desaturate: desaturate(#203c31, 20%); - greyscale: greyscale(#203c31); - hsl-clamp: hsl(380, 150%, 150%); - spin-p: spin(hsl(340, 50%, 50%), 40); - spin-n: spin(hsl(30, 50%, 50%), -40); - luma-white: luma(#fff); - luma-black: luma(#000); - luma-black-alpha: luma(rgba(0,0,0,0.5)); - luma-red: luma(#ff0000); - luma-green: luma(#00ff00); - luma-blue: luma(#0000ff); - luma-yellow: luma(#ffff00); - luma-cyan: luma(#00ffff); - luma-white-alpha: luma(rgba(255,255,255,0.5)); - contrast-filter: contrast(30%); - saturate-filter: saturate(5%); - contrast-white: contrast(#fff); - contrast-black: contrast(#000); - contrast-red: contrast(#ff0000); - contrast-green: contrast(#00ff00); - contrast-blue: contrast(#0000ff); - contrast-yellow: contrast(#ffff00); - contrast-cyan: contrast(#00ffff); - contrast-light: contrast(#fff, #111111, #eeeeee); - contrast-dark: contrast(#000, #111111, #eeeeee); - contrast-wrongorder: contrast(#fff, #eeeeee, #111111, 0.5); - contrast-light-thresh: contrast(#fff, #111111, #eeeeee, 0.5); - contrast-dark-thresh: contrast(#000, #111111, #eeeeee, 0.5); - contrast-high-thresh: contrast(#555, #111111, #eeeeee, 0.6); - contrast-low-thresh: contrast(#555, #111111, #eeeeee, 0.1); - contrast-light-thresh-per: contrast(#fff, #111111, #eeeeee, 50%); - contrast-dark-thresh-per: contrast(#000, #111111, #eeeeee, 50%); - contrast-high-thresh-per: contrast(#555, #111111, #eeeeee, 60%); - contrast-low-thresh-per: contrast(#555, #111111, #eeeeee, 10%); - format: %("rgb(%d, %d, %d)", @r, 128, 64); - format-string: %("hello %s", "world"); - format-multiple: %("hello %s %d", "earth", 2); - format-url-encode: %('red is %A', #ff0000); - eformat: e(%("rgb(%d, %d, %d)", @r, 128, 64)); - - unitless: unit(12px); - unit: unit((13px + 1px), em); - - hue: hue(hsl(98, 12%, 95%)); - saturation: saturation(hsl(98, 12%, 95%)); - lightness: lightness(hsl(98, 12%, 95%)); - hsvhue: hsvhue(hsv(98, 12%, 95%)); - hsvsaturation: hsvsaturation(hsv(98, 12%, 95%)); - hsvvalue: hsvvalue(hsv(98, 12%, 95%)); - red: red(#f00); - green: green(#0f0); - blue: blue(#00f); - rounded: round((@r/3)); - rounded-two: round((@r/3), 2); - roundedpx: round((10px / 3)); - roundedpx-three: round((10px / 3), 3); - rounded-percentage: round(10.2%); - ceil: ceil(10.1px); - floor: floor(12.9px); - sqrt: sqrt(25px); - pi: pi(); - mod: mod(13m, 11cm); // could take into account units, doesn't at the moment - abs: abs(-4%); - tan: tan(42deg); - sin: sin(10deg); - cos: cos(12); - atan: atan(tan(0.1rad)); - atan: convert(acos(cos(34deg)), deg); - atan: convert(acos(cos(50grad)), deg); - pow: pow(8px, 2); - pow: pow(4, 3); - pow: pow(3, 3em); - min: min(0); - min: min("junk", 6, 5); - min: min(1pc, 3pt); - max: max(1, 3); - max: max(3%, 1cm, 8%, 2mm); - percentage: percentage((10px / 50)); - color: color("#ff0011"); - tint: tint(#777777, 13); - tint-full: tint(#777777, 100); - tint-percent: tint(#777777, 13%); - shade: shade(#777777, 13); - shade-full: shade(#777777, 100); - shade-percent: shade(#777777, 13%); - - fade-out: fadeOut(red, 5%); // support fadeOut and fadeout - fade-in: fadein(fadeout(red, 10%), 5%); - - hsv: hsv(5, 50%, 30%); - hsva: hsva(3, 50%, 30%, 0.2); - - mix: mix(#ff0000, #ffff00, 80); - mix-0: mix(#ff0000, #ffff00, 0); - mix-100: mix(#ff0000, #ffff00, 100); - mix-weightless: mix(#ff0000, #ffff00); - mixt: mix(#ff0000, transparent); - - .is-a { - color: iscolor(#ddd); - color1: iscolor(red); - color2: iscolor(rgb(0, 0, 0)); - color3: iscolor(transparent); - keyword: iskeyword(hello); - number: isnumber(32); - string: isstring("hello"); - pixel: ispixel(32px); - percent: ispercentage(32%); - em: isem(32em); - cat: isunit(32cat, cat); - } -} - -#alpha { - alpha: darken(hsla(25, 50%, 50%, 0.6), 10%); - alpha2: alpha(rgba(3, 4, 5, 0.5)); - alpha3: alpha(transparent); -} - -#blendmodes { - multiply: multiply(#f60000, #f60000); - screen: screen(#f60000, #0000f6); - overlay: overlay(#f60000, #0000f6); - softlight: softlight(#f60000, #ffffff); - hardlight: hardlight(#f60000, #0000f6); - difference: difference(#f60000, #0000f6); - exclusion: exclusion(#f60000, #0000f6); - average: average(#f60000, #0000f6); - negation: negation(#f60000, #313131); -} - -#extract-and-length { - @anon: A B C 1 2 3; - extract: extract(@anon, 6) extract(@anon, 5) extract(@anon, 4) extract(@anon, 3) extract(@anon, 2) extract(@anon, 1); - length: length(@anon); -} diff --git a/test/Fixtures/lessjs (1.5)/less/ie-filters.less b/test/Fixtures/lessjs (1.5)/less/ie-filters.less deleted file mode 100644 index 3350b653..00000000 --- a/test/Fixtures/lessjs (1.5)/less/ie-filters.less +++ /dev/null @@ -1,15 +0,0 @@ -@fat: 0; -@cloudhead: "#000000"; - -.nav { - filter: progid:DXImageTransform.Microsoft.Alpha(opacity = 20); - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=@fat); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#333333", endColorstr=@cloudhead, GradientType=@fat); -} -.evalTest(@arg) { - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=@arg); -} -.evalTest1 { - .evalTest(30); - .evalTest(5); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/import-inline.less b/test/Fixtures/lessjs (1.5)/less/import-inline.less deleted file mode 100644 index 95a11896..00000000 --- a/test/Fixtures/lessjs (1.5)/less/import-inline.less +++ /dev/null @@ -1,2 +0,0 @@ -@import (inline) url("import/import-test-d.css") (min-width:600px); -@import (inline, css) url("import/invalid-css.less"); \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/import-interpolation.less b/test/Fixtures/lessjs (1.5)/less/import-interpolation.less deleted file mode 100644 index 21cfe086..00000000 --- a/test/Fixtures/lessjs (1.5)/less/import-interpolation.less +++ /dev/null @@ -1,8 +0,0 @@ -@my_theme: "test"; - -@import "import/import-@{my_theme}-e.less"; - -@import "import/import-@{in}@{terpolation}.less"; - -@in: "in"; -@terpolation: "terpolation"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/import-once.less b/test/Fixtures/lessjs (1.5)/less/import-once.less deleted file mode 100644 index 0a4024a3..00000000 --- a/test/Fixtures/lessjs (1.5)/less/import-once.less +++ /dev/null @@ -1,6 +0,0 @@ -@import "import/import-once-test-c"; -@import "import/import-once-test-c"; -@import "import/import-once-test-c.less"; -@import "import/deeper/import-once-test-a"; -@import (multiple) "import/import-test-f.less"; -@import (multiple) "import/import-test-f.less"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/import-reference.less b/test/Fixtures/lessjs (1.5)/less/import-reference.less deleted file mode 100644 index cf9da168..00000000 --- a/test/Fixtures/lessjs (1.5)/less/import-reference.less +++ /dev/null @@ -1,18 +0,0 @@ -@import (reference) url("import-once.less"); -@import (reference) url("css-3.less"); -@import (reference) url("media.less"); -/* - The media statement above is invalid (no selector) - We should ban invalid media queries with properties and no selector? -*/ -@import (reference) url("import/import-reference.less"); - -.b { - .z(); -} - -.zz(); - -.visible:extend(.z all) { - extend: test; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/import.less b/test/Fixtures/lessjs (1.5)/less/import.less deleted file mode 100644 index 01689408..00000000 --- a/test/Fixtures/lessjs (1.5)/less/import.less +++ /dev/null @@ -1,21 +0,0 @@ -@import url(http://fonts.googleapis.com/css?family=Open+Sans); - -@import url(/absolute/something.css) screen and (color) and (max-width: 600px); - -@var: 100px; -@import url("//ha.com/file.css") (min-width:@var); - -#import-test { - .mixin; - width: 10px; - height: (@a + 10%); -} -@import "import/import-test-e" screen and (max-width: 600px); - -@import url("import/import-test-a.less"); - -@import (less, multiple) "import/import-test-d.css" screen and (max-width: 601px); - -@import (multiple) "import/import-test-e" screen and (max-width: 602px); - -@import (less, multiple) url("import/import-test-d.css") screen and (max-width: 603px); \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/import/deeper/import-once-test-a.less b/test/Fixtures/lessjs (1.5)/less/import/deeper/import-once-test-a.less deleted file mode 100644 index 8a747fc0..00000000 --- a/test/Fixtures/lessjs (1.5)/less/import/deeper/import-once-test-a.less +++ /dev/null @@ -1 +0,0 @@ -@import "../import-once-test-c"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/import/import-and-relative-paths-test.less b/test/Fixtures/lessjs (1.5)/less/import/import-and-relative-paths-test.less deleted file mode 100644 index da699989..00000000 --- a/test/Fixtures/lessjs (1.5)/less/import/import-and-relative-paths-test.less +++ /dev/null @@ -1,6 +0,0 @@ -@import "../css/background.css"; -@import "import-test-d.css"; - -@import "imports/logo"; -@import "imports/font"; - diff --git a/test/Fixtures/lessjs (1.5)/less/import/import-charset-test.less b/test/Fixtures/lessjs (1.5)/less/import/import-charset-test.less deleted file mode 100644 index 07a66e1a..00000000 --- a/test/Fixtures/lessjs (1.5)/less/import/import-charset-test.less +++ /dev/null @@ -1 +0,0 @@ -@charset "ISO-8859-1"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/import/import-interpolation.less b/test/Fixtures/lessjs (1.5)/less/import/import-interpolation.less deleted file mode 100644 index aa49a702..00000000 --- a/test/Fixtures/lessjs (1.5)/less/import/import-interpolation.less +++ /dev/null @@ -1 +0,0 @@ -@import "import-@{in}@{terpolation}2.less"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/import/import-interpolation2.less b/test/Fixtures/lessjs (1.5)/less/import/import-interpolation2.less deleted file mode 100644 index 12bfb4e1..00000000 --- a/test/Fixtures/lessjs (1.5)/less/import/import-interpolation2.less +++ /dev/null @@ -1,5 +0,0 @@ -.a { - var: test; -} - -@in: "redefined-does-nothing"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/import/import-once-test-c.less b/test/Fixtures/lessjs (1.5)/less/import/import-once-test-c.less deleted file mode 100644 index 686747a8..00000000 --- a/test/Fixtures/lessjs (1.5)/less/import/import-once-test-c.less +++ /dev/null @@ -1,6 +0,0 @@ - -@c: red; - -#import { - color: @c; -} diff --git a/test/Fixtures/lessjs (1.5)/less/import/import-reference.less b/test/Fixtures/lessjs (1.5)/less/import/import-reference.less deleted file mode 100644 index 9eac45fc..00000000 --- a/test/Fixtures/lessjs (1.5)/less/import/import-reference.less +++ /dev/null @@ -1,43 +0,0 @@ -.z { - color: red; - .c { - color: green; - } -} -.only-with-visible, -.z { - color: green; - &:hover { - color: green; - } - & { - color: green; - } - & + & { - color: green; - .sub { - color: green; - } - } -} - -& { - .hidden { - hidden: true; - } -} - -@media tv { - .hidden { - hidden: true; - } -} - -/* comment is not output */ - -.zz { - .y { - pulled-in: yes; - } - /* comment pulled in */ -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/import/import-test-a.less b/test/Fixtures/lessjs (1.5)/less/import/import-test-a.less deleted file mode 100644 index b3b3b8fc..00000000 --- a/test/Fixtures/lessjs (1.5)/less/import/import-test-a.less +++ /dev/null @@ -1,3 +0,0 @@ -@import "import-test-b.less"; -@a: 20%; -@import "urls.less"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/import/import-test-b.less b/test/Fixtures/lessjs (1.5)/less/import/import-test-b.less deleted file mode 100644 index ce2d35a8..00000000 --- a/test/Fixtures/lessjs (1.5)/less/import/import-test-b.less +++ /dev/null @@ -1,8 +0,0 @@ -@import "import-test-c"; - -@b: 100%; - -.mixin { - height: 10px; - color: @c; -} diff --git a/test/Fixtures/lessjs (1.5)/less/import/import-test-c.less b/test/Fixtures/lessjs (1.5)/less/import/import-test-c.less deleted file mode 100644 index 686747a8..00000000 --- a/test/Fixtures/lessjs (1.5)/less/import/import-test-c.less +++ /dev/null @@ -1,6 +0,0 @@ - -@c: red; - -#import { - color: @c; -} diff --git a/test/Fixtures/lessjs (1.5)/less/import/import-test-d.css b/test/Fixtures/lessjs (1.5)/less/import/import-test-d.css deleted file mode 100644 index 30575f01..00000000 --- a/test/Fixtures/lessjs (1.5)/less/import/import-test-d.css +++ /dev/null @@ -1 +0,0 @@ -#css { color: yellow; } diff --git a/test/Fixtures/lessjs (1.5)/less/import/import-test-e.less b/test/Fixtures/lessjs (1.5)/less/import/import-test-e.less deleted file mode 100644 index 98b84b0a..00000000 --- a/test/Fixtures/lessjs (1.5)/less/import/import-test-e.less +++ /dev/null @@ -1,2 +0,0 @@ - -body { width: 100% } diff --git a/test/Fixtures/lessjs (1.5)/less/import/import-test-f.less b/test/Fixtures/lessjs (1.5)/less/import/import-test-f.less deleted file mode 100644 index a63d67f6..00000000 --- a/test/Fixtures/lessjs (1.5)/less/import/import-test-f.less +++ /dev/null @@ -1,5 +0,0 @@ -@import "import-test-e"; - -.test-f { - height: 10px; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/import/imports/font.less b/test/Fixtures/lessjs (1.5)/less/import/imports/font.less deleted file mode 100644 index 5abb7e76..00000000 --- a/test/Fixtures/lessjs (1.5)/less/import/imports/font.less +++ /dev/null @@ -1,8 +0,0 @@ -@font-face { - font-family: xecret; - src: url('../assets/xecret.ttf'); -} - -#secret { - font-family: xecret, sans-serif; -} diff --git a/test/Fixtures/lessjs (1.5)/less/import/imports/logo.less b/test/Fixtures/lessjs (1.5)/less/import/imports/logo.less deleted file mode 100644 index 22893a23..00000000 --- a/test/Fixtures/lessjs (1.5)/less/import/imports/logo.less +++ /dev/null @@ -1,5 +0,0 @@ -#logo { - width: 100px; - height: 100px; - background: url('../assets/logo.png'); -} diff --git a/test/Fixtures/lessjs (1.5)/less/import/invalid-css.less b/test/Fixtures/lessjs (1.5)/less/import/invalid-css.less deleted file mode 100644 index ed585d63..00000000 --- a/test/Fixtures/lessjs (1.5)/less/import/invalid-css.less +++ /dev/null @@ -1 +0,0 @@ -this isn't very valid CSS. \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/import/urls.less b/test/Fixtures/lessjs (1.5)/less/import/urls.less deleted file mode 100644 index bb48f77a..00000000 --- a/test/Fixtures/lessjs (1.5)/less/import/urls.less +++ /dev/null @@ -1 +0,0 @@ -// empty file showing that it loads from the relative path first diff --git a/test/Fixtures/lessjs (1.5)/less/javascript.less b/test/Fixtures/lessjs (1.5)/less/javascript.less deleted file mode 100644 index b826a787..00000000 --- a/test/Fixtures/lessjs (1.5)/less/javascript.less +++ /dev/null @@ -1,29 +0,0 @@ -.eval { - js: `42`; - js: `1 + 1`; - js: `"hello world"`; - js: `[1, 2, 3]`; - title: `typeof process.title`; - ternary: `(1 + 1 == 2 ? true : false)`; - multiline: `(function(){var x = 1 + 1; - return x})()`; -} -.scope { - @foo: 42; - var: `parseInt(this.foo.toJS())`; - escaped: ~`2 + 5 + 'px'`; -} -.vars { - @var: `4 + 4`; - width: @var; -} -.escape-interpol { - @world: "world"; - width: ~`"hello" + " " + @{world}`; -} -.arrays { - @ary: 1, 2, 3; - @ary2: 1 2 3; - ary: `@{ary}.join(', ')`; - ary1: `@{ary2}.join(', ')`; -} diff --git a/test/Fixtures/lessjs (1.5)/less/lazy-eval.less b/test/Fixtures/lessjs (1.5)/less/lazy-eval.less deleted file mode 100644 index 72b3fd46..00000000 --- a/test/Fixtures/lessjs (1.5)/less/lazy-eval.less +++ /dev/null @@ -1,6 +0,0 @@ -@var: @a; -@a: 100%; - -.lazy-eval { - width: @var; -} diff --git a/test/Fixtures/lessjs (1.5)/less/legacy/legacy.less b/test/Fixtures/lessjs (1.5)/less/legacy/legacy.less deleted file mode 100644 index 92d00088..00000000 --- a/test/Fixtures/lessjs (1.5)/less/legacy/legacy.less +++ /dev/null @@ -1,7 +0,0 @@ -@media (-o-min-device-pixel-ratio: 2/1) { - .test-math-and-units { - font: ignores 0/0 rules; - test-division: 4 / 2 + 5em; - simple: 1px + 1px; - } -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/media.less b/test/Fixtures/lessjs (1.5)/less/media.less deleted file mode 100644 index 01a6a020..00000000 --- a/test/Fixtures/lessjs (1.5)/less/media.less +++ /dev/null @@ -1,234 +0,0 @@ - -// For now, variables can't be declared inside @media blocks. - -@var: 42; - -@media print { - .class { - color: blue; - .sub { - width: @var; - } - } - .top, header > h1 { - color: (#222 * 2); - } -} - -@media screen { - @base: 8; - body { max-width: (@base * 60); } -} - -@ratio_large: 16; -@ratio_small: 9; - -@media all and (device-aspect-ratio: @ratio_large / @ratio_small) { - body { max-width: 800px; } -} - -@media all and (orientation:portrait) { - aside { float: none; } -} - -@media handheld and (min-width: @var), screen and (min-width: 20em) { - body { - max-width: 480px; - } -} - -body { - @media print { - padding: 20px; - - header { - background-color: red; - } - - @media (orientation:landscape) { - margin-left: 20px; - } - } -} - -@media screen { - .sidebar { - width: 300px; - @media (orientation: landscape) { - width: 500px; - } - } -} - -@media a { - .first { - @media b { - .second { - .third { - width: 300px; - @media c { - width: 500px; - } - } - .fourth { - width: 3; - } - } - } - } -} - -body { - @media a, b and c { - width: 95%; - - @media x, y { - width: 100%; - } - } -} - -.mediaMixin(@fallback: 200px) { - background: black; - - @media handheld { - background: white; - - @media (max-width: @fallback) { - background: red; - } - } -} - -.a { - .mediaMixin(100px); -} - -.b { - .mediaMixin(); -} -@smartphone: ~"only screen and (max-width: 200px)"; -@media @smartphone { - body { - width: 480px; - } -} - -@media print { - @page :left { - margin: 0.5cm; - } - @page :right { - margin: 0.5cm; - } - @page Test:first { - margin: 1cm; - } - @page :first { - size: 8.5in 11in; - @top-left { - margin: 1cm; - } - @top-left-corner { - margin: 1cm; - } - @top-center { - margin: 1cm; - } - @top-right { - margin: 1cm; - } - @top-right-corner { - margin: 1cm; - } - @bottom-left { - margin: 1cm; - } - @bottom-left-corner { - margin: 1cm; - } - @bottom-center { - margin: 1cm; - } - @bottom-right { - margin: 1cm; - } - @bottom-right-corner { - margin: 1cm; - } - @left-top { - margin: 1cm; - } - @left-middle { - margin: 1cm; - } - @left-bottom { - margin: 1cm; - } - @right-top { - margin: 1cm; - } - @right-middle { - content: "Page " counter(page); - } - @right-bottom { - margin: 1cm; - } - } -} - -@media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: 2/1), (min-resolution: 2dppx), (min-resolution: 128dpcm) { - .b { - background: red; - } -} - -.bg() { - background: red; - - @media (max-width: 500px) { - background: green; - } -} - -body { - .bg(); -} - -@bpMedium: 1000px; -@media (max-width: @bpMedium) { - body { - .bg(); - background: blue; - } -} - -@media (max-width: 1200px) { - /* a comment */ - - @media (max-width: 900px) { - body { font-size: 11px; } - } -} - -.nav-justified { - @media (min-width: 480px) { - > li { - display: table-cell; - } - } -} - -.menu -{ - @media (min-width: 768px) { - .nav-justified(); - } -} -@all: ~"all"; -@tv: ~"tv"; -@media @all and @tv { - .all-and-tv-variables { - var: all-and-tv; - } -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/merge.less b/test/Fixtures/lessjs (1.5)/less/merge.less deleted file mode 100644 index 52d0796e..00000000 --- a/test/Fixtures/lessjs (1.5)/less/merge.less +++ /dev/null @@ -1,51 +0,0 @@ -.first-transform() { - transform+: rotate(90deg), skew(30deg); -} -.second-transform() { - transform+: scale(2,4); -} -.third-transform() { - transform: scaleX(45deg); -} -.fourth-transform() { - transform+: scaleX(45deg); -} -.fifth-transform() { - transform+: scale(2,4) !important; -} -.first-background() { - background+: url(data://img1.png); -} -.second-background() { - background+: url(data://img2.png); -} - -.test1 { - // Can merge values - .first-transform(); - .second-transform(); -} -.test2 { - // Wont merge values without +: merge directive, for backwards compatibility with css - .first-transform(); - .third-transform(); -} -.test3 { - // Wont merge values from two sources with different properties - .fourth-transform(); - .first-background(); -} -.test4 { - // Wont merge values from sources that merked as !important, for backwards compatibility with css - .first-transform(); - .fifth-transform(); -} -.test5 { - // Wont merge values from mixins that merked as !important, for backwards compatibility with css - .first-transform(); - .second-transform() !important; -} -.test6 { - // Ignores !merge if no peers found - .second-transform(); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/mixins-args.less b/test/Fixtures/lessjs (1.5)/less/mixins-args.less deleted file mode 100644 index 8cdc67df..00000000 --- a/test/Fixtures/lessjs (1.5)/less/mixins-args.less +++ /dev/null @@ -1,215 +0,0 @@ -.mixin (@a: 1px, @b: 50%) { - width: (@a * 5); - height: (@b - 1%); -} - -.mixina (@style, @width, @color: black) { - border: @width @style @color; -} - -.mixiny -(@a: 0, @b: 0) { - margin: @a; - padding: @b; -} - -.hidden() { - color: transparent; // asd -} - -#hidden { - .hidden; -} - -#hidden1 { - .hidden(); -} - -.two-args { - color: blue; - .mixin(2px, 100%); - .mixina(dotted, 2px); -} - -.one-arg { - .mixin(3px); -} - -.no-parens { - .mixin; -} - -.no-args { - .mixin(); -} - -.var-args { - @var: 9; - .mixin(@var, (@var * 2)); -} - -.multi-mix { - .mixin(2px, 30%); - .mixiny(4, 5); -} - -.maxa(@arg1: 10, @arg2: #f00) { - padding: (@arg1 * 2px); - color: @arg2; -} - -body { - .maxa(15); -} - -@glob: 5; -.global-mixin(@a:2) { - width: (@glob + @a); -} - -.scope-mix { - .global-mixin(3); -} - -.nested-ruleset (@width: 200px) { - width: @width; - .column { margin: @width; } -} -.content { - .nested-ruleset(600px); -} - -// - -.same-var-name2(@radius) { - radius: @radius; -} -.same-var-name(@radius) { - .same-var-name2(@radius); -} -#same-var-name { - .same-var-name(5px); -} - -// - -.var-inside () { - @var: 10px; - width: @var; -} -#var-inside { .var-inside; } - -.mixin-arguments (@width: 0px, ...) { - border: @arguments; - width: @width; -} - -.arguments { - .mixin-arguments(1px, solid, black); -} -.arguments2 { - .mixin-arguments(); -} -.arguments3 { - .mixin-arguments; -} - -.mixin-arguments2 (@width, @rest...) { - border: @arguments; - rest: @rest; - width: @width; -} -.arguments4 { - .mixin-arguments2(0, 1, 2, 3, 4); -} - -// Edge cases - -.edge-case { - .mixin-arguments("{"); -} - -// Division vs. Literal Slash -.border-radius(@r: 2px/5px) { - border-radius: @r; -} -.slash-vs-math { - .border-radius(); - .border-radius(5px/10px); - .border-radius((3px * 2)); -} -// semi-colon vs comma for delimiting - -.mixin-takes-one(@a) { - one: @a; -} - -.mixin-takes-two(@a; @b) { - one: @a; - two: @b; -} - -.comma-vs-semi-colon { - .mixin-takes-two(@a : a; @b : b, c); - .mixin-takes-two(@a : d, e; @b : f); - .mixin-takes-one(@a: g); - .mixin-takes-one(@a : h;); - .mixin-takes-one(i); - .mixin-takes-one(j;); - .mixin-takes-two(k, l); - .mixin-takes-one(m, n;); - .mixin-takes-two(o, p; q); - .mixin-takes-two(r, s; t;); -} - -.mixin-conflict(@a:defA, @b:defB, @c:defC) { - three: @a, @b, @c; -} - -.mixin-conflict(@a:defA, @b:defB, @c:defC, @d:defD) { - four: @a, @b, @c, @d; -} - -#named-conflict { - .mixin-conflict(11, 12, 13, @a:a); - .mixin-conflict(@a:a, 21, 22, 23); -} -@a: 3px; -.mixin-default-arg(@a: 1px, @b: @a, @c: @b) { - defaults: 1px 1px 1px; - defaults: 2px 2px 2px; -} - -.test-mixin-default-arg { - .mixin-default-arg(); - .mixin-default-arg(2px); -} - -.mixin-comma-default1(@color; @padding; @margin: 2, 2, 2, 2) { - margin: @margin; -} -.selector { - .mixin-comma-default1(#33acfe; 4); -} -.mixin-comma-default2(@margin: 2, 2, 2, 2;) { - margin: @margin; -} -.selector2 { - .mixin-comma-default2(); -} -.mixin-comma-default3(@margin: 2, 2, 2, 2) { - margin: @margin; -} -.selector3 { - .mixin-comma-default3(4,2,2,2); -} - -.test-calling-one-arg-mixin(@a) { -} - -.test-calling-one-arg-mixin(@a, @b, @rest...) { -} - -div { - .test-calling-one-arg-mixin(1); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/mixins-closure.less b/test/Fixtures/lessjs (1.5)/less/mixins-closure.less deleted file mode 100644 index 01251d2a..00000000 --- a/test/Fixtures/lessjs (1.5)/less/mixins-closure.less +++ /dev/null @@ -1,26 +0,0 @@ -.scope { - @var: 99px; - .mixin () { - width: @var; - } -} - -.class { - .scope > .mixin; -} - -.overwrite { - @var: 0px; - .scope > .mixin; -} - -.nested { - @var: 5px; - .mixin () { - width: @var; - } - .class { - @var: 10px; - .mixin; - } -} diff --git a/test/Fixtures/lessjs (1.5)/less/mixins-guards.less b/test/Fixtures/lessjs (1.5)/less/mixins-guards.less deleted file mode 100644 index 4d0774df..00000000 --- a/test/Fixtures/lessjs (1.5)/less/mixins-guards.less +++ /dev/null @@ -1,153 +0,0 @@ - -// Stacking, functions.. - -.light (@a) when (lightness(@a) > 50%) { - color: white; -} -.light (@a) when (lightness(@a) < 50%) { - color: black; -} -.light (@a) { - margin: 1px; -} - -.light1 { .light(#ddd) } -.light2 { .light(#444) } - -// Arguments against each other - -.max (@a, @b) when (@a > @b) { - width: @a; -} -.max (@a, @b) when (@a < @b) { - width: @b; -} - -.max1 { .max(3, 6) } -.max2 { .max(8, 1) } - -// Globals inside guards - -@g: auto; - -.glob (@a) when (@a = @g) { - margin: @a @g; -} -.glob1 { .glob(auto) } - -// Other operators - -.ops (@a) when (@a >= 0) { - height: gt-or-eq; -} -.ops (@a) when (@a =< 0) { - height: lt-or-eq; -} -.ops (@a) when (@a <= 0) { - height: lt-or-eq-alias; -} -.ops (@a) when not(@a = 0) { - height: not-eq; -} -.ops1 { .ops(0) } -.ops2 { .ops(1) } -.ops3 { .ops(-1) } - -// Scope and default values - -@a: auto; - -.default (@a: inherit) when (@a = inherit) { - content: default; -} -.default1 { .default } - -// true & false keywords -.test (@a) when (@a) { - content: "true."; -} -.test (@a) when not (@a) { - content: "false."; -} - -.test1 { .test(true) } -.test2 { .test(false) } -.test3 { .test(1) } -.test4 { .test(boo) } -.test5 { .test("true") } - -// Boolean expressions - -.bool () when (true) and (false) { content: true and false } // FALSE -.bool () when (true) and (true) { content: true and true } // TRUE -.bool () when (true) { content: true } // TRUE -.bool () when (false) and (false) { content: true } // FALSE -.bool () when (false), (true) { content: false, true } // TRUE -.bool () when (false) and (true) and (true), (true) { content: false and true and true, true } // TRUE -.bool () when (true) and (true) and (false), (false) { content: true and true and false, false } // FALSE -.bool () when (false), (true) and (true) { content: false, true and true } // TRUE -.bool () when (false), (false), (true) { content: false, false, true } // TRUE -.bool () when (false), (false) and (true), (false) { content: false, false and true, false } // FALSE -.bool () when (false), (true) and (true) and (true), (false) { content: false, true and true and true, false } // TRUE -.bool () when not (false) { content: not false } -.bool () when not (true) and not (false) { content: not true and not false } -.bool () when not (true) and not (true) { content: not true and not true } -.bool () when not (false) and (false), not (false) { content: not false and false, not false } - -.bool1 { .bool } - -.equality-unit-test(@num) when (@num = 1%) { - test: fail; -} -.equality-unit-test(@num) when (@num = 2) { - test: pass; -} -.equality-units { - .equality-unit-test(1px); - .equality-unit-test(2px); -} - -.colorguard(@col) when (@col = red) { content: is @col; } -.colorguard(@col) when not (blue = @col) { content: is not blue its @col; } -.colorguard(@col) {} -.colorguardtest { - .colorguard(red); - .colorguard(blue); - .colorguard(purple); -} - -.stringguard(@str) when (@str = "theme1") { content: is theme1; } -.stringguard(@str) when not ("theme2" = @str) { content: is not theme2; } -.stringguard(@str) when (~"theme1" = @str) { content: is theme1 no quotes; } -.stringguard(@str) {} -.stringguardtest { - .stringguard("theme1"); - .stringguard("theme2"); - .stringguard(theme1); -} - -.mixin(...) { - catch:all; -} -.mixin(@var) when (@var=4) { - declare: 4; -} -.mixin(@var) when (@var=4px) { - declare: 4px; -} -#tryNumberPx { - .mixin(4px); -} - -.lock-mixin(@a) { - .inner-locked-mixin(@x: @a) when (@a = 1) { - a: @a; - x: @x; - } -} -.call-lock-mixin { - .lock-mixin(1); - .call-inner-lock-mixin { - .inner-locked-mixin(); - } -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/mixins-important.less b/test/Fixtures/lessjs (1.5)/less/mixins-important.less deleted file mode 100644 index c8cc1d5c..00000000 --- a/test/Fixtures/lessjs (1.5)/less/mixins-important.less +++ /dev/null @@ -1,25 +0,0 @@ -.submixin(@a) { - border-width: @a; -} -.mixin (9) { - border: 9 !important; -} -.mixin (@a: 0) { - border: @a; - boxer: @a; - .inner { - test: @a; - } - // comment - .submixin(@a); -} - -.class { - .mixin(1); - .mixin(2) !important; - .mixin(3); - .mixin(4) !important; - .mixin(5); - .mixin !important; - .mixin(9); -} diff --git a/test/Fixtures/lessjs (1.5)/less/mixins-named-args.less b/test/Fixtures/lessjs (1.5)/less/mixins-named-args.less deleted file mode 100644 index d79e0f47..00000000 --- a/test/Fixtures/lessjs (1.5)/less/mixins-named-args.less +++ /dev/null @@ -1,36 +0,0 @@ -.mixin (@a: 1px, @b: 50%) { - width: (@a * 5); - height: (@b - 1%); - args: @arguments; -} -.mixin (@a: 1px, @b: 50%) when (@b > 75%){ - text-align: center; -} - -.named-arg { - color: blue; - .mixin(@b: 100%); -} - -.class { - @var: 20%; - .mixin(@b: @var); -} - -.all-args-wrong-args { - .mixin(@b: 10%, @a: 2px); -} - -.mixin2 (@a: 1px, @b: 50%, @c: 50) { - width: (@a * 5); - height: (@b - 1%); - color: (#000000 + @c); -} - -.named-args2 { - .mixin2(3px, @c: 100); -} - -.named-args3 { - .mixin2(@b: 30%, @c: #123456); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/mixins-nested.less b/test/Fixtures/lessjs (1.5)/less/mixins-nested.less deleted file mode 100644 index 43443de2..00000000 --- a/test/Fixtures/lessjs (1.5)/less/mixins-nested.less +++ /dev/null @@ -1,22 +0,0 @@ -.mix-inner (@var) { - border-width: @var; -} - -.mix (@a: 10) { - .inner { - height: (@a * 10); - - .innest { - width: @a; - .mix-inner((@a * 2)); - } - } -} - -.class { - .mix(30); -} - -.class2 { - .mix(60); -} diff --git a/test/Fixtures/lessjs (1.5)/less/mixins-pattern.less b/test/Fixtures/lessjs (1.5)/less/mixins-pattern.less deleted file mode 100644 index f6a12ece..00000000 --- a/test/Fixtures/lessjs (1.5)/less/mixins-pattern.less +++ /dev/null @@ -1,99 +0,0 @@ -.mixin (...) { - variadic: true; -} -.mixin () { - zero: 0; -} -.mixin (@a: 1px) { - one: 1; -} -.mixin (@a) { - one-req: 1; -} -.mixin (@a: 1px, @b: 2px) { - two: 2; -} - -.mixin (@a, @b, @c) { - three-req: 3; -} - -.mixin (@a: 1px, @b: 2px, @c: 3px) { - three: 3; -} - -.zero { - .mixin(); -} - -.one { - .mixin(1); -} - -.two { - .mixin(1, 2); -} - -.three { - .mixin(1, 2, 3); -} - -// - -.mixout ('left') { - left: 1; -} - -.mixout ('right') { - right: 1; -} - -.left { - .mixout('left'); -} -.right { - .mixout('right'); -} - -// - -.border (@side, @width) { - color: black; - .border-side(@side, @width); -} -.border-side (left, @w) { - border-left: @w; -} -.border-side (right, @w) { - border-right: @w; -} - -.border-right { - .border(right, 4px); -} -.border-left { - .border(left, 4px); -} - -// - - -.border-radius (@r) { - both: (@r * 10); -} -.border-radius (@r, left) { - left: @r; -} -.border-radius (@r, right) { - right: @r; -} - -.only-right { - .border-radius(33, right); -} -.only-left { - .border-radius(33, left); -} -.left-right { - .border-radius(33); -} diff --git a/test/Fixtures/lessjs (1.5)/less/mixins.less b/test/Fixtures/lessjs (1.5)/less/mixins.less deleted file mode 100644 index be9e2bbd..00000000 --- a/test/Fixtures/lessjs (1.5)/less/mixins.less +++ /dev/null @@ -1,141 +0,0 @@ -.mixin { border: 1px solid black; } -.mixout { border-color: orange; } -.borders { border-style: dashed; } - -#namespace { - .borders { - border-style: dotted; - } - .biohazard { - content: "death"; - .man { - color: transparent; - } - } -} -#theme { - > .mixin { - background-color: grey; - } -} -#container { - color: black; - .mixin; - .mixout; - #theme > .mixin; -} - -#header { - .milk { - color: white; - .mixin; - #theme > .mixin; - } - #cookie { - .chips { - #namespace .borders; - .calories { - #container; - } - } - .borders; - } -} -.secure-zone { #namespace .biohazard .man; } -.direct { - #namespace > .borders; -} - -.bo, .bar { - width: 100%; -} -.bo { - border: 1px; -} -.ar.bo.ca { - color: black; -} -.jo.ki { - background: none; -} -.amp { - &.support { - color: orange; - .higher { - top: 0px; - } - &.deeper { - height: auto; - } - } -} -.extended { - .bo; - .jo.ki; - .amp.support; - .amp.support.higher; - .amp.support.deeper; -} -.do .re .mi .fa { - .sol .la { - .si { - color: cyan; - } - } -} -.mutli-selector-parents { - .do.re.mi.fa.sol.la.si; -} -.foo .bar { - .bar; -} -.has_parents() { - & .underParents { - color: red; - } -} -.has_parents(); -.parent { - .has_parents(); -} -.margin_between(@above, @below) { - * + & { margin-top: @above; } - legend + & { margin-top: 0; } - & + * { margin-top: @below; } -} -h1 { .margin_between(25px, 10px); } -h2 { .margin_between(20px, 8px); } -h3 { .margin_between(15px, 5px); } - -.mixin_def(@url, @position){ - background-image: @url; - background-position: @position; -} -.error{ - @s: "/"; - .mixin_def( "@{s}a.png", center center); -} -.recursion() { - color: black; -} -.test-rec { - .recursion { - .recursion(); - } -} -.paddingFloat(@padding) { padding-left: @padding; } - -.button { - .paddingFloat(((10px + 12) * 2)); - - &.large { .paddingFloat(((10em * 2) * 2)); } -} -.clearfix() { - // ... -} -.clearfix { - .clearfix(); -} -.foo { - .clearfix(); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/no-js-errors/no-js-errors.less b/test/Fixtures/lessjs (1.5)/less/no-js-errors/no-js-errors.less deleted file mode 100644 index 15ef8a45..00000000 --- a/test/Fixtures/lessjs (1.5)/less/no-js-errors/no-js-errors.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - a: `1 + 1`; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/no-js-errors/no-js-errors.txt b/test/Fixtures/lessjs (1.5)/less/no-js-errors/no-js-errors.txt deleted file mode 100644 index d81dd2bd..00000000 --- a/test/Fixtures/lessjs (1.5)/less/no-js-errors/no-js-errors.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: You are using JavaScript, which has been disabled. in {path}no-js-errors.less on line 2, column 6: -1 .a { -2 a: `1 + 1`; -3 } diff --git a/test/Fixtures/lessjs (1.5)/less/no-output.less b/test/Fixtures/lessjs (1.5)/less/no-output.less deleted file mode 100644 index b4e6a499..00000000 --- a/test/Fixtures/lessjs (1.5)/less/no-output.less +++ /dev/null @@ -1,2 +0,0 @@ -.mixin() { -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/operations.less b/test/Fixtures/lessjs (1.5)/less/operations.less deleted file mode 100644 index 3e483c8b..00000000 --- a/test/Fixtures/lessjs (1.5)/less/operations.less +++ /dev/null @@ -1,62 +0,0 @@ -#operations { - color: (#110000 + #000011 + #001100); // #111111 - height: (10px / 2px + 6px - 1px * 2); // 9px - width: (2 * 4 - 5em); // 3em - .spacing { - height: (10px / 2px+6px-1px*2); - width: (2 * 4-5em); - } - substraction: (20 - 10 - 5 - 5); // 0 - division: (20 / 5 / 4); // 1 -} - -@x: 4; -@y: 12em; - -.with-variables { - height: (@x + @y); // 16em - width: (12 + @y); // 24em - size: (5cm - @x); // 1cm -} - -.with-functions { - color: (rgb(200, 200, 200) / 2); - color: (2 * hsl(0, 50%, 50%)); - color: (rgb(10, 10, 10) + hsl(0, 50%, 50%)); -} - -@z: -2; - -.negative { - height: (2px + @z); // 0px - width: (2px - @z); // 4px -} - -.shorthands { - padding: -1px 2px 0 -4px; // -} - -.rem-dimensions { - font-size: (20rem / 5 + 1.5rem); // 5.5rem -} - -.colors { - color: #123; // #112233 - border-color: (#234 + #111111); // #334455 - background-color: (#222222 - #fff); // #000000 - .other { - color: (2 * #111); // #222222 - border-color: (#333333 / 3 + #111); // #222222 - } -} - -.negations { - @var: 4px; - variable: (-@var); // 4 - variable1: (-@var + @var); // 0 - variable2: (@var + -@var); // 0 - variable3: (@var - -@var); // 8 - variable4: (-@var - -@var); // 0 - paren: (-(@var)); // -4px - paren2: (-(2 + 2) * -@var); // 16 -} diff --git a/test/Fixtures/lessjs (1.5)/less/parens.less b/test/Fixtures/lessjs (1.5)/less/parens.less deleted file mode 100644 index deb41391..00000000 --- a/test/Fixtures/lessjs (1.5)/less/parens.less +++ /dev/null @@ -1,41 +0,0 @@ -.parens { - @var: 1px; - border: (@var * 2) solid black; - margin: (@var * 1) (@var + 2) (4 * 4) 3; - width: (6 * 6); - padding: 2px (6 * 6px); -} - -.more-parens { - @var: (2 * 2); - padding: (2 * @var) 4 4 (@var * 1px); - width-all: ((@var * @var) * 6); - width-first: ((@var * @var)) * 6; - width-keep: (@var * @var) * 6; - height-keep: (7 * 7) + (8 * 8); - height-all: ((7 * 7) + (8 * 8)); - height-parts: ((7 * 7)) + ((8 * 8)); - margin-keep: (4 * (5 + 5) / 2) - (@var * 2); - margin-parts: ((4 * (5 + 5) / 2)) - ((@var * 2)); - margin-all: ((4 * (5 + 5) / 2) + (-(@var * 2))); - border-radius-keep: 4px * (1 + 1) / @var + 3px; - border-radius-parts: ((4px * (1 + 1))) / ((@var + 3px)); - border-radius-all: (4px * (1 + 1) / @var + 3px); - //margin: (6 * 6)px; -} - -.negative { - @var: 1; - neg-var: -@var; // -1 ? - neg-var-paren: -(@var); // -(1) ? -} - -.nested-parens { - width: 2 * (4 * (2 + (1 + 6))) - 1; - height: ((2 + 3) * (2 + 3) / (9 - 4)) + 1; -} - -.mixed-units { - margin: 2px 4em 1 5pc; - padding: (2px + 4px) 1em 2px 2; -} diff --git a/test/Fixtures/lessjs (1.5)/less/rulesets.less b/test/Fixtures/lessjs (1.5)/less/rulesets.less deleted file mode 100644 index e81192db..00000000 --- a/test/Fixtures/lessjs (1.5)/less/rulesets.less +++ /dev/null @@ -1,30 +0,0 @@ -#first > .one { - > #second .two > #deux { - width: 50%; - #third { - &:focus { - color: black; - #fifth { - > #sixth { - .seventh #eighth { - + #ninth { - color: purple; - } - } - } - } - } - height: 100%; - } - #fourth, #five, #six { - color: #110000; - .seven, .eight > #nine { - border: 1px solid black; - } - #ten { - color: red; - } - } - } - font-size: 2em; -} diff --git a/test/Fixtures/lessjs (1.5)/less/scope.less b/test/Fixtures/lessjs (1.5)/less/scope.less deleted file mode 100644 index 36d37061..00000000 --- a/test/Fixtures/lessjs (1.5)/less/scope.less +++ /dev/null @@ -1,79 +0,0 @@ -@x: red; -@x: blue; -@z: transparent; -@mix: none; - -.mixin { - @mix: #989; -} -@mix: blue; -.tiny-scope { - color: @mix; // #989 - .mixin; -} - -.scope1 { - @y: orange; - @z: black; - color: @x; // blue - border-color: @z; // black - .hidden { - @x: #131313; - } - .scope2 { - @y: red; - color: @x; // blue - .scope3 { - @local: white; - color: @y; // red - border-color: @z; // black - background-color: @local; // white - } - } -} - -#namespace { - .scoped_mixin() { - @local-will-be-made-global: green; - .scope { - scoped-val: @local-will-be-made-global; - } - } -} - -#namespace > .scoped_mixin(); - -.setHeight(@h) { @height: 1024px; } -.useHeightInMixinCall(@h) { .useHeightInMixinCall { mixin-height: @h; } } -@mainHeight: 50%; -.setHeight(@mainHeight); -.heightIsSet { height: @height; } -.useHeightInMixinCall(@height); - -.importRuleset() { - .imported { - exists: true; - } -} -.importRuleset(); -.testImported { - .imported; -} - -@parameterDefault: 'top level'; -@anotherVariable: 'top level'; -//mixin uses top-level variables -.mixinNoParam(@parameter: @parameterDefault) when (@parameter = 'top level') { - default: @parameter; - scope: @anotherVariable; - sub-scope-only: @subScopeOnly; -} - -#allAreUsedHere { - //redefine top-level variables in different scope - @parameterDefault: 'inside'; - @anotherVariable: 'inside'; - @subScopeOnly: 'inside'; - //use the mixin - .mixinNoParam(); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/selectors.less b/test/Fixtures/lessjs (1.5)/less/selectors.less deleted file mode 100644 index ed7db7ce..00000000 --- a/test/Fixtures/lessjs (1.5)/less/selectors.less +++ /dev/null @@ -1,144 +0,0 @@ -h1, h2, h3 { - a, p { - &:hover { - color: red; - } - } -} - -#all { color: blue; } -#the { color: blue; } -#same { color: blue; } - -ul, li, div, q, blockquote, textarea { - margin: 0; -} - -td { - margin: 0; - padding: 0; -} - -td, input { - line-height: 1em; -} - -a { - color: red; - - &:hover { color: blue; } - - div & { color: green; } - - p & span { color: yellow; } -} - -.foo { - .bar, .baz { - & .qux { - display: block; - } - .qux & { - display: inline; - } - .qux& { - display: inline-block; - } - .qux & .biz { - display: none; - } - } -} - -.b { - &.c { - .a& { - color: red; - } - } -} - -.b { - .c & { - &.a { - color: red; - } - } -} - -.p { - .foo &.bar { - color: red; - } -} - -.p { - .foo&.bar { - color: red; - } -} - -.foo { - .foo + & { - background: amber; - } - & + & { - background: amber; - } -} - -.foo, .bar { - & + & { - background: amber; - } -} - -.foo, .bar { - a, b { - & > & { - background: amber; - } - } -} - -.other ::fnord { color: red } -.other::fnord { color: red } -.other { - ::bnord {color: red } - &::bnord {color: red } -} -// selector interpolation -@theme: blood; -@selector: ~".@{theme}"; -@{selector} { - color:red; -} -@{selector}red { - color: green; -} -.red { - #@{theme}.@{theme}&.black { - color:black; - } -} -@num: 3; -:nth-child(@{num}) { - selector: interpolated; -} -.test { - &:nth-child(odd):not(:nth-child(3)) { - color: #ff0000; - } -} -[prop], -[prop=10%], -[prop="value@{num}"], -[prop*="val@{num}"], -[|prop~="val@{num}"], -[*|prop$="val@{num}"], -[ns|prop^="val@{num}"], -[@{num}^="val@{num}"], -[@{num}=@{num}], -[@{num}] { - attributes: yes; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/sourcemaps/basic.less b/test/Fixtures/lessjs (1.5)/less/sourcemaps/basic.less deleted file mode 100644 index 4ee8b4f6..00000000 --- a/test/Fixtures/lessjs (1.5)/less/sourcemaps/basic.less +++ /dev/null @@ -1,27 +0,0 @@ -@var: black; - -.a() { - color: red; -} - -.b { - color: green; - .a(); - color: blue; - background: @var; -} - -.a, .b { - background: green; - .c, .d { - background: gray; - & + & { - color: red; - } - } -} - -.extend:extend(.a all) { - color: pink; -} -@import (inline) "imported.css"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/sourcemaps/imported.css b/test/Fixtures/lessjs (1.5)/less/sourcemaps/imported.css deleted file mode 100644 index 2ee35f06..00000000 --- a/test/Fixtures/lessjs (1.5)/less/sourcemaps/imported.css +++ /dev/null @@ -1,7 +0,0 @@ -/*comments*/ -.unused-css { - color: white; -} -.imported { - color: black; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.5)/less/static-urls/urls.less b/test/Fixtures/lessjs (1.5)/less/static-urls/urls.less deleted file mode 100644 index b0c7de09..00000000 --- a/test/Fixtures/lessjs (1.5)/less/static-urls/urls.less +++ /dev/null @@ -1,33 +0,0 @@ -@font-face { - src: url("/fonts/garamond-pro.ttf"); - src: local(Futura-Medium), - url(fonts.svg#MyGeometricModern) format("svg"); -} -#shorthands { - background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; -} -#misc { - background-image: url(images/image.jpg); -} -#data-uri { - background: url(data:image/png;charset=utf-8;base64, - kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ - k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U - kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700); -} - -#svg-data-uri { - background: transparent url('data:image/svg+xml, '); -} - -.comma-delimited { - background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg); -} -.values { - @a: 'Trebuchet'; - url: url(@a); -} - -@import "../import/import-and-relative-paths-test"; diff --git a/test/Fixtures/lessjs (1.5)/less/strings.less b/test/Fixtures/lessjs (1.5)/less/strings.less deleted file mode 100644 index c43e368d..00000000 --- a/test/Fixtures/lessjs (1.5)/less/strings.less +++ /dev/null @@ -1,57 +0,0 @@ -#strings { - background-image: url("http://son-of-a-banana.com"); - quotes: "~" "~"; - content: "#*%:&^,)!.(~*})"; - empty: ""; - brackets: "{" "}"; - escapes: "\"hello\" \\world"; - escapes2: "\"llo"; -} -#comments { - content: "/* hello */ // not-so-secret"; -} -#single-quote { - quotes: "'" "'"; - content: '""#!&""'; - empty: ''; - semi-colon: ';'; -} -#escaped { - filter: ~"DX.Transform.MS.BS.filter(opacity=50)"; -} -#one-line { image: url(http://tooks.com) } -#crazy { image: url(http://), "}", url("http://}") } -#interpolation { - @var: '/dev'; - url: "http://lesscss.org@{var}/image.jpg"; - - @var2: 256; - url2: "http://lesscss.org/image-@{var2}.jpg"; - - @var3: #456; - url3: "http://lesscss.org@{var3}"; - - @var4: hello; - url4: "http://lesscss.org/@{var4}"; - - @var5: 54.4px; - url5: "http://lesscss.org/@{var5}"; -} - -// multiple calls with string interpolation - -.mix-mul (@a: green) { - color: ~"@{a}"; -} -.mix-mul-class { - .mix-mul(blue); - .mix-mul(red); - .mix-mul(black); - .mix-mul(orange); -} - -@test: Arial, Verdana, San-Serif; -.watermark { - @family: ~"Univers, @{test}"; - family: @family; -} diff --git a/test/Fixtures/lessjs (1.5)/less/urls.less b/test/Fixtures/lessjs (1.5)/less/urls.less deleted file mode 100644 index 5ef87635..00000000 --- a/test/Fixtures/lessjs (1.5)/less/urls.less +++ /dev/null @@ -1,67 +0,0 @@ -@font-face { - src: url("/fonts/garamond-pro.ttf"); - src: local(Futura-Medium), - url(fonts.svg#MyGeometricModern) format("svg"); -} -#shorthands { - background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; - background: url("img.jpg") center / 100px; - background: #fff url(image.png) center / 1px 100px repeat-x scroll content-box padding-box; -} -#misc { - background-image: url(images/image.jpg); -} -#data-uri { - background: url(data:image/png;charset=utf-8;base64, - kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ - k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U - kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700); - background-image: url("http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700"); -} - -#svg-data-uri { - background: transparent url('data:image/svg+xml, '); -} - -.comma-delimited { - background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg); -} -.values { - @a: 'Trebuchet'; - url: url(@a); -} - -@import "import/import-and-relative-paths-test"; - -#data-uri { - uri: data-uri('image/jpeg;base64', '../data/image.jpg'); -} - -#data-uri-guess { - uri: data-uri('../data/image.jpg'); -} - -#data-uri-ascii { - uri-1: data-uri('text/html', '../data/page.html'); - uri-2: data-uri('../data/page.html'); -} - -#data-uri-toobig { - uri: data-uri('../data/data-uri-fail.png'); -} -.add_an_import(@file_to_import) { -@import "@{file_to_import}"; -} - -.add_an_import("file.css"); - -#svg-functions { - background-image: svg-gradient(to bottom, black, white); - background-image: svg-gradient(to bottom, black, orange 3%, white); - @green_5: green 5%; - @orange_percentage: 3%; - @orange_color: orange; - background-image: svg-gradient(to bottom, (mix(black, white) + #444) 1%, @orange_color @orange_percentage, ((@green_5)), white 95%); -} diff --git a/test/Fixtures/lessjs (1.5)/less/variables.less b/test/Fixtures/lessjs (1.5)/less/variables.less deleted file mode 100644 index e896f404..00000000 --- a/test/Fixtures/lessjs (1.5)/less/variables.less +++ /dev/null @@ -1,83 +0,0 @@ -@a: 2; -@x: (@a * @a); -@y: (@x + 1); -@z: (@x * 2 + @y); -@var: -1; - -.variables { - width: (@z + 1cm); // 14cm -} - -@b: @a * 10; -@c: #888; - -@fonts: "Trebuchet MS", Verdana, sans-serif; -@f: @fonts; - -@quotes: "~" "~"; -@q: @quotes; -@onePixel: 1px; - -.variables { - height: (@b + @x + 0px); // 24px - color: @c; - font-family: @f; - quotes: @q; -} - -.redef { - @var: 0; - .inition { - @var: 4; - @var: 2; - three: @var; - @var: 3; - } - zero: @var; -} - -.values { - minus-one: @var; - @a: 'Trebuchet'; - @multi: 'A', B, C; - font-family: @a, @a, @a; - color: @c !important; - multi: something @multi, @a; -} - -.variable-names { - @var: 'hello'; - @name: 'var'; - name: @@name; -} - -.alpha { - @var: 42; - filter: alpha(opacity=@var); -} - -.polluteMixin() { - @a: 'pollution'; -} -.testPollution { - @a: 'no-pollution'; - a: @a; - .polluteMixin(); - a: @a; -} - -.units { - width: @onePixel; - same-unit-as-previously: (@onePixel / @onePixel); - square-pixel-divided: (@onePixel * @onePixel / @onePixel); - odd-unit: unit((@onePixel * 4em / 2cm)); - percentage: (10 * 50%); - pixels: (50px * 10); - conversion-metric-a: (20mm + 1cm); - conversion-metric-b: (1cm + 20mm); - conversion-imperial: (1in + 72pt + 6pc); - custom-unit: (42octocats * 10); - custom-unit-cancelling: (8cats * 9dogs / 4cats); - mix-units: (1px + 1em); - invalid-units: (1px * 1px); -} diff --git a/test/Fixtures/lessjs (1.5)/less/whitespace.less b/test/Fixtures/lessjs (1.5)/less/whitespace.less deleted file mode 100644 index ab4804da..00000000 --- a/test/Fixtures/lessjs (1.5)/less/whitespace.less +++ /dev/null @@ -1,44 +0,0 @@ - - -.whitespace - { color: white; } - -.whitespace -{ - color: white; -} - .whitespace -{ color: white; } - -.whitespace{color:white;} -.whitespace { color : white ; } - -.white, -.space, -.mania -{ color: white; } - -.no-semi-column { color: white } -.no-semi-column { - color: white; - white-space: pre -} -.no-semi-column {border: 2px solid white} -.newlines { - background: the, - great, - wall; - border: 2px - solid - black; -} -.empty { - -} -.sel -.newline_ws .tab_ws { -color: -white; -background-position: 45 --23; -} diff --git a/test/Fixtures/lessjs (1.6)/css/charsets.css b/test/Fixtures/lessjs (1.6)/css/charsets.css deleted file mode 100644 index 9f44090c..00000000 --- a/test/Fixtures/lessjs (1.6)/css/charsets.css +++ /dev/null @@ -1 +0,0 @@ -@charset "UTF-8"; diff --git a/test/Fixtures/lessjs (1.6)/css/colors.css b/test/Fixtures/lessjs (1.6)/css/colors.css deleted file mode 100644 index 08a22abb..00000000 --- a/test/Fixtures/lessjs (1.6)/css/colors.css +++ /dev/null @@ -1,87 +0,0 @@ -#yelow #short { - color: #fea; -} -#yelow #long { - color: #ffeeaa; -} -#yelow #rgba { - color: rgba(255, 238, 170, 0.1); -} -#yelow #argb { - color: #1affeeaa; -} -#blue #short { - color: #00f; -} -#blue #long { - color: #0000ff; -} -#blue #rgba { - color: rgba(0, 0, 255, 0.1); -} -#blue #argb { - color: #1a0000ff; -} -#alpha #hsla { - color: rgba(61, 45, 41, 0.6); -} -#overflow .a { - color: #000000; -} -#overflow .b { - color: #ffffff; -} -#overflow .c { - color: #ffffff; -} -#overflow .d { - color: #00ff00; -} -#overflow .e { - color: rgba(0, 31, 255, 0.42); -} -#grey { - color: #c8c8c8; -} -#333333 { - color: #333333; -} -#808080 { - color: #808080; -} -#00ff00 { - color: #00ff00; -} -.lightenblue { - color: #3333ff; -} -.darkenblue { - color: #0000cc; -} -.unknowncolors { - color: blue2; - border: 2px solid superred; -} -.transparent { - color: transparent; - background-color: rgba(0, 0, 0, 0); -} -#alpha #fromvar { - opacity: 0.7; -} -#alpha #short { - opacity: 1; -} -#alpha #long { - opacity: 1; -} -#alpha #rgba { - opacity: 0.2; -} -#alpha #hsl { - opacity: 1; -} -#percentage { - color: 255; - border-color: rgba(255, 0, 0, 0.5); -} diff --git a/test/Fixtures/lessjs (1.6)/css/comments.css b/test/Fixtures/lessjs (1.6)/css/comments.css deleted file mode 100644 index b85f5b4f..00000000 --- a/test/Fixtures/lessjs (1.6)/css/comments.css +++ /dev/null @@ -1,69 +0,0 @@ -/******************\ -* * -* Comment Header * -* * -\******************/ -/* - - Comment - -*/ -/* - * Comment Test - * - * - cloudhead (http://cloudhead.net) - * - */ -/* Colors - * ------ - * #EDF8FC (background blue) - * #166C89 (darkest blue) - * - * Text: - * #333 (standard text) // A comment within a comment! - * #1F9EC9 (standard link) - * - */ -/* @group Variables -------------------- */ -#comments, -.comments { - /**/ - color: red; - /* A C-style comment */ - /* A C-style comment */ - background-color: orange; - font-size: 12px; - /* lost comment */ - content: "content"; - border: 1px solid black; - padding: 0; - margin: 2em; -} -/* commented out - #more-comments { - color: grey; - } -*/ -.selector, -.lots, -.comments { - color: #808080, /* blue */ #ffa500; - -webkit-border-radius: 2px /* webkit only */; - -moz-border-radius: 8px /* moz only with operation */; -} -.test { - color: 1px; -} -#last { - color: #0000ff; -} -/* */ -/* { */ -/* */ -/* */ -/* */ -#div { - color: #A33; -} -/* } */ diff --git a/test/Fixtures/lessjs (1.6)/css/compression/compression.css b/test/Fixtures/lessjs (1.6)/css/compression/compression.css deleted file mode 100644 index f9cc90a3..00000000 --- a/test/Fixtures/lessjs (1.6)/css/compression/compression.css +++ /dev/null @@ -1,3 +0,0 @@ -#colours{color1:#fea;color2:#fea;color3:rgba(255,238,170,0.1);string:"#ffeeaa";/*! but not this type - Note preserved whitespace - */}dimensions{val:.1px;val:0;val:4cm;val:.2;val:5;angles-must-have-unit:0deg;durations-must-have-unit:0s;length-doesnt-have-unit:0;width:auto\9}@page{marks:none;@top-left-corner{vertical-align:top}@top-left{vertical-align:top}}.shadow^.dom,body^^.shadow{display:done} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/css/css-3.css b/test/Fixtures/lessjs (1.6)/css/css-3.css deleted file mode 100644 index 61f635c2..00000000 --- a/test/Fixtures/lessjs (1.6)/css/css-3.css +++ /dev/null @@ -1,129 +0,0 @@ -.comma-delimited { - text-shadow: -1px -1px 1px #ff0000, 6px 5px 5px #ffff00; - -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset, 0pt 4px 6px rgba(255, 255, 255, 0.4) inset; - -webkit-transform: rotate(0deg); -} -@font-face { - font-family: Headline; - unicode-range: U+??????, U+0???, U+0-7F, U+A5; -} -.other { - -moz-transform: translate(0, 11em) rotate(-90deg); - transform: rotateX(45deg); -} -.item[data-cra_zy-attr1b-ut3=bold] { - font-weight: bold; -} -p:not([class*="lead"]) { - color: black; -} -input[type="text"].class#id[attr=32]:not(1) { - color: white; -} -div#id.class[a=1][b=2].class:not(1) { - color: white; -} -ul.comma > li:not(:only-child)::after { - color: white; -} -ol.comma > li:nth-last-child(2)::after { - color: white; -} -li:nth-child(4n+1), -li:nth-child(-5n), -li:nth-child(-n+2) { - color: white; -} -a[href^="http://"] { - color: black; -} -a[href$="http://"] { - color: black; -} -form[data-disabled] { - color: black; -} -p::before { - color: black; -} -#issue322 { - -webkit-animation: anim2 7s infinite ease-in-out; -} -@-webkit-keyframes frames { - 0% { - border: 1px; - } - 5.5% { - border: 2px; - } - 100% { - border: 3px; - } -} -@keyframes fontbulger1 { - to { - font-size: 15px; - } - from, - to { - font-size: 12px; - } - 0%, - 100% { - font-size: 12px; - } -} -.units { - font: 1.2rem/2rem; - font: 8vw/9vw; - font: 10vh/12vh; - font: 12vm/15vm; - font: 12vmin/15vmin; - font: 1.2ch/1.5ch; -} -@supports ( box-shadow: 2px 2px 2px black ) or - ( -moz-box-shadow: 2px 2px 2px black ) { - .outline { - box-shadow: 2px 2px 2px black; - -moz-box-shadow: 2px 2px 2px black; - } -} -@-x-document url-prefix(""github.com"") { - h1 { - color: red; - } -} -@viewport { - font-size: 10px; -} -@namespace foo url(http://www.example.com); -foo|h1 { - color: blue; -} -foo|* { - color: yellow; -} -|h1 { - color: red; -} -*|h1 { - color: green; -} -h1 { - color: green; -} -.upper-test { - UpperCaseProperties: allowed; -} -@host { - div { - display: block; - } -} -::distributed(input::placeholder) { - color: #b3b3b3; -} -.shadow ^ .dom, -body ^^ .shadow { - display: done; -} diff --git a/test/Fixtures/lessjs (1.6)/css/css-escapes.css b/test/Fixtures/lessjs (1.6)/css/css-escapes.css deleted file mode 100644 index 4d343aa6..00000000 --- a/test/Fixtures/lessjs (1.6)/css/css-escapes.css +++ /dev/null @@ -1,24 +0,0 @@ -.escape\|random\|char { - color: red; -} -.mixin\!tUp { - font-weight: bold; -} -.\34 04 { - background: red; -} -.\34 04 strong { - color: #ff00ff; - font-weight: bold; -} -.trailingTest\+ { - color: red; -} -/* This hideous test of hideousness checks for the selector "blockquote" with various permutations of hex escapes */ -\62\6c\6f \63 \6B \0071 \000075o\74 e { - color: silver; -} -[ng\:cloak], -ng\:form { - display: none; -} diff --git a/test/Fixtures/lessjs (1.6)/css/css-guards.css b/test/Fixtures/lessjs (1.6)/css/css-guards.css deleted file mode 100644 index f4b8a108..00000000 --- a/test/Fixtures/lessjs (1.6)/css/css-guards.css +++ /dev/null @@ -1,37 +0,0 @@ -.light { - color: green; -} -.see-the { - color: green; -} -.hide-the { - color: green; -} -.multiple-conditions-1 { - color: red; -} -.inheritance .test { - color: black; -} -.inheritance:hover { - color: pink; -} -.clsWithGuard { - dispaly: none; -} -.dont-split-me-up { - width: 1px; - color: red; - height: 1px; -} - + .dont-split-me-up { - sibling: true; -} -.scope-check { - sub-prop: 2px; - prop: 1px; -} -.scope-check-2 { - sub-prop: 2px; - prop: 1px; -} diff --git a/test/Fixtures/lessjs (1.6)/css/css.css b/test/Fixtures/lessjs (1.6)/css/css.css deleted file mode 100644 index b011a7e3..00000000 --- a/test/Fixtures/lessjs (1.6)/css/css.css +++ /dev/null @@ -1,95 +0,0 @@ -@charset "utf-8"; -div { - color: black; -} -div { - width: 99%; -} -* { - min-width: 45em; -} -h1, -h2 > a > p, -h3 { - color: none; -} -div.class { - color: blue; -} -div#id { - color: green; -} -.class#id { - color: purple; -} -.one.two.three { - color: grey; -} -@media print { - * { - font-size: 3em; - } -} -@media screen { - * { - font-size: 10px; - } -} -@font-face { - font-family: 'Garamond Pro'; -} -a:hover, -a:link { - color: #999; -} -p, -p:first-child { - text-transform: none; -} -q:lang(no) { - quotes: none; -} -p + h1 { - font-size: 2.2em; -} -#shorthands { - border: 1px solid #000; - font: 12px/16px Arial; - font: 100%/16px Arial; - margin: 1px 0; - padding: 0 auto; -} -#more-shorthands { - margin: 0; - padding: 1px 0 2px 0; - font: normal small / 20px 'Trebuchet MS', Verdana, sans-serif; - font: 0/0 a; - border-radius: 5px / 10px; -} -.misc { - -moz-border-radius: 2px; - display: -moz-inline-stack; - width: .1em; - background-color: #009998; - background: -webkit-gradient(linear, left top, left bottom, from(#ff0000), to(#0000ff)); - margin: ; - filter: alpha(opacity=100); - width: auto\9; -} -.misc .nested-multiple { - multiple-semi-colons: yes; -} -#important { - color: red !important; - width: 100%!important; - height: 20px ! important; -} -@font-face { - font-family: font-a; -} -@font-face { - font-family: font-b; -} -.æøå { - margin: 0; -} diff --git a/test/Fixtures/lessjs (1.6)/css/debug/linenumbers-all.css b/test/Fixtures/lessjs (1.6)/css/debug/linenumbers-all.css deleted file mode 100644 index bf156312..00000000 --- a/test/Fixtures/lessjs (1.6)/css/debug/linenumbers-all.css +++ /dev/null @@ -1,49 +0,0 @@ -@charset "UTF-8"; -/* line 3, {pathimport}test.less */ -@media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000033}} -/* @charset "ISO-8859-1"; */ -/* line 23, {pathimport}test.less */ -@media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\0000323}} -.tst3 { - color: grey; -} -/* line 15, {path}linenumbers.less */ -@media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\0000315}} -.test1 { - color: black; -} -/* line 6, {path}linenumbers.less */ -@media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\000036}} -.test2 { - color: red; -} -@media all { - /* line 5, {pathimport}test.less */ - @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000035}} - .tst { - color: black; - } -} -@media all and screen { - /* line 7, {pathimport}test.less */ - @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000037}} - .tst { - color: red; - } - /* line 9, {pathimport}test.less */ - @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000039}} - .tst .tst3 { - color: white; - } -} -/* line 18, {pathimport}test.less */ -@media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\0000318}} -.tst2 { - color: white; -} -/* line 27, {path}linenumbers.less */ -@media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\0000327}} -.test { - color: red; - width: 2; -} diff --git a/test/Fixtures/lessjs (1.6)/css/debug/linenumbers-comments.css b/test/Fixtures/lessjs (1.6)/css/debug/linenumbers-comments.css deleted file mode 100644 index ddeb0c4d..00000000 --- a/test/Fixtures/lessjs (1.6)/css/debug/linenumbers-comments.css +++ /dev/null @@ -1,40 +0,0 @@ -@charset "UTF-8"; -/* line 3, {pathimport}test.less */ -/* @charset "ISO-8859-1"; */ -/* line 23, {pathimport}test.less */ -.tst3 { - color: grey; -} -/* line 15, {path}linenumbers.less */ -.test1 { - color: black; -} -/* line 6, {path}linenumbers.less */ -.test2 { - color: red; -} -@media all { - /* line 5, {pathimport}test.less */ - .tst { - color: black; - } -} -@media all and screen { - /* line 7, {pathimport}test.less */ - .tst { - color: red; - } - /* line 9, {pathimport}test.less */ - .tst .tst3 { - color: white; - } -} -/* line 18, {pathimport}test.less */ -.tst2 { - color: white; -} -/* line 27, {path}linenumbers.less */ -.test { - color: red; - width: 2; -} diff --git a/test/Fixtures/lessjs (1.6)/css/debug/linenumbers-mediaquery.css b/test/Fixtures/lessjs (1.6)/css/debug/linenumbers-mediaquery.css deleted file mode 100644 index 9d272f47..00000000 --- a/test/Fixtures/lessjs (1.6)/css/debug/linenumbers-mediaquery.css +++ /dev/null @@ -1,40 +0,0 @@ -@charset "UTF-8"; -@media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000033}} -/* @charset "ISO-8859-1"; */ -@media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\0000323}} -.tst3 { - color: grey; -} -@media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\0000315}} -.test1 { - color: black; -} -@media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\000036}} -.test2 { - color: red; -} -@media all { - @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000035}} - .tst { - color: black; - } -} -@media all and screen { - @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000037}} - .tst { - color: red; - } - @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000039}} - .tst .tst3 { - color: white; - } -} -@media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\0000318}} -.tst2 { - color: white; -} -@media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\0000327}} -.test { - color: red; - width: 2; -} diff --git a/test/Fixtures/lessjs (1.6)/css/empty.css b/test/Fixtures/lessjs (1.6)/css/empty.css deleted file mode 100644 index e69de29b..00000000 diff --git a/test/Fixtures/lessjs (1.6)/css/extend-chaining.css b/test/Fixtures/lessjs (1.6)/css/extend-chaining.css deleted file mode 100644 index 820e134f..00000000 --- a/test/Fixtures/lessjs (1.6)/css/extend-chaining.css +++ /dev/null @@ -1,81 +0,0 @@ -.a, -.b, -.c { - color: black; -} -.f, -.e, -.d { - color: black; -} -.g.h, -.i.j.h, -.k.j.h { - color: black; -} -.i.j, -.k.j { - color: white; -} -.l, -.m, -.n, -.o, -.p, -.q, -.r, -.s, -.t { - color: black; -} -.u, -.v.u.v { - color: black; -} -.w, -.v.w.v { - color: black; -} -.x, -.y, -.z { - color: x; -} -.y, -.z, -.x { - color: y; -} -.z, -.x, -.y { - color: z; -} -.va, -.vb, -.vc { - color: black; -} -.vb, -.vc { - color: white; -} -@media tv { - .ma, - .mb, - .mc { - color: black; - } - .md, - .ma, - .mb, - .mc { - color: white; - } -} -@media tv and plasma { - .me, - .mf { - background: red; - } -} diff --git a/test/Fixtures/lessjs (1.6)/css/extend-clearfix.css b/test/Fixtures/lessjs (1.6)/css/extend-clearfix.css deleted file mode 100644 index 966892a2..00000000 --- a/test/Fixtures/lessjs (1.6)/css/extend-clearfix.css +++ /dev/null @@ -1,19 +0,0 @@ -.clearfix, -.foo, -.bar { - *zoom: 1; -} -.clearfix:after, -.foo:after, -.bar:after { - content: ''; - display: block; - clear: both; - height: 0; -} -.foo { - color: red; -} -.bar { - color: blue; -} diff --git a/test/Fixtures/lessjs (1.6)/css/extend-exact.css b/test/Fixtures/lessjs (1.6)/css/extend-exact.css deleted file mode 100644 index beff4133..00000000 --- a/test/Fixtures/lessjs (1.6)/css/extend-exact.css +++ /dev/null @@ -1,37 +0,0 @@ -.replace.replace .replace, -.c.replace + .replace .replace, -.replace.replace .c, -.c.replace + .replace .c, -.rep_ace { - prop: copy-paste-replace; -} -.a .b .c { - prop: not_effected; -} -.a, -.effected { - prop: is_effected; -} -.a .b { - prop: not_effected; -} -.a .b.c { - prop: not_effected; -} -.c .b .a, -.a .b .a, -.c .a .a, -.a .a .a, -.c .b .c, -.a .b .c, -.c .a .c, -.a .a .c { - prop: not_effected; -} -.e.e, -.dbl { - prop: extend-double; -} -.e.e:hover { - hover: not-extended; -} diff --git a/test/Fixtures/lessjs (1.6)/css/extend-media.css b/test/Fixtures/lessjs (1.6)/css/extend-media.css deleted file mode 100644 index 23bd7b85..00000000 --- a/test/Fixtures/lessjs (1.6)/css/extend-media.css +++ /dev/null @@ -1,24 +0,0 @@ -.ext1 .ext2, -.all .ext2 { - background: black; -} -@media tv { - .ext1 .ext3, - .tv-lowres .ext3, - .all .ext3 { - color: white; - } - .tv-lowres { - background: blue; - } -} -@media tv and hires { - .ext1 .ext4, - .tv-hires .ext4, - .all .ext4 { - color: green; - } - .tv-hires { - background: red; - } -} diff --git a/test/Fixtures/lessjs (1.6)/css/extend-nest.css b/test/Fixtures/lessjs (1.6)/css/extend-nest.css deleted file mode 100644 index 2c3905d9..00000000 --- a/test/Fixtures/lessjs (1.6)/css/extend-nest.css +++ /dev/null @@ -1,57 +0,0 @@ -.sidebar, -.sidebar2, -.type1 .sidebar3, -.type2.sidebar4 { - width: 300px; - background: red; -} -.sidebar .box, -.sidebar2 .box, -.type1 .sidebar3 .box, -.type2.sidebar4 .box { - background: #FFF; - border: 1px solid #000; - margin: 10px 0; -} -.sidebar2 { - background: blue; -} -.type1 .sidebar3 { - background: green; -} -.type2.sidebar4 { - background: red; -} -.button, -.submit { - color: black; -} -.button:hover, -.submit:hover { - color: white; -} -.button2 :hover { - nested: white; -} -.button2 :hover { - notnested: black; -} -.amp-test-h, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e.amp-test-g { - test: extended by masses of selectors; -} diff --git a/test/Fixtures/lessjs (1.6)/css/extend-selector.css b/test/Fixtures/lessjs (1.6)/css/extend-selector.css deleted file mode 100644 index da47254b..00000000 --- a/test/Fixtures/lessjs (1.6)/css/extend-selector.css +++ /dev/null @@ -1,80 +0,0 @@ -.error, -.badError { - border: 1px #f00; - background: #fdd; -} -.error.intrusion, -.badError.intrusion { - font-size: 1.3em; - font-weight: bold; -} -.intrusion .error, -.intrusion .badError { - display: none; -} -.badError { - border-width: 3px; -} -.foo .bar, -.foo .baz, -.ext1 .ext2 .bar, -.ext1 .ext2 .baz, -.ext3 .bar, -.ext3 .baz, -.ext4 .bar, -.ext4 .baz { - display: none; -} -div.ext5, -.ext6 > .ext5, -div.ext7, -.ext6 > .ext7 { - width: 100px; -} -.ext, -.a .c, -.b .c { - test: 1; -} -.a, -.b { - test: 2; -} -.a .c, -.b .c { - test: 3; -} -.a .c .d, -.b .c .d { - test: 4; -} -.replace.replace .replace, -.c.replace + .replace .replace, -.replace.replace .c, -.c.replace + .replace .c, -.rep_ace.rep_ace .rep_ace, -.c.rep_ace + .rep_ace .rep_ace, -.rep_ace.rep_ace .c, -.c.rep_ace + .rep_ace .c { - prop: copy-paste-replace; -} -.attributes [data="test"], -.attributes .attributes .attribute-test { - extend: attributes; -} -.attributes [data], -.attributes .attributes .attribute-test2 { - extend: attributes2; -} -.attributes [data="test3"], -.attributes .attributes .attribute-test { - extend: attributes2; -} -.header .header-nav, -.footer .footer-nav { - background: red; -} -.header .header-nav:before, -.footer .footer-nav:before { - background: blue; -} diff --git a/test/Fixtures/lessjs (1.6)/css/extend.css b/test/Fixtures/lessjs (1.6)/css/extend.css deleted file mode 100644 index 2895641a..00000000 --- a/test/Fixtures/lessjs (1.6)/css/extend.css +++ /dev/null @@ -1,76 +0,0 @@ -.error, -.badError { - border: 1px #f00; - background: #fdd; -} -.error.intrusion, -.badError.intrusion { - font-size: 1.3em; - font-weight: bold; -} -.intrusion .error, -.intrusion .badError { - display: none; -} -.badError { - border-width: 3px; -} -.foo .bar, -.foo .baz, -.ext1 .ext2 .bar, -.ext1 .ext2 .baz, -.ext3 .bar, -.ext3 .baz, -.foo .ext3, -.ext4 .bar, -.ext4 .baz, -.foo .ext4 { - display: none; -} -div.ext5, -.ext6 > .ext5, -div.ext7, -.ext6 > .ext7 { - width: 100px; -} -.ext8.ext9, -.fuu { - result: add-foo; -} -.ext8 .ext9, -.ext8 + .ext9, -.ext8 > .ext9, -.buu, -.zap, -.zoo { - result: bar-matched; -} -.ext8.nomatch { - result: none; -} -.ext8 .ext9, -.buu { - result: match-nested-bar; -} -.ext8.ext9, -.fuu { - result: match-nested-foo; -} -.aa, -.cc { - color: black; -} -.aa .dd, -.aa .ee { - background: red; -} -.bb, -.cc, -.ee, -.ff { - background: red; -} -.bb .bb, -.ff .ff { - color: black; -} diff --git a/test/Fixtures/lessjs (1.6)/css/extract-and-length.css b/test/Fixtures/lessjs (1.6)/css/extract-and-length.css deleted file mode 100644 index f550e201..00000000 --- a/test/Fixtures/lessjs (1.6)/css/extract-and-length.css +++ /dev/null @@ -1,133 +0,0 @@ -.multiunit { - length: 6; - extract: abc "abc" 1 1px 1% #112233; -} -.incorrect-index { - v1: extract(a b c, 5); - v2: extract(a, b, c, -2); -} -.scalar { - var-value: variable; - var-length: 1; - ill-index: extract(variable, 2); - name-value: name; - string-value: "string"; - number-value: 12345678; - color-value: #0000ff; - rgba-value: rgba(80, 160, 240, 0.67); - empty-value: ; - name-length: 1; - string-length: 1; - number-length: 1; - color-length: 1; - rgba-length: 1; - empty-length: 1; -} -.mixin-arguments-1 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-2 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-3 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-4 { - length: 0; - extract: extract(, 2) | extract(, 1); -} -.mixin-arguments-2 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-3 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-4 { - length: 3; - extract: c | b; -} -.mixin-arguments-2 { - length: 4; - extract: 3 | 2 | 1; -} -.mixin-arguments-3 { - length: 4; - extract: 3 | 2 | 1; -} -.mixin-arguments-4 { - length: 3; - extract: 3 | 2; -} -.md-space-comma { - length-1: 3; - extract-1: 1 2 3; - length-2: 3; - extract-2: 2; -} -.md-space-comma-as-args-2 { - length: 3; - extract: "x" "y" "z" | 1 2 3 | a b c; -} -.md-space-comma-as-args-3 { - length: 3; - extract: "x" "y" "z" | 1 2 3 | a b c; -} -.md-space-comma-as-args-4 { - length: 2; - extract: "x" "y" "z" | 1 2 3; -} -.md-cat-space-comma { - length-1: 3; - extract-1: 1 2 3; - length-2: 3; - extract-2: 2; -} -.md-cat-space-comma-as-args-2 { - length: 3; - extract: "x" "y" "z" | 1 2 3 | a b c; -} -.md-cat-space-comma-as-args-3 { - length: 3; - extract: "x" "y" "z" | 1 2 3 | a b c; -} -.md-cat-space-comma-as-args-4 { - length: 2; - extract: "x" "y" "z" | 1 2 3; -} -.md-cat-comma-space { - length-1: 3; - extract-1: 1, 2, 3; - length-2: 3; - extract-2: 2; -} -.md-cat-comma-space-as-args-1 { - length: 3; - extract: "x", "y", "z" | 1, 2, 3 | a, b, c; -} -.md-cat-comma-space-as-args-2 { - length: 3; - extract: "x", "y", "z" | 1, 2, 3 | a, b, c; -} -.md-cat-comma-space-as-args-3 { - length: 3; - extract: "x", "y", "z" | 1, 2, 3 | a, b, c; -} -.md-cat-comma-space-as-args-4 { - length: 0; - extract: extract(, 2) | extract(, 1); -} -.md-3D { - length-1: 2; - extract-1: a b c d, 1 2 3 4; - length-2: 2; - extract-2: 5 6 7 8; - length-3: 4; - extract-3: 7; - length-4: 1; - extract-4: 8; -} diff --git a/test/Fixtures/lessjs (1.6)/css/functions.css b/test/Fixtures/lessjs (1.6)/css/functions.css deleted file mode 100644 index 2c7896df..00000000 --- a/test/Fixtures/lessjs (1.6)/css/functions.css +++ /dev/null @@ -1,141 +0,0 @@ -#functions { - color: #660000; - width: 16; - height: undefined("self"); - border-width: 5; - variable: 11; - background: linear-gradient(#000000, #ffffff); -} -#built-in { - escaped: -Some::weird(#thing, y); - lighten: #ffcccc; - darken: #330000; - saturate: #203c31; - desaturate: #29332f; - greyscale: #2e2e2e; - hsl-clamp: #ffffff; - spin-p: #bf6a40; - spin-n: #bf4055; - luma-white: 100%; - luma-black: 0%; - luma-black-alpha: 0%; - luma-red: 21%; - luma-green: 72%; - luma-blue: 7%; - luma-yellow: 93%; - luma-cyan: 79%; - luma-white-alpha: 50%; - contrast-filter: contrast(30%); - saturate-filter: saturate(5%); - contrast-white: #000000; - contrast-black: #ffffff; - contrast-red: #ffffff; - contrast-green: #000000; - contrast-blue: #ffffff; - contrast-yellow: #000000; - contrast-cyan: #000000; - contrast-light: #111111; - contrast-dark: #eeeeee; - contrast-wrongorder: #111111; - contrast-light-thresh: #111111; - contrast-dark-thresh: #eeeeee; - contrast-high-thresh: #eeeeee; - contrast-low-thresh: #111111; - contrast-light-thresh-per: #111111; - contrast-dark-thresh-per: #eeeeee; - contrast-high-thresh-per: #eeeeee; - contrast-low-thresh-per: #111111; - format: "rgb(32, 128, 64)"; - format-string: "hello world"; - format-multiple: "hello earth 2"; - format-url-encode: "red is %23ff0000"; - eformat: rgb(32, 128, 64); - unitless: 12; - unit: 14em; - hue: 98; - saturation: 12%; - lightness: 95%; - hsvhue: 98; - hsvsaturation: 12%; - hsvvalue: 95%; - red: 255; - green: 255; - blue: 255; - rounded: 11; - rounded-two: 10.67; - roundedpx: 3px; - roundedpx-three: 3.333px; - rounded-percentage: 10%; - ceil: 11px; - floor: 12px; - sqrt: 5px; - pi: 3.14159265; - mod: 2m; - abs: 4%; - tan: 0.90040404; - sin: 0.17364818; - cos: 0.84385396; - atan: 0.1rad; - atan: 34deg; - atan: 45deg; - pow: 64px; - pow: 64; - pow: 27; - min: 0; - min: min("junk", 5); - min: 3pt; - max: 3; - max: max(8%, 1cm); - percentage: 20%; - color: #ff0011; - tint: #898989; - tint-full: #ffffff; - tint-percent: #898989; - tint-negative: #656565; - shade: #686868; - shade-full: #000000; - shade-percent: #686868; - shade-negative: #868686; - fade-out: rgba(255, 0, 0, 0.95); - fade-in: rgba(255, 0, 0, 0.95); - hsv: #4d2926; - hsva: rgba(77, 40, 38, 0.2); - mix: #ff3300; - mix-0: #ffff00; - mix-100: #ff0000; - mix-weightless: #ff8000; - mixt: rgba(255, 0, 0, 0.5); -} -#built-in .is-a { - color: true; - color1: true; - color2: true; - color3: true; - keyword: true; - number: true; - string: true; - pixel: true; - percent: true; - em: true; - cat: true; -} -#alpha { - alpha: rgba(153, 94, 51, 0.6); - alpha2: 0.5; - alpha3: 0; -} -#blendmodes { - multiply: #ed0000; - screen: #f600f6; - overlay: #ed0000; - softlight: #fa0000; - hardlight: #0000ed; - difference: #f600f6; - exclusion: #f600f6; - average: #7b007b; - negation: #d73131; -} -#extract-and-length { - extract: 3 2 1 C B A; - length: 6; -} diff --git a/test/Fixtures/lessjs (1.6)/css/globalVars/extended.css b/test/Fixtures/lessjs (1.6)/css/globalVars/extended.css deleted file mode 100644 index 1149ac87..00000000 --- a/test/Fixtures/lessjs (1.6)/css/globalVars/extended.css +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Test - */ -#header { - color: #333333; - border-left: 1px; - border-right: 2px; -} -#footer { - color: #114411; - border-color: #f20d0d; -} diff --git a/test/Fixtures/lessjs (1.6)/css/globalVars/simple.css b/test/Fixtures/lessjs (1.6)/css/globalVars/simple.css deleted file mode 100644 index 55779d8b..00000000 --- a/test/Fixtures/lessjs (1.6)/css/globalVars/simple.css +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Test - */ -.class { - color: #ff0000; -} diff --git a/test/Fixtures/lessjs (1.6)/css/ie-filters.css b/test/Fixtures/lessjs (1.6)/css/ie-filters.css deleted file mode 100644 index 007aa536..00000000 --- a/test/Fixtures/lessjs (1.6)/css/ie-filters.css +++ /dev/null @@ -1,9 +0,0 @@ -.nav { - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=20); - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#333333", endColorstr="#000000", GradientType=0); -} -.evalTest1 { - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=30); - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=5); -} diff --git a/test/Fixtures/lessjs (1.6)/css/import-inline.css b/test/Fixtures/lessjs (1.6)/css/import-inline.css deleted file mode 100644 index f198d3c1..00000000 --- a/test/Fixtures/lessjs (1.6)/css/import-inline.css +++ /dev/null @@ -1,5 +0,0 @@ -this isn't very valid CSS. -@media (min-width: 600px) { - #css { color: yellow; } - -} diff --git a/test/Fixtures/lessjs (1.6)/css/import-interpolation.css b/test/Fixtures/lessjs (1.6)/css/import-interpolation.css deleted file mode 100644 index 16b7a150..00000000 --- a/test/Fixtures/lessjs (1.6)/css/import-interpolation.css +++ /dev/null @@ -1,6 +0,0 @@ -body { - width: 100%; -} -.a { - var: test; -} diff --git a/test/Fixtures/lessjs (1.6)/css/import-once.css b/test/Fixtures/lessjs (1.6)/css/import-once.css deleted file mode 100644 index 2f86b3b3..00000000 --- a/test/Fixtures/lessjs (1.6)/css/import-once.css +++ /dev/null @@ -1,15 +0,0 @@ -#import { - color: #ff0000; -} -body { - width: 100%; -} -.test-f { - height: 10px; -} -body { - width: 100%; -} -.test-f { - height: 10px; -} diff --git a/test/Fixtures/lessjs (1.6)/css/import-reference.css b/test/Fixtures/lessjs (1.6)/css/import-reference.css deleted file mode 100644 index d61df816..00000000 --- a/test/Fixtures/lessjs (1.6)/css/import-reference.css +++ /dev/null @@ -1,49 +0,0 @@ -/* - The media statement above is invalid (no selector) - We should ban invalid media queries with properties and no selector? -*/ -.visible { - color: red; -} -.visible .c { - color: green; -} -.visible { - color: green; -} -.visible:hover { - color: green; -} -.only-with-visible + .visible, -.visible + .only-with-visible, -.visible + .visible { - color: green; -} -.only-with-visible + .visible .sub, -.visible + .only-with-visible .sub, -.visible + .visible .sub { - color: green; -} -.b { - color: red; - color: green; -} -.b .c { - color: green; -} -.b:hover { - color: green; -} -.b + .b { - color: green; -} -.b + .b .sub { - color: green; -} -.y { - pulled-in: yes; -} -/* comment pulled in */ -.visible { - extend: test; -} diff --git a/test/Fixtures/lessjs (1.6)/css/import.css b/test/Fixtures/lessjs (1.6)/css/import.css deleted file mode 100644 index a3749181..00000000 --- a/test/Fixtures/lessjs (1.6)/css/import.css +++ /dev/null @@ -1,36 +0,0 @@ -@import url(http://fonts.googleapis.com/css?family=Open+Sans); -@import url(/absolute/something.css) screen and (color) and (max-width: 600px); -@import url("//ha.com/file.css") (min-width: 100px); -#import-test { - height: 10px; - color: #ff0000; - width: 10px; - height: 30%; -} -@media screen and (max-width: 600px) { - body { - width: 100%; - } -} -#import { - color: #ff0000; -} -.mixin { - height: 10px; - color: #ff0000; -} -@media screen and (max-width: 601px) { - #css { - color: yellow; - } -} -@media screen and (max-width: 602px) { - body { - width: 100%; - } -} -@media screen and (max-width: 603px) { - #css { - color: yellow; - } -} diff --git a/test/Fixtures/lessjs (1.6)/css/javascript.css b/test/Fixtures/lessjs (1.6)/css/javascript.css deleted file mode 100644 index 8268ab33..00000000 --- a/test/Fixtures/lessjs (1.6)/css/javascript.css +++ /dev/null @@ -1,23 +0,0 @@ -.eval { - js: 42; - js: 2; - js: "hello world"; - js: 1, 2, 3; - title: "string"; - ternary: true; - multiline: 2; -} -.scope { - var: 42; - escaped: 7px; -} -.vars { - width: 8; -} -.escape-interpol { - width: hello world; -} -.arrays { - ary: "1, 2, 3"; - ary1: "1, 2, 3"; -} diff --git a/test/Fixtures/lessjs (1.6)/css/lazy-eval.css b/test/Fixtures/lessjs (1.6)/css/lazy-eval.css deleted file mode 100644 index 1adfb8f3..00000000 --- a/test/Fixtures/lessjs (1.6)/css/lazy-eval.css +++ /dev/null @@ -1,3 +0,0 @@ -.lazy-eval { - width: 100%; -} diff --git a/test/Fixtures/lessjs (1.6)/css/legacy/legacy.css b/test/Fixtures/lessjs (1.6)/css/legacy/legacy.css deleted file mode 100644 index 2f9bb80b..00000000 --- a/test/Fixtures/lessjs (1.6)/css/legacy/legacy.css +++ /dev/null @@ -1,7 +0,0 @@ -@media (-o-min-device-pixel-ratio: 2/1) { - .test-math-and-units { - font: ignores 0/0 rules; - test-division: 7em; - simple: 2px; - } -} diff --git a/test/Fixtures/lessjs (1.6)/css/media.css b/test/Fixtures/lessjs (1.6)/css/media.css deleted file mode 100644 index 607f0e44..00000000 --- a/test/Fixtures/lessjs (1.6)/css/media.css +++ /dev/null @@ -1,219 +0,0 @@ -@media print { - .class { - color: blue; - } - .class .sub { - width: 42; - } - .top, - header > h1 { - color: #444444; - } -} -@media screen { - body { - max-width: 480; - } -} -@media all and (device-aspect-ratio: 16 / 9) { - body { - max-width: 800px; - } -} -@media all and (orientation: portrait) { - aside { - float: none; - } -} -@media handheld and (min-width: 42), screen and (min-width: 20em) { - body { - max-width: 480px; - } -} -@media print { - body { - padding: 20px; - } - body header { - background-color: red; - } -} -@media print and (orientation: landscape) { - body { - margin-left: 20px; - } -} -@media screen { - .sidebar { - width: 300px; - } -} -@media screen and (orientation: landscape) { - .sidebar { - width: 500px; - } -} -@media a and b { - .first .second .third { - width: 300px; - } - .first .second .fourth { - width: 3; - } -} -@media a and b and c { - .first .second .third { - width: 500px; - } -} -@media a, b and c { - body { - width: 95%; - } -} -@media a and x, b and c and x, a and y, b and c and y { - body { - width: 100%; - } -} -.a { - background: black; -} -@media handheld { - .a { - background: white; - } -} -@media handheld and (max-width: 100px) { - .a { - background: red; - } -} -.b { - background: black; -} -@media handheld { - .b { - background: white; - } -} -@media handheld and (max-width: 200px) { - .b { - background: red; - } -} -@media only screen and (max-width: 200px) { - body { - width: 480px; - } -} -@media print { - @page :left { - margin: 0.5cm; - } - @page :right { - margin: 0.5cm; - } - @page Test:first { - margin: 1cm; - } - @page :first { - size: 8.5in 11in; - - @top-left { - margin: 1cm; - } - @top-left-corner { - margin: 1cm; - } - @top-center { - margin: 1cm; - } - @top-right { - margin: 1cm; - } - @top-right-corner { - margin: 1cm; - } - @bottom-left { - margin: 1cm; - } - @bottom-left-corner { - margin: 1cm; - } - @bottom-center { - margin: 1cm; - } - @bottom-right { - margin: 1cm; - } - @bottom-right-corner { - margin: 1cm; - } - @left-top { - margin: 1cm; - } - @left-middle { - margin: 1cm; - } - @left-bottom { - margin: 1cm; - } - @right-top { - margin: 1cm; - } - @right-middle { - content: "Page " counter(page); - } - @right-bottom { - margin: 1cm; - } - } -} -@media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: 2/1), (min-resolution: 2dppx), (min-resolution: 128dpcm) { - .b { - background: red; - } -} -body { - background: red; -} -@media (max-width: 500px) { - body { - background: green; - } -} -@media (max-width: 1000px) { - body { - background: red; - background: blue; - } -} -@media (max-width: 1000px) and (max-width: 500px) { - body { - background: green; - } -} -@media (max-width: 1200px) { - /* a comment */ -} -@media (max-width: 1200px) and (max-width: 900px) { - body { - font-size: 11px; - } -} -@media (min-width: 480px) { - .nav-justified > li { - display: table-cell; - } -} -@media (min-width: 768px) and (min-width: 480px) { - .menu > li { - display: table-cell; - } -} -@media all and tv { - .all-and-tv-variables { - var: all-and-tv; - } -} diff --git a/test/Fixtures/lessjs (1.6)/css/merge.css b/test/Fixtures/lessjs (1.6)/css/merge.css deleted file mode 100644 index 18539f1a..00000000 --- a/test/Fixtures/lessjs (1.6)/css/merge.css +++ /dev/null @@ -1,26 +0,0 @@ -.test1 { - transform: rotate(90deg), skew(30deg), scale(2, 4); -} -.test2 { - transform: rotate(90deg), skew(30deg); - transform: scaleX(45deg); -} -.test3 { - transform: scaleX(45deg); - background: url(data://img1.png); -} -.test4 { - transform: rotate(90deg), skew(30deg); - transform: scale(2, 4) !important; -} -.test5 { - transform: rotate(90deg), skew(30deg); - transform: scale(2, 4) !important; -} -.test6 { - transform: scale(2, 4); -} -.test-interleaved { - transform: t1, t2, t3; - background: b1, b2, b3; -} diff --git a/test/Fixtures/lessjs (1.6)/css/mixins-args.css b/test/Fixtures/lessjs (1.6)/css/mixins-args.css deleted file mode 100644 index 2b6c5c96..00000000 --- a/test/Fixtures/lessjs (1.6)/css/mixins-args.css +++ /dev/null @@ -1,113 +0,0 @@ -#hidden { - color: transparent; -} -#hidden1 { - color: transparent; -} -.two-args { - color: blue; - width: 10px; - height: 99%; - border: 2px dotted #000000; -} -.one-arg { - width: 15px; - height: 49%; -} -.no-parens { - width: 5px; - height: 49%; -} -.no-args { - width: 5px; - height: 49%; -} -.var-args { - width: 45; - height: 17%; -} -.multi-mix { - width: 10px; - height: 29%; - margin: 4; - padding: 5; -} -body { - padding: 30px; - color: #ff0000; -} -.scope-mix { - width: 8; -} -.content { - width: 600px; -} -.content .column { - margin: 600px; -} -#same-var-name { - radius: 5px; -} -#var-inside { - width: 10px; -} -.arguments { - border: 1px solid #000000; - width: 1px; -} -.arguments2 { - border: 0px; - width: 0px; -} -.arguments3 { - border: 0px; - width: 0px; -} -.arguments4 { - border: 0 1 2 3 4; - rest: 1 2 3 4; - width: 0; -} -.edge-case { - border: "{"; - width: "{"; -} -.slash-vs-math { - border-radius: 2px/5px; - border-radius: 5px/10px; - border-radius: 6px; -} -.comma-vs-semi-colon { - one: a; - two: b, c; - one: d, e; - two: f; - one: g; - one: h; - one: i; - one: j; - one: k; - two: l; - one: m, n; - one: o, p; - two: q; - one: r, s; - two: t; -} -#named-conflict { - four: a, 11, 12, 13; - four: a, 21, 22, 23; -} -.test-mixin-default-arg { - defaults: 1px 1px 1px; - defaults: 2px 2px 2px; -} -.selector { - margin: 2, 2, 2, 2; -} -.selector2 { - margin: 2, 2, 2, 2; -} -.selector3 { - margin: 4; -} diff --git a/test/Fixtures/lessjs (1.6)/css/mixins-closure.css b/test/Fixtures/lessjs (1.6)/css/mixins-closure.css deleted file mode 100644 index b1021b6f..00000000 --- a/test/Fixtures/lessjs (1.6)/css/mixins-closure.css +++ /dev/null @@ -1,9 +0,0 @@ -.class { - width: 99px; -} -.overwrite { - width: 99px; -} -.nested .class { - width: 5px; -} diff --git a/test/Fixtures/lessjs (1.6)/css/mixins-guards-default-func.css b/test/Fixtures/lessjs (1.6)/css/mixins-guards-default-func.css deleted file mode 100644 index e47f05cf..00000000 --- a/test/Fixtures/lessjs (1.6)/css/mixins-guards-default-func.css +++ /dev/null @@ -1,129 +0,0 @@ -guard-default-basic-1-1 { - case: 1; -} -guard-default-basic-1-2 { - default: 2; -} -guard-default-basic-2-0 { - default: 0; -} -guard-default-basic-2-2 { - case: 2; -} -guard-default-basic-3-0 { - default: 0; -} -guard-default-basic-3-2 { - case: 2; -} -guard-default-basic-3-3 { - case: 3; -} -guard-default-definition-order-0 { - default: 0; -} -guard-default-definition-order-2 { - case: 2; -} -guard-default-definition-order-2 { - case: 3; -} -guard-default-out-of-guard-0 { - case-0: default(); - case-1: 1; - default: 2; - case-2: default(); -} -guard-default-out-of-guard-1 { - default: default(); -} -guard-default-out-of-guard-2 { - default: default(); -} -guard-default-expr-not-1 { - case: 1; - default: 1; -} -guard-default-expr-eq-true { - case: true; -} -guard-default-expr-eq-false { - case: false; - default: false; -} -guard-default-expr-or-1 { - case: 1; -} -guard-default-expr-or-2 { - case: 2; - default: 2; -} -guard-default-expr-or-3 { - default: 3; -} -guard-default-expr-and-1 { - case: 1; -} -guard-default-expr-and-2 { - case: 2; -} -guard-default-expr-and-3 { - default: 3; -} -guard-default-expr-always-1 { - case: 1; - default: 1; -} -guard-default-expr-always-2 { - default: 2; -} -guard-default-expr-never-1 { - case: 1; -} -guard-default-multi-1-0 { - case: 0; -} -guard-default-multi-1-1 { - default-1: 1; -} -guard-default-multi-2-1 { - default-1: no; -} -guard-default-multi-2-2 { - default-2: no; -} -guard-default-multi-2-3 { - default-3: 3; -} -guard-default-multi-3-blue { - case-2: #00008b; -} -guard-default-multi-3-green { - default-color: #008000; -} -guard-default-multi-3-foo { - case-1: I am 'foo'; -} -guard-default-multi-3-baz { - default-string: I am 'baz'; -} -guard-default-multi-4 { - always: 1; - always: 2; - case: 2; -} -guard-default-not-ambiguos-2 { - case: 1; - not-default: 2; -} -guard-default-not-ambiguos-3 { - case: 1; - not-default-1: 2; - not-default-2: 2; -} -guard-default-scopes-3 { - 3: when default; -} -guard-default-scopes-1 { - 1: no condition; -} diff --git a/test/Fixtures/lessjs (1.6)/css/mixins-guards.css b/test/Fixtures/lessjs (1.6)/css/mixins-guards.css deleted file mode 100644 index 25e6f287..00000000 --- a/test/Fixtures/lessjs (1.6)/css/mixins-guards.css +++ /dev/null @@ -1,82 +0,0 @@ -.light1 { - color: white; - margin: 1px; -} -.light2 { - color: black; - margin: 1px; -} -.max1 { - width: 6; -} -.max2 { - width: 8; -} -.glob1 { - margin: auto auto; -} -.ops1 { - height: gt-or-eq; - height: lt-or-eq; - height: lt-or-eq-alias; -} -.ops2 { - height: gt-or-eq; - height: not-eq; -} -.ops3 { - height: lt-or-eq; - height: lt-or-eq-alias; - height: not-eq; -} -.default1 { - content: default; -} -.test1 { - content: "true."; -} -.test2 { - content: "false."; -} -.test3 { - content: "false."; -} -.test4 { - content: "false."; -} -.test5 { - content: "false."; -} -.bool1 { - content: true and true; - content: true; - content: false, true; - content: false and true and true, true; - content: false, true and true; - content: false, false, true; - content: false, true and true and true, false; - content: not false; - content: not false and false, not false; -} -.equality-units { - test: pass; -} -.colorguardtest { - content: is #ff0000; - content: is not #0000ff its #ff0000; - content: is not #0000ff its #800080; -} -.stringguardtest { - content: is theme1; - content: is not theme2; - content: is theme1 no quotes; -} -#tryNumberPx { - catch: all; - declare: 4; - declare: 4px; -} -.call-lock-mixin .call-inner-lock-mixin { - a: 1; - x: 1; -} diff --git a/test/Fixtures/lessjs (1.6)/css/mixins-important.css b/test/Fixtures/lessjs (1.6)/css/mixins-important.css deleted file mode 100644 index b100af7f..00000000 --- a/test/Fixtures/lessjs (1.6)/css/mixins-important.css +++ /dev/null @@ -1,45 +0,0 @@ -.class { - border: 1; - boxer: 1; - border-width: 1; - border: 2 !important; - boxer: 2 !important; - border-width: 2 !important; - border: 3; - boxer: 3; - border-width: 3; - border: 4 !important; - boxer: 4 !important; - border-width: 4 !important; - border: 5; - boxer: 5; - border-width: 5; - border: 0 !important; - boxer: 0 !important; - border-width: 0 !important; - border: 9 !important; - border: 9; - boxer: 9; - border-width: 9; -} -.class .inner { - test: 1; -} -.class .inner { - test: 2 !important; -} -.class .inner { - test: 3; -} -.class .inner { - test: 4 !important; -} -.class .inner { - test: 5; -} -.class .inner { - test: 0 !important; -} -.class .inner { - test: 9; -} diff --git a/test/Fixtures/lessjs (1.6)/css/mixins-interpolated.css b/test/Fixtures/lessjs (1.6)/css/mixins-interpolated.css deleted file mode 100644 index 637b5b68..00000000 --- a/test/Fixtures/lessjs (1.6)/css/mixins-interpolated.css +++ /dev/null @@ -1,39 +0,0 @@ -.foo { - a: 1; -} -.foo { - a: 2; -} -#foo { - a: 3; -} -#foo { - a: 4; -} -mi-test-a { - a: 1; - a: 2; - a: 3; - a: 4; -} -.b .bb.foo-xxx .yyy-foo#foo .foo.bbb { - b: 1; -} -mi-test-b { - b: 1; -} -#foo-foo > .bar .baz { - c: c; -} -mi-test-c-1 > .bar .baz { - c: c; -} -mi-test-c-2 .baz { - c: c; -} -mi-test-c-3 { - c: c; -} -mi-test-d { - gender: "Male"; -} diff --git a/test/Fixtures/lessjs (1.6)/css/mixins-named-args.css b/test/Fixtures/lessjs (1.6)/css/mixins-named-args.css deleted file mode 100644 index e460aa10..00000000 --- a/test/Fixtures/lessjs (1.6)/css/mixins-named-args.css +++ /dev/null @@ -1,27 +0,0 @@ -.named-arg { - color: blue; - width: 5px; - height: 99%; - args: 1px 100%; - text-align: center; -} -.class { - width: 5px; - height: 19%; - args: 1px 20%; -} -.all-args-wrong-args { - width: 10px; - height: 9%; - args: 2px 10%; -} -.named-args2 { - width: 15px; - height: 49%; - color: #646464; -} -.named-args3 { - width: 5px; - height: 29%; - color: #123456; -} diff --git a/test/Fixtures/lessjs (1.6)/css/mixins-nested.css b/test/Fixtures/lessjs (1.6)/css/mixins-nested.css deleted file mode 100644 index 6378c475..00000000 --- a/test/Fixtures/lessjs (1.6)/css/mixins-nested.css +++ /dev/null @@ -1,14 +0,0 @@ -.class .inner { - height: 300; -} -.class .inner .innest { - width: 30; - border-width: 60; -} -.class2 .inner { - height: 600; -} -.class2 .inner .innest { - width: 60; - border-width: 120; -} diff --git a/test/Fixtures/lessjs (1.6)/css/mixins-pattern.css b/test/Fixtures/lessjs (1.6)/css/mixins-pattern.css deleted file mode 100644 index 8b828335..00000000 --- a/test/Fixtures/lessjs (1.6)/css/mixins-pattern.css +++ /dev/null @@ -1,47 +0,0 @@ -.zero { - variadic: true; - zero: 0; - one: 1; - two: 2; - three: 3; -} -.one { - variadic: true; - one: 1; - one-req: 1; - two: 2; - three: 3; -} -.two { - variadic: true; - two: 2; - three: 3; -} -.three { - variadic: true; - three-req: 3; - three: 3; -} -.left { - left: 1; -} -.right { - right: 1; -} -.border-right { - color: black; - border-right: 4px; -} -.border-left { - color: black; - border-left: 4px; -} -.only-right { - right: 33; -} -.only-left { - left: 33; -} -.left-right { - both: 330; -} diff --git a/test/Fixtures/lessjs (1.6)/css/mixins.css b/test/Fixtures/lessjs (1.6)/css/mixins.css deleted file mode 100644 index 32097f97..00000000 --- a/test/Fixtures/lessjs (1.6)/css/mixins.css +++ /dev/null @@ -1,141 +0,0 @@ -.mixin { - border: 1px solid black; -} -.mixout { - border-color: orange; -} -.borders { - border-style: dashed; -} -#namespace .borders { - border-style: dotted; -} -#namespace .biohazard { - content: "death"; -} -#namespace .biohazard .man { - color: transparent; -} -#theme > .mixin { - background-color: grey; -} -#container { - color: black; - border: 1px solid black; - border-color: orange; - background-color: grey; -} -#header .milk { - color: white; - border: 1px solid black; - background-color: grey; -} -#header #cookie { - border-style: dashed; -} -#header #cookie .chips { - border-style: dotted; -} -#header #cookie .chips .calories { - color: black; - border: 1px solid black; - border-color: orange; - background-color: grey; -} -.secure-zone { - color: transparent; -} -.direct { - border-style: dotted; -} -.bo, -.bar { - width: 100%; -} -.bo { - border: 1px; -} -.ar.bo.ca { - color: black; -} -.jo.ki { - background: none; -} -.amp.support { - color: orange; -} -.amp.support .higher { - top: 0px; -} -.amp.support.deeper { - height: auto; -} -.extended { - width: 100%; - border: 1px; - background: none; - color: orange; - top: 0px; - height: auto; -} -.extended .higher { - top: 0px; -} -.extended.deeper { - height: auto; -} -.do .re .mi .fa .sol .la .si { - color: cyan; -} -.mutli-selector-parents { - color: cyan; -} -.foo .bar { - width: 100%; -} -.underParents { - color: red; -} -.parent .underParents { - color: red; -} -* + h1 { - margin-top: 25px; -} -legend + h1 { - margin-top: 0; -} -h1 + * { - margin-top: 10px; -} -* + h2 { - margin-top: 20px; -} -legend + h2 { - margin-top: 0; -} -h2 + * { - margin-top: 8px; -} -* + h3 { - margin-top: 15px; -} -legend + h3 { - margin-top: 0; -} -h3 + * { - margin-top: 5px; -} -.error { - background-image: "/a.png"; - background-position: center center; -} -.test-rec .recursion { - color: black; -} -.button { - padding-left: 44px; -} -.button.large { - padding-left: 40em; -} diff --git a/test/Fixtures/lessjs (1.6)/css/modifyVars/extended.css b/test/Fixtures/lessjs (1.6)/css/modifyVars/extended.css deleted file mode 100644 index 32edb38f..00000000 --- a/test/Fixtures/lessjs (1.6)/css/modifyVars/extended.css +++ /dev/null @@ -1,9 +0,0 @@ -#header { - color: #333333; - border-left: 1px; - border-right: 2px; -} -#footer { - color: #114411; - border-color: #842210; -} diff --git a/test/Fixtures/lessjs (1.6)/css/no-output.css b/test/Fixtures/lessjs (1.6)/css/no-output.css deleted file mode 100644 index e69de29b..00000000 diff --git a/test/Fixtures/lessjs (1.6)/css/operations.css b/test/Fixtures/lessjs (1.6)/css/operations.css deleted file mode 100644 index fb9e0aff..00000000 --- a/test/Fixtures/lessjs (1.6)/css/operations.css +++ /dev/null @@ -1,49 +0,0 @@ -#operations { - color: #111111; - height: 9px; - width: 3em; - substraction: 0; - division: 1; -} -#operations .spacing { - height: 9px; - width: 3em; -} -.with-variables { - height: 16em; - width: 24em; - size: 1cm; -} -.with-functions { - color: #646464; - color: #ff8080; - color: #c94a4a; -} -.negative { - height: 0px; - width: 4px; -} -.shorthands { - padding: -1px 2px 0 -4px; -} -.rem-dimensions { - font-size: 5.5rem; -} -.colors { - color: #123; - border-color: #334455; - background-color: #000000; -} -.colors .other { - color: #222222; - border-color: #222222; -} -.negations { - variable: -4px; - variable1: 0px; - variable2: 0px; - variable3: 8px; - variable4: 0px; - paren: -4px; - paren2: 16px; -} diff --git a/test/Fixtures/lessjs (1.6)/css/parens.css b/test/Fixtures/lessjs (1.6)/css/parens.css deleted file mode 100644 index dc09fdf5..00000000 --- a/test/Fixtures/lessjs (1.6)/css/parens.css +++ /dev/null @@ -1,36 +0,0 @@ -.parens { - border: 2px solid #000000; - margin: 1px 3px 16 3; - width: 36; - padding: 2px 36px; -} -.more-parens { - padding: 8 4 4 4px; - width-all: 96; - width-first: 16 * 6; - width-keep: (4 * 4) * 6; - height-keep: (7 * 7) + (8 * 8); - height-all: 113; - height-parts: 49 + 64; - margin-keep: (4 * (5 + 5) / 2) - (4 * 2); - margin-parts: 20 - 8; - margin-all: 12; - border-radius-keep: 4px * (1 + 1) / 4 + 3px; - border-radius-parts: 8px / 7px; - border-radius-all: 5px; -} -.negative { - neg-var: -1; - neg-var-paren: -(1); -} -.nested-parens { - width: 2 * (4 * (2 + (1 + 6))) - 1; - height: ((2 + 3) * (2 + 3) / (9 - 4)) + 1; -} -.mixed-units { - margin: 2px 4em 1 5pc; - padding: 6px 1em 2px 2; -} -.test-false-negatives { - a: (; -} diff --git a/test/Fixtures/lessjs (1.6)/css/property-name-interp.css b/test/Fixtures/lessjs (1.6)/css/property-name-interp.css deleted file mode 100644 index 2082b819..00000000 --- a/test/Fixtures/lessjs (1.6)/css/property-name-interp.css +++ /dev/null @@ -1,20 +0,0 @@ -pi-test { - border: 0; - ufo-width: 50%; - *-z-border: 1px dashed blue; - -www-border-top: 2px; - radius-is-not-a-border: true; - border-top-left-radius: 2em; - border-top-red-radius-: 3pt; - global-local-mixer-property: strong; -} -pi-test-merge { - pre-property-ish: high, middle, low, base; - pre-property-ish+: nice try dude; -} -pi-indirect-vars { - auto: auto; -} -pi-complex-values { - 3px rgba(255, 255, 0, 0.5), 3.141592653589793 /* foo */3px rgba(255, 255, 0, 0.5), 3.141592653589793 /* foo */: none; -} diff --git a/test/Fixtures/lessjs (1.6)/css/rulesets.css b/test/Fixtures/lessjs (1.6)/css/rulesets.css deleted file mode 100644 index 408c76aa..00000000 --- a/test/Fixtures/lessjs (1.6)/css/rulesets.css +++ /dev/null @@ -1,33 +0,0 @@ -#first > .one { - font-size: 2em; -} -#first > .one > #second .two > #deux { - width: 50%; -} -#first > .one > #second .two > #deux #third { - height: 100%; -} -#first > .one > #second .two > #deux #third:focus { - color: black; -} -#first > .one > #second .two > #deux #third:focus #fifth > #sixth .seventh #eighth + #ninth { - color: purple; -} -#first > .one > #second .two > #deux #fourth, -#first > .one > #second .two > #deux #five, -#first > .one > #second .two > #deux #six { - color: #110000; -} -#first > .one > #second .two > #deux #fourth .seven, -#first > .one > #second .two > #deux #five .seven, -#first > .one > #second .two > #deux #six .seven, -#first > .one > #second .two > #deux #fourth .eight > #nine, -#first > .one > #second .two > #deux #five .eight > #nine, -#first > .one > #second .two > #deux #six .eight > #nine { - border: 1px solid black; -} -#first > .one > #second .two > #deux #fourth #ten, -#first > .one > #second .two > #deux #five #ten, -#first > .one > #second .two > #deux #six #ten { - color: red; -} diff --git a/test/Fixtures/lessjs (1.6)/css/scope.css b/test/Fixtures/lessjs (1.6)/css/scope.css deleted file mode 100644 index baa05523..00000000 --- a/test/Fixtures/lessjs (1.6)/css/scope.css +++ /dev/null @@ -1,35 +0,0 @@ -.tiny-scope { - color: #998899; -} -.scope1 { - color: #0000ff; - border-color: #000000; -} -.scope1 .scope2 { - color: #0000ff; -} -.scope1 .scope2 .scope3 { - color: #ff0000; - border-color: #000000; - background-color: #ffffff; -} -.scope { - scoped-val: #008000; -} -.heightIsSet { - height: 1024px; -} -.useHeightInMixinCall { - mixin-height: 1024px; -} -.imported { - exists: true; -} -.testImported { - exists: true; -} -#allAreUsedHere { - default: 'top level'; - scope: 'top level'; - sub-scope-only: 'inside'; -} diff --git a/test/Fixtures/lessjs (1.6)/css/selectors.css b/test/Fixtures/lessjs (1.6)/css/selectors.css deleted file mode 100644 index ec855bec..00000000 --- a/test/Fixtures/lessjs (1.6)/css/selectors.css +++ /dev/null @@ -1,153 +0,0 @@ -h1 a:hover, -h2 a:hover, -h3 a:hover, -h1 p:hover, -h2 p:hover, -h3 p:hover { - color: red; -} -#all { - color: blue; -} -#the { - color: blue; -} -#same { - color: blue; -} -ul, -li, -div, -q, -blockquote, -textarea { - margin: 0; -} -td { - margin: 0; - padding: 0; -} -td, -input { - line-height: 1em; -} -a { - color: red; -} -a:hover { - color: blue; -} -div a { - color: green; -} -p a span { - color: yellow; -} -.foo .bar .qux, -.foo .baz .qux { - display: block; -} -.qux .foo .bar, -.qux .foo .baz { - display: inline; -} -.qux.foo .bar, -.qux.foo .baz { - display: inline-block; -} -.qux .foo .bar .biz, -.qux .foo .baz .biz { - display: none; -} -.a.b.c { - color: red; -} -.c .b.a { - color: red; -} -.foo .p.bar { - color: red; -} -.foo.p.bar { - color: red; -} -.foo + .foo { - background: amber; -} -.foo + .foo { - background: amber; -} -.foo + .foo, -.foo + .bar, -.bar + .foo, -.bar + .bar { - background: amber; -} -.foo a > .foo a, -.foo a > .bar a, -.foo a > .foo b, -.foo a > .bar b, -.bar a > .foo a, -.bar a > .bar a, -.bar a > .foo b, -.bar a > .bar b, -.foo b > .foo a, -.foo b > .bar a, -.foo b > .foo b, -.foo b > .bar b, -.bar b > .foo a, -.bar b > .bar a, -.bar b > .foo b, -.bar b > .bar b { - background: amber; -} -.other ::fnord { - color: #ff0000; -} -.other::fnord { - color: #ff0000; -} -.other ::bnord { - color: #ff0000; -} -.other::bnord { - color: #ff0000; -} -.blood { - color: red; -} -.bloodred { - color: green; -} -#blood.blood.red.black { - color: black; -} -:nth-child(3) { - selector: interpolated; -} -.test:nth-child(odd):not(:nth-child(3)) { - color: #ff0000; -} -[prop], -[prop=10%], -[prop="value3"], -[prop*="val3"], -[|prop~="val3"], -[*|prop$="val3"], -[ns|prop^="val3"], -[3^="val3"], -[3=3], -[3] { - attributes: yes; -} -/* -Large comment means chunk will be emitted after } which means chunk will begin with whitespace... -blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank -blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank -blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank -blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank -blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank -*/ -.blood { - color: red; -} diff --git a/test/Fixtures/lessjs (1.6)/css/static-urls/urls.css b/test/Fixtures/lessjs (1.6)/css/static-urls/urls.css deleted file mode 100644 index ed174e87..00000000 --- a/test/Fixtures/lessjs (1.6)/css/static-urls/urls.css +++ /dev/null @@ -1,45 +0,0 @@ -@import "css/background.css"; -@import "folder (1)/import-test-d.css"; -@font-face { - src: url("/fonts/garamond-pro.ttf"); - src: local(Futura-Medium), url(folder\ \(1\)/fonts.svg#MyGeometricModern) format("svg"); -} -#shorthands { - background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; -} -#misc { - background-image: url(folder\ \(1\)/images/image.jpg); -} -#data-uri { - background: url(data:image/png;charset=utf-8;base64, - kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ - k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U - kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700); -} -#svg-data-uri { - background: transparent url('data:image/svg+xml, '); -} -.comma-delimited { - background: url(folder\ \(1\)/bg.jpg) no-repeat, url(folder\ \(1\)/bg.png) repeat-x top left, url(folder\ \(1\)/bg); -} -.values { - url: url('folder (1)/Trebuchet'); -} -#logo { - width: 100px; - height: 100px; - background: url('assets/logo.png'); -} -@font-face { - font-family: xecret; - src: url('assets/xecret.ttf'); -} -#secret { - font-family: xecret, sans-serif; -} -#imported-relative-path { - background-image: url(../data/image.jpg); - border-image: url('../data/image.jpg'); -} diff --git a/test/Fixtures/lessjs (1.6)/css/strings.css b/test/Fixtures/lessjs (1.6)/css/strings.css deleted file mode 100644 index cd6d6020..00000000 --- a/test/Fixtures/lessjs (1.6)/css/strings.css +++ /dev/null @@ -1,43 +0,0 @@ -#strings { - background-image: url("http://son-of-a-banana.com"); - quotes: "~" "~"; - content: "#*%:&^,)!.(~*})"; - empty: ""; - brackets: "{" "}"; - escapes: "\"hello\" \\world"; - escapes2: "\"llo"; -} -#comments { - content: "/* hello */ // not-so-secret"; -} -#single-quote { - quotes: "'" "'"; - content: '""#!&""'; - empty: ''; - semi-colon: ';'; -} -#escaped { - filter: DX.Transform.MS.BS.filter(opacity=50); -} -#one-line { - image: url(http://tooks.com); -} -#crazy { - image: url(http://), "}", url("http://}"); -} -#interpolation { - url: "http://lesscss.org/dev/image.jpg"; - url2: "http://lesscss.org/image-256.jpg"; - url3: "http://lesscss.org#445566"; - url4: "http://lesscss.org/hello"; - url5: "http://lesscss.org/54.4px"; -} -.mix-mul-class { - color: #0000ff; - color: #ff0000; - color: #000000; - color: #ffa500; -} -.watermark { - family: Univers, Arial, Verdana, San-Serif; -} diff --git a/test/Fixtures/lessjs (1.6)/css/url-args/urls.css b/test/Fixtures/lessjs (1.6)/css/url-args/urls.css deleted file mode 100644 index 0b4b13f3..00000000 --- a/test/Fixtures/lessjs (1.6)/css/url-args/urls.css +++ /dev/null @@ -1,56 +0,0 @@ -@font-face { - src: url("/fonts/garamond-pro.ttf?424242"); - src: local(Futura-Medium), url(fonts.svg?424242#MyGeometricModern) format("svg"); -} -#shorthands { - background: url("http://www.lesscss.org/spec.html?424242") no-repeat 0 4px; - background: url("img.jpg?424242") center / 100px; - background: #ffffff url(image.png?424242) center / 1px 100px repeat-x scroll content-box padding-box; -} -#misc { - background-image: url(images/image.jpg?424242); -} -#data-uri { - background: url(data:image/png;charset=utf-8;base64, - kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ - k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U - kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700&424242); - background-image: url("http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700&424242"); -} -#svg-data-uri { - background: transparent url('data:image/svg+xml, '); -} -.comma-delimited { - background: url(bg.jpg?424242) no-repeat, url(bg.png?424242) repeat-x top left, url(bg?424242); -} -.values { - url: url('Trebuchet?424242'); -} -@font-face { - font-family: xecret; - src: url('../assets/xecret.ttf?424242'); -} -#secret { - font-family: xecret, sans-serif; -} -#data-uri { - uri: url("data:image/jpeg;base64,bm90IGFjdHVhbGx5IGEganBlZyBmaWxlCg=="); -} -#data-uri-guess { - uri: url("data:image/jpeg;base64,bm90IGFjdHVhbGx5IGEganBlZyBmaWxlCg=="); -} -#data-uri-ascii { - uri-1: url("data:text/html,%3Ch1%3EThis%20page%20is%20100%25%20Awesome.%3C%2Fh1%3E%0A"); - uri-2: url("data:text/html,%3Ch1%3EThis%20page%20is%20100%25%20Awesome.%3C%2Fh1%3E%0A"); -} -#svg-functions { - background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhZGllbnQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjwvbGluZWFyR3JhZGllbnQ+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkaWVudCkiIC8+PC9zdmc+'); - background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhZGllbnQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIvPjxzdG9wIG9mZnNldD0iMyUiIHN0b3AtY29sb3I9IiNmZmE1MDAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIGZpbGw9InVybCgjZ3JhZGllbnQpIiAvPjwvc3ZnPg=='); - background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhZGllbnQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIxJSIgc3RvcC1jb2xvcj0iI2M0YzRjNCIvPjxzdG9wIG9mZnNldD0iMyUiIHN0b3AtY29sb3I9IiNmZmE1MDAiLz48c3RvcCBvZmZzZXQ9IjUlIiBzdG9wLWNvbG9yPSIjMDA4MDAwIi8+PHN0b3Agb2Zmc2V0PSI5NSUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIGZpbGw9InVybCgjZ3JhZGllbnQpIiAvPjwvc3ZnPg=='); -} -#data-uri-with-spaces { - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(' data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9=='); -} diff --git a/test/Fixtures/lessjs (1.6)/css/urls.css b/test/Fixtures/lessjs (1.6)/css/urls.css deleted file mode 100644 index cc7087d0..00000000 --- a/test/Fixtures/lessjs (1.6)/css/urls.css +++ /dev/null @@ -1,71 +0,0 @@ -@import "css/background.css"; -@import "import/import-test-d.css"; -@import "file.css"; -@font-face { - src: url("/fonts/garamond-pro.ttf"); - src: local(Futura-Medium), url(fonts.svg#MyGeometricModern) format("svg"); -} -#shorthands { - background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; - background: url("img.jpg") center / 100px; - background: #ffffff url(image.png) center / 1px 100px repeat-x scroll content-box padding-box; -} -#misc { - background-image: url(images/image.jpg); -} -#data-uri { - background: url(data:image/png;charset=utf-8;base64, - kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ - k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U - kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700); - background-image: url("http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700"); -} -#svg-data-uri { - background: transparent url('data:image/svg+xml, '); -} -.comma-delimited { - background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg); -} -.values { - url: url('Trebuchet'); -} -#logo { - width: 100px; - height: 100px; - background: url('import/assets/logo.png'); -} -@font-face { - font-family: xecret; - src: url('import/assets/xecret.ttf'); -} -#secret { - font-family: xecret, sans-serif; -} -#imported-relative-path { - background-image: url(../data/image.jpg); - border-image: url('../data/image.jpg'); -} -#relative-url-import { - background-image: url(../data/image.jpg); - border-image: url('../data/image.jpg'); -} -#data-uri { - uri: url("data:image/jpeg;base64,bm90IGFjdHVhbGx5IGEganBlZyBmaWxlCg=="); -} -#data-uri-guess { - uri: url("data:image/jpeg;base64,bm90IGFjdHVhbGx5IGEganBlZyBmaWxlCg=="); -} -#data-uri-ascii { - uri-1: url("data:text/html,%3Ch1%3EThis%20page%20is%20100%25%20Awesome.%3C%2Fh1%3E%0A"); - uri-2: url("data:text/html,%3Ch1%3EThis%20page%20is%20100%25%20Awesome.%3C%2Fh1%3E%0A"); -} -#data-uri-toobig { - uri: url('../data/data-uri-fail.png'); -} -#svg-functions { - background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhZGllbnQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjwvbGluZWFyR3JhZGllbnQ+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkaWVudCkiIC8+PC9zdmc+'); - background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhZGllbnQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIvPjxzdG9wIG9mZnNldD0iMyUiIHN0b3AtY29sb3I9IiNmZmE1MDAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIGZpbGw9InVybCgjZ3JhZGllbnQpIiAvPjwvc3ZnPg=='); - background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhZGllbnQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIxJSIgc3RvcC1jb2xvcj0iI2M0YzRjNCIvPjxzdG9wIG9mZnNldD0iMyUiIHN0b3AtY29sb3I9IiNmZmE1MDAiLz48c3RvcCBvZmZzZXQ9IjUlIiBzdG9wLWNvbG9yPSIjMDA4MDAwIi8+PHN0b3Agb2Zmc2V0PSI5NSUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIGZpbGw9InVybCgjZ3JhZGllbnQpIiAvPjwvc3ZnPg=='); -} diff --git a/test/Fixtures/lessjs (1.6)/css/variables.css b/test/Fixtures/lessjs (1.6)/css/variables.css deleted file mode 100644 index f8d8518b..00000000 --- a/test/Fixtures/lessjs (1.6)/css/variables.css +++ /dev/null @@ -1,45 +0,0 @@ -.variables { - width: 14cm; -} -.variables { - height: 24px; - color: #888888; - font-family: "Trebuchet MS", Verdana, sans-serif; - quotes: "~" "~"; -} -.redef { - zero: 0; -} -.redef .inition { - three: 3; -} -.values { - minus-one: -1; - font-family: 'Trebuchet', 'Trebuchet', 'Trebuchet'; - color: #888888 !important; - multi: something 'A', B, C, 'Trebuchet'; -} -.variable-names { - name: 'hello'; -} -.alpha { - filter: alpha(opacity=42); -} -.testPollution { - a: 'no-pollution'; -} -.units { - width: 1px; - same-unit-as-previously: 1px; - square-pixel-divided: 1px; - odd-unit: 2; - percentage: 500%; - pixels: 500px; - conversion-metric-a: 30mm; - conversion-metric-b: 3cm; - conversion-imperial: 3in; - custom-unit: 420octocats; - custom-unit-cancelling: 18dogs; - mix-units: 2px; - invalid-units: 1px; -} diff --git a/test/Fixtures/lessjs (1.6)/css/whitespace.css b/test/Fixtures/lessjs (1.6)/css/whitespace.css deleted file mode 100644 index 74c9b65e..00000000 --- a/test/Fixtures/lessjs (1.6)/css/whitespace.css +++ /dev/null @@ -1,42 +0,0 @@ -.whitespace { - color: white; -} -.whitespace { - color: white; -} -.whitespace { - color: white; -} -.whitespace { - color: white; -} -.whitespace { - color: white ; -} -.white, -.space, -.mania { - color: white; -} -.no-semi-column { - color: #ffffff; -} -.no-semi-column { - color: white; - white-space: pre; -} -.no-semi-column { - border: 2px solid #ffffff; -} -.newlines { - background: the, - great, - wall; - border: 2px - solid - black; -} -.sel .newline_ws .tab_ws { - color: white; - background-position: 45 -23; -} diff --git a/test/Fixtures/lessjs (1.6)/data/data-uri-fail.png b/test/Fixtures/lessjs (1.6)/data/data-uri-fail.png deleted file mode 100644 index f91b59fb314c105c5d290775cd5395bc6140caf7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52420 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 zbiv&This page is 100% Awesome. diff --git a/test/Fixtures/lessjs (1.6)/expected/charsets.css b/test/Fixtures/lessjs (1.6)/expected/charsets.css deleted file mode 100644 index 9f44090c..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/charsets.css +++ /dev/null @@ -1 +0,0 @@ -@charset "UTF-8"; diff --git a/test/Fixtures/lessjs (1.6)/expected/colors.css b/test/Fixtures/lessjs (1.6)/expected/colors.css deleted file mode 100644 index 08a22abb..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/colors.css +++ /dev/null @@ -1,87 +0,0 @@ -#yelow #short { - color: #fea; -} -#yelow #long { - color: #ffeeaa; -} -#yelow #rgba { - color: rgba(255, 238, 170, 0.1); -} -#yelow #argb { - color: #1affeeaa; -} -#blue #short { - color: #00f; -} -#blue #long { - color: #0000ff; -} -#blue #rgba { - color: rgba(0, 0, 255, 0.1); -} -#blue #argb { - color: #1a0000ff; -} -#alpha #hsla { - color: rgba(61, 45, 41, 0.6); -} -#overflow .a { - color: #000000; -} -#overflow .b { - color: #ffffff; -} -#overflow .c { - color: #ffffff; -} -#overflow .d { - color: #00ff00; -} -#overflow .e { - color: rgba(0, 31, 255, 0.42); -} -#grey { - color: #c8c8c8; -} -#333333 { - color: #333333; -} -#808080 { - color: #808080; -} -#00ff00 { - color: #00ff00; -} -.lightenblue { - color: #3333ff; -} -.darkenblue { - color: #0000cc; -} -.unknowncolors { - color: blue2; - border: 2px solid superred; -} -.transparent { - color: transparent; - background-color: rgba(0, 0, 0, 0); -} -#alpha #fromvar { - opacity: 0.7; -} -#alpha #short { - opacity: 1; -} -#alpha #long { - opacity: 1; -} -#alpha #rgba { - opacity: 0.2; -} -#alpha #hsl { - opacity: 1; -} -#percentage { - color: 255; - border-color: rgba(255, 0, 0, 0.5); -} diff --git a/test/Fixtures/lessjs (1.6)/expected/comments.css b/test/Fixtures/lessjs (1.6)/expected/comments.css deleted file mode 100644 index b7670230..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/comments.css +++ /dev/null @@ -1,69 +0,0 @@ -/******************\ -* * -* Comment Header * -* * -\******************/ -/* - - Comment - -*/ -/* - * Comment Test - * - * - cloudhead (http://cloudhead.net) - * - */ -/* Colors - * ------ - * #EDF8FC (background blue) - * #166C89 (darkest blue) - * - * Text: - * #333 (standard text) // A comment within a comment! - * #1F9EC9 (standard link) - * - */ -/* @group Variables -------------------- */ -#comments, -.comments { - /**/ - color: red; - /* A C-style comment */ - /* A C-style comment */ - background-color: orange; - font-size: 12px; - /* lost comment */ - content: "content"; - border: 1px solid black; - padding: 0; - margin: 2em; -} -/* commented out - #more-comments { - color: grey; - } -*/ -.selector, -.lots, -.comments { - color: #808080, /* blue */ #ffa500; - -webkit-border-radius: 2px /* webkit only */; - -moz-border-radius: 8px /* moz only with operation */; -} -.test { - color: 1px; -} -#last { - color: blue; -} -/* */ -/* { */ -/* */ -/* */ -/* */ -#div { - color: #A33; -} -/* } */ diff --git a/test/Fixtures/lessjs (1.6)/expected/css-3.css b/test/Fixtures/lessjs (1.6)/expected/css-3.css deleted file mode 100644 index 61f635c2..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/css-3.css +++ /dev/null @@ -1,129 +0,0 @@ -.comma-delimited { - text-shadow: -1px -1px 1px #ff0000, 6px 5px 5px #ffff00; - -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset, 0pt 4px 6px rgba(255, 255, 255, 0.4) inset; - -webkit-transform: rotate(0deg); -} -@font-face { - font-family: Headline; - unicode-range: U+??????, U+0???, U+0-7F, U+A5; -} -.other { - -moz-transform: translate(0, 11em) rotate(-90deg); - transform: rotateX(45deg); -} -.item[data-cra_zy-attr1b-ut3=bold] { - font-weight: bold; -} -p:not([class*="lead"]) { - color: black; -} -input[type="text"].class#id[attr=32]:not(1) { - color: white; -} -div#id.class[a=1][b=2].class:not(1) { - color: white; -} -ul.comma > li:not(:only-child)::after { - color: white; -} -ol.comma > li:nth-last-child(2)::after { - color: white; -} -li:nth-child(4n+1), -li:nth-child(-5n), -li:nth-child(-n+2) { - color: white; -} -a[href^="http://"] { - color: black; -} -a[href$="http://"] { - color: black; -} -form[data-disabled] { - color: black; -} -p::before { - color: black; -} -#issue322 { - -webkit-animation: anim2 7s infinite ease-in-out; -} -@-webkit-keyframes frames { - 0% { - border: 1px; - } - 5.5% { - border: 2px; - } - 100% { - border: 3px; - } -} -@keyframes fontbulger1 { - to { - font-size: 15px; - } - from, - to { - font-size: 12px; - } - 0%, - 100% { - font-size: 12px; - } -} -.units { - font: 1.2rem/2rem; - font: 8vw/9vw; - font: 10vh/12vh; - font: 12vm/15vm; - font: 12vmin/15vmin; - font: 1.2ch/1.5ch; -} -@supports ( box-shadow: 2px 2px 2px black ) or - ( -moz-box-shadow: 2px 2px 2px black ) { - .outline { - box-shadow: 2px 2px 2px black; - -moz-box-shadow: 2px 2px 2px black; - } -} -@-x-document url-prefix(""github.com"") { - h1 { - color: red; - } -} -@viewport { - font-size: 10px; -} -@namespace foo url(http://www.example.com); -foo|h1 { - color: blue; -} -foo|* { - color: yellow; -} -|h1 { - color: red; -} -*|h1 { - color: green; -} -h1 { - color: green; -} -.upper-test { - UpperCaseProperties: allowed; -} -@host { - div { - display: block; - } -} -::distributed(input::placeholder) { - color: #b3b3b3; -} -.shadow ^ .dom, -body ^^ .shadow { - display: done; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/css-escapes.css b/test/Fixtures/lessjs (1.6)/expected/css-escapes.css deleted file mode 100644 index 4d343aa6..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/css-escapes.css +++ /dev/null @@ -1,24 +0,0 @@ -.escape\|random\|char { - color: red; -} -.mixin\!tUp { - font-weight: bold; -} -.\34 04 { - background: red; -} -.\34 04 strong { - color: #ff00ff; - font-weight: bold; -} -.trailingTest\+ { - color: red; -} -/* This hideous test of hideousness checks for the selector "blockquote" with various permutations of hex escapes */ -\62\6c\6f \63 \6B \0071 \000075o\74 e { - color: silver; -} -[ng\:cloak], -ng\:form { - display: none; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/css-guards.css b/test/Fixtures/lessjs (1.6)/expected/css-guards.css deleted file mode 100644 index f4b8a108..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/css-guards.css +++ /dev/null @@ -1,37 +0,0 @@ -.light { - color: green; -} -.see-the { - color: green; -} -.hide-the { - color: green; -} -.multiple-conditions-1 { - color: red; -} -.inheritance .test { - color: black; -} -.inheritance:hover { - color: pink; -} -.clsWithGuard { - dispaly: none; -} -.dont-split-me-up { - width: 1px; - color: red; - height: 1px; -} - + .dont-split-me-up { - sibling: true; -} -.scope-check { - sub-prop: 2px; - prop: 1px; -} -.scope-check-2 { - sub-prop: 2px; - prop: 1px; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/css.css b/test/Fixtures/lessjs (1.6)/expected/css.css deleted file mode 100644 index 24040ff3..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/css.css +++ /dev/null @@ -1,95 +0,0 @@ -@charset "utf-8"; -div { - color: black; -} -div { - width: 99%; -} -* { - min-width: 45em; -} -h1, -h2 > a > p, -h3 { - color: none; -} -div.class { - color: blue; -} -div#id { - color: green; -} -.class#id { - color: purple; -} -.one.two.three { - color: grey; -} -@media print { - * { - font-size: 3em; - } -} -@media screen { - * { - font-size: 10px; - } -} -@font-face { - font-family: 'Garamond Pro'; -} -a:hover, -a:link { - color: #999; -} -p, -p:first-child { - text-transform: none; -} -q:lang(no) { - quotes: none; -} -p + h1 { - font-size: 2.2em; -} -#shorthands { - border: 1px solid #000; - font: 12px/16px Arial; - font: 100%/16px Arial; - margin: 1px 0; - padding: 0 auto; -} -#more-shorthands { - margin: 0; - padding: 1px 0 2px 0; - font: normal small / 20px 'Trebuchet MS', Verdana, sans-serif; - font: 0/0 a; - border-radius: 0.5px; -} -.misc { - -moz-border-radius: 2px; - display: -moz-inline-stack; - width: .1em; - background-color: #009998; - background: -webkit-gradient(linear, left top, left bottom, from(#ff0000), to(#0000ff)); - margin: ; - filter: alpha(opacity=100); - width: auto\9; -} -.misc .nested-multiple { - multiple-semi-colons: yes; -} -#important { - color: red !important; - width: 100% !important; - height: 20px !important; -} -@font-face { - font-family: font-a; -} -@font-face { - font-family: font-b; -} -.æøå { - margin: 0; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/empty.css b/test/Fixtures/lessjs (1.6)/expected/empty.css deleted file mode 100644 index 8b137891..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/empty.css +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/Fixtures/lessjs (1.6)/expected/extend-chaining.css b/test/Fixtures/lessjs (1.6)/expected/extend-chaining.css deleted file mode 100644 index 820e134f..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/extend-chaining.css +++ /dev/null @@ -1,81 +0,0 @@ -.a, -.b, -.c { - color: black; -} -.f, -.e, -.d { - color: black; -} -.g.h, -.i.j.h, -.k.j.h { - color: black; -} -.i.j, -.k.j { - color: white; -} -.l, -.m, -.n, -.o, -.p, -.q, -.r, -.s, -.t { - color: black; -} -.u, -.v.u.v { - color: black; -} -.w, -.v.w.v { - color: black; -} -.x, -.y, -.z { - color: x; -} -.y, -.z, -.x { - color: y; -} -.z, -.x, -.y { - color: z; -} -.va, -.vb, -.vc { - color: black; -} -.vb, -.vc { - color: white; -} -@media tv { - .ma, - .mb, - .mc { - color: black; - } - .md, - .ma, - .mb, - .mc { - color: white; - } -} -@media tv and plasma { - .me, - .mf { - background: red; - } -} diff --git a/test/Fixtures/lessjs (1.6)/expected/extend-clearfix.css b/test/Fixtures/lessjs (1.6)/expected/extend-clearfix.css deleted file mode 100644 index 966892a2..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/extend-clearfix.css +++ /dev/null @@ -1,19 +0,0 @@ -.clearfix, -.foo, -.bar { - *zoom: 1; -} -.clearfix:after, -.foo:after, -.bar:after { - content: ''; - display: block; - clear: both; - height: 0; -} -.foo { - color: red; -} -.bar { - color: blue; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/extend-exact.css b/test/Fixtures/lessjs (1.6)/expected/extend-exact.css deleted file mode 100644 index beff4133..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/extend-exact.css +++ /dev/null @@ -1,37 +0,0 @@ -.replace.replace .replace, -.c.replace + .replace .replace, -.replace.replace .c, -.c.replace + .replace .c, -.rep_ace { - prop: copy-paste-replace; -} -.a .b .c { - prop: not_effected; -} -.a, -.effected { - prop: is_effected; -} -.a .b { - prop: not_effected; -} -.a .b.c { - prop: not_effected; -} -.c .b .a, -.a .b .a, -.c .a .a, -.a .a .a, -.c .b .c, -.a .b .c, -.c .a .c, -.a .a .c { - prop: not_effected; -} -.e.e, -.dbl { - prop: extend-double; -} -.e.e:hover { - hover: not-extended; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/extend-media.css b/test/Fixtures/lessjs (1.6)/expected/extend-media.css deleted file mode 100644 index 23bd7b85..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/extend-media.css +++ /dev/null @@ -1,24 +0,0 @@ -.ext1 .ext2, -.all .ext2 { - background: black; -} -@media tv { - .ext1 .ext3, - .tv-lowres .ext3, - .all .ext3 { - color: white; - } - .tv-lowres { - background: blue; - } -} -@media tv and hires { - .ext1 .ext4, - .tv-hires .ext4, - .all .ext4 { - color: green; - } - .tv-hires { - background: red; - } -} diff --git a/test/Fixtures/lessjs (1.6)/expected/extend-nest.css b/test/Fixtures/lessjs (1.6)/expected/extend-nest.css deleted file mode 100644 index 2c3905d9..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/extend-nest.css +++ /dev/null @@ -1,57 +0,0 @@ -.sidebar, -.sidebar2, -.type1 .sidebar3, -.type2.sidebar4 { - width: 300px; - background: red; -} -.sidebar .box, -.sidebar2 .box, -.type1 .sidebar3 .box, -.type2.sidebar4 .box { - background: #FFF; - border: 1px solid #000; - margin: 10px 0; -} -.sidebar2 { - background: blue; -} -.type1 .sidebar3 { - background: green; -} -.type2.sidebar4 { - background: red; -} -.button, -.submit { - color: black; -} -.button:hover, -.submit:hover { - color: white; -} -.button2 :hover { - nested: white; -} -.button2 :hover { - notnested: black; -} -.amp-test-h, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e.amp-test-g { - test: extended by masses of selectors; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/extend-selector.css b/test/Fixtures/lessjs (1.6)/expected/extend-selector.css deleted file mode 100644 index da47254b..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/extend-selector.css +++ /dev/null @@ -1,80 +0,0 @@ -.error, -.badError { - border: 1px #f00; - background: #fdd; -} -.error.intrusion, -.badError.intrusion { - font-size: 1.3em; - font-weight: bold; -} -.intrusion .error, -.intrusion .badError { - display: none; -} -.badError { - border-width: 3px; -} -.foo .bar, -.foo .baz, -.ext1 .ext2 .bar, -.ext1 .ext2 .baz, -.ext3 .bar, -.ext3 .baz, -.ext4 .bar, -.ext4 .baz { - display: none; -} -div.ext5, -.ext6 > .ext5, -div.ext7, -.ext6 > .ext7 { - width: 100px; -} -.ext, -.a .c, -.b .c { - test: 1; -} -.a, -.b { - test: 2; -} -.a .c, -.b .c { - test: 3; -} -.a .c .d, -.b .c .d { - test: 4; -} -.replace.replace .replace, -.c.replace + .replace .replace, -.replace.replace .c, -.c.replace + .replace .c, -.rep_ace.rep_ace .rep_ace, -.c.rep_ace + .rep_ace .rep_ace, -.rep_ace.rep_ace .c, -.c.rep_ace + .rep_ace .c { - prop: copy-paste-replace; -} -.attributes [data="test"], -.attributes .attributes .attribute-test { - extend: attributes; -} -.attributes [data], -.attributes .attributes .attribute-test2 { - extend: attributes2; -} -.attributes [data="test3"], -.attributes .attributes .attribute-test { - extend: attributes2; -} -.header .header-nav, -.footer .footer-nav { - background: red; -} -.header .header-nav:before, -.footer .footer-nav:before { - background: blue; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/extend.css b/test/Fixtures/lessjs (1.6)/expected/extend.css deleted file mode 100644 index 2895641a..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/extend.css +++ /dev/null @@ -1,76 +0,0 @@ -.error, -.badError { - border: 1px #f00; - background: #fdd; -} -.error.intrusion, -.badError.intrusion { - font-size: 1.3em; - font-weight: bold; -} -.intrusion .error, -.intrusion .badError { - display: none; -} -.badError { - border-width: 3px; -} -.foo .bar, -.foo .baz, -.ext1 .ext2 .bar, -.ext1 .ext2 .baz, -.ext3 .bar, -.ext3 .baz, -.foo .ext3, -.ext4 .bar, -.ext4 .baz, -.foo .ext4 { - display: none; -} -div.ext5, -.ext6 > .ext5, -div.ext7, -.ext6 > .ext7 { - width: 100px; -} -.ext8.ext9, -.fuu { - result: add-foo; -} -.ext8 .ext9, -.ext8 + .ext9, -.ext8 > .ext9, -.buu, -.zap, -.zoo { - result: bar-matched; -} -.ext8.nomatch { - result: none; -} -.ext8 .ext9, -.buu { - result: match-nested-bar; -} -.ext8.ext9, -.fuu { - result: match-nested-foo; -} -.aa, -.cc { - color: black; -} -.aa .dd, -.aa .ee { - background: red; -} -.bb, -.cc, -.ee, -.ff { - background: red; -} -.bb .bb, -.ff .ff { - color: black; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/extract-and-length.css b/test/Fixtures/lessjs (1.6)/expected/extract-and-length.css deleted file mode 100644 index f550e201..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/extract-and-length.css +++ /dev/null @@ -1,133 +0,0 @@ -.multiunit { - length: 6; - extract: abc "abc" 1 1px 1% #112233; -} -.incorrect-index { - v1: extract(a b c, 5); - v2: extract(a, b, c, -2); -} -.scalar { - var-value: variable; - var-length: 1; - ill-index: extract(variable, 2); - name-value: name; - string-value: "string"; - number-value: 12345678; - color-value: #0000ff; - rgba-value: rgba(80, 160, 240, 0.67); - empty-value: ; - name-length: 1; - string-length: 1; - number-length: 1; - color-length: 1; - rgba-length: 1; - empty-length: 1; -} -.mixin-arguments-1 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-2 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-3 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-4 { - length: 0; - extract: extract(, 2) | extract(, 1); -} -.mixin-arguments-2 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-3 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-4 { - length: 3; - extract: c | b; -} -.mixin-arguments-2 { - length: 4; - extract: 3 | 2 | 1; -} -.mixin-arguments-3 { - length: 4; - extract: 3 | 2 | 1; -} -.mixin-arguments-4 { - length: 3; - extract: 3 | 2; -} -.md-space-comma { - length-1: 3; - extract-1: 1 2 3; - length-2: 3; - extract-2: 2; -} -.md-space-comma-as-args-2 { - length: 3; - extract: "x" "y" "z" | 1 2 3 | a b c; -} -.md-space-comma-as-args-3 { - length: 3; - extract: "x" "y" "z" | 1 2 3 | a b c; -} -.md-space-comma-as-args-4 { - length: 2; - extract: "x" "y" "z" | 1 2 3; -} -.md-cat-space-comma { - length-1: 3; - extract-1: 1 2 3; - length-2: 3; - extract-2: 2; -} -.md-cat-space-comma-as-args-2 { - length: 3; - extract: "x" "y" "z" | 1 2 3 | a b c; -} -.md-cat-space-comma-as-args-3 { - length: 3; - extract: "x" "y" "z" | 1 2 3 | a b c; -} -.md-cat-space-comma-as-args-4 { - length: 2; - extract: "x" "y" "z" | 1 2 3; -} -.md-cat-comma-space { - length-1: 3; - extract-1: 1, 2, 3; - length-2: 3; - extract-2: 2; -} -.md-cat-comma-space-as-args-1 { - length: 3; - extract: "x", "y", "z" | 1, 2, 3 | a, b, c; -} -.md-cat-comma-space-as-args-2 { - length: 3; - extract: "x", "y", "z" | 1, 2, 3 | a, b, c; -} -.md-cat-comma-space-as-args-3 { - length: 3; - extract: "x", "y", "z" | 1, 2, 3 | a, b, c; -} -.md-cat-comma-space-as-args-4 { - length: 0; - extract: extract(, 2) | extract(, 1); -} -.md-3D { - length-1: 2; - extract-1: a b c d, 1 2 3 4; - length-2: 2; - extract-2: 5 6 7 8; - length-3: 4; - extract-3: 7; - length-4: 1; - extract-4: 8; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/functions.css b/test/Fixtures/lessjs (1.6)/expected/functions.css deleted file mode 100644 index afa6448e..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/functions.css +++ /dev/null @@ -1,141 +0,0 @@ -#functions { - color: _color("evil red"); - width: increment(15); - height: undefined("self"); - border-width: add(2, 3); - variable: increment(10); - background: linear-gradient(#000000, #ffffff); -} -#built-in { - escaped: -Some::weird(#thing, y); - lighten: #ffcccc; - darken: #330000; - saturate: #203c31; - desaturate: #29332f; - greyscale: #2e2e2e; - hsl-clamp: #ffffff; - spin-p: #bf6a40; - spin-n: #bf4055; - luma-white: 100%; - luma-black: 0%; - luma-black-alpha: 0%; - luma-red: 21%; - luma-green: 72%; - luma-blue: 7%; - luma-yellow: 93%; - luma-cyan: 79%; - luma-white-alpha: 50%; - contrast-filter: contrast(30%); - saturate-filter: saturate(5%); - contrast-white: #000000; - contrast-black: #ffffff; - contrast-red: #ffffff; - contrast-green: #000000; - contrast-blue: #ffffff; - contrast-yellow: #000000; - contrast-cyan: #000000; - contrast-light: #111111; - contrast-dark: #eeeeee; - contrast-wrongorder: #111111; - contrast-light-thresh: #111111; - contrast-dark-thresh: #eeeeee; - contrast-high-thresh: #eeeeee; - contrast-low-thresh: #111111; - contrast-light-thresh-per: #111111; - contrast-dark-thresh-per: #eeeeee; - contrast-high-thresh-per: #eeeeee; - contrast-low-thresh-per: #111111; - format: "rgb(32, 128, 64)"; - format-string: "hello world"; - format-multiple: "hello earth 2"; - format-url-encode: "red is %23ff0000"; - eformat: rgb(32, 128, 64); - unitless: 12; - unit: 14em; - hue: 98; - saturation: 12%; - lightness: 95%; - hsvhue: 98; - hsvsaturation: 12%; - hsvvalue: 95%; - red: 255; - green: 255; - blue: 255; - rounded: 11; - rounded-two: 10.67; - roundedpx: 3px; - roundedpx-three: 3.333px; - rounded-percentage: 10%; - ceil: 11px; - floor: 12px; - sqrt: 5px; - pi: 3.14159265; - mod: 2m; - abs: 4%; - tan: 0.90040415; - sin: 0.17364819; - cos: 0.84385396; - atan: 0.1rad; - atan: 34deg; - atan: 44.9999964deg; - pow: 64px; - pow: 64; - pow: 27; - min: 0; - min: min("junk", 5); - min: 3pt; - max: 3; - max: max(8%, 1cm); - percentage: 20%; - color: #ff0011; - tint: #898989; - tint-full: #ffffff; - tint-percent: #898989; - tint-negative: #656565; - shade: #686868; - shade-full: #000000; - shade-percent: #686868; - shade-negative: #868686; - fade-out: rgba(255, 0, 0, 0.95); - fade-in: rgba(255, 0, 0, 0.95); - hsv: #4d2926; - hsva: rgba(77, 40, 38, 0.2); - mix: #ff3300; - mix-0: #ffff00; - mix-100: #ff0000; - mix-weightless: #ff8000; - mixt: rgba(255, 0, 0, 0.5); -} -#built-in .is-a { - color: true; - color1: true; - color2: true; - color3: true; - keyword: true; - number: true; - string: true; - pixel: true; - percent: true; - em: true; - cat: true; -} -#alpha { - alpha: rgba(153, 94, 51, 0.6); - alpha2: 0.5; - alpha3: 0; -} -#blendmodes { - multiply: #ed0000; - screen: #f600f6; - overlay: #ed0000; - softlight: #fa0000; - hardlight: #0000ed; - difference: #f600f6; - exclusion: #f600f6; - average: #7b007b; - negation: #d73131; -} -#extract-and-length { - extract: 3 2 1 C B A; - length: 6; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/ie-filters.css b/test/Fixtures/lessjs (1.6)/expected/ie-filters.css deleted file mode 100644 index 007aa536..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/ie-filters.css +++ /dev/null @@ -1,9 +0,0 @@ -.nav { - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=20); - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#333333", endColorstr="#000000", GradientType=0); -} -.evalTest1 { - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=30); - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=5); -} diff --git a/test/Fixtures/lessjs (1.6)/expected/import-inline.css b/test/Fixtures/lessjs (1.6)/expected/import-inline.css deleted file mode 100644 index f198d3c1..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/import-inline.css +++ /dev/null @@ -1,5 +0,0 @@ -this isn't very valid CSS. -@media (min-width: 600px) { - #css { color: yellow; } - -} diff --git a/test/Fixtures/lessjs (1.6)/expected/import-interpolation.css b/test/Fixtures/lessjs (1.6)/expected/import-interpolation.css deleted file mode 100644 index 16b7a150..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/import-interpolation.css +++ /dev/null @@ -1,6 +0,0 @@ -body { - width: 100%; -} -.a { - var: test; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/import-once.css b/test/Fixtures/lessjs (1.6)/expected/import-once.css deleted file mode 100644 index 2f86b3b3..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/import-once.css +++ /dev/null @@ -1,15 +0,0 @@ -#import { - color: #ff0000; -} -body { - width: 100%; -} -.test-f { - height: 10px; -} -body { - width: 100%; -} -.test-f { - height: 10px; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/import-reference.css b/test/Fixtures/lessjs (1.6)/expected/import-reference.css deleted file mode 100644 index d61df816..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/import-reference.css +++ /dev/null @@ -1,49 +0,0 @@ -/* - The media statement above is invalid (no selector) - We should ban invalid media queries with properties and no selector? -*/ -.visible { - color: red; -} -.visible .c { - color: green; -} -.visible { - color: green; -} -.visible:hover { - color: green; -} -.only-with-visible + .visible, -.visible + .only-with-visible, -.visible + .visible { - color: green; -} -.only-with-visible + .visible .sub, -.visible + .only-with-visible .sub, -.visible + .visible .sub { - color: green; -} -.b { - color: red; - color: green; -} -.b .c { - color: green; -} -.b:hover { - color: green; -} -.b + .b { - color: green; -} -.b + .b .sub { - color: green; -} -.y { - pulled-in: yes; -} -/* comment pulled in */ -.visible { - extend: test; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/import.css b/test/Fixtures/lessjs (1.6)/expected/import.css deleted file mode 100644 index a3749181..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/import.css +++ /dev/null @@ -1,36 +0,0 @@ -@import url(http://fonts.googleapis.com/css?family=Open+Sans); -@import url(/absolute/something.css) screen and (color) and (max-width: 600px); -@import url("//ha.com/file.css") (min-width: 100px); -#import-test { - height: 10px; - color: #ff0000; - width: 10px; - height: 30%; -} -@media screen and (max-width: 600px) { - body { - width: 100%; - } -} -#import { - color: #ff0000; -} -.mixin { - height: 10px; - color: #ff0000; -} -@media screen and (max-width: 601px) { - #css { - color: yellow; - } -} -@media screen and (max-width: 602px) { - body { - width: 100%; - } -} -@media screen and (max-width: 603px) { - #css { - color: yellow; - } -} diff --git a/test/Fixtures/lessjs (1.6)/expected/javascript.css b/test/Fixtures/lessjs (1.6)/expected/javascript.css deleted file mode 100644 index ba09e148..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/javascript.css +++ /dev/null @@ -1,20 +0,0 @@ -.eval { - js: /* Sorry, can not do JavaScript evaluation in PHP... :( */; - title: /* Sorry, can not do JavaScript evaluation in PHP... :( */; - ternary: /* Sorry, can not do JavaScript evaluation in PHP... :( */; - multiline: /* Sorry, can not do JavaScript evaluation in PHP... :( */; -} -.scope { - var: /* Sorry, can not do JavaScript evaluation in PHP... :( */; - escaped: /* Sorry, can not do JavaScript evaluation in PHP... :( */; -} -.vars { - width: /* Sorry, can not do JavaScript evaluation in PHP... :( */; -} -.escape-interpol { - width: /* Sorry, can not do JavaScript evaluation in PHP... :( */; -} -.arrays { - ary: /* Sorry, can not do JavaScript evaluation in PHP... :( */; - ary1: /* Sorry, can not do JavaScript evaluation in PHP... :( */; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/lazy-eval.css b/test/Fixtures/lessjs (1.6)/expected/lazy-eval.css deleted file mode 100644 index 1adfb8f3..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/lazy-eval.css +++ /dev/null @@ -1,3 +0,0 @@ -.lazy-eval { - width: 100%; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/media.css b/test/Fixtures/lessjs (1.6)/expected/media.css deleted file mode 100644 index 607f0e44..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/media.css +++ /dev/null @@ -1,219 +0,0 @@ -@media print { - .class { - color: blue; - } - .class .sub { - width: 42; - } - .top, - header > h1 { - color: #444444; - } -} -@media screen { - body { - max-width: 480; - } -} -@media all and (device-aspect-ratio: 16 / 9) { - body { - max-width: 800px; - } -} -@media all and (orientation: portrait) { - aside { - float: none; - } -} -@media handheld and (min-width: 42), screen and (min-width: 20em) { - body { - max-width: 480px; - } -} -@media print { - body { - padding: 20px; - } - body header { - background-color: red; - } -} -@media print and (orientation: landscape) { - body { - margin-left: 20px; - } -} -@media screen { - .sidebar { - width: 300px; - } -} -@media screen and (orientation: landscape) { - .sidebar { - width: 500px; - } -} -@media a and b { - .first .second .third { - width: 300px; - } - .first .second .fourth { - width: 3; - } -} -@media a and b and c { - .first .second .third { - width: 500px; - } -} -@media a, b and c { - body { - width: 95%; - } -} -@media a and x, b and c and x, a and y, b and c and y { - body { - width: 100%; - } -} -.a { - background: black; -} -@media handheld { - .a { - background: white; - } -} -@media handheld and (max-width: 100px) { - .a { - background: red; - } -} -.b { - background: black; -} -@media handheld { - .b { - background: white; - } -} -@media handheld and (max-width: 200px) { - .b { - background: red; - } -} -@media only screen and (max-width: 200px) { - body { - width: 480px; - } -} -@media print { - @page :left { - margin: 0.5cm; - } - @page :right { - margin: 0.5cm; - } - @page Test:first { - margin: 1cm; - } - @page :first { - size: 8.5in 11in; - - @top-left { - margin: 1cm; - } - @top-left-corner { - margin: 1cm; - } - @top-center { - margin: 1cm; - } - @top-right { - margin: 1cm; - } - @top-right-corner { - margin: 1cm; - } - @bottom-left { - margin: 1cm; - } - @bottom-left-corner { - margin: 1cm; - } - @bottom-center { - margin: 1cm; - } - @bottom-right { - margin: 1cm; - } - @bottom-right-corner { - margin: 1cm; - } - @left-top { - margin: 1cm; - } - @left-middle { - margin: 1cm; - } - @left-bottom { - margin: 1cm; - } - @right-top { - margin: 1cm; - } - @right-middle { - content: "Page " counter(page); - } - @right-bottom { - margin: 1cm; - } - } -} -@media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: 2/1), (min-resolution: 2dppx), (min-resolution: 128dpcm) { - .b { - background: red; - } -} -body { - background: red; -} -@media (max-width: 500px) { - body { - background: green; - } -} -@media (max-width: 1000px) { - body { - background: red; - background: blue; - } -} -@media (max-width: 1000px) and (max-width: 500px) { - body { - background: green; - } -} -@media (max-width: 1200px) { - /* a comment */ -} -@media (max-width: 1200px) and (max-width: 900px) { - body { - font-size: 11px; - } -} -@media (min-width: 480px) { - .nav-justified > li { - display: table-cell; - } -} -@media (min-width: 768px) and (min-width: 480px) { - .menu > li { - display: table-cell; - } -} -@media all and tv { - .all-and-tv-variables { - var: all-and-tv; - } -} diff --git a/test/Fixtures/lessjs (1.6)/expected/merge.css b/test/Fixtures/lessjs (1.6)/expected/merge.css deleted file mode 100644 index 18539f1a..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/merge.css +++ /dev/null @@ -1,26 +0,0 @@ -.test1 { - transform: rotate(90deg), skew(30deg), scale(2, 4); -} -.test2 { - transform: rotate(90deg), skew(30deg); - transform: scaleX(45deg); -} -.test3 { - transform: scaleX(45deg); - background: url(data://img1.png); -} -.test4 { - transform: rotate(90deg), skew(30deg); - transform: scale(2, 4) !important; -} -.test5 { - transform: rotate(90deg), skew(30deg); - transform: scale(2, 4) !important; -} -.test6 { - transform: scale(2, 4); -} -.test-interleaved { - transform: t1, t2, t3; - background: b1, b2, b3; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/mixins-args.css b/test/Fixtures/lessjs (1.6)/expected/mixins-args.css deleted file mode 100644 index 724613ad..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/mixins-args.css +++ /dev/null @@ -1,113 +0,0 @@ -#hidden { - color: transparent; -} -#hidden1 { - color: transparent; -} -.two-args { - color: blue; - width: 10px; - height: 99%; - border: 2px dotted #000000; -} -.one-arg { - width: 15px; - height: 49%; -} -.no-parens { - width: 5px; - height: 49%; -} -.no-args { - width: 5px; - height: 49%; -} -.var-args { - width: 45; - height: 17%; -} -.multi-mix { - width: 10px; - height: 29%; - margin: 4; - padding: 5; -} -body { - padding: 30px; - color: #ff0000; -} -.scope-mix { - width: 8; -} -.content { - width: 600px; -} -.content .column { - margin: 600px; -} -#same-var-name { - radius: 5px; -} -#var-inside { - width: 10px; -} -.arguments { - border: 1px solid #000000; - width: 1px; -} -.arguments2 { - border: 0px; - width: 0px; -} -.arguments3 { - border: 0px; - width: 0px; -} -.arguments4 { - border: 0 1 2 3 4; - rest: 1 2 3 4; - width: 0; -} -.edge-case { - border: "{"; - width: "{"; -} -.slash-vs-math { - border-radius: 0.4px; - border-radius: 0.5px; - border-radius: 6px; -} -.comma-vs-semi-colon { - one: a; - two: b, c; - one: d, e; - two: f; - one: g; - one: h; - one: i; - one: j; - one: k; - two: l; - one: m, n; - one: o, p; - two: q; - one: r, s; - two: t; -} -#named-conflict { - four: a, 11, 12, 13; - four: a, 21, 22, 23; -} -.test-mixin-default-arg { - defaults: 1px 1px 1px; - defaults: 2px 2px 2px; -} -.selector { - margin: 2, 2, 2, 2; -} -.selector2 { - margin: 2, 2, 2, 2; -} -.selector3 { - margin: 4; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/mixins-closure.css b/test/Fixtures/lessjs (1.6)/expected/mixins-closure.css deleted file mode 100644 index b1021b6f..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/mixins-closure.css +++ /dev/null @@ -1,9 +0,0 @@ -.class { - width: 99px; -} -.overwrite { - width: 99px; -} -.nested .class { - width: 5px; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/mixins-guards-default-func.css b/test/Fixtures/lessjs (1.6)/expected/mixins-guards-default-func.css deleted file mode 100644 index e47f05cf..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/mixins-guards-default-func.css +++ /dev/null @@ -1,129 +0,0 @@ -guard-default-basic-1-1 { - case: 1; -} -guard-default-basic-1-2 { - default: 2; -} -guard-default-basic-2-0 { - default: 0; -} -guard-default-basic-2-2 { - case: 2; -} -guard-default-basic-3-0 { - default: 0; -} -guard-default-basic-3-2 { - case: 2; -} -guard-default-basic-3-3 { - case: 3; -} -guard-default-definition-order-0 { - default: 0; -} -guard-default-definition-order-2 { - case: 2; -} -guard-default-definition-order-2 { - case: 3; -} -guard-default-out-of-guard-0 { - case-0: default(); - case-1: 1; - default: 2; - case-2: default(); -} -guard-default-out-of-guard-1 { - default: default(); -} -guard-default-out-of-guard-2 { - default: default(); -} -guard-default-expr-not-1 { - case: 1; - default: 1; -} -guard-default-expr-eq-true { - case: true; -} -guard-default-expr-eq-false { - case: false; - default: false; -} -guard-default-expr-or-1 { - case: 1; -} -guard-default-expr-or-2 { - case: 2; - default: 2; -} -guard-default-expr-or-3 { - default: 3; -} -guard-default-expr-and-1 { - case: 1; -} -guard-default-expr-and-2 { - case: 2; -} -guard-default-expr-and-3 { - default: 3; -} -guard-default-expr-always-1 { - case: 1; - default: 1; -} -guard-default-expr-always-2 { - default: 2; -} -guard-default-expr-never-1 { - case: 1; -} -guard-default-multi-1-0 { - case: 0; -} -guard-default-multi-1-1 { - default-1: 1; -} -guard-default-multi-2-1 { - default-1: no; -} -guard-default-multi-2-2 { - default-2: no; -} -guard-default-multi-2-3 { - default-3: 3; -} -guard-default-multi-3-blue { - case-2: #00008b; -} -guard-default-multi-3-green { - default-color: #008000; -} -guard-default-multi-3-foo { - case-1: I am 'foo'; -} -guard-default-multi-3-baz { - default-string: I am 'baz'; -} -guard-default-multi-4 { - always: 1; - always: 2; - case: 2; -} -guard-default-not-ambiguos-2 { - case: 1; - not-default: 2; -} -guard-default-not-ambiguos-3 { - case: 1; - not-default-1: 2; - not-default-2: 2; -} -guard-default-scopes-3 { - 3: when default; -} -guard-default-scopes-1 { - 1: no condition; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/mixins-guards.css b/test/Fixtures/lessjs (1.6)/expected/mixins-guards.css deleted file mode 100644 index 25e6f287..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/mixins-guards.css +++ /dev/null @@ -1,82 +0,0 @@ -.light1 { - color: white; - margin: 1px; -} -.light2 { - color: black; - margin: 1px; -} -.max1 { - width: 6; -} -.max2 { - width: 8; -} -.glob1 { - margin: auto auto; -} -.ops1 { - height: gt-or-eq; - height: lt-or-eq; - height: lt-or-eq-alias; -} -.ops2 { - height: gt-or-eq; - height: not-eq; -} -.ops3 { - height: lt-or-eq; - height: lt-or-eq-alias; - height: not-eq; -} -.default1 { - content: default; -} -.test1 { - content: "true."; -} -.test2 { - content: "false."; -} -.test3 { - content: "false."; -} -.test4 { - content: "false."; -} -.test5 { - content: "false."; -} -.bool1 { - content: true and true; - content: true; - content: false, true; - content: false and true and true, true; - content: false, true and true; - content: false, false, true; - content: false, true and true and true, false; - content: not false; - content: not false and false, not false; -} -.equality-units { - test: pass; -} -.colorguardtest { - content: is #ff0000; - content: is not #0000ff its #ff0000; - content: is not #0000ff its #800080; -} -.stringguardtest { - content: is theme1; - content: is not theme2; - content: is theme1 no quotes; -} -#tryNumberPx { - catch: all; - declare: 4; - declare: 4px; -} -.call-lock-mixin .call-inner-lock-mixin { - a: 1; - x: 1; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/mixins-important.css b/test/Fixtures/lessjs (1.6)/expected/mixins-important.css deleted file mode 100644 index b100af7f..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/mixins-important.css +++ /dev/null @@ -1,45 +0,0 @@ -.class { - border: 1; - boxer: 1; - border-width: 1; - border: 2 !important; - boxer: 2 !important; - border-width: 2 !important; - border: 3; - boxer: 3; - border-width: 3; - border: 4 !important; - boxer: 4 !important; - border-width: 4 !important; - border: 5; - boxer: 5; - border-width: 5; - border: 0 !important; - boxer: 0 !important; - border-width: 0 !important; - border: 9 !important; - border: 9; - boxer: 9; - border-width: 9; -} -.class .inner { - test: 1; -} -.class .inner { - test: 2 !important; -} -.class .inner { - test: 3; -} -.class .inner { - test: 4 !important; -} -.class .inner { - test: 5; -} -.class .inner { - test: 0 !important; -} -.class .inner { - test: 9; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/mixins-interpolated.css b/test/Fixtures/lessjs (1.6)/expected/mixins-interpolated.css deleted file mode 100644 index 637b5b68..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/mixins-interpolated.css +++ /dev/null @@ -1,39 +0,0 @@ -.foo { - a: 1; -} -.foo { - a: 2; -} -#foo { - a: 3; -} -#foo { - a: 4; -} -mi-test-a { - a: 1; - a: 2; - a: 3; - a: 4; -} -.b .bb.foo-xxx .yyy-foo#foo .foo.bbb { - b: 1; -} -mi-test-b { - b: 1; -} -#foo-foo > .bar .baz { - c: c; -} -mi-test-c-1 > .bar .baz { - c: c; -} -mi-test-c-2 .baz { - c: c; -} -mi-test-c-3 { - c: c; -} -mi-test-d { - gender: "Male"; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/mixins-named-args.css b/test/Fixtures/lessjs (1.6)/expected/mixins-named-args.css deleted file mode 100644 index e460aa10..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/mixins-named-args.css +++ /dev/null @@ -1,27 +0,0 @@ -.named-arg { - color: blue; - width: 5px; - height: 99%; - args: 1px 100%; - text-align: center; -} -.class { - width: 5px; - height: 19%; - args: 1px 20%; -} -.all-args-wrong-args { - width: 10px; - height: 9%; - args: 2px 10%; -} -.named-args2 { - width: 15px; - height: 49%; - color: #646464; -} -.named-args3 { - width: 5px; - height: 29%; - color: #123456; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/mixins-nested.css b/test/Fixtures/lessjs (1.6)/expected/mixins-nested.css deleted file mode 100644 index 6378c475..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/mixins-nested.css +++ /dev/null @@ -1,14 +0,0 @@ -.class .inner { - height: 300; -} -.class .inner .innest { - width: 30; - border-width: 60; -} -.class2 .inner { - height: 600; -} -.class2 .inner .innest { - width: 60; - border-width: 120; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/mixins-pattern.css b/test/Fixtures/lessjs (1.6)/expected/mixins-pattern.css deleted file mode 100644 index 8b828335..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/mixins-pattern.css +++ /dev/null @@ -1,47 +0,0 @@ -.zero { - variadic: true; - zero: 0; - one: 1; - two: 2; - three: 3; -} -.one { - variadic: true; - one: 1; - one-req: 1; - two: 2; - three: 3; -} -.two { - variadic: true; - two: 2; - three: 3; -} -.three { - variadic: true; - three-req: 3; - three: 3; -} -.left { - left: 1; -} -.right { - right: 1; -} -.border-right { - color: black; - border-right: 4px; -} -.border-left { - color: black; - border-left: 4px; -} -.only-right { - right: 33; -} -.only-left { - left: 33; -} -.left-right { - both: 330; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/mixins.css b/test/Fixtures/lessjs (1.6)/expected/mixins.css deleted file mode 100644 index 32097f97..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/mixins.css +++ /dev/null @@ -1,141 +0,0 @@ -.mixin { - border: 1px solid black; -} -.mixout { - border-color: orange; -} -.borders { - border-style: dashed; -} -#namespace .borders { - border-style: dotted; -} -#namespace .biohazard { - content: "death"; -} -#namespace .biohazard .man { - color: transparent; -} -#theme > .mixin { - background-color: grey; -} -#container { - color: black; - border: 1px solid black; - border-color: orange; - background-color: grey; -} -#header .milk { - color: white; - border: 1px solid black; - background-color: grey; -} -#header #cookie { - border-style: dashed; -} -#header #cookie .chips { - border-style: dotted; -} -#header #cookie .chips .calories { - color: black; - border: 1px solid black; - border-color: orange; - background-color: grey; -} -.secure-zone { - color: transparent; -} -.direct { - border-style: dotted; -} -.bo, -.bar { - width: 100%; -} -.bo { - border: 1px; -} -.ar.bo.ca { - color: black; -} -.jo.ki { - background: none; -} -.amp.support { - color: orange; -} -.amp.support .higher { - top: 0px; -} -.amp.support.deeper { - height: auto; -} -.extended { - width: 100%; - border: 1px; - background: none; - color: orange; - top: 0px; - height: auto; -} -.extended .higher { - top: 0px; -} -.extended.deeper { - height: auto; -} -.do .re .mi .fa .sol .la .si { - color: cyan; -} -.mutli-selector-parents { - color: cyan; -} -.foo .bar { - width: 100%; -} -.underParents { - color: red; -} -.parent .underParents { - color: red; -} -* + h1 { - margin-top: 25px; -} -legend + h1 { - margin-top: 0; -} -h1 + * { - margin-top: 10px; -} -* + h2 { - margin-top: 20px; -} -legend + h2 { - margin-top: 0; -} -h2 + * { - margin-top: 8px; -} -* + h3 { - margin-top: 15px; -} -legend + h3 { - margin-top: 0; -} -h3 + * { - margin-top: 5px; -} -.error { - background-image: "/a.png"; - background-position: center center; -} -.test-rec .recursion { - color: black; -} -.button { - padding-left: 44px; -} -.button.large { - padding-left: 40em; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/no-output.css b/test/Fixtures/lessjs (1.6)/expected/no-output.css deleted file mode 100644 index 8b137891..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/no-output.css +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/Fixtures/lessjs (1.6)/expected/operations.css b/test/Fixtures/lessjs (1.6)/expected/operations.css deleted file mode 100644 index fb9e0aff..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/operations.css +++ /dev/null @@ -1,49 +0,0 @@ -#operations { - color: #111111; - height: 9px; - width: 3em; - substraction: 0; - division: 1; -} -#operations .spacing { - height: 9px; - width: 3em; -} -.with-variables { - height: 16em; - width: 24em; - size: 1cm; -} -.with-functions { - color: #646464; - color: #ff8080; - color: #c94a4a; -} -.negative { - height: 0px; - width: 4px; -} -.shorthands { - padding: -1px 2px 0 -4px; -} -.rem-dimensions { - font-size: 5.5rem; -} -.colors { - color: #123; - border-color: #334455; - background-color: #000000; -} -.colors .other { - color: #222222; - border-color: #222222; -} -.negations { - variable: -4px; - variable1: 0px; - variable2: 0px; - variable3: 8px; - variable4: 0px; - paren: -4px; - paren2: 16px; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/parens.css b/test/Fixtures/lessjs (1.6)/expected/parens.css deleted file mode 100644 index 7321696b..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/parens.css +++ /dev/null @@ -1,36 +0,0 @@ -.parens { - border: 2px solid #000000; - margin: 1px 3px 16 3; - width: 36; - padding: 2px 36px; -} -.more-parens { - padding: 8 4 4 4px; - width-all: 96; - width-first: 96; - width-keep: 96; - height-keep: 113; - height-all: 113; - height-parts: 113; - margin-keep: 12; - margin-parts: 12; - margin-all: 12; - border-radius-keep: 5px; - border-radius-parts: 1.14285714px; - border-radius-all: 5px; -} -.negative { - neg-var: -1; - neg-var-paren: -1; -} -.nested-parens { - width: 71; - height: 6; -} -.mixed-units { - margin: 2px 4em 1 5pc; - padding: 6px 1em 2px 2; -} -.test-false-negatives { - a: (; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/property-name-interp.css b/test/Fixtures/lessjs (1.6)/expected/property-name-interp.css deleted file mode 100644 index ccb78557..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/property-name-interp.css +++ /dev/null @@ -1,20 +0,0 @@ -pi-test { - border: 0; - ufo-width: 50%; - *-z-border: 1px dashed blue; - -www-border-top: 2px; - radius-is-not-a-border: true; - border-top-left-radius: 2em; - border-top-red-radius-: 3pt; - global-local-mixer-property: strong; -} -pi-test-merge { - pre-property-ish: high, middle, low, base; - pre-property-ish+: nice try dude; -} -pi-indirect-vars { - auto: auto; -} -pi-complex-values { - 3px rgba(255, 255, 0, 0.5), 3.14159265 /* foo */3px rgba(255, 255, 0, 0.5), 3.14159265 /* foo */: none; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/rulesets.css b/test/Fixtures/lessjs (1.6)/expected/rulesets.css deleted file mode 100644 index 408c76aa..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/rulesets.css +++ /dev/null @@ -1,33 +0,0 @@ -#first > .one { - font-size: 2em; -} -#first > .one > #second .two > #deux { - width: 50%; -} -#first > .one > #second .two > #deux #third { - height: 100%; -} -#first > .one > #second .two > #deux #third:focus { - color: black; -} -#first > .one > #second .two > #deux #third:focus #fifth > #sixth .seventh #eighth + #ninth { - color: purple; -} -#first > .one > #second .two > #deux #fourth, -#first > .one > #second .two > #deux #five, -#first > .one > #second .two > #deux #six { - color: #110000; -} -#first > .one > #second .two > #deux #fourth .seven, -#first > .one > #second .two > #deux #five .seven, -#first > .one > #second .two > #deux #six .seven, -#first > .one > #second .two > #deux #fourth .eight > #nine, -#first > .one > #second .two > #deux #five .eight > #nine, -#first > .one > #second .two > #deux #six .eight > #nine { - border: 1px solid black; -} -#first > .one > #second .two > #deux #fourth #ten, -#first > .one > #second .two > #deux #five #ten, -#first > .one > #second .two > #deux #six #ten { - color: red; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/scope.css b/test/Fixtures/lessjs (1.6)/expected/scope.css deleted file mode 100644 index baa05523..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/scope.css +++ /dev/null @@ -1,35 +0,0 @@ -.tiny-scope { - color: #998899; -} -.scope1 { - color: #0000ff; - border-color: #000000; -} -.scope1 .scope2 { - color: #0000ff; -} -.scope1 .scope2 .scope3 { - color: #ff0000; - border-color: #000000; - background-color: #ffffff; -} -.scope { - scoped-val: #008000; -} -.heightIsSet { - height: 1024px; -} -.useHeightInMixinCall { - mixin-height: 1024px; -} -.imported { - exists: true; -} -.testImported { - exists: true; -} -#allAreUsedHere { - default: 'top level'; - scope: 'top level'; - sub-scope-only: 'inside'; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/selectors.css b/test/Fixtures/lessjs (1.6)/expected/selectors.css deleted file mode 100644 index 11909fe5..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/selectors.css +++ /dev/null @@ -1,153 +0,0 @@ -h1 a:hover, -h2 a:hover, -h3 a:hover, -h1 p:hover, -h2 p:hover, -h3 p:hover { - color: red; -} -#all { - color: blue; -} -#the { - color: blue; -} -#same { - color: blue; -} -ul, -li, -div, -q, -blockquote, -textarea { - margin: 0; -} -td { - margin: 0; - padding: 0; -} -td, -input { - line-height: 1em; -} -a { - color: red; -} -a:hover { - color: blue; -} -div a { - color: green; -} -p a span { - color: yellow; -} -.foo .bar .qux, -.foo .baz .qux { - display: block; -} -.qux .foo .bar, -.qux .foo .baz { - display: inline; -} -.qux.foo .bar, -.qux.foo .baz { - display: inline-block; -} -.qux .foo .bar .biz, -.qux .foo .baz .biz { - display: none; -} -.a.b.c { - color: red; -} -.c .b.a { - color: red; -} -.foo .p.bar { - color: red; -} -.foo.p.bar { - color: red; -} -.foo + .foo { - background: amber; -} -.foo + .foo { - background: amber; -} -.foo + .foo, -.foo + .bar, -.bar + .foo, -.bar + .bar { - background: amber; -} -.foo a > .foo a, -.foo a > .bar a, -.foo a > .foo b, -.foo a > .bar b, -.bar a > .foo a, -.bar a > .bar a, -.bar a > .foo b, -.bar a > .bar b, -.foo b > .foo a, -.foo b > .bar a, -.foo b > .foo b, -.foo b > .bar b, -.bar b > .foo a, -.bar b > .bar a, -.bar b > .foo b, -.bar b > .bar b { - background: amber; -} -.other ::fnord { - color: red; -} -.other::fnord { - color: red; -} -.other ::bnord { - color: red; -} -.other::bnord { - color: red; -} -.blood { - color: red; -} -.bloodred { - color: green; -} -#blood.blood.red.black { - color: black; -} -:nth-child(3) { - selector: interpolated; -} -.test:nth-child(odd):not(:nth-child(3)) { - color: #ff0000; -} -[prop], -[prop=10%], -[prop="value3"], -[prop*="val3"], -[|prop~="val3"], -[*|prop$="val3"], -[ns|prop^="val3"], -[3^="val3"], -[3=3], -[3] { - attributes: yes; -} -/* -Large comment means chunk will be emitted after } which means chunk will begin with whitespace... -blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank -blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank -blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank -blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank -blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank -*/ -.blood { - color: red; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/strings.css b/test/Fixtures/lessjs (1.6)/expected/strings.css deleted file mode 100644 index cd6d6020..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/strings.css +++ /dev/null @@ -1,43 +0,0 @@ -#strings { - background-image: url("http://son-of-a-banana.com"); - quotes: "~" "~"; - content: "#*%:&^,)!.(~*})"; - empty: ""; - brackets: "{" "}"; - escapes: "\"hello\" \\world"; - escapes2: "\"llo"; -} -#comments { - content: "/* hello */ // not-so-secret"; -} -#single-quote { - quotes: "'" "'"; - content: '""#!&""'; - empty: ''; - semi-colon: ';'; -} -#escaped { - filter: DX.Transform.MS.BS.filter(opacity=50); -} -#one-line { - image: url(http://tooks.com); -} -#crazy { - image: url(http://), "}", url("http://}"); -} -#interpolation { - url: "http://lesscss.org/dev/image.jpg"; - url2: "http://lesscss.org/image-256.jpg"; - url3: "http://lesscss.org#445566"; - url4: "http://lesscss.org/hello"; - url5: "http://lesscss.org/54.4px"; -} -.mix-mul-class { - color: #0000ff; - color: #ff0000; - color: #000000; - color: #ffa500; -} -.watermark { - family: Univers, Arial, Verdana, San-Serif; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/urls.css b/test/Fixtures/lessjs (1.6)/expected/urls.css deleted file mode 100644 index af5b0542..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/urls.css +++ /dev/null @@ -1,71 +0,0 @@ -@import "css/background.css"; -@import "import/import-test-d.css"; -@import "file.css"; -@font-face { - src: url("/fonts/garamond-pro.ttf"); - src: local(Futura-Medium), url(fonts.svg#MyGeometricModern) format("svg"); -} -#shorthands { - background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; - background: url("img.jpg") center / 100px; - background: #ffffff url(image.png) center / 1px 100px repeat-x scroll content-box padding-box; -} -#misc { - background-image: url(images/image.jpg); -} -#data-uri { - background: url(data:image/png;charset=utf-8;base64, - kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ - k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U - kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700); - background-image: url("http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700"); -} -#svg-data-uri { - background: rgba(0, 0, 0, 0) url('data:image/svg+xml, '); -} -.comma-delimited { - background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg); -} -.values { - url: url('Trebuchet'); -} -#logo { - width: 100px; - height: 100px; - background: url('import/assets/logo.png'); -} -@font-face { - font-family: xecret; - src: url('import/assets/xecret.ttf'); -} -#secret { - font-family: xecret, sans-serif; -} -#imported-relative-path { - background-image: url(../data/image.jpg); - border-image: url('../data/image.jpg'); -} -#relative-url-import { - background-image: url(../data/image.jpg); - border-image: url('../data/image.jpg'); -} -#data-uri { - uri: url("data:image/jpeg;base64,bm90IGFjdHVhbGx5IGEganBlZyBmaWxlCg=="); -} -#data-uri-guess { - uri: url("data:image/jpeg;base64,bm90IGFjdHVhbGx5IGEganBlZyBmaWxlCg=="); -} -#data-uri-ascii { - uri-1: url("data:text/html,%3Ch1%3EThis%20page%20is%20100%25%20Awesome.%3C%2Fh1%3E%0A"); - uri-2: url("data:text/html,%3Ch1%3EThis%20page%20is%20100%25%20Awesome.%3C%2Fh1%3E%0A"); -} -#data-uri-toobig { - uri: url('../data/data-uri-fail.png'); -} -#svg-functions { - background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhZGllbnQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjwvbGluZWFyR3JhZGllbnQ+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkaWVudCkiIC8+PC9zdmc+'); - background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhZGllbnQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIvPjxzdG9wIG9mZnNldD0iMyUiIHN0b3AtY29sb3I9IiNmZmE1MDAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIGZpbGw9InVybCgjZ3JhZGllbnQpIiAvPjwvc3ZnPg=='); - background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhZGllbnQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIxJSIgc3RvcC1jb2xvcj0iI2M0YzRjNCIvPjxzdG9wIG9mZnNldD0iMyUiIHN0b3AtY29sb3I9IiNmZmE1MDAiLz48c3RvcCBvZmZzZXQ9IjUlIiBzdG9wLWNvbG9yPSIjMDA4MDAwIi8+PHN0b3Agb2Zmc2V0PSI5NSUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIGZpbGw9InVybCgjZ3JhZGllbnQpIiAvPjwvc3ZnPg=='); -} diff --git a/test/Fixtures/lessjs (1.6)/expected/variables.css b/test/Fixtures/lessjs (1.6)/expected/variables.css deleted file mode 100644 index 0eb73974..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/variables.css +++ /dev/null @@ -1,45 +0,0 @@ -.variables { - width: 14cm; -} -.variables { - height: 24px; - color: #888888; - font-family: "Trebuchet MS", Verdana, sans-serif; - quotes: "~" "~"; -} -.redef { - zero: 0; -} -.redef .inition { - three: 3; -} -.values { - minus-one: -1; - font-family: 'Trebuchet', 'Trebuchet', 'Trebuchet'; - color: #888888 !important; - multi: something 'A', B, C, 'Trebuchet'; -} -.variable-names { - name: 'hello'; -} -.alpha { - filter: alpha(opacity=42); -} -.testPollution { - a: 'no-pollution'; -} -.units { - width: 1px; - same-unit-as-previously: 1px; - square-pixel-divided: 1px; - odd-unit: 2; - percentage: 500%; - pixels: 500px; - conversion-metric-a: 30mm; - conversion-metric-b: 3cm; - conversion-imperial: 3.00000055in; - custom-unit: 420octocats; - custom-unit-cancelling: 18dogs; - mix-units: 2px; - invalid-units: 1px; -} diff --git a/test/Fixtures/lessjs (1.6)/expected/whitespace.css b/test/Fixtures/lessjs (1.6)/expected/whitespace.css deleted file mode 100644 index bafbd90b..00000000 --- a/test/Fixtures/lessjs (1.6)/expected/whitespace.css +++ /dev/null @@ -1,42 +0,0 @@ -.whitespace { - color: white; -} -.whitespace { - color: white; -} -.whitespace { - color: white; -} -.whitespace { - color: white; -} -.whitespace { - color: white; -} -.white, -.space, -.mania { - color: white; -} -.no-semi-column { - color: white; -} -.no-semi-column { - color: white; - white-space: pre; -} -.no-semi-column { - border: 2px solid #ffffff; -} -.newlines { - background: the, - great, - wall; - border: 2px - solid - black; -} -.sel .newline_ws .tab_ws { - color: white; - background-position: 45 -23; -} diff --git a/test/Fixtures/lessjs (1.6)/less/charsets.less b/test/Fixtures/lessjs (1.6)/less/charsets.less deleted file mode 100644 index 550d40e9..00000000 --- a/test/Fixtures/lessjs (1.6)/less/charsets.less +++ /dev/null @@ -1,3 +0,0 @@ -@charset "UTF-8"; - -@import "import/import-charset-test"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/colors.less b/test/Fixtures/lessjs (1.6)/less/colors.less deleted file mode 100644 index 7abda4e5..00000000 --- a/test/Fixtures/lessjs (1.6)/less/colors.less +++ /dev/null @@ -1,98 +0,0 @@ -#yelow { - #short { - color: #fea; - } - #long { - color: #ffeeaa; - } - #rgba { - color: rgba(255, 238, 170, 0.1); - } - #argb { - color: argb(rgba(255, 238, 170, 0.1)); - } -} - -#blue { - #short { - color: #00f; - } - #long { - color: #0000ff; - } - #rgba { - color: rgba(0, 0, 255, 0.1); - } - #argb { - color: argb(rgba(0, 0, 255, 0.1)); - } -} - -#alpha #hsla { - color: hsla(11, 20%, 20%, 0.6); -} - -#overflow { - .a { color: (#111111 - #444444); } // #000000 - .b { color: (#eee + #fff); } // #ffffff - .c { color: (#aaa * 3); } // #ffffff - .d { color: (#00ee00 + #009900); } // #00ff00 - .e { color: rgba(-99.9, 31.4159, 321, 0.42); } -} - -#grey { - color: rgb(200, 200, 200); -} - -#333333 { - color: rgb(20%, 20%, 20%); -} - -#808080 { - color: hsl(50, 0%, 50%); -} - -#00ff00 { - color: hsl(120, 100%, 50%); -} - -.lightenblue { - color: lighten(blue, 10%); -} - -.darkenblue { - color: darken(blue, 10%); -} - -.unknowncolors { - color: blue2; - border: 2px solid superred; -} - -.transparent { - color: transparent; - background-color: rgba(0, 0, 0, 0); -} -#alpha { - @colorvar: rgba(150, 200, 150, 0.7); - #fromvar { - opacity: alpha(@colorvar); - } - #short { - opacity: alpha(#aaa); - } - #long { - opacity: alpha(#bababa); - } - #rgba { - opacity: alpha(rgba(50, 120, 95, 0.2)); - } - #hsl { - opacity: alpha(hsl(120, 100%, 50%)); - } -} - -#percentage { - color: red(rgb(100%, 0, 0)); - border-color: rgba(100%, 0, 0, 50%); -} diff --git a/test/Fixtures/lessjs (1.6)/less/comments.less b/test/Fixtures/lessjs (1.6)/less/comments.less deleted file mode 100644 index 7859911e..00000000 --- a/test/Fixtures/lessjs (1.6)/less/comments.less +++ /dev/null @@ -1,83 +0,0 @@ -/******************\ -* * -* Comment Header * -* * -\******************/ - -/* - - Comment - -*/ - -/* - * Comment Test - * - * - cloudhead (http://cloudhead.net) - * - */ - -//////////////// -@var: "content"; -//////////////// - -/* Colors - * ------ - * #EDF8FC (background blue) - * #166C89 (darkest blue) - * - * Text: - * #333 (standard text) // A comment within a comment! - * #1F9EC9 (standard link) - * - */ - -/* @group Variables -------------------- */ -#comments /* boo *//* boo again*/, -//.commented_out1 -//.commented_out2 -//.commented_out3 -.comments //end of comments1 -//end of comments2 -{ - /**/ // An empty comment - color: red; /* A C-style comment */ /* A C-style comment */ - background-color: orange; // A little comment - font-size: 12px; - - /* lost comment */ content: @var; - - border: 1px solid black; - - // padding & margin // - padding: 0; // }{ '" - margin: 2em; -} // - -/* commented out - #more-comments { - color: grey; - } -*/ - -.selector /* .with */, .lots, /* of */ .comments { - color: grey, /* blue */ orange; - -webkit-border-radius: 2px /* webkit only */; - -moz-border-radius: (2px * 4) /* moz only with operation */; -} - -.mixin_def_with_colors(@a: white, // in - @b: 1px //put in @b - causes problems! ---> - ) // the - when (@a = white) { - .test { - color: @b; - } -} -.mixin_def_with_colors(); - -#last { color: blue } -// - -/* *//* { *//* *//* *//* */#div { color:#A33; }/* } */ diff --git a/test/Fixtures/lessjs (1.6)/less/compression/compression.less b/test/Fixtures/lessjs (1.6)/less/compression/compression.less deleted file mode 100644 index c196336a..00000000 --- a/test/Fixtures/lessjs (1.6)/less/compression/compression.less +++ /dev/null @@ -1,36 +0,0 @@ -#colours { - color1: #fea; - color2: #ffeeaa; - color3: rgba(255, 238, 170, 0.1); - @color1: #fea; - string: "@{color1}"; - /* comments are stripped */ - // both types! - /*! but not this type - Note preserved whitespace - */ -} -dimensions { - val: 0.1px; - val: 0em; - val: 4cm; - val: 0.2; - val: 5; - angles-must-have-unit: 0deg; - durations-must-have-unit: 0s; - length-doesnt-have-unit: 0px; - width: auto\9; -} -@page { - marks: none; -@top-left-corner { - vertical-align: top; -} -@top-left { - vertical-align: top; -} -} -.shadow ^ .dom, -body ^^ .shadow { - display: done; -} diff --git a/test/Fixtures/lessjs (1.6)/less/css-3.less b/test/Fixtures/lessjs (1.6)/less/css-3.less deleted file mode 100644 index 06a5d2c5..00000000 --- a/test/Fixtures/lessjs (1.6)/less/css-3.less +++ /dev/null @@ -1,129 +0,0 @@ -.comma-delimited { - text-shadow: -1px -1px 1px red, 6px 5px 5px yellow; - -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset, - 0pt 4px 6px rgba(255, 255, 255, 0.4) inset; - -webkit-transform: rotate(-0.0000000001deg); -} -@font-face { - font-family: Headline; - unicode-range: U+??????, U+0???, U+0-7F, U+A5; -} -.other { - -moz-transform: translate(0, 11em) rotate(-90deg); - transform: rotateX(45deg); -} -.item[data-cra_zy-attr1b-ut3=bold] { - font-weight: bold; -} -p:not([class*="lead"]) { - color: black; -} - -input[type="text"].class#id[attr=32]:not(1) { - color: white; -} - -div#id.class[a=1][b=2].class:not(1) { - color: white; -} - -ul.comma > li:not(:only-child)::after { - color: white; -} - -ol.comma > li:nth-last-child(2)::after { - color: white; -} - -li:nth-child(4n+1), -li:nth-child(-5n), -li:nth-child(-n+2) { - color: white; -} - -a[href^="http://"] { - color: black; -} - -a[href$="http://"] { - color: black; -} - -form[data-disabled] { - color: black; -} - -p::before { - color: black; -} - -#issue322 { - -webkit-animation: anim2 7s infinite ease-in-out; -} - -@-webkit-keyframes frames { - 0% { border: 1px } - 5.5% { border: 2px } - 100% { border: 3px } -} - -@keyframes fontbulger1 { - to { - font-size: 15px; - } - from,to { - font-size: 12px; - } - 0%,100% { - font-size: 12px; - } -} - -.units { - font: 1.2rem/2rem; - font: 8vw/9vw; - font: 10vh/12vh; - font: 12vm/15vm; - font: 12vmin/15vmin; - font: 1.2ch/1.5ch; -} - -@supports ( box-shadow: 2px 2px 2px black ) or - ( -moz-box-shadow: 2px 2px 2px black ) { - .outline { - box-shadow: 2px 2px 2px black; - -moz-box-shadow: 2px 2px 2px black; - } -} - -@-x-document url-prefix(""github.com"") { - h1 { - color: red; - } -} - -@viewport { - font-size: 10px; -} -@namespace foo url(http://www.example.com); - -foo|h1 { color: blue; } -foo|* { color: yellow; } -|h1 { color: red; } -*|h1 { color: green; } -h1 { color: green; } -.upper-test { - UpperCaseProperties: allowed; -} -@host { - div { - display: block; - } -} -::distributed(input::placeholder) { - color: #b3b3b3; -} -.shadow ^ .dom, -body ^^ .shadow { - display: done; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/css-escapes.less b/test/Fixtures/lessjs (1.6)/less/css-escapes.less deleted file mode 100644 index 6a4b2830..00000000 --- a/test/Fixtures/lessjs (1.6)/less/css-escapes.less +++ /dev/null @@ -1,33 +0,0 @@ -@ugly: fuchsia; - -.escape\|random\|char { - color: red; -} - -.mixin\!tUp { - font-weight: bold; -} - -// class="404" -.\34 04 { - background: red; - - strong { - color: @ugly; - .mixin\!tUp; - } -} - -.trailingTest\+ { - color: red; -} - -/* This hideous test of hideousness checks for the selector "blockquote" with various permutations of hex escapes */ -\62\6c\6f \63 \6B \0071 \000075o\74 e { - color: silver; -} - -[ng\:cloak], -ng\:form { - display: none; -} diff --git a/test/Fixtures/lessjs (1.6)/less/css-guards.less b/test/Fixtures/lessjs (1.6)/less/css-guards.less deleted file mode 100644 index 6dd1cd68..00000000 --- a/test/Fixtures/lessjs (1.6)/less/css-guards.less +++ /dev/null @@ -1,99 +0,0 @@ - -.light when (lightness(@a) > 50%) { - color: green; -} -.dark when (lightness(@a) < 50%) { - color: orange; -} -@a: #ddd; - -.see-the { - @a: #444; // this mirrors what mixins do - they evaluate the guards at the point of definition - .light(); - .dark(); -} - -.hide-the { - .light(); - .dark(); -} - -.multiple-conditions-1 when (@b = 1), (@c = 2), (@d = 3) { - color: red; -} - -.multiple-conditions-2 when (@b = 1), (@c = 2), (@d = 2) { - color: blue; -} - -@b: 2; -@c: 3; -@d: 3; - -.inheritance when (@b = 2) { - .test { - color: black; - } - &:hover { - color: pink; - } - .hideme when (@b = 1) { - color: green; - } - & when (@b = 1) { - hideme: green; - } -} - -.hideme when (@b = 1) { - .test { - color: black; - } - &:hover { - color: pink; - } - .hideme when (@b = 1) { - color: green; - } -} - -& when (@b = 1) { - .hideme { - color: red; - } -} - -.mixin-with-guard-inside(@colWidth) { - // selector with guard (applies also to & when() ...) - .clsWithGuard when (@colWidth <= 0) { - dispaly: none; - } -} - -.mixin-with-guard-inside(0px); - -.dont-split-me-up { - width: 1px; - & when (@c = 3) { - color: red; - } - & when (@c = 3) { - height: 1px; - } - + & when (@c = 3) { // creates invalid css but tests that we don't fold it in - sibling: true; - } -} - -.scope-check when (@c = 3) { - @k: 1px; - & when (@c = 3) { - @k: 2px; - sub-prop: @k; - } - prop: @k; -} -.scope-check-2 { - .scope-check(); - @k:4px; -} diff --git a/test/Fixtures/lessjs (1.6)/less/css.less b/test/Fixtures/lessjs (1.6)/less/css.less deleted file mode 100644 index 766bdd4d..00000000 --- a/test/Fixtures/lessjs (1.6)/less/css.less +++ /dev/null @@ -1,108 +0,0 @@ -@charset "utf-8"; -div { color: black; } -div { width: 99%; } - -* { - min-width: 45em; -} - -h1, h2 > a > p, h3 { - color: none; -} - -div.class { - color: blue; -} - -div#id { - color: green; -} - -.class#id { - color: purple; -} - -.one.two.three { - color: grey; -} - -@media print { - * { - font-size: 3em; - } -} - -@media screen { - * { - font-size: 10px; - } -} - -@font-face { - font-family: 'Garamond Pro'; -} - -a:hover, a:link { - color: #999; -} - -p, p:first-child { - text-transform: none; -} - -q:lang(no) { - quotes: none; -} - -p + h1 { - font-size: +2.2em; -} - -#shorthands { - border: 1px solid #000; - font: 12px/16px Arial; - font: 100%/16px Arial; - margin: 1px 0; - padding: 0 auto; -} - -#more-shorthands { - margin: 0; - padding: 1px 0 2px 0; - font: normal small/20px 'Trebuchet MS', Verdana, sans-serif; - font: 0/0 a; - border-radius: 5px / 10px; -} - -.misc { - -moz-border-radius: 2px; - display: -moz-inline-stack; - width: .1em; - background-color: #009998; - background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue)); - margin: ; - .nested-multiple { - multiple-semi-colons: yes;;;;;; - }; - filter: alpha(opacity=100); - width: auto\9; -} - -#important { - color: red !important; - width: 100%!important; - height: 20px ! important; -} - -.def-font(@name) { - @font-face { - font-family: @name - } -} - -.def-font(font-a); -.def-font(font-b); - -.æøå { - margin: 0; -} diff --git a/test/Fixtures/lessjs (1.6)/less/debug/import/test.less b/test/Fixtures/lessjs (1.6)/less/debug/import/test.less deleted file mode 100644 index 795082f5..00000000 --- a/test/Fixtures/lessjs (1.6)/less/debug/import/test.less +++ /dev/null @@ -1,25 +0,0 @@ -@charset "ISO-8859-1"; - -.mixin_import1() { - @media all { - .tst { - color: black; - @media screen { - color: red; - .tst3 { - color: white; - } - } - } - } -} - -.mixin_import2() { - .tst2 { - color: white; - } -} - -.tst3 { - color: grey; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/debug/linenumbers.less b/test/Fixtures/lessjs (1.6)/less/debug/linenumbers.less deleted file mode 100644 index 3bcaed01..00000000 --- a/test/Fixtures/lessjs (1.6)/less/debug/linenumbers.less +++ /dev/null @@ -1,33 +0,0 @@ -@charset "UTF-8"; - -@import "import/test.less"; - -.start() { - .test2 { - color: red; - } -} - -.mix() { - color: black; -} - -.test1 { - .mix(); -} - -.start(); - -.mixin_import1(); - -.mixin_import2(); - -@debug: 1; -& when (@debug = 1) { - .test { - color: red; - & when (@debug = 1) { - width: 2; - } - } -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/empty.less b/test/Fixtures/lessjs (1.6)/less/empty.less deleted file mode 100644 index e69de29b..00000000 diff --git a/test/Fixtures/lessjs (1.6)/less/errors/add-mixed-units.less b/test/Fixtures/lessjs (1.6)/less/errors/add-mixed-units.less deleted file mode 100644 index 9b708de9..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/add-mixed-units.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - error: (1px + 3em); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/add-mixed-units.txt b/test/Fixtures/lessjs (1.6)/less/errors/add-mixed-units.txt deleted file mode 100644 index 9ea45438..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/add-mixed-units.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: Incompatible units. Change the units or use the unit function. Bad units: 'px' and 'em'. in {path}add-mixed-units.less on line 2, column 3: -1 .a { -2 error: (1px + 3em); -3 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/add-mixed-units2.less b/test/Fixtures/lessjs (1.6)/less/errors/add-mixed-units2.less deleted file mode 100644 index 26631160..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/add-mixed-units2.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - error: ((1px * 2px) + (3em * 3px)); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/add-mixed-units2.txt b/test/Fixtures/lessjs (1.6)/less/errors/add-mixed-units2.txt deleted file mode 100644 index ca34304f..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/add-mixed-units2.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: Incompatible units. Change the units or use the unit function. Bad units: 'px*px' and 'em*px'. in {path}add-mixed-units2.less on line 2, column 3: -1 .a { -2 error: ((1px * 2px) + (3em * 3px)); -3 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/bad-variable-declaration1.less b/test/Fixtures/lessjs (1.6)/less/errors/bad-variable-declaration1.less deleted file mode 100644 index c2dc6ac0..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/bad-variable-declaration1.less +++ /dev/null @@ -1 +0,0 @@ -@@demo: "hi"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/bad-variable-declaration1.txt b/test/Fixtures/lessjs (1.6)/less/errors/bad-variable-declaration1.txt deleted file mode 100644 index 5ae9d4a4..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/bad-variable-declaration1.txt +++ /dev/null @@ -1,2 +0,0 @@ -ParseError: Unrecognised input in {path}bad-variable-declaration1.less on line 1, column 1: -1 @@demo: "hi"; diff --git a/test/Fixtures/lessjs (1.6)/less/errors/color-func-invalid-color.less b/test/Fixtures/lessjs (1.6)/less/errors/color-func-invalid-color.less deleted file mode 100644 index 5a1edd01..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/color-func-invalid-color.less +++ /dev/null @@ -1,3 +0,0 @@ -.test { - color: color("NOT A COLOR"); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/color-func-invalid-color.txt b/test/Fixtures/lessjs (1.6)/less/errors/color-func-invalid-color.txt deleted file mode 100644 index 08990c30..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/color-func-invalid-color.txt +++ /dev/null @@ -1,4 +0,0 @@ -ArgumentError: error evaluating function `color`: argument must be a color keyword or 3/6 digit hex e.g. #FFF in {path}color-func-invalid-color.less on line 2, column 10: -1 .test { -2 color: color("NOT A COLOR"); -3 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/comment-in-selector.less b/test/Fixtures/lessjs (1.6)/less/errors/comment-in-selector.less deleted file mode 100644 index a7d26396..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/comment-in-selector.less +++ /dev/null @@ -1 +0,0 @@ -#gaga /* Comment */ span { color: red } \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/comment-in-selector.txt b/test/Fixtures/lessjs (1.6)/less/errors/comment-in-selector.txt deleted file mode 100644 index e48f878c..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/comment-in-selector.txt +++ /dev/null @@ -1,2 +0,0 @@ -ParseError: Unrecognised input in {path}comment-in-selector.less on line 1, column 21: -1 #gaga /* Comment */ span { color: red } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/css-guard-default-func.less b/test/Fixtures/lessjs (1.6)/less/errors/css-guard-default-func.less deleted file mode 100644 index db6639e1..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/css-guard-default-func.less +++ /dev/null @@ -1,4 +0,0 @@ - -selector when (default()) { - color: red; -} diff --git a/test/Fixtures/lessjs (1.6)/less/errors/css-guard-default-func.txt b/test/Fixtures/lessjs (1.6)/less/errors/css-guard-default-func.txt deleted file mode 100644 index ea670295..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/css-guard-default-func.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: error evaluating function `default`: it is currently only allowed in parametric mixin guards, in {path}css-guard-default-func.less on line 2, column 16: -1 -2 selector when (default()) { -3 color: red; diff --git a/test/Fixtures/lessjs (1.6)/less/errors/divide-mixed-units.less b/test/Fixtures/lessjs (1.6)/less/errors/divide-mixed-units.less deleted file mode 100644 index d228b7c4..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/divide-mixed-units.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - error: (1px / 3em); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/divide-mixed-units.txt b/test/Fixtures/lessjs (1.6)/less/errors/divide-mixed-units.txt deleted file mode 100644 index c189d2aa..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/divide-mixed-units.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: Multiple units in dimension. Correct the units or use the unit function. Bad unit: px/em in {path}divide-mixed-units.less on line 2, column 3: -1 .a { -2 error: (1px / 3em); -3 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/extend-no-selector.less b/test/Fixtures/lessjs (1.6)/less/errors/extend-no-selector.less deleted file mode 100644 index 84689ef3..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/extend-no-selector.less +++ /dev/null @@ -1,3 +0,0 @@ -:extend(.a all) { - property: red; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/extend-no-selector.txt b/test/Fixtures/lessjs (1.6)/less/errors/extend-no-selector.txt deleted file mode 100644 index bd2e3cd7..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/extend-no-selector.txt +++ /dev/null @@ -1,3 +0,0 @@ -SyntaxError: Extend must be used to extend a selector, it cannot be used on its own in {path}extend-no-selector.less on line 1, column 17: -1 :extend(.a all) { -2 property: red; diff --git a/test/Fixtures/lessjs (1.6)/less/errors/extend-not-at-end.less b/test/Fixtures/lessjs (1.6)/less/errors/extend-not-at-end.less deleted file mode 100644 index 90ee512c..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/extend-not-at-end.less +++ /dev/null @@ -1,3 +0,0 @@ -.a:extend(.b all).c { - property: red; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/extend-not-at-end.txt b/test/Fixtures/lessjs (1.6)/less/errors/extend-not-at-end.txt deleted file mode 100644 index 32ebedfc..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/extend-not-at-end.txt +++ /dev/null @@ -1,3 +0,0 @@ -SyntaxError: Extend can only be used at the end of selector in {path}extend-not-at-end.less on line 1, column 21: -1 .a:extend(.b all).c { -2 property: red; diff --git a/test/Fixtures/lessjs (1.6)/less/errors/import-missing.less b/test/Fixtures/lessjs (1.6)/less/errors/import-missing.less deleted file mode 100644 index 5ce8e4d9..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/import-missing.less +++ /dev/null @@ -1,6 +0,0 @@ -.a { - color: green; - // tests line number for import reference is correct -} - -@import "file-does-not-exist.less"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/import-missing.txt b/test/Fixtures/lessjs (1.6)/less/errors/import-missing.txt deleted file mode 100644 index 488d154a..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/import-missing.txt +++ /dev/null @@ -1,3 +0,0 @@ -FileError: '{pathhref}file-does-not-exist.less' wasn't found{404status} in {path}import-missing.less on line 6, column 1: -5 -6 @import "file-does-not-exist.less"; diff --git a/test/Fixtures/lessjs (1.6)/less/errors/import-no-semi.less b/test/Fixtures/lessjs (1.6)/less/errors/import-no-semi.less deleted file mode 100644 index bf2c7f65..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/import-no-semi.less +++ /dev/null @@ -1 +0,0 @@ -@import "this-statement-is-invalid.less" \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/import-no-semi.txt b/test/Fixtures/lessjs (1.6)/less/errors/import-no-semi.txt deleted file mode 100644 index 8b3f795c..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/import-no-semi.txt +++ /dev/null @@ -1,2 +0,0 @@ -ParseError: Unrecognised input in {path}import-no-semi.less on line 1, column 1: -1 @import "this-statement-is-invalid.less" diff --git a/test/Fixtures/lessjs (1.6)/less/errors/import-subfolder1.less b/test/Fixtures/lessjs (1.6)/less/errors/import-subfolder1.less deleted file mode 100644 index 4280673b..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/import-subfolder1.less +++ /dev/null @@ -1 +0,0 @@ -@import "imports/import-subfolder1.less"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/import-subfolder1.txt b/test/Fixtures/lessjs (1.6)/less/errors/import-subfolder1.txt deleted file mode 100644 index 97629276..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/import-subfolder1.txt +++ /dev/null @@ -1,3 +0,0 @@ -NameError: .mixin-not-defined is undefined in {path}mixin-not-defined.less on line 11, column 1: -10 -11 .mixin-not-defined(); diff --git a/test/Fixtures/lessjs (1.6)/less/errors/import-subfolder2.less b/test/Fixtures/lessjs (1.6)/less/errors/import-subfolder2.less deleted file mode 100644 index a6b9b9ce..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/import-subfolder2.less +++ /dev/null @@ -1 +0,0 @@ -@import "imports/import-subfolder2.less"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/import-subfolder2.txt b/test/Fixtures/lessjs (1.6)/less/errors/import-subfolder2.txt deleted file mode 100644 index b5b1a69b..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/import-subfolder2.txt +++ /dev/null @@ -1,4 +0,0 @@ -ParseError: missing opening `{` in {path}parse-error-curly-bracket.less on line 4, column 1: -3 } -4 } -5 diff --git a/test/Fixtures/lessjs (1.6)/less/errors/imports/import-subfolder1.less b/test/Fixtures/lessjs (1.6)/less/errors/imports/import-subfolder1.less deleted file mode 100644 index 24ec0532..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/imports/import-subfolder1.less +++ /dev/null @@ -1 +0,0 @@ -@import "subfolder/mixin-not-defined.less"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/imports/import-subfolder2.less b/test/Fixtures/lessjs (1.6)/less/errors/imports/import-subfolder2.less deleted file mode 100644 index 6058ad14..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/imports/import-subfolder2.less +++ /dev/null @@ -1 +0,0 @@ -@import "subfolder/parse-error-curly-bracket.less"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/imports/import-test.less b/test/Fixtures/lessjs (1.6)/less/errors/imports/import-test.less deleted file mode 100644 index a91ae054..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/imports/import-test.less +++ /dev/null @@ -1,4 +0,0 @@ -.someclass -{ - font-weight: bold; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/imports/subfolder/mixin-not-defined.less b/test/Fixtures/lessjs (1.6)/less/errors/imports/subfolder/mixin-not-defined.less deleted file mode 100644 index 2bb2d091..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/imports/subfolder/mixin-not-defined.less +++ /dev/null @@ -1 +0,0 @@ -@import "../../mixin-not-defined.less"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/imports/subfolder/parse-error-curly-bracket.less b/test/Fixtures/lessjs (1.6)/less/errors/imports/subfolder/parse-error-curly-bracket.less deleted file mode 100644 index f37fa9d0..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/imports/subfolder/parse-error-curly-bracket.less +++ /dev/null @@ -1 +0,0 @@ -@import "../../parse-error-curly-bracket.less"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/javascript-error.less b/test/Fixtures/lessjs (1.6)/less/errors/javascript-error.less deleted file mode 100644 index 9cffb9ff..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/javascript-error.less +++ /dev/null @@ -1,3 +0,0 @@ -.scope { - var: `this.foo.toJS()`; -} diff --git a/test/Fixtures/lessjs (1.6)/less/errors/javascript-error.txt b/test/Fixtures/lessjs (1.6)/less/errors/javascript-error.txt deleted file mode 100644 index 3c83a966..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/javascript-error.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: JavaScript evaluation error: 'TypeError: Cannot call method 'toJS' of undefined' in {path}javascript-error.less on line 2, column 27: -1 .scope { -2 var: `this.foo.toJS()`; -3 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/javascript-undefined-var.less b/test/Fixtures/lessjs (1.6)/less/errors/javascript-undefined-var.less deleted file mode 100644 index 7cd580c4..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/javascript-undefined-var.less +++ /dev/null @@ -1,3 +0,0 @@ -.scope { - @a: `@{b}`; -} diff --git a/test/Fixtures/lessjs (1.6)/less/errors/javascript-undefined-var.txt b/test/Fixtures/lessjs (1.6)/less/errors/javascript-undefined-var.txt deleted file mode 100644 index b363aff9..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/javascript-undefined-var.txt +++ /dev/null @@ -1,4 +0,0 @@ -NameError: variable @b is undefined in {path}javascript-undefined-var.less on line 2, column 15: -1 .scope { -2 @a: `@{b}`; -3 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/mixed-mixin-definition-args-1.less b/test/Fixtures/lessjs (1.6)/less/errors/mixed-mixin-definition-args-1.less deleted file mode 100644 index 9b0e23af..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/mixed-mixin-definition-args-1.less +++ /dev/null @@ -1,6 +0,0 @@ -.mixin(@a : 4, @b : 3, @c: 2) { - will: fail; -} -.mixin-test { - .mixin(@a: 5; @b: 6, @c: 7); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/mixed-mixin-definition-args-1.txt b/test/Fixtures/lessjs (1.6)/less/errors/mixed-mixin-definition-args-1.txt deleted file mode 100644 index a07f5e9d..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/mixed-mixin-definition-args-1.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: Cannot mix ; and , as delimiter types in {path}mixed-mixin-definition-args-1.less on line 5, column 30: -4 .mixin-test { -5 .mixin(@a: 5; @b: 6, @c: 7); -6 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/mixed-mixin-definition-args-2.less b/test/Fixtures/lessjs (1.6)/less/errors/mixed-mixin-definition-args-2.less deleted file mode 100644 index c9709427..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/mixed-mixin-definition-args-2.less +++ /dev/null @@ -1,6 +0,0 @@ -.mixin(@a : 4, @b : 3, @c: 2) { - will: fail; -} -.mixin-test { - .mixin(@a: 5, @b: 6; @c: 7); -} diff --git a/test/Fixtures/lessjs (1.6)/less/errors/mixed-mixin-definition-args-2.txt b/test/Fixtures/lessjs (1.6)/less/errors/mixed-mixin-definition-args-2.txt deleted file mode 100644 index fa00183b..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/mixed-mixin-definition-args-2.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: Cannot mix ; and , as delimiter types in {path}mixed-mixin-definition-args-2.less on line 5, column 26: -4 .mixin-test { -5 .mixin(@a: 5, @b: 6; @c: 7); -6 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/mixin-not-defined.less b/test/Fixtures/lessjs (1.6)/less/errors/mixin-not-defined.less deleted file mode 100644 index e2dad5ce..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/mixin-not-defined.less +++ /dev/null @@ -1,11 +0,0 @@ - -.error-is-further-on() { -} - -.pad-here-to-reproduce-error-in() { -} - -.the-import-subfolder-test() { -} - -.mixin-not-defined(); \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/mixin-not-defined.txt b/test/Fixtures/lessjs (1.6)/less/errors/mixin-not-defined.txt deleted file mode 100644 index 97629276..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/mixin-not-defined.txt +++ /dev/null @@ -1,3 +0,0 @@ -NameError: .mixin-not-defined is undefined in {path}mixin-not-defined.less on line 11, column 1: -10 -11 .mixin-not-defined(); diff --git a/test/Fixtures/lessjs (1.6)/less/errors/mixin-not-matched.less b/test/Fixtures/lessjs (1.6)/less/errors/mixin-not-matched.less deleted file mode 100644 index be0d6b1a..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/mixin-not-matched.less +++ /dev/null @@ -1,6 +0,0 @@ -@saxofon:trumpete; - -.mixin(saxofon) { -} - -.mixin(@saxofon); \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/mixin-not-matched.txt b/test/Fixtures/lessjs (1.6)/less/errors/mixin-not-matched.txt deleted file mode 100644 index 57df9772..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/mixin-not-matched.txt +++ /dev/null @@ -1,3 +0,0 @@ -RuntimeError: No matching definition was found for `.mixin(trumpete)` in {path}mixin-not-matched.less on line 6, column 1: -5 -6 .mixin(@saxofon); diff --git a/test/Fixtures/lessjs (1.6)/less/errors/mixin-not-matched2.less b/test/Fixtures/lessjs (1.6)/less/errors/mixin-not-matched2.less deleted file mode 100644 index 14f44bf3..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/mixin-not-matched2.less +++ /dev/null @@ -1,6 +0,0 @@ -@saxofon:trumpete; - -.mixin(@a, @b) { -} - -.mixin(@a: @saxofon); \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/mixin-not-matched2.txt b/test/Fixtures/lessjs (1.6)/less/errors/mixin-not-matched2.txt deleted file mode 100644 index dceedaf0..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/mixin-not-matched2.txt +++ /dev/null @@ -1,3 +0,0 @@ -RuntimeError: No matching definition was found for `.mixin(@a:trumpete)` in {path}mixin-not-matched2.less on line 6, column 1: -5 -6 .mixin(@a: @saxofon); diff --git a/test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-1.less b/test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-1.less deleted file mode 100644 index dc90b86b..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-1.less +++ /dev/null @@ -1,9 +0,0 @@ - -guard-default-func-conflict { - .m(@x, 1) {} - .m(@x, 2) when (default()) {} - .m(@x, 2) when (default()) {} - - .m(1, 1); - .m(1, 2); -} diff --git a/test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-1.txt b/test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-1.txt deleted file mode 100644 index d123c21c..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-1.txt +++ /dev/null @@ -1,4 +0,0 @@ -RuntimeError: Ambiguous use of `default()` found when matching for `.m(1, 2)` in {path}mixins-guards-default-func-1.less on line 8, column 5: -7 .m(1, 1); -8 .m(1, 2); -9 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-2.less b/test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-2.less deleted file mode 100644 index 079b5737..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-2.less +++ /dev/null @@ -1,9 +0,0 @@ - -guard-default-func-conflict { - .m(1) {} - .m(@x) when not(default()) {} - .m(@x) when (@x = 3) and (default()) {} - - .m(2); - .m(3); -} diff --git a/test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-2.txt b/test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-2.txt deleted file mode 100644 index 7f7d7cce..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-2.txt +++ /dev/null @@ -1,4 +0,0 @@ -RuntimeError: Ambiguous use of `default()` found when matching for `.m(3)` in {path}mixins-guards-default-func-2.less on line 8, column 5: -7 .m(2); -8 .m(3); -9 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-3.less b/test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-3.less deleted file mode 100644 index ec357fa1..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-3.less +++ /dev/null @@ -1,9 +0,0 @@ - -guard-default-func-conflict { - .m(1) {} - .m(@x) when not(default()) {} - .m(@x) when not(default()) {} - - .m(1); - .m(2); -} diff --git a/test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-3.txt b/test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-3.txt deleted file mode 100644 index 2a2728cc..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/mixins-guards-default-func-3.txt +++ /dev/null @@ -1,4 +0,0 @@ -RuntimeError: Ambiguous use of `default()` found when matching for `.m(2)` in {path}mixins-guards-default-func-3.less on line 8, column 5: -7 .m(1); -8 .m(2); -9 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/multiple-guards-on-css-selectors.less b/test/Fixtures/lessjs (1.6)/less/errors/multiple-guards-on-css-selectors.less deleted file mode 100644 index 4eabb60a..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/multiple-guards-on-css-selectors.less +++ /dev/null @@ -1,4 +0,0 @@ -@ie8: true; -.a when (@ie8 = true), -.b { -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/multiple-guards-on-css-selectors.txt b/test/Fixtures/lessjs (1.6)/less/errors/multiple-guards-on-css-selectors.txt deleted file mode 100644 index 3d23e26b..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/multiple-guards-on-css-selectors.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: Guards are only currently allowed on a single selector. in {path}multiple-guards-on-css-selectors.less on line 3, column 1: -2 .a when (@ie8 = true), -3 .b { -4 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/multiple-guards-on-css-selectors2.less b/test/Fixtures/lessjs (1.6)/less/errors/multiple-guards-on-css-selectors2.less deleted file mode 100644 index 4b1bc6ff..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/multiple-guards-on-css-selectors2.less +++ /dev/null @@ -1,4 +0,0 @@ -@ie8: true; -.a, -.b when (@ie8 = true) { -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/multiple-guards-on-css-selectors2.txt b/test/Fixtures/lessjs (1.6)/less/errors/multiple-guards-on-css-selectors2.txt deleted file mode 100644 index d0e5a52b..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/multiple-guards-on-css-selectors2.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: Guards are only currently allowed on a single selector. in {path}multiple-guards-on-css-selectors2.less on line 3, column 23: -2 .a, -3 .b when (@ie8 = true) { -4 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/multiply-mixed-units.less b/test/Fixtures/lessjs (1.6)/less/errors/multiply-mixed-units.less deleted file mode 100644 index ff983a85..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/multiply-mixed-units.less +++ /dev/null @@ -1,7 +0,0 @@ -/* Test */ -#blah { - // blah -} -.a { - error: (1px * 1em); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/multiply-mixed-units.txt b/test/Fixtures/lessjs (1.6)/less/errors/multiply-mixed-units.txt deleted file mode 100644 index 9ed834f1..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/multiply-mixed-units.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: Multiple units in dimension. Correct the units or use the unit function. Bad unit: em*px in {path}multiply-mixed-units.less on line 6, column 3: -5 .a { -6 error: (1px * 1em); -7 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/parens-error-1.less b/test/Fixtures/lessjs (1.6)/less/errors/parens-error-1.less deleted file mode 100644 index 7c8ec10e..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/parens-error-1.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - something: (12 (13 + 5 -23) + 5); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/parens-error-1.txt b/test/Fixtures/lessjs (1.6)/less/errors/parens-error-1.txt deleted file mode 100644 index 6fc40ac0..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/parens-error-1.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: expected ')' got '(' in {path}parens-error-1.less on line 2, column 18: -1 .a { -2 something: (12 (13 + 5 -23) + 5); -3 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/parens-error-2.less b/test/Fixtures/lessjs (1.6)/less/errors/parens-error-2.less deleted file mode 100644 index 4a392b8e..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/parens-error-2.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - something: (12 * (13 + 5 -23)); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/parens-error-2.txt b/test/Fixtures/lessjs (1.6)/less/errors/parens-error-2.txt deleted file mode 100644 index cee5c52d..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/parens-error-2.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: expected ')' got '-' in {path}parens-error-2.less on line 2, column 28: -1 .a { -2 something: (12 * (13 + 5 -23)); -3 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/parens-error-3.less b/test/Fixtures/lessjs (1.6)/less/errors/parens-error-3.less deleted file mode 100644 index 9e6d5405..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/parens-error-3.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - something: (12 + (13 + 10 -23)); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/parens-error-3.txt b/test/Fixtures/lessjs (1.6)/less/errors/parens-error-3.txt deleted file mode 100644 index 3280ef04..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/parens-error-3.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: expected ')' got '-' in {path}parens-error-3.less on line 2, column 29: -1 .a { -2 something: (12 + (13 + 10 -23)); -3 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/parse-error-curly-bracket.less b/test/Fixtures/lessjs (1.6)/less/errors/parse-error-curly-bracket.less deleted file mode 100644 index f78ceb70..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/parse-error-curly-bracket.less +++ /dev/null @@ -1,4 +0,0 @@ -body { - background-color: #fff; - } -} diff --git a/test/Fixtures/lessjs (1.6)/less/errors/parse-error-curly-bracket.txt b/test/Fixtures/lessjs (1.6)/less/errors/parse-error-curly-bracket.txt deleted file mode 100644 index b5b1a69b..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/parse-error-curly-bracket.txt +++ /dev/null @@ -1,4 +0,0 @@ -ParseError: missing opening `{` in {path}parse-error-curly-bracket.less on line 4, column 1: -3 } -4 } -5 diff --git a/test/Fixtures/lessjs (1.6)/less/errors/parse-error-extra-parens.less b/test/Fixtures/lessjs (1.6)/less/errors/parse-error-extra-parens.less deleted file mode 100644 index 46d023a9..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/parse-error-extra-parens.less +++ /dev/null @@ -1,5 +0,0 @@ -@media (extra: bracket)) { - body { - background-color: #fff; - } -} diff --git a/test/Fixtures/lessjs (1.6)/less/errors/parse-error-extra-parens.txt b/test/Fixtures/lessjs (1.6)/less/errors/parse-error-extra-parens.txt deleted file mode 100644 index 5c1aaef2..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/parse-error-extra-parens.txt +++ /dev/null @@ -1,3 +0,0 @@ -ParseError: missing opening `(` in {path}parse-error-extra-parens.less on line 1, column 24: -1 @media (extra: bracket)) { -2 body { diff --git a/test/Fixtures/lessjs (1.6)/less/errors/parse-error-missing-bracket.less b/test/Fixtures/lessjs (1.6)/less/errors/parse-error-missing-bracket.less deleted file mode 100644 index 144a6edf..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/parse-error-missing-bracket.less +++ /dev/null @@ -1,2 +0,0 @@ -body { - background-color: #fff; diff --git a/test/Fixtures/lessjs (1.6)/less/errors/parse-error-missing-bracket.txt b/test/Fixtures/lessjs (1.6)/less/errors/parse-error-missing-bracket.txt deleted file mode 100644 index 7db2716e..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/parse-error-missing-bracket.txt +++ /dev/null @@ -1,3 +0,0 @@ -ParseError: missing closing `}` in {path}parse-error-missing-bracket.less on line 1, column 6: -1 body { -2 background-color: #fff; diff --git a/test/Fixtures/lessjs (1.6)/less/errors/parse-error-missing-parens.less b/test/Fixtures/lessjs (1.6)/less/errors/parse-error-missing-parens.less deleted file mode 100644 index 55d25791..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/parse-error-missing-parens.less +++ /dev/null @@ -1,5 +0,0 @@ -@media (missing: bracket { - body { - background-color: #fff; - } -} diff --git a/test/Fixtures/lessjs (1.6)/less/errors/parse-error-missing-parens.txt b/test/Fixtures/lessjs (1.6)/less/errors/parse-error-missing-parens.txt deleted file mode 100644 index a7a67067..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/parse-error-missing-parens.txt +++ /dev/null @@ -1,3 +0,0 @@ -ParseError: missing closing `)` in {path}parse-error-missing-parens.less on line 1, column 8: -1 @media (missing: bracket { -2 body { diff --git a/test/Fixtures/lessjs (1.6)/less/errors/parse-error-with-import.less b/test/Fixtures/lessjs (1.6)/less/errors/parse-error-with-import.less deleted file mode 100644 index 6be3de85..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/parse-error-with-import.less +++ /dev/null @@ -1,13 +0,0 @@ -@import 'import/import-test.less'; - -body -{ - font-family: arial, sans-serif; -} - -nonsense; - -.clickable -{ - cursor: pointer; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/parse-error-with-import.txt b/test/Fixtures/lessjs (1.6)/less/errors/parse-error-with-import.txt deleted file mode 100644 index 07732c92..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/parse-error-with-import.txt +++ /dev/null @@ -1,4 +0,0 @@ -ParseError: Unrecognised input in {path}parse-error-with-import.less on line 8, column 9: -7 -8 nonsense; -9 diff --git a/test/Fixtures/lessjs (1.6)/less/errors/property-asterisk-only-name.less b/test/Fixtures/lessjs (1.6)/less/errors/property-asterisk-only-name.less deleted file mode 100644 index c6a9990c..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/property-asterisk-only-name.less +++ /dev/null @@ -1,3 +0,0 @@ -a { - * : 1; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/property-asterisk-only-name.txt b/test/Fixtures/lessjs (1.6)/less/errors/property-asterisk-only-name.txt deleted file mode 100644 index 6adc6c69..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/property-asterisk-only-name.txt +++ /dev/null @@ -1,4 +0,0 @@ -ParseError: Unrecognised input in {path}property-asterisk-only-name.less on line 2, column 5: -1 a { -2 * : 1; -3 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/property-ie5-hack.less b/test/Fixtures/lessjs (1.6)/less/errors/property-ie5-hack.less deleted file mode 100644 index 51bf6e39..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/property-ie5-hack.less +++ /dev/null @@ -1,3 +0,0 @@ -.test { - display/*/: block; /*sorry for IE5*/ -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/property-ie5-hack.txt b/test/Fixtures/lessjs (1.6)/less/errors/property-ie5-hack.txt deleted file mode 100644 index e42ef90e..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/property-ie5-hack.txt +++ /dev/null @@ -1,4 +0,0 @@ -ParseError: Unrecognised input in {path}property-ie5-hack.less on line 2, column 3: -1 .test { -2 display/*/: block; /*sorry for IE5*/ -3 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/property-in-root.less b/test/Fixtures/lessjs (1.6)/less/errors/property-in-root.less deleted file mode 100644 index 8fed4be3..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/property-in-root.less +++ /dev/null @@ -1,4 +0,0 @@ -.a() { - prop:1; -} -.a(); \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/property-in-root.txt b/test/Fixtures/lessjs (1.6)/less/errors/property-in-root.txt deleted file mode 100644 index 04b27766..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/property-in-root.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: properties must be inside selector blocks, they cannot be in the root. in {path}property-in-root.less on line 2, column 3: -1 .a() { -2 prop:1; -3 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/property-in-root2.less b/test/Fixtures/lessjs (1.6)/less/errors/property-in-root2.less deleted file mode 100644 index ce8656d1..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/property-in-root2.less +++ /dev/null @@ -1 +0,0 @@ -@import "property-in-root"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/property-in-root2.txt b/test/Fixtures/lessjs (1.6)/less/errors/property-in-root2.txt deleted file mode 100644 index 04b27766..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/property-in-root2.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: properties must be inside selector blocks, they cannot be in the root. in {path}property-in-root.less on line 2, column 3: -1 .a() { -2 prop:1; -3 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/property-in-root3.less b/test/Fixtures/lessjs (1.6)/less/errors/property-in-root3.less deleted file mode 100644 index 056c2f72..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/property-in-root3.less +++ /dev/null @@ -1,4 +0,0 @@ -prop:1; -.a { - prop:1; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/property-in-root3.txt b/test/Fixtures/lessjs (1.6)/less/errors/property-in-root3.txt deleted file mode 100644 index 68ef9454..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/property-in-root3.txt +++ /dev/null @@ -1,3 +0,0 @@ -SyntaxError: properties must be inside selector blocks, they cannot be in the root. in {path}property-in-root3.less on line 1, column 1: -1 prop:1; -2 .a { diff --git a/test/Fixtures/lessjs (1.6)/less/errors/property-interp-not-defined.less b/test/Fixtures/lessjs (1.6)/less/errors/property-interp-not-defined.less deleted file mode 100644 index 544fd5f9..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/property-interp-not-defined.less +++ /dev/null @@ -1 +0,0 @@ -a {outline-@{color}: green} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/property-interp-not-defined.txt b/test/Fixtures/lessjs (1.6)/less/errors/property-interp-not-defined.txt deleted file mode 100644 index 2537f9ea..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/property-interp-not-defined.txt +++ /dev/null @@ -1,2 +0,0 @@ -NameError: variable @color is undefined in {path}property-interp-not-defined.less on line 1, column 12: -1 a {outline-@{color}: green} diff --git a/test/Fixtures/lessjs (1.6)/less/errors/recursive-variable.less b/test/Fixtures/lessjs (1.6)/less/errors/recursive-variable.less deleted file mode 100644 index c1ca75f1..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/recursive-variable.less +++ /dev/null @@ -1 +0,0 @@ -@bodyColor: darken(@bodyColor, 30%); \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/recursive-variable.txt b/test/Fixtures/lessjs (1.6)/less/errors/recursive-variable.txt deleted file mode 100644 index eb616e7d..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/recursive-variable.txt +++ /dev/null @@ -1,2 +0,0 @@ -NameError: Recursive variable definition for @bodyColor in {path}recursive-variable.less on line 1, column 20: -1 @bodyColor: darken(@bodyColor, 30%); diff --git a/test/Fixtures/lessjs (1.6)/less/errors/svg-gradient1.less b/test/Fixtures/lessjs (1.6)/less/errors/svg-gradient1.less deleted file mode 100644 index c069ff72..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/svg-gradient1.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - a: svg-gradient(horizontal, black, white); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/svg-gradient1.txt b/test/Fixtures/lessjs (1.6)/less/errors/svg-gradient1.txt deleted file mode 100644 index ec662fe6..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/svg-gradient1.txt +++ /dev/null @@ -1,4 +0,0 @@ -ArgumentError: error evaluating function `svg-gradient`: svg-gradient direction must be 'to bottom', 'to right', 'to bottom right', 'to top right' or 'ellipse at center' in {path}svg-gradient1.less on line 2, column 6: -1 .a { -2 a: svg-gradient(horizontal, black, white); -3 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/svg-gradient2.less b/test/Fixtures/lessjs (1.6)/less/errors/svg-gradient2.less deleted file mode 100644 index ff14ef11..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/svg-gradient2.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - a: svg-gradient(to bottom, black, orange, 45%, white); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/svg-gradient2.txt b/test/Fixtures/lessjs (1.6)/less/errors/svg-gradient2.txt deleted file mode 100644 index 7004115f..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/svg-gradient2.txt +++ /dev/null @@ -1,4 +0,0 @@ -ArgumentError: error evaluating function `svg-gradient`: svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position] in {path}svg-gradient2.less on line 2, column 6: -1 .a { -2 a: svg-gradient(to bottom, black, orange, 45%, white); -3 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/svg-gradient3.less b/test/Fixtures/lessjs (1.6)/less/errors/svg-gradient3.less deleted file mode 100644 index 8f185246..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/svg-gradient3.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - a: svg-gradient(black, orange); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/svg-gradient3.txt b/test/Fixtures/lessjs (1.6)/less/errors/svg-gradient3.txt deleted file mode 100644 index eb0b483e..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/svg-gradient3.txt +++ /dev/null @@ -1,4 +0,0 @@ -ArgumentError: error evaluating function `svg-gradient`: svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position] in {path}svg-gradient3.less on line 2, column 6: -1 .a { -2 a: svg-gradient(black, orange); -3 } diff --git a/test/Fixtures/lessjs (1.6)/less/errors/unit-function.less b/test/Fixtures/lessjs (1.6)/less/errors/unit-function.less deleted file mode 100644 index 119e9818..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/unit-function.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - font-size: unit(80/16,rem); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/errors/unit-function.txt b/test/Fixtures/lessjs (1.6)/less/errors/unit-function.txt deleted file mode 100644 index baf90f42..00000000 --- a/test/Fixtures/lessjs (1.6)/less/errors/unit-function.txt +++ /dev/null @@ -1,4 +0,0 @@ -ArgumentError: error evaluating function `unit`: the first argument to unit must be a number. Have you forgotten parenthesis? in {path}unit-function.less on line 2, column 14: -1 .a { -2 font-size: unit(80/16,rem); -3 } diff --git a/test/Fixtures/lessjs (1.6)/less/extend-chaining.less b/test/Fixtures/lessjs (1.6)/less/extend-chaining.less deleted file mode 100644 index aad221ea..00000000 --- a/test/Fixtures/lessjs (1.6)/less/extend-chaining.less +++ /dev/null @@ -1,91 +0,0 @@ -//very simple chaining -.a { - color: black; -} -.b:extend(.a) {} -.c:extend(.b) {} - -//very simple chaining, ordering not important - -.d:extend(.e) {} -.e:extend(.f) {} -.f { - color: black; -} - -//extend with all - -.g.h { - color: black; -} -.i.j:extend(.g all) { - color: white; -} -.k:extend(.i all) {} - -//extend multi-chaining - -.l { - color: black; -} -.m:extend(.l){} -.n:extend(.m){} -.o:extend(.n){} -.p:extend(.o){} -.q:extend(.p){} -.r:extend(.q){} -.s:extend(.r){} -.t:extend(.s){} - -// self referencing is ignored - -.u {color: black;} -.v.u.v:extend(.u all){} - -// circular reference because the new extend product will match the existing extend - -.w:extend(.w) {color: black;} -.v.w.v:extend(.w all){} - -// classic circular references - -.x:extend(.z) { - color: x; -} -.y:extend(.x) { - color: y; -} -.z:extend(.y) { - color: z; -} - -//very simple chaining, but with the extend inside the ruleset -.va { - color: black; -} -.vb { - &:extend(.va); - color: white; -} -.vc { - &:extend(.vb); -} - -// media queries - dont extend outside, do extend inside - -@media tv { - .ma:extend(.a,.b,.c,.d,.e,.f,.g,.h,.i,.j,.k,.l,.m,.n,.o,.p,.q,.r,.s,.t,.u,.v,.w,.x,.y,.z,.md) { - color: black; - } - .md { - color: white; - } - @media plasma { - .me, .mf { - &:extend(.mb,.md); - background: red; - } - } -} -.mb:extend(.ma) {}; -.mc:extend(.mb) {}; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/extend-clearfix.less b/test/Fixtures/lessjs (1.6)/less/extend-clearfix.less deleted file mode 100644 index 82445dfa..00000000 --- a/test/Fixtures/lessjs (1.6)/less/extend-clearfix.less +++ /dev/null @@ -1,19 +0,0 @@ -.clearfix { - *zoom: 1; - &:after { - content: ''; - display: block; - clear: both; - height: 0; - } -} - -.foo { - &:extend(.clearfix all); - color: red; -} - -.bar { - &:extend(.clearfix all); - color: blue; -} diff --git a/test/Fixtures/lessjs (1.6)/less/extend-exact.less b/test/Fixtures/lessjs (1.6)/less/extend-exact.less deleted file mode 100644 index 41dc4130..00000000 --- a/test/Fixtures/lessjs (1.6)/less/extend-exact.less +++ /dev/null @@ -1,46 +0,0 @@ -.replace.replace, -.c.replace + .replace { - .replace, - .c { - prop: copy-paste-replace; - } -} -.rep_ace:extend(.replace.replace .replace) {} - -.a .b .c { - prop: not_effected; -} - -.a { - prop: is_effected; - .b { - prop: not_effected; - } - .b.c { - prop: not_effected; - } -} - -.c, .a { - .b, .a { - .a, .c { - prop: not_effected; - } - } -} - -.effected { - &:extend(.a); - &:extend(.b); - &:extend(.c); -} - -.e { - && { - prop: extend-double; - &:hover { - hover: not-extended; - } - } -} -.dbl:extend(.e.e) {} diff --git a/test/Fixtures/lessjs (1.6)/less/extend-media.less b/test/Fixtures/lessjs (1.6)/less/extend-media.less deleted file mode 100644 index 1b22c3fa..00000000 --- a/test/Fixtures/lessjs (1.6)/less/extend-media.less +++ /dev/null @@ -1,24 +0,0 @@ -.ext1 .ext2 { - background: black; -} - -@media tv { - .ext1 .ext3 { - color: white; - } - .tv-lowres :extend(.ext1 all) { - background: blue; - } - @media hires { - .ext1 .ext4 { - color: green; - } - .tv-hires :extend(.ext1 all) { - background: red; - } - } -} - -.all:extend(.ext1 all) { - -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/extend-nest.less b/test/Fixtures/lessjs (1.6)/less/extend-nest.less deleted file mode 100644 index 9d4d27bb..00000000 --- a/test/Fixtures/lessjs (1.6)/less/extend-nest.less +++ /dev/null @@ -1,65 +0,0 @@ -.sidebar { - width: 300px; - background: red; - - .box { - background: #FFF; - border: 1px solid #000; - margin: 10px 0; - } -} - -.sidebar2 { - &:extend(.sidebar all); - background: blue; -} - -.type1 { - .sidebar3 { - &:extend(.sidebar all); - background: green; - } -} - -.type2 { - &.sidebar4 { - &:extend(.sidebar all); - background: red; - } -} - -.button { - color: black; - &:hover { - color: white; - } -} -.submit { - &:extend(.button); - &:hover:extend(.button:hover) {} -} - -.nomatch { - &:hover:extend(.button :hover) {} -} - -.button2 { - :hover { - nested: white; - } -} -.button2 :hover { - notnested: black; -} - -.nomatch :extend(.button2:hover) {} - -.amp-test-a, -.amp-test-b { - .amp-test-c &.amp-test-d&.amp-test-e { - .amp-test-f&+&.amp-test-g:extend(.amp-test-h) {} - } -} -.amp-test-h { - test: extended by masses of selectors; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/extend-selector.less b/test/Fixtures/lessjs (1.6)/less/extend-selector.less deleted file mode 100644 index c7588ee0..00000000 --- a/test/Fixtures/lessjs (1.6)/less/extend-selector.less +++ /dev/null @@ -1,99 +0,0 @@ -.error { - border: 1px #f00; - background: #fdd; -} -.error.intrusion { - font-size: 1.3em; - font-weight: bold; -} -.intrusion .error { - display: none; -} -.badError:extend(.error all) { - border-width: 3px; -} - -.foo .bar, .foo .baz { - display: none; -} - -.ext1 .ext2 - :extend(.foo all) { -} - -.ext3:extend(.foo all), -.ext4:extend(.foo all) { -} - -div.ext5, -.ext6 > .ext5 { - width: 100px; -} - -.should-not-exist-in-output, -.ext7:extend(.ext5 all) { -} - -.ext { - test: 1; -} -// same as -// .a .c:extend(.ext all) -// .b .c:extend(.ext all) -// .a .c .d -// .b .c .d -.a, .b { - test: 2; - .c:extend(.ext all) { - test: 3; - .d { - test: 4; - } - } -} - -.replace.replace, -.c.replace + .replace { - .replace, - .c { - prop: copy-paste-replace; - } -} -.rep_ace:extend(.replace all) {} - -.attributes { - [data="test"] { - extend: attributes; - } - .attribute-test { - &:extend([data="test"] all); - } - [data] { - extend: attributes2; - } - .attribute-test2 { - &:extend([data] all); //you could argue it should match [data="test"]... not for now though... - } - @attr-data: "test3"; - [data=@{attr-data}] { - extend: attributes2; - } - .attribute-test { - &:extend([data="test3"] all); - } -} - -.header { - .header-nav { - background: red; - &:before { - background: blue; - } - } -} - -.footer { - .footer-nav { - &:extend( .header .header-nav all ); - } -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/extend.less b/test/Fixtures/lessjs (1.6)/less/extend.less deleted file mode 100644 index 1db5d431..00000000 --- a/test/Fixtures/lessjs (1.6)/less/extend.less +++ /dev/null @@ -1,81 +0,0 @@ -.error { - border: 1px #f00; - background: #fdd; -} -.error.intrusion { - font-size: 1.3em; - font-weight: bold; -} -.intrusion .error { - display: none; -} -.badError { - &:extend(.error all); - border-width: 3px; -} - -.foo .bar, .foo .baz { - display: none; -} - -.ext1 .ext2 { - &:extend(.foo all); -} - -.ext3, -.ext4 { - &:extend(.foo all); - &:extend(.bar all); -} - -div.ext5, -.ext6 > .ext5 { - width: 100px; -} - -.ext7 { - &:extend(.ext5 all); -} - -.ext8.ext9 { - result: add-foo; -} -.ext8 .ext9, -.ext8 + .ext9, -.ext8 > .ext9 { - result: bar-matched; -} -.ext8.nomatch { - result: none; -} -.ext8 { - .ext9 { - result: match-nested-bar; - } -} -.ext8 { - &.ext9 { - result: match-nested-foo; - } -} - -.fuu:extend(.ext8.ext9 all) {} -.buu:extend(.ext8 .ext9 all) {} -.zap:extend(.ext8 + .ext9 all) {} -.zoo:extend(.ext8 > .ext9 all) {} - -.aa { - color: black; - .dd { - background: red; - } -} -.bb { - background: red; - .bb { - color: black; - } -} -.cc:extend(.aa,.bb) {} -.ee:extend(.dd all,.bb) {} -.ff:extend(.dd,.bb all) {} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/extract-and-length.less b/test/Fixtures/lessjs (1.6)/less/extract-and-length.less deleted file mode 100644 index d81e118f..00000000 --- a/test/Fixtures/lessjs (1.6)/less/extract-and-length.less +++ /dev/null @@ -1,133 +0,0 @@ - -// simple array/list: - -.multiunit { - @v: abc "abc" 1 1px 1% #123; - length: length(@v); - extract: extract(@v, 1) extract(@v, 2) extract(@v, 3) extract(@v, 4) extract(@v, 5) extract(@v, 6); -} - -.incorrect-index { - @v1: a b c; - @v2: a, b, c; - v1: extract(@v1, 5); - v2: extract(@v2, -2); -} - -.scalar { - @var: variable; - var-value: extract(@var, 1); - var-length: length(@var); - ill-index: extract(@var, 2); - - name-value: extract(name, 1); - string-value: extract("string", 1); - number-value: extract(12345678, 1); - color-value: extract(blue, 1); - rgba-value: extract(rgba(80, 160, 240, 0.67), 1); - empty-value: extract(~'', 1); - - name-length: length(name); - string-length: length("string"); - number-length: length(12345678); - color-length: length(blue); - rgba-length: length(rgba(80, 160, 240, 0.67)); - empty-length: length(~''); -} - -.mixin-arguments { - .mixin-args(a b c d); - .mixin-args(a, b, c, d); - .mixin-args(1; 2; 3; 4); -} - -.mixin-args(@value) { - &-1 { - length: length(@value); - extract: extract(@value, 3) ~"|" extract(@value, 2) ~"|" extract(@value, 1); - } -} - -.mixin-args(...) { - &-2 { - length: length(@arguments); - extract: extract(@arguments, 3) ~"|" extract(@arguments, 2) ~"|" extract(@arguments, 1); - } -} - -.mixin-args(@values...) { - &-3 { - length: length(@values); - extract: extract(@values, 3) ~"|" extract(@values, 2) ~"|" extract(@values, 1); - } -} - -.mixin-args(@head, @tail...) { - &-4 { - length: length(@tail); - extract: extract(@tail, 2) ~"|" extract(@tail, 1); - } -} - -// "multidimensional" array/list - -.md-space-comma { - @v: a b c, 1 2 3, "x" "y" "z"; - length-1: length(@v); - extract-1: extract(@v, 2); - length-2: length(extract(@v, 2)); - extract-2: extract(extract(@v, 2), 2); - - &-as-args {.mixin-args(a b c, 1 2 3, "x" "y" "z")} -} - -.md-cat-space-comma { - @a: a b c; - @b: 1 2 3; - @c: "x" "y" "z"; - @v: @a, @b, @c; - length-1: length(@v); - extract-1: extract(@v, 2); - length-2: length(extract(@v, 2)); - extract-2: extract(extract(@v, 2), 2); - - &-as-args {.mixin-args(@a, @b, @c)} -} - -.md-cat-comma-space { - @a: a, b, c; - @b: 1, 2, 3; - @c: "x", "y", "z"; - @v: @a @b @c; - length-1: length(@v); - extract-1: extract(@v, 2); - length-2: length(extract(@v, 2)); - extract-2: extract(extract(@v, 2), 2); - - &-as-args {.mixin-args(@a @b @c)} -} - -.md-3D { - @a: a b c d, 1 2 3 4; - @b: 5 6 7 8, e f g h; - .3D(@a, @b); - - .3D(...) { - - @v1: @arguments; - length-1: length(@v1); - extract-1: extract(@v1, 1); - - @v2: extract(@v1, 2); - length-2: length(@v2); - extract-2: extract(@v2, 1); - - @v3: extract(@v2, 1); - length-3: length(@v3); - extract-3: extract(@v3, 3); - - @v4: extract(@v3, 4); - length-4: length(@v4); - extract-4: extract(@v4, 1); - } -} diff --git a/test/Fixtures/lessjs (1.6)/less/functions.less b/test/Fixtures/lessjs (1.6)/less/functions.less deleted file mode 100644 index 170a915b..00000000 --- a/test/Fixtures/lessjs (1.6)/less/functions.less +++ /dev/null @@ -1,155 +0,0 @@ -#functions { - @var: 10; - @colors: #000, #fff; - color: _color("evil red"); // #660000 - width: increment(15); - height: undefined("self"); - border-width: add(2, 3); - variable: increment(@var); - background: linear-gradient(@colors); -} - -#built-in { - @r: 32; - escaped: e("-Some::weird(#thing, y)"); - lighten: lighten(#ff0000, 40%); - darken: darken(#ff0000, 40%); - saturate: saturate(#29332f, 20%); - desaturate: desaturate(#203c31, 20%); - greyscale: greyscale(#203c31); - hsl-clamp: hsl(380, 150%, 150%); - spin-p: spin(hsl(340, 50%, 50%), 40); - spin-n: spin(hsl(30, 50%, 50%), -40); - luma-white: luma(#fff); - luma-black: luma(#000); - luma-black-alpha: luma(rgba(0,0,0,0.5)); - luma-red: luma(#ff0000); - luma-green: luma(#00ff00); - luma-blue: luma(#0000ff); - luma-yellow: luma(#ffff00); - luma-cyan: luma(#00ffff); - luma-white-alpha: luma(rgba(255,255,255,0.5)); - contrast-filter: contrast(30%); - saturate-filter: saturate(5%); - contrast-white: contrast(#fff); - contrast-black: contrast(#000); - contrast-red: contrast(#ff0000); - contrast-green: contrast(#00ff00); - contrast-blue: contrast(#0000ff); - contrast-yellow: contrast(#ffff00); - contrast-cyan: contrast(#00ffff); - contrast-light: contrast(#fff, #111111, #eeeeee); - contrast-dark: contrast(#000, #111111, #eeeeee); - contrast-wrongorder: contrast(#fff, #eeeeee, #111111, 0.5); - contrast-light-thresh: contrast(#fff, #111111, #eeeeee, 0.5); - contrast-dark-thresh: contrast(#000, #111111, #eeeeee, 0.5); - contrast-high-thresh: contrast(#555, #111111, #eeeeee, 0.6); - contrast-low-thresh: contrast(#555, #111111, #eeeeee, 0.1); - contrast-light-thresh-per: contrast(#fff, #111111, #eeeeee, 50%); - contrast-dark-thresh-per: contrast(#000, #111111, #eeeeee, 50%); - contrast-high-thresh-per: contrast(#555, #111111, #eeeeee, 60%); - contrast-low-thresh-per: contrast(#555, #111111, #eeeeee, 10%); - format: %("rgb(%d, %d, %d)", @r, 128, 64); - format-string: %("hello %s", "world"); - format-multiple: %("hello %s %d", "earth", 2); - format-url-encode: %('red is %A', #ff0000); - eformat: e(%("rgb(%d, %d, %d)", @r, 128, 64)); - - unitless: unit(12px); - unit: unit((13px + 1px), em); - - hue: hue(hsl(98, 12%, 95%)); - saturation: saturation(hsl(98, 12%, 95%)); - lightness: lightness(hsl(98, 12%, 95%)); - hsvhue: hsvhue(hsv(98, 12%, 95%)); - hsvsaturation: hsvsaturation(hsv(98, 12%, 95%)); - hsvvalue: hsvvalue(hsv(98, 12%, 95%)); - red: red(#f00); - green: green(#0f0); - blue: blue(#00f); - rounded: round((@r/3)); - rounded-two: round((@r/3), 2); - roundedpx: round((10px / 3)); - roundedpx-three: round((10px / 3), 3); - rounded-percentage: round(10.2%); - ceil: ceil(10.1px); - floor: floor(12.9px); - sqrt: sqrt(25px); - pi: pi(); - mod: mod(13m, 11cm); // could take into account units, doesn't at the moment - abs: abs(-4%); - tan: tan(42deg); - sin: sin(10deg); - cos: cos(12); - atan: atan(tan(0.1rad)); - atan: convert(acos(cos(34deg)), deg); - atan: convert(acos(cos(50grad)), deg); - pow: pow(8px, 2); - pow: pow(4, 3); - pow: pow(3, 3em); - min: min(0); - min: min("junk", 6, 5); - min: min(1pc, 3pt); - max: max(1, 3); - max: max(3%, 1cm, 8%, 2mm); - percentage: percentage((10px / 50)); - color: color("#ff0011"); - tint: tint(#777777, 13); - tint-full: tint(#777777, 100); - tint-percent: tint(#777777, 13%); - tint-negative: tint(#777777, -13%); - shade: shade(#777777, 13); - shade-full: shade(#777777, 100); - shade-percent: shade(#777777, 13%); - shade-negative: shade(#777777, -13%); - - fade-out: fadeOut(red, 5%); // support fadeOut and fadeout - fade-in: fadein(fadeout(red, 10%), 5%); - - hsv: hsv(5, 50%, 30%); - hsva: hsva(3, 50%, 30%, 0.2); - - mix: mix(#ff0000, #ffff00, 80); - mix-0: mix(#ff0000, #ffff00, 0); - mix-100: mix(#ff0000, #ffff00, 100); - mix-weightless: mix(#ff0000, #ffff00); - mixt: mix(#ff0000, transparent); - - .is-a { - color: iscolor(#ddd); - color1: iscolor(red); - color2: iscolor(rgb(0, 0, 0)); - color3: iscolor(transparent); - keyword: iskeyword(hello); - number: isnumber(32); - string: isstring("hello"); - pixel: ispixel(32px); - percent: ispercentage(32%); - em: isem(32em); - cat: isunit(32cat, cat); - } -} - -#alpha { - alpha: darken(hsla(25, 50%, 50%, 0.6), 10%); - alpha2: alpha(rgba(3, 4, 5, 0.5)); - alpha3: alpha(transparent); -} - -#blendmodes { - multiply: multiply(#f60000, #f60000); - screen: screen(#f60000, #0000f6); - overlay: overlay(#f60000, #0000f6); - softlight: softlight(#f60000, #ffffff); - hardlight: hardlight(#f60000, #0000f6); - difference: difference(#f60000, #0000f6); - exclusion: exclusion(#f60000, #0000f6); - average: average(#f60000, #0000f6); - negation: negation(#f60000, #313131); -} - -#extract-and-length { - @anon: A B C 1 2 3; - extract: extract(@anon, 6) extract(@anon, 5) extract(@anon, 4) extract(@anon, 3) extract(@anon, 2) extract(@anon, 1); - length: length(@anon); -} diff --git a/test/Fixtures/lessjs (1.6)/less/globalVars/extended.json b/test/Fixtures/lessjs (1.6)/less/globalVars/extended.json deleted file mode 100644 index 6bd2a484..00000000 --- a/test/Fixtures/lessjs (1.6)/less/globalVars/extended.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "the-border": "1px", - "base-color": "#111", - "red": "#842210" -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/globalVars/extended.less b/test/Fixtures/lessjs (1.6)/less/globalVars/extended.less deleted file mode 100644 index 7a3bf291..00000000 --- a/test/Fixtures/lessjs (1.6)/less/globalVars/extended.less +++ /dev/null @@ -1,10 +0,0 @@ -#header { - color: (@base-color * 3); - border-left: @the-border; - border-right: (@the-border * 2); -} -#footer { - color: (@base-color + #003300); - border-color: @red; -} -@red: desaturate(red, 10%); // less file overrides passed in color <- note line comment on last line to check it is okay \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/globalVars/simple.json b/test/Fixtures/lessjs (1.6)/less/globalVars/simple.json deleted file mode 100644 index 76a63c5a..00000000 --- a/test/Fixtures/lessjs (1.6)/less/globalVars/simple.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "my-color": "red" -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/globalVars/simple.less b/test/Fixtures/lessjs (1.6)/less/globalVars/simple.less deleted file mode 100644 index c3c5e3b8..00000000 --- a/test/Fixtures/lessjs (1.6)/less/globalVars/simple.less +++ /dev/null @@ -1,3 +0,0 @@ -.class { - color: @my-color; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/ie-filters.less b/test/Fixtures/lessjs (1.6)/less/ie-filters.less deleted file mode 100644 index 3350b653..00000000 --- a/test/Fixtures/lessjs (1.6)/less/ie-filters.less +++ /dev/null @@ -1,15 +0,0 @@ -@fat: 0; -@cloudhead: "#000000"; - -.nav { - filter: progid:DXImageTransform.Microsoft.Alpha(opacity = 20); - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=@fat); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#333333", endColorstr=@cloudhead, GradientType=@fat); -} -.evalTest(@arg) { - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=@arg); -} -.evalTest1 { - .evalTest(30); - .evalTest(5); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/import-inline.less b/test/Fixtures/lessjs (1.6)/less/import-inline.less deleted file mode 100644 index 95a11896..00000000 --- a/test/Fixtures/lessjs (1.6)/less/import-inline.less +++ /dev/null @@ -1,2 +0,0 @@ -@import (inline) url("import/import-test-d.css") (min-width:600px); -@import (inline, css) url("import/invalid-css.less"); \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/import-interpolation.less b/test/Fixtures/lessjs (1.6)/less/import-interpolation.less deleted file mode 100644 index 21cfe086..00000000 --- a/test/Fixtures/lessjs (1.6)/less/import-interpolation.less +++ /dev/null @@ -1,8 +0,0 @@ -@my_theme: "test"; - -@import "import/import-@{my_theme}-e.less"; - -@import "import/import-@{in}@{terpolation}.less"; - -@in: "in"; -@terpolation: "terpolation"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/import-once.less b/test/Fixtures/lessjs (1.6)/less/import-once.less deleted file mode 100644 index 0a4024a3..00000000 --- a/test/Fixtures/lessjs (1.6)/less/import-once.less +++ /dev/null @@ -1,6 +0,0 @@ -@import "import/import-once-test-c"; -@import "import/import-once-test-c"; -@import "import/import-once-test-c.less"; -@import "import/deeper/import-once-test-a"; -@import (multiple) "import/import-test-f.less"; -@import (multiple) "import/import-test-f.less"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/import-reference.less b/test/Fixtures/lessjs (1.6)/less/import-reference.less deleted file mode 100644 index cf9da168..00000000 --- a/test/Fixtures/lessjs (1.6)/less/import-reference.less +++ /dev/null @@ -1,18 +0,0 @@ -@import (reference) url("import-once.less"); -@import (reference) url("css-3.less"); -@import (reference) url("media.less"); -/* - The media statement above is invalid (no selector) - We should ban invalid media queries with properties and no selector? -*/ -@import (reference) url("import/import-reference.less"); - -.b { - .z(); -} - -.zz(); - -.visible:extend(.z all) { - extend: test; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/import.less b/test/Fixtures/lessjs (1.6)/less/import.less deleted file mode 100644 index 01689408..00000000 --- a/test/Fixtures/lessjs (1.6)/less/import.less +++ /dev/null @@ -1,21 +0,0 @@ -@import url(http://fonts.googleapis.com/css?family=Open+Sans); - -@import url(/absolute/something.css) screen and (color) and (max-width: 600px); - -@var: 100px; -@import url("//ha.com/file.css") (min-width:@var); - -#import-test { - .mixin; - width: 10px; - height: (@a + 10%); -} -@import "import/import-test-e" screen and (max-width: 600px); - -@import url("import/import-test-a.less"); - -@import (less, multiple) "import/import-test-d.css" screen and (max-width: 601px); - -@import (multiple) "import/import-test-e" screen and (max-width: 602px); - -@import (less, multiple) url("import/import-test-d.css") screen and (max-width: 603px); \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/import/deeper/import-once-test-a.less b/test/Fixtures/lessjs (1.6)/less/import/deeper/import-once-test-a.less deleted file mode 100644 index 8a747fc0..00000000 --- a/test/Fixtures/lessjs (1.6)/less/import/deeper/import-once-test-a.less +++ /dev/null @@ -1 +0,0 @@ -@import "../import-once-test-c"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/import/import-and-relative-paths-test.less b/test/Fixtures/lessjs (1.6)/less/import/import-and-relative-paths-test.less deleted file mode 100644 index d6256c6b..00000000 --- a/test/Fixtures/lessjs (1.6)/less/import/import-and-relative-paths-test.less +++ /dev/null @@ -1,17 +0,0 @@ -@import "../css/background.css"; -@import "import-test-d.css"; - -@import "imports/logo"; -@import "imports/font"; - -.unquoted-relative-path-bg() { - background-image: url(../../data/image.jpg); -} -.quoted-relative-path-border-image() { - border-image: url('../../data/image.jpg'); -} - -#imported-relative-path { - .unquoted-relative-path-bg; - .quoted-relative-path-border-image; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/import/import-charset-test.less b/test/Fixtures/lessjs (1.6)/less/import/import-charset-test.less deleted file mode 100644 index 07a66e1a..00000000 --- a/test/Fixtures/lessjs (1.6)/less/import/import-charset-test.less +++ /dev/null @@ -1 +0,0 @@ -@charset "ISO-8859-1"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/import/import-interpolation.less b/test/Fixtures/lessjs (1.6)/less/import/import-interpolation.less deleted file mode 100644 index aa49a702..00000000 --- a/test/Fixtures/lessjs (1.6)/less/import/import-interpolation.less +++ /dev/null @@ -1 +0,0 @@ -@import "import-@{in}@{terpolation}2.less"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/import/import-interpolation2.less b/test/Fixtures/lessjs (1.6)/less/import/import-interpolation2.less deleted file mode 100644 index 12bfb4e1..00000000 --- a/test/Fixtures/lessjs (1.6)/less/import/import-interpolation2.less +++ /dev/null @@ -1,5 +0,0 @@ -.a { - var: test; -} - -@in: "redefined-does-nothing"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/import/import-once-test-c.less b/test/Fixtures/lessjs (1.6)/less/import/import-once-test-c.less deleted file mode 100644 index 686747a8..00000000 --- a/test/Fixtures/lessjs (1.6)/less/import/import-once-test-c.less +++ /dev/null @@ -1,6 +0,0 @@ - -@c: red; - -#import { - color: @c; -} diff --git a/test/Fixtures/lessjs (1.6)/less/import/import-reference.less b/test/Fixtures/lessjs (1.6)/less/import/import-reference.less deleted file mode 100644 index 9eac45fc..00000000 --- a/test/Fixtures/lessjs (1.6)/less/import/import-reference.less +++ /dev/null @@ -1,43 +0,0 @@ -.z { - color: red; - .c { - color: green; - } -} -.only-with-visible, -.z { - color: green; - &:hover { - color: green; - } - & { - color: green; - } - & + & { - color: green; - .sub { - color: green; - } - } -} - -& { - .hidden { - hidden: true; - } -} - -@media tv { - .hidden { - hidden: true; - } -} - -/* comment is not output */ - -.zz { - .y { - pulled-in: yes; - } - /* comment pulled in */ -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/import/import-test-a.less b/test/Fixtures/lessjs (1.6)/less/import/import-test-a.less deleted file mode 100644 index b3b3b8fc..00000000 --- a/test/Fixtures/lessjs (1.6)/less/import/import-test-a.less +++ /dev/null @@ -1,3 +0,0 @@ -@import "import-test-b.less"; -@a: 20%; -@import "urls.less"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/import/import-test-b.less b/test/Fixtures/lessjs (1.6)/less/import/import-test-b.less deleted file mode 100644 index ce2d35a8..00000000 --- a/test/Fixtures/lessjs (1.6)/less/import/import-test-b.less +++ /dev/null @@ -1,8 +0,0 @@ -@import "import-test-c"; - -@b: 100%; - -.mixin { - height: 10px; - color: @c; -} diff --git a/test/Fixtures/lessjs (1.6)/less/import/import-test-c.less b/test/Fixtures/lessjs (1.6)/less/import/import-test-c.less deleted file mode 100644 index 686747a8..00000000 --- a/test/Fixtures/lessjs (1.6)/less/import/import-test-c.less +++ /dev/null @@ -1,6 +0,0 @@ - -@c: red; - -#import { - color: @c; -} diff --git a/test/Fixtures/lessjs (1.6)/less/import/import-test-d.css b/test/Fixtures/lessjs (1.6)/less/import/import-test-d.css deleted file mode 100644 index 30575f01..00000000 --- a/test/Fixtures/lessjs (1.6)/less/import/import-test-d.css +++ /dev/null @@ -1 +0,0 @@ -#css { color: yellow; } diff --git a/test/Fixtures/lessjs (1.6)/less/import/import-test-e.less b/test/Fixtures/lessjs (1.6)/less/import/import-test-e.less deleted file mode 100644 index 98b84b0a..00000000 --- a/test/Fixtures/lessjs (1.6)/less/import/import-test-e.less +++ /dev/null @@ -1,2 +0,0 @@ - -body { width: 100% } diff --git a/test/Fixtures/lessjs (1.6)/less/import/import-test-f.less b/test/Fixtures/lessjs (1.6)/less/import/import-test-f.less deleted file mode 100644 index fad630f9..00000000 --- a/test/Fixtures/lessjs (1.6)/less/import/import-test-f.less +++ /dev/null @@ -1,5 +0,0 @@ -@import "import-test-e"; - -.test-f { - height: 10px; -} diff --git a/test/Fixtures/lessjs (1.6)/less/import/imports/font.less b/test/Fixtures/lessjs (1.6)/less/import/imports/font.less deleted file mode 100644 index 5abb7e76..00000000 --- a/test/Fixtures/lessjs (1.6)/less/import/imports/font.less +++ /dev/null @@ -1,8 +0,0 @@ -@font-face { - font-family: xecret; - src: url('../assets/xecret.ttf'); -} - -#secret { - font-family: xecret, sans-serif; -} diff --git a/test/Fixtures/lessjs (1.6)/less/import/imports/logo.less b/test/Fixtures/lessjs (1.6)/less/import/imports/logo.less deleted file mode 100644 index 22893a23..00000000 --- a/test/Fixtures/lessjs (1.6)/less/import/imports/logo.less +++ /dev/null @@ -1,5 +0,0 @@ -#logo { - width: 100px; - height: 100px; - background: url('../assets/logo.png'); -} diff --git a/test/Fixtures/lessjs (1.6)/less/import/invalid-css.less b/test/Fixtures/lessjs (1.6)/less/import/invalid-css.less deleted file mode 100644 index ed585d63..00000000 --- a/test/Fixtures/lessjs (1.6)/less/import/invalid-css.less +++ /dev/null @@ -1 +0,0 @@ -this isn't very valid CSS. \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/import/urls.less b/test/Fixtures/lessjs (1.6)/less/import/urls.less deleted file mode 100644 index bb48f77a..00000000 --- a/test/Fixtures/lessjs (1.6)/less/import/urls.less +++ /dev/null @@ -1 +0,0 @@ -// empty file showing that it loads from the relative path first diff --git a/test/Fixtures/lessjs (1.6)/less/javascript.less b/test/Fixtures/lessjs (1.6)/less/javascript.less deleted file mode 100644 index b826a787..00000000 --- a/test/Fixtures/lessjs (1.6)/less/javascript.less +++ /dev/null @@ -1,29 +0,0 @@ -.eval { - js: `42`; - js: `1 + 1`; - js: `"hello world"`; - js: `[1, 2, 3]`; - title: `typeof process.title`; - ternary: `(1 + 1 == 2 ? true : false)`; - multiline: `(function(){var x = 1 + 1; - return x})()`; -} -.scope { - @foo: 42; - var: `parseInt(this.foo.toJS())`; - escaped: ~`2 + 5 + 'px'`; -} -.vars { - @var: `4 + 4`; - width: @var; -} -.escape-interpol { - @world: "world"; - width: ~`"hello" + " " + @{world}`; -} -.arrays { - @ary: 1, 2, 3; - @ary2: 1 2 3; - ary: `@{ary}.join(', ')`; - ary1: `@{ary2}.join(', ')`; -} diff --git a/test/Fixtures/lessjs (1.6)/less/lazy-eval.less b/test/Fixtures/lessjs (1.6)/less/lazy-eval.less deleted file mode 100644 index 72b3fd46..00000000 --- a/test/Fixtures/lessjs (1.6)/less/lazy-eval.less +++ /dev/null @@ -1,6 +0,0 @@ -@var: @a; -@a: 100%; - -.lazy-eval { - width: @var; -} diff --git a/test/Fixtures/lessjs (1.6)/less/legacy/legacy.less b/test/Fixtures/lessjs (1.6)/less/legacy/legacy.less deleted file mode 100644 index 92d00088..00000000 --- a/test/Fixtures/lessjs (1.6)/less/legacy/legacy.less +++ /dev/null @@ -1,7 +0,0 @@ -@media (-o-min-device-pixel-ratio: 2/1) { - .test-math-and-units { - font: ignores 0/0 rules; - test-division: 4 / 2 + 5em; - simple: 1px + 1px; - } -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/media.less b/test/Fixtures/lessjs (1.6)/less/media.less deleted file mode 100644 index 01a6a020..00000000 --- a/test/Fixtures/lessjs (1.6)/less/media.less +++ /dev/null @@ -1,234 +0,0 @@ - -// For now, variables can't be declared inside @media blocks. - -@var: 42; - -@media print { - .class { - color: blue; - .sub { - width: @var; - } - } - .top, header > h1 { - color: (#222 * 2); - } -} - -@media screen { - @base: 8; - body { max-width: (@base * 60); } -} - -@ratio_large: 16; -@ratio_small: 9; - -@media all and (device-aspect-ratio: @ratio_large / @ratio_small) { - body { max-width: 800px; } -} - -@media all and (orientation:portrait) { - aside { float: none; } -} - -@media handheld and (min-width: @var), screen and (min-width: 20em) { - body { - max-width: 480px; - } -} - -body { - @media print { - padding: 20px; - - header { - background-color: red; - } - - @media (orientation:landscape) { - margin-left: 20px; - } - } -} - -@media screen { - .sidebar { - width: 300px; - @media (orientation: landscape) { - width: 500px; - } - } -} - -@media a { - .first { - @media b { - .second { - .third { - width: 300px; - @media c { - width: 500px; - } - } - .fourth { - width: 3; - } - } - } - } -} - -body { - @media a, b and c { - width: 95%; - - @media x, y { - width: 100%; - } - } -} - -.mediaMixin(@fallback: 200px) { - background: black; - - @media handheld { - background: white; - - @media (max-width: @fallback) { - background: red; - } - } -} - -.a { - .mediaMixin(100px); -} - -.b { - .mediaMixin(); -} -@smartphone: ~"only screen and (max-width: 200px)"; -@media @smartphone { - body { - width: 480px; - } -} - -@media print { - @page :left { - margin: 0.5cm; - } - @page :right { - margin: 0.5cm; - } - @page Test:first { - margin: 1cm; - } - @page :first { - size: 8.5in 11in; - @top-left { - margin: 1cm; - } - @top-left-corner { - margin: 1cm; - } - @top-center { - margin: 1cm; - } - @top-right { - margin: 1cm; - } - @top-right-corner { - margin: 1cm; - } - @bottom-left { - margin: 1cm; - } - @bottom-left-corner { - margin: 1cm; - } - @bottom-center { - margin: 1cm; - } - @bottom-right { - margin: 1cm; - } - @bottom-right-corner { - margin: 1cm; - } - @left-top { - margin: 1cm; - } - @left-middle { - margin: 1cm; - } - @left-bottom { - margin: 1cm; - } - @right-top { - margin: 1cm; - } - @right-middle { - content: "Page " counter(page); - } - @right-bottom { - margin: 1cm; - } - } -} - -@media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: 2/1), (min-resolution: 2dppx), (min-resolution: 128dpcm) { - .b { - background: red; - } -} - -.bg() { - background: red; - - @media (max-width: 500px) { - background: green; - } -} - -body { - .bg(); -} - -@bpMedium: 1000px; -@media (max-width: @bpMedium) { - body { - .bg(); - background: blue; - } -} - -@media (max-width: 1200px) { - /* a comment */ - - @media (max-width: 900px) { - body { font-size: 11px; } - } -} - -.nav-justified { - @media (min-width: 480px) { - > li { - display: table-cell; - } - } -} - -.menu -{ - @media (min-width: 768px) { - .nav-justified(); - } -} -@all: ~"all"; -@tv: ~"tv"; -@media @all and @tv { - .all-and-tv-variables { - var: all-and-tv; - } -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/merge.less b/test/Fixtures/lessjs (1.6)/less/merge.less deleted file mode 100644 index f7070d63..00000000 --- a/test/Fixtures/lessjs (1.6)/less/merge.less +++ /dev/null @@ -1,59 +0,0 @@ -.first-transform() { - transform+: rotate(90deg), skew(30deg); -} -.second-transform() { - transform+: scale(2,4); -} -.third-transform() { - transform: scaleX(45deg); -} -.fourth-transform() { - transform+: scaleX(45deg); -} -.fifth-transform() { - transform+: scale(2,4) !important; -} -.first-background() { - background+: url(data://img1.png); -} -.second-background() { - background+: url(data://img2.png); -} - -.test1 { - // Can merge values - .first-transform(); - .second-transform(); -} -.test2 { - // Wont merge values without +: merge directive, for backwards compatibility with css - .first-transform(); - .third-transform(); -} -.test3 { - // Wont merge values from two sources with different properties - .fourth-transform(); - .first-background(); -} -.test4 { - // Wont merge values from sources that merked as !important, for backwards compatibility with css - .first-transform(); - .fifth-transform(); -} -.test5 { - // Wont merge values from mixins that merked as !important, for backwards compatibility with css - .first-transform(); - .second-transform() !important; -} -.test6 { - // Ignores !merge if no peers found - .second-transform(); -} - -.test-interleaved { - transform+: t1; - background+: b1; - transform+: t2; - background+: b2, b3; - transform+: t3; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/mixins-args.less b/test/Fixtures/lessjs (1.6)/less/mixins-args.less deleted file mode 100644 index 8cdc67df..00000000 --- a/test/Fixtures/lessjs (1.6)/less/mixins-args.less +++ /dev/null @@ -1,215 +0,0 @@ -.mixin (@a: 1px, @b: 50%) { - width: (@a * 5); - height: (@b - 1%); -} - -.mixina (@style, @width, @color: black) { - border: @width @style @color; -} - -.mixiny -(@a: 0, @b: 0) { - margin: @a; - padding: @b; -} - -.hidden() { - color: transparent; // asd -} - -#hidden { - .hidden; -} - -#hidden1 { - .hidden(); -} - -.two-args { - color: blue; - .mixin(2px, 100%); - .mixina(dotted, 2px); -} - -.one-arg { - .mixin(3px); -} - -.no-parens { - .mixin; -} - -.no-args { - .mixin(); -} - -.var-args { - @var: 9; - .mixin(@var, (@var * 2)); -} - -.multi-mix { - .mixin(2px, 30%); - .mixiny(4, 5); -} - -.maxa(@arg1: 10, @arg2: #f00) { - padding: (@arg1 * 2px); - color: @arg2; -} - -body { - .maxa(15); -} - -@glob: 5; -.global-mixin(@a:2) { - width: (@glob + @a); -} - -.scope-mix { - .global-mixin(3); -} - -.nested-ruleset (@width: 200px) { - width: @width; - .column { margin: @width; } -} -.content { - .nested-ruleset(600px); -} - -// - -.same-var-name2(@radius) { - radius: @radius; -} -.same-var-name(@radius) { - .same-var-name2(@radius); -} -#same-var-name { - .same-var-name(5px); -} - -// - -.var-inside () { - @var: 10px; - width: @var; -} -#var-inside { .var-inside; } - -.mixin-arguments (@width: 0px, ...) { - border: @arguments; - width: @width; -} - -.arguments { - .mixin-arguments(1px, solid, black); -} -.arguments2 { - .mixin-arguments(); -} -.arguments3 { - .mixin-arguments; -} - -.mixin-arguments2 (@width, @rest...) { - border: @arguments; - rest: @rest; - width: @width; -} -.arguments4 { - .mixin-arguments2(0, 1, 2, 3, 4); -} - -// Edge cases - -.edge-case { - .mixin-arguments("{"); -} - -// Division vs. Literal Slash -.border-radius(@r: 2px/5px) { - border-radius: @r; -} -.slash-vs-math { - .border-radius(); - .border-radius(5px/10px); - .border-radius((3px * 2)); -} -// semi-colon vs comma for delimiting - -.mixin-takes-one(@a) { - one: @a; -} - -.mixin-takes-two(@a; @b) { - one: @a; - two: @b; -} - -.comma-vs-semi-colon { - .mixin-takes-two(@a : a; @b : b, c); - .mixin-takes-two(@a : d, e; @b : f); - .mixin-takes-one(@a: g); - .mixin-takes-one(@a : h;); - .mixin-takes-one(i); - .mixin-takes-one(j;); - .mixin-takes-two(k, l); - .mixin-takes-one(m, n;); - .mixin-takes-two(o, p; q); - .mixin-takes-two(r, s; t;); -} - -.mixin-conflict(@a:defA, @b:defB, @c:defC) { - three: @a, @b, @c; -} - -.mixin-conflict(@a:defA, @b:defB, @c:defC, @d:defD) { - four: @a, @b, @c, @d; -} - -#named-conflict { - .mixin-conflict(11, 12, 13, @a:a); - .mixin-conflict(@a:a, 21, 22, 23); -} -@a: 3px; -.mixin-default-arg(@a: 1px, @b: @a, @c: @b) { - defaults: 1px 1px 1px; - defaults: 2px 2px 2px; -} - -.test-mixin-default-arg { - .mixin-default-arg(); - .mixin-default-arg(2px); -} - -.mixin-comma-default1(@color; @padding; @margin: 2, 2, 2, 2) { - margin: @margin; -} -.selector { - .mixin-comma-default1(#33acfe; 4); -} -.mixin-comma-default2(@margin: 2, 2, 2, 2;) { - margin: @margin; -} -.selector2 { - .mixin-comma-default2(); -} -.mixin-comma-default3(@margin: 2, 2, 2, 2) { - margin: @margin; -} -.selector3 { - .mixin-comma-default3(4,2,2,2); -} - -.test-calling-one-arg-mixin(@a) { -} - -.test-calling-one-arg-mixin(@a, @b, @rest...) { -} - -div { - .test-calling-one-arg-mixin(1); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/mixins-closure.less b/test/Fixtures/lessjs (1.6)/less/mixins-closure.less deleted file mode 100644 index 01251d2a..00000000 --- a/test/Fixtures/lessjs (1.6)/less/mixins-closure.less +++ /dev/null @@ -1,26 +0,0 @@ -.scope { - @var: 99px; - .mixin () { - width: @var; - } -} - -.class { - .scope > .mixin; -} - -.overwrite { - @var: 0px; - .scope > .mixin; -} - -.nested { - @var: 5px; - .mixin () { - width: @var; - } - .class { - @var: 10px; - .mixin; - } -} diff --git a/test/Fixtures/lessjs (1.6)/less/mixins-guards-default-func.less b/test/Fixtures/lessjs (1.6)/less/mixins-guards-default-func.less deleted file mode 100644 index eada9381..00000000 --- a/test/Fixtures/lessjs (1.6)/less/mixins-guards-default-func.less +++ /dev/null @@ -1,195 +0,0 @@ - -// basics: - -guard-default-basic-1 { - .m(1) {case: 1} - .m(@x) when (default()) {default: @x} - - &-1 {.m(1)} - &-2 {.m(2)} -} - -guard-default-basic-2 { - .m(1) {case: 1} - .m(2) {case: 2} - .m(3) {case: 3} - .m(@x) when (default()) {default: @x} - - &-0 {.m(0)} - &-2 {.m(2)} -} - -guard-default-basic-3 { - .m(@x) when (@x = 1) {case: 1} - .m(2) {case: 2} - .m(@x) when (@x = 3) {case: 3} - .m(@x) when (default()) {default: @x} - - &-0 {.m(0)} - &-2 {.m(2)} - &-3 {.m(3)} -} - -guard-default-definition-order { - .m(@x) when (default()) {default: @x} - .m(@x) when (@x = 1) {case: 1} - .m(2) {case: 2} - .m(@x) when (@x = 3) {case: 3} - - &-0 {.m(0)} - &-2 {.m(2)} - &-2 {.m(3)} -} - -// out of guard: - -guard-default-out-of-guard { - .m(1) {case-1: 1} - .m(@x: default()) when (default()) {default: @x} - - &-0 { - case-0: default(); - .m(1); - .m(2); - case-2: default(); - } - &-1 {.m(default())} - &-2 {.m()} -} - -// expressions: - -guard-default-expr-not { - .m(1) {case: 1} - .m(@x) when not(default()) {default: @x} - - &-1 {.m(1)} - &-2 {.m(2)} -} - -guard-default-expr-eq { - .m(@x) when (@x = true) {case: @x} - .m(@x) when (@x = false) {case: @x} - .m(@x) when (@x = default()) {default: @x} - - &-true {.m(true)} - &-false {.m(false)} -} - -guard-default-expr-or { - .m(1) {case: 1} - .m(2) {case: 2} - .m(@x) when (default()), (@x = 2) {default: @x} - - &-1 {.m(1)} - &-2 {.m(2)} - &-3 {.m(3)} -} - -guard-default-expr-and { - .m(1) {case: 1} - .m(2) {case: 2} - .m(@x) when (default()) and (@x = 3) {default: @x} - - &-1 {.m(1)} - &-2 {.m(2)} - &-3 {.m(3)} - &-4 {.m(4)} -} - -guard-default-expr-always { - .m(1) {case: 1} - .m(@x) when (default()), not(default()) {default: @x} // always match - - &-1 {.m(1)} - &-2 {.m(2)} -} - -guard-default-expr-never { - .m(1) {case: 1} - .m(@x) when (default()) and not(default()) {default: @x} // never match - - &-1 {.m(1)} - &-2 {.m(2)} -} - - -// not conflicting multiple default() uses: - -guard-default-multi-1 { - .m(0) {case: 0} - .m(@x) when (default()) {default-1: @x} - .m(2) when (default()) {default-2: @x} - - &-0 {.m(0)} - &-1 {.m(1)} -} - -guard-default-multi-2 { - .m(1, @x) when (default()) {default-1: @x} - .m(2, @x) when (default()) {default-2: @x} - .m(@x, yes) when (default()) {default-3: @x} - - &-1 {.m(1, no)} - &-2 {.m(2, no)} - &-3 {.m(3, yes)} -} - -guard-default-multi-3 { - .m(red) {case-1: darkred} - .m(blue) {case-2: darkblue} - .m(@x) when (iscolor(@x)) and (default()) {default-color: @x} - .m('foo') {case-1: I am 'foo'} - .m('bar') {case-2: I am 'bar'} - .m(@x) when (isstring(@x)) and (default()) {default-string: I am @x} - - &-blue {.m(blue)} - &-green {.m(green)} - &-foo {.m('foo')} - &-baz {.m('baz')} -} - -guard-default-multi-4 { - .m(@x) when (default()), not(default()) {always: @x} - .m(@x) when (default()) and not(default()) {never: @x} - .m(2) {case: 2} - - .m(1); - .m(2); -} - -guard-default-not-ambiguos-2 { - .m(@x) {case: 1} - .m(@x) when (default()) {default: @x} - .m(@x) when not(default()) {not-default: @x} - - .m(2); -} - -guard-default-not-ambiguos-3 { - .m(@x) {case: 1} - .m(@x) when not(default()) {not-default-1: @x} - .m(@x) when not(default()) {not-default-2: @x} - - .m(2); -} - -// default & scope - -guard-default-scopes { - .s1() {.m(@v) {1: no condition}} - .s2() {.m(@v) when (@v) {2: when true}} - .s3() {.m(@v) when (default()) {3: when default}} - - &-3 { - .s2(); - .s3(); - .m(false); - } - - &-1 { - .s1(); - .s3(); - .m(false); - } -} diff --git a/test/Fixtures/lessjs (1.6)/less/mixins-guards.less b/test/Fixtures/lessjs (1.6)/less/mixins-guards.less deleted file mode 100644 index 4d0774df..00000000 --- a/test/Fixtures/lessjs (1.6)/less/mixins-guards.less +++ /dev/null @@ -1,153 +0,0 @@ - -// Stacking, functions.. - -.light (@a) when (lightness(@a) > 50%) { - color: white; -} -.light (@a) when (lightness(@a) < 50%) { - color: black; -} -.light (@a) { - margin: 1px; -} - -.light1 { .light(#ddd) } -.light2 { .light(#444) } - -// Arguments against each other - -.max (@a, @b) when (@a > @b) { - width: @a; -} -.max (@a, @b) when (@a < @b) { - width: @b; -} - -.max1 { .max(3, 6) } -.max2 { .max(8, 1) } - -// Globals inside guards - -@g: auto; - -.glob (@a) when (@a = @g) { - margin: @a @g; -} -.glob1 { .glob(auto) } - -// Other operators - -.ops (@a) when (@a >= 0) { - height: gt-or-eq; -} -.ops (@a) when (@a =< 0) { - height: lt-or-eq; -} -.ops (@a) when (@a <= 0) { - height: lt-or-eq-alias; -} -.ops (@a) when not(@a = 0) { - height: not-eq; -} -.ops1 { .ops(0) } -.ops2 { .ops(1) } -.ops3 { .ops(-1) } - -// Scope and default values - -@a: auto; - -.default (@a: inherit) when (@a = inherit) { - content: default; -} -.default1 { .default } - -// true & false keywords -.test (@a) when (@a) { - content: "true."; -} -.test (@a) when not (@a) { - content: "false."; -} - -.test1 { .test(true) } -.test2 { .test(false) } -.test3 { .test(1) } -.test4 { .test(boo) } -.test5 { .test("true") } - -// Boolean expressions - -.bool () when (true) and (false) { content: true and false } // FALSE -.bool () when (true) and (true) { content: true and true } // TRUE -.bool () when (true) { content: true } // TRUE -.bool () when (false) and (false) { content: true } // FALSE -.bool () when (false), (true) { content: false, true } // TRUE -.bool () when (false) and (true) and (true), (true) { content: false and true and true, true } // TRUE -.bool () when (true) and (true) and (false), (false) { content: true and true and false, false } // FALSE -.bool () when (false), (true) and (true) { content: false, true and true } // TRUE -.bool () when (false), (false), (true) { content: false, false, true } // TRUE -.bool () when (false), (false) and (true), (false) { content: false, false and true, false } // FALSE -.bool () when (false), (true) and (true) and (true), (false) { content: false, true and true and true, false } // TRUE -.bool () when not (false) { content: not false } -.bool () when not (true) and not (false) { content: not true and not false } -.bool () when not (true) and not (true) { content: not true and not true } -.bool () when not (false) and (false), not (false) { content: not false and false, not false } - -.bool1 { .bool } - -.equality-unit-test(@num) when (@num = 1%) { - test: fail; -} -.equality-unit-test(@num) when (@num = 2) { - test: pass; -} -.equality-units { - .equality-unit-test(1px); - .equality-unit-test(2px); -} - -.colorguard(@col) when (@col = red) { content: is @col; } -.colorguard(@col) when not (blue = @col) { content: is not blue its @col; } -.colorguard(@col) {} -.colorguardtest { - .colorguard(red); - .colorguard(blue); - .colorguard(purple); -} - -.stringguard(@str) when (@str = "theme1") { content: is theme1; } -.stringguard(@str) when not ("theme2" = @str) { content: is not theme2; } -.stringguard(@str) when (~"theme1" = @str) { content: is theme1 no quotes; } -.stringguard(@str) {} -.stringguardtest { - .stringguard("theme1"); - .stringguard("theme2"); - .stringguard(theme1); -} - -.mixin(...) { - catch:all; -} -.mixin(@var) when (@var=4) { - declare: 4; -} -.mixin(@var) when (@var=4px) { - declare: 4px; -} -#tryNumberPx { - .mixin(4px); -} - -.lock-mixin(@a) { - .inner-locked-mixin(@x: @a) when (@a = 1) { - a: @a; - x: @x; - } -} -.call-lock-mixin { - .lock-mixin(1); - .call-inner-lock-mixin { - .inner-locked-mixin(); - } -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/mixins-important.less b/test/Fixtures/lessjs (1.6)/less/mixins-important.less deleted file mode 100644 index c8cc1d5c..00000000 --- a/test/Fixtures/lessjs (1.6)/less/mixins-important.less +++ /dev/null @@ -1,25 +0,0 @@ -.submixin(@a) { - border-width: @a; -} -.mixin (9) { - border: 9 !important; -} -.mixin (@a: 0) { - border: @a; - boxer: @a; - .inner { - test: @a; - } - // comment - .submixin(@a); -} - -.class { - .mixin(1); - .mixin(2) !important; - .mixin(3); - .mixin(4) !important; - .mixin(5); - .mixin !important; - .mixin(9); -} diff --git a/test/Fixtures/lessjs (1.6)/less/mixins-interpolated.less b/test/Fixtures/lessjs (1.6)/less/mixins-interpolated.less deleted file mode 100644 index 2e75e980..00000000 --- a/test/Fixtures/lessjs (1.6)/less/mixins-interpolated.less +++ /dev/null @@ -1,69 +0,0 @@ - -@a1: foo; -@a2: ~".foo"; -@a4: ~"#foo"; - -.@{a1} { - a: 1; -} - -@{a2} { - a: 2; -} - -#@{a1} { - a: 3; -} - -@{a4} { - a: 4; -} - -mi-test-a { - .foo; - #foo; -} - -.b .bb { - &.@{a1}-xxx .yyy-@{a1}@{a4} { - & @{a2}.bbb { - b: 1; - } - } -} - -mi-test-b { - .b.bb.foo-xxx.yyy-foo#foo.foo.bbb; -} - -@c1: @a1; -@c2: bar; -@c3: baz; - -#@{c1}-foo { - > .@{c2} { - .@{c3} { - c: c; - } - } -} - -mi-test-c { - &-1 {#foo-foo;} - &-2 {#foo-foo > .bar;} - &-3 {#foo-foo > .bar.baz;} -} - -.Person(@name, @gender_) { - .@{name} { - @gender: @gender_; - .sayGender() { - gender: @gender; - } - } -} - -mi-test-d { - .Person(person, "Male"); - .person.sayGender(); -} diff --git a/test/Fixtures/lessjs (1.6)/less/mixins-named-args.less b/test/Fixtures/lessjs (1.6)/less/mixins-named-args.less deleted file mode 100644 index d79e0f47..00000000 --- a/test/Fixtures/lessjs (1.6)/less/mixins-named-args.less +++ /dev/null @@ -1,36 +0,0 @@ -.mixin (@a: 1px, @b: 50%) { - width: (@a * 5); - height: (@b - 1%); - args: @arguments; -} -.mixin (@a: 1px, @b: 50%) when (@b > 75%){ - text-align: center; -} - -.named-arg { - color: blue; - .mixin(@b: 100%); -} - -.class { - @var: 20%; - .mixin(@b: @var); -} - -.all-args-wrong-args { - .mixin(@b: 10%, @a: 2px); -} - -.mixin2 (@a: 1px, @b: 50%, @c: 50) { - width: (@a * 5); - height: (@b - 1%); - color: (#000000 + @c); -} - -.named-args2 { - .mixin2(3px, @c: 100); -} - -.named-args3 { - .mixin2(@b: 30%, @c: #123456); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/mixins-nested.less b/test/Fixtures/lessjs (1.6)/less/mixins-nested.less deleted file mode 100644 index 43443de2..00000000 --- a/test/Fixtures/lessjs (1.6)/less/mixins-nested.less +++ /dev/null @@ -1,22 +0,0 @@ -.mix-inner (@var) { - border-width: @var; -} - -.mix (@a: 10) { - .inner { - height: (@a * 10); - - .innest { - width: @a; - .mix-inner((@a * 2)); - } - } -} - -.class { - .mix(30); -} - -.class2 { - .mix(60); -} diff --git a/test/Fixtures/lessjs (1.6)/less/mixins-pattern.less b/test/Fixtures/lessjs (1.6)/less/mixins-pattern.less deleted file mode 100644 index f6a12ece..00000000 --- a/test/Fixtures/lessjs (1.6)/less/mixins-pattern.less +++ /dev/null @@ -1,99 +0,0 @@ -.mixin (...) { - variadic: true; -} -.mixin () { - zero: 0; -} -.mixin (@a: 1px) { - one: 1; -} -.mixin (@a) { - one-req: 1; -} -.mixin (@a: 1px, @b: 2px) { - two: 2; -} - -.mixin (@a, @b, @c) { - three-req: 3; -} - -.mixin (@a: 1px, @b: 2px, @c: 3px) { - three: 3; -} - -.zero { - .mixin(); -} - -.one { - .mixin(1); -} - -.two { - .mixin(1, 2); -} - -.three { - .mixin(1, 2, 3); -} - -// - -.mixout ('left') { - left: 1; -} - -.mixout ('right') { - right: 1; -} - -.left { - .mixout('left'); -} -.right { - .mixout('right'); -} - -// - -.border (@side, @width) { - color: black; - .border-side(@side, @width); -} -.border-side (left, @w) { - border-left: @w; -} -.border-side (right, @w) { - border-right: @w; -} - -.border-right { - .border(right, 4px); -} -.border-left { - .border(left, 4px); -} - -// - - -.border-radius (@r) { - both: (@r * 10); -} -.border-radius (@r, left) { - left: @r; -} -.border-radius (@r, right) { - right: @r; -} - -.only-right { - .border-radius(33, right); -} -.only-left { - .border-radius(33, left); -} -.left-right { - .border-radius(33); -} diff --git a/test/Fixtures/lessjs (1.6)/less/mixins.less b/test/Fixtures/lessjs (1.6)/less/mixins.less deleted file mode 100644 index be9e2bbd..00000000 --- a/test/Fixtures/lessjs (1.6)/less/mixins.less +++ /dev/null @@ -1,141 +0,0 @@ -.mixin { border: 1px solid black; } -.mixout { border-color: orange; } -.borders { border-style: dashed; } - -#namespace { - .borders { - border-style: dotted; - } - .biohazard { - content: "death"; - .man { - color: transparent; - } - } -} -#theme { - > .mixin { - background-color: grey; - } -} -#container { - color: black; - .mixin; - .mixout; - #theme > .mixin; -} - -#header { - .milk { - color: white; - .mixin; - #theme > .mixin; - } - #cookie { - .chips { - #namespace .borders; - .calories { - #container; - } - } - .borders; - } -} -.secure-zone { #namespace .biohazard .man; } -.direct { - #namespace > .borders; -} - -.bo, .bar { - width: 100%; -} -.bo { - border: 1px; -} -.ar.bo.ca { - color: black; -} -.jo.ki { - background: none; -} -.amp { - &.support { - color: orange; - .higher { - top: 0px; - } - &.deeper { - height: auto; - } - } -} -.extended { - .bo; - .jo.ki; - .amp.support; - .amp.support.higher; - .amp.support.deeper; -} -.do .re .mi .fa { - .sol .la { - .si { - color: cyan; - } - } -} -.mutli-selector-parents { - .do.re.mi.fa.sol.la.si; -} -.foo .bar { - .bar; -} -.has_parents() { - & .underParents { - color: red; - } -} -.has_parents(); -.parent { - .has_parents(); -} -.margin_between(@above, @below) { - * + & { margin-top: @above; } - legend + & { margin-top: 0; } - & + * { margin-top: @below; } -} -h1 { .margin_between(25px, 10px); } -h2 { .margin_between(20px, 8px); } -h3 { .margin_between(15px, 5px); } - -.mixin_def(@url, @position){ - background-image: @url; - background-position: @position; -} -.error{ - @s: "/"; - .mixin_def( "@{s}a.png", center center); -} -.recursion() { - color: black; -} -.test-rec { - .recursion { - .recursion(); - } -} -.paddingFloat(@padding) { padding-left: @padding; } - -.button { - .paddingFloat(((10px + 12) * 2)); - - &.large { .paddingFloat(((10em * 2) * 2)); } -} -.clearfix() { - // ... -} -.clearfix { - .clearfix(); -} -.foo { - .clearfix(); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/modifyVars/extended.json b/test/Fixtures/lessjs (1.6)/less/modifyVars/extended.json deleted file mode 100644 index 6bd2a484..00000000 --- a/test/Fixtures/lessjs (1.6)/less/modifyVars/extended.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "the-border": "1px", - "base-color": "#111", - "red": "#842210" -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/modifyVars/extended.less b/test/Fixtures/lessjs (1.6)/less/modifyVars/extended.less deleted file mode 100644 index 0badc671..00000000 --- a/test/Fixtures/lessjs (1.6)/less/modifyVars/extended.less +++ /dev/null @@ -1,11 +0,0 @@ -#header { - color: (@base-color * 3); - border-left: @the-border; - border-right: (@the-border * 2); -} -#footer { - color: (@base-color + #003300); - border-color: @red; -} -@red: blue; // var is overridden by the modifyVars -//@base-color: green; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/no-js-errors/no-js-errors.less b/test/Fixtures/lessjs (1.6)/less/no-js-errors/no-js-errors.less deleted file mode 100644 index 15ef8a45..00000000 --- a/test/Fixtures/lessjs (1.6)/less/no-js-errors/no-js-errors.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - a: `1 + 1`; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/no-js-errors/no-js-errors.txt b/test/Fixtures/lessjs (1.6)/less/no-js-errors/no-js-errors.txt deleted file mode 100644 index d81dd2bd..00000000 --- a/test/Fixtures/lessjs (1.6)/less/no-js-errors/no-js-errors.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: You are using JavaScript, which has been disabled. in {path}no-js-errors.less on line 2, column 6: -1 .a { -2 a: `1 + 1`; -3 } diff --git a/test/Fixtures/lessjs (1.6)/less/no-output.less b/test/Fixtures/lessjs (1.6)/less/no-output.less deleted file mode 100644 index b4e6a499..00000000 --- a/test/Fixtures/lessjs (1.6)/less/no-output.less +++ /dev/null @@ -1,2 +0,0 @@ -.mixin() { -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/operations.less b/test/Fixtures/lessjs (1.6)/less/operations.less deleted file mode 100644 index 3e483c8b..00000000 --- a/test/Fixtures/lessjs (1.6)/less/operations.less +++ /dev/null @@ -1,62 +0,0 @@ -#operations { - color: (#110000 + #000011 + #001100); // #111111 - height: (10px / 2px + 6px - 1px * 2); // 9px - width: (2 * 4 - 5em); // 3em - .spacing { - height: (10px / 2px+6px-1px*2); - width: (2 * 4-5em); - } - substraction: (20 - 10 - 5 - 5); // 0 - division: (20 / 5 / 4); // 1 -} - -@x: 4; -@y: 12em; - -.with-variables { - height: (@x + @y); // 16em - width: (12 + @y); // 24em - size: (5cm - @x); // 1cm -} - -.with-functions { - color: (rgb(200, 200, 200) / 2); - color: (2 * hsl(0, 50%, 50%)); - color: (rgb(10, 10, 10) + hsl(0, 50%, 50%)); -} - -@z: -2; - -.negative { - height: (2px + @z); // 0px - width: (2px - @z); // 4px -} - -.shorthands { - padding: -1px 2px 0 -4px; // -} - -.rem-dimensions { - font-size: (20rem / 5 + 1.5rem); // 5.5rem -} - -.colors { - color: #123; // #112233 - border-color: (#234 + #111111); // #334455 - background-color: (#222222 - #fff); // #000000 - .other { - color: (2 * #111); // #222222 - border-color: (#333333 / 3 + #111); // #222222 - } -} - -.negations { - @var: 4px; - variable: (-@var); // 4 - variable1: (-@var + @var); // 0 - variable2: (@var + -@var); // 0 - variable3: (@var - -@var); // 8 - variable4: (-@var - -@var); // 0 - paren: (-(@var)); // -4px - paren2: (-(2 + 2) * -@var); // 16 -} diff --git a/test/Fixtures/lessjs (1.6)/less/parens.less b/test/Fixtures/lessjs (1.6)/less/parens.less deleted file mode 100644 index eeef3448..00000000 --- a/test/Fixtures/lessjs (1.6)/less/parens.less +++ /dev/null @@ -1,45 +0,0 @@ -.parens { - @var: 1px; - border: (@var * 2) solid black; - margin: (@var * 1) (@var + 2) (4 * 4) 3; - width: (6 * 6); - padding: 2px (6 * 6px); -} - -.more-parens { - @var: (2 * 2); - padding: (2 * @var) 4 4 (@var * 1px); - width-all: ((@var * @var) * 6); - width-first: ((@var * @var)) * 6; - width-keep: (@var * @var) * 6; - height-keep: (7 * 7) + (8 * 8); - height-all: ((7 * 7) + (8 * 8)); - height-parts: ((7 * 7)) + ((8 * 8)); - margin-keep: (4 * (5 + 5) / 2) - (@var * 2); - margin-parts: ((4 * (5 + 5) / 2)) - ((@var * 2)); - margin-all: ((4 * (5 + 5) / 2) + (-(@var * 2))); - border-radius-keep: 4px * (1 + 1) / @var + 3px; - border-radius-parts: ((4px * (1 + 1))) / ((@var + 3px)); - border-radius-all: (4px * (1 + 1) / @var + 3px); - //margin: (6 * 6)px; -} - -.negative { - @var: 1; - neg-var: -@var; // -1 ? - neg-var-paren: -(@var); // -(1) ? -} - -.nested-parens { - width: 2 * (4 * (2 + (1 + 6))) - 1; - height: ((2 + 3) * (2 + 3) / (9 - 4)) + 1; -} - -.mixed-units { - margin: 2px 4em 1 5pc; - padding: (2px + 4px) 1em 2px 2; -} - -.test-false-negatives { - a: ~"("; -} diff --git a/test/Fixtures/lessjs (1.6)/less/property-name-interp.less b/test/Fixtures/lessjs (1.6)/less/property-name-interp.less deleted file mode 100644 index 9886e65f..00000000 --- a/test/Fixtures/lessjs (1.6)/less/property-name-interp.less +++ /dev/null @@ -1,53 +0,0 @@ - -pi-test { - @prefix: ufo-; - @a: border; - @bb: top; - @c_c: left; - @d-d4: radius; - @-: -; - - @{a}: 0; - @{prefix}width: 50%; - *-z-@{a} :1px dashed blue; - -www-@{a}-@{bb}: 2px; - @{d-d4}-is-not-a-@{a}:true; - @{a}-@{bb}-@{c_c}-@{d-d4} : 2em; - @{a}@{-}@{bb}@{-}red@{-}@{d-d4}-: 3pt; - - .mixin(mixer); - .merge(ish, base); -} - -@global: global; - -.mixin(@arg) { - @local: local; - @{global}-@{local}-@{arg}-property: strong; -} - -.merge(@p, @v) { - &-merge { - @prefix: pre; - @suffix: ish; - @{prefix}-property-ish+ :high; - pre-property-@{suffix} +: middle; - @{prefix}-property-@{suffix}+: low; - @{prefix}-property-@{p} + : @v; - - @subterfuge: ~'+'; - pre-property-ish@{subterfuge}: nice try dude; - } -} - -pi-indirect-vars { - @{p}: @p; - @p: @@a; - @a: b; - @b: auto; -} - -pi-complex-values { - @{p}@{p}: none; - @p: (1 + 2px) fadeout(#ff0, 50%), pi() /* foo */; -} diff --git a/test/Fixtures/lessjs (1.6)/less/rulesets.less b/test/Fixtures/lessjs (1.6)/less/rulesets.less deleted file mode 100644 index e81192db..00000000 --- a/test/Fixtures/lessjs (1.6)/less/rulesets.less +++ /dev/null @@ -1,30 +0,0 @@ -#first > .one { - > #second .two > #deux { - width: 50%; - #third { - &:focus { - color: black; - #fifth { - > #sixth { - .seventh #eighth { - + #ninth { - color: purple; - } - } - } - } - } - height: 100%; - } - #fourth, #five, #six { - color: #110000; - .seven, .eight > #nine { - border: 1px solid black; - } - #ten { - color: red; - } - } - } - font-size: 2em; -} diff --git a/test/Fixtures/lessjs (1.6)/less/scope.less b/test/Fixtures/lessjs (1.6)/less/scope.less deleted file mode 100644 index 36d37061..00000000 --- a/test/Fixtures/lessjs (1.6)/less/scope.less +++ /dev/null @@ -1,79 +0,0 @@ -@x: red; -@x: blue; -@z: transparent; -@mix: none; - -.mixin { - @mix: #989; -} -@mix: blue; -.tiny-scope { - color: @mix; // #989 - .mixin; -} - -.scope1 { - @y: orange; - @z: black; - color: @x; // blue - border-color: @z; // black - .hidden { - @x: #131313; - } - .scope2 { - @y: red; - color: @x; // blue - .scope3 { - @local: white; - color: @y; // red - border-color: @z; // black - background-color: @local; // white - } - } -} - -#namespace { - .scoped_mixin() { - @local-will-be-made-global: green; - .scope { - scoped-val: @local-will-be-made-global; - } - } -} - -#namespace > .scoped_mixin(); - -.setHeight(@h) { @height: 1024px; } -.useHeightInMixinCall(@h) { .useHeightInMixinCall { mixin-height: @h; } } -@mainHeight: 50%; -.setHeight(@mainHeight); -.heightIsSet { height: @height; } -.useHeightInMixinCall(@height); - -.importRuleset() { - .imported { - exists: true; - } -} -.importRuleset(); -.testImported { - .imported; -} - -@parameterDefault: 'top level'; -@anotherVariable: 'top level'; -//mixin uses top-level variables -.mixinNoParam(@parameter: @parameterDefault) when (@parameter = 'top level') { - default: @parameter; - scope: @anotherVariable; - sub-scope-only: @subScopeOnly; -} - -#allAreUsedHere { - //redefine top-level variables in different scope - @parameterDefault: 'inside'; - @anotherVariable: 'inside'; - @subScopeOnly: 'inside'; - //use the mixin - .mixinNoParam(); -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/selectors.less b/test/Fixtures/lessjs (1.6)/less/selectors.less deleted file mode 100644 index 8b30546f..00000000 --- a/test/Fixtures/lessjs (1.6)/less/selectors.less +++ /dev/null @@ -1,156 +0,0 @@ -h1, h2, h3 { - a, p { - &:hover { - color: red; - } - } -} - -#all { color: blue; } -#the { color: blue; } -#same { color: blue; } - -ul, li, div, q, blockquote, textarea { - margin: 0; -} - -td { - margin: 0; - padding: 0; -} - -td, input { - line-height: 1em; -} - -a { - color: red; - - &:hover { color: blue; } - - div & { color: green; } - - p & span { color: yellow; } -} - -.foo { - .bar, .baz { - & .qux { - display: block; - } - .qux & { - display: inline; - } - .qux& { - display: inline-block; - } - .qux & .biz { - display: none; - } - } -} - -.b { - &.c { - .a& { - color: red; - } - } -} - -.b { - .c & { - &.a { - color: red; - } - } -} - -.p { - .foo &.bar { - color: red; - } -} - -.p { - .foo&.bar { - color: red; - } -} - -.foo { - .foo + & { - background: amber; - } - & + & { - background: amber; - } -} - -.foo, .bar { - & + & { - background: amber; - } -} - -.foo, .bar { - a, b { - & > & { - background: amber; - } - } -} - -.other ::fnord { color: red } -.other::fnord { color: red } -.other { - ::bnord {color: red } - &::bnord {color: red } -} -// selector interpolation -@theme: blood; -@selector: ~".@{theme}"; -@{selector} { - color:red; -} -@{selector}red { - color: green; -} -.red { - #@{theme}.@{theme}&.black { - color:black; - } -} -@num: 3; -:nth-child(@{num}) { - selector: interpolated; -} -.test { - &:nth-child(odd):not(:nth-child(3)) { - color: #ff0000; - } -} -[prop], -[prop=10%], -[prop="value@{num}"], -[prop*="val@{num}"], -[|prop~="val@{num}"], -[*|prop$="val@{num}"], -[ns|prop^="val@{num}"], -[@{num}^="val@{num}"], -[@{num}=@{num}], -[@{num}] { - attributes: yes; -} - -/* -Large comment means chunk will be emitted after } which means chunk will begin with whitespace... -blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank -blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank -blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank -blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank -blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank blank -*/ -@{selector} { - color: red; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/sourcemaps/basic.json b/test/Fixtures/lessjs (1.6)/less/sourcemaps/basic.json deleted file mode 100644 index 76a63c5a..00000000 --- a/test/Fixtures/lessjs (1.6)/less/sourcemaps/basic.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "my-color": "red" -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/sourcemaps/basic.less b/test/Fixtures/lessjs (1.6)/less/sourcemaps/basic.less deleted file mode 100644 index 4ee8b4f6..00000000 --- a/test/Fixtures/lessjs (1.6)/less/sourcemaps/basic.less +++ /dev/null @@ -1,27 +0,0 @@ -@var: black; - -.a() { - color: red; -} - -.b { - color: green; - .a(); - color: blue; - background: @var; -} - -.a, .b { - background: green; - .c, .d { - background: gray; - & + & { - color: red; - } - } -} - -.extend:extend(.a all) { - color: pink; -} -@import (inline) "imported.css"; \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/sourcemaps/imported.css b/test/Fixtures/lessjs (1.6)/less/sourcemaps/imported.css deleted file mode 100644 index 2ee35f06..00000000 --- a/test/Fixtures/lessjs (1.6)/less/sourcemaps/imported.css +++ /dev/null @@ -1,7 +0,0 @@ -/*comments*/ -.unused-css { - color: white; -} -.imported { - color: black; -} \ No newline at end of file diff --git a/test/Fixtures/lessjs (1.6)/less/static-urls/urls.less b/test/Fixtures/lessjs (1.6)/less/static-urls/urls.less deleted file mode 100644 index b0c7de09..00000000 --- a/test/Fixtures/lessjs (1.6)/less/static-urls/urls.less +++ /dev/null @@ -1,33 +0,0 @@ -@font-face { - src: url("/fonts/garamond-pro.ttf"); - src: local(Futura-Medium), - url(fonts.svg#MyGeometricModern) format("svg"); -} -#shorthands { - background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; -} -#misc { - background-image: url(images/image.jpg); -} -#data-uri { - background: url(data:image/png;charset=utf-8;base64, - kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ - k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U - kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700); -} - -#svg-data-uri { - background: transparent url('data:image/svg+xml, '); -} - -.comma-delimited { - background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg); -} -.values { - @a: 'Trebuchet'; - url: url(@a); -} - -@import "../import/import-and-relative-paths-test"; diff --git a/test/Fixtures/lessjs (1.6)/less/strings.less b/test/Fixtures/lessjs (1.6)/less/strings.less deleted file mode 100644 index c43e368d..00000000 --- a/test/Fixtures/lessjs (1.6)/less/strings.less +++ /dev/null @@ -1,57 +0,0 @@ -#strings { - background-image: url("http://son-of-a-banana.com"); - quotes: "~" "~"; - content: "#*%:&^,)!.(~*})"; - empty: ""; - brackets: "{" "}"; - escapes: "\"hello\" \\world"; - escapes2: "\"llo"; -} -#comments { - content: "/* hello */ // not-so-secret"; -} -#single-quote { - quotes: "'" "'"; - content: '""#!&""'; - empty: ''; - semi-colon: ';'; -} -#escaped { - filter: ~"DX.Transform.MS.BS.filter(opacity=50)"; -} -#one-line { image: url(http://tooks.com) } -#crazy { image: url(http://), "}", url("http://}") } -#interpolation { - @var: '/dev'; - url: "http://lesscss.org@{var}/image.jpg"; - - @var2: 256; - url2: "http://lesscss.org/image-@{var2}.jpg"; - - @var3: #456; - url3: "http://lesscss.org@{var3}"; - - @var4: hello; - url4: "http://lesscss.org/@{var4}"; - - @var5: 54.4px; - url5: "http://lesscss.org/@{var5}"; -} - -// multiple calls with string interpolation - -.mix-mul (@a: green) { - color: ~"@{a}"; -} -.mix-mul-class { - .mix-mul(blue); - .mix-mul(red); - .mix-mul(black); - .mix-mul(orange); -} - -@test: Arial, Verdana, San-Serif; -.watermark { - @family: ~"Univers, @{test}"; - family: @family; -} diff --git a/test/Fixtures/lessjs (1.6)/less/url-args/urls.less b/test/Fixtures/lessjs (1.6)/less/url-args/urls.less deleted file mode 100644 index 2f1bd872..00000000 --- a/test/Fixtures/lessjs (1.6)/less/url-args/urls.less +++ /dev/null @@ -1,63 +0,0 @@ -@font-face { - src: url("/fonts/garamond-pro.ttf"); - src: local(Futura-Medium), - url(fonts.svg#MyGeometricModern) format("svg"); -} -#shorthands { - background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; - background: url("img.jpg") center / 100px; - background: #fff url(image.png) center / 1px 100px repeat-x scroll content-box padding-box; -} -#misc { - background-image: url(images/image.jpg); -} -#data-uri { - background: url(data:image/png;charset=utf-8;base64, - kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ - k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U - kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700); - background-image: url("http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700"); -} - -#svg-data-uri { - background: transparent url('data:image/svg+xml, '); -} - -.comma-delimited { - background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg); -} -.values { - @a: 'Trebuchet'; - url: url(@a); -} - -@import "../import/imports/font"; - -#data-uri { - uri: data-uri('image/jpeg;base64', '../../data/image.jpg'); -} - -#data-uri-guess { - uri: data-uri('../../data/image.jpg'); -} - -#data-uri-ascii { - uri-1: data-uri('text/html', '../../data/page.html'); - uri-2: data-uri('../../data/page.html'); -} - -#svg-functions { - background-image: svg-gradient(to bottom, black, white); - background-image: svg-gradient(to bottom, black, orange 3%, white); - @green_5: green 5%; - @orange_percentage: 3%; - @orange_color: orange; - background-image: svg-gradient(to bottom, (mix(black, white) + #444) 1%, @orange_color @orange_percentage, ((@green_5)), white 95%); -} - -#data-uri-with-spaces { - background-image: url( data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url( ' data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9=='); -} diff --git a/test/Fixtures/lessjs (1.6)/less/urls.less b/test/Fixtures/lessjs (1.6)/less/urls.less deleted file mode 100644 index ca1602e2..00000000 --- a/test/Fixtures/lessjs (1.6)/less/urls.less +++ /dev/null @@ -1,72 +0,0 @@ -@font-face { - src: url("/fonts/garamond-pro.ttf"); - src: local(Futura-Medium), - url(fonts.svg#MyGeometricModern) format("svg"); -} -#shorthands { - background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; - background: url("img.jpg") center / 100px; - background: #fff url(image.png) center / 1px 100px repeat-x scroll content-box padding-box; -} -#misc { - background-image: url(images/image.jpg); -} -#data-uri { - background: url(data:image/png;charset=utf-8;base64, - kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ - k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U - kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700); - background-image: url("http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700"); -} - -#svg-data-uri { - background: transparent url('data:image/svg+xml, '); -} - -.comma-delimited { - background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg); -} -.values { - @a: 'Trebuchet'; - url: url(@a); -} - -@import "import/import-and-relative-paths-test"; - -#relative-url-import { - .unquoted-relative-path-bg; - .quoted-relative-path-border-image; -} - -#data-uri { - uri: data-uri('image/jpeg;base64', '../data/image.jpg'); -} - -#data-uri-guess { - uri: data-uri('../data/image.jpg'); -} - -#data-uri-ascii { - uri-1: data-uri('text/html', '../data/page.html'); - uri-2: data-uri('../data/page.html'); -} - -#data-uri-toobig { - uri: data-uri('../data/data-uri-fail.png'); -} -.add_an_import(@file_to_import) { -@import "@{file_to_import}"; -} - -.add_an_import("file.css"); - -#svg-functions { - background-image: svg-gradient(to bottom, black, white); - background-image: svg-gradient(to bottom, black, orange 3%, white); - @green_5: green 5%; - @orange_percentage: 3%; - @orange_color: orange; - background-image: svg-gradient(to bottom, (mix(black, white) + #444) 1%, @orange_color @orange_percentage, ((@green_5)), white 95%); -} diff --git a/test/Fixtures/lessjs (1.6)/less/variables.less b/test/Fixtures/lessjs (1.6)/less/variables.less deleted file mode 100644 index e896f404..00000000 --- a/test/Fixtures/lessjs (1.6)/less/variables.less +++ /dev/null @@ -1,83 +0,0 @@ -@a: 2; -@x: (@a * @a); -@y: (@x + 1); -@z: (@x * 2 + @y); -@var: -1; - -.variables { - width: (@z + 1cm); // 14cm -} - -@b: @a * 10; -@c: #888; - -@fonts: "Trebuchet MS", Verdana, sans-serif; -@f: @fonts; - -@quotes: "~" "~"; -@q: @quotes; -@onePixel: 1px; - -.variables { - height: (@b + @x + 0px); // 24px - color: @c; - font-family: @f; - quotes: @q; -} - -.redef { - @var: 0; - .inition { - @var: 4; - @var: 2; - three: @var; - @var: 3; - } - zero: @var; -} - -.values { - minus-one: @var; - @a: 'Trebuchet'; - @multi: 'A', B, C; - font-family: @a, @a, @a; - color: @c !important; - multi: something @multi, @a; -} - -.variable-names { - @var: 'hello'; - @name: 'var'; - name: @@name; -} - -.alpha { - @var: 42; - filter: alpha(opacity=@var); -} - -.polluteMixin() { - @a: 'pollution'; -} -.testPollution { - @a: 'no-pollution'; - a: @a; - .polluteMixin(); - a: @a; -} - -.units { - width: @onePixel; - same-unit-as-previously: (@onePixel / @onePixel); - square-pixel-divided: (@onePixel * @onePixel / @onePixel); - odd-unit: unit((@onePixel * 4em / 2cm)); - percentage: (10 * 50%); - pixels: (50px * 10); - conversion-metric-a: (20mm + 1cm); - conversion-metric-b: (1cm + 20mm); - conversion-imperial: (1in + 72pt + 6pc); - custom-unit: (42octocats * 10); - custom-unit-cancelling: (8cats * 9dogs / 4cats); - mix-units: (1px + 1em); - invalid-units: (1px * 1px); -} diff --git a/test/Fixtures/lessjs (1.6)/less/whitespace.less b/test/Fixtures/lessjs (1.6)/less/whitespace.less deleted file mode 100644 index ab4804da..00000000 --- a/test/Fixtures/lessjs (1.6)/less/whitespace.less +++ /dev/null @@ -1,44 +0,0 @@ - - -.whitespace - { color: white; } - -.whitespace -{ - color: white; -} - .whitespace -{ color: white; } - -.whitespace{color:white;} -.whitespace { color : white ; } - -.white, -.space, -.mania -{ color: white; } - -.no-semi-column { color: white } -.no-semi-column { - color: white; - white-space: pre -} -.no-semi-column {border: 2px solid white} -.newlines { - background: the, - great, - wall; - border: 2px - solid - black; -} -.empty { - -} -.sel -.newline_ws .tab_ws { -color: -white; -background-position: 45 --23; -} diff --git a/test/assets/less-1.6.3.js b/test/assets/less-1.6.3.js deleted file mode 100644 index 1e3082bc..00000000 --- a/test/assets/less-1.6.3.js +++ /dev/null @@ -1,7640 +0,0 @@ -/*! - * LESS - Leaner CSS v1.6.3 - * http://lesscss.org - * - * Copyright (c) 2009-2014, Alexis Sellier - * Licensed under the Apache v2 License. - * - */ - - /** * @license Apache v2 - */ - - - -(function (window, undefined) {// -// Stub out `require` in the browser -// -function require(arg) { - return window.less[arg.split('/')[1]]; -}; - - -if (typeof(window.less) === 'undefined' || typeof(window.less.nodeType) !== 'undefined') { window.less = {}; } -less = window.less; -tree = window.less.tree = {}; -less.mode = 'browser'; - -var less, tree; - -// Node.js does not have a header file added which defines less -if (less === undefined) { - less = exports; - tree = require('./tree'); - less.mode = 'node'; -} -// -// less.js - parser -// -// A relatively straight-forward predictive parser. -// There is no tokenization/lexing stage, the input is parsed -// in one sweep. -// -// To make the parser fast enough to run in the browser, several -// optimization had to be made: -// -// - Matching and slicing on a huge input is often cause of slowdowns. -// The solution is to chunkify the input into smaller strings. -// The chunks are stored in the `chunks` var, -// `j` holds the current chunk index, and `currentPos` holds -// the index of the current chunk in relation to `input`. -// This gives us an almost 4x speed-up. -// -// - In many cases, we don't need to match individual tokens; -// for example, if a value doesn't hold any variables, operations -// or dynamic references, the parser can effectively 'skip' it, -// treating it as a literal. -// An example would be '1px solid #000' - which evaluates to itself, -// we don't need to know what the individual components are. -// The drawback, of course is that you don't get the benefits of -// syntax-checking on the CSS. This gives us a 50% speed-up in the parser, -// and a smaller speed-up in the code-gen. -// -// -// Token matching is done with the `$` function, which either takes -// a terminal string or regexp, or a non-terminal function to call. -// It also takes care of moving all the indices forwards. -// -// -less.Parser = function Parser(env) { - var input, // LeSS input string - i, // current index in `input` - j, // current chunk - temp, // temporarily holds a chunk's state, for backtracking - memo, // temporarily holds `i`, when backtracking - furthest, // furthest index the parser has gone to - chunks, // chunkified input - current, // current chunk - currentPos, // index of current chunk, in `input` - parser, - parsers, - rootFilename = env && env.filename; - - // Top parser on an import tree must be sure there is one "env" - // which will then be passed around by reference. - if (!(env instanceof tree.parseEnv)) { - env = new tree.parseEnv(env); - } - - var imports = this.imports = { - paths: env.paths || [], // Search paths, when importing - queue: [], // Files which haven't been imported yet - files: env.files, // Holds the imported parse trees - contents: env.contents, // Holds the imported file contents - contentsIgnoredChars: env.contentsIgnoredChars, // lines inserted, not in the original less - mime: env.mime, // MIME type of .less files - error: null, // Error in parsing/evaluating an import - push: function (path, currentFileInfo, importOptions, callback) { - var parserImports = this; - this.queue.push(path); - - var fileParsedFunc = function (e, root, fullPath) { - parserImports.queue.splice(parserImports.queue.indexOf(path), 1); // Remove the path from the queue - - var importedPreviously = fullPath in parserImports.files || fullPath === rootFilename; - - parserImports.files[fullPath] = root; // Store the root - - if (e && !parserImports.error) { parserImports.error = e; } - - callback(e, root, importedPreviously, fullPath); - }; - - if (less.Parser.importer) { - less.Parser.importer(path, currentFileInfo, fileParsedFunc, env); - } else { - less.Parser.fileLoader(path, currentFileInfo, function(e, contents, fullPath, newFileInfo) { - if (e) {fileParsedFunc(e); return;} - - var newEnv = new tree.parseEnv(env); - - newEnv.currentFileInfo = newFileInfo; - newEnv.processImports = false; - newEnv.contents[fullPath] = contents; - - if (currentFileInfo.reference || importOptions.reference) { - newFileInfo.reference = true; - } - - if (importOptions.inline) { - fileParsedFunc(null, contents, fullPath); - } else { - new(less.Parser)(newEnv).parse(contents, function (e, root) { - fileParsedFunc(e, root, fullPath); - }); - } - }, env); - } - } - }; - - function save() { temp = current; memo = currentPos = i; } - function restore() { current = temp; currentPos = i = memo; } - - function sync() { - if (i > currentPos) { - current = current.slice(i - currentPos); - currentPos = i; - } - } - function isWhitespace(str, pos) { - var code = str.charCodeAt(pos | 0); - return (code <= 32) && (code === 32 || code === 10 || code === 9); - } - // - // Parse from a token, regexp or string, and move forward if match - // - function $(tok) { - var tokType = typeof tok, - match, length; - - // Either match a single character in the input, - // or match a regexp in the current chunk (`current`). - // - if (tokType === "string") { - if (input.charAt(i) !== tok) { - return null; - } - skipWhitespace(1); - return tok; - } - - // regexp - sync (); - if (! (match = tok.exec(current))) { - return null; - } - - length = match[0].length; - - // The match is confirmed, add the match length to `i`, - // and consume any extra white-space characters (' ' || '\n') - // which come after that. The reason for this is that LeSS's - // grammar is mostly white-space insensitive. - // - skipWhitespace(length); - - if(typeof(match) === 'string') { - return match; - } else { - return match.length === 1 ? match[0] : match; - } - } - - // Specialization of $(tok) - function $re(tok) { - if (i > currentPos) { - current = current.slice(i - currentPos); - currentPos = i; - } - var m = tok.exec(current); - if (!m) { - return null; - } - - skipWhitespace(m[0].length); - if(typeof m === "string") { - return m; - } - - return m.length === 1 ? m[0] : m; - } - - var _$re = $re; - - // Specialization of $(tok) - function $char(tok) { - if (input.charAt(i) !== tok) { - return null; - } - skipWhitespace(1); - return tok; - } - - function skipWhitespace(length) { - var oldi = i, oldj = j, - curr = i - currentPos, - endIndex = i + current.length - curr, - mem = (i += length), - inp = input, - c; - - for (; i < endIndex; i++) { - c = inp.charCodeAt(i); - if (c > 32) { - break; - } - - if ((c !== 32) && (c !== 10) && (c !== 9) && (c !== 13)) { - break; - } - } - - current = current.slice(length + i - mem + curr); - currentPos = i; - - if (!current.length && (j < chunks.length - 1)) { - current = chunks[++j]; - skipWhitespace(0); // skip space at the beginning of a chunk - return true; // things changed - } - - return oldi !== i || oldj !== j; - } - - function expect(arg, msg) { - // some older browsers return typeof 'function' for RegExp - var result = (Object.prototype.toString.call(arg) === '[object Function]') ? arg.call(parsers) : $(arg); - if (result) { - return result; - } - error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'" - : "unexpected token")); - } - - // Specialization of expect() - function expectChar(arg, msg) { - if (input.charAt(i) === arg) { - skipWhitespace(1); - return arg; - } - error(msg || "expected '" + arg + "' got '" + input.charAt(i) + "'"); - } - - function error(msg, type) { - var e = new Error(msg); - e.index = i; - e.type = type || 'Syntax'; - throw e; - } - - // Same as $(), but don't change the state of the parser, - // just return the match. - function peek(tok) { - if (typeof(tok) === 'string') { - return input.charAt(i) === tok; - } else { - return tok.test(current); - } - } - - // Specialization of peek() - function peekChar(tok) { - return input.charAt(i) === tok; - } - - - function getInput(e, env) { - if (e.filename && env.currentFileInfo.filename && (e.filename !== env.currentFileInfo.filename)) { - return parser.imports.contents[e.filename]; - } else { - return input; - } - } - - function getLocation(index, inputStream) { - var n = index + 1, - line = null, - column = -1; - - while (--n >= 0 && inputStream.charAt(n) !== '\n') { - column++; - } - - if (typeof index === 'number') { - line = (inputStream.slice(0, index).match(/\n/g) || "").length; - } - - return { - line: line, - column: column - }; - } - - function getDebugInfo(index, inputStream, env) { - var filename = env.currentFileInfo.filename; - if(less.mode !== 'browser' && less.mode !== 'rhino') { - filename = require('path').resolve(filename); - } - - return { - lineNumber: getLocation(index, inputStream).line + 1, - fileName: filename - }; - } - - function LessError(e, env) { - var input = getInput(e, env), - loc = getLocation(e.index, input), - line = loc.line, - col = loc.column, - callLine = e.call && getLocation(e.call, input).line, - lines = input.split('\n'); - - this.type = e.type || 'Syntax'; - this.message = e.message; - this.filename = e.filename || env.currentFileInfo.filename; - this.index = e.index; - this.line = typeof(line) === 'number' ? line + 1 : null; - this.callLine = callLine + 1; - this.callExtract = lines[callLine]; - this.stack = e.stack; - this.column = col; - this.extract = [ - lines[line - 1], - lines[line], - lines[line + 1] - ]; - } - - LessError.prototype = new Error(); - LessError.prototype.constructor = LessError; - - this.env = env = env || {}; - - // The optimization level dictates the thoroughness of the parser, - // the lower the number, the less nodes it will create in the tree. - // This could matter for debugging, or if you want to access - // the individual nodes in the tree. - this.optimization = ('optimization' in this.env) ? this.env.optimization : 1; - - // - // The Parser - // - parser = { - - imports: imports, - // - // Parse an input string into an abstract syntax tree, - // @param str A string containing 'less' markup - // @param callback call `callback` when done. - // @param [additionalData] An optional map which can contains vars - a map (key, value) of variables to apply - // - parse: function (str, callback, additionalData) { - var root, line, lines, error = null, globalVars, modifyVars, preText = ""; - - i = j = currentPos = furthest = 0; - - globalVars = (additionalData && additionalData.globalVars) ? less.Parser.serializeVars(additionalData.globalVars) + '\n' : ''; - modifyVars = (additionalData && additionalData.modifyVars) ? '\n' + less.Parser.serializeVars(additionalData.modifyVars) : ''; - - if (globalVars || (additionalData && additionalData.banner)) { - preText = ((additionalData && additionalData.banner) ? additionalData.banner : "") + globalVars; - parser.imports.contentsIgnoredChars[env.currentFileInfo.filename] = preText.length; - } - - str = str.replace(/\r\n/g, '\n'); - // Remove potential UTF Byte Order Mark - input = str = preText + str.replace(/^\uFEFF/, '') + modifyVars; - parser.imports.contents[env.currentFileInfo.filename] = str; - - // Split the input into chunks. - chunks = (function (input) { - var len = input.length, level = 0, parenLevel = 0, - lastOpening, lastOpeningParen, lastMultiComment, lastMultiCommentEndBrace, - chunks = [], emitFrom = 0, - parserCurrentIndex, currentChunkStartIndex, cc, cc2, matched; - - function fail(msg, index) { - error = new(LessError)({ - index: index || parserCurrentIndex, - type: 'Parse', - message: msg, - filename: env.currentFileInfo.filename - }, env); - } - - function emitChunk(force) { - var len = parserCurrentIndex - emitFrom; - if (((len < 512) && !force) || !len) { - return; - } - chunks.push(input.slice(emitFrom, parserCurrentIndex + 1)); - emitFrom = parserCurrentIndex + 1; - } - - for (parserCurrentIndex = 0; parserCurrentIndex < len; parserCurrentIndex++) { - cc = input.charCodeAt(parserCurrentIndex); - if (((cc >= 97) && (cc <= 122)) || (cc < 34)) { - // a-z or whitespace - continue; - } - - switch (cc) { - case 40: // ( - parenLevel++; - lastOpeningParen = parserCurrentIndex; - continue; - case 41: // ) - if (--parenLevel < 0) { - return fail("missing opening `(`"); - } - continue; - case 59: // ; - if (!parenLevel) { emitChunk(); } - continue; - case 123: // { - level++; - lastOpening = parserCurrentIndex; - continue; - case 125: // } - if (--level < 0) { - return fail("missing opening `{`"); - } - if (!level) { emitChunk(); } - continue; - case 92: // \ - if (parserCurrentIndex < len - 1) { parserCurrentIndex++; continue; } - return fail("unescaped `\\`"); - case 34: - case 39: - case 96: // ", ' and ` - matched = 0; - currentChunkStartIndex = parserCurrentIndex; - for (parserCurrentIndex = parserCurrentIndex + 1; parserCurrentIndex < len; parserCurrentIndex++) { - cc2 = input.charCodeAt(parserCurrentIndex); - if (cc2 > 96) { continue; } - if (cc2 == cc) { matched = 1; break; } - if (cc2 == 92) { // \ - if (parserCurrentIndex == len - 1) { - return fail("unescaped `\\`"); - } - parserCurrentIndex++; - } - } - if (matched) { continue; } - return fail("unmatched `" + String.fromCharCode(cc) + "`", currentChunkStartIndex); - case 47: // /, check for comment - if (parenLevel || (parserCurrentIndex == len - 1)) { continue; } - cc2 = input.charCodeAt(parserCurrentIndex + 1); - if (cc2 == 47) { - // //, find lnfeed - for (parserCurrentIndex = parserCurrentIndex + 2; parserCurrentIndex < len; parserCurrentIndex++) { - cc2 = input.charCodeAt(parserCurrentIndex); - if ((cc2 <= 13) && ((cc2 == 10) || (cc2 == 13))) { break; } - } - } else if (cc2 == 42) { - // /*, find */ - lastMultiComment = currentChunkStartIndex = parserCurrentIndex; - for (parserCurrentIndex = parserCurrentIndex + 2; parserCurrentIndex < len - 1; parserCurrentIndex++) { - cc2 = input.charCodeAt(parserCurrentIndex); - if (cc2 == 125) { lastMultiCommentEndBrace = parserCurrentIndex; } - if (cc2 != 42) { continue; } - if (input.charCodeAt(parserCurrentIndex + 1) == 47) { break; } - } - if (parserCurrentIndex == len - 1) { - return fail("missing closing `*/`", currentChunkStartIndex); - } - parserCurrentIndex++; - } - continue; - case 42: // *, check for unmatched */ - if ((parserCurrentIndex < len - 1) && (input.charCodeAt(parserCurrentIndex + 1) == 47)) { - return fail("unmatched `/*`"); - } - continue; - } - } - - if (level !== 0) { - if ((lastMultiComment > lastOpening) && (lastMultiCommentEndBrace > lastMultiComment)) { - return fail("missing closing `}` or `*/`", lastOpening); - } else { - return fail("missing closing `}`", lastOpening); - } - } else if (parenLevel !== 0) { - return fail("missing closing `)`", lastOpeningParen); - } - - emitChunk(true); - return chunks; - })(str); - - if (error) { - return callback(new(LessError)(error, env)); - } - - current = chunks[0]; - - // Start with the primary rule. - // The whole syntax tree is held under a Ruleset node, - // with the `root` property set to true, so no `{}` are - // output. The callback is called when the input is parsed. - try { - root = new(tree.Ruleset)(null, this.parsers.primary()); - root.root = true; - root.firstRoot = true; - } catch (e) { - return callback(new(LessError)(e, env)); - } - - root.toCSS = (function (evaluate) { - return function (options, variables) { - options = options || {}; - var evaldRoot, - css, - evalEnv = new tree.evalEnv(options); - - // - // Allows setting variables with a hash, so: - // - // `{ color: new(tree.Color)('#f01') }` will become: - // - // new(tree.Rule)('@color', - // new(tree.Value)([ - // new(tree.Expression)([ - // new(tree.Color)('#f01') - // ]) - // ]) - // ) - // - if (typeof(variables) === 'object' && !Array.isArray(variables)) { - variables = Object.keys(variables).map(function (k) { - var value = variables[k]; - - if (! (value instanceof tree.Value)) { - if (! (value instanceof tree.Expression)) { - value = new(tree.Expression)([value]); - } - value = new(tree.Value)([value]); - } - return new(tree.Rule)('@' + k, value, false, null, 0); - }); - evalEnv.frames = [new(tree.Ruleset)(null, variables)]; - } - - try { - var preEvalVisitors = [], - visitors = [ - new(tree.joinSelectorVisitor)(), - new(tree.processExtendsVisitor)(), - new(tree.toCSSVisitor)({compress: Boolean(options.compress)}) - ], i, root = this; - - if (options.plugins) { - for(i =0; i < options.plugins.length; i++) { - if (options.plugins[i].isPreEvalVisitor) { - preEvalVisitors.push(options.plugins[i]); - } else { - if (options.plugins[i].isPreVisitor) { - visitors.splice(0, 0, options.plugins[i]); - } else { - visitors.push(options.plugins[i]); - } - } - } - } - - for(i = 0; i < preEvalVisitors.length; i++) { - preEvalVisitors[i].run(root); - } - - evaldRoot = evaluate.call(root, evalEnv); - - for(i = 0; i < visitors.length; i++) { - visitors[i].run(evaldRoot); - } - - if (options.sourceMap) { - evaldRoot = new tree.sourceMapOutput( - { - contentsIgnoredCharsMap: parser.imports.contentsIgnoredChars, - writeSourceMap: options.writeSourceMap, - rootNode: evaldRoot, - contentsMap: parser.imports.contents, - sourceMapFilename: options.sourceMapFilename, - sourceMapURL: options.sourceMapURL, - outputFilename: options.sourceMapOutputFilename, - sourceMapBasepath: options.sourceMapBasepath, - sourceMapRootpath: options.sourceMapRootpath, - outputSourceFiles: options.outputSourceFiles, - sourceMapGenerator: options.sourceMapGenerator - }); - } - - css = evaldRoot.toCSS({ - compress: Boolean(options.compress), - dumpLineNumbers: env.dumpLineNumbers, - strictUnits: Boolean(options.strictUnits), - numPrecision: 8}); - } catch (e) { - throw new(LessError)(e, env); - } - - if (options.cleancss && less.mode === 'node') { - var CleanCSS = require('clean-css'), - cleancssOptions = options.cleancssOptions || {}; - - if (cleancssOptions.keepSpecialComments === undefined) { - cleancssOptions.keepSpecialComments = "*"; - } - cleancssOptions.processImport = false; - cleancssOptions.noRebase = true; - if (cleancssOptions.noAdvanced === undefined) { - cleancssOptions.noAdvanced = true; - } - - return new CleanCSS(cleancssOptions).minify(css); - } else if (options.compress) { - return css.replace(/(^(\s)+)|((\s)+$)/g, ""); - } else { - return css; - } - }; - })(root.eval); - - // If `i` is smaller than the `input.length - 1`, - // it means the parser wasn't able to parse the whole - // string, so we've got a parsing error. - // - // We try to extract a \n delimited string, - // showing the line where the parse error occured. - // We split it up into two parts (the part which parsed, - // and the part which didn't), so we can color them differently. - if (i < input.length - 1) { - i = furthest; - var loc = getLocation(i, input); - lines = input.split('\n'); - line = loc.line + 1; - - error = { - type: "Parse", - message: "Unrecognised input", - index: i, - filename: env.currentFileInfo.filename, - line: line, - column: loc.column, - extract: [ - lines[line - 2], - lines[line - 1], - lines[line] - ] - }; - } - - var finish = function (e) { - e = error || e || parser.imports.error; - - if (e) { - if (!(e instanceof LessError)) { - e = new(LessError)(e, env); - } - - return callback(e); - } - else { - return callback(null, root); - } - }; - - if (env.processImports !== false) { - new tree.importVisitor(this.imports, finish) - .run(root); - } else { - return finish(); - } - }, - - // - // Here in, the parsing rules/functions - // - // The basic structure of the syntax tree generated is as follows: - // - // Ruleset -> Rule -> Value -> Expression -> Entity - // - // Here's some LESS code: - // - // .class { - // color: #fff; - // border: 1px solid #000; - // width: @w + 4px; - // > .child {...} - // } - // - // And here's what the parse tree might look like: - // - // Ruleset (Selector '.class', [ - // Rule ("color", Value ([Expression [Color #fff]])) - // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]])) - // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]])) - // Ruleset (Selector [Element '>', '.child'], [...]) - // ]) - // - // In general, most rules will try to parse a token with the `$()` function, and if the return - // value is truly, will return a new node, of the relevant type. Sometimes, we need to check - // first, before parsing, that's when we use `peek()`. - // - parsers: parsers = { - // - // The `primary` rule is the *entry* and *exit* point of the parser. - // The rules here can appear at any level of the parse tree. - // - // The recursive nature of the grammar is an interplay between the `block` - // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule, - // as represented by this simplified grammar: - // - // primary → (ruleset | rule)+ - // ruleset → selector+ block - // block → '{' primary '}' - // - // Only at one point is the primary rule not called from the - // block rule: at the root level. - // - primary: function () { - var mixin = this.mixin, $re = _$re, root = [], node; - - while (current) - { - node = this.extendRule() || mixin.definition() || this.rule() || this.ruleset() || - mixin.call() || this.comment() || this.directive(); - if (node) { - root.push(node); - } else { - if (!($re(/^[\s\n]+/) || $re(/^;+/))) { - break; - } - } - } - - return root; - }, - - // We create a Comment node for CSS comments `/* */`, - // but keep the LeSS comments `//` silent, by just skipping - // over them. - comment: function () { - var comment; - - if (input.charAt(i) !== '/') { return; } - - if (input.charAt(i + 1) === '/') { - return new(tree.Comment)($re(/^\/\/.*/), true, i, env.currentFileInfo); - } - comment = $re(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/); - if (comment) { - return new(tree.Comment)(comment, false, i, env.currentFileInfo); - } - }, - - comments: function () { - var comment, comments = []; - - while(true) { - comment = this.comment(); - if (!comment) { - break; - } - comments.push(comment); - } - - return comments; - }, - - // - // Entities are tokens which can be found inside an Expression - // - entities: { - // - // A string, which supports escaping " and ' - // - // "milky way" 'he\'s the one!' - // - quoted: function () { - var str, j = i, e, index = i; - - if (input.charAt(j) === '~') { j++; e = true; } // Escaped strings - if (input.charAt(j) !== '"' && input.charAt(j) !== "'") { return; } - - if (e) { $char('~'); } - - str = $re(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/); - if (str) { - return new(tree.Quoted)(str[0], str[1] || str[2], e, index, env.currentFileInfo); - } - }, - - // - // A catch-all word, such as: - // - // black border-collapse - // - keyword: function () { - var k; - - k = $re(/^[_A-Za-z-][_A-Za-z0-9-]*/); - if (k) { - var color = tree.Color.fromKeyword(k); - if (color) { - return color; - } - return new(tree.Keyword)(k); - } - }, - - // - // A function call - // - // rgb(255, 0, 255) - // - // We also try to catch IE's `alpha()`, but let the `alpha` parser - // deal with the details. - // - // The arguments are parsed with the `entities.arguments` parser. - // - call: function () { - var name, nameLC, args, alpha_ret, index = i; - - name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(current); - if (!name) { return; } - - name = name[1]; - nameLC = name.toLowerCase(); - if (nameLC === 'url') { - return null; - } - - i += name.length; - - if (nameLC === 'alpha') { - alpha_ret = parsers.alpha(); - if(typeof alpha_ret !== 'undefined') { - return alpha_ret; - } - } - - $char('('); // Parse the '(' and consume whitespace. - - args = this.arguments(); - - if (! $char(')')) { - return; - } - - if (name) { return new(tree.Call)(name, args, index, env.currentFileInfo); } - }, - arguments: function () { - var args = [], arg; - - while (true) { - arg = this.assignment() || parsers.expression(); - if (!arg) { - break; - } - args.push(arg); - if (! $char(',')) { - break; - } - } - return args; - }, - literal: function () { - return this.dimension() || - this.color() || - this.quoted() || - this.unicodeDescriptor(); - }, - - // Assignments are argument entities for calls. - // They are present in ie filter properties as shown below. - // - // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* ) - // - - assignment: function () { - var key, value; - key = $re(/^\w+(?=\s?=)/i); - if (!key) { - return; - } - if (!$char('=')) { - return; - } - value = parsers.entity(); - if (value) { - return new(tree.Assignment)(key, value); - } - }, - - // - // Parse url() tokens - // - // We use a specific rule for urls, because they don't really behave like - // standard function calls. The difference is that the argument doesn't have - // to be enclosed within a string, so it can't be parsed as an Expression. - // - url: function () { - var value; - - if (input.charAt(i) !== 'u' || !$re(/^url\(/)) { - return; - } - - value = this.quoted() || this.variable() || - $re(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || ""; - - expectChar(')'); - - return new(tree.URL)((value.value != null || value instanceof tree.Variable) - ? value : new(tree.Anonymous)(value), env.currentFileInfo); - }, - - // - // A Variable entity, such as `@fink`, in - // - // width: @fink + 2px - // - // We use a different parser for variable definitions, - // see `parsers.variable`. - // - variable: function () { - var name, index = i; - - if (input.charAt(i) === '@' && (name = $re(/^@@?[\w-]+/))) { - return new(tree.Variable)(name, index, env.currentFileInfo); - } - }, - - // A variable entity useing the protective {} e.g. @{var} - variableCurly: function () { - var curly, index = i; - - if (input.charAt(i) === '@' && (curly = $re(/^@\{([\w-]+)\}/))) { - return new(tree.Variable)("@" + curly[1], index, env.currentFileInfo); - } - }, - - // - // A Hexadecimal color - // - // #4F3C2F - // - // `rgb` and `hsl` colors are parsed through the `entities.call` parser. - // - color: function () { - var rgb; - - if (input.charAt(i) === '#' && (rgb = $re(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/))) { - return new(tree.Color)(rgb[1]); - } - }, - - // - // A Dimension, that is, a number and a unit - // - // 0.5em 95% - // - dimension: function () { - var value, c = input.charCodeAt(i); - //Is the first char of the dimension 0-9, '.', '+' or '-' - if ((c > 57 || c < 43) || c === 47 || c == 44) { - return; - } - - value = $re(/^([+-]?\d*\.?\d+)(%|[a-z]+)?/); - if (value) { - return new(tree.Dimension)(value[1], value[2]); - } - }, - - // - // A unicode descriptor, as is used in unicode-range - // - // U+0?? or U+00A1-00A9 - // - unicodeDescriptor: function () { - var ud; - - ud = $re(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/); - if (ud) { - return new(tree.UnicodeDescriptor)(ud[0]); - } - }, - - // - // JavaScript code to be evaluated - // - // `window.location.href` - // - javascript: function () { - var str, j = i, e; - - if (input.charAt(j) === '~') { j++; e = true; } // Escaped strings - if (input.charAt(j) !== '`') { return; } - if (env.javascriptEnabled !== undefined && !env.javascriptEnabled) { - error("You are using JavaScript, which has been disabled."); - } - - if (e) { $char('~'); } - - str = $re(/^`([^`]*)`/); - if (str) { - return new(tree.JavaScript)(str[1], i, e); - } - } - }, - - // - // The variable part of a variable definition. Used in the `rule` parser - // - // @fink: - // - variable: function () { - var name; - - if (input.charAt(i) === '@' && (name = $re(/^(@[\w-]+)\s*:/))) { return name[1]; } - }, - - // - // extend syntax - used to extend selectors - // - extend: function(isRule) { - var elements, e, index = i, option, extendList, extend; - - if (!(isRule ? $re(/^&:extend\(/) : $re(/^:extend\(/))) { return; } - - do { - option = null; - elements = null; - while (! (option = $re(/^(all)(?=\s*(\)|,))/))) { - e = this.element(); - if (!e) { break; } - if (elements) { elements.push(e); } else { elements = [ e ]; } - } - - option = option && option[1]; - - extend = new(tree.Extend)(new(tree.Selector)(elements), option, index); - if (extendList) { extendList.push(extend); } else { extendList = [ extend ]; } - - } while($char(",")); - - expect(/^\)/); - - if (isRule) { - expect(/^;/); - } - - return extendList; - }, - - // - // extendRule - used in a rule to extend all the parent selectors - // - extendRule: function() { - return this.extend(true); - }, - - // - // Mixins - // - mixin: { - // - // A Mixin call, with an optional argument list - // - // #mixins > .square(#fff); - // .rounded(4px, black); - // .button; - // - // The `while` loop is there because mixins can be - // namespaced, but we only support the child and descendant - // selector for now. - // - call: function () { - var s = input.charAt(i), important = false, index = i, elemIndex, - elements, elem, e, c, args; - - if (s !== '.' && s !== '#') { return; } - - save(); // stop us absorbing part of an invalid selector - - while (true) { - elemIndex = i; - e = $re(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/); - if (!e) { - break; - } - elem = new(tree.Element)(c, e, elemIndex, env.currentFileInfo); - if (elements) { elements.push(elem); } else { elements = [ elem ]; } - c = $char('>'); - } - - if (elements) { - if ($char('(')) { - args = this.args(true).args; - expectChar(')'); - } - - if (parsers.important()) { - important = true; - } - - if (parsers.end()) { - return new(tree.mixin.Call)(elements, args, index, env.currentFileInfo, important); - } - } - - restore(); - }, - args: function (isCall) { - var parsers = parser.parsers, entities = parsers.entities, - returner = { args:null, variadic: false }, - expressions = [], argsSemiColon = [], argsComma = [], - isSemiColonSeperated, expressionContainsNamed, name, nameLoop, value, arg; - - while (true) { - if (isCall) { - arg = parsers.expression(); - } else { - parsers.comments(); - if (input.charAt(i) === '.' && $re(/^\.{3}/)) { - returner.variadic = true; - if ($char(";") && !isSemiColonSeperated) { - isSemiColonSeperated = true; - } - (isSemiColonSeperated ? argsSemiColon : argsComma) - .push({ variadic: true }); - break; - } - arg = entities.variable() || entities.literal() || entities.keyword(); - } - - if (!arg) { - break; - } - - nameLoop = null; - if (arg.throwAwayComments) { - arg.throwAwayComments(); - } - value = arg; - var val = null; - - if (isCall) { - // Variable - if (arg.value.length == 1) { - val = arg.value[0]; - } - } else { - val = arg; - } - - if (val && val instanceof tree.Variable) { - if ($char(':')) { - if (expressions.length > 0) { - if (isSemiColonSeperated) { - error("Cannot mix ; and , as delimiter types"); - } - expressionContainsNamed = true; - } - value = expect(parsers.expression); - nameLoop = (name = val.name); - } else if (!isCall && $re(/^\.{3}/)) { - returner.variadic = true; - if ($char(";") && !isSemiColonSeperated) { - isSemiColonSeperated = true; - } - (isSemiColonSeperated ? argsSemiColon : argsComma) - .push({ name: arg.name, variadic: true }); - break; - } else if (!isCall) { - name = nameLoop = val.name; - value = null; - } - } - - if (value) { - expressions.push(value); - } - - argsComma.push({ name:nameLoop, value:value }); - - if ($char(',')) { - continue; - } - - if ($char(';') || isSemiColonSeperated) { - - if (expressionContainsNamed) { - error("Cannot mix ; and , as delimiter types"); - } - - isSemiColonSeperated = true; - - if (expressions.length > 1) { - value = new(tree.Value)(expressions); - } - argsSemiColon.push({ name:name, value:value }); - - name = null; - expressions = []; - expressionContainsNamed = false; - } - } - - returner.args = isSemiColonSeperated ? argsSemiColon : argsComma; - return returner; - }, - // - // A Mixin definition, with a list of parameters - // - // .rounded (@radius: 2px, @color) { - // ... - // } - // - // Until we have a finer grained state-machine, we have to - // do a look-ahead, to make sure we don't have a mixin call. - // See the `rule` function for more information. - // - // We start by matching `.rounded (`, and then proceed on to - // the argument list, which has optional default values. - // We store the parameters in `params`, with a `value` key, - // if there is a value, such as in the case of `@radius`. - // - // Once we've got our params list, and a closing `)`, we parse - // the `{...}` block. - // - definition: function () { - var name, params = [], match, ruleset, cond, variadic = false; - if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') || - peek(/^[^{]*\}/)) { - return; - } - - save(); - - match = $re(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/); - if (match) { - name = match[1]; - - var argInfo = this.args(false); - params = argInfo.args; - variadic = argInfo.variadic; - - // .mixincall("@{a}"); - // looks a bit like a mixin definition.. so we have to be nice and restore - if (!$char(')')) { - furthest = i; - restore(); - } - - parsers.comments(); - - if ($re(/^when/)) { // Guard - cond = expect(parsers.conditions, 'expected condition'); - } - - ruleset = parsers.block(); - - if (ruleset) { - return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic); - } else { - restore(); - } - } - } - }, - - // - // Entities are the smallest recognized token, - // and can be found inside a rule's value. - // - entity: function () { - var entities = this.entities; - - return entities.literal() || entities.variable() || entities.url() || - entities.call() || entities.keyword() || entities.javascript() || - this.comment(); - }, - - // - // A Rule terminator. Note that we use `peek()` to check for '}', - // because the `block` rule will be expecting it, but we still need to make sure - // it's there, if ';' was ommitted. - // - end: function () { - return $char(';') || peekChar('}'); - }, - - // - // IE's alpha function - // - // alpha(opacity=88) - // - alpha: function () { - var value; - - if (! $re(/^\(opacity=/i)) { return; } - value = $re(/^\d+/) || this.entities.variable(); - if (value) { - expectChar(')'); - return new(tree.Alpha)(value); - } - }, - - // - // A Selector Element - // - // div - // + h1 - // #socks - // input[type="text"] - // - // Elements are the building blocks for Selectors, - // they are made out of a `Combinator` (see combinator rule), - // and an element name, such as a tag a class, or `*`. - // - element: function () { - var e, c, v, index = i; - - c = this.combinator(); - - e = $re(/^(?:\d+\.\d+|\d+)%/) || $re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) || - $char('*') || $char('&') || this.attribute() || $re(/^\([^()@]+\)/) || $re(/^[\.#](?=@)/) || - this.entities.variableCurly(); - - if (! e) { - if ($char('(')) { - if ((v = this.selector()) && $char(')')) { - e = new(tree.Paren)(v); - } - } - } - - if (e) { return new(tree.Element)(c, e, index, env.currentFileInfo); } - }, - - // - // Combinators combine elements together, in a Selector. - // - // Because our parser isn't white-space sensitive, special care - // has to be taken, when parsing the descendant combinator, ` `, - // as it's an empty space. We have to check the previous character - // in the input, to see if it's a ` ` character. More info on how - // we deal with this in *combinator.js*. - // - combinator: function () { - var c = input.charAt(i); - - if (c === '>' || c === '+' || c === '~' || c === '|' || c === '^') { - i++; - if (input.charAt(i) === '^') { - c = '^^'; - i++; - } - while (isWhitespace(input, i)) { i++; } - return new(tree.Combinator)(c); - } else if (isWhitespace(input, i - 1)) { - return new(tree.Combinator)(" "); - } else { - return new(tree.Combinator)(null); - } - }, - // - // A CSS selector (see selector below) - // with less extensions e.g. the ability to extend and guard - // - lessSelector: function () { - return this.selector(true); - }, - // - // A CSS Selector - // - // .class > div + h1 - // li a:hover - // - // Selectors are made out of one or more Elements, see above. - // - selector: function (isLess) { - var index = i, $re = _$re, elements, extendList, c, e, extend, when, condition; - - while ((isLess && (extend = this.extend())) || (isLess && (when = $re(/^when/))) || (e = this.element())) { - if (when) { - condition = expect(this.conditions, 'expected condition'); - } else if (condition) { - error("CSS guard can only be used at the end of selector"); - } else if (extend) { - if (extendList) { extendList.push(extend); } else { extendList = [ extend ]; } - } else { - if (extendList) { error("Extend can only be used at the end of selector"); } - c = input.charAt(i); - if (elements) { elements.push(e); } else { elements = [ e ]; } - e = null; - } - if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') { - break; - } - } - - if (elements) { return new(tree.Selector)(elements, extendList, condition, index, env.currentFileInfo); } - if (extendList) { error("Extend must be used to extend a selector, it cannot be used on its own"); } - }, - attribute: function () { - if (! $char('[')) { return; } - - var entities = this.entities, - key, val, op; - - if (!(key = entities.variableCurly())) { - key = expect(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/); - } - - op = $re(/^[|~*$^]?=/); - if (op) { - val = entities.quoted() || $re(/^[0-9]+%/) || $re(/^[\w-]+/) || entities.variableCurly(); - } - - expectChar(']'); - - return new(tree.Attribute)(key, op, val); - }, - - // - // The `block` rule is used by `ruleset` and `mixin.definition`. - // It's a wrapper around the `primary` rule, with added `{}`. - // - block: function () { - var content; - if ($char('{') && (content = this.primary()) && $char('}')) { - return content; - } - }, - - // - // div, .class, body > p {...} - // - ruleset: function () { - var selectors, s, rules, debugInfo; - - save(); - - if (env.dumpLineNumbers) { - debugInfo = getDebugInfo(i, input, env); - } - - while (true) { - s = this.lessSelector(); - if (!s) { - break; - } - if (selectors) { selectors.push(s); } else { selectors = [ s ]; } - this.comments(); - if (s.condition && selectors.length > 1) { - error("Guards are only currently allowed on a single selector."); - } - if (! $char(',')) { break; } - if (s.condition) { - error("Guards are only currently allowed on a single selector."); - } - this.comments(); - } - - if (selectors && (rules = this.block())) { - var ruleset = new(tree.Ruleset)(selectors, rules, env.strictImports); - if (env.dumpLineNumbers) { - ruleset.debugInfo = debugInfo; - } - return ruleset; - } else { - // Backtrack - furthest = i; - restore(); - } - }, - rule: function (tryAnonymous) { - var name, value, c = input.charAt(i), important, merge = false; - save(); - - if (c === '.' || c === '#' || c === '&') { return; } - - name = this.variable() || this.ruleProperty(); - if (name) { - // prefer to try to parse first if its a variable or we are compressing - // but always fallback on the other one - value = !tryAnonymous && (env.compress || (name.charAt && (name.charAt(0) === '@'))) ? - (this.value() || this.anonymousValue()) : - (this.anonymousValue() || this.value()); - - important = this.important(); - - // a name returned by this.ruleProperty() is always an array of the form: - // [string-1, ..., string-n, ""] or [string-1, ..., string-n, "+"] - // where each item is a tree.Keyword or tree.Variable - merge = name.pop && (name.pop().value === "+"); - - if (value && this.end()) { - return new (tree.Rule)(name, value, important, merge, memo, env.currentFileInfo); - } else { - furthest = i; - restore(); - if (value && !tryAnonymous) { - return this.rule(true); - } - } - } - }, - anonymousValue: function () { - var match; - match = /^([^@+\/'"*`(;{}-]*);/.exec(current); - if (match) { - i += match[0].length - 1; - return new(tree.Anonymous)(match[1]); - } - }, - - // - // An @import directive - // - // @import "lib"; - // - // Depending on our environemnt, importing is done differently: - // In the browser, it's an XHR request, in Node, it would be a - // file-system operation. The function used for importing is - // stored in `import`, which we pass to the Import constructor. - // - "import": function () { - var path, features, index = i; - - save(); - - var dir = $re(/^@import?\s+/); - - var options = (dir ? this.importOptions() : null) || {}; - - if (dir && (path = this.entities.quoted() || this.entities.url())) { - features = this.mediaFeatures(); - if ($char(';')) { - features = features && new(tree.Value)(features); - return new(tree.Import)(path, features, options, index, env.currentFileInfo); - } - } - - restore(); - }, - - importOptions: function() { - var o, options = {}, optionName, value; - - // list of options, surrounded by parens - if (! $char('(')) { return null; } - do { - o = this.importOption(); - if (o) { - optionName = o; - value = true; - switch(optionName) { - case "css": - optionName = "less"; - value = false; - break; - case "once": - optionName = "multiple"; - value = false; - break; - } - options[optionName] = value; - if (! $char(',')) { break; } - } - } while (o); - expectChar(')'); - return options; - }, - - importOption: function() { - var opt = $re(/^(less|css|multiple|once|inline|reference)/); - if (opt) { - return opt[1]; - } - }, - - mediaFeature: function () { - var entities = this.entities, nodes = [], e, p; - do { - e = entities.keyword() || entities.variable(); - if (e) { - nodes.push(e); - } else if ($char('(')) { - p = this.property(); - e = this.value(); - if ($char(')')) { - if (p && e) { - nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, null, i, env.currentFileInfo, true))); - } else if (e) { - nodes.push(new(tree.Paren)(e)); - } else { - return null; - } - } else { return null; } - } - } while (e); - - if (nodes.length > 0) { - return new(tree.Expression)(nodes); - } - }, - - mediaFeatures: function () { - var entities = this.entities, features = [], e; - do { - e = this.mediaFeature(); - if (e) { - features.push(e); - if (! $char(',')) { break; } - } else { - e = entities.variable(); - if (e) { - features.push(e); - if (! $char(',')) { break; } - } - } - } while (e); - - return features.length > 0 ? features : null; - }, - - media: function () { - var features, rules, media, debugInfo; - - if (env.dumpLineNumbers) { - debugInfo = getDebugInfo(i, input, env); - } - - if ($re(/^@media/)) { - features = this.mediaFeatures(); - - rules = this.block(); - if (rules) { - media = new(tree.Media)(rules, features, i, env.currentFileInfo); - if (env.dumpLineNumbers) { - media.debugInfo = debugInfo; - } - return media; - } - } - }, - - // - // A CSS Directive - // - // @charset "utf-8"; - // - directive: function () { - var index = i, name, value, rules, nonVendorSpecificName, - hasBlock, hasIdentifier, hasExpression, identifier; - - if (input.charAt(i) !== '@') { return; } - - value = this['import']() || this.media(); - if (value) { - return value; - } - - save(); - - name = $re(/^@[a-z-]+/); - - if (!name) { return; } - - nonVendorSpecificName = name; - if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) { - nonVendorSpecificName = "@" + name.slice(name.indexOf('-', 2) + 1); - } - - switch(nonVendorSpecificName) { - case "@font-face": - hasBlock = true; - break; - case "@viewport": - case "@top-left": - case "@top-left-corner": - case "@top-center": - case "@top-right": - case "@top-right-corner": - case "@bottom-left": - case "@bottom-left-corner": - case "@bottom-center": - case "@bottom-right": - case "@bottom-right-corner": - case "@left-top": - case "@left-middle": - case "@left-bottom": - case "@right-top": - case "@right-middle": - case "@right-bottom": - hasBlock = true; - break; - case "@host": - case "@page": - case "@document": - case "@supports": - case "@keyframes": - hasBlock = true; - hasIdentifier = true; - break; - case "@namespace": - hasExpression = true; - break; - } - - if (hasIdentifier) { - identifier = ($re(/^[^{]+/) || '').trim(); - if (identifier) { - name += " " + identifier; - } - } - - if (hasBlock) { - rules = this.block(); - if (rules) { - return new(tree.Directive)(name, rules, index, env.currentFileInfo); - } - } else { - value = hasExpression ? this.expression() : this.entity(); - if (value && $char(';')) { - var directive = new(tree.Directive)(name, value, index, env.currentFileInfo); - if (env.dumpLineNumbers) { - directive.debugInfo = getDebugInfo(i, input, env); - } - return directive; - } - } - - restore(); - }, - - // - // A Value is a comma-delimited list of Expressions - // - // font-family: Baskerville, Georgia, serif; - // - // In a Rule, a Value represents everything after the `:`, - // and before the `;`. - // - value: function () { - var e, expressions = []; - - do { - e = this.expression(); - if (e) { - expressions.push(e); - if (! $char(',')) { break; } - } - } while(e); - - if (expressions.length > 0) { - return new(tree.Value)(expressions); - } - }, - important: function () { - if (input.charAt(i) === '!') { - return $re(/^! *important/); - } - }, - sub: function () { - var a, e; - - if ($char('(')) { - a = this.addition(); - if (a) { - e = new(tree.Expression)([a]); - expectChar(')'); - e.parens = true; - return e; - } - } - }, - multiplication: function () { - var m, a, op, operation, isSpaced; - m = this.operand(); - if (m) { - isSpaced = isWhitespace(input, i - 1); - while (true) { - if (peek(/^\/[*\/]/)) { - break; - } - op = $char('/') || $char('*'); - - if (!op) { break; } - - a = this.operand(); - - if (!a) { break; } - - m.parensInOp = true; - a.parensInOp = true; - operation = new(tree.Operation)(op, [operation || m, a], isSpaced); - isSpaced = isWhitespace(input, i - 1); - } - return operation || m; - } - }, - addition: function () { - var m, a, op, operation, isSpaced; - m = this.multiplication(); - if (m) { - isSpaced = isWhitespace(input, i - 1); - while (true) { - op = $re(/^[-+]\s+/) || (!isSpaced && ($char('+') || $char('-'))); - if (!op) { - break; - } - a = this.multiplication(); - if (!a) { - break; - } - - m.parensInOp = true; - a.parensInOp = true; - operation = new(tree.Operation)(op, [operation || m, a], isSpaced); - isSpaced = isWhitespace(input, i - 1); - } - return operation || m; - } - }, - conditions: function () { - var a, b, index = i, condition; - - a = this.condition(); - if (a) { - while (true) { - if (!peek(/^,\s*(not\s*)?\(/) || !$char(',')) { - break; - } - b = this.condition(); - if (!b) { - break; - } - condition = new(tree.Condition)('or', condition || a, b, index); - } - return condition || a; - } - }, - condition: function () { - var entities = this.entities, index = i, negate = false, - a, b, c, op; - - if ($re(/^not/)) { negate = true; } - expectChar('('); - a = this.addition() || entities.keyword() || entities.quoted(); - if (a) { - op = $re(/^(?:>=|<=|=<|[<=>])/); - if (op) { - b = this.addition() || entities.keyword() || entities.quoted(); - if (b) { - c = new(tree.Condition)(op, a, b, index, negate); - } else { - error('expected expression'); - } - } else { - c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate); - } - expectChar(')'); - return $re(/^and/) ? new(tree.Condition)('and', c, this.condition()) : c; - } - }, - - // - // An operand is anything that can be part of an operation, - // such as a Color, or a Variable - // - operand: function () { - var entities = this.entities, - p = input.charAt(i + 1), negate; - - if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $char('-'); } - var o = this.sub() || entities.dimension() || - entities.color() || entities.variable() || - entities.call(); - - if (negate) { - o.parensInOp = true; - o = new(tree.Negative)(o); - } - - return o; - }, - - // - // Expressions either represent mathematical operations, - // or white-space delimited Entities. - // - // 1px solid black - // @var * 2 - // - expression: function () { - var entities = [], e, delim; - - do { - e = this.addition() || this.entity(); - if (e) { - entities.push(e); - // operations do not allow keyword "/" dimension (e.g. small/20px) so we support that here - if (!peek(/^\/[\/*]/)) { - delim = $char('/'); - if (delim) { - entities.push(new(tree.Anonymous)(delim)); - } - } - } - } while (e); - if (entities.length > 0) { - return new(tree.Expression)(entities); - } - }, - property: function () { - var name = $re(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/); - if (name) { - return name[1]; - } - }, - ruleProperty: function () { - var c = current, name = [], index = [], length = 0, s, k; - - function match(re) { - var a = re.exec(c); - if (a) { - index.push(i + length); - length += a[0].length; - c = c.slice(a[1].length); - return name.push(a[1]); - } - } - - match(/^(\*?)/); - while (match(/^((?:[\w-]+)|(?:@\{[\w-]+\}))/)); // ! - if ((name.length > 1) && match(/^\s*(\+?)\s*:/)) { - // at last, we have the complete match now. move forward, - // convert name particles to tree objects and return: - skipWhitespace(length); - if (name[0] === '') { - name.shift(); - index.shift(); - } - for (k = 0; k < name.length; k++) { - s = name[k]; - name[k] = (s.charAt(0) !== '@') - ? new(tree.Keyword)(s) - : new(tree.Variable)('@' + s.slice(2, -1), - index[k], env.currentFileInfo); - } - return name; - } - } - } - }; - return parser; -}; -less.Parser.serializeVars = function(vars) { - var s = ''; - - for (var name in vars) { - if (Object.hasOwnProperty.call(vars, name)) { - var value = vars[name]; - s += ((name[0] === '@') ? '' : '@') + name +': '+ value + - ((('' + value).slice(-1) === ';') ? '' : ';'); - } - } - - return s; -}; - -(function (tree) { - -tree.functions = { - rgb: function (r, g, b) { - return this.rgba(r, g, b, 1.0); - }, - rgba: function (r, g, b, a) { - var rgb = [r, g, b].map(function (c) { return scaled(c, 255); }); - a = number(a); - return new(tree.Color)(rgb, a); - }, - hsl: function (h, s, l) { - return this.hsla(h, s, l, 1.0); - }, - hsla: function (h, s, l, a) { - function hue(h) { - h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h); - if (h * 6 < 1) { return m1 + (m2 - m1) * h * 6; } - else if (h * 2 < 1) { return m2; } - else if (h * 3 < 2) { return m1 + (m2 - m1) * (2/3 - h) * 6; } - else { return m1; } - } - - h = (number(h) % 360) / 360; - s = clamp(number(s)); l = clamp(number(l)); a = clamp(number(a)); - - var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s; - var m1 = l * 2 - m2; - - return this.rgba(hue(h + 1/3) * 255, - hue(h) * 255, - hue(h - 1/3) * 255, - a); - }, - - hsv: function(h, s, v) { - return this.hsva(h, s, v, 1.0); - }, - - hsva: function(h, s, v, a) { - h = ((number(h) % 360) / 360) * 360; - s = number(s); v = number(v); a = number(a); - - var i, f; - i = Math.floor((h / 60) % 6); - f = (h / 60) - i; - - var vs = [v, - v * (1 - s), - v * (1 - f * s), - v * (1 - (1 - f) * s)]; - var perm = [[0, 3, 1], - [2, 0, 1], - [1, 0, 3], - [1, 2, 0], - [3, 1, 0], - [0, 1, 2]]; - - return this.rgba(vs[perm[i][0]] * 255, - vs[perm[i][1]] * 255, - vs[perm[i][2]] * 255, - a); - }, - - hue: function (color) { - return new(tree.Dimension)(Math.round(color.toHSL().h)); - }, - saturation: function (color) { - return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%'); - }, - lightness: function (color) { - return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%'); - }, - hsvhue: function(color) { - return new(tree.Dimension)(Math.round(color.toHSV().h)); - }, - hsvsaturation: function (color) { - return new(tree.Dimension)(Math.round(color.toHSV().s * 100), '%'); - }, - hsvvalue: function (color) { - return new(tree.Dimension)(Math.round(color.toHSV().v * 100), '%'); - }, - red: function (color) { - return new(tree.Dimension)(color.rgb[0]); - }, - green: function (color) { - return new(tree.Dimension)(color.rgb[1]); - }, - blue: function (color) { - return new(tree.Dimension)(color.rgb[2]); - }, - alpha: function (color) { - return new(tree.Dimension)(color.toHSL().a); - }, - luma: function (color) { - return new(tree.Dimension)(Math.round(color.luma() * color.alpha * 100), '%'); - }, - saturate: function (color, amount) { - // filter: saturate(3.2); - // should be kept as is, so check for color - if (!color.rgb) { - return null; - } - var hsl = color.toHSL(); - - hsl.s += amount.value / 100; - hsl.s = clamp(hsl.s); - return hsla(hsl); - }, - desaturate: function (color, amount) { - var hsl = color.toHSL(); - - hsl.s -= amount.value / 100; - hsl.s = clamp(hsl.s); - return hsla(hsl); - }, - lighten: function (color, amount) { - var hsl = color.toHSL(); - - hsl.l += amount.value / 100; - hsl.l = clamp(hsl.l); - return hsla(hsl); - }, - darken: function (color, amount) { - var hsl = color.toHSL(); - - hsl.l -= amount.value / 100; - hsl.l = clamp(hsl.l); - return hsla(hsl); - }, - fadein: function (color, amount) { - var hsl = color.toHSL(); - - hsl.a += amount.value / 100; - hsl.a = clamp(hsl.a); - return hsla(hsl); - }, - fadeout: function (color, amount) { - var hsl = color.toHSL(); - - hsl.a -= amount.value / 100; - hsl.a = clamp(hsl.a); - return hsla(hsl); - }, - fade: function (color, amount) { - var hsl = color.toHSL(); - - hsl.a = amount.value / 100; - hsl.a = clamp(hsl.a); - return hsla(hsl); - }, - spin: function (color, amount) { - var hsl = color.toHSL(); - var hue = (hsl.h + amount.value) % 360; - - hsl.h = hue < 0 ? 360 + hue : hue; - - return hsla(hsl); - }, - // - // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein - // http://sass-lang.com - // - mix: function (color1, color2, weight) { - if (!weight) { - weight = new(tree.Dimension)(50); - } - var p = weight.value / 100.0; - var w = p * 2 - 1; - var a = color1.toHSL().a - color2.toHSL().a; - - var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0; - var w2 = 1 - w1; - - var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2, - color1.rgb[1] * w1 + color2.rgb[1] * w2, - color1.rgb[2] * w1 + color2.rgb[2] * w2]; - - var alpha = color1.alpha * p + color2.alpha * (1 - p); - - return new(tree.Color)(rgb, alpha); - }, - greyscale: function (color) { - return this.desaturate(color, new(tree.Dimension)(100)); - }, - contrast: function (color, dark, light, threshold) { - // filter: contrast(3.2); - // should be kept as is, so check for color - if (!color.rgb) { - return null; - } - if (typeof light === 'undefined') { - light = this.rgba(255, 255, 255, 1.0); - } - if (typeof dark === 'undefined') { - dark = this.rgba(0, 0, 0, 1.0); - } - //Figure out which is actually light and dark! - if (dark.luma() > light.luma()) { - var t = light; - light = dark; - dark = t; - } - if (typeof threshold === 'undefined') { - threshold = 0.43; - } else { - threshold = number(threshold); - } - if (color.luma() < threshold) { - return light; - } else { - return dark; - } - }, - e: function (str) { - return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str); - }, - escape: function (str) { - return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29")); - }, - '%': function (quoted /* arg, arg, ...*/) { - var args = Array.prototype.slice.call(arguments, 1), - str = quoted.value; - - for (var i = 0; i < args.length; i++) { - /*jshint loopfunc:true */ - str = str.replace(/%[sda]/i, function(token) { - var value = token.match(/s/i) ? args[i].value : args[i].toCSS(); - return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value; - }); - } - str = str.replace(/%%/g, '%'); - return new(tree.Quoted)('"' + str + '"', str); - }, - unit: function (val, unit) { - if(!(val instanceof tree.Dimension)) { - throw { type: "Argument", message: "the first argument to unit must be a number" + (val instanceof tree.Operation ? ". Have you forgotten parenthesis?" : "") }; - } - return new(tree.Dimension)(val.value, unit ? unit.toCSS() : ""); - }, - convert: function (val, unit) { - return val.convertTo(unit.value); - }, - round: function (n, f) { - var fraction = typeof(f) === "undefined" ? 0 : f.value; - return _math(function(num) { return num.toFixed(fraction); }, null, n); - }, - pi: function () { - return new(tree.Dimension)(Math.PI); - }, - mod: function(a, b) { - return new(tree.Dimension)(a.value % b.value, a.unit); - }, - pow: function(x, y) { - if (typeof x === "number" && typeof y === "number") { - x = new(tree.Dimension)(x); - y = new(tree.Dimension)(y); - } else if (!(x instanceof tree.Dimension) || !(y instanceof tree.Dimension)) { - throw { type: "Argument", message: "arguments must be numbers" }; - } - - return new(tree.Dimension)(Math.pow(x.value, y.value), x.unit); - }, - _minmax: function (isMin, args) { - args = Array.prototype.slice.call(args); - switch(args.length) { - case 0: throw { type: "Argument", message: "one or more arguments required" }; - case 1: return args[0]; - } - var i, j, current, currentUnified, referenceUnified, unit, - order = [], // elems only contains original argument values. - values = {}; // key is the unit.toString() for unified tree.Dimension values, - // value is the index into the order array. - for (i = 0; i < args.length; i++) { - current = args[i]; - if (!(current instanceof tree.Dimension)) { - order.push(current); - continue; - } - currentUnified = current.unify(); - unit = currentUnified.unit.toString(); - j = values[unit]; - if (j === undefined) { - values[unit] = order.length; - order.push(current); - continue; - } - referenceUnified = order[j].unify(); - if ( isMin && currentUnified.value < referenceUnified.value || - !isMin && currentUnified.value > referenceUnified.value) { - order[j] = current; - } - } - if (order.length == 1) { - return order[0]; - } - args = order.map(function (a) { return a.toCSS(this.env); }) - .join(this.env.compress ? "," : ", "); - return new(tree.Anonymous)((isMin ? "min" : "max") + "(" + args + ")"); - }, - min: function () { - return this._minmax(true, arguments); - }, - max: function () { - return this._minmax(false, arguments); - }, - argb: function (color) { - return new(tree.Anonymous)(color.toARGB()); - }, - percentage: function (n) { - return new(tree.Dimension)(n.value * 100, '%'); - }, - color: function (n) { - if (n instanceof tree.Quoted) { - var colorCandidate = n.value, - returnColor; - returnColor = tree.Color.fromKeyword(colorCandidate); - if (returnColor) { - return returnColor; - } - if (/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/.test(colorCandidate)) { - return new(tree.Color)(colorCandidate.slice(1)); - } - throw { type: "Argument", message: "argument must be a color keyword or 3/6 digit hex e.g. #FFF" }; - } else { - throw { type: "Argument", message: "argument must be a string" }; - } - }, - iscolor: function (n) { - return this._isa(n, tree.Color); - }, - isnumber: function (n) { - return this._isa(n, tree.Dimension); - }, - isstring: function (n) { - return this._isa(n, tree.Quoted); - }, - iskeyword: function (n) { - return this._isa(n, tree.Keyword); - }, - isurl: function (n) { - return this._isa(n, tree.URL); - }, - ispixel: function (n) { - return this.isunit(n, 'px'); - }, - ispercentage: function (n) { - return this.isunit(n, '%'); - }, - isem: function (n) { - return this.isunit(n, 'em'); - }, - isunit: function (n, unit) { - return (n instanceof tree.Dimension) && n.unit.is(unit.value || unit) ? tree.True : tree.False; - }, - _isa: function (n, Type) { - return (n instanceof Type) ? tree.True : tree.False; - }, - tint: function(color, amount) { - return this.mix(this.rgb(255,255,255), color, amount); - }, - shade: function(color, amount) { - return this.mix(this.rgb(0, 0, 0), color, amount); - }, - extract: function(values, index) { - index = index.value - 1; // (1-based index) - // handle non-array values as an array of length 1 - // return 'undefined' if index is invalid - return Array.isArray(values.value) - ? values.value[index] : Array(values)[index]; - }, - length: function(values) { - var n = Array.isArray(values.value) ? values.value.length : 1; - return new tree.Dimension(n); - }, - - "data-uri": function(mimetypeNode, filePathNode) { - - if (typeof window !== 'undefined') { - return new tree.URL(filePathNode || mimetypeNode, this.currentFileInfo).eval(this.env); - } - - var mimetype = mimetypeNode.value; - var filePath = (filePathNode && filePathNode.value); - - var fs = require('fs'), - path = require('path'), - useBase64 = false; - - if (arguments.length < 2) { - filePath = mimetype; - } - - if (this.env.isPathRelative(filePath)) { - if (this.currentFileInfo.relativeUrls) { - filePath = path.join(this.currentFileInfo.currentDirectory, filePath); - } else { - filePath = path.join(this.currentFileInfo.entryPath, filePath); - } - } - - // detect the mimetype if not given - if (arguments.length < 2) { - var mime; - try { - mime = require('mime'); - } catch (ex) { - mime = tree._mime; - } - - mimetype = mime.lookup(filePath); - - // use base 64 unless it's an ASCII or UTF-8 format - var charset = mime.charsets.lookup(mimetype); - useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0; - if (useBase64) { mimetype += ';base64'; } - } - else { - useBase64 = /;base64$/.test(mimetype); - } - - var buf = fs.readFileSync(filePath); - - // IE8 cannot handle a data-uri larger than 32KB. If this is exceeded - // and the --ieCompat flag is enabled, return a normal url() instead. - var DATA_URI_MAX_KB = 32, - fileSizeInKB = parseInt((buf.length / 1024), 10); - if (fileSizeInKB >= DATA_URI_MAX_KB) { - - if (this.env.ieCompat !== false) { - if (!this.env.silent) { - console.warn("Skipped data-uri embedding of %s because its size (%dKB) exceeds IE8-safe %dKB!", filePath, fileSizeInKB, DATA_URI_MAX_KB); - } - - return new tree.URL(filePathNode || mimetypeNode, this.currentFileInfo).eval(this.env); - } - } - - buf = useBase64 ? buf.toString('base64') - : encodeURIComponent(buf); - - var uri = "\"data:" + mimetype + ',' + buf + "\""; - return new(tree.URL)(new(tree.Anonymous)(uri)); - }, - - "svg-gradient": function(direction) { - - function throwArgumentDescriptor() { - throw { type: "Argument", message: "svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position]" }; - } - - if (arguments.length < 3) { - throwArgumentDescriptor(); - } - var stops = Array.prototype.slice.call(arguments, 1), - gradientDirectionSvg, - gradientType = "linear", - rectangleDimension = 'x="0" y="0" width="1" height="1"', - useBase64 = true, - renderEnv = {compress: false}, - returner, - directionValue = direction.toCSS(renderEnv), - i, color, position, positionValue, alpha; - - switch (directionValue) { - case "to bottom": - gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"'; - break; - case "to right": - gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="0%"'; - break; - case "to bottom right": - gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="100%"'; - break; - case "to top right": - gradientDirectionSvg = 'x1="0%" y1="100%" x2="100%" y2="0%"'; - break; - case "ellipse": - case "ellipse at center": - gradientType = "radial"; - gradientDirectionSvg = 'cx="50%" cy="50%" r="75%"'; - rectangleDimension = 'x="-50" y="-50" width="101" height="101"'; - break; - default: - throw { type: "Argument", message: "svg-gradient direction must be 'to bottom', 'to right', 'to bottom right', 'to top right' or 'ellipse at center'" }; - } - returner = '' + - '' + - '<' + gradientType + 'Gradient id="gradient" gradientUnits="userSpaceOnUse" ' + gradientDirectionSvg + '>'; - - for (i = 0; i < stops.length; i+= 1) { - if (stops[i].value) { - color = stops[i].value[0]; - position = stops[i].value[1]; - } else { - color = stops[i]; - position = undefined; - } - - if (!(color instanceof tree.Color) || (!((i === 0 || i+1 === stops.length) && position === undefined) && !(position instanceof tree.Dimension))) { - throwArgumentDescriptor(); - } - positionValue = position ? position.toCSS(renderEnv) : i === 0 ? "0%" : "100%"; - alpha = color.alpha; - returner += ''; - } - returner += '' + - ''; - - if (useBase64) { - try { - returner = require('./encoder').encodeBase64(returner); // TODO browser implementation - } catch(e) { - useBase64 = false; - } - } - - returner = "'data:image/svg+xml" + (useBase64 ? ";base64" : "") + "," + returner + "'"; - return new(tree.URL)(new(tree.Anonymous)(returner)); - } -}; - -// these static methods are used as a fallback when the optional 'mime' dependency is missing -tree._mime = { - // this map is intentionally incomplete - // if you want more, install 'mime' dep - _types: { - '.htm' : 'text/html', - '.html': 'text/html', - '.gif' : 'image/gif', - '.jpg' : 'image/jpeg', - '.jpeg': 'image/jpeg', - '.png' : 'image/png' - }, - lookup: function (filepath) { - var ext = require('path').extname(filepath), - type = tree._mime._types[ext]; - if (type === undefined) { - throw new Error('Optional dependency "mime" is required for ' + ext); - } - return type; - }, - charsets: { - lookup: function (type) { - // assumes all text types are UTF-8 - return type && (/^text\//).test(type) ? 'UTF-8' : ''; - } - } -}; - -// Math - -var mathFunctions = { - // name, unit - ceil: null, - floor: null, - sqrt: null, - abs: null, - tan: "", - sin: "", - cos: "", - atan: "rad", - asin: "rad", - acos: "rad" -}; - -function _math(fn, unit, n) { - if (!(n instanceof tree.Dimension)) { - throw { type: "Argument", message: "argument must be a number" }; - } - if (unit == null) { - unit = n.unit; - } else { - n = n.unify(); - } - return new(tree.Dimension)(fn(parseFloat(n.value)), unit); -} - -// ~ End of Math - -// Color Blending -// ref: http://www.w3.org/TR/compositing-1 - -function colorBlend(mode, color1, color2) { - var ab = color1.alpha, cb, // backdrop - as = color2.alpha, cs, // source - ar, cr, r = []; // result - - ar = as + ab * (1 - as); - for (var i = 0; i < 3; i++) { - cb = color1.rgb[i] / 255; - cs = color2.rgb[i] / 255; - cr = mode(cb, cs); - if (ar) { - cr = (as * cs + ab * (cb - - as * (cb + cs - cr))) / ar; - } - r[i] = cr * 255; - } - - return new(tree.Color)(r, ar); -} - -var colorBlendMode = { - multiply: function(cb, cs) { - return cb * cs; - }, - screen: function(cb, cs) { - return cb + cs - cb * cs; - }, - overlay: function(cb, cs) { - cb *= 2; - return (cb <= 1) - ? colorBlendMode.multiply(cb, cs) - : colorBlendMode.screen(cb - 1, cs); - }, - softlight: function(cb, cs) { - var d = 1, e = cb; - if (cs > 0.5) { - e = 1; - d = (cb > 0.25) ? Math.sqrt(cb) - : ((16 * cb - 12) * cb + 4) * cb; - } - return cb - (1 - 2 * cs) * e * (d - cb); - }, - hardlight: function(cb, cs) { - return colorBlendMode.overlay(cs, cb); - }, - difference: function(cb, cs) { - return Math.abs(cb - cs); - }, - exclusion: function(cb, cs) { - return cb + cs - 2 * cb * cs; - }, - - // non-w3c functions: - average: function(cb, cs) { - return (cb + cs) / 2; - }, - negation: function(cb, cs) { - return 1 - Math.abs(cb + cs - 1); - } -}; - -// ~ End of Color Blending - -tree.defaultFunc = { - eval: function () { - var v = this.value_, e = this.error_; - if (e) { - throw e; - } - if (v != null) { - return v ? tree.True : tree.False; - } - }, - value: function (v) { - this.value_ = v; - }, - error: function (e) { - this.error_ = e; - }, - reset: function () { - this.value_ = this.error_ = null; - } -}; - -function initFunctions() { - var f, tf = tree.functions; - - // math - for (f in mathFunctions) { - if (mathFunctions.hasOwnProperty(f)) { - tf[f] = _math.bind(null, Math[f], mathFunctions[f]); - } - } - - // color blending - for (f in colorBlendMode) { - if (colorBlendMode.hasOwnProperty(f)) { - tf[f] = colorBlend.bind(null, colorBlendMode[f]); - } - } - - // default - f = tree.defaultFunc; - tf["default"] = f.eval.bind(f); - -} initFunctions(); - -function hsla(color) { - return tree.functions.hsla(color.h, color.s, color.l, color.a); -} - -function scaled(n, size) { - if (n instanceof tree.Dimension && n.unit.is('%')) { - return parseFloat(n.value * size / 100); - } else { - return number(n); - } -} - -function number(n) { - if (n instanceof tree.Dimension) { - return parseFloat(n.unit.is('%') ? n.value / 100 : n.value); - } else if (typeof(n) === 'number') { - return n; - } else { - throw { - error: "RuntimeError", - message: "color functions take numbers as parameters" - }; - } -} - -function clamp(val) { - return Math.min(1, Math.max(0, val)); -} - -tree.fround = function(env, value) { - var p; - if (env && (env.numPrecision != null)) { - p = Math.pow(10, env.numPrecision); - return Math.round(value * p) / p; - } else { - return value; - } -}; - -tree.functionCall = function(env, currentFileInfo) { - this.env = env; - this.currentFileInfo = currentFileInfo; -}; - -tree.functionCall.prototype = tree.functions; - -})(require('./tree')); - -(function (tree) { - tree.colors = { - 'aliceblue':'#f0f8ff', - 'antiquewhite':'#faebd7', - 'aqua':'#00ffff', - 'aquamarine':'#7fffd4', - 'azure':'#f0ffff', - 'beige':'#f5f5dc', - 'bisque':'#ffe4c4', - 'black':'#000000', - 'blanchedalmond':'#ffebcd', - 'blue':'#0000ff', - 'blueviolet':'#8a2be2', - 'brown':'#a52a2a', - 'burlywood':'#deb887', - 'cadetblue':'#5f9ea0', - 'chartreuse':'#7fff00', - 'chocolate':'#d2691e', - 'coral':'#ff7f50', - 'cornflowerblue':'#6495ed', - 'cornsilk':'#fff8dc', - 'crimson':'#dc143c', - 'cyan':'#00ffff', - 'darkblue':'#00008b', - 'darkcyan':'#008b8b', - 'darkgoldenrod':'#b8860b', - 'darkgray':'#a9a9a9', - 'darkgrey':'#a9a9a9', - 'darkgreen':'#006400', - 'darkkhaki':'#bdb76b', - 'darkmagenta':'#8b008b', - 'darkolivegreen':'#556b2f', - 'darkorange':'#ff8c00', - 'darkorchid':'#9932cc', - 'darkred':'#8b0000', - 'darksalmon':'#e9967a', - 'darkseagreen':'#8fbc8f', - 'darkslateblue':'#483d8b', - 'darkslategray':'#2f4f4f', - 'darkslategrey':'#2f4f4f', - 'darkturquoise':'#00ced1', - 'darkviolet':'#9400d3', - 'deeppink':'#ff1493', - 'deepskyblue':'#00bfff', - 'dimgray':'#696969', - 'dimgrey':'#696969', - 'dodgerblue':'#1e90ff', - 'firebrick':'#b22222', - 'floralwhite':'#fffaf0', - 'forestgreen':'#228b22', - 'fuchsia':'#ff00ff', - 'gainsboro':'#dcdcdc', - 'ghostwhite':'#f8f8ff', - 'gold':'#ffd700', - 'goldenrod':'#daa520', - 'gray':'#808080', - 'grey':'#808080', - 'green':'#008000', - 'greenyellow':'#adff2f', - 'honeydew':'#f0fff0', - 'hotpink':'#ff69b4', - 'indianred':'#cd5c5c', - 'indigo':'#4b0082', - 'ivory':'#fffff0', - 'khaki':'#f0e68c', - 'lavender':'#e6e6fa', - 'lavenderblush':'#fff0f5', - 'lawngreen':'#7cfc00', - 'lemonchiffon':'#fffacd', - 'lightblue':'#add8e6', - 'lightcoral':'#f08080', - 'lightcyan':'#e0ffff', - 'lightgoldenrodyellow':'#fafad2', - 'lightgray':'#d3d3d3', - 'lightgrey':'#d3d3d3', - 'lightgreen':'#90ee90', - 'lightpink':'#ffb6c1', - 'lightsalmon':'#ffa07a', - 'lightseagreen':'#20b2aa', - 'lightskyblue':'#87cefa', - 'lightslategray':'#778899', - 'lightslategrey':'#778899', - 'lightsteelblue':'#b0c4de', - 'lightyellow':'#ffffe0', - 'lime':'#00ff00', - 'limegreen':'#32cd32', - 'linen':'#faf0e6', - 'magenta':'#ff00ff', - 'maroon':'#800000', - 'mediumaquamarine':'#66cdaa', - 'mediumblue':'#0000cd', - 'mediumorchid':'#ba55d3', - 'mediumpurple':'#9370d8', - 'mediumseagreen':'#3cb371', - 'mediumslateblue':'#7b68ee', - 'mediumspringgreen':'#00fa9a', - 'mediumturquoise':'#48d1cc', - 'mediumvioletred':'#c71585', - 'midnightblue':'#191970', - 'mintcream':'#f5fffa', - 'mistyrose':'#ffe4e1', - 'moccasin':'#ffe4b5', - 'navajowhite':'#ffdead', - 'navy':'#000080', - 'oldlace':'#fdf5e6', - 'olive':'#808000', - 'olivedrab':'#6b8e23', - 'orange':'#ffa500', - 'orangered':'#ff4500', - 'orchid':'#da70d6', - 'palegoldenrod':'#eee8aa', - 'palegreen':'#98fb98', - 'paleturquoise':'#afeeee', - 'palevioletred':'#d87093', - 'papayawhip':'#ffefd5', - 'peachpuff':'#ffdab9', - 'peru':'#cd853f', - 'pink':'#ffc0cb', - 'plum':'#dda0dd', - 'powderblue':'#b0e0e6', - 'purple':'#800080', - 'red':'#ff0000', - 'rosybrown':'#bc8f8f', - 'royalblue':'#4169e1', - 'saddlebrown':'#8b4513', - 'salmon':'#fa8072', - 'sandybrown':'#f4a460', - 'seagreen':'#2e8b57', - 'seashell':'#fff5ee', - 'sienna':'#a0522d', - 'silver':'#c0c0c0', - 'skyblue':'#87ceeb', - 'slateblue':'#6a5acd', - 'slategray':'#708090', - 'slategrey':'#708090', - 'snow':'#fffafa', - 'springgreen':'#00ff7f', - 'steelblue':'#4682b4', - 'tan':'#d2b48c', - 'teal':'#008080', - 'thistle':'#d8bfd8', - 'tomato':'#ff6347', - 'turquoise':'#40e0d0', - 'violet':'#ee82ee', - 'wheat':'#f5deb3', - 'white':'#ffffff', - 'whitesmoke':'#f5f5f5', - 'yellow':'#ffff00', - 'yellowgreen':'#9acd32' - }; -})(require('./tree')); - -(function (tree) { - -tree.debugInfo = function(env, ctx, lineSeperator) { - var result=""; - if (env.dumpLineNumbers && !env.compress) { - switch(env.dumpLineNumbers) { - case 'comments': - result = tree.debugInfo.asComment(ctx); - break; - case 'mediaquery': - result = tree.debugInfo.asMediaQuery(ctx); - break; - case 'all': - result = tree.debugInfo.asComment(ctx) + (lineSeperator || "") + tree.debugInfo.asMediaQuery(ctx); - break; - } - } - return result; -}; - -tree.debugInfo.asComment = function(ctx) { - return '/* line ' + ctx.debugInfo.lineNumber + ', ' + ctx.debugInfo.fileName + ' */\n'; -}; - -tree.debugInfo.asMediaQuery = function(ctx) { - return '@media -sass-debug-info{filename{font-family:' + - ('file://' + ctx.debugInfo.fileName).replace(/([.:\/\\])/g, function (a) { - if (a == '\\') { - a = '\/'; - } - return '\\' + a; - }) + - '}line{font-family:\\00003' + ctx.debugInfo.lineNumber + '}}\n'; -}; - -tree.find = function (obj, fun) { - for (var i = 0, r; i < obj.length; i++) { - r = fun.call(obj, obj[i]); - if (r) { return r; } - } - return null; -}; - -tree.jsify = function (obj) { - if (Array.isArray(obj.value) && (obj.value.length > 1)) { - return '[' + obj.value.map(function (v) { return v.toCSS(false); }).join(', ') + ']'; - } else { - return obj.toCSS(false); - } -}; - -tree.toCSS = function (env) { - var strs = []; - this.genCSS(env, { - add: function(chunk, fileInfo, index) { - strs.push(chunk); - }, - isEmpty: function () { - return strs.length === 0; - } - }); - return strs.join(''); -}; - -tree.outputRuleset = function (env, output, rules) { - var ruleCnt = rules.length, i; - env.tabLevel = (env.tabLevel | 0) + 1; - - // Compressed - if (env.compress) { - output.add('{'); - for (i = 0; i < ruleCnt; i++) { - rules[i].genCSS(env, output); - } - output.add('}'); - env.tabLevel--; - return; - } - - // Non-compressed - var tabSetStr = '\n' + Array(env.tabLevel).join(" "), tabRuleStr = tabSetStr + " "; - if (!ruleCnt) { - output.add(" {" + tabSetStr + '}'); - } else { - output.add(" {" + tabRuleStr); - rules[0].genCSS(env, output); - for (i = 1; i < ruleCnt; i++) { - output.add(tabRuleStr); - rules[i].genCSS(env, output); - } - output.add(tabSetStr + '}'); - } - - env.tabLevel--; -}; - -})(require('./tree')); - -(function (tree) { - -tree.Alpha = function (val) { - this.value = val; -}; -tree.Alpha.prototype = { - type: "Alpha", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - eval: function (env) { - if (this.value.eval) { return new tree.Alpha(this.value.eval(env)); } - return this; - }, - genCSS: function (env, output) { - output.add("alpha(opacity="); - - if (this.value.genCSS) { - this.value.genCSS(env, output); - } else { - output.add(this.value); - } - - output.add(")"); - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -tree.Anonymous = function (string, index, currentFileInfo, mapLines) { - this.value = string.value || string; - this.index = index; - this.mapLines = mapLines; - this.currentFileInfo = currentFileInfo; -}; -tree.Anonymous.prototype = { - type: "Anonymous", - eval: function () { - return new tree.Anonymous(this.value, this.index, this.currentFileInfo, this.mapLines); - }, - compare: function (x) { - if (!x.toCSS) { - return -1; - } - - var left = this.toCSS(), - right = x.toCSS(); - - if (left === right) { - return 0; - } - - return left < right ? -1 : 1; - }, - genCSS: function (env, output) { - output.add(this.value, this.currentFileInfo, this.index, this.mapLines); - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -tree.Assignment = function (key, val) { - this.key = key; - this.value = val; -}; -tree.Assignment.prototype = { - type: "Assignment", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - eval: function (env) { - if (this.value.eval) { - return new(tree.Assignment)(this.key, this.value.eval(env)); - } - return this; - }, - genCSS: function (env, output) { - output.add(this.key + '='); - if (this.value.genCSS) { - this.value.genCSS(env, output); - } else { - output.add(this.value); - } - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -// -// A function call node. -// -tree.Call = function (name, args, index, currentFileInfo) { - this.name = name; - this.args = args; - this.index = index; - this.currentFileInfo = currentFileInfo; -}; -tree.Call.prototype = { - type: "Call", - accept: function (visitor) { - if (this.args) { - this.args = visitor.visitArray(this.args); - } - }, - // - // When evaluating a function call, - // we either find the function in `tree.functions` [1], - // in which case we call it, passing the evaluated arguments, - // if this returns null or we cannot find the function, we - // simply print it out as it appeared originally [2]. - // - // The *functions.js* file contains the built-in functions. - // - // The reason why we evaluate the arguments, is in the case where - // we try to pass a variable to a function, like: `saturate(@color)`. - // The function should receive the value, not the variable. - // - eval: function (env) { - var args = this.args.map(function (a) { return a.eval(env); }), - nameLC = this.name.toLowerCase(), - result, func; - - if (nameLC in tree.functions) { // 1. - try { - func = new tree.functionCall(env, this.currentFileInfo); - result = func[nameLC].apply(func, args); - if (result != null) { - return result; - } - } catch (e) { - throw { type: e.type || "Runtime", - message: "error evaluating function `" + this.name + "`" + - (e.message ? ': ' + e.message : ''), - index: this.index, filename: this.currentFileInfo.filename }; - } - } - - return new tree.Call(this.name, args, this.index, this.currentFileInfo); - }, - - genCSS: function (env, output) { - output.add(this.name + "(", this.currentFileInfo, this.index); - - for(var i = 0; i < this.args.length; i++) { - this.args[i].genCSS(env, output); - if (i + 1 < this.args.length) { - output.add(", "); - } - } - - output.add(")"); - }, - - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { -// -// RGB Colors - #ff0014, #eee -// -tree.Color = function (rgb, a) { - // - // The end goal here, is to parse the arguments - // into an integer triplet, such as `128, 255, 0` - // - // This facilitates operations and conversions. - // - if (Array.isArray(rgb)) { - this.rgb = rgb; - } else if (rgb.length == 6) { - this.rgb = rgb.match(/.{2}/g).map(function (c) { - return parseInt(c, 16); - }); - } else { - this.rgb = rgb.split('').map(function (c) { - return parseInt(c + c, 16); - }); - } - this.alpha = typeof(a) === 'number' ? a : 1; -}; - -var transparentKeyword = "transparent"; - -tree.Color.prototype = { - type: "Color", - eval: function () { return this; }, - luma: function () { return (0.2126 * this.rgb[0] / 255) + (0.7152 * this.rgb[1] / 255) + (0.0722 * this.rgb[2] / 255); }, - - genCSS: function (env, output) { - output.add(this.toCSS(env)); - }, - toCSS: function (env, doNotCompress) { - var compress = env && env.compress && !doNotCompress, - alpha = tree.fround(env, this.alpha); - - // If we have some transparency, the only way to represent it - // is via `rgba`. Otherwise, we use the hex representation, - // which has better compatibility with older browsers. - // Values are capped between `0` and `255`, rounded and zero-padded. - if (alpha < 1) { - if (alpha === 0 && this.isTransparentKeyword) { - return transparentKeyword; - } - return "rgba(" + this.rgb.map(function (c) { - return clamp(Math.round(c), 255); - }).concat(clamp(alpha, 1)) - .join(',' + (compress ? '' : ' ')) + ")"; - } else { - var color = this.toRGB(); - - if (compress) { - var splitcolor = color.split(''); - - // Convert color to short format - if (splitcolor[1] === splitcolor[2] && splitcolor[3] === splitcolor[4] && splitcolor[5] === splitcolor[6]) { - color = '#' + splitcolor[1] + splitcolor[3] + splitcolor[5]; - } - } - - return color; - } - }, - - // - // Operations have to be done per-channel, if not, - // channels will spill onto each other. Once we have - // our result, in the form of an integer triplet, - // we create a new Color node to hold the result. - // - operate: function (env, op, other) { - var rgb = []; - var alpha = this.alpha * (1 - other.alpha) + other.alpha; - for (var c = 0; c < 3; c++) { - rgb[c] = tree.operate(env, op, this.rgb[c], other.rgb[c]); - } - return new(tree.Color)(rgb, alpha); - }, - - toRGB: function () { - return toHex(this.rgb); - }, - - toHSL: function () { - var r = this.rgb[0] / 255, - g = this.rgb[1] / 255, - b = this.rgb[2] / 255, - a = this.alpha; - - var max = Math.max(r, g, b), min = Math.min(r, g, b); - var h, s, l = (max + min) / 2, d = max - min; - - if (max === min) { - h = s = 0; - } else { - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - - switch (max) { - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; - } - h /= 6; - } - return { h: h * 360, s: s, l: l, a: a }; - }, - //Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript - toHSV: function () { - var r = this.rgb[0] / 255, - g = this.rgb[1] / 255, - b = this.rgb[2] / 255, - a = this.alpha; - - var max = Math.max(r, g, b), min = Math.min(r, g, b); - var h, s, v = max; - - var d = max - min; - if (max === 0) { - s = 0; - } else { - s = d / max; - } - - if (max === min) { - h = 0; - } else { - switch(max){ - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; - } - h /= 6; - } - return { h: h * 360, s: s, v: v, a: a }; - }, - toARGB: function () { - return toHex([this.alpha * 255].concat(this.rgb)); - }, - compare: function (x) { - if (!x.rgb) { - return -1; - } - - return (x.rgb[0] === this.rgb[0] && - x.rgb[1] === this.rgb[1] && - x.rgb[2] === this.rgb[2] && - x.alpha === this.alpha) ? 0 : -1; - } -}; - -tree.Color.fromKeyword = function(keyword) { - keyword = keyword.toLowerCase(); - - if (tree.colors.hasOwnProperty(keyword)) { - // detect named color - return new(tree.Color)(tree.colors[keyword].slice(1)); - } - if (keyword === transparentKeyword) { - var transparent = new(tree.Color)([0, 0, 0], 0); - transparent.isTransparentKeyword = true; - return transparent; - } -}; - -function toHex(v) { - return '#' + v.map(function (c) { - c = clamp(Math.round(c), 255); - return (c < 16 ? '0' : '') + c.toString(16); - }).join(''); -} - -function clamp(v, max) { - return Math.min(Math.max(v, 0), max); -} - -})(require('../tree')); - -(function (tree) { - -tree.Comment = function (value, silent, index, currentFileInfo) { - this.value = value; - this.silent = !!silent; - this.currentFileInfo = currentFileInfo; -}; -tree.Comment.prototype = { - type: "Comment", - genCSS: function (env, output) { - if (this.debugInfo) { - output.add(tree.debugInfo(env, this), this.currentFileInfo, this.index); - } - output.add(this.value.trim()); //TODO shouldn't need to trim, we shouldn't grab the \n - }, - toCSS: tree.toCSS, - isSilent: function(env) { - var isReference = (this.currentFileInfo && this.currentFileInfo.reference && !this.isReferenced), - isCompressed = env.compress && !this.value.match(/^\/\*!/); - return this.silent || isReference || isCompressed; - }, - eval: function () { return this; }, - markReferenced: function () { - this.isReferenced = true; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Condition = function (op, l, r, i, negate) { - this.op = op.trim(); - this.lvalue = l; - this.rvalue = r; - this.index = i; - this.negate = negate; -}; -tree.Condition.prototype = { - type: "Condition", - accept: function (visitor) { - this.lvalue = visitor.visit(this.lvalue); - this.rvalue = visitor.visit(this.rvalue); - }, - eval: function (env) { - var a = this.lvalue.eval(env), - b = this.rvalue.eval(env); - - var i = this.index, result; - - result = (function (op) { - switch (op) { - case 'and': - return a && b; - case 'or': - return a || b; - default: - if (a.compare) { - result = a.compare(b); - } else if (b.compare) { - result = b.compare(a); - } else { - throw { type: "Type", - message: "Unable to perform comparison", - index: i }; - } - switch (result) { - case -1: return op === '<' || op === '=<' || op === '<='; - case 0: return op === '=' || op === '>=' || op === '=<' || op === '<='; - case 1: return op === '>' || op === '>='; - } - } - })(this.op); - return this.negate ? !result : result; - } -}; - -})(require('../tree')); - -(function (tree) { - -// -// A number with a unit -// -tree.Dimension = function (value, unit) { - this.value = parseFloat(value); - this.unit = (unit && unit instanceof tree.Unit) ? unit : - new(tree.Unit)(unit ? [unit] : undefined); -}; - -tree.Dimension.prototype = { - type: "Dimension", - accept: function (visitor) { - this.unit = visitor.visit(this.unit); - }, - eval: function (env) { - return this; - }, - toColor: function () { - return new(tree.Color)([this.value, this.value, this.value]); - }, - genCSS: function (env, output) { - if ((env && env.strictUnits) && !this.unit.isSingular()) { - throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: "+this.unit.toString()); - } - - var value = tree.fround(env, this.value), - strValue = String(value); - - if (value !== 0 && value < 0.000001 && value > -0.000001) { - // would be output 1e-6 etc. - strValue = value.toFixed(20).replace(/0+$/, ""); - } - - if (env && env.compress) { - // Zero values doesn't need a unit - if (value === 0 && this.unit.isLength()) { - output.add(strValue); - return; - } - - // Float values doesn't need a leading zero - if (value > 0 && value < 1) { - strValue = (strValue).substr(1); - } - } - - output.add(strValue); - this.unit.genCSS(env, output); - }, - toCSS: tree.toCSS, - - // In an operation between two Dimensions, - // we default to the first Dimension's unit, - // so `1px + 2` will yield `3px`. - operate: function (env, op, other) { - /*jshint noempty:false */ - var value = tree.operate(env, op, this.value, other.value), - unit = this.unit.clone(); - - if (op === '+' || op === '-') { - if (unit.numerator.length === 0 && unit.denominator.length === 0) { - unit.numerator = other.unit.numerator.slice(0); - unit.denominator = other.unit.denominator.slice(0); - } else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) { - // do nothing - } else { - other = other.convertTo(this.unit.usedUnits()); - - if(env.strictUnits && other.unit.toString() !== unit.toString()) { - throw new Error("Incompatible units. Change the units or use the unit function. Bad units: '" + unit.toString() + - "' and '" + other.unit.toString() + "'."); - } - - value = tree.operate(env, op, this.value, other.value); - } - } else if (op === '*') { - unit.numerator = unit.numerator.concat(other.unit.numerator).sort(); - unit.denominator = unit.denominator.concat(other.unit.denominator).sort(); - unit.cancel(); - } else if (op === '/') { - unit.numerator = unit.numerator.concat(other.unit.denominator).sort(); - unit.denominator = unit.denominator.concat(other.unit.numerator).sort(); - unit.cancel(); - } - return new(tree.Dimension)(value, unit); - }, - - compare: function (other) { - if (other instanceof tree.Dimension) { - var a = this.unify(), b = other.unify(), - aValue = a.value, bValue = b.value; - - if (bValue > aValue) { - return -1; - } else if (bValue < aValue) { - return 1; - } else { - if (!b.unit.isEmpty() && a.unit.compare(b.unit) !== 0) { - return -1; - } - return 0; - } - } else { - return -1; - } - }, - - unify: function () { - return this.convertTo({ length: 'm', duration: 's', angle: 'rad' }); - }, - - convertTo: function (conversions) { - var value = this.value, unit = this.unit.clone(), - i, groupName, group, targetUnit, derivedConversions = {}, applyUnit; - - if (typeof conversions === 'string') { - for(i in tree.UnitConversions) { - if (tree.UnitConversions[i].hasOwnProperty(conversions)) { - derivedConversions = {}; - derivedConversions[i] = conversions; - } - } - conversions = derivedConversions; - } - applyUnit = function (atomicUnit, denominator) { - /*jshint loopfunc:true */ - if (group.hasOwnProperty(atomicUnit)) { - if (denominator) { - value = value / (group[atomicUnit] / group[targetUnit]); - } else { - value = value * (group[atomicUnit] / group[targetUnit]); - } - - return targetUnit; - } - - return atomicUnit; - }; - - for (groupName in conversions) { - if (conversions.hasOwnProperty(groupName)) { - targetUnit = conversions[groupName]; - group = tree.UnitConversions[groupName]; - - unit.map(applyUnit); - } - } - - unit.cancel(); - - return new(tree.Dimension)(value, unit); - } -}; - -// http://www.w3.org/TR/css3-values/#absolute-lengths -tree.UnitConversions = { - length: { - 'm': 1, - 'cm': 0.01, - 'mm': 0.001, - 'in': 0.0254, - 'pt': 0.0254 / 72, - 'pc': 0.0254 / 72 * 12 - }, - duration: { - 's': 1, - 'ms': 0.001 - }, - angle: { - 'rad': 1/(2*Math.PI), - 'deg': 1/360, - 'grad': 1/400, - 'turn': 1 - } -}; - -tree.Unit = function (numerator, denominator, backupUnit) { - this.numerator = numerator ? numerator.slice(0).sort() : []; - this.denominator = denominator ? denominator.slice(0).sort() : []; - this.backupUnit = backupUnit; -}; - -tree.Unit.prototype = { - type: "Unit", - clone: function () { - return new tree.Unit(this.numerator.slice(0), this.denominator.slice(0), this.backupUnit); - }, - genCSS: function (env, output) { - if (this.numerator.length >= 1) { - output.add(this.numerator[0]); - } else - if (this.denominator.length >= 1) { - output.add(this.denominator[0]); - } else - if ((!env || !env.strictUnits) && this.backupUnit) { - output.add(this.backupUnit); - } - }, - toCSS: tree.toCSS, - - toString: function () { - var i, returnStr = this.numerator.join("*"); - for (i = 0; i < this.denominator.length; i++) { - returnStr += "/" + this.denominator[i]; - } - return returnStr; - }, - - compare: function (other) { - return this.is(other.toString()) ? 0 : -1; - }, - - is: function (unitString) { - return this.toString() === unitString; - }, - - isLength: function () { - return Boolean(this.toCSS().match(/px|em|%|in|cm|mm|pc|pt|ex/)); - }, - - isEmpty: function () { - return this.numerator.length === 0 && this.denominator.length === 0; - }, - - isSingular: function() { - return this.numerator.length <= 1 && this.denominator.length === 0; - }, - - map: function(callback) { - var i; - - for (i = 0; i < this.numerator.length; i++) { - this.numerator[i] = callback(this.numerator[i], false); - } - - for (i = 0; i < this.denominator.length; i++) { - this.denominator[i] = callback(this.denominator[i], true); - } - }, - - usedUnits: function() { - var group, result = {}, mapUnit; - - mapUnit = function (atomicUnit) { - /*jshint loopfunc:true */ - if (group.hasOwnProperty(atomicUnit) && !result[groupName]) { - result[groupName] = atomicUnit; - } - - return atomicUnit; - }; - - for (var groupName in tree.UnitConversions) { - if (tree.UnitConversions.hasOwnProperty(groupName)) { - group = tree.UnitConversions[groupName]; - - this.map(mapUnit); - } - } - - return result; - }, - - cancel: function () { - var counter = {}, atomicUnit, i, backup; - - for (i = 0; i < this.numerator.length; i++) { - atomicUnit = this.numerator[i]; - if (!backup) { - backup = atomicUnit; - } - counter[atomicUnit] = (counter[atomicUnit] || 0) + 1; - } - - for (i = 0; i < this.denominator.length; i++) { - atomicUnit = this.denominator[i]; - if (!backup) { - backup = atomicUnit; - } - counter[atomicUnit] = (counter[atomicUnit] || 0) - 1; - } - - this.numerator = []; - this.denominator = []; - - for (atomicUnit in counter) { - if (counter.hasOwnProperty(atomicUnit)) { - var count = counter[atomicUnit]; - - if (count > 0) { - for (i = 0; i < count; i++) { - this.numerator.push(atomicUnit); - } - } else if (count < 0) { - for (i = 0; i < -count; i++) { - this.denominator.push(atomicUnit); - } - } - } - } - - if (this.numerator.length === 0 && this.denominator.length === 0 && backup) { - this.backupUnit = backup; - } - - this.numerator.sort(); - this.denominator.sort(); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Directive = function (name, value, index, currentFileInfo) { - this.name = name; - - if (Array.isArray(value)) { - this.rules = [new(tree.Ruleset)(null, value)]; - this.rules[0].allowImports = true; - } else { - this.value = value; - } - this.index = index; - this.currentFileInfo = currentFileInfo; - -}; -tree.Directive.prototype = { - type: "Directive", - accept: function (visitor) { - if (this.rules) { - this.rules = visitor.visitArray(this.rules); - } - if (this.value) { - this.value = visitor.visit(this.value); - } - }, - genCSS: function (env, output) { - output.add(this.name, this.currentFileInfo, this.index); - if (this.rules) { - tree.outputRuleset(env, output, this.rules); - } else { - output.add(' '); - this.value.genCSS(env, output); - output.add(';'); - } - }, - toCSS: tree.toCSS, - eval: function (env) { - var evaldDirective = this; - if (this.rules) { - env.frames.unshift(this); - evaldDirective = new(tree.Directive)(this.name, null, this.index, this.currentFileInfo); - evaldDirective.rules = [this.rules[0].eval(env)]; - evaldDirective.rules[0].root = true; - env.frames.shift(); - } - return evaldDirective; - }, - variable: function (name) { return tree.Ruleset.prototype.variable.call(this.rules[0], name); }, - find: function () { return tree.Ruleset.prototype.find.apply(this.rules[0], arguments); }, - rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.rules[0]); }, - markReferenced: function () { - var i, rules; - this.isReferenced = true; - if (this.rules) { - rules = this.rules[0].rules; - for (i = 0; i < rules.length; i++) { - if (rules[i].markReferenced) { - rules[i].markReferenced(); - } - } - } - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Element = function (combinator, value, index, currentFileInfo) { - this.combinator = combinator instanceof tree.Combinator ? - combinator : new(tree.Combinator)(combinator); - - if (typeof(value) === 'string') { - this.value = value.trim(); - } else if (value) { - this.value = value; - } else { - this.value = ""; - } - this.index = index; - this.currentFileInfo = currentFileInfo; -}; -tree.Element.prototype = { - type: "Element", - accept: function (visitor) { - var value = this.value; - this.combinator = visitor.visit(this.combinator); - if (typeof value === "object") { - this.value = visitor.visit(value); - } - }, - eval: function (env) { - return new(tree.Element)(this.combinator, - this.value.eval ? this.value.eval(env) : this.value, - this.index, - this.currentFileInfo); - }, - genCSS: function (env, output) { - output.add(this.toCSS(env), this.currentFileInfo, this.index); - }, - toCSS: function (env) { - var value = (this.value.toCSS ? this.value.toCSS(env) : this.value); - if (value === '' && this.combinator.value.charAt(0) === '&') { - return ''; - } else { - return this.combinator.toCSS(env || {}) + value; - } - } -}; - -tree.Attribute = function (key, op, value) { - this.key = key; - this.op = op; - this.value = value; -}; -tree.Attribute.prototype = { - type: "Attribute", - eval: function (env) { - return new(tree.Attribute)(this.key.eval ? this.key.eval(env) : this.key, - this.op, (this.value && this.value.eval) ? this.value.eval(env) : this.value); - }, - genCSS: function (env, output) { - output.add(this.toCSS(env)); - }, - toCSS: function (env) { - var value = this.key.toCSS ? this.key.toCSS(env) : this.key; - - if (this.op) { - value += this.op; - value += (this.value.toCSS ? this.value.toCSS(env) : this.value); - } - - return '[' + value + ']'; - } -}; - -tree.Combinator = function (value) { - if (value === ' ') { - this.value = ' '; - } else { - this.value = value ? value.trim() : ""; - } -}; -tree.Combinator.prototype = { - type: "Combinator", - _outputMap: { - '' : '', - ' ' : ' ', - ':' : ' :', - '+' : ' + ', - '~' : ' ~ ', - '>' : ' > ', - '|' : '|', - '^' : ' ^ ', - '^^' : ' ^^ ' - }, - _outputMapCompressed: { - '' : '', - ' ' : ' ', - ':' : ' :', - '+' : '+', - '~' : '~', - '>' : '>', - '|' : '|', - '^' : '^', - '^^' : '^^' - }, - genCSS: function (env, output) { - output.add((env.compress ? this._outputMapCompressed : this._outputMap)[this.value]); - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -tree.Expression = function (value) { this.value = value; }; -tree.Expression.prototype = { - type: "Expression", - accept: function (visitor) { - if (this.value) { - this.value = visitor.visitArray(this.value); - } - }, - eval: function (env) { - var returnValue, - inParenthesis = this.parens && !this.parensInOp, - doubleParen = false; - if (inParenthesis) { - env.inParenthesis(); - } - if (this.value.length > 1) { - returnValue = new(tree.Expression)(this.value.map(function (e) { - return e.eval(env); - })); - } else if (this.value.length === 1) { - if (this.value[0].parens && !this.value[0].parensInOp) { - doubleParen = true; - } - returnValue = this.value[0].eval(env); - } else { - returnValue = this; - } - if (inParenthesis) { - env.outOfParenthesis(); - } - if (this.parens && this.parensInOp && !(env.isMathOn()) && !doubleParen) { - returnValue = new(tree.Paren)(returnValue); - } - return returnValue; - }, - genCSS: function (env, output) { - for(var i = 0; i < this.value.length; i++) { - this.value[i].genCSS(env, output); - if (i + 1 < this.value.length) { - output.add(" "); - } - } - }, - toCSS: tree.toCSS, - throwAwayComments: function () { - this.value = this.value.filter(function(v) { - return !(v instanceof tree.Comment); - }); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Extend = function Extend(selector, option, index) { - this.selector = selector; - this.option = option; - this.index = index; - this.object_id = tree.Extend.next_id++; - this.parent_ids = [this.object_id]; - - switch(option) { - case "all": - this.allowBefore = true; - this.allowAfter = true; - break; - default: - this.allowBefore = false; - this.allowAfter = false; - break; - } -}; -tree.Extend.next_id = 0; - -tree.Extend.prototype = { - type: "Extend", - accept: function (visitor) { - this.selector = visitor.visit(this.selector); - }, - eval: function (env) { - return new(tree.Extend)(this.selector.eval(env), this.option, this.index); - }, - clone: function (env) { - return new(tree.Extend)(this.selector, this.option, this.index); - }, - findSelfSelectors: function (selectors) { - var selfElements = [], - i, - selectorElements; - - for(i = 0; i < selectors.length; i++) { - selectorElements = selectors[i].elements; - // duplicate the logic in genCSS function inside the selector node. - // future TODO - move both logics into the selector joiner visitor - if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === "") { - selectorElements[0].combinator.value = ' '; - } - selfElements = selfElements.concat(selectors[i].elements); - } - - this.selfSelectors = [{ elements: selfElements }]; - } -}; - -})(require('../tree')); - -(function (tree) { -// -// CSS @import node -// -// The general strategy here is that we don't want to wait -// for the parsing to be completed, before we start importing -// the file. That's because in the context of a browser, -// most of the time will be spent waiting for the server to respond. -// -// On creation, we push the import path to our import queue, though -// `import,push`, we also pass it a callback, which it'll call once -// the file has been fetched, and parsed. -// -tree.Import = function (path, features, options, index, currentFileInfo) { - this.options = options; - this.index = index; - this.path = path; - this.features = features; - this.currentFileInfo = currentFileInfo; - - if (this.options.less !== undefined || this.options.inline) { - this.css = !this.options.less || this.options.inline; - } else { - var pathValue = this.getPath(); - if (pathValue && /css([\?;].*)?$/.test(pathValue)) { - this.css = true; - } - } -}; - -// -// The actual import node doesn't return anything, when converted to CSS. -// The reason is that it's used at the evaluation stage, so that the rules -// it imports can be treated like any other rules. -// -// In `eval`, we make sure all Import nodes get evaluated, recursively, so -// we end up with a flat structure, which can easily be imported in the parent -// ruleset. -// -tree.Import.prototype = { - type: "Import", - accept: function (visitor) { - if (this.features) { - this.features = visitor.visit(this.features); - } - this.path = visitor.visit(this.path); - if (!this.options.inline && this.root) { - this.root = visitor.visit(this.root); - } - }, - genCSS: function (env, output) { - if (this.css) { - output.add("@import ", this.currentFileInfo, this.index); - this.path.genCSS(env, output); - if (this.features) { - output.add(" "); - this.features.genCSS(env, output); - } - output.add(';'); - } - }, - toCSS: tree.toCSS, - getPath: function () { - if (this.path instanceof tree.Quoted) { - var path = this.path.value; - return (this.css !== undefined || /(\.[a-z]*$)|([\?;].*)$/.test(path)) ? path : path + '.less'; - } else if (this.path instanceof tree.URL) { - return this.path.value.value; - } - return null; - }, - evalForImport: function (env) { - return new(tree.Import)(this.path.eval(env), this.features, this.options, this.index, this.currentFileInfo); - }, - evalPath: function (env) { - var path = this.path.eval(env); - var rootpath = this.currentFileInfo && this.currentFileInfo.rootpath; - - if (!(path instanceof tree.URL)) { - if (rootpath) { - var pathValue = path.value; - // Add the base path if the import is relative - if (pathValue && env.isPathRelative(pathValue)) { - path.value = rootpath +pathValue; - } - } - path.value = env.normalizePath(path.value); - } - - return path; - }, - eval: function (env) { - var ruleset, features = this.features && this.features.eval(env); - - if (this.skip) { return []; } - - if (this.options.inline) { - //todo needs to reference css file not import - var contents = new(tree.Anonymous)(this.root, 0, {filename: this.importedFilename}, true); - return this.features ? new(tree.Media)([contents], this.features.value) : [contents]; - } else if (this.css) { - var newImport = new(tree.Import)(this.evalPath(env), features, this.options, this.index); - if (!newImport.css && this.error) { - throw this.error; - } - return newImport; - } else { - ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0)); - - ruleset.evalImports(env); - - return this.features ? new(tree.Media)(ruleset.rules, this.features.value) : ruleset.rules; - } - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.JavaScript = function (string, index, escaped) { - this.escaped = escaped; - this.expression = string; - this.index = index; -}; -tree.JavaScript.prototype = { - type: "JavaScript", - eval: function (env) { - var result, - that = this, - context = {}; - - var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) { - return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env)); - }); - - try { - expression = new(Function)('return (' + expression + ')'); - } catch (e) { - throw { message: "JavaScript evaluation error: " + e.message + " from `" + expression + "`" , - index: this.index }; - } - - var variables = env.frames[0].variables(); - for (var k in variables) { - if (variables.hasOwnProperty(k)) { - /*jshint loopfunc:true */ - context[k.slice(1)] = { - value: variables[k].value, - toJS: function () { - return this.value.eval(env).toCSS(); - } - }; - } - } - - try { - result = expression.call(context); - } catch (e) { - throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message.replace(/["]/g, "'") + "'" , - index: this.index }; - } - if (typeof(result) === 'number') { - return new(tree.Dimension)(result); - } else if (typeof(result) === 'string') { - return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index); - } else if (Array.isArray(result)) { - return new(tree.Anonymous)(result.join(', ')); - } else { - return new(tree.Anonymous)(result); - } - } -}; - -})(require('../tree')); - - -(function (tree) { - -tree.Keyword = function (value) { this.value = value; }; -tree.Keyword.prototype = { - type: "Keyword", - eval: function () { return this; }, - genCSS: function (env, output) { - output.add(this.value); - }, - toCSS: tree.toCSS, - compare: function (other) { - if (other instanceof tree.Keyword) { - return other.value === this.value ? 0 : 1; - } else { - return -1; - } - } -}; - -tree.True = new(tree.Keyword)('true'); -tree.False = new(tree.Keyword)('false'); - -})(require('../tree')); - -(function (tree) { - -tree.Media = function (value, features, index, currentFileInfo) { - this.index = index; - this.currentFileInfo = currentFileInfo; - - var selectors = this.emptySelectors(); - - this.features = new(tree.Value)(features); - this.rules = [new(tree.Ruleset)(selectors, value)]; - this.rules[0].allowImports = true; -}; -tree.Media.prototype = { - type: "Media", - accept: function (visitor) { - if (this.features) { - this.features = visitor.visit(this.features); - } - if (this.rules) { - this.rules = visitor.visitArray(this.rules); - } - }, - genCSS: function (env, output) { - output.add('@media ', this.currentFileInfo, this.index); - this.features.genCSS(env, output); - tree.outputRuleset(env, output, this.rules); - }, - toCSS: tree.toCSS, - eval: function (env) { - if (!env.mediaBlocks) { - env.mediaBlocks = []; - env.mediaPath = []; - } - - var media = new(tree.Media)(null, [], this.index, this.currentFileInfo); - if(this.debugInfo) { - this.rules[0].debugInfo = this.debugInfo; - media.debugInfo = this.debugInfo; - } - var strictMathBypass = false; - if (!env.strictMath) { - strictMathBypass = true; - env.strictMath = true; - } - try { - media.features = this.features.eval(env); - } - finally { - if (strictMathBypass) { - env.strictMath = false; - } - } - - env.mediaPath.push(media); - env.mediaBlocks.push(media); - - env.frames.unshift(this.rules[0]); - media.rules = [this.rules[0].eval(env)]; - env.frames.shift(); - - env.mediaPath.pop(); - - return env.mediaPath.length === 0 ? media.evalTop(env) : - media.evalNested(env); - }, - variable: function (name) { return tree.Ruleset.prototype.variable.call(this.rules[0], name); }, - find: function () { return tree.Ruleset.prototype.find.apply(this.rules[0], arguments); }, - rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.rules[0]); }, - emptySelectors: function() { - var el = new(tree.Element)('', '&', this.index, this.currentFileInfo), - sels = [new(tree.Selector)([el], null, null, this.index, this.currentFileInfo)]; - sels[0].mediaEmpty = true; - return sels; - }, - markReferenced: function () { - var i, rules = this.rules[0].rules; - this.isReferenced = true; - for (i = 0; i < rules.length; i++) { - if (rules[i].markReferenced) { - rules[i].markReferenced(); - } - } - }, - - evalTop: function (env) { - var result = this; - - // Render all dependent Media blocks. - if (env.mediaBlocks.length > 1) { - var selectors = this.emptySelectors(); - result = new(tree.Ruleset)(selectors, env.mediaBlocks); - result.multiMedia = true; - } - - delete env.mediaBlocks; - delete env.mediaPath; - - return result; - }, - evalNested: function (env) { - var i, value, - path = env.mediaPath.concat([this]); - - // Extract the media-query conditions separated with `,` (OR). - for (i = 0; i < path.length; i++) { - value = path[i].features instanceof tree.Value ? - path[i].features.value : path[i].features; - path[i] = Array.isArray(value) ? value : [value]; - } - - // Trace all permutations to generate the resulting media-query. - // - // (a, b and c) with nested (d, e) -> - // a and d - // a and e - // b and c and d - // b and c and e - this.features = new(tree.Value)(this.permute(path).map(function (path) { - path = path.map(function (fragment) { - return fragment.toCSS ? fragment : new(tree.Anonymous)(fragment); - }); - - for(i = path.length - 1; i > 0; i--) { - path.splice(i, 0, new(tree.Anonymous)("and")); - } - - return new(tree.Expression)(path); - })); - - // Fake a tree-node that doesn't output anything. - return new(tree.Ruleset)([], []); - }, - permute: function (arr) { - if (arr.length === 0) { - return []; - } else if (arr.length === 1) { - return arr[0]; - } else { - var result = []; - var rest = this.permute(arr.slice(1)); - for (var i = 0; i < rest.length; i++) { - for (var j = 0; j < arr[0].length; j++) { - result.push([arr[0][j]].concat(rest[i])); - } - } - return result; - } - }, - bubbleSelectors: function (selectors) { - this.rules = [new(tree.Ruleset)(selectors.slice(0), [this.rules[0]])]; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.mixin = {}; -tree.mixin.Call = function (elements, args, index, currentFileInfo, important) { - this.selector = new(tree.Selector)(elements); - this.arguments = (args && args.length) ? args : null; - this.index = index; - this.currentFileInfo = currentFileInfo; - this.important = important; -}; -tree.mixin.Call.prototype = { - type: "MixinCall", - accept: function (visitor) { - if (this.selector) { - this.selector = visitor.visit(this.selector); - } - if (this.arguments) { - this.arguments = visitor.visitArray(this.arguments); - } - }, - eval: function (env) { - var mixins, mixin, args, rules = [], match = false, i, m, f, isRecursive, isOneFound, rule, - candidates = [], candidate, conditionResult = [], defaultFunc = tree.defaultFunc, - defaultResult, defNone = 0, defTrue = 1, defFalse = 2, count; - - args = this.arguments && this.arguments.map(function (a) { - return { name: a.name, value: a.value.eval(env) }; - }); - - for (i = 0; i < env.frames.length; i++) { - if ((mixins = env.frames[i].find(this.selector)).length > 0) { - isOneFound = true; - - // To make `default()` function independent of definition order we have two "subpasses" here. - // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`), - // and build candidate list with corresponding flags. Then, when we know all possible matches, - // we make a final decision. - - for (m = 0; m < mixins.length; m++) { - mixin = mixins[m]; - isRecursive = false; - for(f = 0; f < env.frames.length; f++) { - if ((!(mixin instanceof tree.mixin.Definition)) && mixin === (env.frames[f].originalRuleset || env.frames[f])) { - isRecursive = true; - break; - } - } - if (isRecursive) { - continue; - } - - if (mixin.matchArgs(args, env)) { - candidate = {mixin: mixin, group: defNone}; - - if (mixin.matchCondition) { - for (f = 0; f < 2; f++) { - defaultFunc.value(f); - conditionResult[f] = mixin.matchCondition(args, env); - } - if (conditionResult[0] || conditionResult[1]) { - if (conditionResult[0] != conditionResult[1]) { - candidate.group = conditionResult[1] ? - defTrue : defFalse; - } - - candidates.push(candidate); - } - } - else { - candidates.push(candidate); - } - - match = true; - } - } - - defaultFunc.reset(); - - count = [0, 0, 0]; - for (m = 0; m < candidates.length; m++) { - count[candidates[m].group]++; - } - - if (count[defNone] > 0) { - defaultResult = defFalse; - } else { - defaultResult = defTrue; - if ((count[defTrue] + count[defFalse]) > 1) { - throw { type: 'Runtime', - message: 'Ambiguous use of `default()` found when matching for `' - + this.format(args) + '`', - index: this.index, filename: this.currentFileInfo.filename }; - } - } - - for (m = 0; m < candidates.length; m++) { - candidate = candidates[m].group; - if ((candidate === defNone) || (candidate === defaultResult)) { - try { - mixin = candidates[m].mixin; - if (!(mixin instanceof tree.mixin.Definition)) { - mixin = new tree.mixin.Definition("", [], mixin.rules, null, false); - mixin.originalRuleset = mixins[m].originalRuleset || mixins[m]; - } - Array.prototype.push.apply( - rules, mixin.eval(env, args, this.important).rules); - } catch (e) { - throw { message: e.message, index: this.index, filename: this.currentFileInfo.filename, stack: e.stack }; - } - } - } - - if (match) { - if (!this.currentFileInfo || !this.currentFileInfo.reference) { - for (i = 0; i < rules.length; i++) { - rule = rules[i]; - if (rule.markReferenced) { - rule.markReferenced(); - } - } - } - return rules; - } - } - } - if (isOneFound) { - throw { type: 'Runtime', - message: 'No matching definition was found for `' + this.format(args) + '`', - index: this.index, filename: this.currentFileInfo.filename }; - } else { - throw { type: 'Name', - message: this.selector.toCSS().trim() + " is undefined", - index: this.index, filename: this.currentFileInfo.filename }; - } - }, - format: function (args) { - return this.selector.toCSS().trim() + '(' + - (args ? args.map(function (a) { - var argValue = ""; - if (a.name) { - argValue += a.name + ":"; - } - if (a.value.toCSS) { - argValue += a.value.toCSS(); - } else { - argValue += "???"; - } - return argValue; - }).join(', ') : "") + ")"; - } -}; - -tree.mixin.Definition = function (name, params, rules, condition, variadic) { - this.name = name; - this.selectors = [new(tree.Selector)([new(tree.Element)(null, name, this.index, this.currentFileInfo)])]; - this.params = params; - this.condition = condition; - this.variadic = variadic; - this.arity = params.length; - this.rules = rules; - this._lookups = {}; - this.required = params.reduce(function (count, p) { - if (!p.name || (p.name && !p.value)) { return count + 1; } - else { return count; } - }, 0); - this.parent = tree.Ruleset.prototype; - this.frames = []; -}; -tree.mixin.Definition.prototype = { - type: "MixinDefinition", - accept: function (visitor) { - if (this.params && this.params.length) { - this.params = visitor.visitArray(this.params); - } - this.rules = visitor.visitArray(this.rules); - if (this.condition) { - this.condition = visitor.visit(this.condition); - } - }, - variable: function (name) { return this.parent.variable.call(this, name); }, - variables: function () { return this.parent.variables.call(this); }, - find: function () { return this.parent.find.apply(this, arguments); }, - rulesets: function () { return this.parent.rulesets.apply(this); }, - - evalParams: function (env, mixinEnv, args, evaldArguments) { - /*jshint boss:true */ - var frame = new(tree.Ruleset)(null, null), - varargs, arg, - params = this.params.slice(0), - i, j, val, name, isNamedFound, argIndex; - - mixinEnv = new tree.evalEnv(mixinEnv, [frame].concat(mixinEnv.frames)); - - if (args) { - args = args.slice(0); - - for(i = 0; i < args.length; i++) { - arg = args[i]; - if (name = (arg && arg.name)) { - isNamedFound = false; - for(j = 0; j < params.length; j++) { - if (!evaldArguments[j] && name === params[j].name) { - evaldArguments[j] = arg.value.eval(env); - frame.prependRule(new(tree.Rule)(name, arg.value.eval(env))); - isNamedFound = true; - break; - } - } - if (isNamedFound) { - args.splice(i, 1); - i--; - continue; - } else { - throw { type: 'Runtime', message: "Named argument for " + this.name + - ' ' + args[i].name + ' not found' }; - } - } - } - } - argIndex = 0; - for (i = 0; i < params.length; i++) { - if (evaldArguments[i]) { continue; } - - arg = args && args[argIndex]; - - if (name = params[i].name) { - if (params[i].variadic && args) { - varargs = []; - for (j = argIndex; j < args.length; j++) { - varargs.push(args[j].value.eval(env)); - } - frame.prependRule(new(tree.Rule)(name, new(tree.Expression)(varargs).eval(env))); - } else { - val = arg && arg.value; - if (val) { - val = val.eval(env); - } else if (params[i].value) { - val = params[i].value.eval(mixinEnv); - frame.resetCache(); - } else { - throw { type: 'Runtime', message: "wrong number of arguments for " + this.name + - ' (' + args.length + ' for ' + this.arity + ')' }; - } - - frame.prependRule(new(tree.Rule)(name, val)); - evaldArguments[i] = val; - } - } - - if (params[i].variadic && args) { - for (j = argIndex; j < args.length; j++) { - evaldArguments[j] = args[j].value.eval(env); - } - } - argIndex++; - } - - return frame; - }, - eval: function (env, args, important) { - var _arguments = [], - mixinFrames = this.frames.concat(env.frames), - frame = this.evalParams(env, new(tree.evalEnv)(env, mixinFrames), args, _arguments), - rules, ruleset; - - frame.prependRule(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env))); - - rules = this.rules.slice(0); - - ruleset = new(tree.Ruleset)(null, rules); - ruleset.originalRuleset = this; - ruleset = ruleset.eval(new(tree.evalEnv)(env, [this, frame].concat(mixinFrames))); - if (important) { - ruleset = this.parent.makeImportant.apply(ruleset); - } - return ruleset; - }, - matchCondition: function (args, env) { - if (this.condition && !this.condition.eval( - new(tree.evalEnv)(env, - [this.evalParams(env, new(tree.evalEnv)(env, this.frames.concat(env.frames)), args, [])] // the parameter variables - .concat(this.frames) // the parent namespace/mixin frames - .concat(env.frames)))) { // the current environment frames - return false; - } - return true; - }, - matchArgs: function (args, env) { - var argsLength = (args && args.length) || 0, len; - - if (! this.variadic) { - if (argsLength < this.required) { return false; } - if (argsLength > this.params.length) { return false; } - } else { - if (argsLength < (this.required - 1)) { return false; } - } - - len = Math.min(argsLength, this.arity); - - for (var i = 0; i < len; i++) { - if (!this.params[i].name && !this.params[i].variadic) { - if (args[i].value.eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) { - return false; - } - } - } - return true; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Negative = function (node) { - this.value = node; -}; -tree.Negative.prototype = { - type: "Negative", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add('-'); - this.value.genCSS(env, output); - }, - toCSS: tree.toCSS, - eval: function (env) { - if (env.isMathOn()) { - return (new(tree.Operation)('*', [new(tree.Dimension)(-1), this.value])).eval(env); - } - return new(tree.Negative)(this.value.eval(env)); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Operation = function (op, operands, isSpaced) { - this.op = op.trim(); - this.operands = operands; - this.isSpaced = isSpaced; -}; -tree.Operation.prototype = { - type: "Operation", - accept: function (visitor) { - this.operands = visitor.visit(this.operands); - }, - eval: function (env) { - var a = this.operands[0].eval(env), - b = this.operands[1].eval(env); - - if (env.isMathOn()) { - if (a instanceof tree.Dimension && b instanceof tree.Color) { - a = a.toColor(); - } - if (b instanceof tree.Dimension && a instanceof tree.Color) { - b = b.toColor(); - } - if (!a.operate) { - throw { type: "Operation", - message: "Operation on an invalid type" }; - } - - return a.operate(env, this.op, b); - } else { - return new(tree.Operation)(this.op, [a, b], this.isSpaced); - } - }, - genCSS: function (env, output) { - this.operands[0].genCSS(env, output); - if (this.isSpaced) { - output.add(" "); - } - output.add(this.op); - if (this.isSpaced) { - output.add(" "); - } - this.operands[1].genCSS(env, output); - }, - toCSS: tree.toCSS -}; - -tree.operate = function (env, op, a, b) { - switch (op) { - case '+': return a + b; - case '-': return a - b; - case '*': return a * b; - case '/': return a / b; - } -}; - -})(require('../tree')); - - -(function (tree) { - -tree.Paren = function (node) { - this.value = node; -}; -tree.Paren.prototype = { - type: "Paren", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add('('); - this.value.genCSS(env, output); - output.add(')'); - }, - toCSS: tree.toCSS, - eval: function (env) { - return new(tree.Paren)(this.value.eval(env)); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Quoted = function (str, content, escaped, index, currentFileInfo) { - this.escaped = escaped; - this.value = content || ''; - this.quote = str.charAt(0); - this.index = index; - this.currentFileInfo = currentFileInfo; -}; -tree.Quoted.prototype = { - type: "Quoted", - genCSS: function (env, output) { - if (!this.escaped) { - output.add(this.quote, this.currentFileInfo, this.index); - } - output.add(this.value); - if (!this.escaped) { - output.add(this.quote); - } - }, - toCSS: tree.toCSS, - eval: function (env) { - var that = this; - var value = this.value.replace(/`([^`]+)`/g, function (_, exp) { - return new(tree.JavaScript)(exp, that.index, true).eval(env).value; - }).replace(/@\{([\w-]+)\}/g, function (_, name) { - var v = new(tree.Variable)('@' + name, that.index, that.currentFileInfo).eval(env, true); - return (v instanceof tree.Quoted) ? v.value : v.toCSS(); - }); - return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index, this.currentFileInfo); - }, - compare: function (x) { - if (!x.toCSS) { - return -1; - } - - var left = this.toCSS(), - right = x.toCSS(); - - if (left === right) { - return 0; - } - - return left < right ? -1 : 1; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Rule = function (name, value, important, merge, index, currentFileInfo, inline) { - this.name = name; - this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]); - this.important = important ? ' ' + important.trim() : ''; - this.merge = merge; - this.index = index; - this.currentFileInfo = currentFileInfo; - this.inline = inline || false; - this.variable = name.charAt && (name.charAt(0) === '@'); -}; - -tree.Rule.prototype = { - type: "Rule", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add(this.name + (env.compress ? ':' : ': '), this.currentFileInfo, this.index); - try { - this.value.genCSS(env, output); - } - catch(e) { - e.index = this.index; - e.filename = this.currentFileInfo.filename; - throw e; - } - output.add(this.important + ((this.inline || (env.lastRule && env.compress)) ? "" : ";"), this.currentFileInfo, this.index); - }, - toCSS: tree.toCSS, - eval: function (env) { - var strictMathBypass = false, name = this.name; - if (typeof name !== "string") { - // expand 'primitive' name directly to get - // things faster (~10% for benchmark.less): - name = (name.length === 1) - && (name[0] instanceof tree.Keyword) - ? name[0].value : evalName(env, name); - } - if (name === "font" && !env.strictMath) { - strictMathBypass = true; - env.strictMath = true; - } - try { - return new(tree.Rule)(name, - this.value.eval(env), - this.important, - this.merge, - this.index, this.currentFileInfo, this.inline); - } - catch(e) { - e.index = e.index || this.index; - throw e; - } - finally { - if (strictMathBypass) { - env.strictMath = false; - } - } - }, - makeImportant: function () { - return new(tree.Rule)(this.name, - this.value, - "!important", - this.merge, - this.index, this.currentFileInfo, this.inline); - } -}; - -function evalName(env, name) { - var value = "", i, n = name.length, - output = {add: function (s) {value += s;}}; - for (i = 0; i < n; i++) { - name[i].eval(env).genCSS(env, output); - } - return value; -} - -})(require('../tree')); - -(function (tree) { - -tree.Ruleset = function (selectors, rules, strictImports) { - this.selectors = selectors; - this.rules = rules; - this._lookups = {}; - this.strictImports = strictImports; -}; -tree.Ruleset.prototype = { - type: "Ruleset", - accept: function (visitor) { - if (this.paths) { - visitor.visitArray(this.paths, true); - } else if (this.selectors) { - this.selectors = visitor.visitArray(this.selectors); - } - if (this.rules && this.rules.length) { - this.rules = visitor.visitArray(this.rules); - } - }, - eval: function (env) { - var thisSelectors = this.selectors, selectors, - selCnt, i, defaultFunc = tree.defaultFunc; - if (thisSelectors && (selCnt = thisSelectors.length)) { - selectors = []; - defaultFunc.error({ - type: "Syntax", - message: "it is currently only allowed in parametric mixin guards," - }); - for (i = 0; i < selCnt; i++) { - selectors.push(thisSelectors[i].eval(env)); - } - defaultFunc.reset(); - } - - var rules = this.rules ? this.rules.slice(0) : null, - ruleset = new(tree.Ruleset)(selectors, rules, this.strictImports), - rule, subRule; - - ruleset.originalRuleset = this; - ruleset.root = this.root; - ruleset.firstRoot = this.firstRoot; - ruleset.allowImports = this.allowImports; - - if(this.debugInfo) { - ruleset.debugInfo = this.debugInfo; - } - - // push the current ruleset to the frames stack - var envFrames = env.frames; - envFrames.unshift(ruleset); - - // currrent selectors - var envSelectors = env.selectors; - if (!envSelectors) { - env.selectors = envSelectors = []; - } - envSelectors.unshift(this.selectors); - - // Evaluate imports - if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) { - ruleset.evalImports(env); - } - - // Store the frames around mixin definitions, - // so they can be evaluated like closures when the time comes. - var rsRules = ruleset.rules, rsRuleCnt = rsRules ? rsRules.length : 0; - for (i = 0; i < rsRuleCnt; i++) { - if (rsRules[i] instanceof tree.mixin.Definition) { - rsRules[i].frames = envFrames.slice(0); - } - } - - var mediaBlockCount = (env.mediaBlocks && env.mediaBlocks.length) || 0; - - // Evaluate mixin calls. - for (i = 0; i < rsRuleCnt; i++) { - if (rsRules[i] instanceof tree.mixin.Call) { - /*jshint loopfunc:true */ - rules = rsRules[i].eval(env).filter(function(r) { - if ((r instanceof tree.Rule) && r.variable) { - // do not pollute the scope if the variable is - // already there. consider returning false here - // but we need a way to "return" variable from mixins - return !(ruleset.variable(r.name)); - } - return true; - }); - rsRules.splice.apply(rsRules, [i, 1].concat(rules)); - rsRuleCnt += rules.length - 1; - i += rules.length-1; - ruleset.resetCache(); - } - } - - // Evaluate everything else - for (i = 0; i < rsRules.length; i++) { - rule = rsRules[i]; - if (! (rule instanceof tree.mixin.Definition)) { - rsRules[i] = rule = rule.eval ? rule.eval(env) : rule; - // for rulesets, check if it is a css guard and can be removed - if (rule instanceof tree.Ruleset && rule.selectors && rule.selectors.length === 1) { - // check if it can be folded in (e.g. & where) - if (rule.selectors[0].isJustParentSelector()) { - rsRules.splice(i--, 1); - // cannot call if there is no selector, so we can just continue - if (!rule.selectors[0].evaldCondition) { - continue; - } - for(var j = 0; j < rule.rules.length; j++) { - subRule = rule.rules[j]; - if (!(subRule instanceof tree.Rule) || !subRule.variable) { - rsRules.splice(++i, 0, subRule); - } - } - } - } - } - } - - // Pop the stack - envFrames.shift(); - envSelectors.shift(); - - if (env.mediaBlocks) { - for (i = mediaBlockCount; i < env.mediaBlocks.length; i++) { - env.mediaBlocks[i].bubbleSelectors(selectors); - } - } - - return ruleset; - }, - evalImports: function(env) { - var rules = this.rules, i, importRules; - if (!rules) { return; } - - for (i = 0; i < rules.length; i++) { - if (rules[i] instanceof tree.Import) { - importRules = rules[i].eval(env); - if (importRules && importRules.length) { - rules.splice.apply(rules, [i, 1].concat(importRules)); - i+= importRules.length-1; - } else { - rules.splice(i, 1, importRules); - } - this.resetCache(); - } - } - }, - makeImportant: function() { - return new tree.Ruleset(this.selectors, this.rules.map(function (r) { - if (r.makeImportant) { - return r.makeImportant(); - } else { - return r; - } - }), this.strictImports); - }, - matchArgs: function (args) { - return !args || args.length === 0; - }, - // lets you call a css selector with a guard - matchCondition: function (args, env) { - var lastSelector = this.selectors[this.selectors.length-1]; - if (!lastSelector.evaldCondition) { - return false; - } - if (lastSelector.condition && - !lastSelector.condition.eval( - new(tree.evalEnv)(env, - env.frames))) { - return false; - } - return true; - }, - resetCache: function () { - this._rulesets = null; - this._variables = null; - this._lookups = {}; - }, - variables: function () { - if (!this._variables) { - this._variables = !this.rules ? {} : this.rules.reduce(function (hash, r) { - if (r instanceof tree.Rule && r.variable === true) { - hash[r.name] = r; - } - return hash; - }, {}); - } - return this._variables; - }, - variable: function (name) { - return this.variables()[name]; - }, - rulesets: function () { - if (!this.rules) { return null; } - - var _Ruleset = tree.Ruleset, _MixinDefinition = tree.mixin.Definition, - filtRules = [], rules = this.rules, cnt = rules.length, - i, rule; - - for (i = 0; i < cnt; i++) { - rule = rules[i]; - if ((rule instanceof _Ruleset) || (rule instanceof _MixinDefinition)) { - filtRules.push(rule); - } - } - - return filtRules; - }, - prependRule: function (rule) { - var rules = this.rules; - if (rules) { rules.unshift(rule); } else { this.rules = [ rule ]; } - }, - find: function (selector, self) { - self = self || this; - var rules = [], match, - key = selector.toCSS(); - - if (key in this._lookups) { return this._lookups[key]; } - - this.rulesets().forEach(function (rule) { - if (rule !== self) { - for (var j = 0; j < rule.selectors.length; j++) { - match = selector.match(rule.selectors[j]); - if (match) { - if (selector.elements.length > match) { - Array.prototype.push.apply(rules, rule.find( - new(tree.Selector)(selector.elements.slice(match)), self)); - } else { - rules.push(rule); - } - break; - } - } - } - }); - this._lookups[key] = rules; - return rules; - }, - genCSS: function (env, output) { - var i, j, - ruleNodes = [], - rulesetNodes = [], - rulesetNodeCnt, - debugInfo, // Line number debugging - rule, - path; - - env.tabLevel = (env.tabLevel || 0); - - if (!this.root) { - env.tabLevel++; - } - - var tabRuleStr = env.compress ? '' : Array(env.tabLevel + 1).join(" "), - tabSetStr = env.compress ? '' : Array(env.tabLevel).join(" "), - sep; - - for (i = 0; i < this.rules.length; i++) { - rule = this.rules[i]; - if (rule.rules || (rule instanceof tree.Media) || rule instanceof tree.Directive || (this.root && rule instanceof tree.Comment)) { - rulesetNodes.push(rule); - } else { - ruleNodes.push(rule); - } - } - - // If this is the root node, we don't render - // a selector, or {}. - if (!this.root) { - debugInfo = tree.debugInfo(env, this, tabSetStr); - - if (debugInfo) { - output.add(debugInfo); - output.add(tabSetStr); - } - - var paths = this.paths, pathCnt = paths.length, - pathSubCnt; - - sep = env.compress ? ',' : (',\n' + tabSetStr); - - for (i = 0; i < pathCnt; i++) { - path = paths[i]; - if (!(pathSubCnt = path.length)) { continue; } - if (i > 0) { output.add(sep); } - - env.firstSelector = true; - path[0].genCSS(env, output); - - env.firstSelector = false; - for (j = 1; j < pathSubCnt; j++) { - path[j].genCSS(env, output); - } - } - - output.add((env.compress ? '{' : ' {\n') + tabRuleStr); - } - - // Compile rules and rulesets - for (i = 0; i < ruleNodes.length; i++) { - rule = ruleNodes[i]; - - // @page{ directive ends up with root elements inside it, a mix of rules and rulesets - // In this instance we do not know whether it is the last property - if (i + 1 === ruleNodes.length && (!this.root || rulesetNodes.length === 0 || this.firstRoot)) { - env.lastRule = true; - } - - if (rule.genCSS) { - rule.genCSS(env, output); - } else if (rule.value) { - output.add(rule.value.toString()); - } - - if (!env.lastRule) { - output.add(env.compress ? '' : ('\n' + tabRuleStr)); - } else { - env.lastRule = false; - } - } - - if (!this.root) { - output.add((env.compress ? '}' : '\n' + tabSetStr + '}')); - env.tabLevel--; - } - - sep = (env.compress ? "" : "\n") + (this.root ? tabRuleStr : tabSetStr); - rulesetNodeCnt = rulesetNodes.length; - if (rulesetNodeCnt) { - if (ruleNodes.length && sep) { output.add(sep); } - rulesetNodes[0].genCSS(env, output); - for (i = 1; i < rulesetNodeCnt; i++) { - if (sep) { output.add(sep); } - rulesetNodes[i].genCSS(env, output); - } - } - - if (!output.isEmpty() && !env.compress && this.firstRoot) { - output.add('\n'); - } - }, - - toCSS: tree.toCSS, - - markReferenced: function () { - for (var s = 0; s < this.selectors.length; s++) { - this.selectors[s].markReferenced(); - } - }, - - joinSelectors: function (paths, context, selectors) { - for (var s = 0; s < selectors.length; s++) { - this.joinSelector(paths, context, selectors[s]); - } - }, - - joinSelector: function (paths, context, selector) { - - var i, j, k, - hasParentSelector, newSelectors, el, sel, parentSel, - newSelectorPath, afterParentJoin, newJoinedSelector, - newJoinedSelectorEmpty, lastSelector, currentElements, - selectorsMultiplied; - - for (i = 0; i < selector.elements.length; i++) { - el = selector.elements[i]; - if (el.value === '&') { - hasParentSelector = true; - } - } - - if (!hasParentSelector) { - if (context.length > 0) { - for (i = 0; i < context.length; i++) { - paths.push(context[i].concat(selector)); - } - } - else { - paths.push([selector]); - } - return; - } - - // The paths are [[Selector]] - // The first list is a list of comma seperated selectors - // The inner list is a list of inheritance seperated selectors - // e.g. - // .a, .b { - // .c { - // } - // } - // == [[.a] [.c]] [[.b] [.c]] - // - - // the elements from the current selector so far - currentElements = []; - // the current list of new selectors to add to the path. - // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors - // by the parents - newSelectors = [[]]; - - for (i = 0; i < selector.elements.length; i++) { - el = selector.elements[i]; - // non parent reference elements just get added - if (el.value !== "&") { - currentElements.push(el); - } else { - // the new list of selectors to add - selectorsMultiplied = []; - - // merge the current list of non parent selector elements - // on to the current list of selectors to add - if (currentElements.length > 0) { - this.mergeElementsOnToSelectors(currentElements, newSelectors); - } - - // loop through our current selectors - for (j = 0; j < newSelectors.length; j++) { - sel = newSelectors[j]; - // if we don't have any parent paths, the & might be in a mixin so that it can be used - // whether there are parents or not - if (context.length === 0) { - // the combinator used on el should now be applied to the next element instead so that - // it is not lost - if (sel.length > 0) { - sel[0].elements = sel[0].elements.slice(0); - sel[0].elements.push(new(tree.Element)(el.combinator, '', el.index, el.currentFileInfo)); - } - selectorsMultiplied.push(sel); - } - else { - // and the parent selectors - for (k = 0; k < context.length; k++) { - parentSel = context[k]; - // We need to put the current selectors - // then join the last selector's elements on to the parents selectors - - // our new selector path - newSelectorPath = []; - // selectors from the parent after the join - afterParentJoin = []; - newJoinedSelectorEmpty = true; - - //construct the joined selector - if & is the first thing this will be empty, - // if not newJoinedSelector will be the last set of elements in the selector - if (sel.length > 0) { - newSelectorPath = sel.slice(0); - lastSelector = newSelectorPath.pop(); - newJoinedSelector = selector.createDerived(lastSelector.elements.slice(0)); - newJoinedSelectorEmpty = false; - } - else { - newJoinedSelector = selector.createDerived([]); - } - - //put together the parent selectors after the join - if (parentSel.length > 1) { - afterParentJoin = afterParentJoin.concat(parentSel.slice(1)); - } - - if (parentSel.length > 0) { - newJoinedSelectorEmpty = false; - - // join the elements so far with the first part of the parent - newJoinedSelector.elements.push(new(tree.Element)(el.combinator, parentSel[0].elements[0].value, el.index, el.currentFileInfo)); - newJoinedSelector.elements = newJoinedSelector.elements.concat(parentSel[0].elements.slice(1)); - } - - if (!newJoinedSelectorEmpty) { - // now add the joined selector - newSelectorPath.push(newJoinedSelector); - } - - // and the rest of the parent - newSelectorPath = newSelectorPath.concat(afterParentJoin); - - // add that to our new set of selectors - selectorsMultiplied.push(newSelectorPath); - } - } - } - - // our new selectors has been multiplied, so reset the state - newSelectors = selectorsMultiplied; - currentElements = []; - } - } - - // if we have any elements left over (e.g. .a& .b == .b) - // add them on to all the current selectors - if (currentElements.length > 0) { - this.mergeElementsOnToSelectors(currentElements, newSelectors); - } - - for (i = 0; i < newSelectors.length; i++) { - if (newSelectors[i].length > 0) { - paths.push(newSelectors[i]); - } - } - }, - - mergeElementsOnToSelectors: function(elements, selectors) { - var i, sel; - - if (selectors.length === 0) { - selectors.push([ new(tree.Selector)(elements) ]); - return; - } - - for (i = 0; i < selectors.length; i++) { - sel = selectors[i]; - - // if the previous thing in sel is a parent this needs to join on to it - if (sel.length > 0) { - sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements)); - } - else { - sel.push(new(tree.Selector)(elements)); - } - } - } -}; -})(require('../tree')); - -(function (tree) { - -tree.Selector = function (elements, extendList, condition, index, currentFileInfo, isReferenced) { - this.elements = elements; - this.extendList = extendList; - this.condition = condition; - this.currentFileInfo = currentFileInfo || {}; - this.isReferenced = isReferenced; - if (!condition) { - this.evaldCondition = true; - } -}; -tree.Selector.prototype = { - type: "Selector", - accept: function (visitor) { - if (this.elements) { - this.elements = visitor.visitArray(this.elements); - } - if (this.extendList) { - this.extendList = visitor.visitArray(this.extendList); - } - if (this.condition) { - this.condition = visitor.visit(this.condition); - } - }, - createDerived: function(elements, extendList, evaldCondition) { - evaldCondition = (evaldCondition != null) ? evaldCondition : this.evaldCondition; - var newSelector = new(tree.Selector)(elements, extendList || this.extendList, null, this.index, this.currentFileInfo, this.isReferenced); - newSelector.evaldCondition = evaldCondition; - newSelector.mediaEmpty = this.mediaEmpty; - return newSelector; - }, - match: function (other) { - var elements = this.elements, - len = elements.length, - olen, i; - - other.CacheElements(); - - olen = other._elements.length; - if (olen === 0 || len < olen) { - return 0; - } else { - for (i = 0; i < olen; i++) { - if (elements[i].value !== other._elements[i]) { - return 0; - } - } - } - - return olen; // return number of matched elements - }, - CacheElements: function(){ - var css = '', len, v, i; - - if( !this._elements ){ - - len = this.elements.length; - for(i = 0; i < len; i++){ - - v = this.elements[i]; - css += v.combinator.value; - - if( !v.value.value ){ - css += v.value; - continue; - } - - if( typeof v.value.value !== "string" ){ - css = ''; - break; - } - css += v.value.value; - } - - this._elements = css.match(/[,&#\.\w-]([\w-]|(\\.))*/g); - - if (this._elements) { - if (this._elements[0] === "&") { - this._elements.shift(); - } - - } else { - this._elements = []; - } - - } - }, - isJustParentSelector: function() { - return !this.mediaEmpty && - this.elements.length === 1 && - this.elements[0].value === '&' && - (this.elements[0].combinator.value === ' ' || this.elements[0].combinator.value === ''); - }, - eval: function (env) { - var evaldCondition = this.condition && this.condition.eval(env), - elements = this.elements, extendList = this.extendList; - - elements = elements && elements.map(function (e) { return e.eval(env); }); - extendList = extendList && extendList.map(function(extend) { return extend.eval(env); }); - - return this.createDerived(elements, extendList, evaldCondition); - }, - genCSS: function (env, output) { - var i, element; - if ((!env || !env.firstSelector) && this.elements[0].combinator.value === "") { - output.add(' ', this.currentFileInfo, this.index); - } - if (!this._css) { - //TODO caching? speed comparison? - for(i = 0; i < this.elements.length; i++) { - element = this.elements[i]; - element.genCSS(env, output); - } - } - }, - toCSS: tree.toCSS, - markReferenced: function () { - this.isReferenced = true; - }, - getIsReferenced: function() { - return !this.currentFileInfo.reference || this.isReferenced; - }, - getIsOutput: function() { - return this.evaldCondition; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.UnicodeDescriptor = function (value) { - this.value = value; -}; -tree.UnicodeDescriptor.prototype = { - type: "UnicodeDescriptor", - genCSS: function (env, output) { - output.add(this.value); - }, - toCSS: tree.toCSS, - eval: function () { return this; } -}; - -})(require('../tree')); - -(function (tree) { - -tree.URL = function (val, currentFileInfo, isEvald) { - this.value = val; - this.currentFileInfo = currentFileInfo; - this.isEvald = isEvald; -}; -tree.URL.prototype = { - type: "Url", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add("url("); - this.value.genCSS(env, output); - output.add(")"); - }, - toCSS: tree.toCSS, - eval: function (ctx) { - var val = this.value.eval(ctx), - rootpath; - - if (!this.isEvald) { - // Add the base path if the URL is relative - rootpath = this.currentFileInfo && this.currentFileInfo.rootpath; - if (rootpath && typeof val.value === "string" && ctx.isPathRelative(val.value)) { - if (!val.quote) { - rootpath = rootpath.replace(/[\(\)'"\s]/g, function(match) { return "\\"+match; }); - } - val.value = rootpath + val.value; - } - - val.value = ctx.normalizePath(val.value); - - // Add url args if enabled - if (ctx.urlArgs) { - if (!val.value.match(/^\s*data:/)) { - var delimiter = val.value.indexOf('?') === -1 ? '?' : '&'; - var urlArgs = delimiter + ctx.urlArgs; - if (val.value.indexOf('#') !== -1) { - val.value = val.value.replace('#', urlArgs + '#'); - } else { - val.value += urlArgs; - } - } - } - } - - return new(tree.URL)(val, this.currentFileInfo, true); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Value = function (value) { - this.value = value; -}; -tree.Value.prototype = { - type: "Value", - accept: function (visitor) { - if (this.value) { - this.value = visitor.visitArray(this.value); - } - }, - eval: function (env) { - if (this.value.length === 1) { - return this.value[0].eval(env); - } else { - return new(tree.Value)(this.value.map(function (v) { - return v.eval(env); - })); - } - }, - genCSS: function (env, output) { - var i; - for(i = 0; i < this.value.length; i++) { - this.value[i].genCSS(env, output); - if (i+1 < this.value.length) { - output.add((env && env.compress) ? ',' : ', '); - } - } - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -tree.Variable = function (name, index, currentFileInfo) { - this.name = name; - this.index = index; - this.currentFileInfo = currentFileInfo || {}; -}; -tree.Variable.prototype = { - type: "Variable", - eval: function (env) { - var variable, name = this.name; - - if (name.indexOf('@@') === 0) { - name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value; - } - - if (this.evaluating) { - throw { type: 'Name', - message: "Recursive variable definition for " + name, - filename: this.currentFileInfo.file, - index: this.index }; - } - - this.evaluating = true; - - variable = tree.find(env.frames, function (frame) { - var v = frame.variable(name); - if (v) { - return v.value.eval(env); - } - }); - if (variable) { - this.evaluating = false; - return variable; - } else { - throw { type: 'Name', - message: "variable " + name + " is undefined", - filename: this.currentFileInfo.filename, - index: this.index }; - } - } -}; - -})(require('../tree')); - -(function (tree) { - - var parseCopyProperties = [ - 'paths', // option - unmodified - paths to search for imports on - 'optimization', // option - optimization level (for the chunker) - 'files', // list of files that have been imported, used for import-once - 'contents', // map - filename to contents of all the files - 'contentsIgnoredChars', // map - filename to lines at the begining of each file to ignore - 'relativeUrls', // option - whether to adjust URL's to be relative - 'rootpath', // option - rootpath to append to URL's - 'strictImports', // option - - 'insecure', // option - whether to allow imports from insecure ssl hosts - 'dumpLineNumbers', // option - whether to dump line numbers - 'compress', // option - whether to compress - 'processImports', // option - whether to process imports. if false then imports will not be imported - 'syncImport', // option - whether to import synchronously - 'javascriptEnabled',// option - whether JavaScript is enabled. if undefined, defaults to true - 'mime', // browser only - mime type for sheet import - 'useFileCache', // browser only - whether to use the per file session cache - 'currentFileInfo' // information about the current file - for error reporting and importing and making urls relative etc. - ]; - - //currentFileInfo = { - // 'relativeUrls' - option - whether to adjust URL's to be relative - // 'filename' - full resolved filename of current file - // 'rootpath' - path to append to normal URLs for this node - // 'currentDirectory' - path to the current file, absolute - // 'rootFilename' - filename of the base file - // 'entryPath' - absolute path to the entry file - // 'reference' - whether the file should not be output and only output parts that are referenced - - tree.parseEnv = function(options) { - copyFromOriginal(options, this, parseCopyProperties); - - if (!this.contents) { this.contents = {}; } - if (!this.contentsIgnoredChars) { this.contentsIgnoredChars = {}; } - if (!this.files) { this.files = {}; } - - if (!this.currentFileInfo) { - var filename = (options && options.filename) || "input"; - var entryPath = filename.replace(/[^\/\\]*$/, ""); - if (options) { - options.filename = null; - } - this.currentFileInfo = { - filename: filename, - relativeUrls: this.relativeUrls, - rootpath: (options && options.rootpath) || "", - currentDirectory: entryPath, - entryPath: entryPath, - rootFilename: filename - }; - } - }; - - var evalCopyProperties = [ - 'silent', // whether to swallow errors and warnings - 'verbose', // whether to log more activity - 'compress', // whether to compress - 'yuicompress', // whether to compress with the outside tool yui compressor - 'ieCompat', // whether to enforce IE compatibility (IE8 data-uri) - 'strictMath', // whether math has to be within parenthesis - 'strictUnits', // whether units need to evaluate correctly - 'cleancss', // whether to compress with clean-css - 'sourceMap', // whether to output a source map - 'importMultiple', // whether we are currently importing multiple copies - 'urlArgs' // whether to add args into url tokens - ]; - - tree.evalEnv = function(options, frames) { - copyFromOriginal(options, this, evalCopyProperties); - - this.frames = frames || []; - }; - - tree.evalEnv.prototype.inParenthesis = function () { - if (!this.parensStack) { - this.parensStack = []; - } - this.parensStack.push(true); - }; - - tree.evalEnv.prototype.outOfParenthesis = function () { - this.parensStack.pop(); - }; - - tree.evalEnv.prototype.isMathOn = function () { - return this.strictMath ? (this.parensStack && this.parensStack.length) : true; - }; - - tree.evalEnv.prototype.isPathRelative = function (path) { - return !/^(?:[a-z-]+:|\/)/.test(path); - }; - - tree.evalEnv.prototype.normalizePath = function( path ) { - var - segments = path.split("/").reverse(), - segment; - - path = []; - while (segments.length !== 0 ) { - segment = segments.pop(); - switch( segment ) { - case ".": - break; - case "..": - if ((path.length === 0) || (path[path.length - 1] === "..")) { - path.push( segment ); - } else { - path.pop(); - } - break; - default: - path.push( segment ); - break; - } - } - - return path.join("/"); - }; - - //todo - do the same for the toCSS env - //tree.toCSSEnv = function (options) { - //}; - - var copyFromOriginal = function(original, destination, propertiesToCopy) { - if (!original) { return; } - - for(var i = 0; i < propertiesToCopy.length; i++) { - if (original.hasOwnProperty(propertiesToCopy[i])) { - destination[propertiesToCopy[i]] = original[propertiesToCopy[i]]; - } - } - }; - -})(require('./tree')); - -(function (tree) { - - var _visitArgs = { visitDeeper: true }, - _hasIndexed = false; - - function _noop(node) { - return node; - } - - function indexNodeTypes(parent, ticker) { - // add .typeIndex to tree node types for lookup table - var key, child; - for (key in parent) { - if (parent.hasOwnProperty(key)) { - child = parent[key]; - switch (typeof child) { - case "function": - // ignore bound functions directly on tree which do not have a prototype - // or aren't nodes - if (child.prototype && child.prototype.type) { - child.prototype.typeIndex = ticker++; - } - break; - case "object": - ticker = indexNodeTypes(child, ticker); - break; - } - } - } - return ticker; - } - - tree.visitor = function(implementation) { - this._implementation = implementation; - this._visitFnCache = []; - - if (!_hasIndexed) { - indexNodeTypes(tree, 1); - _hasIndexed = true; - } - }; - - tree.visitor.prototype = { - visit: function(node) { - if (!node) { - return node; - } - - var nodeTypeIndex = node.typeIndex; - if (!nodeTypeIndex) { - return node; - } - - var visitFnCache = this._visitFnCache, - impl = this._implementation, - aryIndx = nodeTypeIndex << 1, - outAryIndex = aryIndx | 1, - func = visitFnCache[aryIndx], - funcOut = visitFnCache[outAryIndex], - visitArgs = _visitArgs, - fnName; - - visitArgs.visitDeeper = true; - - if (!func) { - fnName = "visit" + node.type; - func = impl[fnName] || _noop; - funcOut = impl[fnName + "Out"] || _noop; - visitFnCache[aryIndx] = func; - visitFnCache[outAryIndex] = funcOut; - } - - if (func !== _noop) { - var newNode = func.call(impl, node, visitArgs); - if (impl.isReplacing) { - node = newNode; - } - } - - if (visitArgs.visitDeeper && node && node.accept) { - node.accept(this); - } - - if (funcOut != _noop) { - funcOut.call(impl, node); - } - - return node; - }, - visitArray: function(nodes, nonReplacing) { - if (!nodes) { - return nodes; - } - - var cnt = nodes.length, i; - - // Non-replacing - if (nonReplacing || !this._implementation.isReplacing) { - for (i = 0; i < cnt; i++) { - this.visit(nodes[i]); - } - return nodes; - } - - // Replacing - var out = []; - for (i = 0; i < cnt; i++) { - var evald = this.visit(nodes[i]); - if (!evald.splice) { - out.push(evald); - } else if (evald.length) { - this.flatten(evald, out); - } - } - return out; - }, - flatten: function(arr, out) { - if (!out) { - out = []; - } - - var cnt, i, item, - nestedCnt, j, nestedItem; - - for (i = 0, cnt = arr.length; i < cnt; i++) { - item = arr[i]; - if (!item.splice) { - out.push(item); - continue; - } - - for (j = 0, nestedCnt = item.length; j < nestedCnt; j++) { - nestedItem = item[j]; - if (!nestedItem.splice) { - out.push(nestedItem); - } else if (nestedItem.length) { - this.flatten(nestedItem, out); - } - } - } - - return out; - } - }; - -})(require('./tree')); -(function (tree) { - tree.importVisitor = function(importer, finish, evalEnv) { - this._visitor = new tree.visitor(this); - this._importer = importer; - this._finish = finish; - this.env = evalEnv || new tree.evalEnv(); - this.importCount = 0; - }; - - tree.importVisitor.prototype = { - isReplacing: true, - run: function (root) { - var error; - try { - // process the contents - this._visitor.visit(root); - } - catch(e) { - error = e; - } - - this.isFinished = true; - - if (this.importCount === 0) { - this._finish(error); - } - }, - visitImport: function (importNode, visitArgs) { - var importVisitor = this, - evaldImportNode, - inlineCSS = importNode.options.inline; - - if (!importNode.css || inlineCSS) { - - try { - evaldImportNode = importNode.evalForImport(this.env); - } catch(e){ - if (!e.filename) { e.index = importNode.index; e.filename = importNode.currentFileInfo.filename; } - // attempt to eval properly and treat as css - importNode.css = true; - // if that fails, this error will be thrown - importNode.error = e; - } - - if (evaldImportNode && (!evaldImportNode.css || inlineCSS)) { - importNode = evaldImportNode; - this.importCount++; - var env = new tree.evalEnv(this.env, this.env.frames.slice(0)); - - if (importNode.options.multiple) { - env.importMultiple = true; - } - - this._importer.push(importNode.getPath(), importNode.currentFileInfo, importNode.options, function (e, root, imported, fullPath) { - if (e && !e.filename) { e.index = importNode.index; e.filename = importNode.currentFileInfo.filename; } - - if (imported && !env.importMultiple) { importNode.skip = imported; } - - var subFinish = function(e) { - importVisitor.importCount--; - - if (importVisitor.importCount === 0 && importVisitor.isFinished) { - importVisitor._finish(e); - } - }; - - if (root) { - importNode.root = root; - importNode.importedFilename = fullPath; - if (!inlineCSS && !importNode.skip) { - new(tree.importVisitor)(importVisitor._importer, subFinish, env) - .run(root); - return; - } - } - - subFinish(); - }); - } - } - visitArgs.visitDeeper = false; - return importNode; - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - return ruleNode; - }, - visitDirective: function (directiveNode, visitArgs) { - this.env.frames.unshift(directiveNode); - return directiveNode; - }, - visitDirectiveOut: function (directiveNode) { - this.env.frames.shift(); - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - this.env.frames.unshift(mixinDefinitionNode); - return mixinDefinitionNode; - }, - visitMixinDefinitionOut: function (mixinDefinitionNode) { - this.env.frames.shift(); - }, - visitRuleset: function (rulesetNode, visitArgs) { - this.env.frames.unshift(rulesetNode); - return rulesetNode; - }, - visitRulesetOut: function (rulesetNode) { - this.env.frames.shift(); - }, - visitMedia: function (mediaNode, visitArgs) { - this.env.frames.unshift(mediaNode.ruleset); - return mediaNode; - }, - visitMediaOut: function (mediaNode) { - this.env.frames.shift(); - } - }; - -})(require('./tree')); -(function (tree) { - tree.joinSelectorVisitor = function() { - this.contexts = [[]]; - this._visitor = new tree.visitor(this); - }; - - tree.joinSelectorVisitor.prototype = { - run: function (root) { - return this._visitor.visit(root); - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - - visitRuleset: function (rulesetNode, visitArgs) { - var context = this.contexts[this.contexts.length - 1], - paths = [], selectors; - - this.contexts.push(paths); - - if (! rulesetNode.root) { - selectors = rulesetNode.selectors; - if (selectors) { - selectors = selectors.filter(function(selector) { return selector.getIsOutput(); }); - rulesetNode.selectors = selectors.length ? selectors : (selectors = null); - if (selectors) { rulesetNode.joinSelectors(paths, context, selectors); } - } - if (!selectors) { rulesetNode.rules = null; } - rulesetNode.paths = paths; - } - }, - visitRulesetOut: function (rulesetNode) { - this.contexts.length = this.contexts.length - 1; - }, - visitMedia: function (mediaNode, visitArgs) { - var context = this.contexts[this.contexts.length - 1]; - mediaNode.rules[0].root = (context.length === 0 || context[0].multiMedia); - } - }; - -})(require('./tree')); -(function (tree) { - tree.toCSSVisitor = function(env) { - this._visitor = new tree.visitor(this); - this._env = env; - }; - - tree.toCSSVisitor.prototype = { - isReplacing: true, - run: function (root) { - return this._visitor.visit(root); - }, - - visitRule: function (ruleNode, visitArgs) { - if (ruleNode.variable) { - return []; - } - return ruleNode; - }, - - visitMixinDefinition: function (mixinNode, visitArgs) { - // mixin definitions do not get eval'd - this means they keep state - // so we have to clear that state here so it isn't used if toCSS is called twice - mixinNode.frames = []; - return []; - }, - - visitExtend: function (extendNode, visitArgs) { - return []; - }, - - visitComment: function (commentNode, visitArgs) { - if (commentNode.isSilent(this._env)) { - return []; - } - return commentNode; - }, - - visitMedia: function(mediaNode, visitArgs) { - mediaNode.accept(this._visitor); - visitArgs.visitDeeper = false; - - if (!mediaNode.rules.length) { - return []; - } - return mediaNode; - }, - - visitDirective: function(directiveNode, visitArgs) { - if (directiveNode.currentFileInfo.reference && !directiveNode.isReferenced) { - return []; - } - if (directiveNode.name === "@charset") { - // Only output the debug info together with subsequent @charset definitions - // a comment (or @media statement) before the actual @charset directive would - // be considered illegal css as it has to be on the first line - if (this.charset) { - if (directiveNode.debugInfo) { - var comment = new tree.Comment("/* " + directiveNode.toCSS(this._env).replace(/\n/g, "")+" */\n"); - comment.debugInfo = directiveNode.debugInfo; - return this._visitor.visit(comment); - } - return []; - } - this.charset = true; - } - return directiveNode; - }, - - checkPropertiesInRoot: function(rules) { - var ruleNode; - for(var i = 0; i < rules.length; i++) { - ruleNode = rules[i]; - if (ruleNode instanceof tree.Rule && !ruleNode.variable) { - throw { message: "properties must be inside selector blocks, they cannot be in the root.", - index: ruleNode.index, filename: ruleNode.currentFileInfo ? ruleNode.currentFileInfo.filename : null}; - } - } - }, - - visitRuleset: function (rulesetNode, visitArgs) { - var rule, rulesets = []; - if (rulesetNode.firstRoot) { - this.checkPropertiesInRoot(rulesetNode.rules); - } - if (! rulesetNode.root) { - if (rulesetNode.paths) { - rulesetNode.paths = rulesetNode.paths - .filter(function(p) { - var i; - if (p[0].elements[0].combinator.value === ' ') { - p[0].elements[0].combinator = new(tree.Combinator)(''); - } - for(i = 0; i < p.length; i++) { - if (p[i].getIsReferenced() && p[i].getIsOutput()) { - return true; - } - } - return false; - }); - } - - // Compile rules and rulesets - var nodeRules = rulesetNode.rules, nodeRuleCnt = nodeRules ? nodeRules.length : 0; - for (var i = 0; i < nodeRuleCnt; ) { - rule = nodeRules[i]; - if (rule && rule.rules) { - // visit because we are moving them out from being a child - rulesets.push(this._visitor.visit(rule)); - nodeRules.splice(i, 1); - nodeRuleCnt--; - continue; - } - i++; - } - // accept the visitor to remove rules and refactor itself - // then we can decide now whether we want it or not - if (nodeRuleCnt > 0) { - rulesetNode.accept(this._visitor); - } else { - rulesetNode.rules = null; - } - visitArgs.visitDeeper = false; - - nodeRules = rulesetNode.rules; - if (nodeRules) { - this._mergeRules(nodeRules); - nodeRules = rulesetNode.rules; - } - if (nodeRules) { - this._removeDuplicateRules(nodeRules); - nodeRules = rulesetNode.rules; - } - - // now decide whether we keep the ruleset - if (nodeRules && nodeRules.length > 0 && rulesetNode.paths.length > 0) { - rulesets.splice(0, 0, rulesetNode); - } - } else { - rulesetNode.accept(this._visitor); - visitArgs.visitDeeper = false; - if (rulesetNode.firstRoot || (rulesetNode.rules && rulesetNode.rules.length > 0)) { - rulesets.splice(0, 0, rulesetNode); - } - } - if (rulesets.length === 1) { - return rulesets[0]; - } - return rulesets; - }, - - _removeDuplicateRules: function(rules) { - if (!rules) { return; } - - // remove duplicates - var ruleCache = {}, - ruleList, rule, i; - - for(i = rules.length - 1; i >= 0 ; i--) { - rule = rules[i]; - if (rule instanceof tree.Rule) { - if (!ruleCache[rule.name]) { - ruleCache[rule.name] = rule; - } else { - ruleList = ruleCache[rule.name]; - if (ruleList instanceof tree.Rule) { - ruleList = ruleCache[rule.name] = [ruleCache[rule.name].toCSS(this._env)]; - } - var ruleCSS = rule.toCSS(this._env); - if (ruleList.indexOf(ruleCSS) !== -1) { - rules.splice(i, 1); - } else { - ruleList.push(ruleCSS); - } - } - } - } - }, - - _mergeRules: function (rules) { - if (!rules) { return; } - - var groups = {}, - parts, - rule, - key; - - for (var i = 0; i < rules.length; i++) { - rule = rules[i]; - - if ((rule instanceof tree.Rule) && rule.merge) { - key = [rule.name, - rule.important ? "!" : ""].join(","); - - if (!groups[key]) { - groups[key] = []; - } else { - rules.splice(i--, 1); - } - - groups[key].push(rule); - } - } - - Object.keys(groups).map(function (k) { - parts = groups[k]; - - if (parts.length > 1) { - rule = parts[0]; - - rule.value = new (tree.Value)(parts.map(function (p) { - return p.value; - })); - } - }); - } - }; - -})(require('./tree')); -(function (tree) { - /*jshint loopfunc:true */ - - tree.extendFinderVisitor = function() { - this._visitor = new tree.visitor(this); - this.contexts = []; - this.allExtendsStack = [[]]; - }; - - tree.extendFinderVisitor.prototype = { - run: function (root) { - root = this._visitor.visit(root); - root.allExtends = this.allExtendsStack[0]; - return root; - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitRuleset: function (rulesetNode, visitArgs) { - if (rulesetNode.root) { - return; - } - - var i, j, extend, allSelectorsExtendList = [], extendList; - - // get &:extend(.a); rules which apply to all selectors in this ruleset - var rules = rulesetNode.rules, ruleCnt = rules ? rules.length : 0; - for(i = 0; i < ruleCnt; i++) { - if (rulesetNode.rules[i] instanceof tree.Extend) { - allSelectorsExtendList.push(rules[i]); - rulesetNode.extendOnEveryPath = true; - } - } - - // now find every selector and apply the extends that apply to all extends - // and the ones which apply to an individual extend - var paths = rulesetNode.paths; - for(i = 0; i < paths.length; i++) { - var selectorPath = paths[i], - selector = selectorPath[selectorPath.length - 1], - selExtendList = selector.extendList; - - extendList = selExtendList ? selExtendList.slice(0).concat(allSelectorsExtendList) - : allSelectorsExtendList; - - if (extendList) { - extendList = extendList.map(function(allSelectorsExtend) { - return allSelectorsExtend.clone(); - }); - } - - for(j = 0; j < extendList.length; j++) { - this.foundExtends = true; - extend = extendList[j]; - extend.findSelfSelectors(selectorPath); - extend.ruleset = rulesetNode; - if (j === 0) { extend.firstExtendOnThisSelectorPath = true; } - this.allExtendsStack[this.allExtendsStack.length-1].push(extend); - } - } - - this.contexts.push(rulesetNode.selectors); - }, - visitRulesetOut: function (rulesetNode) { - if (!rulesetNode.root) { - this.contexts.length = this.contexts.length - 1; - } - }, - visitMedia: function (mediaNode, visitArgs) { - mediaNode.allExtends = []; - this.allExtendsStack.push(mediaNode.allExtends); - }, - visitMediaOut: function (mediaNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - }, - visitDirective: function (directiveNode, visitArgs) { - directiveNode.allExtends = []; - this.allExtendsStack.push(directiveNode.allExtends); - }, - visitDirectiveOut: function (directiveNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - } - }; - - tree.processExtendsVisitor = function() { - this._visitor = new tree.visitor(this); - }; - - tree.processExtendsVisitor.prototype = { - run: function(root) { - var extendFinder = new tree.extendFinderVisitor(); - extendFinder.run(root); - if (!extendFinder.foundExtends) { return root; } - root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends)); - this.allExtendsStack = [root.allExtends]; - return this._visitor.visit(root); - }, - doExtendChaining: function (extendsList, extendsListTarget, iterationCount) { - // - // chaining is different from normal extension.. if we extend an extend then we are not just copying, altering and pasting - // the selector we would do normally, but we are also adding an extend with the same target selector - // this means this new extend can then go and alter other extends - // - // this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors - // this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already processed if - // we look at each selector at a time, as is done in visitRuleset - - var extendIndex, targetExtendIndex, matches, extendsToAdd = [], newSelector, extendVisitor = this, selectorPath, extend, targetExtend, newExtend; - - iterationCount = iterationCount || 0; - - //loop through comparing every extend with every target extend. - // a target extend is the one on the ruleset we are looking at copy/edit/pasting in place - // e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one - // and the second is the target. - // the seperation into two lists allows us to process a subset of chains with a bigger set, as is the - // case when processing media queries - for(extendIndex = 0; extendIndex < extendsList.length; extendIndex++){ - for(targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++){ - - extend = extendsList[extendIndex]; - targetExtend = extendsListTarget[targetExtendIndex]; - - // look for circular references - if( extend.parent_ids.indexOf( targetExtend.object_id ) >= 0 ){ continue; } - - // find a match in the target extends self selector (the bit before :extend) - selectorPath = [targetExtend.selfSelectors[0]]; - matches = extendVisitor.findMatch(extend, selectorPath); - - if (matches.length) { - - // we found a match, so for each self selector.. - extend.selfSelectors.forEach(function(selfSelector) { - - // process the extend as usual - newSelector = extendVisitor.extendSelector(matches, selectorPath, selfSelector); - - // but now we create a new extend from it - newExtend = new(tree.Extend)(targetExtend.selector, targetExtend.option, 0); - newExtend.selfSelectors = newSelector; - - // add the extend onto the list of extends for that selector - newSelector[newSelector.length-1].extendList = [newExtend]; - - // record that we need to add it. - extendsToAdd.push(newExtend); - newExtend.ruleset = targetExtend.ruleset; - - //remember its parents for circular references - newExtend.parent_ids = newExtend.parent_ids.concat(targetExtend.parent_ids, extend.parent_ids); - - // only process the selector once.. if we have :extend(.a,.b) then multiple - // extends will look at the same selector path, so when extending - // we know that any others will be duplicates in terms of what is added to the css - if (targetExtend.firstExtendOnThisSelectorPath) { - newExtend.firstExtendOnThisSelectorPath = true; - targetExtend.ruleset.paths.push(newSelector); - } - }); - } - } - } - - if (extendsToAdd.length) { - // try to detect circular references to stop a stack overflow. - // may no longer be needed. - this.extendChainCount++; - if (iterationCount > 100) { - var selectorOne = "{unable to calculate}"; - var selectorTwo = "{unable to calculate}"; - try - { - selectorOne = extendsToAdd[0].selfSelectors[0].toCSS(); - selectorTwo = extendsToAdd[0].selector.toCSS(); - } - catch(e) {} - throw {message: "extend circular reference detected. One of the circular extends is currently:"+selectorOne+":extend(" + selectorTwo+")"}; - } - - // now process the new extends on the existing rules so that we can handle a extending b extending c ectending d extending e... - return extendsToAdd.concat(extendVisitor.doExtendChaining(extendsToAdd, extendsListTarget, iterationCount+1)); - } else { - return extendsToAdd; - } - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitSelector: function (selectorNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitRuleset: function (rulesetNode, visitArgs) { - if (rulesetNode.root) { - return; - } - var matches, pathIndex, extendIndex, allExtends = this.allExtendsStack[this.allExtendsStack.length-1], selectorsToAdd = [], extendVisitor = this, selectorPath; - - // look at each selector path in the ruleset, find any extend matches and then copy, find and replace - - for(extendIndex = 0; extendIndex < allExtends.length; extendIndex++) { - for(pathIndex = 0; pathIndex < rulesetNode.paths.length; pathIndex++) { - selectorPath = rulesetNode.paths[pathIndex]; - - // extending extends happens initially, before the main pass - if (rulesetNode.extendOnEveryPath) { continue; } - var extendList = selectorPath[selectorPath.length-1].extendList; - if (extendList && extendList.length) { continue; } - - matches = this.findMatch(allExtends[extendIndex], selectorPath); - - if (matches.length) { - - allExtends[extendIndex].selfSelectors.forEach(function(selfSelector) { - selectorsToAdd.push(extendVisitor.extendSelector(matches, selectorPath, selfSelector)); - }); - } - } - } - rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd); - }, - findMatch: function (extend, haystackSelectorPath) { - // - // look through the haystack selector path to try and find the needle - extend.selector - // returns an array of selector matches that can then be replaced - // - var haystackSelectorIndex, hackstackSelector, hackstackElementIndex, haystackElement, - targetCombinator, i, - extendVisitor = this, - needleElements = extend.selector.elements, - potentialMatches = [], potentialMatch, matches = []; - - // loop through the haystack elements - for(haystackSelectorIndex = 0; haystackSelectorIndex < haystackSelectorPath.length; haystackSelectorIndex++) { - hackstackSelector = haystackSelectorPath[haystackSelectorIndex]; - - for(hackstackElementIndex = 0; hackstackElementIndex < hackstackSelector.elements.length; hackstackElementIndex++) { - - haystackElement = hackstackSelector.elements[hackstackElementIndex]; - - // if we allow elements before our match we can add a potential match every time. otherwise only at the first element. - if (extend.allowBefore || (haystackSelectorIndex === 0 && hackstackElementIndex === 0)) { - potentialMatches.push({pathIndex: haystackSelectorIndex, index: hackstackElementIndex, matched: 0, initialCombinator: haystackElement.combinator}); - } - - for(i = 0; i < potentialMatches.length; i++) { - potentialMatch = potentialMatches[i]; - - // selectors add " " onto the first element. When we use & it joins the selectors together, but if we don't - // then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to work out - // what the resulting combinator will be - targetCombinator = haystackElement.combinator.value; - if (targetCombinator === '' && hackstackElementIndex === 0) { - targetCombinator = ' '; - } - - // if we don't match, null our match to indicate failure - if (!extendVisitor.isElementValuesEqual(needleElements[potentialMatch.matched].value, haystackElement.value) || - (potentialMatch.matched > 0 && needleElements[potentialMatch.matched].combinator.value !== targetCombinator)) { - potentialMatch = null; - } else { - potentialMatch.matched++; - } - - // if we are still valid and have finished, test whether we have elements after and whether these are allowed - if (potentialMatch) { - potentialMatch.finished = potentialMatch.matched === needleElements.length; - if (potentialMatch.finished && - (!extend.allowAfter && (hackstackElementIndex+1 < hackstackSelector.elements.length || haystackSelectorIndex+1 < haystackSelectorPath.length))) { - potentialMatch = null; - } - } - // if null we remove, if not, we are still valid, so either push as a valid match or continue - if (potentialMatch) { - if (potentialMatch.finished) { - potentialMatch.length = needleElements.length; - potentialMatch.endPathIndex = haystackSelectorIndex; - potentialMatch.endPathElementIndex = hackstackElementIndex + 1; // index after end of match - potentialMatches.length = 0; // we don't allow matches to overlap, so start matching again - matches.push(potentialMatch); - } - } else { - potentialMatches.splice(i, 1); - i--; - } - } - } - } - return matches; - }, - isElementValuesEqual: function(elementValue1, elementValue2) { - if (typeof elementValue1 === "string" || typeof elementValue2 === "string") { - return elementValue1 === elementValue2; - } - if (elementValue1 instanceof tree.Attribute) { - if (elementValue1.op !== elementValue2.op || elementValue1.key !== elementValue2.key) { - return false; - } - if (!elementValue1.value || !elementValue2.value) { - if (elementValue1.value || elementValue2.value) { - return false; - } - return true; - } - elementValue1 = elementValue1.value.value || elementValue1.value; - elementValue2 = elementValue2.value.value || elementValue2.value; - return elementValue1 === elementValue2; - } - elementValue1 = elementValue1.value; - elementValue2 = elementValue2.value; - if (elementValue1 instanceof tree.Selector) { - if (!(elementValue2 instanceof tree.Selector) || elementValue1.elements.length !== elementValue2.elements.length) { - return false; - } - for(var i = 0; i currentSelectorPathIndex && currentSelectorPathElementIndex > 0) { - path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); - currentSelectorPathElementIndex = 0; - currentSelectorPathIndex++; - } - - newElements = selector.elements - .slice(currentSelectorPathElementIndex, match.index) - .concat([firstElement]) - .concat(replacementSelector.elements.slice(1)); - - if (currentSelectorPathIndex === match.pathIndex && matchIndex > 0) { - path[path.length - 1].elements = - path[path.length - 1].elements.concat(newElements); - } else { - path = path.concat(selectorPath.slice(currentSelectorPathIndex, match.pathIndex)); - - path.push(new tree.Selector( - newElements - )); - } - currentSelectorPathIndex = match.endPathIndex; - currentSelectorPathElementIndex = match.endPathElementIndex; - if (currentSelectorPathElementIndex >= selectorPath[currentSelectorPathIndex].elements.length) { - currentSelectorPathElementIndex = 0; - currentSelectorPathIndex++; - } - } - - if (currentSelectorPathIndex < selectorPath.length && currentSelectorPathElementIndex > 0) { - path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); - currentSelectorPathIndex++; - } - - path = path.concat(selectorPath.slice(currentSelectorPathIndex, selectorPath.length)); - - return path; - }, - visitRulesetOut: function (rulesetNode) { - }, - visitMedia: function (mediaNode, visitArgs) { - var newAllExtends = mediaNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]); - newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, mediaNode.allExtends)); - this.allExtendsStack.push(newAllExtends); - }, - visitMediaOut: function (mediaNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - }, - visitDirective: function (directiveNode, visitArgs) { - var newAllExtends = directiveNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]); - newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, directiveNode.allExtends)); - this.allExtendsStack.push(newAllExtends); - }, - visitDirectiveOut: function (directiveNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - } - }; - -})(require('./tree')); - -(function (tree) { - - tree.sourceMapOutput = function (options) { - this._css = []; - this._rootNode = options.rootNode; - this._writeSourceMap = options.writeSourceMap; - this._contentsMap = options.contentsMap; - this._contentsIgnoredCharsMap = options.contentsIgnoredCharsMap; - this._sourceMapFilename = options.sourceMapFilename; - this._outputFilename = options.outputFilename; - this._sourceMapURL = options.sourceMapURL; - if (options.sourceMapBasepath) { - this._sourceMapBasepath = options.sourceMapBasepath.replace(/\\/g, '/'); - } - this._sourceMapRootpath = options.sourceMapRootpath; - this._outputSourceFiles = options.outputSourceFiles; - this._sourceMapGeneratorConstructor = options.sourceMapGenerator || require("source-map").SourceMapGenerator; - - if (this._sourceMapRootpath && this._sourceMapRootpath.charAt(this._sourceMapRootpath.length-1) !== '/') { - this._sourceMapRootpath += '/'; - } - - this._lineNumber = 0; - this._column = 0; - }; - - tree.sourceMapOutput.prototype.normalizeFilename = function(filename) { - filename = filename.replace(/\\/g, '/'); - - if (this._sourceMapBasepath && filename.indexOf(this._sourceMapBasepath) === 0) { - filename = filename.substring(this._sourceMapBasepath.length); - if (filename.charAt(0) === '\\' || filename.charAt(0) === '/') { - filename = filename.substring(1); - } - } - return (this._sourceMapRootpath || "") + filename; - }; - - tree.sourceMapOutput.prototype.add = function(chunk, fileInfo, index, mapLines) { - - //ignore adding empty strings - if (!chunk) { - return; - } - - var lines, - sourceLines, - columns, - sourceColumns, - i; - - if (fileInfo) { - var inputSource = this._contentsMap[fileInfo.filename]; - - // remove vars/banner added to the top of the file - if (this._contentsIgnoredCharsMap[fileInfo.filename]) { - // adjust the index - index -= this._contentsIgnoredCharsMap[fileInfo.filename]; - if (index < 0) { index = 0; } - // adjust the source - inputSource = inputSource.slice(this._contentsIgnoredCharsMap[fileInfo.filename]); - } - inputSource = inputSource.substring(0, index); - sourceLines = inputSource.split("\n"); - sourceColumns = sourceLines[sourceLines.length-1]; - } - - lines = chunk.split("\n"); - columns = lines[lines.length-1]; - - if (fileInfo) { - if (!mapLines) { - this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + 1, column: this._column}, - original: { line: sourceLines.length, column: sourceColumns.length}, - source: this.normalizeFilename(fileInfo.filename)}); - } else { - for(i = 0; i < lines.length; i++) { - this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + i + 1, column: i === 0 ? this._column : 0}, - original: { line: sourceLines.length + i, column: i === 0 ? sourceColumns.length : 0}, - source: this.normalizeFilename(fileInfo.filename)}); - } - } - } - - if (lines.length === 1) { - this._column += columns.length; - } else { - this._lineNumber += lines.length - 1; - this._column = columns.length; - } - - this._css.push(chunk); - }; - - tree.sourceMapOutput.prototype.isEmpty = function() { - return this._css.length === 0; - }; - - tree.sourceMapOutput.prototype.toCSS = function(env) { - this._sourceMapGenerator = new this._sourceMapGeneratorConstructor({ file: this._outputFilename, sourceRoot: null }); - - if (this._outputSourceFiles) { - for(var filename in this._contentsMap) { - if (this._contentsMap.hasOwnProperty(filename)) - { - var source = this._contentsMap[filename]; - if (this._contentsIgnoredCharsMap[filename]) { - source = source.slice(this._contentsIgnoredCharsMap[filename]); - } - this._sourceMapGenerator.setSourceContent(this.normalizeFilename(filename), source); - } - } - } - - this._rootNode.genCSS(env, this); - - if (this._css.length > 0) { - var sourceMapURL, - sourceMapContent = JSON.stringify(this._sourceMapGenerator.toJSON()); - - if (this._sourceMapURL) { - sourceMapURL = this._sourceMapURL; - } else if (this._sourceMapFilename) { - sourceMapURL = this.normalizeFilename(this._sourceMapFilename); - } - - if (this._writeSourceMap) { - this._writeSourceMap(sourceMapContent); - } else { - sourceMapURL = "data:application/json," + encodeURIComponent(sourceMapContent); - } - - if (sourceMapURL) { - this._css.push("/*# sourceMappingURL=" + sourceMapURL + " */"); - } - } - - return this._css.join(''); - }; - -})(require('./tree')); - -// -// browser.js - client-side engine -// -/*global less, window, document, XMLHttpRequest, location */ - -var isFileProtocol = /^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol); - -less.env = less.env || (location.hostname == '127.0.0.1' || - location.hostname == '0.0.0.0' || - location.hostname == 'localhost' || - (location.port && - location.port.length > 0) || - isFileProtocol ? 'development' - : 'production'); - -var logLevel = { - info: 2, - errors: 1, - none: 0 -}; - -// The amount of logging in the javascript console. -// 2 - Information and errors -// 1 - Errors -// 0 - None -// Defaults to 2 -less.logLevel = typeof(less.logLevel) != 'undefined' ? less.logLevel : logLevel.info; - -// Load styles asynchronously (default: false) -// -// This is set to `false` by default, so that the body -// doesn't start loading before the stylesheets are parsed. -// Setting this to `true` can result in flickering. -// -less.async = less.async || false; -less.fileAsync = less.fileAsync || false; - -// Interval between watch polls -less.poll = less.poll || (isFileProtocol ? 1000 : 1500); - -//Setup user functions -if (less.functions) { - for(var func in less.functions) { - if (less.functions.hasOwnProperty(func)) { - less.tree.functions[func] = less.functions[func]; - } - } -} - -var dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(location.hash); -if (dumpLineNumbers) { - less.dumpLineNumbers = dumpLineNumbers[1]; -} - -var typePattern = /^text\/(x-)?less$/; -var cache = null; -var fileCache = {}; - -function log(str, level) { - console.log(str); -} - -function extractId(href) { - return href.replace(/^[a-z-]+:\/+?[^\/]+/, '' ) // Remove protocol & domain - .replace(/^\//, '' ) // Remove root / - .replace(/\.[a-zA-Z]+$/, '' ) // Remove simple extension - .replace(/[^\.\w-]+/g, '-') // Replace illegal characters - .replace(/\./g, ':'); // Replace dots with colons(for valid id) -} - -function errorConsole(e, rootHref) { - var template = '{line} {content}'; - var filename = e.filename || rootHref; - var errors = []; - var content = (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') + - " in " + filename + " "; - - var errorline = function (e, i, classname) { - if (e.extract[i] !== undefined) { - errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1)) - .replace(/\{class\}/, classname) - .replace(/\{content\}/, e.extract[i])); - } - }; - - if (e.extract) { - errorline(e, 0, ''); - errorline(e, 1, 'line'); - errorline(e, 2, ''); - content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':\n' + - errors.join('\n'); - } else if (e.stack) { - content += e.stack; - } - log(content, logLevel.errors); -} - -function createCSS(styles, sheet, lastModified) { - // Strip the query-string - var href = sheet.href || ''; - - // If there is no title set, use the filename, minus the extension - var id = 'less:' + (sheet.title || extractId(href)); - - // If this has already been inserted into the DOM, we may need to replace it - var oldCss = document.getElementById(id); - var keepOldCss = false; - - // Create a new stylesheet node for insertion or (if necessary) replacement - var css = document.createElement('style'); - css.setAttribute('type', 'text/css'); - if (sheet.media) { - css.setAttribute('media', sheet.media); - } - css.id = id; - - if (css.styleSheet) { // IE - try { - css.styleSheet.cssText = styles; - } catch (e) { - throw new(Error)("Couldn't reassign styleSheet.cssText."); - } - } else { - css.appendChild(document.createTextNode(styles)); - - // If new contents match contents of oldCss, don't replace oldCss - keepOldCss = (oldCss !== null && oldCss.childNodes.length > 0 && css.childNodes.length > 0 && - oldCss.firstChild.nodeValue === css.firstChild.nodeValue); - } - - var head = document.getElementsByTagName('head')[0]; - - // If there is no oldCss, just append; otherwise, only append if we need - // to replace oldCss with an updated stylesheet - if (oldCss === null || keepOldCss === false) { - var nextEl = sheet && sheet.nextSibling || null; - if (nextEl) { - nextEl.parentNode.insertBefore(css, nextEl); - } else { - head.appendChild(css); - } - } - if (oldCss && keepOldCss === false) { - oldCss.parentNode.removeChild(oldCss); - } - - // Don't update the local store if the file wasn't modified - if (lastModified && cache) { - //log('saving ' + href + ' to cache.', logLevel.info); - try { - cache.setItem(href, styles); - cache.setItem(href + ':timestamp', lastModified); - } catch(e) { - //TODO - could do with adding more robust error handling - //log('failed to save', logLevel.errors); - } - } -} - -function errorHTML(e, rootHref) { - var id = 'less-error-message:' + extractId(rootHref || ""); - var template = '
  • {content}
  • '; - var elem = document.createElement('div'), timer, content, errors = []; - var filename = e.filename || rootHref; - var filenameNoPath = filename.match(/([^\/]+(\?.*)?)$/)[1]; - - elem.id = id; - elem.className = "less-error-message"; - - content = '

    ' + (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') + - '

    ' + '
    ' + - '
      ' + errors.join('') + '
    '; - } else if (e.stack) { - content += '
    ' + e.stack.split('\n').slice(1).join('
    '); - } - elem.innerHTML = content; - - // CSS for error messages - createCSS([ - '.less-error-message ul, .less-error-message li {', - 'list-style-type: none;', - 'margin-right: 15px;', - 'padding: 4px 0;', - 'margin: 0;', - '}', - '.less-error-message label {', - 'font-size: 12px;', - 'margin-right: 15px;', - 'padding: 4px 0;', - 'color: #cc7777;', - '}', - '.less-error-message pre {', - 'color: #dd6666;', - 'padding: 4px 0;', - 'margin: 0;', - 'display: inline-block;', - '}', - '.less-error-message pre.line {', - 'color: #ff0000;', - '}', - '.less-error-message h3 {', - 'font-size: 20px;', - 'font-weight: bold;', - 'padding: 15px 0 5px 0;', - 'margin: 0;', - '}', - '.less-error-message a {', - 'color: #10a', - '}', - '.less-error-message .error {', - 'color: red;', - 'font-weight: bold;', - 'padding-bottom: 2px;', - 'border-bottom: 1px dashed red;', - '}' - ].join('\n'), { title: 'error-message' }); - - elem.style.cssText = [ - "font-family: Arial, sans-serif", - "border: 1px solid #e00", - "background-color: #eee", - "border-radius: 5px", - "-webkit-border-radius: 5px", - "-moz-border-radius: 5px", - "color: #e00", - "padding: 15px", - "margin-bottom: 15px" - ].join(';'); - - if (less.env == 'development') { - timer = setInterval(function () { - if (document.body) { - if (document.getElementById(id)) { - document.body.replaceChild(elem, document.getElementById(id)); - } else { - document.body.insertBefore(elem, document.body.firstChild); - } - clearInterval(timer); - } - }, 10); - } -} - -function error(e, rootHref) { - if (!less.errorReporting || less.errorReporting === "html") { - errorHTML(e, rootHref); - } else if (less.errorReporting === "console") { - errorConsole(e, rootHref); - } else if (typeof less.errorReporting === 'function') { - less.errorReporting("add", e, rootHref); - } -} - -function removeErrorHTML(path) { - var node = document.getElementById('less-error-message:' + extractId(path)); - if (node) { - node.parentNode.removeChild(node); - } -} - -function removeErrorConsole(path) { - //no action -} - -function removeError(path) { - if (!less.errorReporting || less.errorReporting === "html") { - removeErrorHTML(path); - } else if (less.errorReporting === "console") { - removeErrorConsole(path); - } else if (typeof less.errorReporting === 'function') { - less.errorReporting("remove", path); - } -} - -function loadStyles(modifyVars) { - var styles = document.getElementsByTagName('style'), - style; - for (var i = 0; i < styles.length; i++) { - style = styles[i]; - if (style.type.match(typePattern)) { - var env = new less.tree.parseEnv(less), - lessText = style.innerHTML || ''; - env.filename = document.location.href.replace(/#.*$/, ''); - - if (modifyVars || less.globalVars) { - env.useFileCache = true; - } - - /*jshint loopfunc:true */ - // use closure to store current value of i - var callback = (function(style) { - return function (e, cssAST) { - if (e) { - return error(e, "inline"); - } - var css = cssAST.toCSS(less); - style.type = 'text/css'; - if (style.styleSheet) { - style.styleSheet.cssText = css; - } else { - style.innerHTML = css; - } - }; - })(style); - new(less.Parser)(env).parse(lessText, callback, {globalVars: less.globalVars, modifyVars: modifyVars}); - } - } -} - -function extractUrlParts(url, baseUrl) { - // urlParts[1] = protocol&hostname || / - // urlParts[2] = / if path relative to host base - // urlParts[3] = directories - // urlParts[4] = filename - // urlParts[5] = parameters - - var urlPartsRegex = /^((?:[a-z-]+:)?\/+?(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i, - urlParts = url.match(urlPartsRegex), - returner = {}, directories = [], i, baseUrlParts; - - if (!urlParts) { - throw new Error("Could not parse sheet href - '"+url+"'"); - } - - // Stylesheets in IE don't always return the full path - if (!urlParts[1] || urlParts[2]) { - baseUrlParts = baseUrl.match(urlPartsRegex); - if (!baseUrlParts) { - throw new Error("Could not parse page url - '"+baseUrl+"'"); - } - urlParts[1] = urlParts[1] || baseUrlParts[1] || ""; - if (!urlParts[2]) { - urlParts[3] = baseUrlParts[3] + urlParts[3]; - } - } - - if (urlParts[3]) { - directories = urlParts[3].replace(/\\/g, "/").split("/"); - - // extract out . before .. so .. doesn't absorb a non-directory - for(i = 0; i < directories.length; i++) { - if (directories[i] === ".") { - directories.splice(i, 1); - i -= 1; - } - } - - for(i = 0; i < directories.length; i++) { - if (directories[i] === ".." && i > 0) { - directories.splice(i-1, 2); - i -= 2; - } - } - } - - returner.hostPart = urlParts[1]; - returner.directories = directories; - returner.path = urlParts[1] + directories.join("/"); - returner.fileUrl = returner.path + (urlParts[4] || ""); - returner.url = returner.fileUrl + (urlParts[5] || ""); - return returner; -} - -function pathDiff(url, baseUrl) { - // diff between two paths to create a relative path - - var urlParts = extractUrlParts(url), - baseUrlParts = extractUrlParts(baseUrl), - i, max, urlDirectories, baseUrlDirectories, diff = ""; - if (urlParts.hostPart !== baseUrlParts.hostPart) { - return ""; - } - max = Math.max(baseUrlParts.directories.length, urlParts.directories.length); - for(i = 0; i < max; i++) { - if (baseUrlParts.directories[i] !== urlParts.directories[i]) { break; } - } - baseUrlDirectories = baseUrlParts.directories.slice(i); - urlDirectories = urlParts.directories.slice(i); - for(i = 0; i < baseUrlDirectories.length-1; i++) { - diff += "../"; - } - for(i = 0; i < urlDirectories.length-1; i++) { - diff += urlDirectories[i] + "/"; - } - return diff; -} - -function getXMLHttpRequest() { - if (window.XMLHttpRequest) { - return new XMLHttpRequest(); - } else { - try { - /*global ActiveXObject */ - return new ActiveXObject("MSXML2.XMLHTTP.3.0"); - } catch (e) { - //log("browser doesn't support AJAX.", logLevel.errors); - return null; - } - } -} - -function doXHR(url, type, callback, errback) { - var xhr = getXMLHttpRequest(); - var async = isFileProtocol ? less.fileAsync : less.async; - - if (typeof(xhr.overrideMimeType) === 'function') { - xhr.overrideMimeType('text/css'); - } - //log("XHR: Getting '" + url + "'", logLevel.info); - xhr.open('GET', url, async); - xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5'); - xhr.send(null); - - function handleResponse(xhr, callback, errback) { - if (xhr.status >= 200 && xhr.status < 300) { - callback(xhr.responseText, - xhr.getResponseHeader("Last-Modified")); - } else if (typeof(errback) === 'function') { - errback(xhr.status, url); - } - } - - if (isFileProtocol && !less.fileAsync) { - if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) { - callback(xhr.responseText); - } else { - errback(xhr.status, url); - } - } else if (async) { - xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - handleResponse(xhr, callback, errback); - } - }; - } else { - handleResponse(xhr, callback, errback); - } -} - -function loadFile(originalHref, currentFileInfo, callback, env, modifyVars) { - - if (currentFileInfo && currentFileInfo.currentDirectory && !/^([a-z-]+:)?\//.test(originalHref)) { - originalHref = currentFileInfo.currentDirectory + originalHref; - } - - // sheet may be set to the stylesheet for the initial load or a collection of properties including - // some env variables for imports - var hrefParts = extractUrlParts(originalHref, window.location.href); - var href = hrefParts.url; - var newFileInfo = { - currentDirectory: hrefParts.path, - filename: href - }; - - if (currentFileInfo) { - newFileInfo.entryPath = currentFileInfo.entryPath; - newFileInfo.rootpath = currentFileInfo.rootpath; - newFileInfo.rootFilename = currentFileInfo.rootFilename; - newFileInfo.relativeUrls = currentFileInfo.relativeUrls; - } else { - newFileInfo.entryPath = hrefParts.path; - newFileInfo.rootpath = less.rootpath || hrefParts.path; - newFileInfo.rootFilename = href; - newFileInfo.relativeUrls = env.relativeUrls; - } - - if (newFileInfo.relativeUrls) { - if (env.rootpath) { - newFileInfo.rootpath = extractUrlParts(env.rootpath + pathDiff(hrefParts.path, newFileInfo.entryPath)).path; - } else { - newFileInfo.rootpath = hrefParts.path; - } - } - - if (env.useFileCache && fileCache[href]) { - try { - var lessText = fileCache[href]; - callback(null, lessText, href, newFileInfo, { lastModified: new Date() }); - } catch (e) { - callback(e, null, href); - } - return; - } - - doXHR(href, env.mime, function (data, lastModified) { - // per file cache - fileCache[href] = data; - - // Use remote copy (re-parse) - try { - callback(null, data, href, newFileInfo, { lastModified: lastModified }); - } catch (e) { - callback(e, null, href); - } - }, function (status, url) { - callback({ type: 'File', message: "'" + url + "' wasn't found (" + status + ")" }, null, href); - }); -} - -function loadStyleSheet(sheet, callback, reload, remaining, modifyVars) { - - var env = new less.tree.parseEnv(less); - env.mime = sheet.type; - - if (modifyVars || less.globalVars) { - env.useFileCache = true; - } - - loadFile(sheet.href, null, function(e, data, path, newFileInfo, webInfo) { - - if (webInfo) { - webInfo.remaining = remaining; - - var css = cache && cache.getItem(path), - timestamp = cache && cache.getItem(path + ':timestamp'); - - if (!reload && timestamp && webInfo.lastModified && - (new(Date)(webInfo.lastModified).valueOf() === - new(Date)(timestamp).valueOf())) { - // Use local copy - createCSS(css, sheet); - webInfo.local = true; - callback(null, null, data, sheet, webInfo, path); - return; - } - } - - //TODO add tests around how this behaves when reloading - removeError(path); - - if (data) { - env.currentFileInfo = newFileInfo; - new(less.Parser)(env).parse(data, function (e, root) { - if (e) { return callback(e, null, null, sheet); } - try { - callback(e, root, data, sheet, webInfo, path); - } catch (e) { - callback(e, null, null, sheet); - } - }, {modifyVars: modifyVars, globalVars: less.globalVars}); - } else { - callback(e, null, null, sheet, webInfo, path); - } - }, env, modifyVars); -} - -function loadStyleSheets(callback, reload, modifyVars) { - for (var i = 0; i < less.sheets.length; i++) { - loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1), modifyVars); - } -} - -function initRunningMode(){ - if (less.env === 'development') { - less.optimization = 0; - less.watchTimer = setInterval(function () { - if (less.watchMode) { - loadStyleSheets(function (e, root, _, sheet, env) { - if (e) { - error(e, sheet.href); - } else if (root) { - createCSS(root.toCSS(less), sheet, env.lastModified); - } - }); - } - }, less.poll); - } else { - less.optimization = 3; - } -} - - - -// -// Watch mode -// -less.watch = function () { - if (!less.watchMode ){ - less.env = 'development'; - initRunningMode(); - } - this.watchMode = true; - return true; -}; - -less.unwatch = function () {clearInterval(less.watchTimer); this.watchMode = false; return false; }; - -if (/!watch/.test(location.hash)) { - less.watch(); -} - -if (less.env != 'development') { - try { - cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage; - } catch (_) {} -} - -// -// Get all tags with the 'rel' attribute set to "stylesheet/less" -// -var links = document.getElementsByTagName('link'); - -less.sheets = []; - -for (var i = 0; i < links.length; i++) { - if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) && - (links[i].type.match(typePattern)))) { - less.sheets.push(links[i]); - } -} - -// -// With this function, it's possible to alter variables and re-render -// CSS without reloading less-files -// -less.modifyVars = function(record) { - less.refresh(false, record); -}; - -less.refresh = function (reload, modifyVars) { - var startTime, endTime; - startTime = endTime = new Date(); - - loadStyleSheets(function (e, root, _, sheet, env) { - if (e) { - return error(e, sheet.href); - } - if (env.local) { - //log("loading " + sheet.href + " from cache.", logLevel.info); - } else { - //log("parsed " + sheet.href + " successfully.", logLevel.info); - //createCSS(root.toCSS(less), sheet, env.lastModified); - - - // less.php changes - var css = root.toCSS(less); - function totextarea(){ - var textarea = document.getElementById('lessjs_textarea'); - if( textarea ){ - textarea.value = css; - diffUsingJS(0); - }else{ - window.setTimeout(totextarea,300); - } - } - totextarea(); - - } - log("css for " + sheet.href + " generated in " + (new Date() - endTime) + 'ms', logLevel.info); - if (env.remaining === 0) { - //log("css generated in " + (new Date() - startTime) + 'ms', logLevel.info); - } - endTime = new Date(); - }, reload, modifyVars); - - loadStyles(modifyVars); -}; - -less.refreshStyles = loadStyles; - -less.Parser.fileLoader = loadFile; - -less.refresh(less.env === 'development'); - -// amd.js -// -// Define Less as an AMD module. -if (typeof define === "function" && define.amd) { - define(function () { return less; } ); -} - -})(window); \ No newline at end of file diff --git a/test/assets/less-1.7.0.js b/test/assets/less-1.7.0.js deleted file mode 100644 index a9c76111..00000000 --- a/test/assets/less-1.7.0.js +++ /dev/null @@ -1,7936 +0,0 @@ -/*! - * LESS - Leaner CSS v1.7.0 - * http://lesscss.org - * - * Copyright (c) 2009-2014, Alexis Sellier - * Licensed under the Apache v2 License. - * - */ - - /** * @license Apache v2 - */ - - - -(function (window, undefined) {// -// Stub out `require` in the browser -// -function require(arg) { - return window.less[arg.split('/')[1]]; -}; - - -if (typeof(window.less) === 'undefined' || typeof(window.less.nodeType) !== 'undefined') { window.less = {}; } -less = window.less; -tree = window.less.tree = {}; -less.mode = 'browser'; - -var less, tree; - -// Node.js does not have a header file added which defines less -if (less === undefined) { - less = exports; - tree = require('./tree'); - less.mode = 'node'; -} -// -// less.js - parser -// -// A relatively straight-forward predictive parser. -// There is no tokenization/lexing stage, the input is parsed -// in one sweep. -// -// To make the parser fast enough to run in the browser, several -// optimization had to be made: -// -// - Matching and slicing on a huge input is often cause of slowdowns. -// The solution is to chunkify the input into smaller strings. -// The chunks are stored in the `chunks` var, -// `j` holds the current chunk index, and `currentPos` holds -// the index of the current chunk in relation to `input`. -// This gives us an almost 4x speed-up. -// -// - In many cases, we don't need to match individual tokens; -// for example, if a value doesn't hold any variables, operations -// or dynamic references, the parser can effectively 'skip' it, -// treating it as a literal. -// An example would be '1px solid #000' - which evaluates to itself, -// we don't need to know what the individual components are. -// The drawback, of course is that you don't get the benefits of -// syntax-checking on the CSS. This gives us a 50% speed-up in the parser, -// and a smaller speed-up in the code-gen. -// -// -// Token matching is done with the `$` function, which either takes -// a terminal string or regexp, or a non-terminal function to call. -// It also takes care of moving all the indices forwards. -// -// -less.Parser = function Parser(env) { - var input, // LeSS input string - i, // current index in `input` - j, // current chunk - saveStack = [], // holds state for backtracking - furthest, // furthest index the parser has gone to - chunks, // chunkified input - current, // current chunk - currentPos, // index of current chunk, in `input` - parser, - parsers, - rootFilename = env && env.filename; - - // Top parser on an import tree must be sure there is one "env" - // which will then be passed around by reference. - if (!(env instanceof tree.parseEnv)) { - env = new tree.parseEnv(env); - } - - var imports = this.imports = { - paths: env.paths || [], // Search paths, when importing - queue: [], // Files which haven't been imported yet - files: env.files, // Holds the imported parse trees - contents: env.contents, // Holds the imported file contents - contentsIgnoredChars: env.contentsIgnoredChars, // lines inserted, not in the original less - mime: env.mime, // MIME type of .less files - error: null, // Error in parsing/evaluating an import - push: function (path, currentFileInfo, importOptions, callback) { - var parserImports = this; - this.queue.push(path); - - var fileParsedFunc = function (e, root, fullPath) { - parserImports.queue.splice(parserImports.queue.indexOf(path), 1); // Remove the path from the queue - - var importedPreviously = fullPath === rootFilename; - - parserImports.files[fullPath] = root; // Store the root - - if (e && !parserImports.error) { parserImports.error = e; } - - callback(e, root, importedPreviously, fullPath); - }; - - if (less.Parser.importer) { - less.Parser.importer(path, currentFileInfo, fileParsedFunc, env); - } else { - less.Parser.fileLoader(path, currentFileInfo, function(e, contents, fullPath, newFileInfo) { - if (e) {fileParsedFunc(e); return;} - - var newEnv = new tree.parseEnv(env); - - newEnv.currentFileInfo = newFileInfo; - newEnv.processImports = false; - newEnv.contents[fullPath] = contents; - - if (currentFileInfo.reference || importOptions.reference) { - newFileInfo.reference = true; - } - - if (importOptions.inline) { - fileParsedFunc(null, contents, fullPath); - } else { - new(less.Parser)(newEnv).parse(contents, function (e, root) { - fileParsedFunc(e, root, fullPath); - }); - } - }, env); - } - } - }; - - function save() { currentPos = i; saveStack.push( { current: current, i: i, j: j }); } - function restore() { var state = saveStack.pop(); current = state.current; currentPos = i = state.i; j = state.j; } - function forget() { saveStack.pop(); } - - function sync() { - if (i > currentPos) { - current = current.slice(i - currentPos); - currentPos = i; - } - } - function isWhitespace(str, pos) { - var code = str.charCodeAt(pos | 0); - return (code <= 32) && (code === 32 || code === 10 || code === 9); - } - // - // Parse from a token, regexp or string, and move forward if match - // - function $(tok) { - var tokType = typeof tok, - match, length; - - // Either match a single character in the input, - // or match a regexp in the current chunk (`current`). - // - if (tokType === "string") { - if (input.charAt(i) !== tok) { - return null; - } - skipWhitespace(1); - return tok; - } - - // regexp - sync (); - if (! (match = tok.exec(current))) { - return null; - } - - length = match[0].length; - - // The match is confirmed, add the match length to `i`, - // and consume any extra white-space characters (' ' || '\n') - // which come after that. The reason for this is that LeSS's - // grammar is mostly white-space insensitive. - // - skipWhitespace(length); - - if(typeof(match) === 'string') { - return match; - } else { - return match.length === 1 ? match[0] : match; - } - } - - // Specialization of $(tok) - function $re(tok) { - if (i > currentPos) { - current = current.slice(i - currentPos); - currentPos = i; - } - var m = tok.exec(current); - if (!m) { - return null; - } - - skipWhitespace(m[0].length); - if(typeof m === "string") { - return m; - } - - return m.length === 1 ? m[0] : m; - } - - var _$re = $re; - - // Specialization of $(tok) - function $char(tok) { - if (input.charAt(i) !== tok) { - return null; - } - skipWhitespace(1); - return tok; - } - - function skipWhitespace(length) { - var oldi = i, oldj = j, - curr = i - currentPos, - endIndex = i + current.length - curr, - mem = (i += length), - inp = input, - c; - - for (; i < endIndex; i++) { - c = inp.charCodeAt(i); - if (c > 32) { - break; - } - - if ((c !== 32) && (c !== 10) && (c !== 9) && (c !== 13)) { - break; - } - } - - current = current.slice(length + i - mem + curr); - currentPos = i; - - if (!current.length && (j < chunks.length - 1)) { - current = chunks[++j]; - skipWhitespace(0); // skip space at the beginning of a chunk - return true; // things changed - } - - return oldi !== i || oldj !== j; - } - - function expect(arg, msg) { - // some older browsers return typeof 'function' for RegExp - var result = (Object.prototype.toString.call(arg) === '[object Function]') ? arg.call(parsers) : $(arg); - if (result) { - return result; - } - error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'" - : "unexpected token")); - } - - // Specialization of expect() - function expectChar(arg, msg) { - if (input.charAt(i) === arg) { - skipWhitespace(1); - return arg; - } - error(msg || "expected '" + arg + "' got '" + input.charAt(i) + "'"); - } - - function error(msg, type) { - var e = new Error(msg); - e.index = i; - e.type = type || 'Syntax'; - throw e; - } - - // Same as $(), but don't change the state of the parser, - // just return the match. - function peek(tok) { - if (typeof(tok) === 'string') { - return input.charAt(i) === tok; - } else { - return tok.test(current); - } - } - - // Specialization of peek() - function peekChar(tok) { - return input.charAt(i) === tok; - } - - - function getInput(e, env) { - if (e.filename && env.currentFileInfo.filename && (e.filename !== env.currentFileInfo.filename)) { - return parser.imports.contents[e.filename]; - } else { - return input; - } - } - - function getLocation(index, inputStream) { - var n = index + 1, - line = null, - column = -1; - - while (--n >= 0 && inputStream.charAt(n) !== '\n') { - column++; - } - - if (typeof index === 'number') { - line = (inputStream.slice(0, index).match(/\n/g) || "").length; - } - - return { - line: line, - column: column - }; - } - - function getDebugInfo(index, inputStream, env) { - var filename = env.currentFileInfo.filename; - if(less.mode !== 'browser' && less.mode !== 'rhino') { - filename = require('path').resolve(filename); - } - - return { - lineNumber: getLocation(index, inputStream).line + 1, - fileName: filename - }; - } - - function LessError(e, env) { - var input = getInput(e, env), - loc = getLocation(e.index, input), - line = loc.line, - col = loc.column, - callLine = e.call && getLocation(e.call, input).line, - lines = input.split('\n'); - - this.type = e.type || 'Syntax'; - this.message = e.message; - this.filename = e.filename || env.currentFileInfo.filename; - this.index = e.index; - this.line = typeof(line) === 'number' ? line + 1 : null; - this.callLine = callLine + 1; - this.callExtract = lines[callLine]; - this.stack = e.stack; - this.column = col; - this.extract = [ - lines[line - 1], - lines[line], - lines[line + 1] - ]; - } - - LessError.prototype = new Error(); - LessError.prototype.constructor = LessError; - - this.env = env = env || {}; - - // The optimization level dictates the thoroughness of the parser, - // the lower the number, the less nodes it will create in the tree. - // This could matter for debugging, or if you want to access - // the individual nodes in the tree. - this.optimization = ('optimization' in this.env) ? this.env.optimization : 1; - - // - // The Parser - // - parser = { - - imports: imports, - // - // Parse an input string into an abstract syntax tree, - // @param str A string containing 'less' markup - // @param callback call `callback` when done. - // @param [additionalData] An optional map which can contains vars - a map (key, value) of variables to apply - // - parse: function (str, callback, additionalData) { - var root, line, lines, error = null, globalVars, modifyVars, preText = ""; - - i = j = currentPos = furthest = 0; - - globalVars = (additionalData && additionalData.globalVars) ? less.Parser.serializeVars(additionalData.globalVars) + '\n' : ''; - modifyVars = (additionalData && additionalData.modifyVars) ? '\n' + less.Parser.serializeVars(additionalData.modifyVars) : ''; - - if (globalVars || (additionalData && additionalData.banner)) { - preText = ((additionalData && additionalData.banner) ? additionalData.banner : "") + globalVars; - parser.imports.contentsIgnoredChars[env.currentFileInfo.filename] = preText.length; - } - - str = str.replace(/\r\n/g, '\n'); - // Remove potential UTF Byte Order Mark - input = str = preText + str.replace(/^\uFEFF/, '') + modifyVars; - parser.imports.contents[env.currentFileInfo.filename] = str; - - // Split the input into chunks. - chunks = (function (input) { - var len = input.length, level = 0, parenLevel = 0, - lastOpening, lastOpeningParen, lastMultiComment, lastMultiCommentEndBrace, - chunks = [], emitFrom = 0, - parserCurrentIndex, currentChunkStartIndex, cc, cc2, matched; - - function fail(msg, index) { - error = new(LessError)({ - index: index || parserCurrentIndex, - type: 'Parse', - message: msg, - filename: env.currentFileInfo.filename - }, env); - } - - function emitChunk(force) { - var len = parserCurrentIndex - emitFrom; - if (((len < 512) && !force) || !len) { - return; - } - chunks.push(input.slice(emitFrom, parserCurrentIndex + 1)); - emitFrom = parserCurrentIndex + 1; - } - - for (parserCurrentIndex = 0; parserCurrentIndex < len; parserCurrentIndex++) { - cc = input.charCodeAt(parserCurrentIndex); - if (((cc >= 97) && (cc <= 122)) || (cc < 34)) { - // a-z or whitespace - continue; - } - - switch (cc) { - case 40: // ( - parenLevel++; - lastOpeningParen = parserCurrentIndex; - continue; - case 41: // ) - if (--parenLevel < 0) { - return fail("missing opening `(`"); - } - continue; - case 59: // ; - if (!parenLevel) { emitChunk(); } - continue; - case 123: // { - level++; - lastOpening = parserCurrentIndex; - continue; - case 125: // } - if (--level < 0) { - return fail("missing opening `{`"); - } - if (!level && !parenLevel) { emitChunk(); } - continue; - case 92: // \ - if (parserCurrentIndex < len - 1) { parserCurrentIndex++; continue; } - return fail("unescaped `\\`"); - case 34: - case 39: - case 96: // ", ' and ` - matched = 0; - currentChunkStartIndex = parserCurrentIndex; - for (parserCurrentIndex = parserCurrentIndex + 1; parserCurrentIndex < len; parserCurrentIndex++) { - cc2 = input.charCodeAt(parserCurrentIndex); - if (cc2 > 96) { continue; } - if (cc2 == cc) { matched = 1; break; } - if (cc2 == 92) { // \ - if (parserCurrentIndex == len - 1) { - return fail("unescaped `\\`"); - } - parserCurrentIndex++; - } - } - if (matched) { continue; } - return fail("unmatched `" + String.fromCharCode(cc) + "`", currentChunkStartIndex); - case 47: // /, check for comment - if (parenLevel || (parserCurrentIndex == len - 1)) { continue; } - cc2 = input.charCodeAt(parserCurrentIndex + 1); - if (cc2 == 47) { - // //, find lnfeed - for (parserCurrentIndex = parserCurrentIndex + 2; parserCurrentIndex < len; parserCurrentIndex++) { - cc2 = input.charCodeAt(parserCurrentIndex); - if ((cc2 <= 13) && ((cc2 == 10) || (cc2 == 13))) { break; } - } - } else if (cc2 == 42) { - // /*, find */ - lastMultiComment = currentChunkStartIndex = parserCurrentIndex; - for (parserCurrentIndex = parserCurrentIndex + 2; parserCurrentIndex < len - 1; parserCurrentIndex++) { - cc2 = input.charCodeAt(parserCurrentIndex); - if (cc2 == 125) { lastMultiCommentEndBrace = parserCurrentIndex; } - if (cc2 != 42) { continue; } - if (input.charCodeAt(parserCurrentIndex + 1) == 47) { break; } - } - if (parserCurrentIndex == len - 1) { - return fail("missing closing `*/`", currentChunkStartIndex); - } - parserCurrentIndex++; - } - continue; - case 42: // *, check for unmatched */ - if ((parserCurrentIndex < len - 1) && (input.charCodeAt(parserCurrentIndex + 1) == 47)) { - return fail("unmatched `/*`"); - } - continue; - } - } - - if (level !== 0) { - if ((lastMultiComment > lastOpening) && (lastMultiCommentEndBrace > lastMultiComment)) { - return fail("missing closing `}` or `*/`", lastOpening); - } else { - return fail("missing closing `}`", lastOpening); - } - } else if (parenLevel !== 0) { - return fail("missing closing `)`", lastOpeningParen); - } - - emitChunk(true); - return chunks; - })(str); - - if (error) { - return callback(new(LessError)(error, env)); - } - - current = chunks[0]; - - // Start with the primary rule. - // The whole syntax tree is held under a Ruleset node, - // with the `root` property set to true, so no `{}` are - // output. The callback is called when the input is parsed. - try { - root = new(tree.Ruleset)(null, this.parsers.primary()); - root.root = true; - root.firstRoot = true; - } catch (e) { - return callback(new(LessError)(e, env)); - } - - root.toCSS = (function (evaluate) { - return function (options, variables) { - options = options || {}; - var evaldRoot, - css, - evalEnv = new tree.evalEnv(options); - - // - // Allows setting variables with a hash, so: - // - // `{ color: new(tree.Color)('#f01') }` will become: - // - // new(tree.Rule)('@color', - // new(tree.Value)([ - // new(tree.Expression)([ - // new(tree.Color)('#f01') - // ]) - // ]) - // ) - // - if (typeof(variables) === 'object' && !Array.isArray(variables)) { - variables = Object.keys(variables).map(function (k) { - var value = variables[k]; - - if (! (value instanceof tree.Value)) { - if (! (value instanceof tree.Expression)) { - value = new(tree.Expression)([value]); - } - value = new(tree.Value)([value]); - } - return new(tree.Rule)('@' + k, value, false, null, 0); - }); - evalEnv.frames = [new(tree.Ruleset)(null, variables)]; - } - - try { - var preEvalVisitors = [], - visitors = [ - new(tree.joinSelectorVisitor)(), - new(tree.processExtendsVisitor)(), - new(tree.toCSSVisitor)({compress: Boolean(options.compress)}) - ], i, root = this; - - if (options.plugins) { - for(i =0; i < options.plugins.length; i++) { - if (options.plugins[i].isPreEvalVisitor) { - preEvalVisitors.push(options.plugins[i]); - } else { - if (options.plugins[i].isPreVisitor) { - visitors.splice(0, 0, options.plugins[i]); - } else { - visitors.push(options.plugins[i]); - } - } - } - } - - for(i = 0; i < preEvalVisitors.length; i++) { - preEvalVisitors[i].run(root); - } - - evaldRoot = evaluate.call(root, evalEnv); - - for(i = 0; i < visitors.length; i++) { - visitors[i].run(evaldRoot); - } - - if (options.sourceMap) { - evaldRoot = new tree.sourceMapOutput( - { - contentsIgnoredCharsMap: parser.imports.contentsIgnoredChars, - writeSourceMap: options.writeSourceMap, - rootNode: evaldRoot, - contentsMap: parser.imports.contents, - sourceMapFilename: options.sourceMapFilename, - sourceMapURL: options.sourceMapURL, - outputFilename: options.sourceMapOutputFilename, - sourceMapBasepath: options.sourceMapBasepath, - sourceMapRootpath: options.sourceMapRootpath, - outputSourceFiles: options.outputSourceFiles, - sourceMapGenerator: options.sourceMapGenerator - }); - } - - css = evaldRoot.toCSS({ - compress: Boolean(options.compress), - dumpLineNumbers: env.dumpLineNumbers, - strictUnits: Boolean(options.strictUnits), - numPrecision: 8}); - } catch (e) { - throw new(LessError)(e, env); - } - - if (options.cleancss && less.mode === 'node') { - var CleanCSS = require('clean-css'), - cleancssOptions = options.cleancssOptions || {}; - - if (cleancssOptions.keepSpecialComments === undefined) { - cleancssOptions.keepSpecialComments = "*"; - } - cleancssOptions.processImport = false; - cleancssOptions.noRebase = true; - if (cleancssOptions.noAdvanced === undefined) { - cleancssOptions.noAdvanced = true; - } - - return new CleanCSS(cleancssOptions).minify(css); - } else if (options.compress) { - return css.replace(/(^(\s)+)|((\s)+$)/g, ""); - } else { - return css; - } - }; - })(root.eval); - - // If `i` is smaller than the `input.length - 1`, - // it means the parser wasn't able to parse the whole - // string, so we've got a parsing error. - // - // We try to extract a \n delimited string, - // showing the line where the parse error occured. - // We split it up into two parts (the part which parsed, - // and the part which didn't), so we can color them differently. - if (i < input.length - 1) { - i = furthest; - var loc = getLocation(i, input); - lines = input.split('\n'); - line = loc.line + 1; - - error = { - type: "Parse", - message: "Unrecognised input", - index: i, - filename: env.currentFileInfo.filename, - line: line, - column: loc.column, - extract: [ - lines[line - 2], - lines[line - 1], - lines[line] - ] - }; - } - - var finish = function (e) { - e = error || e || parser.imports.error; - - if (e) { - if (!(e instanceof LessError)) { - e = new(LessError)(e, env); - } - - return callback(e); - } - else { - return callback(null, root); - } - }; - - if (env.processImports !== false) { - new tree.importVisitor(this.imports, finish) - .run(root); - } else { - return finish(); - } - }, - - // - // Here in, the parsing rules/functions - // - // The basic structure of the syntax tree generated is as follows: - // - // Ruleset -> Rule -> Value -> Expression -> Entity - // - // Here's some LESS code: - // - // .class { - // color: #fff; - // border: 1px solid #000; - // width: @w + 4px; - // > .child {...} - // } - // - // And here's what the parse tree might look like: - // - // Ruleset (Selector '.class', [ - // Rule ("color", Value ([Expression [Color #fff]])) - // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]])) - // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]])) - // Ruleset (Selector [Element '>', '.child'], [...]) - // ]) - // - // In general, most rules will try to parse a token with the `$()` function, and if the return - // value is truly, will return a new node, of the relevant type. Sometimes, we need to check - // first, before parsing, that's when we use `peek()`. - // - parsers: parsers = { - // - // The `primary` rule is the *entry* and *exit* point of the parser. - // The rules here can appear at any level of the parse tree. - // - // The recursive nature of the grammar is an interplay between the `block` - // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule, - // as represented by this simplified grammar: - // - // primary → (ruleset | rule)+ - // ruleset → selector+ block - // block → '{' primary '}' - // - // Only at one point is the primary rule not called from the - // block rule: at the root level. - // - primary: function () { - var mixin = this.mixin, $re = _$re, root = [], node; - - while (current) - { - node = this.extendRule() || mixin.definition() || this.rule() || this.ruleset() || - mixin.call() || this.comment() || this.rulesetCall() || this.directive(); - if (node) { - root.push(node); - } else { - if (!($re(/^[\s\n]+/) || $re(/^;+/))) { - break; - } - } - if (peekChar('}')) { - break; - } - } - - return root; - }, - - // We create a Comment node for CSS comments `/* */`, - // but keep the LeSS comments `//` silent, by just skipping - // over them. - comment: function () { - var comment; - - if (input.charAt(i) !== '/') { return; } - - if (input.charAt(i + 1) === '/') { - return new(tree.Comment)($re(/^\/\/.*/), true, i, env.currentFileInfo); - } - comment = $re(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/); - if (comment) { - return new(tree.Comment)(comment, false, i, env.currentFileInfo); - } - }, - - comments: function () { - var comment, comments = []; - - while(true) { - comment = this.comment(); - if (!comment) { - break; - } - comments.push(comment); - } - - return comments; - }, - - // - // Entities are tokens which can be found inside an Expression - // - entities: { - // - // A string, which supports escaping " and ' - // - // "milky way" 'he\'s the one!' - // - quoted: function () { - var str, j = i, e, index = i; - - if (input.charAt(j) === '~') { j++; e = true; } // Escaped strings - if (input.charAt(j) !== '"' && input.charAt(j) !== "'") { return; } - - if (e) { $char('~'); } - - str = $re(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/); - if (str) { - return new(tree.Quoted)(str[0], str[1] || str[2], e, index, env.currentFileInfo); - } - }, - - // - // A catch-all word, such as: - // - // black border-collapse - // - keyword: function () { - var k; - - k = $re(/^%|^[_A-Za-z-][_A-Za-z0-9-]*/); - if (k) { - var color = tree.Color.fromKeyword(k); - if (color) { - return color; - } - return new(tree.Keyword)(k); - } - }, - - // - // A function call - // - // rgb(255, 0, 255) - // - // We also try to catch IE's `alpha()`, but let the `alpha` parser - // deal with the details. - // - // The arguments are parsed with the `entities.arguments` parser. - // - call: function () { - var name, nameLC, args, alpha_ret, index = i; - - name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(current); - if (!name) { return; } - - name = name[1]; - nameLC = name.toLowerCase(); - if (nameLC === 'url') { - return null; - } - - i += name.length; - - if (nameLC === 'alpha') { - alpha_ret = parsers.alpha(); - if(typeof alpha_ret !== 'undefined') { - return alpha_ret; - } - } - - $char('('); // Parse the '(' and consume whitespace. - - args = this.arguments(); - - if (! $char(')')) { - return; - } - - if (name) { return new(tree.Call)(name, args, index, env.currentFileInfo); } - }, - arguments: function () { - var args = [], arg; - - while (true) { - arg = this.assignment() || parsers.expression(); - if (!arg) { - break; - } - args.push(arg); - if (! $char(',')) { - break; - } - } - return args; - }, - literal: function () { - return this.dimension() || - this.color() || - this.quoted() || - this.unicodeDescriptor(); - }, - - // Assignments are argument entities for calls. - // They are present in ie filter properties as shown below. - // - // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* ) - // - - assignment: function () { - var key, value; - key = $re(/^\w+(?=\s?=)/i); - if (!key) { - return; - } - if (!$char('=')) { - return; - } - value = parsers.entity(); - if (value) { - return new(tree.Assignment)(key, value); - } - }, - - // - // Parse url() tokens - // - // We use a specific rule for urls, because they don't really behave like - // standard function calls. The difference is that the argument doesn't have - // to be enclosed within a string, so it can't be parsed as an Expression. - // - url: function () { - var value; - - if (input.charAt(i) !== 'u' || !$re(/^url\(/)) { - return; - } - - value = this.quoted() || this.variable() || - $re(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || ""; - - expectChar(')'); - - return new(tree.URL)((value.value != null || value instanceof tree.Variable) - ? value : new(tree.Anonymous)(value), env.currentFileInfo); - }, - - // - // A Variable entity, such as `@fink`, in - // - // width: @fink + 2px - // - // We use a different parser for variable definitions, - // see `parsers.variable`. - // - variable: function () { - var name, index = i; - - if (input.charAt(i) === '@' && (name = $re(/^@@?[\w-]+/))) { - return new(tree.Variable)(name, index, env.currentFileInfo); - } - }, - - // A variable entity useing the protective {} e.g. @{var} - variableCurly: function () { - var curly, index = i; - - if (input.charAt(i) === '@' && (curly = $re(/^@\{([\w-]+)\}/))) { - return new(tree.Variable)("@" + curly[1], index, env.currentFileInfo); - } - }, - - // - // A Hexadecimal color - // - // #4F3C2F - // - // `rgb` and `hsl` colors are parsed through the `entities.call` parser. - // - color: function () { - var rgb; - - if (input.charAt(i) === '#' && (rgb = $re(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/))) { - return new(tree.Color)(rgb[1]); - } - }, - - // - // A Dimension, that is, a number and a unit - // - // 0.5em 95% - // - dimension: function () { - var value, c = input.charCodeAt(i); - //Is the first char of the dimension 0-9, '.', '+' or '-' - if ((c > 57 || c < 43) || c === 47 || c == 44) { - return; - } - - value = $re(/^([+-]?\d*\.?\d+)(%|[a-z]+)?/); - if (value) { - return new(tree.Dimension)(value[1], value[2]); - } - }, - - // - // A unicode descriptor, as is used in unicode-range - // - // U+0?? or U+00A1-00A9 - // - unicodeDescriptor: function () { - var ud; - - ud = $re(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/); - if (ud) { - return new(tree.UnicodeDescriptor)(ud[0]); - } - }, - - // - // JavaScript code to be evaluated - // - // `window.location.href` - // - javascript: function () { - var str, j = i, e; - - if (input.charAt(j) === '~') { j++; e = true; } // Escaped strings - if (input.charAt(j) !== '`') { return; } - if (env.javascriptEnabled !== undefined && !env.javascriptEnabled) { - error("You are using JavaScript, which has been disabled."); - } - - if (e) { $char('~'); } - - str = $re(/^`([^`]*)`/); - if (str) { - return new(tree.JavaScript)(str[1], i, e); - } - } - }, - - // - // The variable part of a variable definition. Used in the `rule` parser - // - // @fink: - // - variable: function () { - var name; - - if (input.charAt(i) === '@' && (name = $re(/^(@[\w-]+)\s*:/))) { return name[1]; } - }, - - // - // The variable part of a variable definition. Used in the `rule` parser - // - // @fink(); - // - rulesetCall: function () { - var name; - - if (input.charAt(i) === '@' && (name = $re(/^(@[\w-]+)\s*\(\s*\)\s*;/))) { - return new tree.RulesetCall(name[1]); - } - }, - - // - // extend syntax - used to extend selectors - // - extend: function(isRule) { - var elements, e, index = i, option, extendList, extend; - - if (!(isRule ? $re(/^&:extend\(/) : $re(/^:extend\(/))) { return; } - - do { - option = null; - elements = null; - while (! (option = $re(/^(all)(?=\s*(\)|,))/))) { - e = this.element(); - if (!e) { break; } - if (elements) { elements.push(e); } else { elements = [ e ]; } - } - - option = option && option[1]; - - extend = new(tree.Extend)(new(tree.Selector)(elements), option, index); - if (extendList) { extendList.push(extend); } else { extendList = [ extend ]; } - - } while($char(",")); - - expect(/^\)/); - - if (isRule) { - expect(/^;/); - } - - return extendList; - }, - - // - // extendRule - used in a rule to extend all the parent selectors - // - extendRule: function() { - return this.extend(true); - }, - - // - // Mixins - // - mixin: { - // - // A Mixin call, with an optional argument list - // - // #mixins > .square(#fff); - // .rounded(4px, black); - // .button; - // - // The `while` loop is there because mixins can be - // namespaced, but we only support the child and descendant - // selector for now. - // - call: function () { - var s = input.charAt(i), important = false, index = i, elemIndex, - elements, elem, e, c, args; - - if (s !== '.' && s !== '#') { return; } - - save(); // stop us absorbing part of an invalid selector - - while (true) { - elemIndex = i; - e = $re(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/); - if (!e) { - break; - } - elem = new(tree.Element)(c, e, elemIndex, env.currentFileInfo); - if (elements) { elements.push(elem); } else { elements = [ elem ]; } - c = $char('>'); - } - - if (elements) { - if ($char('(')) { - args = this.args(true).args; - expectChar(')'); - } - - if (parsers.important()) { - important = true; - } - - if (parsers.end()) { - forget(); - return new(tree.mixin.Call)(elements, args, index, env.currentFileInfo, important); - } - } - - restore(); - }, - args: function (isCall) { - var parsers = parser.parsers, entities = parsers.entities, - returner = { args:null, variadic: false }, - expressions = [], argsSemiColon = [], argsComma = [], - isSemiColonSeperated, expressionContainsNamed, name, nameLoop, value, arg; - - save(); - - while (true) { - if (isCall) { - arg = parsers.detachedRuleset() || parsers.expression(); - } else { - parsers.comments(); - if (input.charAt(i) === '.' && $re(/^\.{3}/)) { - returner.variadic = true; - if ($char(";") && !isSemiColonSeperated) { - isSemiColonSeperated = true; - } - (isSemiColonSeperated ? argsSemiColon : argsComma) - .push({ variadic: true }); - break; - } - arg = entities.variable() || entities.literal() || entities.keyword(); - } - - if (!arg) { - break; - } - - nameLoop = null; - if (arg.throwAwayComments) { - arg.throwAwayComments(); - } - value = arg; - var val = null; - - if (isCall) { - // Variable - if (arg.value && arg.value.length == 1) { - val = arg.value[0]; - } - } else { - val = arg; - } - - if (val && val instanceof tree.Variable) { - if ($char(':')) { - if (expressions.length > 0) { - if (isSemiColonSeperated) { - error("Cannot mix ; and , as delimiter types"); - } - expressionContainsNamed = true; - } - - // we do not support setting a ruleset as a default variable - it doesn't make sense - // However if we do want to add it, there is nothing blocking it, just don't error - // and remove isCall dependency below - value = (isCall && parsers.detachedRuleset()) || parsers.expression(); - - if (!value) { - if (isCall) { - error("could not understand value for named argument"); - } else { - restore(); - returner.args = []; - return returner; - } - } - nameLoop = (name = val.name); - } else if (!isCall && $re(/^\.{3}/)) { - returner.variadic = true; - if ($char(";") && !isSemiColonSeperated) { - isSemiColonSeperated = true; - } - (isSemiColonSeperated ? argsSemiColon : argsComma) - .push({ name: arg.name, variadic: true }); - break; - } else if (!isCall) { - name = nameLoop = val.name; - value = null; - } - } - - if (value) { - expressions.push(value); - } - - argsComma.push({ name:nameLoop, value:value }); - - if ($char(',')) { - continue; - } - - if ($char(';') || isSemiColonSeperated) { - - if (expressionContainsNamed) { - error("Cannot mix ; and , as delimiter types"); - } - - isSemiColonSeperated = true; - - if (expressions.length > 1) { - value = new(tree.Value)(expressions); - } - argsSemiColon.push({ name:name, value:value }); - - name = null; - expressions = []; - expressionContainsNamed = false; - } - } - - forget(); - returner.args = isSemiColonSeperated ? argsSemiColon : argsComma; - return returner; - }, - // - // A Mixin definition, with a list of parameters - // - // .rounded (@radius: 2px, @color) { - // ... - // } - // - // Until we have a finer grained state-machine, we have to - // do a look-ahead, to make sure we don't have a mixin call. - // See the `rule` function for more information. - // - // We start by matching `.rounded (`, and then proceed on to - // the argument list, which has optional default values. - // We store the parameters in `params`, with a `value` key, - // if there is a value, such as in the case of `@radius`. - // - // Once we've got our params list, and a closing `)`, we parse - // the `{...}` block. - // - definition: function () { - var name, params = [], match, ruleset, cond, variadic = false; - if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') || - peek(/^[^{]*\}/)) { - return; - } - - save(); - - match = $re(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/); - if (match) { - name = match[1]; - - var argInfo = this.args(false); - params = argInfo.args; - variadic = argInfo.variadic; - - // .mixincall("@{a}"); - // looks a bit like a mixin definition.. - // also - // .mixincall(@a: {rule: set;}); - // so we have to be nice and restore - if (!$char(')')) { - furthest = i; - restore(); - return; - } - - parsers.comments(); - - if ($re(/^when/)) { // Guard - cond = expect(parsers.conditions, 'expected condition'); - } - - ruleset = parsers.block(); - - if (ruleset) { - forget(); - return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic); - } else { - restore(); - } - } else { - forget(); - } - } - }, - - // - // Entities are the smallest recognized token, - // and can be found inside a rule's value. - // - entity: function () { - var entities = this.entities; - - return entities.literal() || entities.variable() || entities.url() || - entities.call() || entities.keyword() || entities.javascript() || - this.comment(); - }, - - // - // A Rule terminator. Note that we use `peek()` to check for '}', - // because the `block` rule will be expecting it, but we still need to make sure - // it's there, if ';' was ommitted. - // - end: function () { - return $char(';') || peekChar('}'); - }, - - // - // IE's alpha function - // - // alpha(opacity=88) - // - alpha: function () { - var value; - - if (! $re(/^\(opacity=/i)) { return; } - value = $re(/^\d+/) || this.entities.variable(); - if (value) { - expectChar(')'); - return new(tree.Alpha)(value); - } - }, - - // - // A Selector Element - // - // div - // + h1 - // #socks - // input[type="text"] - // - // Elements are the building blocks for Selectors, - // they are made out of a `Combinator` (see combinator rule), - // and an element name, such as a tag a class, or `*`. - // - element: function () { - var e, c, v, index = i; - - c = this.combinator(); - - e = $re(/^(?:\d+\.\d+|\d+)%/) || $re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) || - $char('*') || $char('&') || this.attribute() || $re(/^\([^()@]+\)/) || $re(/^[\.#](?=@)/) || - this.entities.variableCurly(); - - if (! e) { - save(); - if ($char('(')) { - if ((v = this.selector()) && $char(')')) { - e = new(tree.Paren)(v); - forget(); - } else { - restore(); - } - } else { - forget(); - } - } - - if (e) { return new(tree.Element)(c, e, index, env.currentFileInfo); } - }, - - // - // Combinators combine elements together, in a Selector. - // - // Because our parser isn't white-space sensitive, special care - // has to be taken, when parsing the descendant combinator, ` `, - // as it's an empty space. We have to check the previous character - // in the input, to see if it's a ` ` character. More info on how - // we deal with this in *combinator.js*. - // - combinator: function () { - var c = input.charAt(i); - - if (c === '>' || c === '+' || c === '~' || c === '|' || c === '^') { - i++; - if (input.charAt(i) === '^') { - c = '^^'; - i++; - } - while (isWhitespace(input, i)) { i++; } - return new(tree.Combinator)(c); - } else if (isWhitespace(input, i - 1)) { - return new(tree.Combinator)(" "); - } else { - return new(tree.Combinator)(null); - } - }, - // - // A CSS selector (see selector below) - // with less extensions e.g. the ability to extend and guard - // - lessSelector: function () { - return this.selector(true); - }, - // - // A CSS Selector - // - // .class > div + h1 - // li a:hover - // - // Selectors are made out of one or more Elements, see above. - // - selector: function (isLess) { - var index = i, $re = _$re, elements, extendList, c, e, extend, when, condition; - - while ((isLess && (extend = this.extend())) || (isLess && (when = $re(/^when/))) || (e = this.element())) { - if (when) { - condition = expect(this.conditions, 'expected condition'); - } else if (condition) { - error("CSS guard can only be used at the end of selector"); - } else if (extend) { - if (extendList) { extendList.push(extend); } else { extendList = [ extend ]; } - } else { - if (extendList) { error("Extend can only be used at the end of selector"); } - c = input.charAt(i); - if (elements) { elements.push(e); } else { elements = [ e ]; } - e = null; - } - if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') { - break; - } - } - - if (elements) { return new(tree.Selector)(elements, extendList, condition, index, env.currentFileInfo); } - if (extendList) { error("Extend must be used to extend a selector, it cannot be used on its own"); } - }, - attribute: function () { - if (! $char('[')) { return; } - - var entities = this.entities, - key, val, op; - - if (!(key = entities.variableCurly())) { - key = expect(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/); - } - - op = $re(/^[|~*$^]?=/); - if (op) { - val = entities.quoted() || $re(/^[0-9]+%/) || $re(/^[\w-]+/) || entities.variableCurly(); - } - - expectChar(']'); - - return new(tree.Attribute)(key, op, val); - }, - - // - // The `block` rule is used by `ruleset` and `mixin.definition`. - // It's a wrapper around the `primary` rule, with added `{}`. - // - block: function () { - var content; - if ($char('{') && (content = this.primary()) && $char('}')) { - return content; - } - }, - - blockRuleset: function() { - var block = this.block(); - - if (block) { - block = new tree.Ruleset(null, block); - } - return block; - }, - - detachedRuleset: function() { - var blockRuleset = this.blockRuleset(); - if (blockRuleset) { - return new tree.DetachedRuleset(blockRuleset); - } - }, - - // - // div, .class, body > p {...} - // - ruleset: function () { - var selectors, s, rules, debugInfo; - - save(); - - if (env.dumpLineNumbers) { - debugInfo = getDebugInfo(i, input, env); - } - - while (true) { - s = this.lessSelector(); - if (!s) { - break; - } - if (selectors) { selectors.push(s); } else { selectors = [ s ]; } - this.comments(); - if (s.condition && selectors.length > 1) { - error("Guards are only currently allowed on a single selector."); - } - if (! $char(',')) { break; } - if (s.condition) { - error("Guards are only currently allowed on a single selector."); - } - this.comments(); - } - - if (selectors && (rules = this.block())) { - forget(); - var ruleset = new(tree.Ruleset)(selectors, rules, env.strictImports); - if (env.dumpLineNumbers) { - ruleset.debugInfo = debugInfo; - } - return ruleset; - } else { - // Backtrack - furthest = i; - restore(); - } - }, - rule: function (tryAnonymous) { - var name, value, startOfRule = i, c = input.charAt(startOfRule), important, merge, isVariable; - - if (c === '.' || c === '#' || c === '&') { return; } - - save(); - - name = this.variable() || this.ruleProperty(); - if (name) { - isVariable = typeof name === "string"; - - if (isVariable) { - value = this.detachedRuleset(); - } - - if (!value) { - // prefer to try to parse first if its a variable or we are compressing - // but always fallback on the other one - value = !tryAnonymous && (env.compress || isVariable) ? - (this.value() || this.anonymousValue()) : - (this.anonymousValue() || this.value()); - - important = this.important(); - - // a name returned by this.ruleProperty() is always an array of the form: - // [string-1, ..., string-n, ""] or [string-1, ..., string-n, "+"] - // where each item is a tree.Keyword or tree.Variable - merge = !isVariable && name.pop().value; - } - - if (value && this.end()) { - forget(); - return new (tree.Rule)(name, value, important, merge, startOfRule, env.currentFileInfo); - } else { - furthest = i; - restore(); - if (value && !tryAnonymous) { - return this.rule(true); - } - } - } else { - forget(); - } - }, - anonymousValue: function () { - var match; - match = /^([^@+\/'"*`(;{}-]*);/.exec(current); - if (match) { - i += match[0].length - 1; - return new(tree.Anonymous)(match[1]); - } - }, - - // - // An @import directive - // - // @import "lib"; - // - // Depending on our environemnt, importing is done differently: - // In the browser, it's an XHR request, in Node, it would be a - // file-system operation. The function used for importing is - // stored in `import`, which we pass to the Import constructor. - // - "import": function () { - var path, features, index = i; - - save(); - - var dir = $re(/^@import?\s+/); - - var options = (dir ? this.importOptions() : null) || {}; - - if (dir && (path = this.entities.quoted() || this.entities.url())) { - features = this.mediaFeatures(); - if ($char(';')) { - forget(); - features = features && new(tree.Value)(features); - return new(tree.Import)(path, features, options, index, env.currentFileInfo); - } - } - - restore(); - }, - - importOptions: function() { - var o, options = {}, optionName, value; - - // list of options, surrounded by parens - if (! $char('(')) { return null; } - do { - o = this.importOption(); - if (o) { - optionName = o; - value = true; - switch(optionName) { - case "css": - optionName = "less"; - value = false; - break; - case "once": - optionName = "multiple"; - value = false; - break; - } - options[optionName] = value; - if (! $char(',')) { break; } - } - } while (o); - expectChar(')'); - return options; - }, - - importOption: function() { - var opt = $re(/^(less|css|multiple|once|inline|reference)/); - if (opt) { - return opt[1]; - } - }, - - mediaFeature: function () { - var entities = this.entities, nodes = [], e, p; - do { - e = entities.keyword() || entities.variable(); - if (e) { - nodes.push(e); - } else if ($char('(')) { - p = this.property(); - e = this.value(); - if ($char(')')) { - if (p && e) { - nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, null, i, env.currentFileInfo, true))); - } else if (e) { - nodes.push(new(tree.Paren)(e)); - } else { - return null; - } - } else { return null; } - } - } while (e); - - if (nodes.length > 0) { - return new(tree.Expression)(nodes); - } - }, - - mediaFeatures: function () { - var entities = this.entities, features = [], e; - do { - e = this.mediaFeature(); - if (e) { - features.push(e); - if (! $char(',')) { break; } - } else { - e = entities.variable(); - if (e) { - features.push(e); - if (! $char(',')) { break; } - } - } - } while (e); - - return features.length > 0 ? features : null; - }, - - media: function () { - var features, rules, media, debugInfo; - - if (env.dumpLineNumbers) { - debugInfo = getDebugInfo(i, input, env); - } - - if ($re(/^@media/)) { - features = this.mediaFeatures(); - - rules = this.block(); - if (rules) { - media = new(tree.Media)(rules, features, i, env.currentFileInfo); - if (env.dumpLineNumbers) { - media.debugInfo = debugInfo; - } - return media; - } - } - }, - - // - // A CSS Directive - // - // @charset "utf-8"; - // - directive: function () { - var index = i, name, value, rules, nonVendorSpecificName, - hasIdentifier, hasExpression, hasUnknown, hasBlock = true; - - if (input.charAt(i) !== '@') { return; } - - value = this['import']() || this.media(); - if (value) { - return value; - } - - save(); - - name = $re(/^@[a-z-]+/); - - if (!name) { return; } - - nonVendorSpecificName = name; - if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) { - nonVendorSpecificName = "@" + name.slice(name.indexOf('-', 2) + 1); - } - - switch(nonVendorSpecificName) { - /* - case "@font-face": - case "@viewport": - case "@top-left": - case "@top-left-corner": - case "@top-center": - case "@top-right": - case "@top-right-corner": - case "@bottom-left": - case "@bottom-left-corner": - case "@bottom-center": - case "@bottom-right": - case "@bottom-right-corner": - case "@left-top": - case "@left-middle": - case "@left-bottom": - case "@right-top": - case "@right-middle": - case "@right-bottom": - hasBlock = true; - break; - */ - case "@charset": - hasIdentifier = true; - hasBlock = false; - break; - case "@namespace": - hasExpression = true; - hasBlock = false; - break; - case "@keyframes": - hasIdentifier = true; - break; - case "@host": - case "@page": - case "@document": - case "@supports": - hasUnknown = true; - break; - } - - if (hasIdentifier) { - value = this.entity(); - if (!value) { - error("expected " + name + " identifier"); - } - } else if (hasExpression) { - value = this.expression(); - if (!value) { - error("expected " + name + " expression"); - } - } else if (hasUnknown) { - value = ($re(/^[^{;]+/) || '').trim(); - if (value) { - value = new(tree.Anonymous)(value); - } - } - - if (hasBlock) { - rules = this.blockRuleset(); - } - - if (rules || (!hasBlock && value && $char(';'))) { - forget(); - return new(tree.Directive)(name, value, rules, index, env.currentFileInfo, - env.dumpLineNumbers ? getDebugInfo(index, input, env) : null); - } - - restore(); - }, - - // - // A Value is a comma-delimited list of Expressions - // - // font-family: Baskerville, Georgia, serif; - // - // In a Rule, a Value represents everything after the `:`, - // and before the `;`. - // - value: function () { - var e, expressions = []; - - do { - e = this.expression(); - if (e) { - expressions.push(e); - if (! $char(',')) { break; } - } - } while(e); - - if (expressions.length > 0) { - return new(tree.Value)(expressions); - } - }, - important: function () { - if (input.charAt(i) === '!') { - return $re(/^! *important/); - } - }, - sub: function () { - var a, e; - - if ($char('(')) { - a = this.addition(); - if (a) { - e = new(tree.Expression)([a]); - expectChar(')'); - e.parens = true; - return e; - } - } - }, - multiplication: function () { - var m, a, op, operation, isSpaced; - m = this.operand(); - if (m) { - isSpaced = isWhitespace(input, i - 1); - while (true) { - if (peek(/^\/[*\/]/)) { - break; - } - op = $char('/') || $char('*'); - - if (!op) { break; } - - a = this.operand(); - - if (!a) { break; } - - m.parensInOp = true; - a.parensInOp = true; - operation = new(tree.Operation)(op, [operation || m, a], isSpaced); - isSpaced = isWhitespace(input, i - 1); - } - return operation || m; - } - }, - addition: function () { - var m, a, op, operation, isSpaced; - m = this.multiplication(); - if (m) { - isSpaced = isWhitespace(input, i - 1); - while (true) { - op = $re(/^[-+]\s+/) || (!isSpaced && ($char('+') || $char('-'))); - if (!op) { - break; - } - a = this.multiplication(); - if (!a) { - break; - } - - m.parensInOp = true; - a.parensInOp = true; - operation = new(tree.Operation)(op, [operation || m, a], isSpaced); - isSpaced = isWhitespace(input, i - 1); - } - return operation || m; - } - }, - conditions: function () { - var a, b, index = i, condition; - - a = this.condition(); - if (a) { - while (true) { - if (!peek(/^,\s*(not\s*)?\(/) || !$char(',')) { - break; - } - b = this.condition(); - if (!b) { - break; - } - condition = new(tree.Condition)('or', condition || a, b, index); - } - return condition || a; - } - }, - condition: function () { - var entities = this.entities, index = i, negate = false, - a, b, c, op; - - if ($re(/^not/)) { negate = true; } - expectChar('('); - a = this.addition() || entities.keyword() || entities.quoted(); - if (a) { - op = $re(/^(?:>=|<=|=<|[<=>])/); - if (op) { - b = this.addition() || entities.keyword() || entities.quoted(); - if (b) { - c = new(tree.Condition)(op, a, b, index, negate); - } else { - error('expected expression'); - } - } else { - c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate); - } - expectChar(')'); - return $re(/^and/) ? new(tree.Condition)('and', c, this.condition()) : c; - } - }, - - // - // An operand is anything that can be part of an operation, - // such as a Color, or a Variable - // - operand: function () { - var entities = this.entities, - p = input.charAt(i + 1), negate; - - if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $char('-'); } - var o = this.sub() || entities.dimension() || - entities.color() || entities.variable() || - entities.call(); - - if (negate) { - o.parensInOp = true; - o = new(tree.Negative)(o); - } - - return o; - }, - - // - // Expressions either represent mathematical operations, - // or white-space delimited Entities. - // - // 1px solid black - // @var * 2 - // - expression: function () { - var entities = [], e, delim; - - do { - e = this.addition() || this.entity(); - if (e) { - entities.push(e); - // operations do not allow keyword "/" dimension (e.g. small/20px) so we support that here - if (!peek(/^\/[\/*]/)) { - delim = $char('/'); - if (delim) { - entities.push(new(tree.Anonymous)(delim)); - } - } - } - } while (e); - if (entities.length > 0) { - return new(tree.Expression)(entities); - } - }, - property: function () { - var name = $re(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/); - if (name) { - return name[1]; - } - }, - ruleProperty: function () { - var c = current, name = [], index = [], length = 0, s, k; - - function match(re) { - var a = re.exec(c); - if (a) { - index.push(i + length); - length += a[0].length; - c = c.slice(a[1].length); - return name.push(a[1]); - } - } - - match(/^(\*?)/); - while (match(/^((?:[\w-]+)|(?:@\{[\w-]+\}))/)); // ! - if ((name.length > 1) && match(/^\s*((?:\+_|\+)?)\s*:/)) { - // at last, we have the complete match now. move forward, - // convert name particles to tree objects and return: - skipWhitespace(length); - if (name[0] === '') { - name.shift(); - index.shift(); - } - for (k = 0; k < name.length; k++) { - s = name[k]; - name[k] = (s.charAt(0) !== '@') - ? new(tree.Keyword)(s) - : new(tree.Variable)('@' + s.slice(2, -1), - index[k], env.currentFileInfo); - } - return name; - } - } - } - }; - return parser; -}; -less.Parser.serializeVars = function(vars) { - var s = ''; - - for (var name in vars) { - if (Object.hasOwnProperty.call(vars, name)) { - var value = vars[name]; - s += ((name[0] === '@') ? '' : '@') + name +': '+ value + - ((('' + value).slice(-1) === ';') ? '' : ';'); - } - } - - return s; -}; - -(function (tree) { - -tree.functions = { - rgb: function (r, g, b) { - return this.rgba(r, g, b, 1.0); - }, - rgba: function (r, g, b, a) { - var rgb = [r, g, b].map(function (c) { return scaled(c, 255); }); - a = number(a); - return new(tree.Color)(rgb, a); - }, - hsl: function (h, s, l) { - return this.hsla(h, s, l, 1.0); - }, - hsla: function (h, s, l, a) { - function hue(h) { - h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h); - if (h * 6 < 1) { return m1 + (m2 - m1) * h * 6; } - else if (h * 2 < 1) { return m2; } - else if (h * 3 < 2) { return m1 + (m2 - m1) * (2/3 - h) * 6; } - else { return m1; } - } - - h = (number(h) % 360) / 360; - s = clamp(number(s)); l = clamp(number(l)); a = clamp(number(a)); - - var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s; - var m1 = l * 2 - m2; - - return this.rgba(hue(h + 1/3) * 255, - hue(h) * 255, - hue(h - 1/3) * 255, - a); - }, - - hsv: function(h, s, v) { - return this.hsva(h, s, v, 1.0); - }, - - hsva: function(h, s, v, a) { - h = ((number(h) % 360) / 360) * 360; - s = number(s); v = number(v); a = number(a); - - var i, f; - i = Math.floor((h / 60) % 6); - f = (h / 60) - i; - - var vs = [v, - v * (1 - s), - v * (1 - f * s), - v * (1 - (1 - f) * s)]; - var perm = [[0, 3, 1], - [2, 0, 1], - [1, 0, 3], - [1, 2, 0], - [3, 1, 0], - [0, 1, 2]]; - - return this.rgba(vs[perm[i][0]] * 255, - vs[perm[i][1]] * 255, - vs[perm[i][2]] * 255, - a); - }, - - hue: function (color) { - return new(tree.Dimension)(Math.round(color.toHSL().h)); - }, - saturation: function (color) { - return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%'); - }, - lightness: function (color) { - return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%'); - }, - hsvhue: function(color) { - return new(tree.Dimension)(Math.round(color.toHSV().h)); - }, - hsvsaturation: function (color) { - return new(tree.Dimension)(Math.round(color.toHSV().s * 100), '%'); - }, - hsvvalue: function (color) { - return new(tree.Dimension)(Math.round(color.toHSV().v * 100), '%'); - }, - red: function (color) { - return new(tree.Dimension)(color.rgb[0]); - }, - green: function (color) { - return new(tree.Dimension)(color.rgb[1]); - }, - blue: function (color) { - return new(tree.Dimension)(color.rgb[2]); - }, - alpha: function (color) { - return new(tree.Dimension)(color.toHSL().a); - }, - luma: function (color) { - return new(tree.Dimension)(Math.round(color.luma() * color.alpha * 100), '%'); - }, - luminance: function (color) { - var luminance = - (0.2126 * color.rgb[0] / 255) - + (0.7152 * color.rgb[1] / 255) - + (0.0722 * color.rgb[2] / 255); - - return new(tree.Dimension)(Math.round(luminance * color.alpha * 100), '%'); - }, - saturate: function (color, amount) { - // filter: saturate(3.2); - // should be kept as is, so check for color - if (!color.rgb) { - return null; - } - var hsl = color.toHSL(); - - hsl.s += amount.value / 100; - hsl.s = clamp(hsl.s); - return hsla(hsl); - }, - desaturate: function (color, amount) { - var hsl = color.toHSL(); - - hsl.s -= amount.value / 100; - hsl.s = clamp(hsl.s); - return hsla(hsl); - }, - lighten: function (color, amount) { - var hsl = color.toHSL(); - - hsl.l += amount.value / 100; - hsl.l = clamp(hsl.l); - return hsla(hsl); - }, - darken: function (color, amount) { - var hsl = color.toHSL(); - - hsl.l -= amount.value / 100; - hsl.l = clamp(hsl.l); - return hsla(hsl); - }, - fadein: function (color, amount) { - var hsl = color.toHSL(); - - hsl.a += amount.value / 100; - hsl.a = clamp(hsl.a); - return hsla(hsl); - }, - fadeout: function (color, amount) { - var hsl = color.toHSL(); - - hsl.a -= amount.value / 100; - hsl.a = clamp(hsl.a); - return hsla(hsl); - }, - fade: function (color, amount) { - var hsl = color.toHSL(); - - hsl.a = amount.value / 100; - hsl.a = clamp(hsl.a); - return hsla(hsl); - }, - spin: function (color, amount) { - var hsl = color.toHSL(); - var hue = (hsl.h + amount.value) % 360; - - hsl.h = hue < 0 ? 360 + hue : hue; - - return hsla(hsl); - }, - // - // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein - // http://sass-lang.com - // - mix: function (color1, color2, weight) { - if (!weight) { - weight = new(tree.Dimension)(50); - } - var p = weight.value / 100.0; - var w = p * 2 - 1; - var a = color1.toHSL().a - color2.toHSL().a; - - var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0; - var w2 = 1 - w1; - - var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2, - color1.rgb[1] * w1 + color2.rgb[1] * w2, - color1.rgb[2] * w1 + color2.rgb[2] * w2]; - - var alpha = color1.alpha * p + color2.alpha * (1 - p); - - return new(tree.Color)(rgb, alpha); - }, - greyscale: function (color) { - return this.desaturate(color, new(tree.Dimension)(100)); - }, - contrast: function (color, dark, light, threshold) { - // filter: contrast(3.2); - // should be kept as is, so check for color - if (!color.rgb) { - return null; - } - if (typeof light === 'undefined') { - light = this.rgba(255, 255, 255, 1.0); - } - if (typeof dark === 'undefined') { - dark = this.rgba(0, 0, 0, 1.0); - } - //Figure out which is actually light and dark! - if (dark.luma() > light.luma()) { - var t = light; - light = dark; - dark = t; - } - if (typeof threshold === 'undefined') { - threshold = 0.43; - } else { - threshold = number(threshold); - } - if (color.luma() < threshold) { - return light; - } else { - return dark; - } - }, - e: function (str) { - return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str); - }, - escape: function (str) { - return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29")); - }, - replace: function (string, pattern, replacement, flags) { - var result = string.value; - - result = result.replace(new RegExp(pattern.value, flags ? flags.value : ''), replacement.value); - return new(tree.Quoted)(string.quote || '', result, string.escaped); - }, - '%': function (string /* arg, arg, ...*/) { - var args = Array.prototype.slice.call(arguments, 1), - result = string.value; - - for (var i = 0; i < args.length; i++) { - /*jshint loopfunc:true */ - result = result.replace(/%[sda]/i, function(token) { - var value = token.match(/s/i) ? args[i].value : args[i].toCSS(); - return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value; - }); - } - result = result.replace(/%%/g, '%'); - return new(tree.Quoted)(string.quote || '', result, string.escaped); - }, - unit: function (val, unit) { - if(!(val instanceof tree.Dimension)) { - throw { type: "Argument", message: "the first argument to unit must be a number" + (val instanceof tree.Operation ? ". Have you forgotten parenthesis?" : "") }; - } - if (unit) { - if (unit instanceof tree.Keyword) { - unit = unit.value; - } else { - unit = unit.toCSS(); - } - } else { - unit = ""; - } - return new(tree.Dimension)(val.value, unit); - }, - convert: function (val, unit) { - return val.convertTo(unit.value); - }, - round: function (n, f) { - var fraction = typeof(f) === "undefined" ? 0 : f.value; - return _math(function(num) { return num.toFixed(fraction); }, null, n); - }, - pi: function () { - return new(tree.Dimension)(Math.PI); - }, - mod: function(a, b) { - return new(tree.Dimension)(a.value % b.value, a.unit); - }, - pow: function(x, y) { - if (typeof x === "number" && typeof y === "number") { - x = new(tree.Dimension)(x); - y = new(tree.Dimension)(y); - } else if (!(x instanceof tree.Dimension) || !(y instanceof tree.Dimension)) { - throw { type: "Argument", message: "arguments must be numbers" }; - } - - return new(tree.Dimension)(Math.pow(x.value, y.value), x.unit); - }, - _minmax: function (isMin, args) { - args = Array.prototype.slice.call(args); - switch(args.length) { - case 0: throw { type: "Argument", message: "one or more arguments required" }; - } - var i, j, current, currentUnified, referenceUnified, unit, unitStatic, unitClone, - order = [], // elems only contains original argument values. - values = {}; // key is the unit.toString() for unified tree.Dimension values, - // value is the index into the order array. - for (i = 0; i < args.length; i++) { - current = args[i]; - if (!(current instanceof tree.Dimension)) { - if(Array.isArray(args[i].value)) { - Array.prototype.push.apply(args, Array.prototype.slice.call(args[i].value)); - } - continue; - } - currentUnified = current.unit.toString() === "" && unitClone !== undefined ? new(tree.Dimension)(current.value, unitClone).unify() : current.unify(); - unit = currentUnified.unit.toString() === "" && unitStatic !== undefined ? unitStatic : currentUnified.unit.toString(); - unitStatic = unit !== "" && unitStatic === undefined || unit !== "" && order[0].unify().unit.toString() === "" ? unit : unitStatic; - unitClone = unit !== "" && unitClone === undefined ? current.unit.toString() : unitClone; - j = values[""] !== undefined && unit !== "" && unit === unitStatic ? values[""] : values[unit]; - if (j === undefined) { - if(unitStatic !== undefined && unit !== unitStatic) { - throw{ type: "Argument", message: "incompatible types" }; - } - values[unit] = order.length; - order.push(current); - continue; - } - referenceUnified = order[j].unit.toString() === "" && unitClone !== undefined ? new(tree.Dimension)(order[j].value, unitClone).unify() : order[j].unify(); - if ( isMin && currentUnified.value < referenceUnified.value || - !isMin && currentUnified.value > referenceUnified.value) { - order[j] = current; - } - } - if (order.length == 1) { - return order[0]; - } - args = order.map(function (a) { return a.toCSS(this.env); }).join(this.env.compress ? "," : ", "); - return new(tree.Anonymous)((isMin ? "min" : "max") + "(" + args + ")"); - }, - min: function () { - return this._minmax(true, arguments); - }, - max: function () { - return this._minmax(false, arguments); - }, - "get-unit": function (n) { - return new(tree.Anonymous)(n.unit); - }, - argb: function (color) { - return new(tree.Anonymous)(color.toARGB()); - }, - percentage: function (n) { - return new(tree.Dimension)(n.value * 100, '%'); - }, - color: function (n) { - if (n instanceof tree.Quoted) { - var colorCandidate = n.value, - returnColor; - returnColor = tree.Color.fromKeyword(colorCandidate); - if (returnColor) { - return returnColor; - } - if (/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/.test(colorCandidate)) { - return new(tree.Color)(colorCandidate.slice(1)); - } - throw { type: "Argument", message: "argument must be a color keyword or 3/6 digit hex e.g. #FFF" }; - } else { - throw { type: "Argument", message: "argument must be a string" }; - } - }, - iscolor: function (n) { - return this._isa(n, tree.Color); - }, - isnumber: function (n) { - return this._isa(n, tree.Dimension); - }, - isstring: function (n) { - return this._isa(n, tree.Quoted); - }, - iskeyword: function (n) { - return this._isa(n, tree.Keyword); - }, - isurl: function (n) { - return this._isa(n, tree.URL); - }, - ispixel: function (n) { - return this.isunit(n, 'px'); - }, - ispercentage: function (n) { - return this.isunit(n, '%'); - }, - isem: function (n) { - return this.isunit(n, 'em'); - }, - isunit: function (n, unit) { - return (n instanceof tree.Dimension) && n.unit.is(unit.value || unit) ? tree.True : tree.False; - }, - _isa: function (n, Type) { - return (n instanceof Type) ? tree.True : tree.False; - }, - tint: function(color, amount) { - return this.mix(this.rgb(255,255,255), color, amount); - }, - shade: function(color, amount) { - return this.mix(this.rgb(0, 0, 0), color, amount); - }, - extract: function(values, index) { - index = index.value - 1; // (1-based index) - // handle non-array values as an array of length 1 - // return 'undefined' if index is invalid - return Array.isArray(values.value) - ? values.value[index] : Array(values)[index]; - }, - length: function(values) { - var n = Array.isArray(values.value) ? values.value.length : 1; - return new tree.Dimension(n); - }, - - "data-uri": function(mimetypeNode, filePathNode) { - - if (typeof window !== 'undefined') { - return new tree.URL(filePathNode || mimetypeNode, this.currentFileInfo).eval(this.env); - } - - var mimetype = mimetypeNode.value; - var filePath = (filePathNode && filePathNode.value); - - var fs = require('fs'), - path = require('path'), - useBase64 = false; - - if (arguments.length < 2) { - filePath = mimetype; - } - - if (this.env.isPathRelative(filePath)) { - if (this.currentFileInfo.relativeUrls) { - filePath = path.join(this.currentFileInfo.currentDirectory, filePath); - } else { - filePath = path.join(this.currentFileInfo.entryPath, filePath); - } - } - - // detect the mimetype if not given - if (arguments.length < 2) { - var mime; - try { - mime = require('mime'); - } catch (ex) { - mime = tree._mime; - } - - mimetype = mime.lookup(filePath); - - // use base 64 unless it's an ASCII or UTF-8 format - var charset = mime.charsets.lookup(mimetype); - useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0; - if (useBase64) { mimetype += ';base64'; } - } - else { - useBase64 = /;base64$/.test(mimetype); - } - - var buf = fs.readFileSync(filePath); - - // IE8 cannot handle a data-uri larger than 32KB. If this is exceeded - // and the --ieCompat flag is enabled, return a normal url() instead. - var DATA_URI_MAX_KB = 32, - fileSizeInKB = parseInt((buf.length / 1024), 10); - if (fileSizeInKB >= DATA_URI_MAX_KB) { - - if (this.env.ieCompat !== false) { - if (!this.env.silent) { - console.warn("Skipped data-uri embedding of %s because its size (%dKB) exceeds IE8-safe %dKB!", filePath, fileSizeInKB, DATA_URI_MAX_KB); - } - - return new tree.URL(filePathNode || mimetypeNode, this.currentFileInfo).eval(this.env); - } - } - - buf = useBase64 ? buf.toString('base64') - : encodeURIComponent(buf); - - var uri = "\"data:" + mimetype + ',' + buf + "\""; - return new(tree.URL)(new(tree.Anonymous)(uri)); - }, - - "svg-gradient": function(direction) { - - function throwArgumentDescriptor() { - throw { type: "Argument", message: "svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position]" }; - } - - if (arguments.length < 3) { - throwArgumentDescriptor(); - } - var stops = Array.prototype.slice.call(arguments, 1), - gradientDirectionSvg, - gradientType = "linear", - rectangleDimension = 'x="0" y="0" width="1" height="1"', - useBase64 = true, - renderEnv = {compress: false}, - returner, - directionValue = direction.toCSS(renderEnv), - i, color, position, positionValue, alpha; - - switch (directionValue) { - case "to bottom": - gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"'; - break; - case "to right": - gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="0%"'; - break; - case "to bottom right": - gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="100%"'; - break; - case "to top right": - gradientDirectionSvg = 'x1="0%" y1="100%" x2="100%" y2="0%"'; - break; - case "ellipse": - case "ellipse at center": - gradientType = "radial"; - gradientDirectionSvg = 'cx="50%" cy="50%" r="75%"'; - rectangleDimension = 'x="-50" y="-50" width="101" height="101"'; - break; - default: - throw { type: "Argument", message: "svg-gradient direction must be 'to bottom', 'to right', 'to bottom right', 'to top right' or 'ellipse at center'" }; - } - returner = '' + - '' + - '<' + gradientType + 'Gradient id="gradient" gradientUnits="userSpaceOnUse" ' + gradientDirectionSvg + '>'; - - for (i = 0; i < stops.length; i+= 1) { - if (stops[i].value) { - color = stops[i].value[0]; - position = stops[i].value[1]; - } else { - color = stops[i]; - position = undefined; - } - - if (!(color instanceof tree.Color) || (!((i === 0 || i+1 === stops.length) && position === undefined) && !(position instanceof tree.Dimension))) { - throwArgumentDescriptor(); - } - positionValue = position ? position.toCSS(renderEnv) : i === 0 ? "0%" : "100%"; - alpha = color.alpha; - returner += ''; - } - returner += '' + - ''; - - if (useBase64) { - try { - returner = require('./encoder').encodeBase64(returner); // TODO browser implementation - } catch(e) { - useBase64 = false; - } - } - - returner = "'data:image/svg+xml" + (useBase64 ? ";base64" : "") + "," + returner + "'"; - return new(tree.URL)(new(tree.Anonymous)(returner)); - } -}; - -// these static methods are used as a fallback when the optional 'mime' dependency is missing -tree._mime = { - // this map is intentionally incomplete - // if you want more, install 'mime' dep - _types: { - '.htm' : 'text/html', - '.html': 'text/html', - '.gif' : 'image/gif', - '.jpg' : 'image/jpeg', - '.jpeg': 'image/jpeg', - '.png' : 'image/png' - }, - lookup: function (filepath) { - var ext = require('path').extname(filepath), - type = tree._mime._types[ext]; - if (type === undefined) { - throw new Error('Optional dependency "mime" is required for ' + ext); - } - return type; - }, - charsets: { - lookup: function (type) { - // assumes all text types are UTF-8 - return type && (/^text\//).test(type) ? 'UTF-8' : ''; - } - } -}; - -// Math - -var mathFunctions = { - // name, unit - ceil: null, - floor: null, - sqrt: null, - abs: null, - tan: "", - sin: "", - cos: "", - atan: "rad", - asin: "rad", - acos: "rad" -}; - -function _math(fn, unit, n) { - if (!(n instanceof tree.Dimension)) { - throw { type: "Argument", message: "argument must be a number" }; - } - if (unit == null) { - unit = n.unit; - } else { - n = n.unify(); - } - return new(tree.Dimension)(fn(parseFloat(n.value)), unit); -} - -// ~ End of Math - -// Color Blending -// ref: http://www.w3.org/TR/compositing-1 - -function colorBlend(mode, color1, color2) { - var ab = color1.alpha, cb, // backdrop - as = color2.alpha, cs, // source - ar, cr, r = []; // result - - ar = as + ab * (1 - as); - for (var i = 0; i < 3; i++) { - cb = color1.rgb[i] / 255; - cs = color2.rgb[i] / 255; - cr = mode(cb, cs); - if (ar) { - cr = (as * cs + ab * (cb - - as * (cb + cs - cr))) / ar; - } - r[i] = cr * 255; - } - - return new(tree.Color)(r, ar); -} - -var colorBlendMode = { - multiply: function(cb, cs) { - return cb * cs; - }, - screen: function(cb, cs) { - return cb + cs - cb * cs; - }, - overlay: function(cb, cs) { - cb *= 2; - return (cb <= 1) - ? colorBlendMode.multiply(cb, cs) - : colorBlendMode.screen(cb - 1, cs); - }, - softlight: function(cb, cs) { - var d = 1, e = cb; - if (cs > 0.5) { - e = 1; - d = (cb > 0.25) ? Math.sqrt(cb) - : ((16 * cb - 12) * cb + 4) * cb; - } - return cb - (1 - 2 * cs) * e * (d - cb); - }, - hardlight: function(cb, cs) { - return colorBlendMode.overlay(cs, cb); - }, - difference: function(cb, cs) { - return Math.abs(cb - cs); - }, - exclusion: function(cb, cs) { - return cb + cs - 2 * cb * cs; - }, - - // non-w3c functions: - average: function(cb, cs) { - return (cb + cs) / 2; - }, - negation: function(cb, cs) { - return 1 - Math.abs(cb + cs - 1); - } -}; - -// ~ End of Color Blending - -tree.defaultFunc = { - eval: function () { - var v = this.value_, e = this.error_; - if (e) { - throw e; - } - if (v != null) { - return v ? tree.True : tree.False; - } - }, - value: function (v) { - this.value_ = v; - }, - error: function (e) { - this.error_ = e; - }, - reset: function () { - this.value_ = this.error_ = null; - } -}; - -function initFunctions() { - var f, tf = tree.functions; - - // math - for (f in mathFunctions) { - if (mathFunctions.hasOwnProperty(f)) { - tf[f] = _math.bind(null, Math[f], mathFunctions[f]); - } - } - - // color blending - for (f in colorBlendMode) { - if (colorBlendMode.hasOwnProperty(f)) { - tf[f] = colorBlend.bind(null, colorBlendMode[f]); - } - } - - // default - f = tree.defaultFunc; - tf["default"] = f.eval.bind(f); - -} initFunctions(); - -function hsla(color) { - return tree.functions.hsla(color.h, color.s, color.l, color.a); -} - -function scaled(n, size) { - if (n instanceof tree.Dimension && n.unit.is('%')) { - return parseFloat(n.value * size / 100); - } else { - return number(n); - } -} - -function number(n) { - if (n instanceof tree.Dimension) { - return parseFloat(n.unit.is('%') ? n.value / 100 : n.value); - } else if (typeof(n) === 'number') { - return n; - } else { - throw { - error: "RuntimeError", - message: "color functions take numbers as parameters" - }; - } -} - -function clamp(val) { - return Math.min(1, Math.max(0, val)); -} - -tree.fround = function(env, value) { - var p; - if (env && (env.numPrecision != null)) { - p = Math.pow(10, env.numPrecision); - return Math.round(value * p) / p; - } else { - return value; - } -}; - -tree.functionCall = function(env, currentFileInfo) { - this.env = env; - this.currentFileInfo = currentFileInfo; -}; - -tree.functionCall.prototype = tree.functions; - -})(require('./tree')); - -(function (tree) { - tree.colors = { - 'aliceblue':'#f0f8ff', - 'antiquewhite':'#faebd7', - 'aqua':'#00ffff', - 'aquamarine':'#7fffd4', - 'azure':'#f0ffff', - 'beige':'#f5f5dc', - 'bisque':'#ffe4c4', - 'black':'#000000', - 'blanchedalmond':'#ffebcd', - 'blue':'#0000ff', - 'blueviolet':'#8a2be2', - 'brown':'#a52a2a', - 'burlywood':'#deb887', - 'cadetblue':'#5f9ea0', - 'chartreuse':'#7fff00', - 'chocolate':'#d2691e', - 'coral':'#ff7f50', - 'cornflowerblue':'#6495ed', - 'cornsilk':'#fff8dc', - 'crimson':'#dc143c', - 'cyan':'#00ffff', - 'darkblue':'#00008b', - 'darkcyan':'#008b8b', - 'darkgoldenrod':'#b8860b', - 'darkgray':'#a9a9a9', - 'darkgrey':'#a9a9a9', - 'darkgreen':'#006400', - 'darkkhaki':'#bdb76b', - 'darkmagenta':'#8b008b', - 'darkolivegreen':'#556b2f', - 'darkorange':'#ff8c00', - 'darkorchid':'#9932cc', - 'darkred':'#8b0000', - 'darksalmon':'#e9967a', - 'darkseagreen':'#8fbc8f', - 'darkslateblue':'#483d8b', - 'darkslategray':'#2f4f4f', - 'darkslategrey':'#2f4f4f', - 'darkturquoise':'#00ced1', - 'darkviolet':'#9400d3', - 'deeppink':'#ff1493', - 'deepskyblue':'#00bfff', - 'dimgray':'#696969', - 'dimgrey':'#696969', - 'dodgerblue':'#1e90ff', - 'firebrick':'#b22222', - 'floralwhite':'#fffaf0', - 'forestgreen':'#228b22', - 'fuchsia':'#ff00ff', - 'gainsboro':'#dcdcdc', - 'ghostwhite':'#f8f8ff', - 'gold':'#ffd700', - 'goldenrod':'#daa520', - 'gray':'#808080', - 'grey':'#808080', - 'green':'#008000', - 'greenyellow':'#adff2f', - 'honeydew':'#f0fff0', - 'hotpink':'#ff69b4', - 'indianred':'#cd5c5c', - 'indigo':'#4b0082', - 'ivory':'#fffff0', - 'khaki':'#f0e68c', - 'lavender':'#e6e6fa', - 'lavenderblush':'#fff0f5', - 'lawngreen':'#7cfc00', - 'lemonchiffon':'#fffacd', - 'lightblue':'#add8e6', - 'lightcoral':'#f08080', - 'lightcyan':'#e0ffff', - 'lightgoldenrodyellow':'#fafad2', - 'lightgray':'#d3d3d3', - 'lightgrey':'#d3d3d3', - 'lightgreen':'#90ee90', - 'lightpink':'#ffb6c1', - 'lightsalmon':'#ffa07a', - 'lightseagreen':'#20b2aa', - 'lightskyblue':'#87cefa', - 'lightslategray':'#778899', - 'lightslategrey':'#778899', - 'lightsteelblue':'#b0c4de', - 'lightyellow':'#ffffe0', - 'lime':'#00ff00', - 'limegreen':'#32cd32', - 'linen':'#faf0e6', - 'magenta':'#ff00ff', - 'maroon':'#800000', - 'mediumaquamarine':'#66cdaa', - 'mediumblue':'#0000cd', - 'mediumorchid':'#ba55d3', - 'mediumpurple':'#9370d8', - 'mediumseagreen':'#3cb371', - 'mediumslateblue':'#7b68ee', - 'mediumspringgreen':'#00fa9a', - 'mediumturquoise':'#48d1cc', - 'mediumvioletred':'#c71585', - 'midnightblue':'#191970', - 'mintcream':'#f5fffa', - 'mistyrose':'#ffe4e1', - 'moccasin':'#ffe4b5', - 'navajowhite':'#ffdead', - 'navy':'#000080', - 'oldlace':'#fdf5e6', - 'olive':'#808000', - 'olivedrab':'#6b8e23', - 'orange':'#ffa500', - 'orangered':'#ff4500', - 'orchid':'#da70d6', - 'palegoldenrod':'#eee8aa', - 'palegreen':'#98fb98', - 'paleturquoise':'#afeeee', - 'palevioletred':'#d87093', - 'papayawhip':'#ffefd5', - 'peachpuff':'#ffdab9', - 'peru':'#cd853f', - 'pink':'#ffc0cb', - 'plum':'#dda0dd', - 'powderblue':'#b0e0e6', - 'purple':'#800080', - 'red':'#ff0000', - 'rosybrown':'#bc8f8f', - 'royalblue':'#4169e1', - 'saddlebrown':'#8b4513', - 'salmon':'#fa8072', - 'sandybrown':'#f4a460', - 'seagreen':'#2e8b57', - 'seashell':'#fff5ee', - 'sienna':'#a0522d', - 'silver':'#c0c0c0', - 'skyblue':'#87ceeb', - 'slateblue':'#6a5acd', - 'slategray':'#708090', - 'slategrey':'#708090', - 'snow':'#fffafa', - 'springgreen':'#00ff7f', - 'steelblue':'#4682b4', - 'tan':'#d2b48c', - 'teal':'#008080', - 'thistle':'#d8bfd8', - 'tomato':'#ff6347', - 'turquoise':'#40e0d0', - 'violet':'#ee82ee', - 'wheat':'#f5deb3', - 'white':'#ffffff', - 'whitesmoke':'#f5f5f5', - 'yellow':'#ffff00', - 'yellowgreen':'#9acd32' - }; -})(require('./tree')); - -(function (tree) { - -tree.debugInfo = function(env, ctx, lineSeperator) { - var result=""; - if (env.dumpLineNumbers && !env.compress) { - switch(env.dumpLineNumbers) { - case 'comments': - result = tree.debugInfo.asComment(ctx); - break; - case 'mediaquery': - result = tree.debugInfo.asMediaQuery(ctx); - break; - case 'all': - result = tree.debugInfo.asComment(ctx) + (lineSeperator || "") + tree.debugInfo.asMediaQuery(ctx); - break; - } - } - return result; -}; - -tree.debugInfo.asComment = function(ctx) { - return '/* line ' + ctx.debugInfo.lineNumber + ', ' + ctx.debugInfo.fileName + ' */\n'; -}; - -tree.debugInfo.asMediaQuery = function(ctx) { - return '@media -sass-debug-info{filename{font-family:' + - ('file://' + ctx.debugInfo.fileName).replace(/([.:\/\\])/g, function (a) { - if (a == '\\') { - a = '\/'; - } - return '\\' + a; - }) + - '}line{font-family:\\00003' + ctx.debugInfo.lineNumber + '}}\n'; -}; - -tree.find = function (obj, fun) { - for (var i = 0, r; i < obj.length; i++) { - r = fun.call(obj, obj[i]); - if (r) { return r; } - } - return null; -}; - -tree.jsify = function (obj) { - if (Array.isArray(obj.value) && (obj.value.length > 1)) { - return '[' + obj.value.map(function (v) { return v.toCSS(false); }).join(', ') + ']'; - } else { - return obj.toCSS(false); - } -}; - -tree.toCSS = function (env) { - var strs = []; - this.genCSS(env, { - add: function(chunk, fileInfo, index) { - strs.push(chunk); - }, - isEmpty: function () { - return strs.length === 0; - } - }); - return strs.join(''); -}; - -tree.outputRuleset = function (env, output, rules) { - var ruleCnt = rules.length, i; - env.tabLevel = (env.tabLevel | 0) + 1; - - // Compressed - if (env.compress) { - output.add('{'); - for (i = 0; i < ruleCnt; i++) { - rules[i].genCSS(env, output); - } - output.add('}'); - env.tabLevel--; - return; - } - - // Non-compressed - var tabSetStr = '\n' + Array(env.tabLevel).join(" "), tabRuleStr = tabSetStr + " "; - if (!ruleCnt) { - output.add(" {" + tabSetStr + '}'); - } else { - output.add(" {" + tabRuleStr); - rules[0].genCSS(env, output); - for (i = 1; i < ruleCnt; i++) { - output.add(tabRuleStr); - rules[i].genCSS(env, output); - } - output.add(tabSetStr + '}'); - } - - env.tabLevel--; -}; - -})(require('./tree')); - -(function (tree) { - -tree.Alpha = function (val) { - this.value = val; -}; -tree.Alpha.prototype = { - type: "Alpha", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - eval: function (env) { - if (this.value.eval) { return new tree.Alpha(this.value.eval(env)); } - return this; - }, - genCSS: function (env, output) { - output.add("alpha(opacity="); - - if (this.value.genCSS) { - this.value.genCSS(env, output); - } else { - output.add(this.value); - } - - output.add(")"); - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -tree.Anonymous = function (string, index, currentFileInfo, mapLines) { - this.value = string.value || string; - this.index = index; - this.mapLines = mapLines; - this.currentFileInfo = currentFileInfo; -}; -tree.Anonymous.prototype = { - type: "Anonymous", - eval: function () { - return new tree.Anonymous(this.value, this.index, this.currentFileInfo, this.mapLines); - }, - compare: function (x) { - if (!x.toCSS) { - return -1; - } - - var left = this.toCSS(), - right = x.toCSS(); - - if (left === right) { - return 0; - } - - return left < right ? -1 : 1; - }, - genCSS: function (env, output) { - output.add(this.value, this.currentFileInfo, this.index, this.mapLines); - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -tree.Assignment = function (key, val) { - this.key = key; - this.value = val; -}; -tree.Assignment.prototype = { - type: "Assignment", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - eval: function (env) { - if (this.value.eval) { - return new(tree.Assignment)(this.key, this.value.eval(env)); - } - return this; - }, - genCSS: function (env, output) { - output.add(this.key + '='); - if (this.value.genCSS) { - this.value.genCSS(env, output); - } else { - output.add(this.value); - } - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -// -// A function call node. -// -tree.Call = function (name, args, index, currentFileInfo) { - this.name = name; - this.args = args; - this.index = index; - this.currentFileInfo = currentFileInfo; -}; -tree.Call.prototype = { - type: "Call", - accept: function (visitor) { - if (this.args) { - this.args = visitor.visitArray(this.args); - } - }, - // - // When evaluating a function call, - // we either find the function in `tree.functions` [1], - // in which case we call it, passing the evaluated arguments, - // if this returns null or we cannot find the function, we - // simply print it out as it appeared originally [2]. - // - // The *functions.js* file contains the built-in functions. - // - // The reason why we evaluate the arguments, is in the case where - // we try to pass a variable to a function, like: `saturate(@color)`. - // The function should receive the value, not the variable. - // - eval: function (env) { - var args = this.args.map(function (a) { return a.eval(env); }), - nameLC = this.name.toLowerCase(), - result, func; - - if (nameLC in tree.functions) { // 1. - try { - func = new tree.functionCall(env, this.currentFileInfo); - result = func[nameLC].apply(func, args); - if (result != null) { - return result; - } - } catch (e) { - throw { type: e.type || "Runtime", - message: "error evaluating function `" + this.name + "`" + - (e.message ? ': ' + e.message : ''), - index: this.index, filename: this.currentFileInfo.filename }; - } - } - - return new tree.Call(this.name, args, this.index, this.currentFileInfo); - }, - - genCSS: function (env, output) { - output.add(this.name + "(", this.currentFileInfo, this.index); - - for(var i = 0; i < this.args.length; i++) { - this.args[i].genCSS(env, output); - if (i + 1 < this.args.length) { - output.add(", "); - } - } - - output.add(")"); - }, - - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { -// -// RGB Colors - #ff0014, #eee -// -tree.Color = function (rgb, a) { - // - // The end goal here, is to parse the arguments - // into an integer triplet, such as `128, 255, 0` - // - // This facilitates operations and conversions. - // - if (Array.isArray(rgb)) { - this.rgb = rgb; - } else if (rgb.length == 6) { - this.rgb = rgb.match(/.{2}/g).map(function (c) { - return parseInt(c, 16); - }); - } else { - this.rgb = rgb.split('').map(function (c) { - return parseInt(c + c, 16); - }); - } - this.alpha = typeof(a) === 'number' ? a : 1; -}; - -var transparentKeyword = "transparent"; - -tree.Color.prototype = { - type: "Color", - eval: function () { return this; }, - luma: function () { - var r = this.rgb[0] / 255, - g = this.rgb[1] / 255, - b = this.rgb[2] / 255; - - r = (r <= 0.03928) ? r / 12.92 : Math.pow(((r + 0.055) / 1.055), 2.4); - g = (g <= 0.03928) ? g / 12.92 : Math.pow(((g + 0.055) / 1.055), 2.4); - b = (b <= 0.03928) ? b / 12.92 : Math.pow(((b + 0.055) / 1.055), 2.4); - - return 0.2126 * r + 0.7152 * g + 0.0722 * b; - }, - - genCSS: function (env, output) { - output.add(this.toCSS(env)); - }, - toCSS: function (env, doNotCompress) { - var compress = env && env.compress && !doNotCompress, - alpha = tree.fround(env, this.alpha); - - // If we have some transparency, the only way to represent it - // is via `rgba`. Otherwise, we use the hex representation, - // which has better compatibility with older browsers. - // Values are capped between `0` and `255`, rounded and zero-padded. - if (alpha < 1) { - if (alpha === 0 && this.isTransparentKeyword) { - return transparentKeyword; - } - return "rgba(" + this.rgb.map(function (c) { - return clamp(Math.round(c), 255); - }).concat(clamp(alpha, 1)) - .join(',' + (compress ? '' : ' ')) + ")"; - } else { - var color = this.toRGB(); - - if (compress) { - var splitcolor = color.split(''); - - // Convert color to short format - if (splitcolor[1] === splitcolor[2] && splitcolor[3] === splitcolor[4] && splitcolor[5] === splitcolor[6]) { - color = '#' + splitcolor[1] + splitcolor[3] + splitcolor[5]; - } - } - - return color; - } - }, - - // - // Operations have to be done per-channel, if not, - // channels will spill onto each other. Once we have - // our result, in the form of an integer triplet, - // we create a new Color node to hold the result. - // - operate: function (env, op, other) { - var rgb = []; - var alpha = this.alpha * (1 - other.alpha) + other.alpha; - for (var c = 0; c < 3; c++) { - rgb[c] = tree.operate(env, op, this.rgb[c], other.rgb[c]); - } - return new(tree.Color)(rgb, alpha); - }, - - toRGB: function () { - return toHex(this.rgb); - }, - - toHSL: function () { - var r = this.rgb[0] / 255, - g = this.rgb[1] / 255, - b = this.rgb[2] / 255, - a = this.alpha; - - var max = Math.max(r, g, b), min = Math.min(r, g, b); - var h, s, l = (max + min) / 2, d = max - min; - - if (max === min) { - h = s = 0; - } else { - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - - switch (max) { - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; - } - h /= 6; - } - return { h: h * 360, s: s, l: l, a: a }; - }, - //Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript - toHSV: function () { - var r = this.rgb[0] / 255, - g = this.rgb[1] / 255, - b = this.rgb[2] / 255, - a = this.alpha; - - var max = Math.max(r, g, b), min = Math.min(r, g, b); - var h, s, v = max; - - var d = max - min; - if (max === 0) { - s = 0; - } else { - s = d / max; - } - - if (max === min) { - h = 0; - } else { - switch(max){ - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; - } - h /= 6; - } - return { h: h * 360, s: s, v: v, a: a }; - }, - toARGB: function () { - return toHex([this.alpha * 255].concat(this.rgb)); - }, - compare: function (x) { - if (!x.rgb) { - return -1; - } - - return (x.rgb[0] === this.rgb[0] && - x.rgb[1] === this.rgb[1] && - x.rgb[2] === this.rgb[2] && - x.alpha === this.alpha) ? 0 : -1; - } -}; - -tree.Color.fromKeyword = function(keyword) { - keyword = keyword.toLowerCase(); - - if (tree.colors.hasOwnProperty(keyword)) { - // detect named color - return new(tree.Color)(tree.colors[keyword].slice(1)); - } - if (keyword === transparentKeyword) { - var transparent = new(tree.Color)([0, 0, 0], 0); - transparent.isTransparentKeyword = true; - return transparent; - } -}; - -function toHex(v) { - return '#' + v.map(function (c) { - c = clamp(Math.round(c), 255); - return (c < 16 ? '0' : '') + c.toString(16); - }).join(''); -} - -function clamp(v, max) { - return Math.min(Math.max(v, 0), max); -} - -})(require('../tree')); - -(function (tree) { - -tree.Comment = function (value, silent, index, currentFileInfo) { - this.value = value; - this.silent = !!silent; - this.currentFileInfo = currentFileInfo; -}; -tree.Comment.prototype = { - type: "Comment", - genCSS: function (env, output) { - if (this.debugInfo) { - output.add(tree.debugInfo(env, this), this.currentFileInfo, this.index); - } - output.add(this.value.trim()); //TODO shouldn't need to trim, we shouldn't grab the \n - }, - toCSS: tree.toCSS, - isSilent: function(env) { - var isReference = (this.currentFileInfo && this.currentFileInfo.reference && !this.isReferenced), - isCompressed = env.compress && !this.value.match(/^\/\*!/); - return this.silent || isReference || isCompressed; - }, - eval: function () { return this; }, - markReferenced: function () { - this.isReferenced = true; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Condition = function (op, l, r, i, negate) { - this.op = op.trim(); - this.lvalue = l; - this.rvalue = r; - this.index = i; - this.negate = negate; -}; -tree.Condition.prototype = { - type: "Condition", - accept: function (visitor) { - this.lvalue = visitor.visit(this.lvalue); - this.rvalue = visitor.visit(this.rvalue); - }, - eval: function (env) { - var a = this.lvalue.eval(env), - b = this.rvalue.eval(env); - - var i = this.index, result; - - result = (function (op) { - switch (op) { - case 'and': - return a && b; - case 'or': - return a || b; - default: - if (a.compare) { - result = a.compare(b); - } else if (b.compare) { - result = b.compare(a); - } else { - throw { type: "Type", - message: "Unable to perform comparison", - index: i }; - } - switch (result) { - case -1: return op === '<' || op === '=<' || op === '<='; - case 0: return op === '=' || op === '>=' || op === '=<' || op === '<='; - case 1: return op === '>' || op === '>='; - } - } - })(this.op); - return this.negate ? !result : result; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.DetachedRuleset = function (ruleset, frames) { - this.ruleset = ruleset; - this.frames = frames; -}; -tree.DetachedRuleset.prototype = { - type: "DetachedRuleset", - accept: function (visitor) { - this.ruleset = visitor.visit(this.ruleset); - }, - eval: function (env) { - var frames = this.frames || env.frames.slice(0); - return new tree.DetachedRuleset(this.ruleset, frames); - }, - callEval: function (env) { - return this.ruleset.eval(this.frames ? new(tree.evalEnv)(env, this.frames.concat(env.frames)) : env); - } -}; -})(require('../tree')); - -(function (tree) { - -// -// A number with a unit -// -tree.Dimension = function (value, unit) { - this.value = parseFloat(value); - this.unit = (unit && unit instanceof tree.Unit) ? unit : - new(tree.Unit)(unit ? [unit] : undefined); -}; - -tree.Dimension.prototype = { - type: "Dimension", - accept: function (visitor) { - this.unit = visitor.visit(this.unit); - }, - eval: function (env) { - return this; - }, - toColor: function () { - return new(tree.Color)([this.value, this.value, this.value]); - }, - genCSS: function (env, output) { - if ((env && env.strictUnits) && !this.unit.isSingular()) { - throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: "+this.unit.toString()); - } - - var value = tree.fround(env, this.value), - strValue = String(value); - - if (value !== 0 && value < 0.000001 && value > -0.000001) { - // would be output 1e-6 etc. - strValue = value.toFixed(20).replace(/0+$/, ""); - } - - if (env && env.compress) { - // Zero values doesn't need a unit - if (value === 0 && this.unit.isLength()) { - output.add(strValue); - return; - } - - // Float values doesn't need a leading zero - if (value > 0 && value < 1) { - strValue = (strValue).substr(1); - } - } - - output.add(strValue); - this.unit.genCSS(env, output); - }, - toCSS: tree.toCSS, - - // In an operation between two Dimensions, - // we default to the first Dimension's unit, - // so `1px + 2` will yield `3px`. - operate: function (env, op, other) { - /*jshint noempty:false */ - var value = tree.operate(env, op, this.value, other.value), - unit = this.unit.clone(); - - if (op === '+' || op === '-') { - if (unit.numerator.length === 0 && unit.denominator.length === 0) { - unit.numerator = other.unit.numerator.slice(0); - unit.denominator = other.unit.denominator.slice(0); - } else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) { - // do nothing - } else { - other = other.convertTo(this.unit.usedUnits()); - - if(env.strictUnits && other.unit.toString() !== unit.toString()) { - throw new Error("Incompatible units. Change the units or use the unit function. Bad units: '" + unit.toString() + - "' and '" + other.unit.toString() + "'."); - } - - value = tree.operate(env, op, this.value, other.value); - } - } else if (op === '*') { - unit.numerator = unit.numerator.concat(other.unit.numerator).sort(); - unit.denominator = unit.denominator.concat(other.unit.denominator).sort(); - unit.cancel(); - } else if (op === '/') { - unit.numerator = unit.numerator.concat(other.unit.denominator).sort(); - unit.denominator = unit.denominator.concat(other.unit.numerator).sort(); - unit.cancel(); - } - return new(tree.Dimension)(value, unit); - }, - - compare: function (other) { - if (other instanceof tree.Dimension) { - var a, b, - aValue, bValue; - - if (this.unit.isEmpty() || other.unit.isEmpty()) { - a = this; - b = other; - } else { - a = this.unify(); - b = other.unify(); - if (a.unit.compare(b.unit) !== 0) { - return -1; - } - } - aValue = a.value; - bValue = b.value; - - if (bValue > aValue) { - return -1; - } else if (bValue < aValue) { - return 1; - } else { - return 0; - } - } else { - return -1; - } - }, - - unify: function () { - return this.convertTo({ length: 'px', duration: 's', angle: 'rad' }); - }, - - convertTo: function (conversions) { - var value = this.value, unit = this.unit.clone(), - i, groupName, group, targetUnit, derivedConversions = {}, applyUnit; - - if (typeof conversions === 'string') { - for(i in tree.UnitConversions) { - if (tree.UnitConversions[i].hasOwnProperty(conversions)) { - derivedConversions = {}; - derivedConversions[i] = conversions; - } - } - conversions = derivedConversions; - } - applyUnit = function (atomicUnit, denominator) { - /*jshint loopfunc:true */ - if (group.hasOwnProperty(atomicUnit)) { - if (denominator) { - value = value / (group[atomicUnit] / group[targetUnit]); - } else { - value = value * (group[atomicUnit] / group[targetUnit]); - } - - return targetUnit; - } - - return atomicUnit; - }; - - for (groupName in conversions) { - if (conversions.hasOwnProperty(groupName)) { - targetUnit = conversions[groupName]; - group = tree.UnitConversions[groupName]; - - unit.map(applyUnit); - } - } - - unit.cancel(); - - return new(tree.Dimension)(value, unit); - } -}; - -// http://www.w3.org/TR/css3-values/#absolute-lengths -tree.UnitConversions = { - length: { - 'm': 1, - 'cm': 0.01, - 'mm': 0.001, - 'in': 0.0254, - 'px': 0.0254 / 96, - 'pt': 0.0254 / 72, - 'pc': 0.0254 / 72 * 12 - }, - duration: { - 's': 1, - 'ms': 0.001 - }, - angle: { - 'rad': 1/(2*Math.PI), - 'deg': 1/360, - 'grad': 1/400, - 'turn': 1 - } -}; - -tree.Unit = function (numerator, denominator, backupUnit) { - this.numerator = numerator ? numerator.slice(0).sort() : []; - this.denominator = denominator ? denominator.slice(0).sort() : []; - this.backupUnit = backupUnit; -}; - -tree.Unit.prototype = { - type: "Unit", - clone: function () { - return new tree.Unit(this.numerator.slice(0), this.denominator.slice(0), this.backupUnit); - }, - genCSS: function (env, output) { - if (this.numerator.length >= 1) { - output.add(this.numerator[0]); - } else - if (this.denominator.length >= 1) { - output.add(this.denominator[0]); - } else - if ((!env || !env.strictUnits) && this.backupUnit) { - output.add(this.backupUnit); - } - }, - toCSS: tree.toCSS, - - toString: function () { - var i, returnStr = this.numerator.join("*"); - for (i = 0; i < this.denominator.length; i++) { - returnStr += "/" + this.denominator[i]; - } - return returnStr; - }, - - compare: function (other) { - return this.is(other.toString()) ? 0 : -1; - }, - - is: function (unitString) { - return this.toString() === unitString; - }, - - isLength: function () { - return Boolean(this.toCSS().match(/px|em|%|in|cm|mm|pc|pt|ex/)); - }, - - isEmpty: function () { - return this.numerator.length === 0 && this.denominator.length === 0; - }, - - isSingular: function() { - return this.numerator.length <= 1 && this.denominator.length === 0; - }, - - map: function(callback) { - var i; - - for (i = 0; i < this.numerator.length; i++) { - this.numerator[i] = callback(this.numerator[i], false); - } - - for (i = 0; i < this.denominator.length; i++) { - this.denominator[i] = callback(this.denominator[i], true); - } - }, - - usedUnits: function() { - var group, result = {}, mapUnit; - - mapUnit = function (atomicUnit) { - /*jshint loopfunc:true */ - if (group.hasOwnProperty(atomicUnit) && !result[groupName]) { - result[groupName] = atomicUnit; - } - - return atomicUnit; - }; - - for (var groupName in tree.UnitConversions) { - if (tree.UnitConversions.hasOwnProperty(groupName)) { - group = tree.UnitConversions[groupName]; - - this.map(mapUnit); - } - } - - return result; - }, - - cancel: function () { - var counter = {}, atomicUnit, i, backup; - - for (i = 0; i < this.numerator.length; i++) { - atomicUnit = this.numerator[i]; - if (!backup) { - backup = atomicUnit; - } - counter[atomicUnit] = (counter[atomicUnit] || 0) + 1; - } - - for (i = 0; i < this.denominator.length; i++) { - atomicUnit = this.denominator[i]; - if (!backup) { - backup = atomicUnit; - } - counter[atomicUnit] = (counter[atomicUnit] || 0) - 1; - } - - this.numerator = []; - this.denominator = []; - - for (atomicUnit in counter) { - if (counter.hasOwnProperty(atomicUnit)) { - var count = counter[atomicUnit]; - - if (count > 0) { - for (i = 0; i < count; i++) { - this.numerator.push(atomicUnit); - } - } else if (count < 0) { - for (i = 0; i < -count; i++) { - this.denominator.push(atomicUnit); - } - } - } - } - - if (this.numerator.length === 0 && this.denominator.length === 0 && backup) { - this.backupUnit = backup; - } - - this.numerator.sort(); - this.denominator.sort(); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Directive = function (name, value, rules, index, currentFileInfo, debugInfo) { - this.name = name; - this.value = value; - if (rules) { - this.rules = rules; - this.rules.allowImports = true; - } - this.index = index; - this.currentFileInfo = currentFileInfo; - this.debugInfo = debugInfo; -}; - -tree.Directive.prototype = { - type: "Directive", - accept: function (visitor) { - var value = this.value, rules = this.rules; - if (rules) { - rules = visitor.visit(rules); - } - if (value) { - value = visitor.visit(value); - } - }, - genCSS: function (env, output) { - var value = this.value, rules = this.rules; - output.add(this.name, this.currentFileInfo, this.index); - if (value) { - output.add(' '); - value.genCSS(env, output); - } - if (rules) { - tree.outputRuleset(env, output, [rules]); - } else { - output.add(';'); - } - }, - toCSS: tree.toCSS, - eval: function (env) { - var value = this.value, rules = this.rules; - if (value) { - value = value.eval(env); - } - if (rules) { - rules = rules.eval(env); - rules.root = true; - } - return new(tree.Directive)(this.name, value, rules, - this.index, this.currentFileInfo, this.debugInfo); - }, - variable: function (name) { if (this.rules) return tree.Ruleset.prototype.variable.call(this.rules, name); }, - find: function () { if (this.rules) return tree.Ruleset.prototype.find.apply(this.rules, arguments); }, - rulesets: function () { if (this.rules) return tree.Ruleset.prototype.rulesets.apply(this.rules); }, - markReferenced: function () { - var i, rules; - this.isReferenced = true; - if (this.rules) { - rules = this.rules.rules; - for (i = 0; i < rules.length; i++) { - if (rules[i].markReferenced) { - rules[i].markReferenced(); - } - } - } - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Element = function (combinator, value, index, currentFileInfo) { - this.combinator = combinator instanceof tree.Combinator ? - combinator : new(tree.Combinator)(combinator); - - if (typeof(value) === 'string') { - this.value = value.trim(); - } else if (value) { - this.value = value; - } else { - this.value = ""; - } - this.index = index; - this.currentFileInfo = currentFileInfo; -}; -tree.Element.prototype = { - type: "Element", - accept: function (visitor) { - var value = this.value; - this.combinator = visitor.visit(this.combinator); - if (typeof value === "object") { - this.value = visitor.visit(value); - } - }, - eval: function (env) { - return new(tree.Element)(this.combinator, - this.value.eval ? this.value.eval(env) : this.value, - this.index, - this.currentFileInfo); - }, - genCSS: function (env, output) { - output.add(this.toCSS(env), this.currentFileInfo, this.index); - }, - toCSS: function (env) { - var value = (this.value.toCSS ? this.value.toCSS(env) : this.value); - if (value === '' && this.combinator.value.charAt(0) === '&') { - return ''; - } else { - return this.combinator.toCSS(env || {}) + value; - } - } -}; - -tree.Attribute = function (key, op, value) { - this.key = key; - this.op = op; - this.value = value; -}; -tree.Attribute.prototype = { - type: "Attribute", - eval: function (env) { - return new(tree.Attribute)(this.key.eval ? this.key.eval(env) : this.key, - this.op, (this.value && this.value.eval) ? this.value.eval(env) : this.value); - }, - genCSS: function (env, output) { - output.add(this.toCSS(env)); - }, - toCSS: function (env) { - var value = this.key.toCSS ? this.key.toCSS(env) : this.key; - - if (this.op) { - value += this.op; - value += (this.value.toCSS ? this.value.toCSS(env) : this.value); - } - - return '[' + value + ']'; - } -}; - -tree.Combinator = function (value) { - if (value === ' ') { - this.value = ' '; - } else { - this.value = value ? value.trim() : ""; - } -}; -tree.Combinator.prototype = { - type: "Combinator", - _outputMap: { - '' : '', - ' ' : ' ', - ':' : ' :', - '+' : ' + ', - '~' : ' ~ ', - '>' : ' > ', - '|' : '|', - '^' : ' ^ ', - '^^' : ' ^^ ' - }, - _outputMapCompressed: { - '' : '', - ' ' : ' ', - ':' : ' :', - '+' : '+', - '~' : '~', - '>' : '>', - '|' : '|', - '^' : '^', - '^^' : '^^' - }, - genCSS: function (env, output) { - output.add((env.compress ? this._outputMapCompressed : this._outputMap)[this.value]); - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -tree.Expression = function (value) { this.value = value; }; -tree.Expression.prototype = { - type: "Expression", - accept: function (visitor) { - if (this.value) { - this.value = visitor.visitArray(this.value); - } - }, - eval: function (env) { - var returnValue, - inParenthesis = this.parens && !this.parensInOp, - doubleParen = false; - if (inParenthesis) { - env.inParenthesis(); - } - if (this.value.length > 1) { - returnValue = new(tree.Expression)(this.value.map(function (e) { - return e.eval(env); - })); - } else if (this.value.length === 1) { - if (this.value[0].parens && !this.value[0].parensInOp) { - doubleParen = true; - } - returnValue = this.value[0].eval(env); - } else { - returnValue = this; - } - if (inParenthesis) { - env.outOfParenthesis(); - } - if (this.parens && this.parensInOp && !(env.isMathOn()) && !doubleParen) { - returnValue = new(tree.Paren)(returnValue); - } - return returnValue; - }, - genCSS: function (env, output) { - for(var i = 0; i < this.value.length; i++) { - this.value[i].genCSS(env, output); - if (i + 1 < this.value.length) { - output.add(" "); - } - } - }, - toCSS: tree.toCSS, - throwAwayComments: function () { - this.value = this.value.filter(function(v) { - return !(v instanceof tree.Comment); - }); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Extend = function Extend(selector, option, index) { - this.selector = selector; - this.option = option; - this.index = index; - this.object_id = tree.Extend.next_id++; - this.parent_ids = [this.object_id]; - - switch(option) { - case "all": - this.allowBefore = true; - this.allowAfter = true; - break; - default: - this.allowBefore = false; - this.allowAfter = false; - break; - } -}; -tree.Extend.next_id = 0; - -tree.Extend.prototype = { - type: "Extend", - accept: function (visitor) { - this.selector = visitor.visit(this.selector); - }, - eval: function (env) { - return new(tree.Extend)(this.selector.eval(env), this.option, this.index); - }, - clone: function (env) { - return new(tree.Extend)(this.selector, this.option, this.index); - }, - findSelfSelectors: function (selectors) { - var selfElements = [], - i, - selectorElements; - - for(i = 0; i < selectors.length; i++) { - selectorElements = selectors[i].elements; - // duplicate the logic in genCSS function inside the selector node. - // future TODO - move both logics into the selector joiner visitor - if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === "") { - selectorElements[0].combinator.value = ' '; - } - selfElements = selfElements.concat(selectors[i].elements); - } - - this.selfSelectors = [{ elements: selfElements }]; - } -}; - -})(require('../tree')); - -(function (tree) { -// -// CSS @import node -// -// The general strategy here is that we don't want to wait -// for the parsing to be completed, before we start importing -// the file. That's because in the context of a browser, -// most of the time will be spent waiting for the server to respond. -// -// On creation, we push the import path to our import queue, though -// `import,push`, we also pass it a callback, which it'll call once -// the file has been fetched, and parsed. -// -tree.Import = function (path, features, options, index, currentFileInfo) { - this.options = options; - this.index = index; - this.path = path; - this.features = features; - this.currentFileInfo = currentFileInfo; - - if (this.options.less !== undefined || this.options.inline) { - this.css = !this.options.less || this.options.inline; - } else { - var pathValue = this.getPath(); - if (pathValue && /css([\?;].*)?$/.test(pathValue)) { - this.css = true; - } - } -}; - -// -// The actual import node doesn't return anything, when converted to CSS. -// The reason is that it's used at the evaluation stage, so that the rules -// it imports can be treated like any other rules. -// -// In `eval`, we make sure all Import nodes get evaluated, recursively, so -// we end up with a flat structure, which can easily be imported in the parent -// ruleset. -// -tree.Import.prototype = { - type: "Import", - accept: function (visitor) { - if (this.features) { - this.features = visitor.visit(this.features); - } - this.path = visitor.visit(this.path); - if (!this.options.inline && this.root) { - this.root = visitor.visit(this.root); - } - }, - genCSS: function (env, output) { - if (this.css) { - output.add("@import ", this.currentFileInfo, this.index); - this.path.genCSS(env, output); - if (this.features) { - output.add(" "); - this.features.genCSS(env, output); - } - output.add(';'); - } - }, - toCSS: tree.toCSS, - getPath: function () { - if (this.path instanceof tree.Quoted) { - var path = this.path.value; - return (this.css !== undefined || /(\.[a-z]*$)|([\?;].*)$/.test(path)) ? path : path + '.less'; - } else if (this.path instanceof tree.URL) { - return this.path.value.value; - } - return null; - }, - evalForImport: function (env) { - return new(tree.Import)(this.path.eval(env), this.features, this.options, this.index, this.currentFileInfo); - }, - evalPath: function (env) { - var path = this.path.eval(env); - var rootpath = this.currentFileInfo && this.currentFileInfo.rootpath; - - if (!(path instanceof tree.URL)) { - if (rootpath) { - var pathValue = path.value; - // Add the base path if the import is relative - if (pathValue && env.isPathRelative(pathValue)) { - path.value = rootpath +pathValue; - } - } - path.value = env.normalizePath(path.value); - } - - return path; - }, - eval: function (env) { - var ruleset, features = this.features && this.features.eval(env); - - if (this.skip) { - if (typeof this.skip === "function") { - this.skip = this.skip(); - } - if (this.skip) { - return []; - } - } - - if (this.options.inline) { - //todo needs to reference css file not import - var contents = new(tree.Anonymous)(this.root, 0, {filename: this.importedFilename}, true); - return this.features ? new(tree.Media)([contents], this.features.value) : [contents]; - } else if (this.css) { - var newImport = new(tree.Import)(this.evalPath(env), features, this.options, this.index); - if (!newImport.css && this.error) { - throw this.error; - } - return newImport; - } else { - ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0)); - - ruleset.evalImports(env); - - return this.features ? new(tree.Media)(ruleset.rules, this.features.value) : ruleset.rules; - } - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.JavaScript = function (string, index, escaped) { - this.escaped = escaped; - this.expression = string; - this.index = index; -}; -tree.JavaScript.prototype = { - type: "JavaScript", - eval: function (env) { - var result, - that = this, - context = {}; - - var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) { - return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env)); - }); - - try { - expression = new(Function)('return (' + expression + ')'); - } catch (e) { - throw { message: "JavaScript evaluation error: " + e.message + " from `" + expression + "`" , - index: this.index }; - } - - var variables = env.frames[0].variables(); - for (var k in variables) { - if (variables.hasOwnProperty(k)) { - /*jshint loopfunc:true */ - context[k.slice(1)] = { - value: variables[k].value, - toJS: function () { - return this.value.eval(env).toCSS(); - } - }; - } - } - - try { - result = expression.call(context); - } catch (e) { - throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message.replace(/["]/g, "'") + "'" , - index: this.index }; - } - if (typeof(result) === 'number') { - return new(tree.Dimension)(result); - } else if (typeof(result) === 'string') { - return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index); - } else if (Array.isArray(result)) { - return new(tree.Anonymous)(result.join(', ')); - } else { - return new(tree.Anonymous)(result); - } - } -}; - -})(require('../tree')); - - -(function (tree) { - -tree.Keyword = function (value) { this.value = value; }; -tree.Keyword.prototype = { - type: "Keyword", - eval: function () { return this; }, - genCSS: function (env, output) { - if (this.value === '%') { throw { type: "Syntax", message: "Invalid % without number" }; } - output.add(this.value); - }, - toCSS: tree.toCSS, - compare: function (other) { - if (other instanceof tree.Keyword) { - return other.value === this.value ? 0 : 1; - } else { - return -1; - } - } -}; - -tree.True = new(tree.Keyword)('true'); -tree.False = new(tree.Keyword)('false'); - -})(require('../tree')); - -(function (tree) { - -tree.Media = function (value, features, index, currentFileInfo) { - this.index = index; - this.currentFileInfo = currentFileInfo; - - var selectors = this.emptySelectors(); - - this.features = new(tree.Value)(features); - this.rules = [new(tree.Ruleset)(selectors, value)]; - this.rules[0].allowImports = true; -}; -tree.Media.prototype = { - type: "Media", - accept: function (visitor) { - if (this.features) { - this.features = visitor.visit(this.features); - } - if (this.rules) { - this.rules = visitor.visitArray(this.rules); - } - }, - genCSS: function (env, output) { - output.add('@media ', this.currentFileInfo, this.index); - this.features.genCSS(env, output); - tree.outputRuleset(env, output, this.rules); - }, - toCSS: tree.toCSS, - eval: function (env) { - if (!env.mediaBlocks) { - env.mediaBlocks = []; - env.mediaPath = []; - } - - var media = new(tree.Media)(null, [], this.index, this.currentFileInfo); - if(this.debugInfo) { - this.rules[0].debugInfo = this.debugInfo; - media.debugInfo = this.debugInfo; - } - var strictMathBypass = false; - if (!env.strictMath) { - strictMathBypass = true; - env.strictMath = true; - } - try { - media.features = this.features.eval(env); - } - finally { - if (strictMathBypass) { - env.strictMath = false; - } - } - - env.mediaPath.push(media); - env.mediaBlocks.push(media); - - env.frames.unshift(this.rules[0]); - media.rules = [this.rules[0].eval(env)]; - env.frames.shift(); - - env.mediaPath.pop(); - - return env.mediaPath.length === 0 ? media.evalTop(env) : - media.evalNested(env); - }, - variable: function (name) { return tree.Ruleset.prototype.variable.call(this.rules[0], name); }, - find: function () { return tree.Ruleset.prototype.find.apply(this.rules[0], arguments); }, - rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.rules[0]); }, - emptySelectors: function() { - var el = new(tree.Element)('', '&', this.index, this.currentFileInfo), - sels = [new(tree.Selector)([el], null, null, this.index, this.currentFileInfo)]; - sels[0].mediaEmpty = true; - return sels; - }, - markReferenced: function () { - var i, rules = this.rules[0].rules; - this.rules[0].markReferenced(); - this.isReferenced = true; - for (i = 0; i < rules.length; i++) { - if (rules[i].markReferenced) { - rules[i].markReferenced(); - } - } - }, - - evalTop: function (env) { - var result = this; - - // Render all dependent Media blocks. - if (env.mediaBlocks.length > 1) { - var selectors = this.emptySelectors(); - result = new(tree.Ruleset)(selectors, env.mediaBlocks); - result.multiMedia = true; - } - - delete env.mediaBlocks; - delete env.mediaPath; - - return result; - }, - evalNested: function (env) { - var i, value, - path = env.mediaPath.concat([this]); - - // Extract the media-query conditions separated with `,` (OR). - for (i = 0; i < path.length; i++) { - value = path[i].features instanceof tree.Value ? - path[i].features.value : path[i].features; - path[i] = Array.isArray(value) ? value : [value]; - } - - // Trace all permutations to generate the resulting media-query. - // - // (a, b and c) with nested (d, e) -> - // a and d - // a and e - // b and c and d - // b and c and e - this.features = new(tree.Value)(this.permute(path).map(function (path) { - path = path.map(function (fragment) { - return fragment.toCSS ? fragment : new(tree.Anonymous)(fragment); - }); - - for(i = path.length - 1; i > 0; i--) { - path.splice(i, 0, new(tree.Anonymous)("and")); - } - - return new(tree.Expression)(path); - })); - - // Fake a tree-node that doesn't output anything. - return new(tree.Ruleset)([], []); - }, - permute: function (arr) { - if (arr.length === 0) { - return []; - } else if (arr.length === 1) { - return arr[0]; - } else { - var result = []; - var rest = this.permute(arr.slice(1)); - for (var i = 0; i < rest.length; i++) { - for (var j = 0; j < arr[0].length; j++) { - result.push([arr[0][j]].concat(rest[i])); - } - } - return result; - } - }, - bubbleSelectors: function (selectors) { - if (!selectors) - return; - this.rules = [new(tree.Ruleset)(selectors.slice(0), [this.rules[0]])]; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.mixin = {}; -tree.mixin.Call = function (elements, args, index, currentFileInfo, important) { - this.selector = new(tree.Selector)(elements); - this.arguments = (args && args.length) ? args : null; - this.index = index; - this.currentFileInfo = currentFileInfo; - this.important = important; -}; -tree.mixin.Call.prototype = { - type: "MixinCall", - accept: function (visitor) { - if (this.selector) { - this.selector = visitor.visit(this.selector); - } - if (this.arguments) { - this.arguments = visitor.visitArray(this.arguments); - } - }, - eval: function (env) { - var mixins, mixin, args, rules = [], match = false, i, m, f, isRecursive, isOneFound, rule, - candidates = [], candidate, conditionResult = [], defaultFunc = tree.defaultFunc, - defaultResult, defNone = 0, defTrue = 1, defFalse = 2, count; - - args = this.arguments && this.arguments.map(function (a) { - return { name: a.name, value: a.value.eval(env) }; - }); - - for (i = 0; i < env.frames.length; i++) { - if ((mixins = env.frames[i].find(this.selector)).length > 0) { - isOneFound = true; - - // To make `default()` function independent of definition order we have two "subpasses" here. - // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`), - // and build candidate list with corresponding flags. Then, when we know all possible matches, - // we make a final decision. - - for (m = 0; m < mixins.length; m++) { - mixin = mixins[m]; - isRecursive = false; - for(f = 0; f < env.frames.length; f++) { - if ((!(mixin instanceof tree.mixin.Definition)) && mixin === (env.frames[f].originalRuleset || env.frames[f])) { - isRecursive = true; - break; - } - } - if (isRecursive) { - continue; - } - - if (mixin.matchArgs(args, env)) { - candidate = {mixin: mixin, group: defNone}; - - if (mixin.matchCondition) { - for (f = 0; f < 2; f++) { - defaultFunc.value(f); - conditionResult[f] = mixin.matchCondition(args, env); - } - if (conditionResult[0] || conditionResult[1]) { - if (conditionResult[0] != conditionResult[1]) { - candidate.group = conditionResult[1] ? - defTrue : defFalse; - } - - candidates.push(candidate); - } - } - else { - candidates.push(candidate); - } - - match = true; - } - } - - defaultFunc.reset(); - - count = [0, 0, 0]; - for (m = 0; m < candidates.length; m++) { - count[candidates[m].group]++; - } - - if (count[defNone] > 0) { - defaultResult = defFalse; - } else { - defaultResult = defTrue; - if ((count[defTrue] + count[defFalse]) > 1) { - throw { type: 'Runtime', - message: 'Ambiguous use of `default()` found when matching for `' - + this.format(args) + '`', - index: this.index, filename: this.currentFileInfo.filename }; - } - } - - for (m = 0; m < candidates.length; m++) { - candidate = candidates[m].group; - if ((candidate === defNone) || (candidate === defaultResult)) { - try { - mixin = candidates[m].mixin; - if (!(mixin instanceof tree.mixin.Definition)) { - mixin = new tree.mixin.Definition("", [], mixin.rules, null, false); - mixin.originalRuleset = mixins[m].originalRuleset || mixins[m]; - } - Array.prototype.push.apply( - rules, mixin.evalCall(env, args, this.important).rules); - } catch (e) { - throw { message: e.message, index: this.index, filename: this.currentFileInfo.filename, stack: e.stack }; - } - } - } - - if (match) { - if (!this.currentFileInfo || !this.currentFileInfo.reference) { - for (i = 0; i < rules.length; i++) { - rule = rules[i]; - if (rule.markReferenced) { - rule.markReferenced(); - } - } - } - return rules; - } - } - } - if (isOneFound) { - throw { type: 'Runtime', - message: 'No matching definition was found for `' + this.format(args) + '`', - index: this.index, filename: this.currentFileInfo.filename }; - } else { - throw { type: 'Name', - message: this.selector.toCSS().trim() + " is undefined", - index: this.index, filename: this.currentFileInfo.filename }; - } - }, - format: function (args) { - return this.selector.toCSS().trim() + '(' + - (args ? args.map(function (a) { - var argValue = ""; - if (a.name) { - argValue += a.name + ":"; - } - if (a.value.toCSS) { - argValue += a.value.toCSS(); - } else { - argValue += "???"; - } - return argValue; - }).join(', ') : "") + ")"; - } -}; - -tree.mixin.Definition = function (name, params, rules, condition, variadic, frames) { - this.name = name; - this.selectors = [new(tree.Selector)([new(tree.Element)(null, name, this.index, this.currentFileInfo)])]; - this.params = params; - this.condition = condition; - this.variadic = variadic; - this.arity = params.length; - this.rules = rules; - this._lookups = {}; - this.required = params.reduce(function (count, p) { - if (!p.name || (p.name && !p.value)) { return count + 1; } - else { return count; } - }, 0); - this.parent = tree.Ruleset.prototype; - this.frames = frames; -}; -tree.mixin.Definition.prototype = { - type: "MixinDefinition", - accept: function (visitor) { - if (this.params && this.params.length) { - this.params = visitor.visitArray(this.params); - } - this.rules = visitor.visitArray(this.rules); - if (this.condition) { - this.condition = visitor.visit(this.condition); - } - }, - variable: function (name) { return this.parent.variable.call(this, name); }, - variables: function () { return this.parent.variables.call(this); }, - find: function () { return this.parent.find.apply(this, arguments); }, - rulesets: function () { return this.parent.rulesets.apply(this); }, - - evalParams: function (env, mixinEnv, args, evaldArguments) { - /*jshint boss:true */ - var frame = new(tree.Ruleset)(null, null), - varargs, arg, - params = this.params.slice(0), - i, j, val, name, isNamedFound, argIndex, argsLength = 0; - - mixinEnv = new tree.evalEnv(mixinEnv, [frame].concat(mixinEnv.frames)); - - if (args) { - args = args.slice(0); - argsLength = args.length; - - for(i = 0; i < argsLength; i++) { - arg = args[i]; - if (name = (arg && arg.name)) { - isNamedFound = false; - for(j = 0; j < params.length; j++) { - if (!evaldArguments[j] && name === params[j].name) { - evaldArguments[j] = arg.value.eval(env); - frame.prependRule(new(tree.Rule)(name, arg.value.eval(env))); - isNamedFound = true; - break; - } - } - if (isNamedFound) { - args.splice(i, 1); - i--; - continue; - } else { - throw { type: 'Runtime', message: "Named argument for " + this.name + - ' ' + args[i].name + ' not found' }; - } - } - } - } - argIndex = 0; - for (i = 0; i < params.length; i++) { - if (evaldArguments[i]) { continue; } - - arg = args && args[argIndex]; - - if (name = params[i].name) { - if (params[i].variadic) { - varargs = []; - for (j = argIndex; j < argsLength; j++) { - varargs.push(args[j].value.eval(env)); - } - frame.prependRule(new(tree.Rule)(name, new(tree.Expression)(varargs).eval(env))); - } else { - val = arg && arg.value; - if (val) { - val = val.eval(env); - } else if (params[i].value) { - val = params[i].value.eval(mixinEnv); - frame.resetCache(); - } else { - throw { type: 'Runtime', message: "wrong number of arguments for " + this.name + - ' (' + argsLength + ' for ' + this.arity + ')' }; - } - - frame.prependRule(new(tree.Rule)(name, val)); - evaldArguments[i] = val; - } - } - - if (params[i].variadic && args) { - for (j = argIndex; j < argsLength; j++) { - evaldArguments[j] = args[j].value.eval(env); - } - } - argIndex++; - } - - return frame; - }, - eval: function (env) { - return new tree.mixin.Definition(this.name, this.params, this.rules, this.condition, this.variadic, this.frames || env.frames.slice(0)); - }, - evalCall: function (env, args, important) { - var _arguments = [], - mixinFrames = this.frames ? this.frames.concat(env.frames) : env.frames, - frame = this.evalParams(env, new(tree.evalEnv)(env, mixinFrames), args, _arguments), - rules, ruleset; - - frame.prependRule(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env))); - - rules = this.rules.slice(0); - - ruleset = new(tree.Ruleset)(null, rules); - ruleset.originalRuleset = this; - ruleset = ruleset.eval(new(tree.evalEnv)(env, [this, frame].concat(mixinFrames))); - if (important) { - ruleset = this.parent.makeImportant.apply(ruleset); - } - return ruleset; - }, - matchCondition: function (args, env) { - if (this.condition && !this.condition.eval( - new(tree.evalEnv)(env, - [this.evalParams(env, new(tree.evalEnv)(env, this.frames.concat(env.frames)), args, [])] // the parameter variables - .concat(this.frames) // the parent namespace/mixin frames - .concat(env.frames)))) { // the current environment frames - return false; - } - return true; - }, - matchArgs: function (args, env) { - var argsLength = (args && args.length) || 0, len; - - if (! this.variadic) { - if (argsLength < this.required) { return false; } - if (argsLength > this.params.length) { return false; } - } else { - if (argsLength < (this.required - 1)) { return false; } - } - - len = Math.min(argsLength, this.arity); - - for (var i = 0; i < len; i++) { - if (!this.params[i].name && !this.params[i].variadic) { - if (args[i].value.eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) { - return false; - } - } - } - return true; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Negative = function (node) { - this.value = node; -}; -tree.Negative.prototype = { - type: "Negative", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add('-'); - this.value.genCSS(env, output); - }, - toCSS: tree.toCSS, - eval: function (env) { - if (env.isMathOn()) { - return (new(tree.Operation)('*', [new(tree.Dimension)(-1), this.value])).eval(env); - } - return new(tree.Negative)(this.value.eval(env)); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Operation = function (op, operands, isSpaced) { - this.op = op.trim(); - this.operands = operands; - this.isSpaced = isSpaced; -}; -tree.Operation.prototype = { - type: "Operation", - accept: function (visitor) { - this.operands = visitor.visit(this.operands); - }, - eval: function (env) { - var a = this.operands[0].eval(env), - b = this.operands[1].eval(env); - - if (env.isMathOn()) { - if (a instanceof tree.Dimension && b instanceof tree.Color) { - a = a.toColor(); - } - if (b instanceof tree.Dimension && a instanceof tree.Color) { - b = b.toColor(); - } - if (!a.operate) { - throw { type: "Operation", - message: "Operation on an invalid type" }; - } - - return a.operate(env, this.op, b); - } else { - return new(tree.Operation)(this.op, [a, b], this.isSpaced); - } - }, - genCSS: function (env, output) { - this.operands[0].genCSS(env, output); - if (this.isSpaced) { - output.add(" "); - } - output.add(this.op); - if (this.isSpaced) { - output.add(" "); - } - this.operands[1].genCSS(env, output); - }, - toCSS: tree.toCSS -}; - -tree.operate = function (env, op, a, b) { - switch (op) { - case '+': return a + b; - case '-': return a - b; - case '*': return a * b; - case '/': return a / b; - } -}; - -})(require('../tree')); - - -(function (tree) { - -tree.Paren = function (node) { - this.value = node; -}; -tree.Paren.prototype = { - type: "Paren", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add('('); - this.value.genCSS(env, output); - output.add(')'); - }, - toCSS: tree.toCSS, - eval: function (env) { - return new(tree.Paren)(this.value.eval(env)); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Quoted = function (str, content, escaped, index, currentFileInfo) { - this.escaped = escaped; - this.value = content || ''; - this.quote = str.charAt(0); - this.index = index; - this.currentFileInfo = currentFileInfo; -}; -tree.Quoted.prototype = { - type: "Quoted", - genCSS: function (env, output) { - if (!this.escaped) { - output.add(this.quote, this.currentFileInfo, this.index); - } - output.add(this.value); - if (!this.escaped) { - output.add(this.quote); - } - }, - toCSS: tree.toCSS, - eval: function (env) { - var that = this; - var value = this.value.replace(/`([^`]+)`/g, function (_, exp) { - return new(tree.JavaScript)(exp, that.index, true).eval(env).value; - }).replace(/@\{([\w-]+)\}/g, function (_, name) { - var v = new(tree.Variable)('@' + name, that.index, that.currentFileInfo).eval(env, true); - return (v instanceof tree.Quoted) ? v.value : v.toCSS(); - }); - return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index, this.currentFileInfo); - }, - compare: function (x) { - if (!x.toCSS) { - return -1; - } - - var left = this.toCSS(), - right = x.toCSS(); - - if (left === right) { - return 0; - } - - return left < right ? -1 : 1; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Rule = function (name, value, important, merge, index, currentFileInfo, inline) { - this.name = name; - this.value = (value instanceof tree.Value || value instanceof tree.Ruleset) ? value : new(tree.Value)([value]); - this.important = important ? ' ' + important.trim() : ''; - this.merge = merge; - this.index = index; - this.currentFileInfo = currentFileInfo; - this.inline = inline || false; - this.variable = name.charAt && (name.charAt(0) === '@'); -}; - -tree.Rule.prototype = { - type: "Rule", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add(this.name + (env.compress ? ':' : ': '), this.currentFileInfo, this.index); - try { - this.value.genCSS(env, output); - } - catch(e) { - e.index = this.index; - e.filename = this.currentFileInfo.filename; - throw e; - } - output.add(this.important + ((this.inline || (env.lastRule && env.compress)) ? "" : ";"), this.currentFileInfo, this.index); - }, - toCSS: tree.toCSS, - eval: function (env) { - var strictMathBypass = false, name = this.name, evaldValue; - if (typeof name !== "string") { - // expand 'primitive' name directly to get - // things faster (~10% for benchmark.less): - name = (name.length === 1) - && (name[0] instanceof tree.Keyword) - ? name[0].value : evalName(env, name); - } - if (name === "font" && !env.strictMath) { - strictMathBypass = true; - env.strictMath = true; - } - try { - evaldValue = this.value.eval(env); - - if (!this.variable && evaldValue.type === "DetachedRuleset") { - throw { message: "Rulesets cannot be evaluated on a property.", - index: this.index, filename: this.currentFileInfo.filename }; - } - - return new(tree.Rule)(name, - evaldValue, - this.important, - this.merge, - this.index, this.currentFileInfo, this.inline); - } - catch(e) { - if (typeof e.index !== 'number') { - e.index = this.index; - e.filename = this.currentFileInfo.filename; - } - throw e; - } - finally { - if (strictMathBypass) { - env.strictMath = false; - } - } - }, - makeImportant: function () { - return new(tree.Rule)(this.name, - this.value, - "!important", - this.merge, - this.index, this.currentFileInfo, this.inline); - } -}; - -function evalName(env, name) { - var value = "", i, n = name.length, - output = {add: function (s) {value += s;}}; - for (i = 0; i < n; i++) { - name[i].eval(env).genCSS(env, output); - } - return value; -} - -})(require('../tree')); - -(function (tree) { - -tree.RulesetCall = function (variable) { - this.variable = variable; -}; -tree.RulesetCall.prototype = { - type: "RulesetCall", - accept: function (visitor) { - }, - eval: function (env) { - var detachedRuleset = new(tree.Variable)(this.variable).eval(env); - return detachedRuleset.callEval(env); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Ruleset = function (selectors, rules, strictImports) { - this.selectors = selectors; - this.rules = rules; - this._lookups = {}; - this.strictImports = strictImports; -}; -tree.Ruleset.prototype = { - type: "Ruleset", - accept: function (visitor) { - if (this.paths) { - visitor.visitArray(this.paths, true); - } else if (this.selectors) { - this.selectors = visitor.visitArray(this.selectors); - } - if (this.rules && this.rules.length) { - this.rules = visitor.visitArray(this.rules); - } - }, - eval: function (env) { - var thisSelectors = this.selectors, selectors, - selCnt, selector, i, defaultFunc = tree.defaultFunc, hasOnePassingSelector = false; - - if (thisSelectors && (selCnt = thisSelectors.length)) { - selectors = []; - defaultFunc.error({ - type: "Syntax", - message: "it is currently only allowed in parametric mixin guards," - }); - for (i = 0; i < selCnt; i++) { - selector = thisSelectors[i].eval(env); - selectors.push(selector); - if (selector.evaldCondition) { - hasOnePassingSelector = true; - } - } - defaultFunc.reset(); - } else { - hasOnePassingSelector = true; - } - - var rules = this.rules ? this.rules.slice(0) : null, - ruleset = new(tree.Ruleset)(selectors, rules, this.strictImports), - rule, subRule; - - ruleset.originalRuleset = this; - ruleset.root = this.root; - ruleset.firstRoot = this.firstRoot; - ruleset.allowImports = this.allowImports; - - if(this.debugInfo) { - ruleset.debugInfo = this.debugInfo; - } - - if (!hasOnePassingSelector) { - rules.length = 0; - } - - // push the current ruleset to the frames stack - var envFrames = env.frames; - envFrames.unshift(ruleset); - - // currrent selectors - var envSelectors = env.selectors; - if (!envSelectors) { - env.selectors = envSelectors = []; - } - envSelectors.unshift(this.selectors); - - // Evaluate imports - if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) { - ruleset.evalImports(env); - } - - // Store the frames around mixin definitions, - // so they can be evaluated like closures when the time comes. - var rsRules = ruleset.rules, rsRuleCnt = rsRules ? rsRules.length : 0; - for (i = 0; i < rsRuleCnt; i++) { - if (rsRules[i] instanceof tree.mixin.Definition || rsRules[i] instanceof tree.DetachedRuleset) { - rsRules[i] = rsRules[i].eval(env); - } - } - - var mediaBlockCount = (env.mediaBlocks && env.mediaBlocks.length) || 0; - - // Evaluate mixin calls. - for (i = 0; i < rsRuleCnt; i++) { - if (rsRules[i] instanceof tree.mixin.Call) { - /*jshint loopfunc:true */ - rules = rsRules[i].eval(env).filter(function(r) { - if ((r instanceof tree.Rule) && r.variable) { - // do not pollute the scope if the variable is - // already there. consider returning false here - // but we need a way to "return" variable from mixins - return !(ruleset.variable(r.name)); - } - return true; - }); - rsRules.splice.apply(rsRules, [i, 1].concat(rules)); - rsRuleCnt += rules.length - 1; - i += rules.length-1; - ruleset.resetCache(); - } else if (rsRules[i] instanceof tree.RulesetCall) { - /*jshint loopfunc:true */ - rules = rsRules[i].eval(env).rules.filter(function(r) { - if ((r instanceof tree.Rule) && r.variable) { - // do not pollute the scope at all - return false; - } - return true; - }); - rsRules.splice.apply(rsRules, [i, 1].concat(rules)); - rsRuleCnt += rules.length - 1; - i += rules.length-1; - ruleset.resetCache(); - } - } - - // Evaluate everything else - for (i = 0; i < rsRules.length; i++) { - rule = rsRules[i]; - if (! (rule instanceof tree.mixin.Definition || rule instanceof tree.DetachedRuleset)) { - rsRules[i] = rule = rule.eval ? rule.eval(env) : rule; - } - } - - // Evaluate everything else - for (i = 0; i < rsRules.length; i++) { - rule = rsRules[i]; - // for rulesets, check if it is a css guard and can be removed - if (rule instanceof tree.Ruleset && rule.selectors && rule.selectors.length === 1) { - // check if it can be folded in (e.g. & where) - if (rule.selectors[0].isJustParentSelector()) { - rsRules.splice(i--, 1); - - for(var j = 0; j < rule.rules.length; j++) { - subRule = rule.rules[j]; - if (!(subRule instanceof tree.Rule) || !subRule.variable) { - rsRules.splice(++i, 0, subRule); - } - } - } - } - } - - // Pop the stack - envFrames.shift(); - envSelectors.shift(); - - if (env.mediaBlocks) { - for (i = mediaBlockCount; i < env.mediaBlocks.length; i++) { - env.mediaBlocks[i].bubbleSelectors(selectors); - } - } - - return ruleset; - }, - evalImports: function(env) { - var rules = this.rules, i, importRules; - if (!rules) { return; } - - for (i = 0; i < rules.length; i++) { - if (rules[i] instanceof tree.Import) { - importRules = rules[i].eval(env); - if (importRules && importRules.length) { - rules.splice.apply(rules, [i, 1].concat(importRules)); - i+= importRules.length-1; - } else { - rules.splice(i, 1, importRules); - } - this.resetCache(); - } - } - }, - makeImportant: function() { - return new tree.Ruleset(this.selectors, this.rules.map(function (r) { - if (r.makeImportant) { - return r.makeImportant(); - } else { - return r; - } - }), this.strictImports); - }, - matchArgs: function (args) { - return !args || args.length === 0; - }, - // lets you call a css selector with a guard - matchCondition: function (args, env) { - var lastSelector = this.selectors[this.selectors.length-1]; - if (!lastSelector.evaldCondition) { - return false; - } - if (lastSelector.condition && - !lastSelector.condition.eval( - new(tree.evalEnv)(env, - env.frames))) { - return false; - } - return true; - }, - resetCache: function () { - this._rulesets = null; - this._variables = null; - this._lookups = {}; - }, - variables: function () { - if (!this._variables) { - this._variables = !this.rules ? {} : this.rules.reduce(function (hash, r) { - if (r instanceof tree.Rule && r.variable === true) { - hash[r.name] = r; - } - return hash; - }, {}); - } - return this._variables; - }, - variable: function (name) { - return this.variables()[name]; - }, - rulesets: function () { - if (!this.rules) { return null; } - - var _Ruleset = tree.Ruleset, _MixinDefinition = tree.mixin.Definition, - filtRules = [], rules = this.rules, cnt = rules.length, - i, rule; - - for (i = 0; i < cnt; i++) { - rule = rules[i]; - if ((rule instanceof _Ruleset) || (rule instanceof _MixinDefinition)) { - filtRules.push(rule); - } - } - - return filtRules; - }, - prependRule: function (rule) { - var rules = this.rules; - if (rules) { rules.unshift(rule); } else { this.rules = [ rule ]; } - }, - find: function (selector, self) { - self = self || this; - var rules = [], match, - key = selector.toCSS(); - - if (key in this._lookups) { return this._lookups[key]; } - - this.rulesets().forEach(function (rule) { - if (rule !== self) { - for (var j = 0; j < rule.selectors.length; j++) { - match = selector.match(rule.selectors[j]); - if (match) { - if (selector.elements.length > match) { - Array.prototype.push.apply(rules, rule.find( - new(tree.Selector)(selector.elements.slice(match)), self)); - } else { - rules.push(rule); - } - break; - } - } - } - }); - this._lookups[key] = rules; - return rules; - }, - genCSS: function (env, output) { - var i, j, - ruleNodes = [], - rulesetNodes = [], - rulesetNodeCnt, - debugInfo, // Line number debugging - rule, - path; - - env.tabLevel = (env.tabLevel || 0); - - if (!this.root) { - env.tabLevel++; - } - - var tabRuleStr = env.compress ? '' : Array(env.tabLevel + 1).join(" "), - tabSetStr = env.compress ? '' : Array(env.tabLevel).join(" "), - sep; - - for (i = 0; i < this.rules.length; i++) { - rule = this.rules[i]; - if (rule.rules || (rule instanceof tree.Media) || rule instanceof tree.Directive || (this.root && rule instanceof tree.Comment)) { - rulesetNodes.push(rule); - } else { - ruleNodes.push(rule); - } - } - - // If this is the root node, we don't render - // a selector, or {}. - if (!this.root) { - debugInfo = tree.debugInfo(env, this, tabSetStr); - - if (debugInfo) { - output.add(debugInfo); - output.add(tabSetStr); - } - - var paths = this.paths, pathCnt = paths.length, - pathSubCnt; - - sep = env.compress ? ',' : (',\n' + tabSetStr); - - for (i = 0; i < pathCnt; i++) { - path = paths[i]; - if (!(pathSubCnt = path.length)) { continue; } - if (i > 0) { output.add(sep); } - - env.firstSelector = true; - path[0].genCSS(env, output); - - env.firstSelector = false; - for (j = 1; j < pathSubCnt; j++) { - path[j].genCSS(env, output); - } - } - - output.add((env.compress ? '{' : ' {\n') + tabRuleStr); - } - - // Compile rules and rulesets - for (i = 0; i < ruleNodes.length; i++) { - rule = ruleNodes[i]; - - // @page{ directive ends up with root elements inside it, a mix of rules and rulesets - // In this instance we do not know whether it is the last property - if (i + 1 === ruleNodes.length && (!this.root || rulesetNodes.length === 0 || this.firstRoot)) { - env.lastRule = true; - } - - if (rule.genCSS) { - rule.genCSS(env, output); - } else if (rule.value) { - output.add(rule.value.toString()); - } - - if (!env.lastRule) { - output.add(env.compress ? '' : ('\n' + tabRuleStr)); - } else { - env.lastRule = false; - } - } - - if (!this.root) { - output.add((env.compress ? '}' : '\n' + tabSetStr + '}')); - env.tabLevel--; - } - - sep = (env.compress ? "" : "\n") + (this.root ? tabRuleStr : tabSetStr); - rulesetNodeCnt = rulesetNodes.length; - if (rulesetNodeCnt) { - if (ruleNodes.length && sep) { output.add(sep); } - rulesetNodes[0].genCSS(env, output); - for (i = 1; i < rulesetNodeCnt; i++) { - if (sep) { output.add(sep); } - rulesetNodes[i].genCSS(env, output); - } - } - - if (!output.isEmpty() && !env.compress && this.firstRoot) { - output.add('\n'); - } - }, - - toCSS: tree.toCSS, - - markReferenced: function () { - if (!this.selectors) { - return; - } - for (var s = 0; s < this.selectors.length; s++) { - this.selectors[s].markReferenced(); - } - }, - - joinSelectors: function (paths, context, selectors) { - for (var s = 0; s < selectors.length; s++) { - this.joinSelector(paths, context, selectors[s]); - } - }, - - joinSelector: function (paths, context, selector) { - - var i, j, k, - hasParentSelector, newSelectors, el, sel, parentSel, - newSelectorPath, afterParentJoin, newJoinedSelector, - newJoinedSelectorEmpty, lastSelector, currentElements, - selectorsMultiplied; - - for (i = 0; i < selector.elements.length; i++) { - el = selector.elements[i]; - if (el.value === '&') { - hasParentSelector = true; - } - } - - if (!hasParentSelector) { - if (context.length > 0) { - for (i = 0; i < context.length; i++) { - paths.push(context[i].concat(selector)); - } - } - else { - paths.push([selector]); - } - return; - } - - // The paths are [[Selector]] - // The first list is a list of comma seperated selectors - // The inner list is a list of inheritance seperated selectors - // e.g. - // .a, .b { - // .c { - // } - // } - // == [[.a] [.c]] [[.b] [.c]] - // - - // the elements from the current selector so far - currentElements = []; - // the current list of new selectors to add to the path. - // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors - // by the parents - newSelectors = [[]]; - - for (i = 0; i < selector.elements.length; i++) { - el = selector.elements[i]; - // non parent reference elements just get added - if (el.value !== "&") { - currentElements.push(el); - } else { - // the new list of selectors to add - selectorsMultiplied = []; - - // merge the current list of non parent selector elements - // on to the current list of selectors to add - if (currentElements.length > 0) { - this.mergeElementsOnToSelectors(currentElements, newSelectors); - } - - // loop through our current selectors - for (j = 0; j < newSelectors.length; j++) { - sel = newSelectors[j]; - // if we don't have any parent paths, the & might be in a mixin so that it can be used - // whether there are parents or not - if (context.length === 0) { - // the combinator used on el should now be applied to the next element instead so that - // it is not lost - if (sel.length > 0) { - sel[0].elements = sel[0].elements.slice(0); - sel[0].elements.push(new(tree.Element)(el.combinator, '', el.index, el.currentFileInfo)); - } - selectorsMultiplied.push(sel); - } - else { - // and the parent selectors - for (k = 0; k < context.length; k++) { - parentSel = context[k]; - // We need to put the current selectors - // then join the last selector's elements on to the parents selectors - - // our new selector path - newSelectorPath = []; - // selectors from the parent after the join - afterParentJoin = []; - newJoinedSelectorEmpty = true; - - //construct the joined selector - if & is the first thing this will be empty, - // if not newJoinedSelector will be the last set of elements in the selector - if (sel.length > 0) { - newSelectorPath = sel.slice(0); - lastSelector = newSelectorPath.pop(); - newJoinedSelector = selector.createDerived(lastSelector.elements.slice(0)); - newJoinedSelectorEmpty = false; - } - else { - newJoinedSelector = selector.createDerived([]); - } - - //put together the parent selectors after the join - if (parentSel.length > 1) { - afterParentJoin = afterParentJoin.concat(parentSel.slice(1)); - } - - if (parentSel.length > 0) { - newJoinedSelectorEmpty = false; - - // join the elements so far with the first part of the parent - newJoinedSelector.elements.push(new(tree.Element)(el.combinator, parentSel[0].elements[0].value, el.index, el.currentFileInfo)); - newJoinedSelector.elements = newJoinedSelector.elements.concat(parentSel[0].elements.slice(1)); - } - - if (!newJoinedSelectorEmpty) { - // now add the joined selector - newSelectorPath.push(newJoinedSelector); - } - - // and the rest of the parent - newSelectorPath = newSelectorPath.concat(afterParentJoin); - - // add that to our new set of selectors - selectorsMultiplied.push(newSelectorPath); - } - } - } - - // our new selectors has been multiplied, so reset the state - newSelectors = selectorsMultiplied; - currentElements = []; - } - } - - // if we have any elements left over (e.g. .a& .b == .b) - // add them on to all the current selectors - if (currentElements.length > 0) { - this.mergeElementsOnToSelectors(currentElements, newSelectors); - } - - for (i = 0; i < newSelectors.length; i++) { - if (newSelectors[i].length > 0) { - paths.push(newSelectors[i]); - } - } - }, - - mergeElementsOnToSelectors: function(elements, selectors) { - var i, sel; - - if (selectors.length === 0) { - selectors.push([ new(tree.Selector)(elements) ]); - return; - } - - for (i = 0; i < selectors.length; i++) { - sel = selectors[i]; - - // if the previous thing in sel is a parent this needs to join on to it - if (sel.length > 0) { - sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements)); - } - else { - sel.push(new(tree.Selector)(elements)); - } - } - } -}; -})(require('../tree')); - -(function (tree) { - -tree.Selector = function (elements, extendList, condition, index, currentFileInfo, isReferenced) { - this.elements = elements; - this.extendList = extendList; - this.condition = condition; - this.currentFileInfo = currentFileInfo || {}; - this.isReferenced = isReferenced; - if (!condition) { - this.evaldCondition = true; - } -}; -tree.Selector.prototype = { - type: "Selector", - accept: function (visitor) { - if (this.elements) { - this.elements = visitor.visitArray(this.elements); - } - if (this.extendList) { - this.extendList = visitor.visitArray(this.extendList); - } - if (this.condition) { - this.condition = visitor.visit(this.condition); - } - }, - createDerived: function(elements, extendList, evaldCondition) { - evaldCondition = (evaldCondition != null) ? evaldCondition : this.evaldCondition; - var newSelector = new(tree.Selector)(elements, extendList || this.extendList, null, this.index, this.currentFileInfo, this.isReferenced); - newSelector.evaldCondition = evaldCondition; - newSelector.mediaEmpty = this.mediaEmpty; - return newSelector; - }, - match: function (other) { - var elements = this.elements, - len = elements.length, - olen, i; - - other.CacheElements(); - - olen = other._elements.length; - if (olen === 0 || len < olen) { - return 0; - } else { - for (i = 0; i < olen; i++) { - if (elements[i].value !== other._elements[i]) { - return 0; - } - } - } - - return olen; // return number of matched elements - }, - CacheElements: function(){ - var css = '', len, v, i; - - if( !this._elements ){ - - len = this.elements.length; - for(i = 0; i < len; i++){ - - v = this.elements[i]; - css += v.combinator.value; - - if( !v.value.value ){ - css += v.value; - continue; - } - - if( typeof v.value.value !== "string" ){ - css = ''; - break; - } - css += v.value.value; - } - - this._elements = css.match(/[,&#\.\w-]([\w-]|(\\.))*/g); - - if (this._elements) { - if (this._elements[0] === "&") { - this._elements.shift(); - } - - } else { - this._elements = []; - } - - } - }, - isJustParentSelector: function() { - return !this.mediaEmpty && - this.elements.length === 1 && - this.elements[0].value === '&' && - (this.elements[0].combinator.value === ' ' || this.elements[0].combinator.value === ''); - }, - eval: function (env) { - var evaldCondition = this.condition && this.condition.eval(env), - elements = this.elements, extendList = this.extendList; - - elements = elements && elements.map(function (e) { return e.eval(env); }); - extendList = extendList && extendList.map(function(extend) { return extend.eval(env); }); - - return this.createDerived(elements, extendList, evaldCondition); - }, - genCSS: function (env, output) { - var i, element; - if ((!env || !env.firstSelector) && this.elements[0].combinator.value === "") { - output.add(' ', this.currentFileInfo, this.index); - } - if (!this._css) { - //TODO caching? speed comparison? - for(i = 0; i < this.elements.length; i++) { - element = this.elements[i]; - element.genCSS(env, output); - } - } - }, - toCSS: tree.toCSS, - markReferenced: function () { - this.isReferenced = true; - }, - getIsReferenced: function() { - return !this.currentFileInfo.reference || this.isReferenced; - }, - getIsOutput: function() { - return this.evaldCondition; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.UnicodeDescriptor = function (value) { - this.value = value; -}; -tree.UnicodeDescriptor.prototype = { - type: "UnicodeDescriptor", - genCSS: function (env, output) { - output.add(this.value); - }, - toCSS: tree.toCSS, - eval: function () { return this; } -}; - -})(require('../tree')); - -(function (tree) { - -tree.URL = function (val, currentFileInfo, isEvald) { - this.value = val; - this.currentFileInfo = currentFileInfo; - this.isEvald = isEvald; -}; -tree.URL.prototype = { - type: "Url", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add("url("); - this.value.genCSS(env, output); - output.add(")"); - }, - toCSS: tree.toCSS, - eval: function (ctx) { - var val = this.value.eval(ctx), - rootpath; - - if (!this.isEvald) { - // Add the base path if the URL is relative - rootpath = this.currentFileInfo && this.currentFileInfo.rootpath; - if (rootpath && typeof val.value === "string" && ctx.isPathRelative(val.value)) { - if (!val.quote) { - rootpath = rootpath.replace(/[\(\)'"\s]/g, function(match) { return "\\"+match; }); - } - val.value = rootpath + val.value; - } - - val.value = ctx.normalizePath(val.value); - - // Add url args if enabled - if (ctx.urlArgs) { - if (!val.value.match(/^\s*data:/)) { - var delimiter = val.value.indexOf('?') === -1 ? '?' : '&'; - var urlArgs = delimiter + ctx.urlArgs; - if (val.value.indexOf('#') !== -1) { - val.value = val.value.replace('#', urlArgs + '#'); - } else { - val.value += urlArgs; - } - } - } - } - - return new(tree.URL)(val, this.currentFileInfo, true); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Value = function (value) { - this.value = value; -}; -tree.Value.prototype = { - type: "Value", - accept: function (visitor) { - if (this.value) { - this.value = visitor.visitArray(this.value); - } - }, - eval: function (env) { - if (this.value.length === 1) { - return this.value[0].eval(env); - } else { - return new(tree.Value)(this.value.map(function (v) { - return v.eval(env); - })); - } - }, - genCSS: function (env, output) { - var i; - for(i = 0; i < this.value.length; i++) { - this.value[i].genCSS(env, output); - if (i+1 < this.value.length) { - output.add((env && env.compress) ? ',' : ', '); - } - } - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -tree.Variable = function (name, index, currentFileInfo) { - this.name = name; - this.index = index; - this.currentFileInfo = currentFileInfo || {}; -}; -tree.Variable.prototype = { - type: "Variable", - eval: function (env) { - var variable, name = this.name; - - if (name.indexOf('@@') === 0) { - name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value; - } - - if (this.evaluating) { - throw { type: 'Name', - message: "Recursive variable definition for " + name, - filename: this.currentFileInfo.file, - index: this.index }; - } - - this.evaluating = true; - - variable = tree.find(env.frames, function (frame) { - var v = frame.variable(name); - if (v) { - return v.value.eval(env); - } - }); - if (variable) { - this.evaluating = false; - return variable; - } else { - throw { type: 'Name', - message: "variable " + name + " is undefined", - filename: this.currentFileInfo.filename, - index: this.index }; - } - } -}; - -})(require('../tree')); - -(function (tree) { - - var parseCopyProperties = [ - 'paths', // option - unmodified - paths to search for imports on - 'optimization', // option - optimization level (for the chunker) - 'files', // list of files that have been imported, used for import-once - 'contents', // map - filename to contents of all the files - 'contentsIgnoredChars', // map - filename to lines at the begining of each file to ignore - 'relativeUrls', // option - whether to adjust URL's to be relative - 'rootpath', // option - rootpath to append to URL's - 'strictImports', // option - - 'insecure', // option - whether to allow imports from insecure ssl hosts - 'dumpLineNumbers', // option - whether to dump line numbers - 'compress', // option - whether to compress - 'processImports', // option - whether to process imports. if false then imports will not be imported - 'syncImport', // option - whether to import synchronously - 'javascriptEnabled',// option - whether JavaScript is enabled. if undefined, defaults to true - 'mime', // browser only - mime type for sheet import - 'useFileCache', // browser only - whether to use the per file session cache - 'currentFileInfo' // information about the current file - for error reporting and importing and making urls relative etc. - ]; - - //currentFileInfo = { - // 'relativeUrls' - option - whether to adjust URL's to be relative - // 'filename' - full resolved filename of current file - // 'rootpath' - path to append to normal URLs for this node - // 'currentDirectory' - path to the current file, absolute - // 'rootFilename' - filename of the base file - // 'entryPath' - absolute path to the entry file - // 'reference' - whether the file should not be output and only output parts that are referenced - - tree.parseEnv = function(options) { - copyFromOriginal(options, this, parseCopyProperties); - - if (!this.contents) { this.contents = {}; } - if (!this.contentsIgnoredChars) { this.contentsIgnoredChars = {}; } - if (!this.files) { this.files = {}; } - - if (!this.currentFileInfo) { - var filename = (options && options.filename) || "input"; - var entryPath = filename.replace(/[^\/\\]*$/, ""); - if (options) { - options.filename = null; - } - this.currentFileInfo = { - filename: filename, - relativeUrls: this.relativeUrls, - rootpath: (options && options.rootpath) || "", - currentDirectory: entryPath, - entryPath: entryPath, - rootFilename: filename - }; - } - }; - - var evalCopyProperties = [ - 'silent', // whether to swallow errors and warnings - 'verbose', // whether to log more activity - 'compress', // whether to compress - 'yuicompress', // whether to compress with the outside tool yui compressor - 'ieCompat', // whether to enforce IE compatibility (IE8 data-uri) - 'strictMath', // whether math has to be within parenthesis - 'strictUnits', // whether units need to evaluate correctly - 'cleancss', // whether to compress with clean-css - 'sourceMap', // whether to output a source map - 'importMultiple', // whether we are currently importing multiple copies - 'urlArgs' // whether to add args into url tokens - ]; - - tree.evalEnv = function(options, frames) { - copyFromOriginal(options, this, evalCopyProperties); - - this.frames = frames || []; - }; - - tree.evalEnv.prototype.inParenthesis = function () { - if (!this.parensStack) { - this.parensStack = []; - } - this.parensStack.push(true); - }; - - tree.evalEnv.prototype.outOfParenthesis = function () { - this.parensStack.pop(); - }; - - tree.evalEnv.prototype.isMathOn = function () { - return this.strictMath ? (this.parensStack && this.parensStack.length) : true; - }; - - tree.evalEnv.prototype.isPathRelative = function (path) { - return !/^(?:[a-z-]+:|\/)/.test(path); - }; - - tree.evalEnv.prototype.normalizePath = function( path ) { - var - segments = path.split("/").reverse(), - segment; - - path = []; - while (segments.length !== 0 ) { - segment = segments.pop(); - switch( segment ) { - case ".": - break; - case "..": - if ((path.length === 0) || (path[path.length - 1] === "..")) { - path.push( segment ); - } else { - path.pop(); - } - break; - default: - path.push( segment ); - break; - } - } - - return path.join("/"); - }; - - //todo - do the same for the toCSS env - //tree.toCSSEnv = function (options) { - //}; - - var copyFromOriginal = function(original, destination, propertiesToCopy) { - if (!original) { return; } - - for(var i = 0; i < propertiesToCopy.length; i++) { - if (original.hasOwnProperty(propertiesToCopy[i])) { - destination[propertiesToCopy[i]] = original[propertiesToCopy[i]]; - } - } - }; - -})(require('./tree')); - -(function (tree) { - - var _visitArgs = { visitDeeper: true }, - _hasIndexed = false; - - function _noop(node) { - return node; - } - - function indexNodeTypes(parent, ticker) { - // add .typeIndex to tree node types for lookup table - var key, child; - for (key in parent) { - if (parent.hasOwnProperty(key)) { - child = parent[key]; - switch (typeof child) { - case "function": - // ignore bound functions directly on tree which do not have a prototype - // or aren't nodes - if (child.prototype && child.prototype.type) { - child.prototype.typeIndex = ticker++; - } - break; - case "object": - ticker = indexNodeTypes(child, ticker); - break; - } - } - } - return ticker; - } - - tree.visitor = function(implementation) { - this._implementation = implementation; - this._visitFnCache = []; - - if (!_hasIndexed) { - indexNodeTypes(tree, 1); - _hasIndexed = true; - } - }; - - tree.visitor.prototype = { - visit: function(node) { - if (!node) { - return node; - } - - var nodeTypeIndex = node.typeIndex; - if (!nodeTypeIndex) { - return node; - } - - var visitFnCache = this._visitFnCache, - impl = this._implementation, - aryIndx = nodeTypeIndex << 1, - outAryIndex = aryIndx | 1, - func = visitFnCache[aryIndx], - funcOut = visitFnCache[outAryIndex], - visitArgs = _visitArgs, - fnName; - - visitArgs.visitDeeper = true; - - if (!func) { - fnName = "visit" + node.type; - func = impl[fnName] || _noop; - funcOut = impl[fnName + "Out"] || _noop; - visitFnCache[aryIndx] = func; - visitFnCache[outAryIndex] = funcOut; - } - - if (func !== _noop) { - var newNode = func.call(impl, node, visitArgs); - if (impl.isReplacing) { - node = newNode; - } - } - - if (visitArgs.visitDeeper && node && node.accept) { - node.accept(this); - } - - if (funcOut != _noop) { - funcOut.call(impl, node); - } - - return node; - }, - visitArray: function(nodes, nonReplacing) { - if (!nodes) { - return nodes; - } - - var cnt = nodes.length, i; - - // Non-replacing - if (nonReplacing || !this._implementation.isReplacing) { - for (i = 0; i < cnt; i++) { - this.visit(nodes[i]); - } - return nodes; - } - - // Replacing - var out = []; - for (i = 0; i < cnt; i++) { - var evald = this.visit(nodes[i]); - if (!evald.splice) { - out.push(evald); - } else if (evald.length) { - this.flatten(evald, out); - } - } - return out; - }, - flatten: function(arr, out) { - if (!out) { - out = []; - } - - var cnt, i, item, - nestedCnt, j, nestedItem; - - for (i = 0, cnt = arr.length; i < cnt; i++) { - item = arr[i]; - if (!item.splice) { - out.push(item); - continue; - } - - for (j = 0, nestedCnt = item.length; j < nestedCnt; j++) { - nestedItem = item[j]; - if (!nestedItem.splice) { - out.push(nestedItem); - } else if (nestedItem.length) { - this.flatten(nestedItem, out); - } - } - } - - return out; - } - }; - -})(require('./tree')); -(function (tree) { - tree.importVisitor = function(importer, finish, evalEnv, onceFileDetectionMap, recursionDetector) { - this._visitor = new tree.visitor(this); - this._importer = importer; - this._finish = finish; - this.env = evalEnv || new tree.evalEnv(); - this.importCount = 0; - this.onceFileDetectionMap = onceFileDetectionMap || {}; - this.recursionDetector = {}; - if (recursionDetector) { - for(var fullFilename in recursionDetector) { - if (recursionDetector.hasOwnProperty(fullFilename)) { - this.recursionDetector[fullFilename] = true; - } - } - } - }; - - tree.importVisitor.prototype = { - isReplacing: true, - run: function (root) { - var error; - try { - // process the contents - this._visitor.visit(root); - } - catch(e) { - error = e; - } - - this.isFinished = true; - - if (this.importCount === 0) { - this._finish(error); - } - }, - visitImport: function (importNode, visitArgs) { - var importVisitor = this, - evaldImportNode, - inlineCSS = importNode.options.inline; - - if (!importNode.css || inlineCSS) { - - try { - evaldImportNode = importNode.evalForImport(this.env); - } catch(e){ - if (!e.filename) { e.index = importNode.index; e.filename = importNode.currentFileInfo.filename; } - // attempt to eval properly and treat as css - importNode.css = true; - // if that fails, this error will be thrown - importNode.error = e; - } - - if (evaldImportNode && (!evaldImportNode.css || inlineCSS)) { - importNode = evaldImportNode; - this.importCount++; - var env = new tree.evalEnv(this.env, this.env.frames.slice(0)); - - if (importNode.options.multiple) { - env.importMultiple = true; - } - - this._importer.push(importNode.getPath(), importNode.currentFileInfo, importNode.options, function (e, root, importedAtRoot, fullPath) { - if (e && !e.filename) { e.index = importNode.index; e.filename = importNode.currentFileInfo.filename; } - - if (!env.importMultiple) { - if (importedAtRoot) { - importNode.skip = true; - } else { - importNode.skip = function() { - if (fullPath in importVisitor.onceFileDetectionMap) { - return true; - } - importVisitor.onceFileDetectionMap[fullPath] = true; - return false; - }; - } - } - - var subFinish = function(e) { - importVisitor.importCount--; - - if (importVisitor.importCount === 0 && importVisitor.isFinished) { - importVisitor._finish(e); - } - }; - - if (root) { - importNode.root = root; - importNode.importedFilename = fullPath; - var duplicateImport = importedAtRoot || fullPath in importVisitor.recursionDetector; - - if (!inlineCSS && (env.importMultiple || !duplicateImport)) { - importVisitor.recursionDetector[fullPath] = true; - new(tree.importVisitor)(importVisitor._importer, subFinish, env, importVisitor.onceFileDetectionMap, importVisitor.recursionDetector) - .run(root); - return; - } - } - - subFinish(); - }); - } - } - visitArgs.visitDeeper = false; - return importNode; - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - return ruleNode; - }, - visitDirective: function (directiveNode, visitArgs) { - this.env.frames.unshift(directiveNode); - return directiveNode; - }, - visitDirectiveOut: function (directiveNode) { - this.env.frames.shift(); - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - this.env.frames.unshift(mixinDefinitionNode); - return mixinDefinitionNode; - }, - visitMixinDefinitionOut: function (mixinDefinitionNode) { - this.env.frames.shift(); - }, - visitRuleset: function (rulesetNode, visitArgs) { - this.env.frames.unshift(rulesetNode); - return rulesetNode; - }, - visitRulesetOut: function (rulesetNode) { - this.env.frames.shift(); - }, - visitMedia: function (mediaNode, visitArgs) { - this.env.frames.unshift(mediaNode.ruleset); - return mediaNode; - }, - visitMediaOut: function (mediaNode) { - this.env.frames.shift(); - } - }; - -})(require('./tree')); -(function (tree) { - tree.joinSelectorVisitor = function() { - this.contexts = [[]]; - this._visitor = new tree.visitor(this); - }; - - tree.joinSelectorVisitor.prototype = { - run: function (root) { - return this._visitor.visit(root); - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - - visitRuleset: function (rulesetNode, visitArgs) { - var context = this.contexts[this.contexts.length - 1], - paths = [], selectors; - - this.contexts.push(paths); - - if (! rulesetNode.root) { - selectors = rulesetNode.selectors; - if (selectors) { - selectors = selectors.filter(function(selector) { return selector.getIsOutput(); }); - rulesetNode.selectors = selectors.length ? selectors : (selectors = null); - if (selectors) { rulesetNode.joinSelectors(paths, context, selectors); } - } - if (!selectors) { rulesetNode.rules = null; } - rulesetNode.paths = paths; - } - }, - visitRulesetOut: function (rulesetNode) { - this.contexts.length = this.contexts.length - 1; - }, - visitMedia: function (mediaNode, visitArgs) { - var context = this.contexts[this.contexts.length - 1]; - mediaNode.rules[0].root = (context.length === 0 || context[0].multiMedia); - } - }; - -})(require('./tree')); -(function (tree) { - tree.toCSSVisitor = function(env) { - this._visitor = new tree.visitor(this); - this._env = env; - }; - - tree.toCSSVisitor.prototype = { - isReplacing: true, - run: function (root) { - return this._visitor.visit(root); - }, - - visitRule: function (ruleNode, visitArgs) { - if (ruleNode.variable) { - return []; - } - return ruleNode; - }, - - visitMixinDefinition: function (mixinNode, visitArgs) { - // mixin definitions do not get eval'd - this means they keep state - // so we have to clear that state here so it isn't used if toCSS is called twice - mixinNode.frames = []; - return []; - }, - - visitExtend: function (extendNode, visitArgs) { - return []; - }, - - visitComment: function (commentNode, visitArgs) { - if (commentNode.isSilent(this._env)) { - return []; - } - return commentNode; - }, - - visitMedia: function(mediaNode, visitArgs) { - mediaNode.accept(this._visitor); - visitArgs.visitDeeper = false; - - if (!mediaNode.rules.length) { - return []; - } - return mediaNode; - }, - - visitDirective: function(directiveNode, visitArgs) { - if (directiveNode.currentFileInfo.reference && !directiveNode.isReferenced) { - return []; - } - if (directiveNode.name === "@charset") { - // Only output the debug info together with subsequent @charset definitions - // a comment (or @media statement) before the actual @charset directive would - // be considered illegal css as it has to be on the first line - if (this.charset) { - if (directiveNode.debugInfo) { - var comment = new tree.Comment("/* " + directiveNode.toCSS(this._env).replace(/\n/g, "")+" */\n"); - comment.debugInfo = directiveNode.debugInfo; - return this._visitor.visit(comment); - } - return []; - } - this.charset = true; - } - return directiveNode; - }, - - checkPropertiesInRoot: function(rules) { - var ruleNode; - for(var i = 0; i < rules.length; i++) { - ruleNode = rules[i]; - if (ruleNode instanceof tree.Rule && !ruleNode.variable) { - throw { message: "properties must be inside selector blocks, they cannot be in the root.", - index: ruleNode.index, filename: ruleNode.currentFileInfo ? ruleNode.currentFileInfo.filename : null}; - } - } - }, - - visitRuleset: function (rulesetNode, visitArgs) { - var rule, rulesets = []; - if (rulesetNode.firstRoot) { - this.checkPropertiesInRoot(rulesetNode.rules); - } - if (! rulesetNode.root) { - if (rulesetNode.paths) { - rulesetNode.paths = rulesetNode.paths - .filter(function(p) { - var i; - if (p[0].elements[0].combinator.value === ' ') { - p[0].elements[0].combinator = new(tree.Combinator)(''); - } - for(i = 0; i < p.length; i++) { - if (p[i].getIsReferenced() && p[i].getIsOutput()) { - return true; - } - } - return false; - }); - } - - // Compile rules and rulesets - var nodeRules = rulesetNode.rules, nodeRuleCnt = nodeRules ? nodeRules.length : 0; - for (var i = 0; i < nodeRuleCnt; ) { - rule = nodeRules[i]; - if (rule && rule.rules) { - // visit because we are moving them out from being a child - rulesets.push(this._visitor.visit(rule)); - nodeRules.splice(i, 1); - nodeRuleCnt--; - continue; - } - i++; - } - // accept the visitor to remove rules and refactor itself - // then we can decide now whether we want it or not - if (nodeRuleCnt > 0) { - rulesetNode.accept(this._visitor); - } else { - rulesetNode.rules = null; - } - visitArgs.visitDeeper = false; - - nodeRules = rulesetNode.rules; - if (nodeRules) { - this._mergeRules(nodeRules); - nodeRules = rulesetNode.rules; - } - if (nodeRules) { - this._removeDuplicateRules(nodeRules); - nodeRules = rulesetNode.rules; - } - - // now decide whether we keep the ruleset - if (nodeRules && nodeRules.length > 0 && rulesetNode.paths.length > 0) { - rulesets.splice(0, 0, rulesetNode); - } - } else { - rulesetNode.accept(this._visitor); - visitArgs.visitDeeper = false; - if (rulesetNode.firstRoot || (rulesetNode.rules && rulesetNode.rules.length > 0)) { - rulesets.splice(0, 0, rulesetNode); - } - } - if (rulesets.length === 1) { - return rulesets[0]; - } - return rulesets; - }, - - _removeDuplicateRules: function(rules) { - if (!rules) { return; } - - // remove duplicates - var ruleCache = {}, - ruleList, rule, i; - - for(i = rules.length - 1; i >= 0 ; i--) { - rule = rules[i]; - if (rule instanceof tree.Rule) { - if (!ruleCache[rule.name]) { - ruleCache[rule.name] = rule; - } else { - ruleList = ruleCache[rule.name]; - if (ruleList instanceof tree.Rule) { - ruleList = ruleCache[rule.name] = [ruleCache[rule.name].toCSS(this._env)]; - } - var ruleCSS = rule.toCSS(this._env); - if (ruleList.indexOf(ruleCSS) !== -1) { - rules.splice(i, 1); - } else { - ruleList.push(ruleCSS); - } - } - } - } - }, - - _mergeRules: function (rules) { - if (!rules) { return; } - - var groups = {}, - parts, - rule, - key; - - for (var i = 0; i < rules.length; i++) { - rule = rules[i]; - - if ((rule instanceof tree.Rule) && rule.merge) { - key = [rule.name, - rule.important ? "!" : ""].join(","); - - if (!groups[key]) { - groups[key] = []; - } else { - rules.splice(i--, 1); - } - - groups[key].push(rule); - } - } - - Object.keys(groups).map(function (k) { - - function toExpression(values) { - return new (tree.Expression)(values.map(function (p) { - return p.value; - })); - } - - function toValue(values) { - return new (tree.Value)(values.map(function (p) { - return p; - })); - } - - parts = groups[k]; - - if (parts.length > 1) { - rule = parts[0]; - var spacedGroups = []; - var lastSpacedGroup = []; - parts.map(function (p) { - if (p.merge==="+") { - if (lastSpacedGroup.length > 0) { - spacedGroups.push(toExpression(lastSpacedGroup)); - } - lastSpacedGroup = []; - } - lastSpacedGroup.push(p); - }); - spacedGroups.push(toExpression(lastSpacedGroup)); - rule.value = toValue(spacedGroups); - } - }); - } - }; - -})(require('./tree')); -(function (tree) { - /*jshint loopfunc:true */ - - tree.extendFinderVisitor = function() { - this._visitor = new tree.visitor(this); - this.contexts = []; - this.allExtendsStack = [[]]; - }; - - tree.extendFinderVisitor.prototype = { - run: function (root) { - root = this._visitor.visit(root); - root.allExtends = this.allExtendsStack[0]; - return root; - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitRuleset: function (rulesetNode, visitArgs) { - if (rulesetNode.root) { - return; - } - - var i, j, extend, allSelectorsExtendList = [], extendList; - - // get &:extend(.a); rules which apply to all selectors in this ruleset - var rules = rulesetNode.rules, ruleCnt = rules ? rules.length : 0; - for(i = 0; i < ruleCnt; i++) { - if (rulesetNode.rules[i] instanceof tree.Extend) { - allSelectorsExtendList.push(rules[i]); - rulesetNode.extendOnEveryPath = true; - } - } - - // now find every selector and apply the extends that apply to all extends - // and the ones which apply to an individual extend - var paths = rulesetNode.paths; - for(i = 0; i < paths.length; i++) { - var selectorPath = paths[i], - selector = selectorPath[selectorPath.length - 1], - selExtendList = selector.extendList; - - extendList = selExtendList ? selExtendList.slice(0).concat(allSelectorsExtendList) - : allSelectorsExtendList; - - if (extendList) { - extendList = extendList.map(function(allSelectorsExtend) { - return allSelectorsExtend.clone(); - }); - } - - for(j = 0; j < extendList.length; j++) { - this.foundExtends = true; - extend = extendList[j]; - extend.findSelfSelectors(selectorPath); - extend.ruleset = rulesetNode; - if (j === 0) { extend.firstExtendOnThisSelectorPath = true; } - this.allExtendsStack[this.allExtendsStack.length-1].push(extend); - } - } - - this.contexts.push(rulesetNode.selectors); - }, - visitRulesetOut: function (rulesetNode) { - if (!rulesetNode.root) { - this.contexts.length = this.contexts.length - 1; - } - }, - visitMedia: function (mediaNode, visitArgs) { - mediaNode.allExtends = []; - this.allExtendsStack.push(mediaNode.allExtends); - }, - visitMediaOut: function (mediaNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - }, - visitDirective: function (directiveNode, visitArgs) { - directiveNode.allExtends = []; - this.allExtendsStack.push(directiveNode.allExtends); - }, - visitDirectiveOut: function (directiveNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - } - }; - - tree.processExtendsVisitor = function() { - this._visitor = new tree.visitor(this); - }; - - tree.processExtendsVisitor.prototype = { - run: function(root) { - var extendFinder = new tree.extendFinderVisitor(); - extendFinder.run(root); - if (!extendFinder.foundExtends) { return root; } - root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends)); - this.allExtendsStack = [root.allExtends]; - return this._visitor.visit(root); - }, - doExtendChaining: function (extendsList, extendsListTarget, iterationCount) { - // - // chaining is different from normal extension.. if we extend an extend then we are not just copying, altering and pasting - // the selector we would do normally, but we are also adding an extend with the same target selector - // this means this new extend can then go and alter other extends - // - // this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors - // this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already processed if - // we look at each selector at a time, as is done in visitRuleset - - var extendIndex, targetExtendIndex, matches, extendsToAdd = [], newSelector, extendVisitor = this, selectorPath, extend, targetExtend, newExtend; - - iterationCount = iterationCount || 0; - - //loop through comparing every extend with every target extend. - // a target extend is the one on the ruleset we are looking at copy/edit/pasting in place - // e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one - // and the second is the target. - // the seperation into two lists allows us to process a subset of chains with a bigger set, as is the - // case when processing media queries - for(extendIndex = 0; extendIndex < extendsList.length; extendIndex++){ - for(targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++){ - - extend = extendsList[extendIndex]; - targetExtend = extendsListTarget[targetExtendIndex]; - - // look for circular references - if( extend.parent_ids.indexOf( targetExtend.object_id ) >= 0 ){ continue; } - - // find a match in the target extends self selector (the bit before :extend) - selectorPath = [targetExtend.selfSelectors[0]]; - matches = extendVisitor.findMatch(extend, selectorPath); - - if (matches.length) { - - // we found a match, so for each self selector.. - extend.selfSelectors.forEach(function(selfSelector) { - - // process the extend as usual - newSelector = extendVisitor.extendSelector(matches, selectorPath, selfSelector); - - // but now we create a new extend from it - newExtend = new(tree.Extend)(targetExtend.selector, targetExtend.option, 0); - newExtend.selfSelectors = newSelector; - - // add the extend onto the list of extends for that selector - newSelector[newSelector.length-1].extendList = [newExtend]; - - // record that we need to add it. - extendsToAdd.push(newExtend); - newExtend.ruleset = targetExtend.ruleset; - - //remember its parents for circular references - newExtend.parent_ids = newExtend.parent_ids.concat(targetExtend.parent_ids, extend.parent_ids); - - // only process the selector once.. if we have :extend(.a,.b) then multiple - // extends will look at the same selector path, so when extending - // we know that any others will be duplicates in terms of what is added to the css - if (targetExtend.firstExtendOnThisSelectorPath) { - newExtend.firstExtendOnThisSelectorPath = true; - targetExtend.ruleset.paths.push(newSelector); - } - }); - } - } - } - - if (extendsToAdd.length) { - // try to detect circular references to stop a stack overflow. - // may no longer be needed. - this.extendChainCount++; - if (iterationCount > 100) { - var selectorOne = "{unable to calculate}"; - var selectorTwo = "{unable to calculate}"; - try - { - selectorOne = extendsToAdd[0].selfSelectors[0].toCSS(); - selectorTwo = extendsToAdd[0].selector.toCSS(); - } - catch(e) {} - throw {message: "extend circular reference detected. One of the circular extends is currently:"+selectorOne+":extend(" + selectorTwo+")"}; - } - - // now process the new extends on the existing rules so that we can handle a extending b extending c ectending d extending e... - return extendsToAdd.concat(extendVisitor.doExtendChaining(extendsToAdd, extendsListTarget, iterationCount+1)); - } else { - return extendsToAdd; - } - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitSelector: function (selectorNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitRuleset: function (rulesetNode, visitArgs) { - if (rulesetNode.root) { - return; - } - var matches, pathIndex, extendIndex, allExtends = this.allExtendsStack[this.allExtendsStack.length-1], selectorsToAdd = [], extendVisitor = this, selectorPath; - - // look at each selector path in the ruleset, find any extend matches and then copy, find and replace - - for(extendIndex = 0; extendIndex < allExtends.length; extendIndex++) { - for(pathIndex = 0; pathIndex < rulesetNode.paths.length; pathIndex++) { - selectorPath = rulesetNode.paths[pathIndex]; - - // extending extends happens initially, before the main pass - if (rulesetNode.extendOnEveryPath) { continue; } - var extendList = selectorPath[selectorPath.length-1].extendList; - if (extendList && extendList.length) { continue; } - - matches = this.findMatch(allExtends[extendIndex], selectorPath); - - if (matches.length) { - - allExtends[extendIndex].selfSelectors.forEach(function(selfSelector) { - selectorsToAdd.push(extendVisitor.extendSelector(matches, selectorPath, selfSelector)); - }); - } - } - } - rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd); - }, - findMatch: function (extend, haystackSelectorPath) { - // - // look through the haystack selector path to try and find the needle - extend.selector - // returns an array of selector matches that can then be replaced - // - var haystackSelectorIndex, hackstackSelector, hackstackElementIndex, haystackElement, - targetCombinator, i, - extendVisitor = this, - needleElements = extend.selector.elements, - potentialMatches = [], potentialMatch, matches = []; - - // loop through the haystack elements - for(haystackSelectorIndex = 0; haystackSelectorIndex < haystackSelectorPath.length; haystackSelectorIndex++) { - hackstackSelector = haystackSelectorPath[haystackSelectorIndex]; - - for(hackstackElementIndex = 0; hackstackElementIndex < hackstackSelector.elements.length; hackstackElementIndex++) { - - haystackElement = hackstackSelector.elements[hackstackElementIndex]; - - // if we allow elements before our match we can add a potential match every time. otherwise only at the first element. - if (extend.allowBefore || (haystackSelectorIndex === 0 && hackstackElementIndex === 0)) { - potentialMatches.push({pathIndex: haystackSelectorIndex, index: hackstackElementIndex, matched: 0, initialCombinator: haystackElement.combinator}); - } - - for(i = 0; i < potentialMatches.length; i++) { - potentialMatch = potentialMatches[i]; - - // selectors add " " onto the first element. When we use & it joins the selectors together, but if we don't - // then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to work out - // what the resulting combinator will be - targetCombinator = haystackElement.combinator.value; - if (targetCombinator === '' && hackstackElementIndex === 0) { - targetCombinator = ' '; - } - - // if we don't match, null our match to indicate failure - if (!extendVisitor.isElementValuesEqual(needleElements[potentialMatch.matched].value, haystackElement.value) || - (potentialMatch.matched > 0 && needleElements[potentialMatch.matched].combinator.value !== targetCombinator)) { - potentialMatch = null; - } else { - potentialMatch.matched++; - } - - // if we are still valid and have finished, test whether we have elements after and whether these are allowed - if (potentialMatch) { - potentialMatch.finished = potentialMatch.matched === needleElements.length; - if (potentialMatch.finished && - (!extend.allowAfter && (hackstackElementIndex+1 < hackstackSelector.elements.length || haystackSelectorIndex+1 < haystackSelectorPath.length))) { - potentialMatch = null; - } - } - // if null we remove, if not, we are still valid, so either push as a valid match or continue - if (potentialMatch) { - if (potentialMatch.finished) { - potentialMatch.length = needleElements.length; - potentialMatch.endPathIndex = haystackSelectorIndex; - potentialMatch.endPathElementIndex = hackstackElementIndex + 1; // index after end of match - potentialMatches.length = 0; // we don't allow matches to overlap, so start matching again - matches.push(potentialMatch); - } - } else { - potentialMatches.splice(i, 1); - i--; - } - } - } - } - return matches; - }, - isElementValuesEqual: function(elementValue1, elementValue2) { - if (typeof elementValue1 === "string" || typeof elementValue2 === "string") { - return elementValue1 === elementValue2; - } - if (elementValue1 instanceof tree.Attribute) { - if (elementValue1.op !== elementValue2.op || elementValue1.key !== elementValue2.key) { - return false; - } - if (!elementValue1.value || !elementValue2.value) { - if (elementValue1.value || elementValue2.value) { - return false; - } - return true; - } - elementValue1 = elementValue1.value.value || elementValue1.value; - elementValue2 = elementValue2.value.value || elementValue2.value; - return elementValue1 === elementValue2; - } - elementValue1 = elementValue1.value; - elementValue2 = elementValue2.value; - if (elementValue1 instanceof tree.Selector) { - if (!(elementValue2 instanceof tree.Selector) || elementValue1.elements.length !== elementValue2.elements.length) { - return false; - } - for(var i = 0; i currentSelectorPathIndex && currentSelectorPathElementIndex > 0) { - path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); - currentSelectorPathElementIndex = 0; - currentSelectorPathIndex++; - } - - newElements = selector.elements - .slice(currentSelectorPathElementIndex, match.index) - .concat([firstElement]) - .concat(replacementSelector.elements.slice(1)); - - if (currentSelectorPathIndex === match.pathIndex && matchIndex > 0) { - path[path.length - 1].elements = - path[path.length - 1].elements.concat(newElements); - } else { - path = path.concat(selectorPath.slice(currentSelectorPathIndex, match.pathIndex)); - - path.push(new tree.Selector( - newElements - )); - } - currentSelectorPathIndex = match.endPathIndex; - currentSelectorPathElementIndex = match.endPathElementIndex; - if (currentSelectorPathElementIndex >= selectorPath[currentSelectorPathIndex].elements.length) { - currentSelectorPathElementIndex = 0; - currentSelectorPathIndex++; - } - } - - if (currentSelectorPathIndex < selectorPath.length && currentSelectorPathElementIndex > 0) { - path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); - currentSelectorPathIndex++; - } - - path = path.concat(selectorPath.slice(currentSelectorPathIndex, selectorPath.length)); - - return path; - }, - visitRulesetOut: function (rulesetNode) { - }, - visitMedia: function (mediaNode, visitArgs) { - var newAllExtends = mediaNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]); - newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, mediaNode.allExtends)); - this.allExtendsStack.push(newAllExtends); - }, - visitMediaOut: function (mediaNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - }, - visitDirective: function (directiveNode, visitArgs) { - var newAllExtends = directiveNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]); - newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, directiveNode.allExtends)); - this.allExtendsStack.push(newAllExtends); - }, - visitDirectiveOut: function (directiveNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - } - }; - -})(require('./tree')); - -(function (tree) { - - tree.sourceMapOutput = function (options) { - this._css = []; - this._rootNode = options.rootNode; - this._writeSourceMap = options.writeSourceMap; - this._contentsMap = options.contentsMap; - this._contentsIgnoredCharsMap = options.contentsIgnoredCharsMap; - this._sourceMapFilename = options.sourceMapFilename; - this._outputFilename = options.outputFilename; - this._sourceMapURL = options.sourceMapURL; - if (options.sourceMapBasepath) { - this._sourceMapBasepath = options.sourceMapBasepath.replace(/\\/g, '/'); - } - this._sourceMapRootpath = options.sourceMapRootpath; - this._outputSourceFiles = options.outputSourceFiles; - this._sourceMapGeneratorConstructor = options.sourceMapGenerator || require("source-map").SourceMapGenerator; - - if (this._sourceMapRootpath && this._sourceMapRootpath.charAt(this._sourceMapRootpath.length-1) !== '/') { - this._sourceMapRootpath += '/'; - } - - this._lineNumber = 0; - this._column = 0; - }; - - tree.sourceMapOutput.prototype.normalizeFilename = function(filename) { - filename = filename.replace(/\\/g, '/'); - - if (this._sourceMapBasepath && filename.indexOf(this._sourceMapBasepath) === 0) { - filename = filename.substring(this._sourceMapBasepath.length); - if (filename.charAt(0) === '\\' || filename.charAt(0) === '/') { - filename = filename.substring(1); - } - } - return (this._sourceMapRootpath || "") + filename; - }; - - tree.sourceMapOutput.prototype.add = function(chunk, fileInfo, index, mapLines) { - - //ignore adding empty strings - if (!chunk) { - return; - } - - var lines, - sourceLines, - columns, - sourceColumns, - i; - - if (fileInfo) { - var inputSource = this._contentsMap[fileInfo.filename]; - - // remove vars/banner added to the top of the file - if (this._contentsIgnoredCharsMap[fileInfo.filename]) { - // adjust the index - index -= this._contentsIgnoredCharsMap[fileInfo.filename]; - if (index < 0) { index = 0; } - // adjust the source - inputSource = inputSource.slice(this._contentsIgnoredCharsMap[fileInfo.filename]); - } - inputSource = inputSource.substring(0, index); - sourceLines = inputSource.split("\n"); - sourceColumns = sourceLines[sourceLines.length-1]; - } - - lines = chunk.split("\n"); - columns = lines[lines.length-1]; - - if (fileInfo) { - if (!mapLines) { - this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + 1, column: this._column}, - original: { line: sourceLines.length, column: sourceColumns.length}, - source: this.normalizeFilename(fileInfo.filename)}); - } else { - for(i = 0; i < lines.length; i++) { - this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + i + 1, column: i === 0 ? this._column : 0}, - original: { line: sourceLines.length + i, column: i === 0 ? sourceColumns.length : 0}, - source: this.normalizeFilename(fileInfo.filename)}); - } - } - } - - if (lines.length === 1) { - this._column += columns.length; - } else { - this._lineNumber += lines.length - 1; - this._column = columns.length; - } - - this._css.push(chunk); - }; - - tree.sourceMapOutput.prototype.isEmpty = function() { - return this._css.length === 0; - }; - - tree.sourceMapOutput.prototype.toCSS = function(env) { - this._sourceMapGenerator = new this._sourceMapGeneratorConstructor({ file: this._outputFilename, sourceRoot: null }); - - if (this._outputSourceFiles) { - for(var filename in this._contentsMap) { - if (this._contentsMap.hasOwnProperty(filename)) - { - var source = this._contentsMap[filename]; - if (this._contentsIgnoredCharsMap[filename]) { - source = source.slice(this._contentsIgnoredCharsMap[filename]); - } - this._sourceMapGenerator.setSourceContent(this.normalizeFilename(filename), source); - } - } - } - - this._rootNode.genCSS(env, this); - - if (this._css.length > 0) { - var sourceMapURL, - sourceMapContent = JSON.stringify(this._sourceMapGenerator.toJSON()); - - if (this._sourceMapURL) { - sourceMapURL = this._sourceMapURL; - } else if (this._sourceMapFilename) { - sourceMapURL = this.normalizeFilename(this._sourceMapFilename); - } - - if (this._writeSourceMap) { - this._writeSourceMap(sourceMapContent); - } else { - sourceMapURL = "data:application/json," + encodeURIComponent(sourceMapContent); - } - - if (sourceMapURL) { - this._css.push("/*# sourceMappingURL=" + sourceMapURL + " */"); - } - } - - return this._css.join(''); - }; - -})(require('./tree')); - -// -// browser.js - client-side engine -// -/*global less, window, document, XMLHttpRequest, location */ - -var isFileProtocol = /^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol); - -less.env = less.env || (location.hostname == '127.0.0.1' || - location.hostname == '0.0.0.0' || - location.hostname == 'localhost' || - (location.port && - location.port.length > 0) || - isFileProtocol ? 'development' - : 'production'); - -var logLevel = { - debug: 3, - info: 2, - errors: 1, - none: 0 -}; - -// The amount of logging in the javascript console. -// 3 - Debug, information and errors -// 2 - Information and errors -// 1 - Errors -// 0 - None -// Defaults to 2 -less.logLevel = typeof(less.logLevel) != 'undefined' ? less.logLevel : (less.env === 'development' ? logLevel.debug : logLevel.errors); - -// Load styles asynchronously (default: false) -// -// This is set to `false` by default, so that the body -// doesn't start loading before the stylesheets are parsed. -// Setting this to `true` can result in flickering. -// -less.async = less.async || false; -less.fileAsync = less.fileAsync || false; - -// Interval between watch polls -less.poll = less.poll || (isFileProtocol ? 1000 : 1500); - -//Setup user functions -if (less.functions) { - for(var func in less.functions) { - if (less.functions.hasOwnProperty(func)) { - less.tree.functions[func] = less.functions[func]; - } - } -} - -var dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(location.hash); -if (dumpLineNumbers) { - less.dumpLineNumbers = dumpLineNumbers[1]; -} - -var typePattern = /^text\/(x-)?less$/; -var cache = null; -var fileCache = {}; - -function log(str) { - console.log(str); -} - -function extractId(href) { - return href.replace(/^[a-z-]+:\/+?[^\/]+/, '' ) // Remove protocol & domain - .replace(/^\//, '' ) // Remove root / - .replace(/\.[a-zA-Z]+$/, '' ) // Remove simple extension - .replace(/[^\.\w-]+/g, '-') // Replace illegal characters - .replace(/\./g, ':'); // Replace dots with colons(for valid id) -} - -function errorConsole(e, rootHref) { - var template = '{line} {content}'; - var filename = e.filename || rootHref; - var errors = []; - var content = (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') + - " in " + filename + " "; - - var errorline = function (e, i, classname) { - if (e.extract[i] !== undefined) { - errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1)) - .replace(/\{class\}/, classname) - .replace(/\{content\}/, e.extract[i])); - } - }; - - if (e.extract) { - errorline(e, 0, ''); - errorline(e, 1, 'line'); - errorline(e, 2, ''); - content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':\n' + - errors.join('\n'); - } else if (e.stack) { - content += e.stack; - } - //log(content, logLevel.errors); -} - -function createCSS(styles, sheet, lastModified) { - // Strip the query-string - var href = sheet.href || ''; - - // If there is no title set, use the filename, minus the extension - var id = 'less:' + (sheet.title || extractId(href)); - - // If this has already been inserted into the DOM, we may need to replace it - var oldCss = document.getElementById(id); - var keepOldCss = false; - - // Create a new stylesheet node for insertion or (if necessary) replacement - var css = document.createElement('style'); - css.setAttribute('type', 'text/css'); - if (sheet.media) { - css.setAttribute('media', sheet.media); - } - css.id = id; - - if (css.styleSheet) { // IE - try { - css.styleSheet.cssText = styles; - } catch (e) { - throw new(Error)("Couldn't reassign styleSheet.cssText."); - } - } else { - css.appendChild(document.createTextNode(styles)); - - // If new contents match contents of oldCss, don't replace oldCss - keepOldCss = (oldCss !== null && oldCss.childNodes.length > 0 && css.childNodes.length > 0 && - oldCss.firstChild.nodeValue === css.firstChild.nodeValue); - } - - var head = document.getElementsByTagName('head')[0]; - - // If there is no oldCss, just append; otherwise, only append if we need - // to replace oldCss with an updated stylesheet - if (oldCss === null || keepOldCss === false) { - var nextEl = sheet && sheet.nextSibling || null; - if (nextEl) { - nextEl.parentNode.insertBefore(css, nextEl); - } else { - head.appendChild(css); - } - } - if (oldCss && keepOldCss === false) { - oldCss.parentNode.removeChild(oldCss); - } - - // Don't update the local store if the file wasn't modified - if (lastModified && cache) { - //log('saving ' + href + ' to cache.', logLevel.info); - try { - cache.setItem(href, styles); - cache.setItem(href + ':timestamp', lastModified); - } catch(e) { - //TODO - could do with adding more robust error handling - //log('failed to save', logLevel.errors); - } - } -} - -function postProcessCSS(styles) { - if (less.postProcessor && typeof less.postProcessor === 'function') { - styles = less.postProcessor.call(styles, styles) || styles; - } - return styles; -} - -function errorHTML(e, rootHref) { - var id = 'less-error-message:' + extractId(rootHref || ""); - var template = '
  • {content}
  • '; - var elem = document.createElement('div'), timer, content, errors = []; - var filename = e.filename || rootHref; - var filenameNoPath = filename.match(/([^\/]+(\?.*)?)$/)[1]; - - elem.id = id; - elem.className = "less-error-message"; - - content = '

    ' + (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') + - '

    ' + '

    in ' + filenameNoPath + " "; - - var errorline = function (e, i, classname) { - if (e.extract[i] !== undefined) { - errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1)) - .replace(/\{class\}/, classname) - .replace(/\{content\}/, e.extract[i])); - } - }; - - if (e.extract) { - errorline(e, 0, ''); - errorline(e, 1, 'line'); - errorline(e, 2, ''); - content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':

    ' + - '
      ' + errors.join('') + '
    '; - } else if (e.stack) { - content += '
    ' + e.stack.split('\n').slice(1).join('
    '); - } - elem.innerHTML = content; - - // CSS for error messages - createCSS([ - '.less-error-message ul, .less-error-message li {', - 'list-style-type: none;', - 'margin-right: 15px;', - 'padding: 4px 0;', - 'margin: 0;', - '}', - '.less-error-message label {', - 'font-size: 12px;', - 'margin-right: 15px;', - 'padding: 4px 0;', - 'color: #cc7777;', - '}', - '.less-error-message pre {', - 'color: #dd6666;', - 'padding: 4px 0;', - 'margin: 0;', - 'display: inline-block;', - '}', - '.less-error-message pre.line {', - 'color: #ff0000;', - '}', - '.less-error-message h3 {', - 'font-size: 20px;', - 'font-weight: bold;', - 'padding: 15px 0 5px 0;', - 'margin: 0;', - '}', - '.less-error-message a {', - 'color: #10a', - '}', - '.less-error-message .error {', - 'color: red;', - 'font-weight: bold;', - 'padding-bottom: 2px;', - 'border-bottom: 1px dashed red;', - '}' - ].join('\n'), { title: 'error-message' }); - - elem.style.cssText = [ - "font-family: Arial, sans-serif", - "border: 1px solid #e00", - "background-color: #eee", - "border-radius: 5px", - "-webkit-border-radius: 5px", - "-moz-border-radius: 5px", - "color: #e00", - "padding: 15px", - "margin-bottom: 15px" - ].join(';'); - - if (less.env == 'development') { - timer = setInterval(function () { - if (document.body) { - if (document.getElementById(id)) { - document.body.replaceChild(elem, document.getElementById(id)); - } else { - document.body.insertBefore(elem, document.body.firstChild); - } - clearInterval(timer); - } - }, 10); - } -} - -function error(e, rootHref) { - if (!less.errorReporting || less.errorReporting === "html") { - errorHTML(e, rootHref); - } else if (less.errorReporting === "console") { - errorConsole(e, rootHref); - } else if (typeof less.errorReporting === 'function') { - less.errorReporting("add", e, rootHref); - } -} - -function removeErrorHTML(path) { - var node = document.getElementById('less-error-message:' + extractId(path)); - if (node) { - node.parentNode.removeChild(node); - } -} - -function removeErrorConsole(path) { - //no action -} - -function removeError(path) { - if (!less.errorReporting || less.errorReporting === "html") { - removeErrorHTML(path); - } else if (less.errorReporting === "console") { - removeErrorConsole(path); - } else if (typeof less.errorReporting === 'function') { - less.errorReporting("remove", path); - } -} - -function loadStyles(modifyVars) { - var styles = document.getElementsByTagName('style'), - style; - for (var i = 0; i < styles.length; i++) { - style = styles[i]; - if (style.type.match(typePattern)) { - var env = new less.tree.parseEnv(less), - lessText = style.innerHTML || ''; - env.filename = document.location.href.replace(/#.*$/, ''); - - if (modifyVars || less.globalVars) { - env.useFileCache = true; - } - - /*jshint loopfunc:true */ - // use closure to store current value of i - var callback = (function(style) { - return function (e, cssAST) { - if (e) { - return error(e, "inline"); - } - var css = cssAST.toCSS(less); - style.type = 'text/css'; - if (style.styleSheet) { - style.styleSheet.cssText = css; - } else { - style.innerHTML = css; - } - }; - })(style); - new(less.Parser)(env).parse(lessText, callback, {globalVars: less.globalVars, modifyVars: modifyVars}); - } - } -} - -function extractUrlParts(url, baseUrl) { - // urlParts[1] = protocol&hostname || / - // urlParts[2] = / if path relative to host base - // urlParts[3] = directories - // urlParts[4] = filename - // urlParts[5] = parameters - - var urlPartsRegex = /^((?:[a-z-]+:)?\/+?(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i, - urlParts = url.match(urlPartsRegex), - returner = {}, directories = [], i, baseUrlParts; - - if (!urlParts) { - throw new Error("Could not parse sheet href - '"+url+"'"); - } - - // Stylesheets in IE don't always return the full path - if (!urlParts[1] || urlParts[2]) { - baseUrlParts = baseUrl.match(urlPartsRegex); - if (!baseUrlParts) { - throw new Error("Could not parse page url - '"+baseUrl+"'"); - } - urlParts[1] = urlParts[1] || baseUrlParts[1] || ""; - if (!urlParts[2]) { - urlParts[3] = baseUrlParts[3] + urlParts[3]; - } - } - - if (urlParts[3]) { - directories = urlParts[3].replace(/\\/g, "/").split("/"); - - // extract out . before .. so .. doesn't absorb a non-directory - for(i = 0; i < directories.length; i++) { - if (directories[i] === ".") { - directories.splice(i, 1); - i -= 1; - } - } - - for(i = 0; i < directories.length; i++) { - if (directories[i] === ".." && i > 0) { - directories.splice(i-1, 2); - i -= 2; - } - } - } - - returner.hostPart = urlParts[1]; - returner.directories = directories; - returner.path = urlParts[1] + directories.join("/"); - returner.fileUrl = returner.path + (urlParts[4] || ""); - returner.url = returner.fileUrl + (urlParts[5] || ""); - return returner; -} - -function pathDiff(url, baseUrl) { - // diff between two paths to create a relative path - - var urlParts = extractUrlParts(url), - baseUrlParts = extractUrlParts(baseUrl), - i, max, urlDirectories, baseUrlDirectories, diff = ""; - if (urlParts.hostPart !== baseUrlParts.hostPart) { - return ""; - } - max = Math.max(baseUrlParts.directories.length, urlParts.directories.length); - for(i = 0; i < max; i++) { - if (baseUrlParts.directories[i] !== urlParts.directories[i]) { break; } - } - baseUrlDirectories = baseUrlParts.directories.slice(i); - urlDirectories = urlParts.directories.slice(i); - for(i = 0; i < baseUrlDirectories.length-1; i++) { - diff += "../"; - } - for(i = 0; i < urlDirectories.length-1; i++) { - diff += urlDirectories[i] + "/"; - } - return diff; -} - -function getXMLHttpRequest() { - if (window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject)) { - return new XMLHttpRequest(); - } else { - try { - /*global ActiveXObject */ - return new ActiveXObject("Microsoft.XMLHTTP"); - } catch (e) { - //log("browser doesn't support AJAX.", logLevel.errors); - return null; - } - } -} - -function doXHR(url, type, callback, errback) { - var xhr = getXMLHttpRequest(); - var async = isFileProtocol ? less.fileAsync : less.async; - - if (typeof(xhr.overrideMimeType) === 'function') { - xhr.overrideMimeType('text/css'); - } - //log("XHR: Getting '" + url + "'", logLevel.debug); - xhr.open('GET', url, async); - xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5'); - xhr.send(null); - - function handleResponse(xhr, callback, errback) { - if (xhr.status >= 200 && xhr.status < 300) { - callback(xhr.responseText, - xhr.getResponseHeader("Last-Modified")); - } else if (typeof(errback) === 'function') { - errback(xhr.status, url); - } - } - - if (isFileProtocol && !less.fileAsync) { - if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) { - callback(xhr.responseText); - } else { - errback(xhr.status, url); - } - } else if (async) { - xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - handleResponse(xhr, callback, errback); - } - }; - } else { - handleResponse(xhr, callback, errback); - } -} - -function loadFile(originalHref, currentFileInfo, callback, env, modifyVars) { - - if (currentFileInfo && currentFileInfo.currentDirectory && !/^([a-z-]+:)?\//.test(originalHref)) { - originalHref = currentFileInfo.currentDirectory + originalHref; - } - - // sheet may be set to the stylesheet for the initial load or a collection of properties including - // some env variables for imports - var hrefParts = extractUrlParts(originalHref, window.location.href); - var href = hrefParts.url; - var newFileInfo = { - currentDirectory: hrefParts.path, - filename: href - }; - - if (currentFileInfo) { - newFileInfo.entryPath = currentFileInfo.entryPath; - newFileInfo.rootpath = currentFileInfo.rootpath; - newFileInfo.rootFilename = currentFileInfo.rootFilename; - newFileInfo.relativeUrls = currentFileInfo.relativeUrls; - } else { - newFileInfo.entryPath = hrefParts.path; - newFileInfo.rootpath = less.rootpath || hrefParts.path; - newFileInfo.rootFilename = href; - newFileInfo.relativeUrls = env.relativeUrls; - } - - if (newFileInfo.relativeUrls) { - if (env.rootpath) { - newFileInfo.rootpath = extractUrlParts(env.rootpath + pathDiff(hrefParts.path, newFileInfo.entryPath)).path; - } else { - newFileInfo.rootpath = hrefParts.path; - } - } - - if (env.useFileCache && fileCache[href]) { - try { - var lessText = fileCache[href]; - callback(null, lessText, href, newFileInfo, { lastModified: new Date() }); - } catch (e) { - callback(e, null, href); - } - return; - } - - doXHR(href, env.mime, function (data, lastModified) { - // per file cache - fileCache[href] = data; - - // Use remote copy (re-parse) - try { - callback(null, data, href, newFileInfo, { lastModified: lastModified }); - } catch (e) { - callback(e, null, href); - } - }, function (status, url) { - callback({ type: 'File', message: "'" + url + "' wasn't found (" + status + ")" }, null, href); - }); -} - -function loadStyleSheet(sheet, callback, reload, remaining, modifyVars) { - - var env = new less.tree.parseEnv(less); - env.mime = sheet.type; - - if (modifyVars || less.globalVars) { - env.useFileCache = true; - } - - loadFile(sheet.href, null, function(e, data, path, newFileInfo, webInfo) { - - if (webInfo) { - webInfo.remaining = remaining; - - var css = cache && cache.getItem(path), - timestamp = cache && cache.getItem(path + ':timestamp'); - - if (!reload && timestamp && webInfo.lastModified && - (new(Date)(webInfo.lastModified).valueOf() === - new(Date)(timestamp).valueOf())) { - // Use local copy - createCSS(css, sheet); - webInfo.local = true; - callback(null, null, data, sheet, webInfo, path); - return; - } - } - - //TODO add tests around how this behaves when reloading - removeError(path); - - if (data) { - env.currentFileInfo = newFileInfo; - new(less.Parser)(env).parse(data, function (e, root) { - if (e) { return callback(e, null, null, sheet); } - try { - callback(e, root, data, sheet, webInfo, path); - } catch (e) { - callback(e, null, null, sheet); - } - }, {modifyVars: modifyVars, globalVars: less.globalVars}); - } else { - callback(e, null, null, sheet, webInfo, path); - } - }, env, modifyVars); -} - -function loadStyleSheets(callback, reload, modifyVars) { - for (var i = 0; i < less.sheets.length; i++) { - loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1), modifyVars); - } -} - -function initRunningMode(){ - if (less.env === 'development') { - less.optimization = 0; - less.watchTimer = setInterval(function () { - if (less.watchMode) { - loadStyleSheets(function (e, root, _, sheet, env) { - if (e) { - error(e, sheet.href); - } else if (root) { - var styles = root.toCSS(less); - styles = postProcessCSS(styles); - createCSS(styles, sheet, env.lastModified); - } - }); - } - }, less.poll); - } else { - less.optimization = 3; - } -} - - - -// -// Watch mode -// -less.watch = function () { - if (!less.watchMode ){ - less.env = 'development'; - initRunningMode(); - } - this.watchMode = true; - return true; -}; - -less.unwatch = function () {clearInterval(less.watchTimer); this.watchMode = false; return false; }; - -if (/!watch/.test(location.hash)) { - less.watch(); -} - -if (less.env != 'development') { - try { - cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage; - } catch (_) {} -} - -// -// Get all tags with the 'rel' attribute set to "stylesheet/less" -// -var links = document.getElementsByTagName('link'); - -less.sheets = []; - -for (var i = 0; i < links.length; i++) { - if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) && - (links[i].type.match(typePattern)))) { - less.sheets.push(links[i]); - } -} - -// -// With this function, it's possible to alter variables and re-render -// CSS without reloading less-files -// -less.modifyVars = function(record) { - less.refresh(false, record); -}; - -less.refresh = function (reload, modifyVars) { - var startTime, endTime; - startTime = endTime = new Date(); - - loadStyleSheets(function (e, root, _, sheet, env) { - if (e) { - return error(e, sheet.href); - } - if (env.local) { - //log("loading " + sheet.href + " from cache.", logLevel.info); - } else { - //log("parsed " + sheet.href + " successfully.", logLevel.debug); - //var styles = root.toCSS(less); - //styles = postProcessCSS(styles); - //createCSS(styles, sheet, env.lastModified); - - - - // less.php changes - var css = root.toCSS(less); - function totextarea(){ - var textarea = document.getElementById('lessjs_textarea'); - if( textarea ){ - textarea.value = css; - diffUsingJS(0); - }else{ - window.setTimeout(totextarea,300); - } - } - totextarea(); - - - } - log("css for " + sheet.href + " generated in " + (new Date() - endTime) + 'ms', logLevel.info); - if (env.remaining === 0) { - //log("less has finished. css generated in " + (new Date() - startTime) + 'ms', logLevel.info); - } - endTime = new Date(); - }, reload, modifyVars); - - loadStyles(modifyVars); -}; - -less.refreshStyles = loadStyles; - -less.Parser.fileLoader = loadFile; - -less.refresh(less.env === 'development'); - -// amd.js -// -// Define Less as an AMD module. -if (typeof define === "function" && define.amd) { - define(function () { return less; } ); -} - -})(window); \ No newline at end of file diff --git a/test/assets/less-1.7.1.js b/test/assets/less-1.7.1.js deleted file mode 100644 index c62264fc..00000000 --- a/test/assets/less-1.7.1.js +++ /dev/null @@ -1,7936 +0,0 @@ -/*! - * Less - Leaner CSS v1.7.1 - * http://lesscss.org - * - * Copyright (c) 2009-2014, Alexis Sellier - * Licensed under the Apache v2 License. - * - */ - - /** * @license Apache v2 - */ - - - -(function (window, undefined) {// -// Stub out `require` in the browser -// -function require(arg) { - return window.less[arg.split('/')[1]]; -}; - - -if (typeof(window.less) === 'undefined' || typeof(window.less.nodeType) !== 'undefined') { window.less = {}; } -less = window.less; -tree = window.less.tree = {}; -less.mode = 'browser'; - -var less, tree; - -// Node.js does not have a header file added which defines less -if (less === undefined) { - less = exports; - tree = require('./tree'); - less.mode = 'node'; -} -// -// less.js - parser -// -// A relatively straight-forward predictive parser. -// There is no tokenization/lexing stage, the input is parsed -// in one sweep. -// -// To make the parser fast enough to run in the browser, several -// optimization had to be made: -// -// - Matching and slicing on a huge input is often cause of slowdowns. -// The solution is to chunkify the input into smaller strings. -// The chunks are stored in the `chunks` var, -// `j` holds the current chunk index, and `currentPos` holds -// the index of the current chunk in relation to `input`. -// This gives us an almost 4x speed-up. -// -// - In many cases, we don't need to match individual tokens; -// for example, if a value doesn't hold any variables, operations -// or dynamic references, the parser can effectively 'skip' it, -// treating it as a literal. -// An example would be '1px solid #000' - which evaluates to itself, -// we don't need to know what the individual components are. -// The drawback, of course is that you don't get the benefits of -// syntax-checking on the CSS. This gives us a 50% speed-up in the parser, -// and a smaller speed-up in the code-gen. -// -// -// Token matching is done with the `$` function, which either takes -// a terminal string or regexp, or a non-terminal function to call. -// It also takes care of moving all the indices forwards. -// -// -less.Parser = function Parser(env) { - var input, // LeSS input string - i, // current index in `input` - j, // current chunk - saveStack = [], // holds state for backtracking - furthest, // furthest index the parser has gone to - chunks, // chunkified input - current, // current chunk - currentPos, // index of current chunk, in `input` - parser, - parsers, - rootFilename = env && env.filename; - - // Top parser on an import tree must be sure there is one "env" - // which will then be passed around by reference. - if (!(env instanceof tree.parseEnv)) { - env = new tree.parseEnv(env); - } - - var imports = this.imports = { - paths: env.paths || [], // Search paths, when importing - queue: [], // Files which haven't been imported yet - files: env.files, // Holds the imported parse trees - contents: env.contents, // Holds the imported file contents - contentsIgnoredChars: env.contentsIgnoredChars, // lines inserted, not in the original less - mime: env.mime, // MIME type of .less files - error: null, // Error in parsing/evaluating an import - push: function (path, currentFileInfo, importOptions, callback) { - var parserImports = this; - this.queue.push(path); - - var fileParsedFunc = function (e, root, fullPath) { - parserImports.queue.splice(parserImports.queue.indexOf(path), 1); // Remove the path from the queue - - var importedPreviously = fullPath === rootFilename; - - parserImports.files[fullPath] = root; // Store the root - - if (e && !parserImports.error) { parserImports.error = e; } - - callback(e, root, importedPreviously, fullPath); - }; - - if (less.Parser.importer) { - less.Parser.importer(path, currentFileInfo, fileParsedFunc, env); - } else { - less.Parser.fileLoader(path, currentFileInfo, function(e, contents, fullPath, newFileInfo) { - if (e) {fileParsedFunc(e); return;} - - var newEnv = new tree.parseEnv(env); - - newEnv.currentFileInfo = newFileInfo; - newEnv.processImports = false; - newEnv.contents[fullPath] = contents; - - if (currentFileInfo.reference || importOptions.reference) { - newFileInfo.reference = true; - } - - if (importOptions.inline) { - fileParsedFunc(null, contents, fullPath); - } else { - new(less.Parser)(newEnv).parse(contents, function (e, root) { - fileParsedFunc(e, root, fullPath); - }); - } - }, env); - } - } - }; - - function save() { currentPos = i; saveStack.push( { current: current, i: i, j: j }); } - function restore() { var state = saveStack.pop(); current = state.current; currentPos = i = state.i; j = state.j; } - function forget() { saveStack.pop(); } - - function sync() { - if (i > currentPos) { - current = current.slice(i - currentPos); - currentPos = i; - } - } - function isWhitespace(str, pos) { - var code = str.charCodeAt(pos | 0); - return (code <= 32) && (code === 32 || code === 10 || code === 9); - } - // - // Parse from a token, regexp or string, and move forward if match - // - function $(tok) { - var tokType = typeof tok, - match, length; - - // Either match a single character in the input, - // or match a regexp in the current chunk (`current`). - // - if (tokType === "string") { - if (input.charAt(i) !== tok) { - return null; - } - skipWhitespace(1); - return tok; - } - - // regexp - sync (); - if (! (match = tok.exec(current))) { - return null; - } - - length = match[0].length; - - // The match is confirmed, add the match length to `i`, - // and consume any extra white-space characters (' ' || '\n') - // which come after that. The reason for this is that LeSS's - // grammar is mostly white-space insensitive. - // - skipWhitespace(length); - - if(typeof(match) === 'string') { - return match; - } else { - return match.length === 1 ? match[0] : match; - } - } - - // Specialization of $(tok) - function $re(tok) { - if (i > currentPos) { - current = current.slice(i - currentPos); - currentPos = i; - } - var m = tok.exec(current); - if (!m) { - return null; - } - - skipWhitespace(m[0].length); - if(typeof m === "string") { - return m; - } - - return m.length === 1 ? m[0] : m; - } - - var _$re = $re; - - // Specialization of $(tok) - function $char(tok) { - if (input.charAt(i) !== tok) { - return null; - } - skipWhitespace(1); - return tok; - } - - function skipWhitespace(length) { - var oldi = i, oldj = j, - curr = i - currentPos, - endIndex = i + current.length - curr, - mem = (i += length), - inp = input, - c; - - for (; i < endIndex; i++) { - c = inp.charCodeAt(i); - if (c > 32) { - break; - } - - if ((c !== 32) && (c !== 10) && (c !== 9) && (c !== 13)) { - break; - } - } - - current = current.slice(length + i - mem + curr); - currentPos = i; - - if (!current.length && (j < chunks.length - 1)) { - current = chunks[++j]; - skipWhitespace(0); // skip space at the beginning of a chunk - return true; // things changed - } - - return oldi !== i || oldj !== j; - } - - function expect(arg, msg) { - // some older browsers return typeof 'function' for RegExp - var result = (Object.prototype.toString.call(arg) === '[object Function]') ? arg.call(parsers) : $(arg); - if (result) { - return result; - } - error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'" - : "unexpected token")); - } - - // Specialization of expect() - function expectChar(arg, msg) { - if (input.charAt(i) === arg) { - skipWhitespace(1); - return arg; - } - error(msg || "expected '" + arg + "' got '" + input.charAt(i) + "'"); - } - - function error(msg, type) { - var e = new Error(msg); - e.index = i; - e.type = type || 'Syntax'; - throw e; - } - - // Same as $(), but don't change the state of the parser, - // just return the match. - function peek(tok) { - if (typeof(tok) === 'string') { - return input.charAt(i) === tok; - } else { - return tok.test(current); - } - } - - // Specialization of peek() - function peekChar(tok) { - return input.charAt(i) === tok; - } - - - function getInput(e, env) { - if (e.filename && env.currentFileInfo.filename && (e.filename !== env.currentFileInfo.filename)) { - return parser.imports.contents[e.filename]; - } else { - return input; - } - } - - function getLocation(index, inputStream) { - var n = index + 1, - line = null, - column = -1; - - while (--n >= 0 && inputStream.charAt(n) !== '\n') { - column++; - } - - if (typeof index === 'number') { - line = (inputStream.slice(0, index).match(/\n/g) || "").length; - } - - return { - line: line, - column: column - }; - } - - function getDebugInfo(index, inputStream, env) { - var filename = env.currentFileInfo.filename; - if(less.mode !== 'browser' && less.mode !== 'rhino') { - filename = require('path').resolve(filename); - } - - return { - lineNumber: getLocation(index, inputStream).line + 1, - fileName: filename - }; - } - - function LessError(e, env) { - var input = getInput(e, env), - loc = getLocation(e.index, input), - line = loc.line, - col = loc.column, - callLine = e.call && getLocation(e.call, input).line, - lines = input.split('\n'); - - this.type = e.type || 'Syntax'; - this.message = e.message; - this.filename = e.filename || env.currentFileInfo.filename; - this.index = e.index; - this.line = typeof(line) === 'number' ? line + 1 : null; - this.callLine = callLine + 1; - this.callExtract = lines[callLine]; - this.stack = e.stack; - this.column = col; - this.extract = [ - lines[line - 1], - lines[line], - lines[line + 1] - ]; - } - - LessError.prototype = new Error(); - LessError.prototype.constructor = LessError; - - this.env = env = env || {}; - - // The optimization level dictates the thoroughness of the parser, - // the lower the number, the less nodes it will create in the tree. - // This could matter for debugging, or if you want to access - // the individual nodes in the tree. - this.optimization = ('optimization' in this.env) ? this.env.optimization : 1; - - // - // The Parser - // - parser = { - - imports: imports, - // - // Parse an input string into an abstract syntax tree, - // @param str A string containing 'less' markup - // @param callback call `callback` when done. - // @param [additionalData] An optional map which can contains vars - a map (key, value) of variables to apply - // - parse: function (str, callback, additionalData) { - var root, line, lines, error = null, globalVars, modifyVars, preText = ""; - - i = j = currentPos = furthest = 0; - - globalVars = (additionalData && additionalData.globalVars) ? less.Parser.serializeVars(additionalData.globalVars) + '\n' : ''; - modifyVars = (additionalData && additionalData.modifyVars) ? '\n' + less.Parser.serializeVars(additionalData.modifyVars) : ''; - - if (globalVars || (additionalData && additionalData.banner)) { - preText = ((additionalData && additionalData.banner) ? additionalData.banner : "") + globalVars; - parser.imports.contentsIgnoredChars[env.currentFileInfo.filename] = preText.length; - } - - str = str.replace(/\r\n/g, '\n'); - // Remove potential UTF Byte Order Mark - input = str = preText + str.replace(/^\uFEFF/, '') + modifyVars; - parser.imports.contents[env.currentFileInfo.filename] = str; - - // Split the input into chunks. - chunks = (function (input) { - var len = input.length, level = 0, parenLevel = 0, - lastOpening, lastOpeningParen, lastMultiComment, lastMultiCommentEndBrace, - chunks = [], emitFrom = 0, - parserCurrentIndex, currentChunkStartIndex, cc, cc2, matched; - - function fail(msg, index) { - error = new(LessError)({ - index: index || parserCurrentIndex, - type: 'Parse', - message: msg, - filename: env.currentFileInfo.filename - }, env); - } - - function emitChunk(force) { - var len = parserCurrentIndex - emitFrom; - if (((len < 512) && !force) || !len) { - return; - } - chunks.push(input.slice(emitFrom, parserCurrentIndex + 1)); - emitFrom = parserCurrentIndex + 1; - } - - for (parserCurrentIndex = 0; parserCurrentIndex < len; parserCurrentIndex++) { - cc = input.charCodeAt(parserCurrentIndex); - if (((cc >= 97) && (cc <= 122)) || (cc < 34)) { - // a-z or whitespace - continue; - } - - switch (cc) { - case 40: // ( - parenLevel++; - lastOpeningParen = parserCurrentIndex; - continue; - case 41: // ) - if (--parenLevel < 0) { - return fail("missing opening `(`"); - } - continue; - case 59: // ; - if (!parenLevel) { emitChunk(); } - continue; - case 123: // { - level++; - lastOpening = parserCurrentIndex; - continue; - case 125: // } - if (--level < 0) { - return fail("missing opening `{`"); - } - if (!level && !parenLevel) { emitChunk(); } - continue; - case 92: // \ - if (parserCurrentIndex < len - 1) { parserCurrentIndex++; continue; } - return fail("unescaped `\\`"); - case 34: - case 39: - case 96: // ", ' and ` - matched = 0; - currentChunkStartIndex = parserCurrentIndex; - for (parserCurrentIndex = parserCurrentIndex + 1; parserCurrentIndex < len; parserCurrentIndex++) { - cc2 = input.charCodeAt(parserCurrentIndex); - if (cc2 > 96) { continue; } - if (cc2 == cc) { matched = 1; break; } - if (cc2 == 92) { // \ - if (parserCurrentIndex == len - 1) { - return fail("unescaped `\\`"); - } - parserCurrentIndex++; - } - } - if (matched) { continue; } - return fail("unmatched `" + String.fromCharCode(cc) + "`", currentChunkStartIndex); - case 47: // /, check for comment - if (parenLevel || (parserCurrentIndex == len - 1)) { continue; } - cc2 = input.charCodeAt(parserCurrentIndex + 1); - if (cc2 == 47) { - // //, find lnfeed - for (parserCurrentIndex = parserCurrentIndex + 2; parserCurrentIndex < len; parserCurrentIndex++) { - cc2 = input.charCodeAt(parserCurrentIndex); - if ((cc2 <= 13) && ((cc2 == 10) || (cc2 == 13))) { break; } - } - } else if (cc2 == 42) { - // /*, find */ - lastMultiComment = currentChunkStartIndex = parserCurrentIndex; - for (parserCurrentIndex = parserCurrentIndex + 2; parserCurrentIndex < len - 1; parserCurrentIndex++) { - cc2 = input.charCodeAt(parserCurrentIndex); - if (cc2 == 125) { lastMultiCommentEndBrace = parserCurrentIndex; } - if (cc2 != 42) { continue; } - if (input.charCodeAt(parserCurrentIndex + 1) == 47) { break; } - } - if (parserCurrentIndex == len - 1) { - return fail("missing closing `*/`", currentChunkStartIndex); - } - parserCurrentIndex++; - } - continue; - case 42: // *, check for unmatched */ - if ((parserCurrentIndex < len - 1) && (input.charCodeAt(parserCurrentIndex + 1) == 47)) { - return fail("unmatched `/*`"); - } - continue; - } - } - - if (level !== 0) { - if ((lastMultiComment > lastOpening) && (lastMultiCommentEndBrace > lastMultiComment)) { - return fail("missing closing `}` or `*/`", lastOpening); - } else { - return fail("missing closing `}`", lastOpening); - } - } else if (parenLevel !== 0) { - return fail("missing closing `)`", lastOpeningParen); - } - - emitChunk(true); - return chunks; - })(str); - - if (error) { - return callback(new(LessError)(error, env)); - } - - current = chunks[0]; - - // Start with the primary rule. - // The whole syntax tree is held under a Ruleset node, - // with the `root` property set to true, so no `{}` are - // output. The callback is called when the input is parsed. - try { - root = new(tree.Ruleset)(null, this.parsers.primary()); - root.root = true; - root.firstRoot = true; - } catch (e) { - return callback(new(LessError)(e, env)); - } - - root.toCSS = (function (evaluate) { - return function (options, variables) { - options = options || {}; - var evaldRoot, - css, - evalEnv = new tree.evalEnv(options); - - // - // Allows setting variables with a hash, so: - // - // `{ color: new(tree.Color)('#f01') }` will become: - // - // new(tree.Rule)('@color', - // new(tree.Value)([ - // new(tree.Expression)([ - // new(tree.Color)('#f01') - // ]) - // ]) - // ) - // - if (typeof(variables) === 'object' && !Array.isArray(variables)) { - variables = Object.keys(variables).map(function (k) { - var value = variables[k]; - - if (! (value instanceof tree.Value)) { - if (! (value instanceof tree.Expression)) { - value = new(tree.Expression)([value]); - } - value = new(tree.Value)([value]); - } - return new(tree.Rule)('@' + k, value, false, null, 0); - }); - evalEnv.frames = [new(tree.Ruleset)(null, variables)]; - } - - try { - var preEvalVisitors = [], - visitors = [ - new(tree.joinSelectorVisitor)(), - new(tree.processExtendsVisitor)(), - new(tree.toCSSVisitor)({compress: Boolean(options.compress)}) - ], i, root = this; - - if (options.plugins) { - for(i =0; i < options.plugins.length; i++) { - if (options.plugins[i].isPreEvalVisitor) { - preEvalVisitors.push(options.plugins[i]); - } else { - if (options.plugins[i].isPreVisitor) { - visitors.splice(0, 0, options.plugins[i]); - } else { - visitors.push(options.plugins[i]); - } - } - } - } - - for(i = 0; i < preEvalVisitors.length; i++) { - preEvalVisitors[i].run(root); - } - - evaldRoot = evaluate.call(root, evalEnv); - - for(i = 0; i < visitors.length; i++) { - visitors[i].run(evaldRoot); - } - - if (options.sourceMap) { - evaldRoot = new tree.sourceMapOutput( - { - contentsIgnoredCharsMap: parser.imports.contentsIgnoredChars, - writeSourceMap: options.writeSourceMap, - rootNode: evaldRoot, - contentsMap: parser.imports.contents, - sourceMapFilename: options.sourceMapFilename, - sourceMapURL: options.sourceMapURL, - outputFilename: options.sourceMapOutputFilename, - sourceMapBasepath: options.sourceMapBasepath, - sourceMapRootpath: options.sourceMapRootpath, - outputSourceFiles: options.outputSourceFiles, - sourceMapGenerator: options.sourceMapGenerator - }); - } - - css = evaldRoot.toCSS({ - compress: Boolean(options.compress), - dumpLineNumbers: env.dumpLineNumbers, - strictUnits: Boolean(options.strictUnits), - numPrecision: 8}); - } catch (e) { - throw new(LessError)(e, env); - } - - if (options.cleancss && less.mode === 'node') { - var CleanCSS = require('clean-css'), - cleancssOptions = options.cleancssOptions || {}; - - if (cleancssOptions.keepSpecialComments === undefined) { - cleancssOptions.keepSpecialComments = "*"; - } - cleancssOptions.processImport = false; - cleancssOptions.noRebase = true; - if (cleancssOptions.noAdvanced === undefined) { - cleancssOptions.noAdvanced = true; - } - - return new CleanCSS(cleancssOptions).minify(css); - } else if (options.compress) { - return css.replace(/(^(\s)+)|((\s)+$)/g, ""); - } else { - return css; - } - }; - })(root.eval); - - // If `i` is smaller than the `input.length - 1`, - // it means the parser wasn't able to parse the whole - // string, so we've got a parsing error. - // - // We try to extract a \n delimited string, - // showing the line where the parse error occured. - // We split it up into two parts (the part which parsed, - // and the part which didn't), so we can color them differently. - if (i < input.length - 1) { - i = furthest; - var loc = getLocation(i, input); - lines = input.split('\n'); - line = loc.line + 1; - - error = { - type: "Parse", - message: "Unrecognised input", - index: i, - filename: env.currentFileInfo.filename, - line: line, - column: loc.column, - extract: [ - lines[line - 2], - lines[line - 1], - lines[line] - ] - }; - } - - var finish = function (e) { - e = error || e || parser.imports.error; - - if (e) { - if (!(e instanceof LessError)) { - e = new(LessError)(e, env); - } - - return callback(e); - } - else { - return callback(null, root); - } - }; - - if (env.processImports !== false) { - new tree.importVisitor(this.imports, finish) - .run(root); - } else { - return finish(); - } - }, - - // - // Here in, the parsing rules/functions - // - // The basic structure of the syntax tree generated is as follows: - // - // Ruleset -> Rule -> Value -> Expression -> Entity - // - // Here's some Less code: - // - // .class { - // color: #fff; - // border: 1px solid #000; - // width: @w + 4px; - // > .child {...} - // } - // - // And here's what the parse tree might look like: - // - // Ruleset (Selector '.class', [ - // Rule ("color", Value ([Expression [Color #fff]])) - // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]])) - // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]])) - // Ruleset (Selector [Element '>', '.child'], [...]) - // ]) - // - // In general, most rules will try to parse a token with the `$()` function, and if the return - // value is truly, will return a new node, of the relevant type. Sometimes, we need to check - // first, before parsing, that's when we use `peek()`. - // - parsers: parsers = { - // - // The `primary` rule is the *entry* and *exit* point of the parser. - // The rules here can appear at any level of the parse tree. - // - // The recursive nature of the grammar is an interplay between the `block` - // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule, - // as represented by this simplified grammar: - // - // primary → (ruleset | rule)+ - // ruleset → selector+ block - // block → '{' primary '}' - // - // Only at one point is the primary rule not called from the - // block rule: at the root level. - // - primary: function () { - var mixin = this.mixin, $re = _$re, root = [], node; - - while (current) - { - node = this.extendRule() || mixin.definition() || this.rule() || this.ruleset() || - mixin.call() || this.comment() || this.rulesetCall() || this.directive(); - if (node) { - root.push(node); - } else { - if (!($re(/^[\s\n]+/) || $re(/^;+/))) { - break; - } - } - if (peekChar('}')) { - break; - } - } - - return root; - }, - - // We create a Comment node for CSS comments `/* */`, - // but keep the LeSS comments `//` silent, by just skipping - // over them. - comment: function () { - var comment; - - if (input.charAt(i) !== '/') { return; } - - if (input.charAt(i + 1) === '/') { - return new(tree.Comment)($re(/^\/\/.*/), true, i, env.currentFileInfo); - } - comment = $re(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/); - if (comment) { - return new(tree.Comment)(comment, false, i, env.currentFileInfo); - } - }, - - comments: function () { - var comment, comments = []; - - while(true) { - comment = this.comment(); - if (!comment) { - break; - } - comments.push(comment); - } - - return comments; - }, - - // - // Entities are tokens which can be found inside an Expression - // - entities: { - // - // A string, which supports escaping " and ' - // - // "milky way" 'he\'s the one!' - // - quoted: function () { - var str, j = i, e, index = i; - - if (input.charAt(j) === '~') { j++; e = true; } // Escaped strings - if (input.charAt(j) !== '"' && input.charAt(j) !== "'") { return; } - - if (e) { $char('~'); } - - str = $re(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/); - if (str) { - return new(tree.Quoted)(str[0], str[1] || str[2], e, index, env.currentFileInfo); - } - }, - - // - // A catch-all word, such as: - // - // black border-collapse - // - keyword: function () { - var k; - - k = $re(/^%|^[_A-Za-z-][_A-Za-z0-9-]*/); - if (k) { - var color = tree.Color.fromKeyword(k); - if (color) { - return color; - } - return new(tree.Keyword)(k); - } - }, - - // - // A function call - // - // rgb(255, 0, 255) - // - // We also try to catch IE's `alpha()`, but let the `alpha` parser - // deal with the details. - // - // The arguments are parsed with the `entities.arguments` parser. - // - call: function () { - var name, nameLC, args, alpha_ret, index = i; - - name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(current); - if (!name) { return; } - - name = name[1]; - nameLC = name.toLowerCase(); - if (nameLC === 'url') { - return null; - } - - i += name.length; - - if (nameLC === 'alpha') { - alpha_ret = parsers.alpha(); - if(typeof alpha_ret !== 'undefined') { - return alpha_ret; - } - } - - $char('('); // Parse the '(' and consume whitespace. - - args = this.arguments(); - - if (! $char(')')) { - return; - } - - if (name) { return new(tree.Call)(name, args, index, env.currentFileInfo); } - }, - arguments: function () { - var args = [], arg; - - while (true) { - arg = this.assignment() || parsers.expression(); - if (!arg) { - break; - } - args.push(arg); - if (! $char(',')) { - break; - } - } - return args; - }, - literal: function () { - return this.dimension() || - this.color() || - this.quoted() || - this.unicodeDescriptor(); - }, - - // Assignments are argument entities for calls. - // They are present in ie filter properties as shown below. - // - // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* ) - // - - assignment: function () { - var key, value; - key = $re(/^\w+(?=\s?=)/i); - if (!key) { - return; - } - if (!$char('=')) { - return; - } - value = parsers.entity(); - if (value) { - return new(tree.Assignment)(key, value); - } - }, - - // - // Parse url() tokens - // - // We use a specific rule for urls, because they don't really behave like - // standard function calls. The difference is that the argument doesn't have - // to be enclosed within a string, so it can't be parsed as an Expression. - // - url: function () { - var value; - - if (input.charAt(i) !== 'u' || !$re(/^url\(/)) { - return; - } - - value = this.quoted() || this.variable() || - $re(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || ""; - - expectChar(')'); - - return new(tree.URL)((value.value != null || value instanceof tree.Variable) - ? value : new(tree.Anonymous)(value), env.currentFileInfo); - }, - - // - // A Variable entity, such as `@fink`, in - // - // width: @fink + 2px - // - // We use a different parser for variable definitions, - // see `parsers.variable`. - // - variable: function () { - var name, index = i; - - if (input.charAt(i) === '@' && (name = $re(/^@@?[\w-]+/))) { - return new(tree.Variable)(name, index, env.currentFileInfo); - } - }, - - // A variable entity useing the protective {} e.g. @{var} - variableCurly: function () { - var curly, index = i; - - if (input.charAt(i) === '@' && (curly = $re(/^@\{([\w-]+)\}/))) { - return new(tree.Variable)("@" + curly[1], index, env.currentFileInfo); - } - }, - - // - // A Hexadecimal color - // - // #4F3C2F - // - // `rgb` and `hsl` colors are parsed through the `entities.call` parser. - // - color: function () { - var rgb; - - if (input.charAt(i) === '#' && (rgb = $re(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/))) { - var colorCandidateString = rgb.input.match(/^#([\w]+).*/); // strip colons, brackets, whitespaces and other characters that should not definitely be part of color string - colorCandidateString = colorCandidateString[1]; - if (!colorCandidateString.match(/^[A-Fa-f0-9]+$/)) { // verify if candidate consists only of allowed HEX characters - error("Invalid HEX color code"); - } - return new(tree.Color)(rgb[1]); - } - }, - - // - // A Dimension, that is, a number and a unit - // - // 0.5em 95% - // - dimension: function () { - var value, c = input.charCodeAt(i); - //Is the first char of the dimension 0-9, '.', '+' or '-' - if ((c > 57 || c < 43) || c === 47 || c == 44) { - return; - } - - value = $re(/^([+-]?\d*\.?\d+)(%|[a-z]+)?/); - if (value) { - return new(tree.Dimension)(value[1], value[2]); - } - }, - - // - // A unicode descriptor, as is used in unicode-range - // - // U+0?? or U+00A1-00A9 - // - unicodeDescriptor: function () { - var ud; - - ud = $re(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/); - if (ud) { - return new(tree.UnicodeDescriptor)(ud[0]); - } - }, - - // - // JavaScript code to be evaluated - // - // `window.location.href` - // - javascript: function () { - var str, j = i, e; - - if (input.charAt(j) === '~') { j++; e = true; } // Escaped strings - if (input.charAt(j) !== '`') { return; } - if (env.javascriptEnabled !== undefined && !env.javascriptEnabled) { - error("You are using JavaScript, which has been disabled."); - } - - if (e) { $char('~'); } - - str = $re(/^`([^`]*)`/); - if (str) { - return new(tree.JavaScript)(str[1], i, e); - } - } - }, - - // - // The variable part of a variable definition. Used in the `rule` parser - // - // @fink: - // - variable: function () { - var name; - - if (input.charAt(i) === '@' && (name = $re(/^(@[\w-]+)\s*:/))) { return name[1]; } - }, - - // - // The variable part of a variable definition. Used in the `rule` parser - // - // @fink(); - // - rulesetCall: function () { - var name; - - if (input.charAt(i) === '@' && (name = $re(/^(@[\w-]+)\s*\(\s*\)\s*;/))) { - return new tree.RulesetCall(name[1]); - } - }, - - // - // extend syntax - used to extend selectors - // - extend: function(isRule) { - var elements, e, index = i, option, extendList, extend; - - if (!(isRule ? $re(/^&:extend\(/) : $re(/^:extend\(/))) { return; } - - do { - option = null; - elements = null; - while (! (option = $re(/^(all)(?=\s*(\)|,))/))) { - e = this.element(); - if (!e) { break; } - if (elements) { elements.push(e); } else { elements = [ e ]; } - } - - option = option && option[1]; - - extend = new(tree.Extend)(new(tree.Selector)(elements), option, index); - if (extendList) { extendList.push(extend); } else { extendList = [ extend ]; } - - } while($char(",")); - - expect(/^\)/); - - if (isRule) { - expect(/^;/); - } - - return extendList; - }, - - // - // extendRule - used in a rule to extend all the parent selectors - // - extendRule: function() { - return this.extend(true); - }, - - // - // Mixins - // - mixin: { - // - // A Mixin call, with an optional argument list - // - // #mixins > .square(#fff); - // .rounded(4px, black); - // .button; - // - // The `while` loop is there because mixins can be - // namespaced, but we only support the child and descendant - // selector for now. - // - call: function () { - var s = input.charAt(i), important = false, index = i, elemIndex, - elements, elem, e, c, args; - - if (s !== '.' && s !== '#') { return; } - - save(); // stop us absorbing part of an invalid selector - - while (true) { - elemIndex = i; - e = $re(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/); - if (!e) { - break; - } - elem = new(tree.Element)(c, e, elemIndex, env.currentFileInfo); - if (elements) { elements.push(elem); } else { elements = [ elem ]; } - c = $char('>'); - } - - if (elements) { - if ($char('(')) { - args = this.args(true).args; - expectChar(')'); - } - - if (parsers.important()) { - important = true; - } - - if (parsers.end()) { - forget(); - return new(tree.mixin.Call)(elements, args, index, env.currentFileInfo, important); - } - } - - restore(); - }, - args: function (isCall) { - var parsers = parser.parsers, entities = parsers.entities, - returner = { args:null, variadic: false }, - expressions = [], argsSemiColon = [], argsComma = [], - isSemiColonSeperated, expressionContainsNamed, name, nameLoop, value, arg; - - save(); - - while (true) { - if (isCall) { - arg = parsers.detachedRuleset() || parsers.expression(); - } else { - parsers.comments(); - if (input.charAt(i) === '.' && $re(/^\.{3}/)) { - returner.variadic = true; - if ($char(";") && !isSemiColonSeperated) { - isSemiColonSeperated = true; - } - (isSemiColonSeperated ? argsSemiColon : argsComma) - .push({ variadic: true }); - break; - } - arg = entities.variable() || entities.literal() || entities.keyword(); - } - - if (!arg) { - break; - } - - nameLoop = null; - if (arg.throwAwayComments) { - arg.throwAwayComments(); - } - value = arg; - var val = null; - - if (isCall) { - // Variable - if (arg.value && arg.value.length == 1) { - val = arg.value[0]; - } - } else { - val = arg; - } - - if (val && val instanceof tree.Variable) { - if ($char(':')) { - if (expressions.length > 0) { - if (isSemiColonSeperated) { - error("Cannot mix ; and , as delimiter types"); - } - expressionContainsNamed = true; - } - - // we do not support setting a ruleset as a default variable - it doesn't make sense - // However if we do want to add it, there is nothing blocking it, just don't error - // and remove isCall dependency below - value = (isCall && parsers.detachedRuleset()) || parsers.expression(); - - if (!value) { - if (isCall) { - error("could not understand value for named argument"); - } else { - restore(); - returner.args = []; - return returner; - } - } - nameLoop = (name = val.name); - } else if (!isCall && $re(/^\.{3}/)) { - returner.variadic = true; - if ($char(";") && !isSemiColonSeperated) { - isSemiColonSeperated = true; - } - (isSemiColonSeperated ? argsSemiColon : argsComma) - .push({ name: arg.name, variadic: true }); - break; - } else if (!isCall) { - name = nameLoop = val.name; - value = null; - } - } - - if (value) { - expressions.push(value); - } - - argsComma.push({ name:nameLoop, value:value }); - - if ($char(',')) { - continue; - } - - if ($char(';') || isSemiColonSeperated) { - - if (expressionContainsNamed) { - error("Cannot mix ; and , as delimiter types"); - } - - isSemiColonSeperated = true; - - if (expressions.length > 1) { - value = new(tree.Value)(expressions); - } - argsSemiColon.push({ name:name, value:value }); - - name = null; - expressions = []; - expressionContainsNamed = false; - } - } - - forget(); - returner.args = isSemiColonSeperated ? argsSemiColon : argsComma; - return returner; - }, - // - // A Mixin definition, with a list of parameters - // - // .rounded (@radius: 2px, @color) { - // ... - // } - // - // Until we have a finer grained state-machine, we have to - // do a look-ahead, to make sure we don't have a mixin call. - // See the `rule` function for more information. - // - // We start by matching `.rounded (`, and then proceed on to - // the argument list, which has optional default values. - // We store the parameters in `params`, with a `value` key, - // if there is a value, such as in the case of `@radius`. - // - // Once we've got our params list, and a closing `)`, we parse - // the `{...}` block. - // - definition: function () { - var name, params = [], match, ruleset, cond, variadic = false; - if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') || - peek(/^[^{]*\}/)) { - return; - } - - save(); - - match = $re(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/); - if (match) { - name = match[1]; - - var argInfo = this.args(false); - params = argInfo.args; - variadic = argInfo.variadic; - - // .mixincall("@{a}"); - // looks a bit like a mixin definition.. - // also - // .mixincall(@a: {rule: set;}); - // so we have to be nice and restore - if (!$char(')')) { - furthest = i; - restore(); - return; - } - - parsers.comments(); - - if ($re(/^when/)) { // Guard - cond = expect(parsers.conditions, 'expected condition'); - } - - ruleset = parsers.block(); - - if (ruleset) { - forget(); - return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic); - } else { - restore(); - } - } else { - forget(); - } - } - }, - - // - // Entities are the smallest recognized token, - // and can be found inside a rule's value. - // - entity: function () { - var entities = this.entities; - - return entities.literal() || entities.variable() || entities.url() || - entities.call() || entities.keyword() || entities.javascript() || - this.comment(); - }, - - // - // A Rule terminator. Note that we use `peek()` to check for '}', - // because the `block` rule will be expecting it, but we still need to make sure - // it's there, if ';' was ommitted. - // - end: function () { - return $char(';') || peekChar('}'); - }, - - // - // IE's alpha function - // - // alpha(opacity=88) - // - alpha: function () { - var value; - - if (! $re(/^\(opacity=/i)) { return; } - value = $re(/^\d+/) || this.entities.variable(); - if (value) { - expectChar(')'); - return new(tree.Alpha)(value); - } - }, - - // - // A Selector Element - // - // div - // + h1 - // #socks - // input[type="text"] - // - // Elements are the building blocks for Selectors, - // they are made out of a `Combinator` (see combinator rule), - // and an element name, such as a tag a class, or `*`. - // - element: function () { - var e, c, v, index = i; - - c = this.combinator(); - - e = $re(/^(?:\d+\.\d+|\d+)%/) || $re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) || - $char('*') || $char('&') || this.attribute() || $re(/^\([^()@]+\)/) || $re(/^[\.#](?=@)/) || - this.entities.variableCurly(); - - if (! e) { - save(); - if ($char('(')) { - if ((v = this.selector()) && $char(')')) { - e = new(tree.Paren)(v); - forget(); - } else { - restore(); - } - } else { - forget(); - } - } - - if (e) { return new(tree.Element)(c, e, index, env.currentFileInfo); } - }, - - // - // Combinators combine elements together, in a Selector. - // - // Because our parser isn't white-space sensitive, special care - // has to be taken, when parsing the descendant combinator, ` `, - // as it's an empty space. We have to check the previous character - // in the input, to see if it's a ` ` character. More info on how - // we deal with this in *combinator.js*. - // - combinator: function () { - var c = input.charAt(i); - - if (c === '>' || c === '+' || c === '~' || c === '|' || c === '^') { - i++; - if (input.charAt(i) === '^') { - c = '^^'; - i++; - } - while (isWhitespace(input, i)) { i++; } - return new(tree.Combinator)(c); - } else if (isWhitespace(input, i - 1)) { - return new(tree.Combinator)(" "); - } else { - return new(tree.Combinator)(null); - } - }, - // - // A CSS selector (see selector below) - // with less extensions e.g. the ability to extend and guard - // - lessSelector: function () { - return this.selector(true); - }, - // - // A CSS Selector - // - // .class > div + h1 - // li a:hover - // - // Selectors are made out of one or more Elements, see above. - // - selector: function (isLess) { - var index = i, $re = _$re, elements, extendList, c, e, extend, when, condition; - - while ((isLess && (extend = this.extend())) || (isLess && (when = $re(/^when/))) || (e = this.element())) { - if (when) { - condition = expect(this.conditions, 'expected condition'); - } else if (condition) { - error("CSS guard can only be used at the end of selector"); - } else if (extend) { - if (extendList) { extendList.push(extend); } else { extendList = [ extend ]; } - } else { - if (extendList) { error("Extend can only be used at the end of selector"); } - c = input.charAt(i); - if (elements) { elements.push(e); } else { elements = [ e ]; } - e = null; - } - if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') { - break; - } - } - - if (elements) { return new(tree.Selector)(elements, extendList, condition, index, env.currentFileInfo); } - if (extendList) { error("Extend must be used to extend a selector, it cannot be used on its own"); } - }, - attribute: function () { - if (! $char('[')) { return; } - - var entities = this.entities, - key, val, op; - - if (!(key = entities.variableCurly())) { - key = expect(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/); - } - - op = $re(/^[|~*$^]?=/); - if (op) { - val = entities.quoted() || $re(/^[0-9]+%/) || $re(/^[\w-]+/) || entities.variableCurly(); - } - - expectChar(']'); - - return new(tree.Attribute)(key, op, val); - }, - - // - // The `block` rule is used by `ruleset` and `mixin.definition`. - // It's a wrapper around the `primary` rule, with added `{}`. - // - block: function () { - var content; - if ($char('{') && (content = this.primary()) && $char('}')) { - return content; - } - }, - - blockRuleset: function() { - var block = this.block(); - - if (block) { - block = new tree.Ruleset(null, block); - } - return block; - }, - - detachedRuleset: function() { - var blockRuleset = this.blockRuleset(); - if (blockRuleset) { - return new tree.DetachedRuleset(blockRuleset); - } - }, - - // - // div, .class, body > p {...} - // - ruleset: function () { - var selectors, s, rules, debugInfo; - - save(); - - if (env.dumpLineNumbers) { - debugInfo = getDebugInfo(i, input, env); - } - - while (true) { - s = this.lessSelector(); - if (!s) { - break; - } - if (selectors) { selectors.push(s); } else { selectors = [ s ]; } - this.comments(); - if (s.condition && selectors.length > 1) { - error("Guards are only currently allowed on a single selector."); - } - if (! $char(',')) { break; } - if (s.condition) { - error("Guards are only currently allowed on a single selector."); - } - this.comments(); - } - - if (selectors && (rules = this.block())) { - forget(); - var ruleset = new(tree.Ruleset)(selectors, rules, env.strictImports); - if (env.dumpLineNumbers) { - ruleset.debugInfo = debugInfo; - } - return ruleset; - } else { - // Backtrack - furthest = i; - restore(); - } - }, - rule: function (tryAnonymous) { - var name, value, startOfRule = i, c = input.charAt(startOfRule), important, merge, isVariable; - - if (c === '.' || c === '#' || c === '&') { return; } - - save(); - - name = this.variable() || this.ruleProperty(); - if (name) { - isVariable = typeof name === "string"; - - if (isVariable) { - value = this.detachedRuleset(); - } - - if (!value) { - // prefer to try to parse first if its a variable or we are compressing - // but always fallback on the other one - value = !tryAnonymous && (env.compress || isVariable) ? - (this.value() || this.anonymousValue()) : - (this.anonymousValue() || this.value()); - - important = this.important(); - - // a name returned by this.ruleProperty() is always an array of the form: - // [string-1, ..., string-n, ""] or [string-1, ..., string-n, "+"] - // where each item is a tree.Keyword or tree.Variable - merge = !isVariable && name.pop().value; - } - - if (value && this.end()) { - forget(); - return new (tree.Rule)(name, value, important, merge, startOfRule, env.currentFileInfo); - } else { - furthest = i; - restore(); - if (value && !tryAnonymous) { - return this.rule(true); - } - } - } else { - forget(); - } - }, - anonymousValue: function () { - var match; - match = /^([^@+\/'"*`(;{}-]*);/.exec(current); - if (match) { - i += match[0].length - 1; - return new(tree.Anonymous)(match[1]); - } - }, - - // - // An @import directive - // - // @import "lib"; - // - // Depending on our environemnt, importing is done differently: - // In the browser, it's an XHR request, in Node, it would be a - // file-system operation. The function used for importing is - // stored in `import`, which we pass to the Import constructor. - // - "import": function () { - var path, features, index = i; - - save(); - - var dir = $re(/^@import?\s+/); - - var options = (dir ? this.importOptions() : null) || {}; - - if (dir && (path = this.entities.quoted() || this.entities.url())) { - features = this.mediaFeatures(); - if ($char(';')) { - forget(); - features = features && new(tree.Value)(features); - return new(tree.Import)(path, features, options, index, env.currentFileInfo); - } - } - - restore(); - }, - - importOptions: function() { - var o, options = {}, optionName, value; - - // list of options, surrounded by parens - if (! $char('(')) { return null; } - do { - o = this.importOption(); - if (o) { - optionName = o; - value = true; - switch(optionName) { - case "css": - optionName = "less"; - value = false; - break; - case "once": - optionName = "multiple"; - value = false; - break; - } - options[optionName] = value; - if (! $char(',')) { break; } - } - } while (o); - expectChar(')'); - return options; - }, - - importOption: function() { - var opt = $re(/^(less|css|multiple|once|inline|reference)/); - if (opt) { - return opt[1]; - } - }, - - mediaFeature: function () { - var entities = this.entities, nodes = [], e, p; - do { - e = entities.keyword() || entities.variable(); - if (e) { - nodes.push(e); - } else if ($char('(')) { - p = this.property(); - e = this.value(); - if ($char(')')) { - if (p && e) { - nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, null, i, env.currentFileInfo, true))); - } else if (e) { - nodes.push(new(tree.Paren)(e)); - } else { - return null; - } - } else { return null; } - } - } while (e); - - if (nodes.length > 0) { - return new(tree.Expression)(nodes); - } - }, - - mediaFeatures: function () { - var entities = this.entities, features = [], e; - do { - e = this.mediaFeature(); - if (e) { - features.push(e); - if (! $char(',')) { break; } - } else { - e = entities.variable(); - if (e) { - features.push(e); - if (! $char(',')) { break; } - } - } - } while (e); - - return features.length > 0 ? features : null; - }, - - media: function () { - var features, rules, media, debugInfo; - - if (env.dumpLineNumbers) { - debugInfo = getDebugInfo(i, input, env); - } - - if ($re(/^@media/)) { - features = this.mediaFeatures(); - - rules = this.block(); - if (rules) { - media = new(tree.Media)(rules, features, i, env.currentFileInfo); - if (env.dumpLineNumbers) { - media.debugInfo = debugInfo; - } - return media; - } - } - }, - - // - // A CSS Directive - // - // @charset "utf-8"; - // - directive: function () { - var index = i, name, value, rules, nonVendorSpecificName, - hasIdentifier, hasExpression, hasUnknown, hasBlock = true; - - if (input.charAt(i) !== '@') { return; } - - value = this['import']() || this.media(); - if (value) { - return value; - } - - save(); - - name = $re(/^@[a-z-]+/); - - if (!name) { return; } - - nonVendorSpecificName = name; - if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) { - nonVendorSpecificName = "@" + name.slice(name.indexOf('-', 2) + 1); - } - - switch(nonVendorSpecificName) { - /* - case "@font-face": - case "@viewport": - case "@top-left": - case "@top-left-corner": - case "@top-center": - case "@top-right": - case "@top-right-corner": - case "@bottom-left": - case "@bottom-left-corner": - case "@bottom-center": - case "@bottom-right": - case "@bottom-right-corner": - case "@left-top": - case "@left-middle": - case "@left-bottom": - case "@right-top": - case "@right-middle": - case "@right-bottom": - hasBlock = true; - break; - */ - case "@charset": - hasIdentifier = true; - hasBlock = false; - break; - case "@namespace": - hasExpression = true; - hasBlock = false; - break; - case "@keyframes": - hasIdentifier = true; - break; - case "@host": - case "@page": - case "@document": - case "@supports": - hasUnknown = true; - break; - } - - if (hasIdentifier) { - value = this.entity(); - if (!value) { - error("expected " + name + " identifier"); - } - } else if (hasExpression) { - value = this.expression(); - if (!value) { - error("expected " + name + " expression"); - } - } else if (hasUnknown) { - value = ($re(/^[^{;]+/) || '').trim(); - if (value) { - value = new(tree.Anonymous)(value); - } - } - - if (hasBlock) { - rules = this.blockRuleset(); - } - - if (rules || (!hasBlock && value && $char(';'))) { - forget(); - return new(tree.Directive)(name, value, rules, index, env.currentFileInfo, - env.dumpLineNumbers ? getDebugInfo(index, input, env) : null); - } - - restore(); - }, - - // - // A Value is a comma-delimited list of Expressions - // - // font-family: Baskerville, Georgia, serif; - // - // In a Rule, a Value represents everything after the `:`, - // and before the `;`. - // - value: function () { - var e, expressions = []; - - do { - e = this.expression(); - if (e) { - expressions.push(e); - if (! $char(',')) { break; } - } - } while(e); - - if (expressions.length > 0) { - return new(tree.Value)(expressions); - } - }, - important: function () { - if (input.charAt(i) === '!') { - return $re(/^! *important/); - } - }, - sub: function () { - var a, e; - - if ($char('(')) { - a = this.addition(); - if (a) { - e = new(tree.Expression)([a]); - expectChar(')'); - e.parens = true; - return e; - } - } - }, - multiplication: function () { - var m, a, op, operation, isSpaced; - m = this.operand(); - if (m) { - isSpaced = isWhitespace(input, i - 1); - while (true) { - if (peek(/^\/[*\/]/)) { - break; - } - op = $char('/') || $char('*'); - - if (!op) { break; } - - a = this.operand(); - - if (!a) { break; } - - m.parensInOp = true; - a.parensInOp = true; - operation = new(tree.Operation)(op, [operation || m, a], isSpaced); - isSpaced = isWhitespace(input, i - 1); - } - return operation || m; - } - }, - addition: function () { - var m, a, op, operation, isSpaced; - m = this.multiplication(); - if (m) { - isSpaced = isWhitespace(input, i - 1); - while (true) { - op = $re(/^[-+]\s+/) || (!isSpaced && ($char('+') || $char('-'))); - if (!op) { - break; - } - a = this.multiplication(); - if (!a) { - break; - } - - m.parensInOp = true; - a.parensInOp = true; - operation = new(tree.Operation)(op, [operation || m, a], isSpaced); - isSpaced = isWhitespace(input, i - 1); - } - return operation || m; - } - }, - conditions: function () { - var a, b, index = i, condition; - - a = this.condition(); - if (a) { - while (true) { - if (!peek(/^,\s*(not\s*)?\(/) || !$char(',')) { - break; - } - b = this.condition(); - if (!b) { - break; - } - condition = new(tree.Condition)('or', condition || a, b, index); - } - return condition || a; - } - }, - condition: function () { - var entities = this.entities, index = i, negate = false, - a, b, c, op; - - if ($re(/^not/)) { negate = true; } - expectChar('('); - a = this.addition() || entities.keyword() || entities.quoted(); - if (a) { - op = $re(/^(?:>=|<=|=<|[<=>])/); - if (op) { - b = this.addition() || entities.keyword() || entities.quoted(); - if (b) { - c = new(tree.Condition)(op, a, b, index, negate); - } else { - error('expected expression'); - } - } else { - c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate); - } - expectChar(')'); - return $re(/^and/) ? new(tree.Condition)('and', c, this.condition()) : c; - } - }, - - // - // An operand is anything that can be part of an operation, - // such as a Color, or a Variable - // - operand: function () { - var entities = this.entities, - p = input.charAt(i + 1), negate; - - if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $char('-'); } - var o = this.sub() || entities.dimension() || - entities.color() || entities.variable() || - entities.call(); - - if (negate) { - o.parensInOp = true; - o = new(tree.Negative)(o); - } - - return o; - }, - - // - // Expressions either represent mathematical operations, - // or white-space delimited Entities. - // - // 1px solid black - // @var * 2 - // - expression: function () { - var entities = [], e, delim; - - do { - e = this.addition() || this.entity(); - if (e) { - entities.push(e); - // operations do not allow keyword "/" dimension (e.g. small/20px) so we support that here - if (!peek(/^\/[\/*]/)) { - delim = $char('/'); - if (delim) { - entities.push(new(tree.Anonymous)(delim)); - } - } - } - } while (e); - if (entities.length > 0) { - return new(tree.Expression)(entities); - } - }, - property: function () { - var name = $re(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/); - if (name) { - return name[1]; - } - }, - ruleProperty: function () { - var c = current, name = [], index = [], length = 0, s, k; - - function match(re) { - var a = re.exec(c); - if (a) { - index.push(i + length); - length += a[0].length; - c = c.slice(a[1].length); - return name.push(a[1]); - } - } - - match(/^(\*?)/); - while (match(/^((?:[\w-]+)|(?:@\{[\w-]+\}))/)); // ! - if ((name.length > 1) && match(/^\s*((?:\+_|\+)?)\s*:/)) { - // at last, we have the complete match now. move forward, - // convert name particles to tree objects and return: - skipWhitespace(length); - if (name[0] === '') { - name.shift(); - index.shift(); - } - for (k = 0; k < name.length; k++) { - s = name[k]; - name[k] = (s.charAt(0) !== '@') - ? new(tree.Keyword)(s) - : new(tree.Variable)('@' + s.slice(2, -1), - index[k], env.currentFileInfo); - } - return name; - } - } - } - }; - return parser; -}; -less.Parser.serializeVars = function(vars) { - var s = ''; - - for (var name in vars) { - if (Object.hasOwnProperty.call(vars, name)) { - var value = vars[name]; - s += ((name[0] === '@') ? '' : '@') + name +': '+ value + - ((('' + value).slice(-1) === ';') ? '' : ';'); - } - } - - return s; -}; - -(function (tree) { - -tree.functions = { - rgb: function (r, g, b) { - return this.rgba(r, g, b, 1.0); - }, - rgba: function (r, g, b, a) { - var rgb = [r, g, b].map(function (c) { return scaled(c, 255); }); - a = number(a); - return new(tree.Color)(rgb, a); - }, - hsl: function (h, s, l) { - return this.hsla(h, s, l, 1.0); - }, - hsla: function (h, s, l, a) { - function hue(h) { - h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h); - if (h * 6 < 1) { return m1 + (m2 - m1) * h * 6; } - else if (h * 2 < 1) { return m2; } - else if (h * 3 < 2) { return m1 + (m2 - m1) * (2/3 - h) * 6; } - else { return m1; } - } - - h = (number(h) % 360) / 360; - s = clamp(number(s)); l = clamp(number(l)); a = clamp(number(a)); - - var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s; - var m1 = l * 2 - m2; - - return this.rgba(hue(h + 1/3) * 255, - hue(h) * 255, - hue(h - 1/3) * 255, - a); - }, - - hsv: function(h, s, v) { - return this.hsva(h, s, v, 1.0); - }, - - hsva: function(h, s, v, a) { - h = ((number(h) % 360) / 360) * 360; - s = number(s); v = number(v); a = number(a); - - var i, f; - i = Math.floor((h / 60) % 6); - f = (h / 60) - i; - - var vs = [v, - v * (1 - s), - v * (1 - f * s), - v * (1 - (1 - f) * s)]; - var perm = [[0, 3, 1], - [2, 0, 1], - [1, 0, 3], - [1, 2, 0], - [3, 1, 0], - [0, 1, 2]]; - - return this.rgba(vs[perm[i][0]] * 255, - vs[perm[i][1]] * 255, - vs[perm[i][2]] * 255, - a); - }, - - hue: function (color) { - return new(tree.Dimension)(Math.round(color.toHSL().h)); - }, - saturation: function (color) { - return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%'); - }, - lightness: function (color) { - return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%'); - }, - hsvhue: function(color) { - return new(tree.Dimension)(Math.round(color.toHSV().h)); - }, - hsvsaturation: function (color) { - return new(tree.Dimension)(Math.round(color.toHSV().s * 100), '%'); - }, - hsvvalue: function (color) { - return new(tree.Dimension)(Math.round(color.toHSV().v * 100), '%'); - }, - red: function (color) { - return new(tree.Dimension)(color.rgb[0]); - }, - green: function (color) { - return new(tree.Dimension)(color.rgb[1]); - }, - blue: function (color) { - return new(tree.Dimension)(color.rgb[2]); - }, - alpha: function (color) { - return new(tree.Dimension)(color.toHSL().a); - }, - luma: function (color) { - return new(tree.Dimension)(Math.round(color.luma() * color.alpha * 100), '%'); - }, - luminance: function (color) { - var luminance = - (0.2126 * color.rgb[0] / 255) - + (0.7152 * color.rgb[1] / 255) - + (0.0722 * color.rgb[2] / 255); - - return new(tree.Dimension)(Math.round(luminance * color.alpha * 100), '%'); - }, - saturate: function (color, amount) { - // filter: saturate(3.2); - // should be kept as is, so check for color - if (!color.rgb) { - return null; - } - var hsl = color.toHSL(); - - hsl.s += amount.value / 100; - hsl.s = clamp(hsl.s); - return hsla(hsl); - }, - desaturate: function (color, amount) { - var hsl = color.toHSL(); - - hsl.s -= amount.value / 100; - hsl.s = clamp(hsl.s); - return hsla(hsl); - }, - lighten: function (color, amount) { - var hsl = color.toHSL(); - - hsl.l += amount.value / 100; - hsl.l = clamp(hsl.l); - return hsla(hsl); - }, - darken: function (color, amount) { - var hsl = color.toHSL(); - - hsl.l -= amount.value / 100; - hsl.l = clamp(hsl.l); - return hsla(hsl); - }, - fadein: function (color, amount) { - var hsl = color.toHSL(); - - hsl.a += amount.value / 100; - hsl.a = clamp(hsl.a); - return hsla(hsl); - }, - fadeout: function (color, amount) { - var hsl = color.toHSL(); - - hsl.a -= amount.value / 100; - hsl.a = clamp(hsl.a); - return hsla(hsl); - }, - fade: function (color, amount) { - var hsl = color.toHSL(); - - hsl.a = amount.value / 100; - hsl.a = clamp(hsl.a); - return hsla(hsl); - }, - spin: function (color, amount) { - var hsl = color.toHSL(); - var hue = (hsl.h + amount.value) % 360; - - hsl.h = hue < 0 ? 360 + hue : hue; - - return hsla(hsl); - }, - // - // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein - // http://sass-lang.com - // - mix: function (color1, color2, weight) { - if (!weight) { - weight = new(tree.Dimension)(50); - } - var p = weight.value / 100.0; - var w = p * 2 - 1; - var a = color1.toHSL().a - color2.toHSL().a; - - var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0; - var w2 = 1 - w1; - - var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2, - color1.rgb[1] * w1 + color2.rgb[1] * w2, - color1.rgb[2] * w1 + color2.rgb[2] * w2]; - - var alpha = color1.alpha * p + color2.alpha * (1 - p); - - return new(tree.Color)(rgb, alpha); - }, - greyscale: function (color) { - return this.desaturate(color, new(tree.Dimension)(100)); - }, - contrast: function (color, dark, light, threshold) { - // filter: contrast(3.2); - // should be kept as is, so check for color - if (!color.rgb) { - return null; - } - if (typeof light === 'undefined') { - light = this.rgba(255, 255, 255, 1.0); - } - if (typeof dark === 'undefined') { - dark = this.rgba(0, 0, 0, 1.0); - } - //Figure out which is actually light and dark! - if (dark.luma() > light.luma()) { - var t = light; - light = dark; - dark = t; - } - if (typeof threshold === 'undefined') { - threshold = 0.43; - } else { - threshold = number(threshold); - } - if (color.luma() < threshold) { - return light; - } else { - return dark; - } - }, - e: function (str) { - return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str.value); - }, - escape: function (str) { - return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29")); - }, - replace: function (string, pattern, replacement, flags) { - var result = string.value; - - result = result.replace(new RegExp(pattern.value, flags ? flags.value : ''), replacement.value); - return new(tree.Quoted)(string.quote || '', result, string.escaped); - }, - '%': function (string /* arg, arg, ...*/) { - var args = Array.prototype.slice.call(arguments, 1), - result = string.value; - - for (var i = 0; i < args.length; i++) { - /*jshint loopfunc:true */ - result = result.replace(/%[sda]/i, function(token) { - var value = token.match(/s/i) ? args[i].value : args[i].toCSS(); - return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value; - }); - } - result = result.replace(/%%/g, '%'); - return new(tree.Quoted)(string.quote || '', result, string.escaped); - }, - unit: function (val, unit) { - if(!(val instanceof tree.Dimension)) { - throw { type: "Argument", message: "the first argument to unit must be a number" + (val instanceof tree.Operation ? ". Have you forgotten parenthesis?" : "") }; - } - if (unit) { - if (unit instanceof tree.Keyword) { - unit = unit.value; - } else { - unit = unit.toCSS(); - } - } else { - unit = ""; - } - return new(tree.Dimension)(val.value, unit); - }, - convert: function (val, unit) { - return val.convertTo(unit.value); - }, - round: function (n, f) { - var fraction = typeof(f) === "undefined" ? 0 : f.value; - return _math(function(num) { return num.toFixed(fraction); }, null, n); - }, - pi: function () { - return new(tree.Dimension)(Math.PI); - }, - mod: function(a, b) { - return new(tree.Dimension)(a.value % b.value, a.unit); - }, - pow: function(x, y) { - if (typeof x === "number" && typeof y === "number") { - x = new(tree.Dimension)(x); - y = new(tree.Dimension)(y); - } else if (!(x instanceof tree.Dimension) || !(y instanceof tree.Dimension)) { - throw { type: "Argument", message: "arguments must be numbers" }; - } - - return new(tree.Dimension)(Math.pow(x.value, y.value), x.unit); - }, - _minmax: function (isMin, args) { - args = Array.prototype.slice.call(args); - switch(args.length) { - case 0: throw { type: "Argument", message: "one or more arguments required" }; - } - var i, j, current, currentUnified, referenceUnified, unit, unitStatic, unitClone, - order = [], // elems only contains original argument values. - values = {}; // key is the unit.toString() for unified tree.Dimension values, - // value is the index into the order array. - for (i = 0; i < args.length; i++) { - current = args[i]; - if (!(current instanceof tree.Dimension)) { - if(Array.isArray(args[i].value)) { - Array.prototype.push.apply(args, Array.prototype.slice.call(args[i].value)); - } - continue; - } - currentUnified = current.unit.toString() === "" && unitClone !== undefined ? new(tree.Dimension)(current.value, unitClone).unify() : current.unify(); - unit = currentUnified.unit.toString() === "" && unitStatic !== undefined ? unitStatic : currentUnified.unit.toString(); - unitStatic = unit !== "" && unitStatic === undefined || unit !== "" && order[0].unify().unit.toString() === "" ? unit : unitStatic; - unitClone = unit !== "" && unitClone === undefined ? current.unit.toString() : unitClone; - j = values[""] !== undefined && unit !== "" && unit === unitStatic ? values[""] : values[unit]; - if (j === undefined) { - if(unitStatic !== undefined && unit !== unitStatic) { - throw{ type: "Argument", message: "incompatible types" }; - } - values[unit] = order.length; - order.push(current); - continue; - } - referenceUnified = order[j].unit.toString() === "" && unitClone !== undefined ? new(tree.Dimension)(order[j].value, unitClone).unify() : order[j].unify(); - if ( isMin && currentUnified.value < referenceUnified.value || - !isMin && currentUnified.value > referenceUnified.value) { - order[j] = current; - } - } - if (order.length == 1) { - return order[0]; - } - args = order.map(function (a) { return a.toCSS(this.env); }).join(this.env.compress ? "," : ", "); - return new(tree.Anonymous)((isMin ? "min" : "max") + "(" + args + ")"); - }, - min: function () { - return this._minmax(true, arguments); - }, - max: function () { - return this._minmax(false, arguments); - }, - "get-unit": function (n) { - return new(tree.Anonymous)(n.unit); - }, - argb: function (color) { - return new(tree.Anonymous)(color.toARGB()); - }, - percentage: function (n) { - return new(tree.Dimension)(n.value * 100, '%'); - }, - color: function (n) { - if (n instanceof tree.Quoted) { - var colorCandidate = n.value, - returnColor; - returnColor = tree.Color.fromKeyword(colorCandidate); - if (returnColor) { - return returnColor; - } - if (/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/.test(colorCandidate)) { - return new(tree.Color)(colorCandidate.slice(1)); - } - throw { type: "Argument", message: "argument must be a color keyword or 3/6 digit hex e.g. #FFF" }; - } else { - throw { type: "Argument", message: "argument must be a string" }; - } - }, - iscolor: function (n) { - return this._isa(n, tree.Color); - }, - isnumber: function (n) { - return this._isa(n, tree.Dimension); - }, - isstring: function (n) { - return this._isa(n, tree.Quoted); - }, - iskeyword: function (n) { - return this._isa(n, tree.Keyword); - }, - isurl: function (n) { - return this._isa(n, tree.URL); - }, - ispixel: function (n) { - return this.isunit(n, 'px'); - }, - ispercentage: function (n) { - return this.isunit(n, '%'); - }, - isem: function (n) { - return this.isunit(n, 'em'); - }, - isunit: function (n, unit) { - return (n instanceof tree.Dimension) && n.unit.is(unit.value || unit) ? tree.True : tree.False; - }, - _isa: function (n, Type) { - return (n instanceof Type) ? tree.True : tree.False; - }, - tint: function(color, amount) { - return this.mix(this.rgb(255,255,255), color, amount); - }, - shade: function(color, amount) { - return this.mix(this.rgb(0, 0, 0), color, amount); - }, - extract: function(values, index) { - index = index.value - 1; // (1-based index) - // handle non-array values as an array of length 1 - // return 'undefined' if index is invalid - return Array.isArray(values.value) - ? values.value[index] : Array(values)[index]; - }, - length: function(values) { - var n = Array.isArray(values.value) ? values.value.length : 1; - return new tree.Dimension(n); - }, - - "data-uri": function(mimetypeNode, filePathNode) { - - if (typeof window !== 'undefined') { - return new tree.URL(filePathNode || mimetypeNode, this.currentFileInfo).eval(this.env); - } - - var mimetype = mimetypeNode.value; - var filePath = (filePathNode && filePathNode.value); - - var fs = require('./fs'), - path = require('path'), - useBase64 = false; - - if (arguments.length < 2) { - filePath = mimetype; - } - - if (this.env.isPathRelative(filePath)) { - if (this.currentFileInfo.relativeUrls) { - filePath = path.join(this.currentFileInfo.currentDirectory, filePath); - } else { - filePath = path.join(this.currentFileInfo.entryPath, filePath); - } - } - - // detect the mimetype if not given - if (arguments.length < 2) { - var mime; - try { - mime = require('mime'); - } catch (ex) { - mime = tree._mime; - } - - mimetype = mime.lookup(filePath); - - // use base 64 unless it's an ASCII or UTF-8 format - var charset = mime.charsets.lookup(mimetype); - useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0; - if (useBase64) { mimetype += ';base64'; } - } - else { - useBase64 = /;base64$/.test(mimetype); - } - - var buf = fs.readFileSync(filePath); - - // IE8 cannot handle a data-uri larger than 32KB. If this is exceeded - // and the --ieCompat flag is enabled, return a normal url() instead. - var DATA_URI_MAX_KB = 32, - fileSizeInKB = parseInt((buf.length / 1024), 10); - if (fileSizeInKB >= DATA_URI_MAX_KB) { - - if (this.env.ieCompat !== false) { - if (!this.env.silent) { - console.warn("Skipped data-uri embedding of %s because its size (%dKB) exceeds IE8-safe %dKB!", filePath, fileSizeInKB, DATA_URI_MAX_KB); - } - - return new tree.URL(filePathNode || mimetypeNode, this.currentFileInfo).eval(this.env); - } - } - - buf = useBase64 ? buf.toString('base64') - : encodeURIComponent(buf); - - var uri = "\"data:" + mimetype + ',' + buf + "\""; - return new(tree.URL)(new(tree.Anonymous)(uri)); - }, - - "svg-gradient": function(direction) { - - function throwArgumentDescriptor() { - throw { type: "Argument", message: "svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position]" }; - } - - if (arguments.length < 3) { - throwArgumentDescriptor(); - } - var stops = Array.prototype.slice.call(arguments, 1), - gradientDirectionSvg, - gradientType = "linear", - rectangleDimension = 'x="0" y="0" width="1" height="1"', - useBase64 = true, - renderEnv = {compress: false}, - returner, - directionValue = direction.toCSS(renderEnv), - i, color, position, positionValue, alpha; - - switch (directionValue) { - case "to bottom": - gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"'; - break; - case "to right": - gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="0%"'; - break; - case "to bottom right": - gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="100%"'; - break; - case "to top right": - gradientDirectionSvg = 'x1="0%" y1="100%" x2="100%" y2="0%"'; - break; - case "ellipse": - case "ellipse at center": - gradientType = "radial"; - gradientDirectionSvg = 'cx="50%" cy="50%" r="75%"'; - rectangleDimension = 'x="-50" y="-50" width="101" height="101"'; - break; - default: - throw { type: "Argument", message: "svg-gradient direction must be 'to bottom', 'to right', 'to bottom right', 'to top right' or 'ellipse at center'" }; - } - returner = '' + - '' + - '<' + gradientType + 'Gradient id="gradient" gradientUnits="userSpaceOnUse" ' + gradientDirectionSvg + '>'; - - for (i = 0; i < stops.length; i+= 1) { - if (stops[i].value) { - color = stops[i].value[0]; - position = stops[i].value[1]; - } else { - color = stops[i]; - position = undefined; - } - - if (!(color instanceof tree.Color) || (!((i === 0 || i+1 === stops.length) && position === undefined) && !(position instanceof tree.Dimension))) { - throwArgumentDescriptor(); - } - positionValue = position ? position.toCSS(renderEnv) : i === 0 ? "0%" : "100%"; - alpha = color.alpha; - returner += ''; - } - returner += '' + - ''; - - if (useBase64) { - try { - returner = require('./encoder').encodeBase64(returner); // TODO browser implementation - } catch(e) { - useBase64 = false; - } - } - - returner = "'data:image/svg+xml" + (useBase64 ? ";base64" : "") + "," + returner + "'"; - return new(tree.URL)(new(tree.Anonymous)(returner)); - } -}; - -// these static methods are used as a fallback when the optional 'mime' dependency is missing -tree._mime = { - // this map is intentionally incomplete - // if you want more, install 'mime' dep - _types: { - '.htm' : 'text/html', - '.html': 'text/html', - '.gif' : 'image/gif', - '.jpg' : 'image/jpeg', - '.jpeg': 'image/jpeg', - '.png' : 'image/png' - }, - lookup: function (filepath) { - var ext = require('path').extname(filepath), - type = tree._mime._types[ext]; - if (type === undefined) { - throw new Error('Optional dependency "mime" is required for ' + ext); - } - return type; - }, - charsets: { - lookup: function (type) { - // assumes all text types are UTF-8 - return type && (/^text\//).test(type) ? 'UTF-8' : ''; - } - } -}; - -// Math - -var mathFunctions = { - // name, unit - ceil: null, - floor: null, - sqrt: null, - abs: null, - tan: "", - sin: "", - cos: "", - atan: "rad", - asin: "rad", - acos: "rad" -}; - -function _math(fn, unit, n) { - if (!(n instanceof tree.Dimension)) { - throw { type: "Argument", message: "argument must be a number" }; - } - if (unit == null) { - unit = n.unit; - } else { - n = n.unify(); - } - return new(tree.Dimension)(fn(parseFloat(n.value)), unit); -} - -// ~ End of Math - -// Color Blending -// ref: http://www.w3.org/TR/compositing-1 - -function colorBlend(mode, color1, color2) { - var ab = color1.alpha, cb, // backdrop - as = color2.alpha, cs, // source - ar, cr, r = []; // result - - ar = as + ab * (1 - as); - for (var i = 0; i < 3; i++) { - cb = color1.rgb[i] / 255; - cs = color2.rgb[i] / 255; - cr = mode(cb, cs); - if (ar) { - cr = (as * cs + ab * (cb - - as * (cb + cs - cr))) / ar; - } - r[i] = cr * 255; - } - - return new(tree.Color)(r, ar); -} - -var colorBlendMode = { - multiply: function(cb, cs) { - return cb * cs; - }, - screen: function(cb, cs) { - return cb + cs - cb * cs; - }, - overlay: function(cb, cs) { - cb *= 2; - return (cb <= 1) - ? colorBlendMode.multiply(cb, cs) - : colorBlendMode.screen(cb - 1, cs); - }, - softlight: function(cb, cs) { - var d = 1, e = cb; - if (cs > 0.5) { - e = 1; - d = (cb > 0.25) ? Math.sqrt(cb) - : ((16 * cb - 12) * cb + 4) * cb; - } - return cb - (1 - 2 * cs) * e * (d - cb); - }, - hardlight: function(cb, cs) { - return colorBlendMode.overlay(cs, cb); - }, - difference: function(cb, cs) { - return Math.abs(cb - cs); - }, - exclusion: function(cb, cs) { - return cb + cs - 2 * cb * cs; - }, - - // non-w3c functions: - average: function(cb, cs) { - return (cb + cs) / 2; - }, - negation: function(cb, cs) { - return 1 - Math.abs(cb + cs - 1); - } -}; - -// ~ End of Color Blending - -tree.defaultFunc = { - eval: function () { - var v = this.value_, e = this.error_; - if (e) { - throw e; - } - if (v != null) { - return v ? tree.True : tree.False; - } - }, - value: function (v) { - this.value_ = v; - }, - error: function (e) { - this.error_ = e; - }, - reset: function () { - this.value_ = this.error_ = null; - } -}; - -function initFunctions() { - var f, tf = tree.functions; - - // math - for (f in mathFunctions) { - if (mathFunctions.hasOwnProperty(f)) { - tf[f] = _math.bind(null, Math[f], mathFunctions[f]); - } - } - - // color blending - for (f in colorBlendMode) { - if (colorBlendMode.hasOwnProperty(f)) { - tf[f] = colorBlend.bind(null, colorBlendMode[f]); - } - } - - // default - f = tree.defaultFunc; - tf["default"] = f.eval.bind(f); - -} initFunctions(); - -function hsla(color) { - return tree.functions.hsla(color.h, color.s, color.l, color.a); -} - -function scaled(n, size) { - if (n instanceof tree.Dimension && n.unit.is('%')) { - return parseFloat(n.value * size / 100); - } else { - return number(n); - } -} - -function number(n) { - if (n instanceof tree.Dimension) { - return parseFloat(n.unit.is('%') ? n.value / 100 : n.value); - } else if (typeof(n) === 'number') { - return n; - } else { - throw { - error: "RuntimeError", - message: "color functions take numbers as parameters" - }; - } -} - -function clamp(val) { - return Math.min(1, Math.max(0, val)); -} - -tree.fround = function(env, value) { - var p = env && env.numPrecision; - //add "epsilon" to ensure numbers like 1.000000005 (represented as 1.000000004999....) are properly rounded... - return (p == null) ? value : Number((value + 2e-16).toFixed(p)); -}; - -tree.functionCall = function(env, currentFileInfo) { - this.env = env; - this.currentFileInfo = currentFileInfo; -}; - -tree.functionCall.prototype = tree.functions; - -})(require('./tree')); - -(function (tree) { - tree.colors = { - 'aliceblue':'#f0f8ff', - 'antiquewhite':'#faebd7', - 'aqua':'#00ffff', - 'aquamarine':'#7fffd4', - 'azure':'#f0ffff', - 'beige':'#f5f5dc', - 'bisque':'#ffe4c4', - 'black':'#000000', - 'blanchedalmond':'#ffebcd', - 'blue':'#0000ff', - 'blueviolet':'#8a2be2', - 'brown':'#a52a2a', - 'burlywood':'#deb887', - 'cadetblue':'#5f9ea0', - 'chartreuse':'#7fff00', - 'chocolate':'#d2691e', - 'coral':'#ff7f50', - 'cornflowerblue':'#6495ed', - 'cornsilk':'#fff8dc', - 'crimson':'#dc143c', - 'cyan':'#00ffff', - 'darkblue':'#00008b', - 'darkcyan':'#008b8b', - 'darkgoldenrod':'#b8860b', - 'darkgray':'#a9a9a9', - 'darkgrey':'#a9a9a9', - 'darkgreen':'#006400', - 'darkkhaki':'#bdb76b', - 'darkmagenta':'#8b008b', - 'darkolivegreen':'#556b2f', - 'darkorange':'#ff8c00', - 'darkorchid':'#9932cc', - 'darkred':'#8b0000', - 'darksalmon':'#e9967a', - 'darkseagreen':'#8fbc8f', - 'darkslateblue':'#483d8b', - 'darkslategray':'#2f4f4f', - 'darkslategrey':'#2f4f4f', - 'darkturquoise':'#00ced1', - 'darkviolet':'#9400d3', - 'deeppink':'#ff1493', - 'deepskyblue':'#00bfff', - 'dimgray':'#696969', - 'dimgrey':'#696969', - 'dodgerblue':'#1e90ff', - 'firebrick':'#b22222', - 'floralwhite':'#fffaf0', - 'forestgreen':'#228b22', - 'fuchsia':'#ff00ff', - 'gainsboro':'#dcdcdc', - 'ghostwhite':'#f8f8ff', - 'gold':'#ffd700', - 'goldenrod':'#daa520', - 'gray':'#808080', - 'grey':'#808080', - 'green':'#008000', - 'greenyellow':'#adff2f', - 'honeydew':'#f0fff0', - 'hotpink':'#ff69b4', - 'indianred':'#cd5c5c', - 'indigo':'#4b0082', - 'ivory':'#fffff0', - 'khaki':'#f0e68c', - 'lavender':'#e6e6fa', - 'lavenderblush':'#fff0f5', - 'lawngreen':'#7cfc00', - 'lemonchiffon':'#fffacd', - 'lightblue':'#add8e6', - 'lightcoral':'#f08080', - 'lightcyan':'#e0ffff', - 'lightgoldenrodyellow':'#fafad2', - 'lightgray':'#d3d3d3', - 'lightgrey':'#d3d3d3', - 'lightgreen':'#90ee90', - 'lightpink':'#ffb6c1', - 'lightsalmon':'#ffa07a', - 'lightseagreen':'#20b2aa', - 'lightskyblue':'#87cefa', - 'lightslategray':'#778899', - 'lightslategrey':'#778899', - 'lightsteelblue':'#b0c4de', - 'lightyellow':'#ffffe0', - 'lime':'#00ff00', - 'limegreen':'#32cd32', - 'linen':'#faf0e6', - 'magenta':'#ff00ff', - 'maroon':'#800000', - 'mediumaquamarine':'#66cdaa', - 'mediumblue':'#0000cd', - 'mediumorchid':'#ba55d3', - 'mediumpurple':'#9370d8', - 'mediumseagreen':'#3cb371', - 'mediumslateblue':'#7b68ee', - 'mediumspringgreen':'#00fa9a', - 'mediumturquoise':'#48d1cc', - 'mediumvioletred':'#c71585', - 'midnightblue':'#191970', - 'mintcream':'#f5fffa', - 'mistyrose':'#ffe4e1', - 'moccasin':'#ffe4b5', - 'navajowhite':'#ffdead', - 'navy':'#000080', - 'oldlace':'#fdf5e6', - 'olive':'#808000', - 'olivedrab':'#6b8e23', - 'orange':'#ffa500', - 'orangered':'#ff4500', - 'orchid':'#da70d6', - 'palegoldenrod':'#eee8aa', - 'palegreen':'#98fb98', - 'paleturquoise':'#afeeee', - 'palevioletred':'#d87093', - 'papayawhip':'#ffefd5', - 'peachpuff':'#ffdab9', - 'peru':'#cd853f', - 'pink':'#ffc0cb', - 'plum':'#dda0dd', - 'powderblue':'#b0e0e6', - 'purple':'#800080', - 'red':'#ff0000', - 'rosybrown':'#bc8f8f', - 'royalblue':'#4169e1', - 'saddlebrown':'#8b4513', - 'salmon':'#fa8072', - 'sandybrown':'#f4a460', - 'seagreen':'#2e8b57', - 'seashell':'#fff5ee', - 'sienna':'#a0522d', - 'silver':'#c0c0c0', - 'skyblue':'#87ceeb', - 'slateblue':'#6a5acd', - 'slategray':'#708090', - 'slategrey':'#708090', - 'snow':'#fffafa', - 'springgreen':'#00ff7f', - 'steelblue':'#4682b4', - 'tan':'#d2b48c', - 'teal':'#008080', - 'thistle':'#d8bfd8', - 'tomato':'#ff6347', - 'turquoise':'#40e0d0', - 'violet':'#ee82ee', - 'wheat':'#f5deb3', - 'white':'#ffffff', - 'whitesmoke':'#f5f5f5', - 'yellow':'#ffff00', - 'yellowgreen':'#9acd32' - }; -})(require('./tree')); - -(function (tree) { - -tree.debugInfo = function(env, ctx, lineSeperator) { - var result=""; - if (env.dumpLineNumbers && !env.compress) { - switch(env.dumpLineNumbers) { - case 'comments': - result = tree.debugInfo.asComment(ctx); - break; - case 'mediaquery': - result = tree.debugInfo.asMediaQuery(ctx); - break; - case 'all': - result = tree.debugInfo.asComment(ctx) + (lineSeperator || "") + tree.debugInfo.asMediaQuery(ctx); - break; - } - } - return result; -}; - -tree.debugInfo.asComment = function(ctx) { - return '/* line ' + ctx.debugInfo.lineNumber + ', ' + ctx.debugInfo.fileName + ' */\n'; -}; - -tree.debugInfo.asMediaQuery = function(ctx) { - return '@media -sass-debug-info{filename{font-family:' + - ('file://' + ctx.debugInfo.fileName).replace(/([.:\/\\])/g, function (a) { - if (a == '\\') { - a = '\/'; - } - return '\\' + a; - }) + - '}line{font-family:\\00003' + ctx.debugInfo.lineNumber + '}}\n'; -}; - -tree.find = function (obj, fun) { - for (var i = 0, r; i < obj.length; i++) { - r = fun.call(obj, obj[i]); - if (r) { return r; } - } - return null; -}; - -tree.jsify = function (obj) { - if (Array.isArray(obj.value) && (obj.value.length > 1)) { - return '[' + obj.value.map(function (v) { return v.toCSS(false); }).join(', ') + ']'; - } else { - return obj.toCSS(false); - } -}; - -tree.toCSS = function (env) { - var strs = []; - this.genCSS(env, { - add: function(chunk, fileInfo, index) { - strs.push(chunk); - }, - isEmpty: function () { - return strs.length === 0; - } - }); - return strs.join(''); -}; - -tree.outputRuleset = function (env, output, rules) { - var ruleCnt = rules.length, i; - env.tabLevel = (env.tabLevel | 0) + 1; - - // Compressed - if (env.compress) { - output.add('{'); - for (i = 0; i < ruleCnt; i++) { - rules[i].genCSS(env, output); - } - output.add('}'); - env.tabLevel--; - return; - } - - // Non-compressed - var tabSetStr = '\n' + Array(env.tabLevel).join(" "), tabRuleStr = tabSetStr + " "; - if (!ruleCnt) { - output.add(" {" + tabSetStr + '}'); - } else { - output.add(" {" + tabRuleStr); - rules[0].genCSS(env, output); - for (i = 1; i < ruleCnt; i++) { - output.add(tabRuleStr); - rules[i].genCSS(env, output); - } - output.add(tabSetStr + '}'); - } - - env.tabLevel--; -}; - -})(require('./tree')); - -(function (tree) { - -tree.Alpha = function (val) { - this.value = val; -}; -tree.Alpha.prototype = { - type: "Alpha", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - eval: function (env) { - if (this.value.eval) { return new tree.Alpha(this.value.eval(env)); } - return this; - }, - genCSS: function (env, output) { - output.add("alpha(opacity="); - - if (this.value.genCSS) { - this.value.genCSS(env, output); - } else { - output.add(this.value); - } - - output.add(")"); - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -tree.Anonymous = function (value, index, currentFileInfo, mapLines) { - this.value = value; - this.index = index; - this.mapLines = mapLines; - this.currentFileInfo = currentFileInfo; -}; -tree.Anonymous.prototype = { - type: "Anonymous", - eval: function () { - return new tree.Anonymous(this.value, this.index, this.currentFileInfo, this.mapLines); - }, - compare: function (x) { - if (!x.toCSS) { - return -1; - } - - var left = this.toCSS(), - right = x.toCSS(); - - if (left === right) { - return 0; - } - - return left < right ? -1 : 1; - }, - genCSS: function (env, output) { - output.add(this.value, this.currentFileInfo, this.index, this.mapLines); - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -tree.Assignment = function (key, val) { - this.key = key; - this.value = val; -}; -tree.Assignment.prototype = { - type: "Assignment", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - eval: function (env) { - if (this.value.eval) { - return new(tree.Assignment)(this.key, this.value.eval(env)); - } - return this; - }, - genCSS: function (env, output) { - output.add(this.key + '='); - if (this.value.genCSS) { - this.value.genCSS(env, output); - } else { - output.add(this.value); - } - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -// -// A function call node. -// -tree.Call = function (name, args, index, currentFileInfo) { - this.name = name; - this.args = args; - this.index = index; - this.currentFileInfo = currentFileInfo; -}; -tree.Call.prototype = { - type: "Call", - accept: function (visitor) { - if (this.args) { - this.args = visitor.visitArray(this.args); - } - }, - // - // When evaluating a function call, - // we either find the function in `tree.functions` [1], - // in which case we call it, passing the evaluated arguments, - // if this returns null or we cannot find the function, we - // simply print it out as it appeared originally [2]. - // - // The *functions.js* file contains the built-in functions. - // - // The reason why we evaluate the arguments, is in the case where - // we try to pass a variable to a function, like: `saturate(@color)`. - // The function should receive the value, not the variable. - // - eval: function (env) { - var args = this.args.map(function (a) { return a.eval(env); }), - nameLC = this.name.toLowerCase(), - result, func; - - if (nameLC in tree.functions) { // 1. - try { - func = new tree.functionCall(env, this.currentFileInfo); - result = func[nameLC].apply(func, args); - if (result != null) { - return result; - } - } catch (e) { - throw { type: e.type || "Runtime", - message: "error evaluating function `" + this.name + "`" + - (e.message ? ': ' + e.message : ''), - index: this.index, filename: this.currentFileInfo.filename }; - } - } - - return new tree.Call(this.name, args, this.index, this.currentFileInfo); - }, - - genCSS: function (env, output) { - output.add(this.name + "(", this.currentFileInfo, this.index); - - for(var i = 0; i < this.args.length; i++) { - this.args[i].genCSS(env, output); - if (i + 1 < this.args.length) { - output.add(", "); - } - } - - output.add(")"); - }, - - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { -// -// RGB Colors - #ff0014, #eee -// -tree.Color = function (rgb, a) { - // - // The end goal here, is to parse the arguments - // into an integer triplet, such as `128, 255, 0` - // - // This facilitates operations and conversions. - // - if (Array.isArray(rgb)) { - this.rgb = rgb; - } else if (rgb.length == 6) { - this.rgb = rgb.match(/.{2}/g).map(function (c) { - return parseInt(c, 16); - }); - } else { - this.rgb = rgb.split('').map(function (c) { - return parseInt(c + c, 16); - }); - } - this.alpha = typeof(a) === 'number' ? a : 1; -}; - -var transparentKeyword = "transparent"; - -tree.Color.prototype = { - type: "Color", - eval: function () { return this; }, - luma: function () { - var r = this.rgb[0] / 255, - g = this.rgb[1] / 255, - b = this.rgb[2] / 255; - - r = (r <= 0.03928) ? r / 12.92 : Math.pow(((r + 0.055) / 1.055), 2.4); - g = (g <= 0.03928) ? g / 12.92 : Math.pow(((g + 0.055) / 1.055), 2.4); - b = (b <= 0.03928) ? b / 12.92 : Math.pow(((b + 0.055) / 1.055), 2.4); - - return 0.2126 * r + 0.7152 * g + 0.0722 * b; - }, - - genCSS: function (env, output) { - output.add(this.toCSS(env)); - }, - toCSS: function (env, doNotCompress) { - var compress = env && env.compress && !doNotCompress, - alpha = tree.fround(env, this.alpha); - - // If we have some transparency, the only way to represent it - // is via `rgba`. Otherwise, we use the hex representation, - // which has better compatibility with older browsers. - // Values are capped between `0` and `255`, rounded and zero-padded. - if (alpha < 1) { - if (alpha === 0 && this.isTransparentKeyword) { - return transparentKeyword; - } - return "rgba(" + this.rgb.map(function (c) { - return clamp(Math.round(c), 255); - }).concat(clamp(alpha, 1)) - .join(',' + (compress ? '' : ' ')) + ")"; - } else { - var color = this.toRGB(); - - if (compress) { - var splitcolor = color.split(''); - - // Convert color to short format - if (splitcolor[1] === splitcolor[2] && splitcolor[3] === splitcolor[4] && splitcolor[5] === splitcolor[6]) { - color = '#' + splitcolor[1] + splitcolor[3] + splitcolor[5]; - } - } - - return color; - } - }, - - // - // Operations have to be done per-channel, if not, - // channels will spill onto each other. Once we have - // our result, in the form of an integer triplet, - // we create a new Color node to hold the result. - // - operate: function (env, op, other) { - var rgb = []; - var alpha = this.alpha * (1 - other.alpha) + other.alpha; - for (var c = 0; c < 3; c++) { - rgb[c] = tree.operate(env, op, this.rgb[c], other.rgb[c]); - } - return new(tree.Color)(rgb, alpha); - }, - - toRGB: function () { - return toHex(this.rgb); - }, - - toHSL: function () { - var r = this.rgb[0] / 255, - g = this.rgb[1] / 255, - b = this.rgb[2] / 255, - a = this.alpha; - - var max = Math.max(r, g, b), min = Math.min(r, g, b); - var h, s, l = (max + min) / 2, d = max - min; - - if (max === min) { - h = s = 0; - } else { - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - - switch (max) { - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; - } - h /= 6; - } - return { h: h * 360, s: s, l: l, a: a }; - }, - //Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript - toHSV: function () { - var r = this.rgb[0] / 255, - g = this.rgb[1] / 255, - b = this.rgb[2] / 255, - a = this.alpha; - - var max = Math.max(r, g, b), min = Math.min(r, g, b); - var h, s, v = max; - - var d = max - min; - if (max === 0) { - s = 0; - } else { - s = d / max; - } - - if (max === min) { - h = 0; - } else { - switch(max){ - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; - } - h /= 6; - } - return { h: h * 360, s: s, v: v, a: a }; - }, - toARGB: function () { - return toHex([this.alpha * 255].concat(this.rgb)); - }, - compare: function (x) { - if (!x.rgb) { - return -1; - } - - return (x.rgb[0] === this.rgb[0] && - x.rgb[1] === this.rgb[1] && - x.rgb[2] === this.rgb[2] && - x.alpha === this.alpha) ? 0 : -1; - } -}; - -tree.Color.fromKeyword = function(keyword) { - keyword = keyword.toLowerCase(); - - if (tree.colors.hasOwnProperty(keyword)) { - // detect named color - return new(tree.Color)(tree.colors[keyword].slice(1)); - } - if (keyword === transparentKeyword) { - var transparent = new(tree.Color)([0, 0, 0], 0); - transparent.isTransparentKeyword = true; - return transparent; - } -}; - -function toHex(v) { - return '#' + v.map(function (c) { - c = clamp(Math.round(c), 255); - return (c < 16 ? '0' : '') + c.toString(16); - }).join(''); -} - -function clamp(v, max) { - return Math.min(Math.max(v, 0), max); -} - -})(require('../tree')); - -(function (tree) { - -tree.Comment = function (value, silent, index, currentFileInfo) { - this.value = value; - this.silent = !!silent; - this.currentFileInfo = currentFileInfo; -}; -tree.Comment.prototype = { - type: "Comment", - genCSS: function (env, output) { - if (this.debugInfo) { - output.add(tree.debugInfo(env, this), this.currentFileInfo, this.index); - } - output.add(this.value.trim()); //TODO shouldn't need to trim, we shouldn't grab the \n - }, - toCSS: tree.toCSS, - isSilent: function(env) { - var isReference = (this.currentFileInfo && this.currentFileInfo.reference && !this.isReferenced), - isCompressed = env.compress && !this.value.match(/^\/\*!/); - return this.silent || isReference || isCompressed; - }, - eval: function () { return this; }, - markReferenced: function () { - this.isReferenced = true; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Condition = function (op, l, r, i, negate) { - this.op = op.trim(); - this.lvalue = l; - this.rvalue = r; - this.index = i; - this.negate = negate; -}; -tree.Condition.prototype = { - type: "Condition", - accept: function (visitor) { - this.lvalue = visitor.visit(this.lvalue); - this.rvalue = visitor.visit(this.rvalue); - }, - eval: function (env) { - var a = this.lvalue.eval(env), - b = this.rvalue.eval(env); - - var i = this.index, result; - - result = (function (op) { - switch (op) { - case 'and': - return a && b; - case 'or': - return a || b; - default: - if (a.compare) { - result = a.compare(b); - } else if (b.compare) { - result = b.compare(a); - } else { - throw { type: "Type", - message: "Unable to perform comparison", - index: i }; - } - switch (result) { - case -1: return op === '<' || op === '=<' || op === '<='; - case 0: return op === '=' || op === '>=' || op === '=<' || op === '<='; - case 1: return op === '>' || op === '>='; - } - } - })(this.op); - return this.negate ? !result : result; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.DetachedRuleset = function (ruleset, frames) { - this.ruleset = ruleset; - this.frames = frames; -}; -tree.DetachedRuleset.prototype = { - type: "DetachedRuleset", - accept: function (visitor) { - this.ruleset = visitor.visit(this.ruleset); - }, - eval: function (env) { - var frames = this.frames || env.frames.slice(0); - return new tree.DetachedRuleset(this.ruleset, frames); - }, - callEval: function (env) { - return this.ruleset.eval(this.frames ? new(tree.evalEnv)(env, this.frames.concat(env.frames)) : env); - } -}; -})(require('../tree')); - -(function (tree) { - -// -// A number with a unit -// -tree.Dimension = function (value, unit) { - this.value = parseFloat(value); - this.unit = (unit && unit instanceof tree.Unit) ? unit : - new(tree.Unit)(unit ? [unit] : undefined); -}; - -tree.Dimension.prototype = { - type: "Dimension", - accept: function (visitor) { - this.unit = visitor.visit(this.unit); - }, - eval: function (env) { - return this; - }, - toColor: function () { - return new(tree.Color)([this.value, this.value, this.value]); - }, - genCSS: function (env, output) { - if ((env && env.strictUnits) && !this.unit.isSingular()) { - throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: "+this.unit.toString()); - } - - var value = tree.fround(env, this.value), - strValue = String(value); - - if (value !== 0 && value < 0.000001 && value > -0.000001) { - // would be output 1e-6 etc. - strValue = value.toFixed(20).replace(/0+$/, ""); - } - - if (env && env.compress) { - // Zero values doesn't need a unit - if (value === 0 && this.unit.isLength()) { - output.add(strValue); - return; - } - - // Float values doesn't need a leading zero - if (value > 0 && value < 1) { - strValue = (strValue).substr(1); - } - } - - output.add(strValue); - this.unit.genCSS(env, output); - }, - toCSS: tree.toCSS, - - // In an operation between two Dimensions, - // we default to the first Dimension's unit, - // so `1px + 2` will yield `3px`. - operate: function (env, op, other) { - /*jshint noempty:false */ - var value = tree.operate(env, op, this.value, other.value), - unit = this.unit.clone(); - - if (op === '+' || op === '-') { - if (unit.numerator.length === 0 && unit.denominator.length === 0) { - unit.numerator = other.unit.numerator.slice(0); - unit.denominator = other.unit.denominator.slice(0); - } else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) { - // do nothing - } else { - other = other.convertTo(this.unit.usedUnits()); - - if(env.strictUnits && other.unit.toString() !== unit.toString()) { - throw new Error("Incompatible units. Change the units or use the unit function. Bad units: '" + unit.toString() + - "' and '" + other.unit.toString() + "'."); - } - - value = tree.operate(env, op, this.value, other.value); - } - } else if (op === '*') { - unit.numerator = unit.numerator.concat(other.unit.numerator).sort(); - unit.denominator = unit.denominator.concat(other.unit.denominator).sort(); - unit.cancel(); - } else if (op === '/') { - unit.numerator = unit.numerator.concat(other.unit.denominator).sort(); - unit.denominator = unit.denominator.concat(other.unit.numerator).sort(); - unit.cancel(); - } - return new(tree.Dimension)(value, unit); - }, - - compare: function (other) { - if (other instanceof tree.Dimension) { - var a, b, - aValue, bValue; - - if (this.unit.isEmpty() || other.unit.isEmpty()) { - a = this; - b = other; - } else { - a = this.unify(); - b = other.unify(); - if (a.unit.compare(b.unit) !== 0) { - return -1; - } - } - aValue = a.value; - bValue = b.value; - - if (bValue > aValue) { - return -1; - } else if (bValue < aValue) { - return 1; - } else { - return 0; - } - } else { - return -1; - } - }, - - unify: function () { - return this.convertTo({ length: 'px', duration: 's', angle: 'rad' }); - }, - - convertTo: function (conversions) { - var value = this.value, unit = this.unit.clone(), - i, groupName, group, targetUnit, derivedConversions = {}, applyUnit; - - if (typeof conversions === 'string') { - for(i in tree.UnitConversions) { - if (tree.UnitConversions[i].hasOwnProperty(conversions)) { - derivedConversions = {}; - derivedConversions[i] = conversions; - } - } - conversions = derivedConversions; - } - applyUnit = function (atomicUnit, denominator) { - /*jshint loopfunc:true */ - if (group.hasOwnProperty(atomicUnit)) { - if (denominator) { - value = value / (group[atomicUnit] / group[targetUnit]); - } else { - value = value * (group[atomicUnit] / group[targetUnit]); - } - - return targetUnit; - } - - return atomicUnit; - }; - - for (groupName in conversions) { - if (conversions.hasOwnProperty(groupName)) { - targetUnit = conversions[groupName]; - group = tree.UnitConversions[groupName]; - - unit.map(applyUnit); - } - } - - unit.cancel(); - - return new(tree.Dimension)(value, unit); - } -}; - -// http://www.w3.org/TR/css3-values/#absolute-lengths -tree.UnitConversions = { - length: { - 'm': 1, - 'cm': 0.01, - 'mm': 0.001, - 'in': 0.0254, - 'px': 0.0254 / 96, - 'pt': 0.0254 / 72, - 'pc': 0.0254 / 72 * 12 - }, - duration: { - 's': 1, - 'ms': 0.001 - }, - angle: { - 'rad': 1/(2*Math.PI), - 'deg': 1/360, - 'grad': 1/400, - 'turn': 1 - } -}; - -tree.Unit = function (numerator, denominator, backupUnit) { - this.numerator = numerator ? numerator.slice(0).sort() : []; - this.denominator = denominator ? denominator.slice(0).sort() : []; - this.backupUnit = backupUnit; -}; - -tree.Unit.prototype = { - type: "Unit", - clone: function () { - return new tree.Unit(this.numerator.slice(0), this.denominator.slice(0), this.backupUnit); - }, - genCSS: function (env, output) { - if (this.numerator.length >= 1) { - output.add(this.numerator[0]); - } else - if (this.denominator.length >= 1) { - output.add(this.denominator[0]); - } else - if ((!env || !env.strictUnits) && this.backupUnit) { - output.add(this.backupUnit); - } - }, - toCSS: tree.toCSS, - - toString: function () { - var i, returnStr = this.numerator.join("*"); - for (i = 0; i < this.denominator.length; i++) { - returnStr += "/" + this.denominator[i]; - } - return returnStr; - }, - - compare: function (other) { - return this.is(other.toString()) ? 0 : -1; - }, - - is: function (unitString) { - return this.toString() === unitString; - }, - - isLength: function () { - return Boolean(this.toCSS().match(/px|em|%|in|cm|mm|pc|pt|ex/)); - }, - - isEmpty: function () { - return this.numerator.length === 0 && this.denominator.length === 0; - }, - - isSingular: function() { - return this.numerator.length <= 1 && this.denominator.length === 0; - }, - - map: function(callback) { - var i; - - for (i = 0; i < this.numerator.length; i++) { - this.numerator[i] = callback(this.numerator[i], false); - } - - for (i = 0; i < this.denominator.length; i++) { - this.denominator[i] = callback(this.denominator[i], true); - } - }, - - usedUnits: function() { - var group, result = {}, mapUnit; - - mapUnit = function (atomicUnit) { - /*jshint loopfunc:true */ - if (group.hasOwnProperty(atomicUnit) && !result[groupName]) { - result[groupName] = atomicUnit; - } - - return atomicUnit; - }; - - for (var groupName in tree.UnitConversions) { - if (tree.UnitConversions.hasOwnProperty(groupName)) { - group = tree.UnitConversions[groupName]; - - this.map(mapUnit); - } - } - - return result; - }, - - cancel: function () { - var counter = {}, atomicUnit, i, backup; - - for (i = 0; i < this.numerator.length; i++) { - atomicUnit = this.numerator[i]; - if (!backup) { - backup = atomicUnit; - } - counter[atomicUnit] = (counter[atomicUnit] || 0) + 1; - } - - for (i = 0; i < this.denominator.length; i++) { - atomicUnit = this.denominator[i]; - if (!backup) { - backup = atomicUnit; - } - counter[atomicUnit] = (counter[atomicUnit] || 0) - 1; - } - - this.numerator = []; - this.denominator = []; - - for (atomicUnit in counter) { - if (counter.hasOwnProperty(atomicUnit)) { - var count = counter[atomicUnit]; - - if (count > 0) { - for (i = 0; i < count; i++) { - this.numerator.push(atomicUnit); - } - } else if (count < 0) { - for (i = 0; i < -count; i++) { - this.denominator.push(atomicUnit); - } - } - } - } - - if (this.numerator.length === 0 && this.denominator.length === 0 && backup) { - this.backupUnit = backup; - } - - this.numerator.sort(); - this.denominator.sort(); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Directive = function (name, value, rules, index, currentFileInfo, debugInfo) { - this.name = name; - this.value = value; - if (rules) { - this.rules = rules; - this.rules.allowImports = true; - } - this.index = index; - this.currentFileInfo = currentFileInfo; - this.debugInfo = debugInfo; -}; - -tree.Directive.prototype = { - type: "Directive", - accept: function (visitor) { - var value = this.value, rules = this.rules; - if (rules) { - rules = visitor.visit(rules); - } - if (value) { - value = visitor.visit(value); - } - }, - genCSS: function (env, output) { - var value = this.value, rules = this.rules; - output.add(this.name, this.currentFileInfo, this.index); - if (value) { - output.add(' '); - value.genCSS(env, output); - } - if (rules) { - tree.outputRuleset(env, output, [rules]); - } else { - output.add(';'); - } - }, - toCSS: tree.toCSS, - eval: function (env) { - var value = this.value, rules = this.rules; - if (value) { - value = value.eval(env); - } - if (rules) { - rules = rules.eval(env); - rules.root = true; - } - return new(tree.Directive)(this.name, value, rules, - this.index, this.currentFileInfo, this.debugInfo); - }, - variable: function (name) { if (this.rules) return tree.Ruleset.prototype.variable.call(this.rules, name); }, - find: function () { if (this.rules) return tree.Ruleset.prototype.find.apply(this.rules, arguments); }, - rulesets: function () { if (this.rules) return tree.Ruleset.prototype.rulesets.apply(this.rules); }, - markReferenced: function () { - var i, rules; - this.isReferenced = true; - if (this.rules) { - rules = this.rules.rules; - for (i = 0; i < rules.length; i++) { - if (rules[i].markReferenced) { - rules[i].markReferenced(); - } - } - } - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Element = function (combinator, value, index, currentFileInfo) { - this.combinator = combinator instanceof tree.Combinator ? - combinator : new(tree.Combinator)(combinator); - - if (typeof(value) === 'string') { - this.value = value.trim(); - } else if (value) { - this.value = value; - } else { - this.value = ""; - } - this.index = index; - this.currentFileInfo = currentFileInfo; -}; -tree.Element.prototype = { - type: "Element", - accept: function (visitor) { - var value = this.value; - this.combinator = visitor.visit(this.combinator); - if (typeof value === "object") { - this.value = visitor.visit(value); - } - }, - eval: function (env) { - return new(tree.Element)(this.combinator, - this.value.eval ? this.value.eval(env) : this.value, - this.index, - this.currentFileInfo); - }, - genCSS: function (env, output) { - output.add(this.toCSS(env), this.currentFileInfo, this.index); - }, - toCSS: function (env) { - var value = (this.value.toCSS ? this.value.toCSS(env) : this.value); - if (value === '' && this.combinator.value.charAt(0) === '&') { - return ''; - } else { - return this.combinator.toCSS(env || {}) + value; - } - } -}; - -tree.Attribute = function (key, op, value) { - this.key = key; - this.op = op; - this.value = value; -}; -tree.Attribute.prototype = { - type: "Attribute", - eval: function (env) { - return new(tree.Attribute)(this.key.eval ? this.key.eval(env) : this.key, - this.op, (this.value && this.value.eval) ? this.value.eval(env) : this.value); - }, - genCSS: function (env, output) { - output.add(this.toCSS(env)); - }, - toCSS: function (env) { - var value = this.key.toCSS ? this.key.toCSS(env) : this.key; - - if (this.op) { - value += this.op; - value += (this.value.toCSS ? this.value.toCSS(env) : this.value); - } - - return '[' + value + ']'; - } -}; - -tree.Combinator = function (value) { - if (value === ' ') { - this.value = ' '; - } else { - this.value = value ? value.trim() : ""; - } -}; -tree.Combinator.prototype = { - type: "Combinator", - _outputMap: { - '' : '', - ' ' : ' ', - ':' : ' :', - '+' : ' + ', - '~' : ' ~ ', - '>' : ' > ', - '|' : '|', - '^' : ' ^ ', - '^^' : ' ^^ ' - }, - _outputMapCompressed: { - '' : '', - ' ' : ' ', - ':' : ' :', - '+' : '+', - '~' : '~', - '>' : '>', - '|' : '|', - '^' : '^', - '^^' : '^^' - }, - genCSS: function (env, output) { - output.add((env.compress ? this._outputMapCompressed : this._outputMap)[this.value]); - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -tree.Expression = function (value) { this.value = value; }; -tree.Expression.prototype = { - type: "Expression", - accept: function (visitor) { - if (this.value) { - this.value = visitor.visitArray(this.value); - } - }, - eval: function (env) { - var returnValue, - inParenthesis = this.parens && !this.parensInOp, - doubleParen = false; - if (inParenthesis) { - env.inParenthesis(); - } - if (this.value.length > 1) { - returnValue = new(tree.Expression)(this.value.map(function (e) { - return e.eval(env); - })); - } else if (this.value.length === 1) { - if (this.value[0].parens && !this.value[0].parensInOp) { - doubleParen = true; - } - returnValue = this.value[0].eval(env); - } else { - returnValue = this; - } - if (inParenthesis) { - env.outOfParenthesis(); - } - if (this.parens && this.parensInOp && !(env.isMathOn()) && !doubleParen) { - returnValue = new(tree.Paren)(returnValue); - } - return returnValue; - }, - genCSS: function (env, output) { - for(var i = 0; i < this.value.length; i++) { - this.value[i].genCSS(env, output); - if (i + 1 < this.value.length) { - output.add(" "); - } - } - }, - toCSS: tree.toCSS, - throwAwayComments: function () { - this.value = this.value.filter(function(v) { - return !(v instanceof tree.Comment); - }); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Extend = function Extend(selector, option, index) { - this.selector = selector; - this.option = option; - this.index = index; - this.object_id = tree.Extend.next_id++; - this.parent_ids = [this.object_id]; - - switch(option) { - case "all": - this.allowBefore = true; - this.allowAfter = true; - break; - default: - this.allowBefore = false; - this.allowAfter = false; - break; - } -}; -tree.Extend.next_id = 0; - -tree.Extend.prototype = { - type: "Extend", - accept: function (visitor) { - this.selector = visitor.visit(this.selector); - }, - eval: function (env) { - return new(tree.Extend)(this.selector.eval(env), this.option, this.index); - }, - clone: function (env) { - return new(tree.Extend)(this.selector, this.option, this.index); - }, - findSelfSelectors: function (selectors) { - var selfElements = [], - i, - selectorElements; - - for(i = 0; i < selectors.length; i++) { - selectorElements = selectors[i].elements; - // duplicate the logic in genCSS function inside the selector node. - // future TODO - move both logics into the selector joiner visitor - if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === "") { - selectorElements[0].combinator.value = ' '; - } - selfElements = selfElements.concat(selectors[i].elements); - } - - this.selfSelectors = [{ elements: selfElements }]; - } -}; - -})(require('../tree')); - -(function (tree) { -// -// CSS @import node -// -// The general strategy here is that we don't want to wait -// for the parsing to be completed, before we start importing -// the file. That's because in the context of a browser, -// most of the time will be spent waiting for the server to respond. -// -// On creation, we push the import path to our import queue, though -// `import,push`, we also pass it a callback, which it'll call once -// the file has been fetched, and parsed. -// -tree.Import = function (path, features, options, index, currentFileInfo) { - this.options = options; - this.index = index; - this.path = path; - this.features = features; - this.currentFileInfo = currentFileInfo; - - if (this.options.less !== undefined || this.options.inline) { - this.css = !this.options.less || this.options.inline; - } else { - var pathValue = this.getPath(); - if (pathValue && /css([\?;].*)?$/.test(pathValue)) { - this.css = true; - } - } -}; - -// -// The actual import node doesn't return anything, when converted to CSS. -// The reason is that it's used at the evaluation stage, so that the rules -// it imports can be treated like any other rules. -// -// In `eval`, we make sure all Import nodes get evaluated, recursively, so -// we end up with a flat structure, which can easily be imported in the parent -// ruleset. -// -tree.Import.prototype = { - type: "Import", - accept: function (visitor) { - if (this.features) { - this.features = visitor.visit(this.features); - } - this.path = visitor.visit(this.path); - if (!this.options.inline && this.root) { - this.root = visitor.visit(this.root); - } - }, - genCSS: function (env, output) { - if (this.css) { - output.add("@import ", this.currentFileInfo, this.index); - this.path.genCSS(env, output); - if (this.features) { - output.add(" "); - this.features.genCSS(env, output); - } - output.add(';'); - } - }, - toCSS: tree.toCSS, - getPath: function () { - if (this.path instanceof tree.Quoted) { - var path = this.path.value; - return (this.css !== undefined || /(\.[a-z]*$)|([\?;].*)$/.test(path)) ? path : path + '.less'; - } else if (this.path instanceof tree.URL) { - return this.path.value.value; - } - return null; - }, - evalForImport: function (env) { - return new(tree.Import)(this.path.eval(env), this.features, this.options, this.index, this.currentFileInfo); - }, - evalPath: function (env) { - var path = this.path.eval(env); - var rootpath = this.currentFileInfo && this.currentFileInfo.rootpath; - - if (!(path instanceof tree.URL)) { - if (rootpath) { - var pathValue = path.value; - // Add the base path if the import is relative - if (pathValue && env.isPathRelative(pathValue)) { - path.value = rootpath +pathValue; - } - } - path.value = env.normalizePath(path.value); - } - - return path; - }, - eval: function (env) { - var ruleset, features = this.features && this.features.eval(env); - - if (this.skip) { - if (typeof this.skip === "function") { - this.skip = this.skip(); - } - if (this.skip) { - return []; - } - } - - if (this.options.inline) { - //todo needs to reference css file not import - var contents = new(tree.Anonymous)(this.root, 0, {filename: this.importedFilename}, true); - return this.features ? new(tree.Media)([contents], this.features.value) : [contents]; - } else if (this.css) { - var newImport = new(tree.Import)(this.evalPath(env), features, this.options, this.index); - if (!newImport.css && this.error) { - throw this.error; - } - return newImport; - } else { - ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0)); - - ruleset.evalImports(env); - - return this.features ? new(tree.Media)(ruleset.rules, this.features.value) : ruleset.rules; - } - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.JavaScript = function (string, index, escaped) { - this.escaped = escaped; - this.expression = string; - this.index = index; -}; -tree.JavaScript.prototype = { - type: "JavaScript", - eval: function (env) { - var result, - that = this, - context = {}; - - var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) { - return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env)); - }); - - try { - expression = new(Function)('return (' + expression + ')'); - } catch (e) { - throw { message: "JavaScript evaluation error: " + e.message + " from `" + expression + "`" , - index: this.index }; - } - - var variables = env.frames[0].variables(); - for (var k in variables) { - if (variables.hasOwnProperty(k)) { - /*jshint loopfunc:true */ - context[k.slice(1)] = { - value: variables[k].value, - toJS: function () { - return this.value.eval(env).toCSS(); - } - }; - } - } - - try { - result = expression.call(context); - } catch (e) { - throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message.replace(/["]/g, "'") + "'" , - index: this.index }; - } - if (typeof(result) === 'number') { - return new(tree.Dimension)(result); - } else if (typeof(result) === 'string') { - return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index); - } else if (Array.isArray(result)) { - return new(tree.Anonymous)(result.join(', ')); - } else { - return new(tree.Anonymous)(result); - } - } -}; - -})(require('../tree')); - - -(function (tree) { - -tree.Keyword = function (value) { this.value = value; }; -tree.Keyword.prototype = { - type: "Keyword", - eval: function () { return this; }, - genCSS: function (env, output) { - if (this.value === '%') { throw { type: "Syntax", message: "Invalid % without number" }; } - output.add(this.value); - }, - toCSS: tree.toCSS, - compare: function (other) { - if (other instanceof tree.Keyword) { - return other.value === this.value ? 0 : 1; - } else { - return -1; - } - } -}; - -tree.True = new(tree.Keyword)('true'); -tree.False = new(tree.Keyword)('false'); - -})(require('../tree')); - -(function (tree) { - -tree.Media = function (value, features, index, currentFileInfo) { - this.index = index; - this.currentFileInfo = currentFileInfo; - - var selectors = this.emptySelectors(); - - this.features = new(tree.Value)(features); - this.rules = [new(tree.Ruleset)(selectors, value)]; - this.rules[0].allowImports = true; -}; -tree.Media.prototype = { - type: "Media", - accept: function (visitor) { - if (this.features) { - this.features = visitor.visit(this.features); - } - if (this.rules) { - this.rules = visitor.visitArray(this.rules); - } - }, - genCSS: function (env, output) { - output.add('@media ', this.currentFileInfo, this.index); - this.features.genCSS(env, output); - tree.outputRuleset(env, output, this.rules); - }, - toCSS: tree.toCSS, - eval: function (env) { - if (!env.mediaBlocks) { - env.mediaBlocks = []; - env.mediaPath = []; - } - - var media = new(tree.Media)(null, [], this.index, this.currentFileInfo); - if(this.debugInfo) { - this.rules[0].debugInfo = this.debugInfo; - media.debugInfo = this.debugInfo; - } - var strictMathBypass = false; - if (!env.strictMath) { - strictMathBypass = true; - env.strictMath = true; - } - try { - media.features = this.features.eval(env); - } - finally { - if (strictMathBypass) { - env.strictMath = false; - } - } - - env.mediaPath.push(media); - env.mediaBlocks.push(media); - - env.frames.unshift(this.rules[0]); - media.rules = [this.rules[0].eval(env)]; - env.frames.shift(); - - env.mediaPath.pop(); - - return env.mediaPath.length === 0 ? media.evalTop(env) : - media.evalNested(env); - }, - variable: function (name) { return tree.Ruleset.prototype.variable.call(this.rules[0], name); }, - find: function () { return tree.Ruleset.prototype.find.apply(this.rules[0], arguments); }, - rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.rules[0]); }, - emptySelectors: function() { - var el = new(tree.Element)('', '&', this.index, this.currentFileInfo), - sels = [new(tree.Selector)([el], null, null, this.index, this.currentFileInfo)]; - sels[0].mediaEmpty = true; - return sels; - }, - markReferenced: function () { - var i, rules = this.rules[0].rules; - this.rules[0].markReferenced(); - this.isReferenced = true; - for (i = 0; i < rules.length; i++) { - if (rules[i].markReferenced) { - rules[i].markReferenced(); - } - } - }, - - evalTop: function (env) { - var result = this; - - // Render all dependent Media blocks. - if (env.mediaBlocks.length > 1) { - var selectors = this.emptySelectors(); - result = new(tree.Ruleset)(selectors, env.mediaBlocks); - result.multiMedia = true; - } - - delete env.mediaBlocks; - delete env.mediaPath; - - return result; - }, - evalNested: function (env) { - var i, value, - path = env.mediaPath.concat([this]); - - // Extract the media-query conditions separated with `,` (OR). - for (i = 0; i < path.length; i++) { - value = path[i].features instanceof tree.Value ? - path[i].features.value : path[i].features; - path[i] = Array.isArray(value) ? value : [value]; - } - - // Trace all permutations to generate the resulting media-query. - // - // (a, b and c) with nested (d, e) -> - // a and d - // a and e - // b and c and d - // b and c and e - this.features = new(tree.Value)(this.permute(path).map(function (path) { - path = path.map(function (fragment) { - return fragment.toCSS ? fragment : new(tree.Anonymous)(fragment); - }); - - for(i = path.length - 1; i > 0; i--) { - path.splice(i, 0, new(tree.Anonymous)("and")); - } - - return new(tree.Expression)(path); - })); - - // Fake a tree-node that doesn't output anything. - return new(tree.Ruleset)([], []); - }, - permute: function (arr) { - if (arr.length === 0) { - return []; - } else if (arr.length === 1) { - return arr[0]; - } else { - var result = []; - var rest = this.permute(arr.slice(1)); - for (var i = 0; i < rest.length; i++) { - for (var j = 0; j < arr[0].length; j++) { - result.push([arr[0][j]].concat(rest[i])); - } - } - return result; - } - }, - bubbleSelectors: function (selectors) { - if (!selectors) - return; - this.rules = [new(tree.Ruleset)(selectors.slice(0), [this.rules[0]])]; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.mixin = {}; -tree.mixin.Call = function (elements, args, index, currentFileInfo, important) { - this.selector = new(tree.Selector)(elements); - this.arguments = (args && args.length) ? args : null; - this.index = index; - this.currentFileInfo = currentFileInfo; - this.important = important; -}; -tree.mixin.Call.prototype = { - type: "MixinCall", - accept: function (visitor) { - if (this.selector) { - this.selector = visitor.visit(this.selector); - } - if (this.arguments) { - this.arguments = visitor.visitArray(this.arguments); - } - }, - eval: function (env) { - var mixins, mixin, args, rules = [], match = false, i, m, f, isRecursive, isOneFound, rule, - candidates = [], candidate, conditionResult = [], defaultFunc = tree.defaultFunc, - defaultResult, defNone = 0, defTrue = 1, defFalse = 2, count, originalRuleset; - - args = this.arguments && this.arguments.map(function (a) { - return { name: a.name, value: a.value.eval(env) }; - }); - - for (i = 0; i < env.frames.length; i++) { - if ((mixins = env.frames[i].find(this.selector)).length > 0) { - isOneFound = true; - - // To make `default()` function independent of definition order we have two "subpasses" here. - // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`), - // and build candidate list with corresponding flags. Then, when we know all possible matches, - // we make a final decision. - - for (m = 0; m < mixins.length; m++) { - mixin = mixins[m]; - isRecursive = false; - for(f = 0; f < env.frames.length; f++) { - if ((!(mixin instanceof tree.mixin.Definition)) && mixin === (env.frames[f].originalRuleset || env.frames[f])) { - isRecursive = true; - break; - } - } - if (isRecursive) { - continue; - } - - if (mixin.matchArgs(args, env)) { - candidate = {mixin: mixin, group: defNone}; - - if (mixin.matchCondition) { - for (f = 0; f < 2; f++) { - defaultFunc.value(f); - conditionResult[f] = mixin.matchCondition(args, env); - } - if (conditionResult[0] || conditionResult[1]) { - if (conditionResult[0] != conditionResult[1]) { - candidate.group = conditionResult[1] ? - defTrue : defFalse; - } - - candidates.push(candidate); - } - } - else { - candidates.push(candidate); - } - - match = true; - } - } - - defaultFunc.reset(); - - count = [0, 0, 0]; - for (m = 0; m < candidates.length; m++) { - count[candidates[m].group]++; - } - - if (count[defNone] > 0) { - defaultResult = defFalse; - } else { - defaultResult = defTrue; - if ((count[defTrue] + count[defFalse]) > 1) { - throw { type: 'Runtime', - message: 'Ambiguous use of `default()` found when matching for `' - + this.format(args) + '`', - index: this.index, filename: this.currentFileInfo.filename }; - } - } - - for (m = 0; m < candidates.length; m++) { - candidate = candidates[m].group; - if ((candidate === defNone) || (candidate === defaultResult)) { - try { - mixin = candidates[m].mixin; - if (!(mixin instanceof tree.mixin.Definition)) { - originalRuleset = mixin.originalRuleset || mixin; - mixin = new tree.mixin.Definition("", [], mixin.rules, null, false); - mixin.originalRuleset = originalRuleset; - } - Array.prototype.push.apply( - rules, mixin.evalCall(env, args, this.important).rules); - } catch (e) { - throw { message: e.message, index: this.index, filename: this.currentFileInfo.filename, stack: e.stack }; - } - } - } - - if (match) { - if (!this.currentFileInfo || !this.currentFileInfo.reference) { - for (i = 0; i < rules.length; i++) { - rule = rules[i]; - if (rule.markReferenced) { - rule.markReferenced(); - } - } - } - return rules; - } - } - } - if (isOneFound) { - throw { type: 'Runtime', - message: 'No matching definition was found for `' + this.format(args) + '`', - index: this.index, filename: this.currentFileInfo.filename }; - } else { - throw { type: 'Name', - message: this.selector.toCSS().trim() + " is undefined", - index: this.index, filename: this.currentFileInfo.filename }; - } - }, - format: function (args) { - return this.selector.toCSS().trim() + '(' + - (args ? args.map(function (a) { - var argValue = ""; - if (a.name) { - argValue += a.name + ":"; - } - if (a.value.toCSS) { - argValue += a.value.toCSS(); - } else { - argValue += "???"; - } - return argValue; - }).join(', ') : "") + ")"; - } -}; - -tree.mixin.Definition = function (name, params, rules, condition, variadic, frames) { - this.name = name; - this.selectors = [new(tree.Selector)([new(tree.Element)(null, name, this.index, this.currentFileInfo)])]; - this.params = params; - this.condition = condition; - this.variadic = variadic; - this.arity = params.length; - this.rules = rules; - this._lookups = {}; - this.required = params.reduce(function (count, p) { - if (!p.name || (p.name && !p.value)) { return count + 1; } - else { return count; } - }, 0); - this.parent = tree.Ruleset.prototype; - this.frames = frames; -}; -tree.mixin.Definition.prototype = { - type: "MixinDefinition", - accept: function (visitor) { - if (this.params && this.params.length) { - this.params = visitor.visitArray(this.params); - } - this.rules = visitor.visitArray(this.rules); - if (this.condition) { - this.condition = visitor.visit(this.condition); - } - }, - variable: function (name) { return this.parent.variable.call(this, name); }, - variables: function () { return this.parent.variables.call(this); }, - find: function () { return this.parent.find.apply(this, arguments); }, - rulesets: function () { return this.parent.rulesets.apply(this); }, - - evalParams: function (env, mixinEnv, args, evaldArguments) { - /*jshint boss:true */ - var frame = new(tree.Ruleset)(null, null), - varargs, arg, - params = this.params.slice(0), - i, j, val, name, isNamedFound, argIndex, argsLength = 0; - - mixinEnv = new tree.evalEnv(mixinEnv, [frame].concat(mixinEnv.frames)); - - if (args) { - args = args.slice(0); - argsLength = args.length; - - for(i = 0; i < argsLength; i++) { - arg = args[i]; - if (name = (arg && arg.name)) { - isNamedFound = false; - for(j = 0; j < params.length; j++) { - if (!evaldArguments[j] && name === params[j].name) { - evaldArguments[j] = arg.value.eval(env); - frame.prependRule(new(tree.Rule)(name, arg.value.eval(env))); - isNamedFound = true; - break; - } - } - if (isNamedFound) { - args.splice(i, 1); - i--; - continue; - } else { - throw { type: 'Runtime', message: "Named argument for " + this.name + - ' ' + args[i].name + ' not found' }; - } - } - } - } - argIndex = 0; - for (i = 0; i < params.length; i++) { - if (evaldArguments[i]) { continue; } - - arg = args && args[argIndex]; - - if (name = params[i].name) { - if (params[i].variadic) { - varargs = []; - for (j = argIndex; j < argsLength; j++) { - varargs.push(args[j].value.eval(env)); - } - frame.prependRule(new(tree.Rule)(name, new(tree.Expression)(varargs).eval(env))); - } else { - val = arg && arg.value; - if (val) { - val = val.eval(env); - } else if (params[i].value) { - val = params[i].value.eval(mixinEnv); - frame.resetCache(); - } else { - throw { type: 'Runtime', message: "wrong number of arguments for " + this.name + - ' (' + argsLength + ' for ' + this.arity + ')' }; - } - - frame.prependRule(new(tree.Rule)(name, val)); - evaldArguments[i] = val; - } - } - - if (params[i].variadic && args) { - for (j = argIndex; j < argsLength; j++) { - evaldArguments[j] = args[j].value.eval(env); - } - } - argIndex++; - } - - return frame; - }, - eval: function (env) { - return new tree.mixin.Definition(this.name, this.params, this.rules, this.condition, this.variadic, this.frames || env.frames.slice(0)); - }, - evalCall: function (env, args, important) { - var _arguments = [], - mixinFrames = this.frames ? this.frames.concat(env.frames) : env.frames, - frame = this.evalParams(env, new(tree.evalEnv)(env, mixinFrames), args, _arguments), - rules, ruleset; - - frame.prependRule(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env))); - - rules = this.rules.slice(0); - - ruleset = new(tree.Ruleset)(null, rules); - ruleset.originalRuleset = this; - ruleset = ruleset.eval(new(tree.evalEnv)(env, [this, frame].concat(mixinFrames))); - if (important) { - ruleset = this.parent.makeImportant.apply(ruleset); - } - return ruleset; - }, - matchCondition: function (args, env) { - if (this.condition && !this.condition.eval( - new(tree.evalEnv)(env, - [this.evalParams(env, new(tree.evalEnv)(env, this.frames ? this.frames.concat(env.frames) : env.frames), args, [])] // the parameter variables - .concat(this.frames) // the parent namespace/mixin frames - .concat(env.frames)))) { // the current environment frames - return false; - } - return true; - }, - matchArgs: function (args, env) { - var argsLength = (args && args.length) || 0, len; - - if (! this.variadic) { - if (argsLength < this.required) { return false; } - if (argsLength > this.params.length) { return false; } - } else { - if (argsLength < (this.required - 1)) { return false; } - } - - len = Math.min(argsLength, this.arity); - - for (var i = 0; i < len; i++) { - if (!this.params[i].name && !this.params[i].variadic) { - if (args[i].value.eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) { - return false; - } - } - } - return true; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Negative = function (node) { - this.value = node; -}; -tree.Negative.prototype = { - type: "Negative", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add('-'); - this.value.genCSS(env, output); - }, - toCSS: tree.toCSS, - eval: function (env) { - if (env.isMathOn()) { - return (new(tree.Operation)('*', [new(tree.Dimension)(-1), this.value])).eval(env); - } - return new(tree.Negative)(this.value.eval(env)); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Operation = function (op, operands, isSpaced) { - this.op = op.trim(); - this.operands = operands; - this.isSpaced = isSpaced; -}; -tree.Operation.prototype = { - type: "Operation", - accept: function (visitor) { - this.operands = visitor.visit(this.operands); - }, - eval: function (env) { - var a = this.operands[0].eval(env), - b = this.operands[1].eval(env); - - if (env.isMathOn()) { - if (a instanceof tree.Dimension && b instanceof tree.Color) { - a = a.toColor(); - } - if (b instanceof tree.Dimension && a instanceof tree.Color) { - b = b.toColor(); - } - if (!a.operate) { - throw { type: "Operation", - message: "Operation on an invalid type" }; - } - - return a.operate(env, this.op, b); - } else { - return new(tree.Operation)(this.op, [a, b], this.isSpaced); - } - }, - genCSS: function (env, output) { - this.operands[0].genCSS(env, output); - if (this.isSpaced) { - output.add(" "); - } - output.add(this.op); - if (this.isSpaced) { - output.add(" "); - } - this.operands[1].genCSS(env, output); - }, - toCSS: tree.toCSS -}; - -tree.operate = function (env, op, a, b) { - switch (op) { - case '+': return a + b; - case '-': return a - b; - case '*': return a * b; - case '/': return a / b; - } -}; - -})(require('../tree')); - - -(function (tree) { - -tree.Paren = function (node) { - this.value = node; -}; -tree.Paren.prototype = { - type: "Paren", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add('('); - this.value.genCSS(env, output); - output.add(')'); - }, - toCSS: tree.toCSS, - eval: function (env) { - return new(tree.Paren)(this.value.eval(env)); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Quoted = function (str, content, escaped, index, currentFileInfo) { - this.escaped = escaped; - this.value = content || ''; - this.quote = str.charAt(0); - this.index = index; - this.currentFileInfo = currentFileInfo; -}; -tree.Quoted.prototype = { - type: "Quoted", - genCSS: function (env, output) { - if (!this.escaped) { - output.add(this.quote, this.currentFileInfo, this.index); - } - output.add(this.value); - if (!this.escaped) { - output.add(this.quote); - } - }, - toCSS: tree.toCSS, - eval: function (env) { - var that = this; - var value = this.value.replace(/`([^`]+)`/g, function (_, exp) { - return new(tree.JavaScript)(exp, that.index, true).eval(env).value; - }).replace(/@\{([\w-]+)\}/g, function (_, name) { - var v = new(tree.Variable)('@' + name, that.index, that.currentFileInfo).eval(env, true); - return (v instanceof tree.Quoted) ? v.value : v.toCSS(); - }); - return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index, this.currentFileInfo); - }, - compare: function (x) { - if (!x.toCSS) { - return -1; - } - - var left, right; - - // when comparing quoted strings allow the quote to differ - if (x.type === "Quoted" && !this.escaped && !x.escaped) { - left = x.value; - right = this.value; - } else { - left = this.toCSS(); - right = x.toCSS(); - } - - if (left === right) { - return 0; - } - - return left < right ? -1 : 1; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Rule = function (name, value, important, merge, index, currentFileInfo, inline) { - this.name = name; - this.value = (value instanceof tree.Value || value instanceof tree.Ruleset) ? value : new(tree.Value)([value]); - this.important = important ? ' ' + important.trim() : ''; - this.merge = merge; - this.index = index; - this.currentFileInfo = currentFileInfo; - this.inline = inline || false; - this.variable = name.charAt && (name.charAt(0) === '@'); -}; - -tree.Rule.prototype = { - type: "Rule", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add(this.name + (env.compress ? ':' : ': '), this.currentFileInfo, this.index); - try { - this.value.genCSS(env, output); - } - catch(e) { - e.index = this.index; - e.filename = this.currentFileInfo.filename; - throw e; - } - output.add(this.important + ((this.inline || (env.lastRule && env.compress)) ? "" : ";"), this.currentFileInfo, this.index); - }, - toCSS: tree.toCSS, - eval: function (env) { - var strictMathBypass = false, name = this.name, evaldValue; - if (typeof name !== "string") { - // expand 'primitive' name directly to get - // things faster (~10% for benchmark.less): - name = (name.length === 1) - && (name[0] instanceof tree.Keyword) - ? name[0].value : evalName(env, name); - } - if (name === "font" && !env.strictMath) { - strictMathBypass = true; - env.strictMath = true; - } - try { - evaldValue = this.value.eval(env); - - if (!this.variable && evaldValue.type === "DetachedRuleset") { - throw { message: "Rulesets cannot be evaluated on a property.", - index: this.index, filename: this.currentFileInfo.filename }; - } - - return new(tree.Rule)(name, - evaldValue, - this.important, - this.merge, - this.index, this.currentFileInfo, this.inline); - } - catch(e) { - if (typeof e.index !== 'number') { - e.index = this.index; - e.filename = this.currentFileInfo.filename; - } - throw e; - } - finally { - if (strictMathBypass) { - env.strictMath = false; - } - } - }, - makeImportant: function () { - return new(tree.Rule)(this.name, - this.value, - "!important", - this.merge, - this.index, this.currentFileInfo, this.inline); - } -}; - -function evalName(env, name) { - var value = "", i, n = name.length, - output = {add: function (s) {value += s;}}; - for (i = 0; i < n; i++) { - name[i].eval(env).genCSS(env, output); - } - return value; -} - -})(require('../tree')); - -(function (tree) { - -tree.RulesetCall = function (variable) { - this.variable = variable; -}; -tree.RulesetCall.prototype = { - type: "RulesetCall", - accept: function (visitor) { - }, - eval: function (env) { - var detachedRuleset = new(tree.Variable)(this.variable).eval(env); - return detachedRuleset.callEval(env); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Ruleset = function (selectors, rules, strictImports) { - this.selectors = selectors; - this.rules = rules; - this._lookups = {}; - this.strictImports = strictImports; -}; -tree.Ruleset.prototype = { - type: "Ruleset", - accept: function (visitor) { - if (this.paths) { - visitor.visitArray(this.paths, true); - } else if (this.selectors) { - this.selectors = visitor.visitArray(this.selectors); - } - if (this.rules && this.rules.length) { - this.rules = visitor.visitArray(this.rules); - } - }, - eval: function (env) { - var thisSelectors = this.selectors, selectors, - selCnt, selector, i, defaultFunc = tree.defaultFunc, hasOnePassingSelector = false; - - if (thisSelectors && (selCnt = thisSelectors.length)) { - selectors = []; - defaultFunc.error({ - type: "Syntax", - message: "it is currently only allowed in parametric mixin guards," - }); - for (i = 0; i < selCnt; i++) { - selector = thisSelectors[i].eval(env); - selectors.push(selector); - if (selector.evaldCondition) { - hasOnePassingSelector = true; - } - } - defaultFunc.reset(); - } else { - hasOnePassingSelector = true; - } - - var rules = this.rules ? this.rules.slice(0) : null, - ruleset = new(tree.Ruleset)(selectors, rules, this.strictImports), - rule, subRule; - - ruleset.originalRuleset = this; - ruleset.root = this.root; - ruleset.firstRoot = this.firstRoot; - ruleset.allowImports = this.allowImports; - - if(this.debugInfo) { - ruleset.debugInfo = this.debugInfo; - } - - if (!hasOnePassingSelector) { - rules.length = 0; - } - - // push the current ruleset to the frames stack - var envFrames = env.frames; - envFrames.unshift(ruleset); - - // currrent selectors - var envSelectors = env.selectors; - if (!envSelectors) { - env.selectors = envSelectors = []; - } - envSelectors.unshift(this.selectors); - - // Evaluate imports - if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) { - ruleset.evalImports(env); - } - - // Store the frames around mixin definitions, - // so they can be evaluated like closures when the time comes. - var rsRules = ruleset.rules, rsRuleCnt = rsRules ? rsRules.length : 0; - for (i = 0; i < rsRuleCnt; i++) { - if (rsRules[i] instanceof tree.mixin.Definition || rsRules[i] instanceof tree.DetachedRuleset) { - rsRules[i] = rsRules[i].eval(env); - } - } - - var mediaBlockCount = (env.mediaBlocks && env.mediaBlocks.length) || 0; - - // Evaluate mixin calls. - for (i = 0; i < rsRuleCnt; i++) { - if (rsRules[i] instanceof tree.mixin.Call) { - /*jshint loopfunc:true */ - rules = rsRules[i].eval(env).filter(function(r) { - if ((r instanceof tree.Rule) && r.variable) { - // do not pollute the scope if the variable is - // already there. consider returning false here - // but we need a way to "return" variable from mixins - return !(ruleset.variable(r.name)); - } - return true; - }); - rsRules.splice.apply(rsRules, [i, 1].concat(rules)); - rsRuleCnt += rules.length - 1; - i += rules.length-1; - ruleset.resetCache(); - } else if (rsRules[i] instanceof tree.RulesetCall) { - /*jshint loopfunc:true */ - rules = rsRules[i].eval(env).rules.filter(function(r) { - if ((r instanceof tree.Rule) && r.variable) { - // do not pollute the scope at all - return false; - } - return true; - }); - rsRules.splice.apply(rsRules, [i, 1].concat(rules)); - rsRuleCnt += rules.length - 1; - i += rules.length-1; - ruleset.resetCache(); - } - } - - // Evaluate everything else - for (i = 0; i < rsRules.length; i++) { - rule = rsRules[i]; - if (! (rule instanceof tree.mixin.Definition || rule instanceof tree.DetachedRuleset)) { - rsRules[i] = rule = rule.eval ? rule.eval(env) : rule; - } - } - - // Evaluate everything else - for (i = 0; i < rsRules.length; i++) { - rule = rsRules[i]; - // for rulesets, check if it is a css guard and can be removed - if (rule instanceof tree.Ruleset && rule.selectors && rule.selectors.length === 1) { - // check if it can be folded in (e.g. & where) - if (rule.selectors[0].isJustParentSelector()) { - rsRules.splice(i--, 1); - - for(var j = 0; j < rule.rules.length; j++) { - subRule = rule.rules[j]; - if (!(subRule instanceof tree.Rule) || !subRule.variable) { - rsRules.splice(++i, 0, subRule); - } - } - } - } - } - - // Pop the stack - envFrames.shift(); - envSelectors.shift(); - - if (env.mediaBlocks) { - for (i = mediaBlockCount; i < env.mediaBlocks.length; i++) { - env.mediaBlocks[i].bubbleSelectors(selectors); - } - } - - return ruleset; - }, - evalImports: function(env) { - var rules = this.rules, i, importRules; - if (!rules) { return; } - - for (i = 0; i < rules.length; i++) { - if (rules[i] instanceof tree.Import) { - importRules = rules[i].eval(env); - if (importRules && importRules.length) { - rules.splice.apply(rules, [i, 1].concat(importRules)); - i+= importRules.length-1; - } else { - rules.splice(i, 1, importRules); - } - this.resetCache(); - } - } - }, - makeImportant: function() { - return new tree.Ruleset(this.selectors, this.rules.map(function (r) { - if (r.makeImportant) { - return r.makeImportant(); - } else { - return r; - } - }), this.strictImports); - }, - matchArgs: function (args) { - return !args || args.length === 0; - }, - // lets you call a css selector with a guard - matchCondition: function (args, env) { - var lastSelector = this.selectors[this.selectors.length-1]; - if (!lastSelector.evaldCondition) { - return false; - } - if (lastSelector.condition && - !lastSelector.condition.eval( - new(tree.evalEnv)(env, - env.frames))) { - return false; - } - return true; - }, - resetCache: function () { - this._rulesets = null; - this._variables = null; - this._lookups = {}; - }, - variables: function () { - if (!this._variables) { - this._variables = !this.rules ? {} : this.rules.reduce(function (hash, r) { - if (r instanceof tree.Rule && r.variable === true) { - hash[r.name] = r; - } - return hash; - }, {}); - } - return this._variables; - }, - variable: function (name) { - return this.variables()[name]; - }, - rulesets: function () { - if (!this.rules) { return null; } - - var _Ruleset = tree.Ruleset, _MixinDefinition = tree.mixin.Definition, - filtRules = [], rules = this.rules, cnt = rules.length, - i, rule; - - for (i = 0; i < cnt; i++) { - rule = rules[i]; - if ((rule instanceof _Ruleset) || (rule instanceof _MixinDefinition)) { - filtRules.push(rule); - } - } - - return filtRules; - }, - prependRule: function (rule) { - var rules = this.rules; - if (rules) { rules.unshift(rule); } else { this.rules = [ rule ]; } - }, - find: function (selector, self) { - self = self || this; - var rules = [], match, - key = selector.toCSS(); - - if (key in this._lookups) { return this._lookups[key]; } - - this.rulesets().forEach(function (rule) { - if (rule !== self) { - for (var j = 0; j < rule.selectors.length; j++) { - match = selector.match(rule.selectors[j]); - if (match) { - if (selector.elements.length > match) { - Array.prototype.push.apply(rules, rule.find( - new(tree.Selector)(selector.elements.slice(match)), self)); - } else { - rules.push(rule); - } - break; - } - } - } - }); - this._lookups[key] = rules; - return rules; - }, - genCSS: function (env, output) { - var i, j, - ruleNodes = [], - rulesetNodes = [], - rulesetNodeCnt, - debugInfo, // Line number debugging - rule, - path; - - env.tabLevel = (env.tabLevel || 0); - - if (!this.root) { - env.tabLevel++; - } - - var tabRuleStr = env.compress ? '' : Array(env.tabLevel + 1).join(" "), - tabSetStr = env.compress ? '' : Array(env.tabLevel).join(" "), - sep; - - for (i = 0; i < this.rules.length; i++) { - rule = this.rules[i]; - if (rule.rules || (rule instanceof tree.Media) || rule instanceof tree.Directive || (this.root && rule instanceof tree.Comment)) { - rulesetNodes.push(rule); - } else { - ruleNodes.push(rule); - } - } - - // If this is the root node, we don't render - // a selector, or {}. - if (!this.root) { - debugInfo = tree.debugInfo(env, this, tabSetStr); - - if (debugInfo) { - output.add(debugInfo); - output.add(tabSetStr); - } - - var paths = this.paths, pathCnt = paths.length, - pathSubCnt; - - sep = env.compress ? ',' : (',\n' + tabSetStr); - - for (i = 0; i < pathCnt; i++) { - path = paths[i]; - if (!(pathSubCnt = path.length)) { continue; } - if (i > 0) { output.add(sep); } - - env.firstSelector = true; - path[0].genCSS(env, output); - - env.firstSelector = false; - for (j = 1; j < pathSubCnt; j++) { - path[j].genCSS(env, output); - } - } - - output.add((env.compress ? '{' : ' {\n') + tabRuleStr); - } - - // Compile rules and rulesets - for (i = 0; i < ruleNodes.length; i++) { - rule = ruleNodes[i]; - - // @page{ directive ends up with root elements inside it, a mix of rules and rulesets - // In this instance we do not know whether it is the last property - if (i + 1 === ruleNodes.length && (!this.root || rulesetNodes.length === 0 || this.firstRoot)) { - env.lastRule = true; - } - - if (rule.genCSS) { - rule.genCSS(env, output); - } else if (rule.value) { - output.add(rule.value.toString()); - } - - if (!env.lastRule) { - output.add(env.compress ? '' : ('\n' + tabRuleStr)); - } else { - env.lastRule = false; - } - } - - if (!this.root) { - output.add((env.compress ? '}' : '\n' + tabSetStr + '}')); - env.tabLevel--; - } - - sep = (env.compress ? "" : "\n") + (this.root ? tabRuleStr : tabSetStr); - rulesetNodeCnt = rulesetNodes.length; - if (rulesetNodeCnt) { - if (ruleNodes.length && sep) { output.add(sep); } - rulesetNodes[0].genCSS(env, output); - for (i = 1; i < rulesetNodeCnt; i++) { - if (sep) { output.add(sep); } - rulesetNodes[i].genCSS(env, output); - } - } - - if (!output.isEmpty() && !env.compress && this.firstRoot) { - output.add('\n'); - } - }, - - toCSS: tree.toCSS, - - markReferenced: function () { - if (!this.selectors) { - return; - } - for (var s = 0; s < this.selectors.length; s++) { - this.selectors[s].markReferenced(); - } - }, - - joinSelectors: function (paths, context, selectors) { - for (var s = 0; s < selectors.length; s++) { - this.joinSelector(paths, context, selectors[s]); - } - }, - - joinSelector: function (paths, context, selector) { - - var i, j, k, - hasParentSelector, newSelectors, el, sel, parentSel, - newSelectorPath, afterParentJoin, newJoinedSelector, - newJoinedSelectorEmpty, lastSelector, currentElements, - selectorsMultiplied; - - for (i = 0; i < selector.elements.length; i++) { - el = selector.elements[i]; - if (el.value === '&') { - hasParentSelector = true; - } - } - - if (!hasParentSelector) { - if (context.length > 0) { - for (i = 0; i < context.length; i++) { - paths.push(context[i].concat(selector)); - } - } - else { - paths.push([selector]); - } - return; - } - - // The paths are [[Selector]] - // The first list is a list of comma seperated selectors - // The inner list is a list of inheritance seperated selectors - // e.g. - // .a, .b { - // .c { - // } - // } - // == [[.a] [.c]] [[.b] [.c]] - // - - // the elements from the current selector so far - currentElements = []; - // the current list of new selectors to add to the path. - // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors - // by the parents - newSelectors = [[]]; - - for (i = 0; i < selector.elements.length; i++) { - el = selector.elements[i]; - // non parent reference elements just get added - if (el.value !== "&") { - currentElements.push(el); - } else { - // the new list of selectors to add - selectorsMultiplied = []; - - // merge the current list of non parent selector elements - // on to the current list of selectors to add - if (currentElements.length > 0) { - this.mergeElementsOnToSelectors(currentElements, newSelectors); - } - - // loop through our current selectors - for (j = 0; j < newSelectors.length; j++) { - sel = newSelectors[j]; - // if we don't have any parent paths, the & might be in a mixin so that it can be used - // whether there are parents or not - if (context.length === 0) { - // the combinator used on el should now be applied to the next element instead so that - // it is not lost - if (sel.length > 0) { - sel[0].elements = sel[0].elements.slice(0); - sel[0].elements.push(new(tree.Element)(el.combinator, '', el.index, el.currentFileInfo)); - } - selectorsMultiplied.push(sel); - } - else { - // and the parent selectors - for (k = 0; k < context.length; k++) { - parentSel = context[k]; - // We need to put the current selectors - // then join the last selector's elements on to the parents selectors - - // our new selector path - newSelectorPath = []; - // selectors from the parent after the join - afterParentJoin = []; - newJoinedSelectorEmpty = true; - - //construct the joined selector - if & is the first thing this will be empty, - // if not newJoinedSelector will be the last set of elements in the selector - if (sel.length > 0) { - newSelectorPath = sel.slice(0); - lastSelector = newSelectorPath.pop(); - newJoinedSelector = selector.createDerived(lastSelector.elements.slice(0)); - newJoinedSelectorEmpty = false; - } - else { - newJoinedSelector = selector.createDerived([]); - } - - //put together the parent selectors after the join - if (parentSel.length > 1) { - afterParentJoin = afterParentJoin.concat(parentSel.slice(1)); - } - - if (parentSel.length > 0) { - newJoinedSelectorEmpty = false; - - // join the elements so far with the first part of the parent - newJoinedSelector.elements.push(new(tree.Element)(el.combinator, parentSel[0].elements[0].value, el.index, el.currentFileInfo)); - newJoinedSelector.elements = newJoinedSelector.elements.concat(parentSel[0].elements.slice(1)); - } - - if (!newJoinedSelectorEmpty) { - // now add the joined selector - newSelectorPath.push(newJoinedSelector); - } - - // and the rest of the parent - newSelectorPath = newSelectorPath.concat(afterParentJoin); - - // add that to our new set of selectors - selectorsMultiplied.push(newSelectorPath); - } - } - } - - // our new selectors has been multiplied, so reset the state - newSelectors = selectorsMultiplied; - currentElements = []; - } - } - - // if we have any elements left over (e.g. .a& .b == .b) - // add them on to all the current selectors - if (currentElements.length > 0) { - this.mergeElementsOnToSelectors(currentElements, newSelectors); - } - - for (i = 0; i < newSelectors.length; i++) { - if (newSelectors[i].length > 0) { - paths.push(newSelectors[i]); - } - } - }, - - mergeElementsOnToSelectors: function(elements, selectors) { - var i, sel; - - if (selectors.length === 0) { - selectors.push([ new(tree.Selector)(elements) ]); - return; - } - - for (i = 0; i < selectors.length; i++) { - sel = selectors[i]; - - // if the previous thing in sel is a parent this needs to join on to it - if (sel.length > 0) { - sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements)); - } - else { - sel.push(new(tree.Selector)(elements)); - } - } - } -}; -})(require('../tree')); - -(function (tree) { - -tree.Selector = function (elements, extendList, condition, index, currentFileInfo, isReferenced) { - this.elements = elements; - this.extendList = extendList; - this.condition = condition; - this.currentFileInfo = currentFileInfo || {}; - this.isReferenced = isReferenced; - if (!condition) { - this.evaldCondition = true; - } -}; -tree.Selector.prototype = { - type: "Selector", - accept: function (visitor) { - if (this.elements) { - this.elements = visitor.visitArray(this.elements); - } - if (this.extendList) { - this.extendList = visitor.visitArray(this.extendList); - } - if (this.condition) { - this.condition = visitor.visit(this.condition); - } - }, - createDerived: function(elements, extendList, evaldCondition) { - evaldCondition = (evaldCondition != null) ? evaldCondition : this.evaldCondition; - var newSelector = new(tree.Selector)(elements, extendList || this.extendList, null, this.index, this.currentFileInfo, this.isReferenced); - newSelector.evaldCondition = evaldCondition; - newSelector.mediaEmpty = this.mediaEmpty; - return newSelector; - }, - match: function (other) { - var elements = this.elements, - len = elements.length, - olen, i; - - other.CacheElements(); - - olen = other._elements.length; - if (olen === 0 || len < olen) { - return 0; - } else { - for (i = 0; i < olen; i++) { - if (elements[i].value !== other._elements[i]) { - return 0; - } - } - } - - return olen; // return number of matched elements - }, - CacheElements: function(){ - var css = '', len, v, i; - - if( !this._elements ){ - - len = this.elements.length; - for(i = 0; i < len; i++){ - - v = this.elements[i]; - css += v.combinator.value; - - if( !v.value.value ){ - css += v.value; - continue; - } - - if( typeof v.value.value !== "string" ){ - css = ''; - break; - } - css += v.value.value; - } - - this._elements = css.match(/[,&#\.\w-]([\w-]|(\\.))*/g); - - if (this._elements) { - if (this._elements[0] === "&") { - this._elements.shift(); - } - - } else { - this._elements = []; - } - - } - }, - isJustParentSelector: function() { - return !this.mediaEmpty && - this.elements.length === 1 && - this.elements[0].value === '&' && - (this.elements[0].combinator.value === ' ' || this.elements[0].combinator.value === ''); - }, - eval: function (env) { - var evaldCondition = this.condition && this.condition.eval(env), - elements = this.elements, extendList = this.extendList; - - elements = elements && elements.map(function (e) { return e.eval(env); }); - extendList = extendList && extendList.map(function(extend) { return extend.eval(env); }); - - return this.createDerived(elements, extendList, evaldCondition); - }, - genCSS: function (env, output) { - var i, element; - if ((!env || !env.firstSelector) && this.elements[0].combinator.value === "") { - output.add(' ', this.currentFileInfo, this.index); - } - if (!this._css) { - //TODO caching? speed comparison? - for(i = 0; i < this.elements.length; i++) { - element = this.elements[i]; - element.genCSS(env, output); - } - } - }, - toCSS: tree.toCSS, - markReferenced: function () { - this.isReferenced = true; - }, - getIsReferenced: function() { - return !this.currentFileInfo.reference || this.isReferenced; - }, - getIsOutput: function() { - return this.evaldCondition; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.UnicodeDescriptor = function (value) { - this.value = value; -}; -tree.UnicodeDescriptor.prototype = { - type: "UnicodeDescriptor", - genCSS: function (env, output) { - output.add(this.value); - }, - toCSS: tree.toCSS, - eval: function () { return this; } -}; - -})(require('../tree')); - -(function (tree) { - -tree.URL = function (val, currentFileInfo, isEvald) { - this.value = val; - this.currentFileInfo = currentFileInfo; - this.isEvald = isEvald; -}; -tree.URL.prototype = { - type: "Url", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add("url("); - this.value.genCSS(env, output); - output.add(")"); - }, - toCSS: tree.toCSS, - eval: function (ctx) { - var val = this.value.eval(ctx), - rootpath; - - if (!this.isEvald) { - // Add the base path if the URL is relative - rootpath = this.currentFileInfo && this.currentFileInfo.rootpath; - if (rootpath && typeof val.value === "string" && ctx.isPathRelative(val.value)) { - if (!val.quote) { - rootpath = rootpath.replace(/[\(\)'"\s]/g, function(match) { return "\\"+match; }); - } - val.value = rootpath + val.value; - } - - val.value = ctx.normalizePath(val.value); - - // Add url args if enabled - if (ctx.urlArgs) { - if (!val.value.match(/^\s*data:/)) { - var delimiter = val.value.indexOf('?') === -1 ? '?' : '&'; - var urlArgs = delimiter + ctx.urlArgs; - if (val.value.indexOf('#') !== -1) { - val.value = val.value.replace('#', urlArgs + '#'); - } else { - val.value += urlArgs; - } - } - } - } - - return new(tree.URL)(val, this.currentFileInfo, true); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Value = function (value) { - this.value = value; -}; -tree.Value.prototype = { - type: "Value", - accept: function (visitor) { - if (this.value) { - this.value = visitor.visitArray(this.value); - } - }, - eval: function (env) { - if (this.value.length === 1) { - return this.value[0].eval(env); - } else { - return new(tree.Value)(this.value.map(function (v) { - return v.eval(env); - })); - } - }, - genCSS: function (env, output) { - var i; - for(i = 0; i < this.value.length; i++) { - this.value[i].genCSS(env, output); - if (i+1 < this.value.length) { - output.add((env && env.compress) ? ',' : ', '); - } - } - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -tree.Variable = function (name, index, currentFileInfo) { - this.name = name; - this.index = index; - this.currentFileInfo = currentFileInfo || {}; -}; -tree.Variable.prototype = { - type: "Variable", - eval: function (env) { - var variable, name = this.name; - - if (name.indexOf('@@') === 0) { - name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value; - } - - if (this.evaluating) { - throw { type: 'Name', - message: "Recursive variable definition for " + name, - filename: this.currentFileInfo.file, - index: this.index }; - } - - this.evaluating = true; - - variable = tree.find(env.frames, function (frame) { - var v = frame.variable(name); - if (v) { - return v.value.eval(env); - } - }); - if (variable) { - this.evaluating = false; - return variable; - } else { - throw { type: 'Name', - message: "variable " + name + " is undefined", - filename: this.currentFileInfo.filename, - index: this.index }; - } - } -}; - -})(require('../tree')); - -(function (tree) { - - var parseCopyProperties = [ - 'paths', // option - unmodified - paths to search for imports on - 'optimization', // option - optimization level (for the chunker) - 'files', // list of files that have been imported, used for import-once - 'contents', // map - filename to contents of all the files - 'contentsIgnoredChars', // map - filename to lines at the begining of each file to ignore - 'relativeUrls', // option - whether to adjust URL's to be relative - 'rootpath', // option - rootpath to append to URL's - 'strictImports', // option - - 'insecure', // option - whether to allow imports from insecure ssl hosts - 'dumpLineNumbers', // option - whether to dump line numbers - 'compress', // option - whether to compress - 'processImports', // option - whether to process imports. if false then imports will not be imported - 'syncImport', // option - whether to import synchronously - 'javascriptEnabled',// option - whether JavaScript is enabled. if undefined, defaults to true - 'mime', // browser only - mime type for sheet import - 'useFileCache', // browser only - whether to use the per file session cache - 'currentFileInfo' // information about the current file - for error reporting and importing and making urls relative etc. - ]; - - //currentFileInfo = { - // 'relativeUrls' - option - whether to adjust URL's to be relative - // 'filename' - full resolved filename of current file - // 'rootpath' - path to append to normal URLs for this node - // 'currentDirectory' - path to the current file, absolute - // 'rootFilename' - filename of the base file - // 'entryPath' - absolute path to the entry file - // 'reference' - whether the file should not be output and only output parts that are referenced - - tree.parseEnv = function(options) { - copyFromOriginal(options, this, parseCopyProperties); - - if (!this.contents) { this.contents = {}; } - if (!this.contentsIgnoredChars) { this.contentsIgnoredChars = {}; } - if (!this.files) { this.files = {}; } - - if (!this.currentFileInfo) { - var filename = (options && options.filename) || "input"; - var entryPath = filename.replace(/[^\/\\]*$/, ""); - if (options) { - options.filename = null; - } - this.currentFileInfo = { - filename: filename, - relativeUrls: this.relativeUrls, - rootpath: (options && options.rootpath) || "", - currentDirectory: entryPath, - entryPath: entryPath, - rootFilename: filename - }; - } - }; - - var evalCopyProperties = [ - 'silent', // whether to swallow errors and warnings - 'verbose', // whether to log more activity - 'compress', // whether to compress - 'yuicompress', // whether to compress with the outside tool yui compressor - 'ieCompat', // whether to enforce IE compatibility (IE8 data-uri) - 'strictMath', // whether math has to be within parenthesis - 'strictUnits', // whether units need to evaluate correctly - 'cleancss', // whether to compress with clean-css - 'sourceMap', // whether to output a source map - 'importMultiple', // whether we are currently importing multiple copies - 'urlArgs' // whether to add args into url tokens - ]; - - tree.evalEnv = function(options, frames) { - copyFromOriginal(options, this, evalCopyProperties); - - this.frames = frames || []; - }; - - tree.evalEnv.prototype.inParenthesis = function () { - if (!this.parensStack) { - this.parensStack = []; - } - this.parensStack.push(true); - }; - - tree.evalEnv.prototype.outOfParenthesis = function () { - this.parensStack.pop(); - }; - - tree.evalEnv.prototype.isMathOn = function () { - return this.strictMath ? (this.parensStack && this.parensStack.length) : true; - }; - - tree.evalEnv.prototype.isPathRelative = function (path) { - return !/^(?:[a-z-]+:|\/)/.test(path); - }; - - tree.evalEnv.prototype.normalizePath = function( path ) { - var - segments = path.split("/").reverse(), - segment; - - path = []; - while (segments.length !== 0 ) { - segment = segments.pop(); - switch( segment ) { - case ".": - break; - case "..": - if ((path.length === 0) || (path[path.length - 1] === "..")) { - path.push( segment ); - } else { - path.pop(); - } - break; - default: - path.push( segment ); - break; - } - } - - return path.join("/"); - }; - - //todo - do the same for the toCSS env - //tree.toCSSEnv = function (options) { - //}; - - var copyFromOriginal = function(original, destination, propertiesToCopy) { - if (!original) { return; } - - for(var i = 0; i < propertiesToCopy.length; i++) { - if (original.hasOwnProperty(propertiesToCopy[i])) { - destination[propertiesToCopy[i]] = original[propertiesToCopy[i]]; - } - } - }; - -})(require('./tree')); - -(function (tree) { - - var _visitArgs = { visitDeeper: true }, - _hasIndexed = false; - - function _noop(node) { - return node; - } - - function indexNodeTypes(parent, ticker) { - // add .typeIndex to tree node types for lookup table - var key, child; - for (key in parent) { - if (parent.hasOwnProperty(key)) { - child = parent[key]; - switch (typeof child) { - case "function": - // ignore bound functions directly on tree which do not have a prototype - // or aren't nodes - if (child.prototype && child.prototype.type) { - child.prototype.typeIndex = ticker++; - } - break; - case "object": - ticker = indexNodeTypes(child, ticker); - break; - } - } - } - return ticker; - } - - tree.visitor = function(implementation) { - this._implementation = implementation; - this._visitFnCache = []; - - if (!_hasIndexed) { - indexNodeTypes(tree, 1); - _hasIndexed = true; - } - }; - - tree.visitor.prototype = { - visit: function(node) { - if (!node) { - return node; - } - - var nodeTypeIndex = node.typeIndex; - if (!nodeTypeIndex) { - return node; - } - - var visitFnCache = this._visitFnCache, - impl = this._implementation, - aryIndx = nodeTypeIndex << 1, - outAryIndex = aryIndx | 1, - func = visitFnCache[aryIndx], - funcOut = visitFnCache[outAryIndex], - visitArgs = _visitArgs, - fnName; - - visitArgs.visitDeeper = true; - - if (!func) { - fnName = "visit" + node.type; - func = impl[fnName] || _noop; - funcOut = impl[fnName + "Out"] || _noop; - visitFnCache[aryIndx] = func; - visitFnCache[outAryIndex] = funcOut; - } - - if (func !== _noop) { - var newNode = func.call(impl, node, visitArgs); - if (impl.isReplacing) { - node = newNode; - } - } - - if (visitArgs.visitDeeper && node && node.accept) { - node.accept(this); - } - - if (funcOut != _noop) { - funcOut.call(impl, node); - } - - return node; - }, - visitArray: function(nodes, nonReplacing) { - if (!nodes) { - return nodes; - } - - var cnt = nodes.length, i; - - // Non-replacing - if (nonReplacing || !this._implementation.isReplacing) { - for (i = 0; i < cnt; i++) { - this.visit(nodes[i]); - } - return nodes; - } - - // Replacing - var out = []; - for (i = 0; i < cnt; i++) { - var evald = this.visit(nodes[i]); - if (!evald.splice) { - out.push(evald); - } else if (evald.length) { - this.flatten(evald, out); - } - } - return out; - }, - flatten: function(arr, out) { - if (!out) { - out = []; - } - - var cnt, i, item, - nestedCnt, j, nestedItem; - - for (i = 0, cnt = arr.length; i < cnt; i++) { - item = arr[i]; - if (!item.splice) { - out.push(item); - continue; - } - - for (j = 0, nestedCnt = item.length; j < nestedCnt; j++) { - nestedItem = item[j]; - if (!nestedItem.splice) { - out.push(nestedItem); - } else if (nestedItem.length) { - this.flatten(nestedItem, out); - } - } - } - - return out; - } - }; - -})(require('./tree')); -(function (tree) { - tree.importVisitor = function(importer, finish, evalEnv, onceFileDetectionMap, recursionDetector) { - this._visitor = new tree.visitor(this); - this._importer = importer; - this._finish = finish; - this.env = evalEnv || new tree.evalEnv(); - this.importCount = 0; - this.onceFileDetectionMap = onceFileDetectionMap || {}; - this.recursionDetector = {}; - if (recursionDetector) { - for(var fullFilename in recursionDetector) { - if (recursionDetector.hasOwnProperty(fullFilename)) { - this.recursionDetector[fullFilename] = true; - } - } - } - }; - - tree.importVisitor.prototype = { - isReplacing: true, - run: function (root) { - var error; - try { - // process the contents - this._visitor.visit(root); - } - catch(e) { - error = e; - } - - this.isFinished = true; - - if (this.importCount === 0) { - this._finish(error); - } - }, - visitImport: function (importNode, visitArgs) { - var importVisitor = this, - evaldImportNode, - inlineCSS = importNode.options.inline; - - if (!importNode.css || inlineCSS) { - - try { - evaldImportNode = importNode.evalForImport(this.env); - } catch(e){ - if (!e.filename) { e.index = importNode.index; e.filename = importNode.currentFileInfo.filename; } - // attempt to eval properly and treat as css - importNode.css = true; - // if that fails, this error will be thrown - importNode.error = e; - } - - if (evaldImportNode && (!evaldImportNode.css || inlineCSS)) { - importNode = evaldImportNode; - this.importCount++; - var env = new tree.evalEnv(this.env, this.env.frames.slice(0)); - - if (importNode.options.multiple) { - env.importMultiple = true; - } - - this._importer.push(importNode.getPath(), importNode.currentFileInfo, importNode.options, function (e, root, importedAtRoot, fullPath) { - if (e && !e.filename) { e.index = importNode.index; e.filename = importNode.currentFileInfo.filename; } - - if (!env.importMultiple) { - if (importedAtRoot) { - importNode.skip = true; - } else { - importNode.skip = function() { - if (fullPath in importVisitor.onceFileDetectionMap) { - return true; - } - importVisitor.onceFileDetectionMap[fullPath] = true; - return false; - }; - } - } - - var subFinish = function(e) { - importVisitor.importCount--; - - if (importVisitor.importCount === 0 && importVisitor.isFinished) { - importVisitor._finish(e); - } - }; - - if (root) { - importNode.root = root; - importNode.importedFilename = fullPath; - var duplicateImport = importedAtRoot || fullPath in importVisitor.recursionDetector; - - if (!inlineCSS && (env.importMultiple || !duplicateImport)) { - importVisitor.recursionDetector[fullPath] = true; - new(tree.importVisitor)(importVisitor._importer, subFinish, env, importVisitor.onceFileDetectionMap, importVisitor.recursionDetector) - .run(root); - return; - } - } - - subFinish(); - }); - } - } - visitArgs.visitDeeper = false; - return importNode; - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - return ruleNode; - }, - visitDirective: function (directiveNode, visitArgs) { - this.env.frames.unshift(directiveNode); - return directiveNode; - }, - visitDirectiveOut: function (directiveNode) { - this.env.frames.shift(); - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - this.env.frames.unshift(mixinDefinitionNode); - return mixinDefinitionNode; - }, - visitMixinDefinitionOut: function (mixinDefinitionNode) { - this.env.frames.shift(); - }, - visitRuleset: function (rulesetNode, visitArgs) { - this.env.frames.unshift(rulesetNode); - return rulesetNode; - }, - visitRulesetOut: function (rulesetNode) { - this.env.frames.shift(); - }, - visitMedia: function (mediaNode, visitArgs) { - this.env.frames.unshift(mediaNode.ruleset); - return mediaNode; - }, - visitMediaOut: function (mediaNode) { - this.env.frames.shift(); - } - }; - -})(require('./tree')); -(function (tree) { - tree.joinSelectorVisitor = function() { - this.contexts = [[]]; - this._visitor = new tree.visitor(this); - }; - - tree.joinSelectorVisitor.prototype = { - run: function (root) { - return this._visitor.visit(root); - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - - visitRuleset: function (rulesetNode, visitArgs) { - var context = this.contexts[this.contexts.length - 1], - paths = [], selectors; - - this.contexts.push(paths); - - if (! rulesetNode.root) { - selectors = rulesetNode.selectors; - if (selectors) { - selectors = selectors.filter(function(selector) { return selector.getIsOutput(); }); - rulesetNode.selectors = selectors.length ? selectors : (selectors = null); - if (selectors) { rulesetNode.joinSelectors(paths, context, selectors); } - } - if (!selectors) { rulesetNode.rules = null; } - rulesetNode.paths = paths; - } - }, - visitRulesetOut: function (rulesetNode) { - this.contexts.length = this.contexts.length - 1; - }, - visitMedia: function (mediaNode, visitArgs) { - var context = this.contexts[this.contexts.length - 1]; - mediaNode.rules[0].root = (context.length === 0 || context[0].multiMedia); - } - }; - -})(require('./tree')); -(function (tree) { - tree.toCSSVisitor = function(env) { - this._visitor = new tree.visitor(this); - this._env = env; - }; - - tree.toCSSVisitor.prototype = { - isReplacing: true, - run: function (root) { - return this._visitor.visit(root); - }, - - visitRule: function (ruleNode, visitArgs) { - if (ruleNode.variable) { - return []; - } - return ruleNode; - }, - - visitMixinDefinition: function (mixinNode, visitArgs) { - // mixin definitions do not get eval'd - this means they keep state - // so we have to clear that state here so it isn't used if toCSS is called twice - mixinNode.frames = []; - return []; - }, - - visitExtend: function (extendNode, visitArgs) { - return []; - }, - - visitComment: function (commentNode, visitArgs) { - if (commentNode.isSilent(this._env)) { - return []; - } - return commentNode; - }, - - visitMedia: function(mediaNode, visitArgs) { - mediaNode.accept(this._visitor); - visitArgs.visitDeeper = false; - - if (!mediaNode.rules.length) { - return []; - } - return mediaNode; - }, - - visitDirective: function(directiveNode, visitArgs) { - if (directiveNode.currentFileInfo.reference && !directiveNode.isReferenced) { - return []; - } - if (directiveNode.name === "@charset") { - // Only output the debug info together with subsequent @charset definitions - // a comment (or @media statement) before the actual @charset directive would - // be considered illegal css as it has to be on the first line - if (this.charset) { - if (directiveNode.debugInfo) { - var comment = new tree.Comment("/* " + directiveNode.toCSS(this._env).replace(/\n/g, "")+" */\n"); - comment.debugInfo = directiveNode.debugInfo; - return this._visitor.visit(comment); - } - return []; - } - this.charset = true; - } - return directiveNode; - }, - - checkPropertiesInRoot: function(rules) { - var ruleNode; - for(var i = 0; i < rules.length; i++) { - ruleNode = rules[i]; - if (ruleNode instanceof tree.Rule && !ruleNode.variable) { - throw { message: "properties must be inside selector blocks, they cannot be in the root.", - index: ruleNode.index, filename: ruleNode.currentFileInfo ? ruleNode.currentFileInfo.filename : null}; - } - } - }, - - visitRuleset: function (rulesetNode, visitArgs) { - var rule, rulesets = []; - if (rulesetNode.firstRoot) { - this.checkPropertiesInRoot(rulesetNode.rules); - } - if (! rulesetNode.root) { - if (rulesetNode.paths) { - rulesetNode.paths = rulesetNode.paths - .filter(function(p) { - var i; - if (p[0].elements[0].combinator.value === ' ') { - p[0].elements[0].combinator = new(tree.Combinator)(''); - } - for(i = 0; i < p.length; i++) { - if (p[i].getIsReferenced() && p[i].getIsOutput()) { - return true; - } - } - return false; - }); - } - - // Compile rules and rulesets - var nodeRules = rulesetNode.rules, nodeRuleCnt = nodeRules ? nodeRules.length : 0; - for (var i = 0; i < nodeRuleCnt; ) { - rule = nodeRules[i]; - if (rule && rule.rules) { - // visit because we are moving them out from being a child - rulesets.push(this._visitor.visit(rule)); - nodeRules.splice(i, 1); - nodeRuleCnt--; - continue; - } - i++; - } - // accept the visitor to remove rules and refactor itself - // then we can decide now whether we want it or not - if (nodeRuleCnt > 0) { - rulesetNode.accept(this._visitor); - } else { - rulesetNode.rules = null; - } - visitArgs.visitDeeper = false; - - nodeRules = rulesetNode.rules; - if (nodeRules) { - this._mergeRules(nodeRules); - nodeRules = rulesetNode.rules; - } - if (nodeRules) { - this._removeDuplicateRules(nodeRules); - nodeRules = rulesetNode.rules; - } - - // now decide whether we keep the ruleset - if (nodeRules && nodeRules.length > 0 && rulesetNode.paths.length > 0) { - rulesets.splice(0, 0, rulesetNode); - } - } else { - rulesetNode.accept(this._visitor); - visitArgs.visitDeeper = false; - if (rulesetNode.firstRoot || (rulesetNode.rules && rulesetNode.rules.length > 0)) { - rulesets.splice(0, 0, rulesetNode); - } - } - if (rulesets.length === 1) { - return rulesets[0]; - } - return rulesets; - }, - - _removeDuplicateRules: function(rules) { - if (!rules) { return; } - - // remove duplicates - var ruleCache = {}, - ruleList, rule, i; - - for(i = rules.length - 1; i >= 0 ; i--) { - rule = rules[i]; - if (rule instanceof tree.Rule) { - if (!ruleCache[rule.name]) { - ruleCache[rule.name] = rule; - } else { - ruleList = ruleCache[rule.name]; - if (ruleList instanceof tree.Rule) { - ruleList = ruleCache[rule.name] = [ruleCache[rule.name].toCSS(this._env)]; - } - var ruleCSS = rule.toCSS(this._env); - if (ruleList.indexOf(ruleCSS) !== -1) { - rules.splice(i, 1); - } else { - ruleList.push(ruleCSS); - } - } - } - } - }, - - _mergeRules: function (rules) { - if (!rules) { return; } - - var groups = {}, - parts, - rule, - key; - - for (var i = 0; i < rules.length; i++) { - rule = rules[i]; - - if ((rule instanceof tree.Rule) && rule.merge) { - key = [rule.name, - rule.important ? "!" : ""].join(","); - - if (!groups[key]) { - groups[key] = []; - } else { - rules.splice(i--, 1); - } - - groups[key].push(rule); - } - } - - Object.keys(groups).map(function (k) { - - function toExpression(values) { - return new (tree.Expression)(values.map(function (p) { - return p.value; - })); - } - - function toValue(values) { - return new (tree.Value)(values.map(function (p) { - return p; - })); - } - - parts = groups[k]; - - if (parts.length > 1) { - rule = parts[0]; - var spacedGroups = []; - var lastSpacedGroup = []; - parts.map(function (p) { - if (p.merge==="+") { - if (lastSpacedGroup.length > 0) { - spacedGroups.push(toExpression(lastSpacedGroup)); - } - lastSpacedGroup = []; - } - lastSpacedGroup.push(p); - }); - spacedGroups.push(toExpression(lastSpacedGroup)); - rule.value = toValue(spacedGroups); - } - }); - } - }; - -})(require('./tree')); -(function (tree) { - /*jshint loopfunc:true */ - - tree.extendFinderVisitor = function() { - this._visitor = new tree.visitor(this); - this.contexts = []; - this.allExtendsStack = [[]]; - }; - - tree.extendFinderVisitor.prototype = { - run: function (root) { - root = this._visitor.visit(root); - root.allExtends = this.allExtendsStack[0]; - return root; - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitRuleset: function (rulesetNode, visitArgs) { - if (rulesetNode.root) { - return; - } - - var i, j, extend, allSelectorsExtendList = [], extendList; - - // get &:extend(.a); rules which apply to all selectors in this ruleset - var rules = rulesetNode.rules, ruleCnt = rules ? rules.length : 0; - for(i = 0; i < ruleCnt; i++) { - if (rulesetNode.rules[i] instanceof tree.Extend) { - allSelectorsExtendList.push(rules[i]); - rulesetNode.extendOnEveryPath = true; - } - } - - // now find every selector and apply the extends that apply to all extends - // and the ones which apply to an individual extend - var paths = rulesetNode.paths; - for(i = 0; i < paths.length; i++) { - var selectorPath = paths[i], - selector = selectorPath[selectorPath.length - 1], - selExtendList = selector.extendList; - - extendList = selExtendList ? selExtendList.slice(0).concat(allSelectorsExtendList) - : allSelectorsExtendList; - - if (extendList) { - extendList = extendList.map(function(allSelectorsExtend) { - return allSelectorsExtend.clone(); - }); - } - - for(j = 0; j < extendList.length; j++) { - this.foundExtends = true; - extend = extendList[j]; - extend.findSelfSelectors(selectorPath); - extend.ruleset = rulesetNode; - if (j === 0) { extend.firstExtendOnThisSelectorPath = true; } - this.allExtendsStack[this.allExtendsStack.length-1].push(extend); - } - } - - this.contexts.push(rulesetNode.selectors); - }, - visitRulesetOut: function (rulesetNode) { - if (!rulesetNode.root) { - this.contexts.length = this.contexts.length - 1; - } - }, - visitMedia: function (mediaNode, visitArgs) { - mediaNode.allExtends = []; - this.allExtendsStack.push(mediaNode.allExtends); - }, - visitMediaOut: function (mediaNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - }, - visitDirective: function (directiveNode, visitArgs) { - directiveNode.allExtends = []; - this.allExtendsStack.push(directiveNode.allExtends); - }, - visitDirectiveOut: function (directiveNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - } - }; - - tree.processExtendsVisitor = function() { - this._visitor = new tree.visitor(this); - }; - - tree.processExtendsVisitor.prototype = { - run: function(root) { - var extendFinder = new tree.extendFinderVisitor(); - extendFinder.run(root); - if (!extendFinder.foundExtends) { return root; } - root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends)); - this.allExtendsStack = [root.allExtends]; - return this._visitor.visit(root); - }, - doExtendChaining: function (extendsList, extendsListTarget, iterationCount) { - // - // chaining is different from normal extension.. if we extend an extend then we are not just copying, altering and pasting - // the selector we would do normally, but we are also adding an extend with the same target selector - // this means this new extend can then go and alter other extends - // - // this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors - // this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already processed if - // we look at each selector at a time, as is done in visitRuleset - - var extendIndex, targetExtendIndex, matches, extendsToAdd = [], newSelector, extendVisitor = this, selectorPath, extend, targetExtend, newExtend; - - iterationCount = iterationCount || 0; - - //loop through comparing every extend with every target extend. - // a target extend is the one on the ruleset we are looking at copy/edit/pasting in place - // e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one - // and the second is the target. - // the seperation into two lists allows us to process a subset of chains with a bigger set, as is the - // case when processing media queries - for(extendIndex = 0; extendIndex < extendsList.length; extendIndex++){ - for(targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++){ - - extend = extendsList[extendIndex]; - targetExtend = extendsListTarget[targetExtendIndex]; - - // look for circular references - if( extend.parent_ids.indexOf( targetExtend.object_id ) >= 0 ){ continue; } - - // find a match in the target extends self selector (the bit before :extend) - selectorPath = [targetExtend.selfSelectors[0]]; - matches = extendVisitor.findMatch(extend, selectorPath); - - if (matches.length) { - - // we found a match, so for each self selector.. - extend.selfSelectors.forEach(function(selfSelector) { - - // process the extend as usual - newSelector = extendVisitor.extendSelector(matches, selectorPath, selfSelector); - - // but now we create a new extend from it - newExtend = new(tree.Extend)(targetExtend.selector, targetExtend.option, 0); - newExtend.selfSelectors = newSelector; - - // add the extend onto the list of extends for that selector - newSelector[newSelector.length-1].extendList = [newExtend]; - - // record that we need to add it. - extendsToAdd.push(newExtend); - newExtend.ruleset = targetExtend.ruleset; - - //remember its parents for circular references - newExtend.parent_ids = newExtend.parent_ids.concat(targetExtend.parent_ids, extend.parent_ids); - - // only process the selector once.. if we have :extend(.a,.b) then multiple - // extends will look at the same selector path, so when extending - // we know that any others will be duplicates in terms of what is added to the css - if (targetExtend.firstExtendOnThisSelectorPath) { - newExtend.firstExtendOnThisSelectorPath = true; - targetExtend.ruleset.paths.push(newSelector); - } - }); - } - } - } - - if (extendsToAdd.length) { - // try to detect circular references to stop a stack overflow. - // may no longer be needed. - this.extendChainCount++; - if (iterationCount > 100) { - var selectorOne = "{unable to calculate}"; - var selectorTwo = "{unable to calculate}"; - try - { - selectorOne = extendsToAdd[0].selfSelectors[0].toCSS(); - selectorTwo = extendsToAdd[0].selector.toCSS(); - } - catch(e) {} - throw {message: "extend circular reference detected. One of the circular extends is currently:"+selectorOne+":extend(" + selectorTwo+")"}; - } - - // now process the new extends on the existing rules so that we can handle a extending b extending c ectending d extending e... - return extendsToAdd.concat(extendVisitor.doExtendChaining(extendsToAdd, extendsListTarget, iterationCount+1)); - } else { - return extendsToAdd; - } - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitSelector: function (selectorNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitRuleset: function (rulesetNode, visitArgs) { - if (rulesetNode.root) { - return; - } - var matches, pathIndex, extendIndex, allExtends = this.allExtendsStack[this.allExtendsStack.length-1], selectorsToAdd = [], extendVisitor = this, selectorPath; - - // look at each selector path in the ruleset, find any extend matches and then copy, find and replace - - for(extendIndex = 0; extendIndex < allExtends.length; extendIndex++) { - for(pathIndex = 0; pathIndex < rulesetNode.paths.length; pathIndex++) { - selectorPath = rulesetNode.paths[pathIndex]; - - // extending extends happens initially, before the main pass - if (rulesetNode.extendOnEveryPath) { continue; } - var extendList = selectorPath[selectorPath.length-1].extendList; - if (extendList && extendList.length) { continue; } - - matches = this.findMatch(allExtends[extendIndex], selectorPath); - - if (matches.length) { - - allExtends[extendIndex].selfSelectors.forEach(function(selfSelector) { - selectorsToAdd.push(extendVisitor.extendSelector(matches, selectorPath, selfSelector)); - }); - } - } - } - rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd); - }, - findMatch: function (extend, haystackSelectorPath) { - // - // look through the haystack selector path to try and find the needle - extend.selector - // returns an array of selector matches that can then be replaced - // - var haystackSelectorIndex, hackstackSelector, hackstackElementIndex, haystackElement, - targetCombinator, i, - extendVisitor = this, - needleElements = extend.selector.elements, - potentialMatches = [], potentialMatch, matches = []; - - // loop through the haystack elements - for(haystackSelectorIndex = 0; haystackSelectorIndex < haystackSelectorPath.length; haystackSelectorIndex++) { - hackstackSelector = haystackSelectorPath[haystackSelectorIndex]; - - for(hackstackElementIndex = 0; hackstackElementIndex < hackstackSelector.elements.length; hackstackElementIndex++) { - - haystackElement = hackstackSelector.elements[hackstackElementIndex]; - - // if we allow elements before our match we can add a potential match every time. otherwise only at the first element. - if (extend.allowBefore || (haystackSelectorIndex === 0 && hackstackElementIndex === 0)) { - potentialMatches.push({pathIndex: haystackSelectorIndex, index: hackstackElementIndex, matched: 0, initialCombinator: haystackElement.combinator}); - } - - for(i = 0; i < potentialMatches.length; i++) { - potentialMatch = potentialMatches[i]; - - // selectors add " " onto the first element. When we use & it joins the selectors together, but if we don't - // then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to work out - // what the resulting combinator will be - targetCombinator = haystackElement.combinator.value; - if (targetCombinator === '' && hackstackElementIndex === 0) { - targetCombinator = ' '; - } - - // if we don't match, null our match to indicate failure - if (!extendVisitor.isElementValuesEqual(needleElements[potentialMatch.matched].value, haystackElement.value) || - (potentialMatch.matched > 0 && needleElements[potentialMatch.matched].combinator.value !== targetCombinator)) { - potentialMatch = null; - } else { - potentialMatch.matched++; - } - - // if we are still valid and have finished, test whether we have elements after and whether these are allowed - if (potentialMatch) { - potentialMatch.finished = potentialMatch.matched === needleElements.length; - if (potentialMatch.finished && - (!extend.allowAfter && (hackstackElementIndex+1 < hackstackSelector.elements.length || haystackSelectorIndex+1 < haystackSelectorPath.length))) { - potentialMatch = null; - } - } - // if null we remove, if not, we are still valid, so either push as a valid match or continue - if (potentialMatch) { - if (potentialMatch.finished) { - potentialMatch.length = needleElements.length; - potentialMatch.endPathIndex = haystackSelectorIndex; - potentialMatch.endPathElementIndex = hackstackElementIndex + 1; // index after end of match - potentialMatches.length = 0; // we don't allow matches to overlap, so start matching again - matches.push(potentialMatch); - } - } else { - potentialMatches.splice(i, 1); - i--; - } - } - } - } - return matches; - }, - isElementValuesEqual: function(elementValue1, elementValue2) { - if (typeof elementValue1 === "string" || typeof elementValue2 === "string") { - return elementValue1 === elementValue2; - } - if (elementValue1 instanceof tree.Attribute) { - if (elementValue1.op !== elementValue2.op || elementValue1.key !== elementValue2.key) { - return false; - } - if (!elementValue1.value || !elementValue2.value) { - if (elementValue1.value || elementValue2.value) { - return false; - } - return true; - } - elementValue1 = elementValue1.value.value || elementValue1.value; - elementValue2 = elementValue2.value.value || elementValue2.value; - return elementValue1 === elementValue2; - } - elementValue1 = elementValue1.value; - elementValue2 = elementValue2.value; - if (elementValue1 instanceof tree.Selector) { - if (!(elementValue2 instanceof tree.Selector) || elementValue1.elements.length !== elementValue2.elements.length) { - return false; - } - for(var i = 0; i currentSelectorPathIndex && currentSelectorPathElementIndex > 0) { - path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); - currentSelectorPathElementIndex = 0; - currentSelectorPathIndex++; - } - - newElements = selector.elements - .slice(currentSelectorPathElementIndex, match.index) - .concat([firstElement]) - .concat(replacementSelector.elements.slice(1)); - - if (currentSelectorPathIndex === match.pathIndex && matchIndex > 0) { - path[path.length - 1].elements = - path[path.length - 1].elements.concat(newElements); - } else { - path = path.concat(selectorPath.slice(currentSelectorPathIndex, match.pathIndex)); - - path.push(new tree.Selector( - newElements - )); - } - currentSelectorPathIndex = match.endPathIndex; - currentSelectorPathElementIndex = match.endPathElementIndex; - if (currentSelectorPathElementIndex >= selectorPath[currentSelectorPathIndex].elements.length) { - currentSelectorPathElementIndex = 0; - currentSelectorPathIndex++; - } - } - - if (currentSelectorPathIndex < selectorPath.length && currentSelectorPathElementIndex > 0) { - path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); - currentSelectorPathIndex++; - } - - path = path.concat(selectorPath.slice(currentSelectorPathIndex, selectorPath.length)); - - return path; - }, - visitRulesetOut: function (rulesetNode) { - }, - visitMedia: function (mediaNode, visitArgs) { - var newAllExtends = mediaNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]); - newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, mediaNode.allExtends)); - this.allExtendsStack.push(newAllExtends); - }, - visitMediaOut: function (mediaNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - }, - visitDirective: function (directiveNode, visitArgs) { - var newAllExtends = directiveNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]); - newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, directiveNode.allExtends)); - this.allExtendsStack.push(newAllExtends); - }, - visitDirectiveOut: function (directiveNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - } - }; - -})(require('./tree')); - -(function (tree) { - - tree.sourceMapOutput = function (options) { - this._css = []; - this._rootNode = options.rootNode; - this._writeSourceMap = options.writeSourceMap; - this._contentsMap = options.contentsMap; - this._contentsIgnoredCharsMap = options.contentsIgnoredCharsMap; - this._sourceMapFilename = options.sourceMapFilename; - this._outputFilename = options.outputFilename; - this._sourceMapURL = options.sourceMapURL; - if (options.sourceMapBasepath) { - this._sourceMapBasepath = options.sourceMapBasepath.replace(/\\/g, '/'); - } - this._sourceMapRootpath = options.sourceMapRootpath; - this._outputSourceFiles = options.outputSourceFiles; - this._sourceMapGeneratorConstructor = options.sourceMapGenerator || require("source-map").SourceMapGenerator; - - if (this._sourceMapRootpath && this._sourceMapRootpath.charAt(this._sourceMapRootpath.length-1) !== '/') { - this._sourceMapRootpath += '/'; - } - - this._lineNumber = 0; - this._column = 0; - }; - - tree.sourceMapOutput.prototype.normalizeFilename = function(filename) { - filename = filename.replace(/\\/g, '/'); - - if (this._sourceMapBasepath && filename.indexOf(this._sourceMapBasepath) === 0) { - filename = filename.substring(this._sourceMapBasepath.length); - if (filename.charAt(0) === '\\' || filename.charAt(0) === '/') { - filename = filename.substring(1); - } - } - return (this._sourceMapRootpath || "") + filename; - }; - - tree.sourceMapOutput.prototype.add = function(chunk, fileInfo, index, mapLines) { - - //ignore adding empty strings - if (!chunk) { - return; - } - - var lines, - sourceLines, - columns, - sourceColumns, - i; - - if (fileInfo) { - var inputSource = this._contentsMap[fileInfo.filename]; - - // remove vars/banner added to the top of the file - if (this._contentsIgnoredCharsMap[fileInfo.filename]) { - // adjust the index - index -= this._contentsIgnoredCharsMap[fileInfo.filename]; - if (index < 0) { index = 0; } - // adjust the source - inputSource = inputSource.slice(this._contentsIgnoredCharsMap[fileInfo.filename]); - } - inputSource = inputSource.substring(0, index); - sourceLines = inputSource.split("\n"); - sourceColumns = sourceLines[sourceLines.length-1]; - } - - lines = chunk.split("\n"); - columns = lines[lines.length-1]; - - if (fileInfo) { - if (!mapLines) { - this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + 1, column: this._column}, - original: { line: sourceLines.length, column: sourceColumns.length}, - source: this.normalizeFilename(fileInfo.filename)}); - } else { - for(i = 0; i < lines.length; i++) { - this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + i + 1, column: i === 0 ? this._column : 0}, - original: { line: sourceLines.length + i, column: i === 0 ? sourceColumns.length : 0}, - source: this.normalizeFilename(fileInfo.filename)}); - } - } - } - - if (lines.length === 1) { - this._column += columns.length; - } else { - this._lineNumber += lines.length - 1; - this._column = columns.length; - } - - this._css.push(chunk); - }; - - tree.sourceMapOutput.prototype.isEmpty = function() { - return this._css.length === 0; - }; - - tree.sourceMapOutput.prototype.toCSS = function(env) { - this._sourceMapGenerator = new this._sourceMapGeneratorConstructor({ file: this._outputFilename, sourceRoot: null }); - - if (this._outputSourceFiles) { - for(var filename in this._contentsMap) { - if (this._contentsMap.hasOwnProperty(filename)) - { - var source = this._contentsMap[filename]; - if (this._contentsIgnoredCharsMap[filename]) { - source = source.slice(this._contentsIgnoredCharsMap[filename]); - } - this._sourceMapGenerator.setSourceContent(this.normalizeFilename(filename), source); - } - } - } - - this._rootNode.genCSS(env, this); - - if (this._css.length > 0) { - var sourceMapURL, - sourceMapContent = JSON.stringify(this._sourceMapGenerator.toJSON()); - - if (this._sourceMapURL) { - sourceMapURL = this._sourceMapURL; - } else if (this._sourceMapFilename) { - sourceMapURL = this.normalizeFilename(this._sourceMapFilename); - } - - if (this._writeSourceMap) { - this._writeSourceMap(sourceMapContent); - } else { - sourceMapURL = "data:application/json," + encodeURIComponent(sourceMapContent); - } - - if (sourceMapURL) { - this._css.push("/*# sourceMappingURL=" + sourceMapURL + " */"); - } - } - - return this._css.join(''); - }; - -})(require('./tree')); - -// -// browser.js - client-side engine -// -/*global less, window, document, XMLHttpRequest, location */ - -var isFileProtocol = /^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol); - -less.env = less.env || (location.hostname == '127.0.0.1' || - location.hostname == '0.0.0.0' || - location.hostname == 'localhost' || - (location.port && - location.port.length > 0) || - isFileProtocol ? 'development' - : 'production'); - -var logLevel = { - debug: 3, - info: 2, - errors: 1, - none: 0 -}; - -// The amount of logging in the javascript console. -// 3 - Debug, information and errors -// 2 - Information and errors -// 1 - Errors -// 0 - None -// Defaults to 2 -less.logLevel = typeof(less.logLevel) != 'undefined' ? less.logLevel : (less.env === 'development' ? logLevel.debug : logLevel.errors); - -// Load styles asynchronously (default: false) -// -// This is set to `false` by default, so that the body -// doesn't start loading before the stylesheets are parsed. -// Setting this to `true` can result in flickering. -// -less.async = less.async || false; -less.fileAsync = less.fileAsync || false; - -// Interval between watch polls -less.poll = less.poll || (isFileProtocol ? 1000 : 1500); - -//Setup user functions -if (less.functions) { - for(var func in less.functions) { - if (less.functions.hasOwnProperty(func)) { - less.tree.functions[func] = less.functions[func]; - } - } -} - -var dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(location.hash); -if (dumpLineNumbers) { - less.dumpLineNumbers = dumpLineNumbers[1]; -} - -var typePattern = /^text\/(x-)?less$/; -var cache = null; -var fileCache = {}; - -function log(str, level) { - if (typeof(console) !== 'undefined' && less.logLevel >= level) { - console.log('less: ' + str); - } -} - -function extractId(href) { - return href.replace(/^[a-z-]+:\/+?[^\/]+/, '' ) // Remove protocol & domain - .replace(/^\//, '' ) // Remove root / - .replace(/\.[a-zA-Z]+$/, '' ) // Remove simple extension - .replace(/[^\.\w-]+/g, '-') // Replace illegal characters - .replace(/\./g, ':'); // Replace dots with colons(for valid id) -} - -function errorConsole(e, rootHref) { - var template = '{line} {content}'; - var filename = e.filename || rootHref; - var errors = []; - var content = (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') + - " in " + filename + " "; - - var errorline = function (e, i, classname) { - if (e.extract[i] !== undefined) { - errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1)) - .replace(/\{class\}/, classname) - .replace(/\{content\}/, e.extract[i])); - } - }; - - if (e.extract) { - errorline(e, 0, ''); - errorline(e, 1, 'line'); - errorline(e, 2, ''); - content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':\n' + - errors.join('\n'); - } else if (e.stack) { - content += e.stack; - } - log(content, logLevel.errors); -} - -function createCSS(styles, sheet, lastModified) { - // Strip the query-string - var href = sheet.href || ''; - - // If there is no title set, use the filename, minus the extension - var id = 'less:' + (sheet.title || extractId(href)); - - // If this has already been inserted into the DOM, we may need to replace it - var oldCss = document.getElementById(id); - var keepOldCss = false; - - // Create a new stylesheet node for insertion or (if necessary) replacement - var css = document.createElement('style'); - css.setAttribute('type', 'text/css'); - if (sheet.media) { - css.setAttribute('media', sheet.media); - } - css.id = id; - - if (!css.styleSheet) { - css.appendChild(document.createTextNode(styles)); - - // If new contents match contents of oldCss, don't replace oldCss - keepOldCss = (oldCss !== null && oldCss.childNodes.length > 0 && css.childNodes.length > 0 && - oldCss.firstChild.nodeValue === css.firstChild.nodeValue); - } - - var head = document.getElementsByTagName('head')[0]; - - // If there is no oldCss, just append; otherwise, only append if we need - // to replace oldCss with an updated stylesheet - if (oldCss === null || keepOldCss === false) { - var nextEl = sheet && sheet.nextSibling || null; - if (nextEl) { - nextEl.parentNode.insertBefore(css, nextEl); - } else { - head.appendChild(css); - } - } - if (oldCss && keepOldCss === false) { - oldCss.parentNode.removeChild(oldCss); - } - - // For IE. - // This needs to happen *after* the style element is added to the DOM, otherwise IE 7 and 8 may crash. - // See http://social.msdn.microsoft.com/Forums/en-US/7e081b65-878a-4c22-8e68-c10d39c2ed32/internet-explorer-crashes-appending-style-element-to-head - if (css.styleSheet) { - try { - css.styleSheet.cssText = styles; - } catch (e) { - throw new(Error)("Couldn't reassign styleSheet.cssText."); - } - } - - // Don't update the local store if the file wasn't modified - if (lastModified && cache) { - log('saving ' + href + ' to cache.', logLevel.info); - try { - cache.setItem(href, styles); - cache.setItem(href + ':timestamp', lastModified); - } catch(e) { - //TODO - could do with adding more robust error handling - log('failed to save', logLevel.errors); - } - } -} - -function postProcessCSS(styles) { - if (less.postProcessor && typeof less.postProcessor === 'function') { - styles = less.postProcessor.call(styles, styles) || styles; - } - return styles; -} - -function errorHTML(e, rootHref) { - var id = 'less-error-message:' + extractId(rootHref || ""); - var template = '
  • {content}
  • '; - var elem = document.createElement('div'), timer, content, errors = []; - var filename = e.filename || rootHref; - var filenameNoPath = filename.match(/([^\/]+(\?.*)?)$/)[1]; - - elem.id = id; - elem.className = "less-error-message"; - - content = '

    ' + (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') + - '

    ' + '

    in ' + filenameNoPath + " "; - - var errorline = function (e, i, classname) { - if (e.extract[i] !== undefined) { - errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1)) - .replace(/\{class\}/, classname) - .replace(/\{content\}/, e.extract[i])); - } - }; - - if (e.extract) { - errorline(e, 0, ''); - errorline(e, 1, 'line'); - errorline(e, 2, ''); - content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':

    ' + - '
      ' + errors.join('') + '
    '; - } else if (e.stack) { - content += '
    ' + e.stack.split('\n').slice(1).join('
    '); - } - elem.innerHTML = content; - - // CSS for error messages - createCSS([ - '.less-error-message ul, .less-error-message li {', - 'list-style-type: none;', - 'margin-right: 15px;', - 'padding: 4px 0;', - 'margin: 0;', - '}', - '.less-error-message label {', - 'font-size: 12px;', - 'margin-right: 15px;', - 'padding: 4px 0;', - 'color: #cc7777;', - '}', - '.less-error-message pre {', - 'color: #dd6666;', - 'padding: 4px 0;', - 'margin: 0;', - 'display: inline-block;', - '}', - '.less-error-message pre.line {', - 'color: #ff0000;', - '}', - '.less-error-message h3 {', - 'font-size: 20px;', - 'font-weight: bold;', - 'padding: 15px 0 5px 0;', - 'margin: 0;', - '}', - '.less-error-message a {', - 'color: #10a', - '}', - '.less-error-message .error {', - 'color: red;', - 'font-weight: bold;', - 'padding-bottom: 2px;', - 'border-bottom: 1px dashed red;', - '}' - ].join('\n'), { title: 'error-message' }); - - elem.style.cssText = [ - "font-family: Arial, sans-serif", - "border: 1px solid #e00", - "background-color: #eee", - "border-radius: 5px", - "-webkit-border-radius: 5px", - "-moz-border-radius: 5px", - "color: #e00", - "padding: 15px", - "margin-bottom: 15px" - ].join(';'); - - if (less.env == 'development') { - timer = setInterval(function () { - if (document.body) { - if (document.getElementById(id)) { - document.body.replaceChild(elem, document.getElementById(id)); - } else { - document.body.insertBefore(elem, document.body.firstChild); - } - clearInterval(timer); - } - }, 10); - } -} - -function error(e, rootHref) { - if (!less.errorReporting || less.errorReporting === "html") { - errorHTML(e, rootHref); - } else if (less.errorReporting === "console") { - errorConsole(e, rootHref); - } else if (typeof less.errorReporting === 'function') { - less.errorReporting("add", e, rootHref); - } -} - -function removeErrorHTML(path) { - var node = document.getElementById('less-error-message:' + extractId(path)); - if (node) { - node.parentNode.removeChild(node); - } -} - -function removeErrorConsole(path) { - //no action -} - -function removeError(path) { - if (!less.errorReporting || less.errorReporting === "html") { - removeErrorHTML(path); - } else if (less.errorReporting === "console") { - removeErrorConsole(path); - } else if (typeof less.errorReporting === 'function') { - less.errorReporting("remove", path); - } -} - -function loadStyles(modifyVars) { - var styles = document.getElementsByTagName('style'), - style; - for (var i = 0; i < styles.length; i++) { - style = styles[i]; - if (style.type.match(typePattern)) { - var env = new less.tree.parseEnv(less), - lessText = style.innerHTML || ''; - env.filename = document.location.href.replace(/#.*$/, ''); - - if (modifyVars || less.globalVars) { - env.useFileCache = true; - } - - /*jshint loopfunc:true */ - // use closure to store current value of i - var callback = (function(style) { - return function (e, cssAST) { - if (e) { - return error(e, "inline"); - } - var css = cssAST.toCSS(less); - style.type = 'text/css'; - if (style.styleSheet) { - style.styleSheet.cssText = css; - } else { - style.innerHTML = css; - } - }; - })(style); - new(less.Parser)(env).parse(lessText, callback, {globalVars: less.globalVars, modifyVars: modifyVars}); - } - } -} - -function extractUrlParts(url, baseUrl) { - // urlParts[1] = protocol&hostname || / - // urlParts[2] = / if path relative to host base - // urlParts[3] = directories - // urlParts[4] = filename - // urlParts[5] = parameters - - var urlPartsRegex = /^((?:[a-z-]+:)?\/+?(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i, - urlParts = url.match(urlPartsRegex), - returner = {}, directories = [], i, baseUrlParts; - - if (!urlParts) { - throw new Error("Could not parse sheet href - '"+url+"'"); - } - - // Stylesheets in IE don't always return the full path - if (!urlParts[1] || urlParts[2]) { - baseUrlParts = baseUrl.match(urlPartsRegex); - if (!baseUrlParts) { - throw new Error("Could not parse page url - '"+baseUrl+"'"); - } - urlParts[1] = urlParts[1] || baseUrlParts[1] || ""; - if (!urlParts[2]) { - urlParts[3] = baseUrlParts[3] + urlParts[3]; - } - } - - if (urlParts[3]) { - directories = urlParts[3].replace(/\\/g, "/").split("/"); - - // extract out . before .. so .. doesn't absorb a non-directory - for(i = 0; i < directories.length; i++) { - if (directories[i] === ".") { - directories.splice(i, 1); - i -= 1; - } - } - - for(i = 0; i < directories.length; i++) { - if (directories[i] === ".." && i > 0) { - directories.splice(i-1, 2); - i -= 2; - } - } - } - - returner.hostPart = urlParts[1]; - returner.directories = directories; - returner.path = urlParts[1] + directories.join("/"); - returner.fileUrl = returner.path + (urlParts[4] || ""); - returner.url = returner.fileUrl + (urlParts[5] || ""); - return returner; -} - -function pathDiff(url, baseUrl) { - // diff between two paths to create a relative path - - var urlParts = extractUrlParts(url), - baseUrlParts = extractUrlParts(baseUrl), - i, max, urlDirectories, baseUrlDirectories, diff = ""; - if (urlParts.hostPart !== baseUrlParts.hostPart) { - return ""; - } - max = Math.max(baseUrlParts.directories.length, urlParts.directories.length); - for(i = 0; i < max; i++) { - if (baseUrlParts.directories[i] !== urlParts.directories[i]) { break; } - } - baseUrlDirectories = baseUrlParts.directories.slice(i); - urlDirectories = urlParts.directories.slice(i); - for(i = 0; i < baseUrlDirectories.length-1; i++) { - diff += "../"; - } - for(i = 0; i < urlDirectories.length-1; i++) { - diff += urlDirectories[i] + "/"; - } - return diff; -} - -function getXMLHttpRequest() { - if (window.XMLHttpRequest && (window.location.protocol !== "file:" || !("ActiveXObject" in window))) { - return new XMLHttpRequest(); - } else { - try { - /*global ActiveXObject */ - return new ActiveXObject("Microsoft.XMLHTTP"); - } catch (e) { - log("browser doesn't support AJAX.", logLevel.errors); - return null; - } - } -} - -function doXHR(url, type, callback, errback) { - var xhr = getXMLHttpRequest(); - var async = isFileProtocol ? less.fileAsync : less.async; - - if (typeof(xhr.overrideMimeType) === 'function') { - xhr.overrideMimeType('text/css'); - } - log("XHR: Getting '" + url + "'", logLevel.debug); - xhr.open('GET', url, async); - xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5'); - xhr.send(null); - - function handleResponse(xhr, callback, errback) { - if (xhr.status >= 200 && xhr.status < 300) { - callback(xhr.responseText, - xhr.getResponseHeader("Last-Modified")); - } else if (typeof(errback) === 'function') { - errback(xhr.status, url); - } - } - - if (isFileProtocol && !less.fileAsync) { - if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) { - callback(xhr.responseText); - } else { - errback(xhr.status, url); - } - } else if (async) { - xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - handleResponse(xhr, callback, errback); - } - }; - } else { - handleResponse(xhr, callback, errback); - } -} - -function loadFile(originalHref, currentFileInfo, callback, env, modifyVars) { - - if (currentFileInfo && currentFileInfo.currentDirectory && !/^([a-z-]+:)?\//.test(originalHref)) { - originalHref = currentFileInfo.currentDirectory + originalHref; - } - - // sheet may be set to the stylesheet for the initial load or a collection of properties including - // some env variables for imports - var hrefParts = extractUrlParts(originalHref, window.location.href); - var href = hrefParts.url; - var newFileInfo = { - currentDirectory: hrefParts.path, - filename: href - }; - - if (currentFileInfo) { - newFileInfo.entryPath = currentFileInfo.entryPath; - newFileInfo.rootpath = currentFileInfo.rootpath; - newFileInfo.rootFilename = currentFileInfo.rootFilename; - newFileInfo.relativeUrls = currentFileInfo.relativeUrls; - } else { - newFileInfo.entryPath = hrefParts.path; - newFileInfo.rootpath = less.rootpath || hrefParts.path; - newFileInfo.rootFilename = href; - newFileInfo.relativeUrls = env.relativeUrls; - } - - if (newFileInfo.relativeUrls) { - if (env.rootpath) { - newFileInfo.rootpath = extractUrlParts(env.rootpath + pathDiff(hrefParts.path, newFileInfo.entryPath)).path; - } else { - newFileInfo.rootpath = hrefParts.path; - } - } - - if (env.useFileCache && fileCache[href]) { - try { - var lessText = fileCache[href]; - callback(null, lessText, href, newFileInfo, { lastModified: new Date() }); - } catch (e) { - callback(e, null, href); - } - return; - } - - doXHR(href, env.mime, function (data, lastModified) { - // per file cache - fileCache[href] = data; - - // Use remote copy (re-parse) - try { - callback(null, data, href, newFileInfo, { lastModified: lastModified }); - } catch (e) { - callback(e, null, href); - } - }, function (status, url) { - callback({ type: 'File', message: "'" + url + "' wasn't found (" + status + ")" }, null, href); - }); -} - -function loadStyleSheet(sheet, callback, reload, remaining, modifyVars) { - - var env = new less.tree.parseEnv(less); - env.mime = sheet.type; - - if (modifyVars || less.globalVars) { - env.useFileCache = true; - } - - loadFile(sheet.href, null, function(e, data, path, newFileInfo, webInfo) { - - if (webInfo) { - webInfo.remaining = remaining; - - var css = cache && cache.getItem(path), - timestamp = cache && cache.getItem(path + ':timestamp'); - - if (!reload && timestamp && webInfo.lastModified && - (new(Date)(webInfo.lastModified).valueOf() === - new(Date)(timestamp).valueOf())) { - // Use local copy - createCSS(css, sheet); - webInfo.local = true; - callback(null, null, data, sheet, webInfo, path); - return; - } - } - - //TODO add tests around how this behaves when reloading - removeError(path); - - if (data) { - env.currentFileInfo = newFileInfo; - new(less.Parser)(env).parse(data, function (e, root) { - if (e) { return callback(e, null, null, sheet); } - try { - callback(e, root, data, sheet, webInfo, path); - } catch (e) { - callback(e, null, null, sheet); - } - }, {modifyVars: modifyVars, globalVars: less.globalVars}); - } else { - callback(e, null, null, sheet, webInfo, path); - } - }, env, modifyVars); -} - -function loadStyleSheets(callback, reload, modifyVars) { - for (var i = 0; i < less.sheets.length; i++) { - loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1), modifyVars); - } -} - -function initRunningMode(){ - if (less.env === 'development') { - less.optimization = 0; - less.watchTimer = setInterval(function () { - if (less.watchMode) { - loadStyleSheets(function (e, root, _, sheet, env) { - if (e) { - error(e, sheet.href); - } else if (root) { - var styles = root.toCSS(less); - styles = postProcessCSS(styles); - createCSS(styles, sheet, env.lastModified); - } - }); - } - }, less.poll); - } else { - less.optimization = 3; - } -} - - - -// -// Watch mode -// -less.watch = function () { - if (!less.watchMode ){ - less.env = 'development'; - initRunningMode(); - } - this.watchMode = true; - return true; -}; - -less.unwatch = function () {clearInterval(less.watchTimer); this.watchMode = false; return false; }; - -if (/!watch/.test(location.hash)) { - less.watch(); -} - -if (less.env != 'development') { - try { - cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage; - } catch (_) {} -} - -// -// Get all tags with the 'rel' attribute set to "stylesheet/less" -// -var links = document.getElementsByTagName('link'); - -less.sheets = []; - -for (var i = 0; i < links.length; i++) { - if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) && - (links[i].type.match(typePattern)))) { - less.sheets.push(links[i]); - } -} - -// -// With this function, it's possible to alter variables and re-render -// CSS without reloading less-files -// -less.modifyVars = function(record) { - less.refresh(false, record); -}; - -less.refresh = function (reload, modifyVars) { - var startTime, endTime; - startTime = endTime = new Date(); - - loadStyleSheets(function (e, root, _, sheet, env) { - if (e) { - return error(e, sheet.href); - } - if (env.local) { - log("loading " + sheet.href + " from cache.", logLevel.info); - } else { - log("parsed " + sheet.href + " successfully.", logLevel.debug); - var styles = root.toCSS(less); - styles = postProcessCSS(styles); - createCSS(styles, sheet, env.lastModified); - } - log("css for " + sheet.href + " generated in " + (new Date() - endTime) + 'ms', logLevel.info); - if (env.remaining === 0) { - log("less has finished. css generated in " + (new Date() - startTime) + 'ms', logLevel.info); - } - endTime = new Date(); - }, reload, modifyVars); - - loadStyles(modifyVars); -}; - -less.refreshStyles = loadStyles; - -less.Parser.fileLoader = loadFile; - -less.refresh(less.env === 'development'); - -// amd.js -// -// Define Less as an AMD module. -if (typeof define === "function" && define.amd) { - define(function () { return less; } ); -} - -})(window); \ No newline at end of file diff --git a/test/assets/less-1.7.5.js b/test/assets/less-1.7.5.js deleted file mode 100644 index 9530af82..00000000 --- a/test/assets/less-1.7.5.js +++ /dev/null @@ -1,8023 +0,0 @@ -/*! - * Less - Leaner CSS v1.7.5 - * http://lesscss.org - * - * Copyright (c) 2009-2014, Alexis Sellier - * Licensed under the Apache v2 License. - * - */ - - /** * @license Apache v2 - */ - - - -(function (window, undefined) {// -// Stub out `require` in the browser -// -function require(arg) { - return window.less[arg.split('/')[1]]; -}; - - -if (typeof(window.less) === 'undefined' || typeof(window.less.nodeType) !== 'undefined') { window.less = {}; } -less = window.less; -tree = window.less.tree = {}; -less.mode = 'browser'; - -var less, tree; - -// Node.js does not have a header file added which defines less -if (less === undefined) { - less = exports; - tree = require('./tree'); - less.mode = 'node'; -} -// -// less.js - parser -// -// A relatively straight-forward predictive parser. -// There is no tokenization/lexing stage, the input is parsed -// in one sweep. -// -// To make the parser fast enough to run in the browser, several -// optimization had to be made: -// -// - Matching and slicing on a huge input is often cause of slowdowns. -// The solution is to chunkify the input into smaller strings. -// The chunks are stored in the `chunks` var, -// `j` holds the current chunk index, and `currentPos` holds -// the index of the current chunk in relation to `input`. -// This gives us an almost 4x speed-up. -// -// - In many cases, we don't need to match individual tokens; -// for example, if a value doesn't hold any variables, operations -// or dynamic references, the parser can effectively 'skip' it, -// treating it as a literal. -// An example would be '1px solid #000' - which evaluates to itself, -// we don't need to know what the individual components are. -// The drawback, of course is that you don't get the benefits of -// syntax-checking on the CSS. This gives us a 50% speed-up in the parser, -// and a smaller speed-up in the code-gen. -// -// -// Token matching is done with the `$` function, which either takes -// a terminal string or regexp, or a non-terminal function to call. -// It also takes care of moving all the indices forwards. -// -// -less.Parser = function Parser(env) { - var input, // LeSS input string - i, // current index in `input` - j, // current chunk - saveStack = [], // holds state for backtracking - furthest, // furthest index the parser has gone to - chunks, // chunkified input - current, // current chunk - currentPos, // index of current chunk, in `input` - parser, - parsers, - rootFilename = env && env.filename; - - // Top parser on an import tree must be sure there is one "env" - // which will then be passed around by reference. - if (!(env instanceof tree.parseEnv)) { - env = new tree.parseEnv(env); - } - - var imports = this.imports = { - paths: env.paths || [], // Search paths, when importing - queue: [], // Files which haven't been imported yet - files: env.files, // Holds the imported parse trees - contents: env.contents, // Holds the imported file contents - contentsIgnoredChars: env.contentsIgnoredChars, // lines inserted, not in the original less - mime: env.mime, // MIME type of .less files - error: null, // Error in parsing/evaluating an import - push: function (path, currentFileInfo, importOptions, callback) { - var parserImports = this; - this.queue.push(path); - - var fileParsedFunc = function (e, root, fullPath) { - parserImports.queue.splice(parserImports.queue.indexOf(path), 1); // Remove the path from the queue - - var importedPreviously = fullPath === rootFilename; - - parserImports.files[fullPath] = root; // Store the root - - if (e && !parserImports.error) { parserImports.error = e; } - - callback(e, root, importedPreviously, fullPath); - }; - - if (less.Parser.importer) { - less.Parser.importer(path, currentFileInfo, fileParsedFunc, env); - } else { - less.Parser.fileLoader(path, currentFileInfo, function(e, contents, fullPath, newFileInfo) { - if (e) {fileParsedFunc(e); return;} - - var newEnv = new tree.parseEnv(env); - - newEnv.currentFileInfo = newFileInfo; - newEnv.processImports = false; - newEnv.contents[fullPath] = contents; - - if (currentFileInfo.reference || importOptions.reference) { - newFileInfo.reference = true; - } - - if (importOptions.inline) { - fileParsedFunc(null, contents, fullPath); - } else { - new(less.Parser)(newEnv).parse(contents, function (e, root) { - fileParsedFunc(e, root, fullPath); - }); - } - }, env); - } - } - }; - - function save() { currentPos = i; saveStack.push( { current: current, i: i, j: j }); } - function restore() { var state = saveStack.pop(); current = state.current; currentPos = i = state.i; j = state.j; } - function forget() { saveStack.pop(); } - - function sync() { - if (i > currentPos) { - current = current.slice(i - currentPos); - currentPos = i; - } - } - function isWhitespace(str, pos) { - var code = str.charCodeAt(pos | 0); - return (code <= 32) && (code === 32 || code === 10 || code === 9); - } - // - // Parse from a token, regexp or string, and move forward if match - // - function $(tok) { - var tokType = typeof tok, - match, length; - - // Either match a single character in the input, - // or match a regexp in the current chunk (`current`). - // - if (tokType === "string") { - if (input.charAt(i) !== tok) { - return null; - } - skipWhitespace(1); - return tok; - } - - // regexp - sync (); - if (! (match = tok.exec(current))) { - return null; - } - - length = match[0].length; - - // The match is confirmed, add the match length to `i`, - // and consume any extra white-space characters (' ' || '\n') - // which come after that. The reason for this is that LeSS's - // grammar is mostly white-space insensitive. - // - skipWhitespace(length); - - if(typeof(match) === 'string') { - return match; - } else { - return match.length === 1 ? match[0] : match; - } - } - - // Specialization of $(tok) - function $re(tok) { - if (i > currentPos) { - current = current.slice(i - currentPos); - currentPos = i; - } - var m = tok.exec(current); - if (!m) { - return null; - } - - skipWhitespace(m[0].length); - if(typeof m === "string") { - return m; - } - - return m.length === 1 ? m[0] : m; - } - - var _$re = $re; - - // Specialization of $(tok) - function $char(tok) { - if (input.charAt(i) !== tok) { - return null; - } - skipWhitespace(1); - return tok; - } - - function skipWhitespace(length) { - var oldi = i, oldj = j, - curr = i - currentPos, - endIndex = i + current.length - curr, - mem = (i += length), - inp = input, - c; - - for (; i < endIndex; i++) { - c = inp.charCodeAt(i); - if (c > 32) { - break; - } - - if ((c !== 32) && (c !== 10) && (c !== 9) && (c !== 13)) { - break; - } - } - - current = current.slice(length + i - mem + curr); - currentPos = i; - - if (!current.length && (j < chunks.length - 1)) { - current = chunks[++j]; - skipWhitespace(0); // skip space at the beginning of a chunk - return true; // things changed - } - - return oldi !== i || oldj !== j; - } - - function expect(arg, msg, index) { - // some older browsers return typeof 'function' for RegExp - var result = (Object.prototype.toString.call(arg) === '[object Function]') ? arg.call(parsers) : $(arg); - if (result) { - return result; - } - error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'" - : "unexpected token")); - } - - // Specialization of expect() - function expectChar(arg, msg) { - if (input.charAt(i) === arg) { - skipWhitespace(1); - return arg; - } - error(msg || "expected '" + arg + "' got '" + input.charAt(i) + "'"); - } - - function error(msg, type) { - var e = new Error(msg); - e.index = i; - e.type = type || 'Syntax'; - throw e; - } - - // Same as $(), but don't change the state of the parser, - // just return the match. - function peek(tok) { - if (typeof(tok) === 'string') { - return input.charAt(i) === tok; - } else { - return tok.test(current); - } - } - - // Specialization of peek() - function peekChar(tok) { - return input.charAt(i) === tok; - } - - - function getInput(e, env) { - if (e.filename && env.currentFileInfo.filename && (e.filename !== env.currentFileInfo.filename)) { - return parser.imports.contents[e.filename]; - } else { - return input; - } - } - - function getLocation(index, inputStream) { - var n = index + 1, - line = null, - column = -1; - - while (--n >= 0 && inputStream.charAt(n) !== '\n') { - column++; - } - - if (typeof index === 'number') { - line = (inputStream.slice(0, index).match(/\n/g) || "").length; - } - - return { - line: line, - column: column - }; - } - - function getDebugInfo(index, inputStream, env) { - var filename = env.currentFileInfo.filename; - if(less.mode !== 'browser' && less.mode !== 'rhino') { - filename = require('path').resolve(filename); - } - - return { - lineNumber: getLocation(index, inputStream).line + 1, - fileName: filename - }; - } - - function LessError(e, env) { - var input = getInput(e, env), - loc = getLocation(e.index, input), - line = loc.line, - col = loc.column, - callLine = e.call && getLocation(e.call, input).line, - lines = input.split('\n'); - - this.type = e.type || 'Syntax'; - this.message = e.message; - this.filename = e.filename || env.currentFileInfo.filename; - this.index = e.index; - this.line = typeof(line) === 'number' ? line + 1 : null; - this.callLine = callLine + 1; - this.callExtract = lines[callLine]; - this.stack = e.stack; - this.column = col; - this.extract = [ - lines[line - 1], - lines[line], - lines[line + 1] - ]; - } - - LessError.prototype = new Error(); - LessError.prototype.constructor = LessError; - - this.env = env = env || {}; - - // The optimization level dictates the thoroughness of the parser, - // the lower the number, the less nodes it will create in the tree. - // This could matter for debugging, or if you want to access - // the individual nodes in the tree. - this.optimization = ('optimization' in this.env) ? this.env.optimization : 1; - - // - // The Parser - // - parser = { - - imports: imports, - // - // Parse an input string into an abstract syntax tree, - // @param str A string containing 'less' markup - // @param callback call `callback` when done. - // @param [additionalData] An optional map which can contains vars - a map (key, value) of variables to apply - // - parse: function (str, callback, additionalData) { - var root, line, lines, error = null, globalVars, modifyVars, preText = ""; - - i = j = currentPos = furthest = 0; - - globalVars = (additionalData && additionalData.globalVars) ? less.Parser.serializeVars(additionalData.globalVars) + '\n' : ''; - modifyVars = (additionalData && additionalData.modifyVars) ? '\n' + less.Parser.serializeVars(additionalData.modifyVars) : ''; - - if (globalVars || (additionalData && additionalData.banner)) { - preText = ((additionalData && additionalData.banner) ? additionalData.banner : "") + globalVars; - parser.imports.contentsIgnoredChars[env.currentFileInfo.filename] = preText.length; - } - - str = str.replace(/\r\n/g, '\n'); - // Remove potential UTF Byte Order Mark - input = str = preText + str.replace(/^\uFEFF/, '') + modifyVars; - parser.imports.contents[env.currentFileInfo.filename] = str; - - // Split the input into chunks. - chunks = (function (input) { - var len = input.length, level = 0, parenLevel = 0, - lastOpening, lastOpeningParen, lastMultiComment, lastMultiCommentEndBrace, - chunks = [], emitFrom = 0, - parserCurrentIndex, currentChunkStartIndex, cc, cc2, matched; - - function fail(msg, index) { - error = new(LessError)({ - index: index || parserCurrentIndex, - type: 'Parse', - message: msg, - filename: env.currentFileInfo.filename - }, env); - } - - function emitChunk(force) { - var len = parserCurrentIndex - emitFrom; - if (((len < 512) && !force) || !len) { - return; - } - chunks.push(input.slice(emitFrom, parserCurrentIndex + 1)); - emitFrom = parserCurrentIndex + 1; - } - - for (parserCurrentIndex = 0; parserCurrentIndex < len; parserCurrentIndex++) { - cc = input.charCodeAt(parserCurrentIndex); - if (((cc >= 97) && (cc <= 122)) || (cc < 34)) { - // a-z or whitespace - continue; - } - - switch (cc) { - case 40: // ( - parenLevel++; - lastOpeningParen = parserCurrentIndex; - continue; - case 41: // ) - if (--parenLevel < 0) { - return fail("missing opening `(`"); - } - continue; - case 59: // ; - if (!parenLevel) { emitChunk(); } - continue; - case 123: // { - level++; - lastOpening = parserCurrentIndex; - continue; - case 125: // } - if (--level < 0) { - return fail("missing opening `{`"); - } - if (!level && !parenLevel) { emitChunk(); } - continue; - case 92: // \ - if (parserCurrentIndex < len - 1) { parserCurrentIndex++; continue; } - return fail("unescaped `\\`"); - case 34: - case 39: - case 96: // ", ' and ` - matched = 0; - currentChunkStartIndex = parserCurrentIndex; - for (parserCurrentIndex = parserCurrentIndex + 1; parserCurrentIndex < len; parserCurrentIndex++) { - cc2 = input.charCodeAt(parserCurrentIndex); - if (cc2 > 96) { continue; } - if (cc2 == cc) { matched = 1; break; } - if (cc2 == 92) { // \ - if (parserCurrentIndex == len - 1) { - return fail("unescaped `\\`"); - } - parserCurrentIndex++; - } - } - if (matched) { continue; } - return fail("unmatched `" + String.fromCharCode(cc) + "`", currentChunkStartIndex); - case 47: // /, check for comment - if (parenLevel || (parserCurrentIndex == len - 1)) { continue; } - cc2 = input.charCodeAt(parserCurrentIndex + 1); - if (cc2 == 47) { - // //, find lnfeed - for (parserCurrentIndex = parserCurrentIndex + 2; parserCurrentIndex < len; parserCurrentIndex++) { - cc2 = input.charCodeAt(parserCurrentIndex); - if ((cc2 <= 13) && ((cc2 == 10) || (cc2 == 13))) { break; } - } - } else if (cc2 == 42) { - // /*, find */ - lastMultiComment = currentChunkStartIndex = parserCurrentIndex; - for (parserCurrentIndex = parserCurrentIndex + 2; parserCurrentIndex < len - 1; parserCurrentIndex++) { - cc2 = input.charCodeAt(parserCurrentIndex); - if (cc2 == 125) { lastMultiCommentEndBrace = parserCurrentIndex; } - if (cc2 != 42) { continue; } - if (input.charCodeAt(parserCurrentIndex + 1) == 47) { break; } - } - if (parserCurrentIndex == len - 1) { - return fail("missing closing `*/`", currentChunkStartIndex); - } - parserCurrentIndex++; - } - continue; - case 42: // *, check for unmatched */ - if ((parserCurrentIndex < len - 1) && (input.charCodeAt(parserCurrentIndex + 1) == 47)) { - return fail("unmatched `/*`"); - } - continue; - } - } - - if (level !== 0) { - if ((lastMultiComment > lastOpening) && (lastMultiCommentEndBrace > lastMultiComment)) { - return fail("missing closing `}` or `*/`", lastOpening); - } else { - return fail("missing closing `}`", lastOpening); - } - } else if (parenLevel !== 0) { - return fail("missing closing `)`", lastOpeningParen); - } - - emitChunk(true); - return chunks; - })(str); - - if (error) { - return callback(new(LessError)(error, env)); - } - - current = chunks[0]; - - // Start with the primary rule. - // The whole syntax tree is held under a Ruleset node, - // with the `root` property set to true, so no `{}` are - // output. The callback is called when the input is parsed. - try { - root = new(tree.Ruleset)(null, this.parsers.primary()); - root.root = true; - root.firstRoot = true; - } catch (e) { - return callback(new(LessError)(e, env)); - } - - root.toCSS = (function (evaluate) { - return function (options, variables) { - options = options || {}; - var evaldRoot, - css, - evalEnv = new tree.evalEnv(options); - - // - // Allows setting variables with a hash, so: - // - // `{ color: new(tree.Color)('#f01') }` will become: - // - // new(tree.Rule)('@color', - // new(tree.Value)([ - // new(tree.Expression)([ - // new(tree.Color)('#f01') - // ]) - // ]) - // ) - // - if (typeof(variables) === 'object' && !Array.isArray(variables)) { - variables = Object.keys(variables).map(function (k) { - var value = variables[k]; - - if (! (value instanceof tree.Value)) { - if (! (value instanceof tree.Expression)) { - value = new(tree.Expression)([value]); - } - value = new(tree.Value)([value]); - } - return new(tree.Rule)('@' + k, value, false, null, 0); - }); - evalEnv.frames = [new(tree.Ruleset)(null, variables)]; - } - - try { - var preEvalVisitors = [], - visitors = [ - new(tree.joinSelectorVisitor)(), - new(tree.processExtendsVisitor)(), - new(tree.toCSSVisitor)({compress: Boolean(options.compress)}) - ], i, root = this; - - if (options.plugins) { - for(i =0; i < options.plugins.length; i++) { - if (options.plugins[i].isPreEvalVisitor) { - preEvalVisitors.push(options.plugins[i]); - } else { - if (options.plugins[i].isPreVisitor) { - visitors.splice(0, 0, options.plugins[i]); - } else { - visitors.push(options.plugins[i]); - } - } - } - } - - for(i = 0; i < preEvalVisitors.length; i++) { - preEvalVisitors[i].run(root); - } - - evaldRoot = evaluate.call(root, evalEnv); - - for(i = 0; i < visitors.length; i++) { - visitors[i].run(evaldRoot); - } - - if (options.sourceMap) { - evaldRoot = new tree.sourceMapOutput( - { - contentsIgnoredCharsMap: parser.imports.contentsIgnoredChars, - writeSourceMap: options.writeSourceMap, - rootNode: evaldRoot, - contentsMap: parser.imports.contents, - sourceMapFilename: options.sourceMapFilename, - sourceMapURL: options.sourceMapURL, - outputFilename: options.sourceMapOutputFilename, - sourceMapBasepath: options.sourceMapBasepath, - sourceMapRootpath: options.sourceMapRootpath, - outputSourceFiles: options.outputSourceFiles, - sourceMapGenerator: options.sourceMapGenerator - }); - } - - css = evaldRoot.toCSS({ - compress: Boolean(options.compress), - dumpLineNumbers: env.dumpLineNumbers, - strictUnits: Boolean(options.strictUnits), - numPrecision: 8}); - } catch (e) { - throw new(LessError)(e, env); - } - - if (options.cleancss && less.mode === 'node') { - var CleanCSS = require('clean-css'), - cleancssOptions = options.cleancssOptions || {}; - - if (cleancssOptions.keepSpecialComments === undefined) { - cleancssOptions.keepSpecialComments = "*"; - } - cleancssOptions.processImport = false; - cleancssOptions.noRebase = true; - if (cleancssOptions.noAdvanced === undefined) { - cleancssOptions.noAdvanced = true; - } - - return new CleanCSS(cleancssOptions).minify(css); - } else if (options.compress) { - return css.replace(/(^(\s)+)|((\s)+$)/g, ""); - } else { - return css; - } - }; - })(root.eval); - - // If `i` is smaller than the `input.length - 1`, - // it means the parser wasn't able to parse the whole - // string, so we've got a parsing error. - // - // We try to extract a \n delimited string, - // showing the line where the parse error occured. - // We split it up into two parts (the part which parsed, - // and the part which didn't), so we can color them differently. - if (i < input.length - 1) { - i = furthest; - var loc = getLocation(i, input); - lines = input.split('\n'); - line = loc.line + 1; - - error = { - type: "Parse", - message: "Unrecognised input", - index: i, - filename: env.currentFileInfo.filename, - line: line, - column: loc.column, - extract: [ - lines[line - 2], - lines[line - 1], - lines[line] - ] - }; - } - - var finish = function (e) { - e = error || e || parser.imports.error; - - if (e) { - if (!(e instanceof LessError)) { - e = new(LessError)(e, env); - } - - return callback(e); - } - else { - return callback(null, root); - } - }; - - if (env.processImports !== false) { - new tree.importVisitor(this.imports, finish) - .run(root); - } else { - return finish(); - } - }, - - // - // Here in, the parsing rules/functions - // - // The basic structure of the syntax tree generated is as follows: - // - // Ruleset -> Rule -> Value -> Expression -> Entity - // - // Here's some Less code: - // - // .class { - // color: #fff; - // border: 1px solid #000; - // width: @w + 4px; - // > .child {...} - // } - // - // And here's what the parse tree might look like: - // - // Ruleset (Selector '.class', [ - // Rule ("color", Value ([Expression [Color #fff]])) - // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]])) - // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]])) - // Ruleset (Selector [Element '>', '.child'], [...]) - // ]) - // - // In general, most rules will try to parse a token with the `$()` function, and if the return - // value is truly, will return a new node, of the relevant type. Sometimes, we need to check - // first, before parsing, that's when we use `peek()`. - // - parsers: parsers = { - // - // The `primary` rule is the *entry* and *exit* point of the parser. - // The rules here can appear at any level of the parse tree. - // - // The recursive nature of the grammar is an interplay between the `block` - // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule, - // as represented by this simplified grammar: - // - // primary → (ruleset | rule)+ - // ruleset → selector+ block - // block → '{' primary '}' - // - // Only at one point is the primary rule not called from the - // block rule: at the root level. - // - primary: function () { - var mixin = this.mixin, $re = _$re, root = [], node; - - while (current) - { - node = this.extendRule() || mixin.definition() || this.rule() || this.ruleset() || - mixin.call() || this.comment() || this.rulesetCall() || this.directive(); - if (node) { - root.push(node); - } else { - if (!($re(/^[\s\n]+/) || $re(/^;+/))) { - break; - } - } - if (peekChar('}')) { - break; - } - } - - return root; - }, - - // We create a Comment node for CSS comments `/* */`, - // but keep the LeSS comments `//` silent, by just skipping - // over them. - comment: function () { - var comment; - - if (input.charAt(i) !== '/') { return; } - - if (input.charAt(i + 1) === '/') { - return new(tree.Comment)($re(/^\/\/.*/), true, i, env.currentFileInfo); - } - comment = $re(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/); - if (comment) { - return new(tree.Comment)(comment, false, i, env.currentFileInfo); - } - }, - - comments: function () { - var comment, comments = []; - - while(true) { - comment = this.comment(); - if (!comment) { - break; - } - comments.push(comment); - } - - return comments; - }, - - // - // Entities are tokens which can be found inside an Expression - // - entities: { - // - // A string, which supports escaping " and ' - // - // "milky way" 'he\'s the one!' - // - quoted: function () { - var str, j = i, e, index = i; - - if (input.charAt(j) === '~') { j++; e = true; } // Escaped strings - if (input.charAt(j) !== '"' && input.charAt(j) !== "'") { return; } - - if (e) { $char('~'); } - - str = $re(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/); - if (str) { - return new(tree.Quoted)(str[0], str[1] || str[2], e, index, env.currentFileInfo); - } - }, - - // - // A catch-all word, such as: - // - // black border-collapse - // - keyword: function () { - var k; - - k = $re(/^%|^[_A-Za-z-][_A-Za-z0-9-]*/); - if (k) { - var color = tree.Color.fromKeyword(k); - if (color) { - return color; - } - return new(tree.Keyword)(k); - } - }, - - // - // A function call - // - // rgb(255, 0, 255) - // - // We also try to catch IE's `alpha()`, but let the `alpha` parser - // deal with the details. - // - // The arguments are parsed with the `entities.arguments` parser. - // - call: function () { - var name, nameLC, args, alpha_ret, index = i; - - name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(current); - if (!name) { return; } - - name = name[1]; - nameLC = name.toLowerCase(); - if (nameLC === 'url') { - return null; - } - - i += name.length; - - if (nameLC === 'alpha') { - alpha_ret = parsers.alpha(); - if(typeof alpha_ret !== 'undefined') { - return alpha_ret; - } - } - - $char('('); // Parse the '(' and consume whitespace. - - args = this.arguments(); - - if (! $char(')')) { - return; - } - - if (name) { return new(tree.Call)(name, args, index, env.currentFileInfo); } - }, - arguments: function () { - var args = [], arg; - - while (true) { - arg = this.assignment() || parsers.expression(); - if (!arg) { - break; - } - args.push(arg); - if (! $char(',')) { - break; - } - } - return args; - }, - literal: function () { - return this.dimension() || - this.color() || - this.quoted() || - this.unicodeDescriptor(); - }, - - // Assignments are argument entities for calls. - // They are present in ie filter properties as shown below. - // - // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* ) - // - - assignment: function () { - var key, value; - key = $re(/^\w+(?=\s?=)/i); - if (!key) { - return; - } - if (!$char('=')) { - return; - } - value = parsers.entity(); - if (value) { - return new(tree.Assignment)(key, value); - } - }, - - // - // Parse url() tokens - // - // We use a specific rule for urls, because they don't really behave like - // standard function calls. The difference is that the argument doesn't have - // to be enclosed within a string, so it can't be parsed as an Expression. - // - url: function () { - var value; - - if (input.charAt(i) !== 'u' || !$re(/^url\(/)) { - return; - } - - value = this.quoted() || this.variable() || - $re(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || ""; - - expectChar(')'); - - return new(tree.URL)((value.value != null || value instanceof tree.Variable) - ? value : new(tree.Anonymous)(value), env.currentFileInfo); - }, - - // - // A Variable entity, such as `@fink`, in - // - // width: @fink + 2px - // - // We use a different parser for variable definitions, - // see `parsers.variable`. - // - variable: function () { - var name, index = i; - - if (input.charAt(i) === '@' && (name = $re(/^@@?[\w-]+/))) { - return new(tree.Variable)(name, index, env.currentFileInfo); - } - }, - - // A variable entity useing the protective {} e.g. @{var} - variableCurly: function () { - var curly, index = i; - - if (input.charAt(i) === '@' && (curly = $re(/^@\{([\w-]+)\}/))) { - return new(tree.Variable)("@" + curly[1], index, env.currentFileInfo); - } - }, - - // - // A Hexadecimal color - // - // #4F3C2F - // - // `rgb` and `hsl` colors are parsed through the `entities.call` parser. - // - color: function () { - var rgb; - - if (input.charAt(i) === '#' && (rgb = $re(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/))) { - var colorCandidateString = rgb.input.match(/^#([\w]+).*/); // strip colons, brackets, whitespaces and other characters that should not definitely be part of color string - colorCandidateString = colorCandidateString[1]; - if (!colorCandidateString.match(/^[A-Fa-f0-9]+$/)) { // verify if candidate consists only of allowed HEX characters - error("Invalid HEX color code"); - } - return new(tree.Color)(rgb[1]); - } - }, - - // - // A Dimension, that is, a number and a unit - // - // 0.5em 95% - // - dimension: function () { - var value, c = input.charCodeAt(i); - //Is the first char of the dimension 0-9, '.', '+' or '-' - if ((c > 57 || c < 43) || c === 47 || c == 44) { - return; - } - - value = $re(/^([+-]?\d*\.?\d+)(%|[a-z]+)?/); - if (value) { - return new(tree.Dimension)(value[1], value[2]); - } - }, - - // - // A unicode descriptor, as is used in unicode-range - // - // U+0?? or U+00A1-00A9 - // - unicodeDescriptor: function () { - var ud; - - ud = $re(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/); - if (ud) { - return new(tree.UnicodeDescriptor)(ud[0]); - } - }, - - // - // JavaScript code to be evaluated - // - // `window.location.href` - // - javascript: function () { - var str, j = i, e; - - if (input.charAt(j) === '~') { j++; e = true; } // Escaped strings - if (input.charAt(j) !== '`') { return; } - if (env.javascriptEnabled !== undefined && !env.javascriptEnabled) { - error("You are using JavaScript, which has been disabled."); - } - - if (e) { $char('~'); } - - str = $re(/^`([^`]*)`/); - if (str) { - return new(tree.JavaScript)(str[1], i, e); - } - } - }, - - // - // The variable part of a variable definition. Used in the `rule` parser - // - // @fink: - // - variable: function () { - var name; - - if (input.charAt(i) === '@' && (name = $re(/^(@[\w-]+)\s*:/))) { return name[1]; } - }, - - // - // The variable part of a variable definition. Used in the `rule` parser - // - // @fink(); - // - rulesetCall: function () { - var name; - - if (input.charAt(i) === '@' && (name = $re(/^(@[\w-]+)\s*\(\s*\)\s*;/))) { - return new tree.RulesetCall(name[1]); - } - }, - - // - // extend syntax - used to extend selectors - // - extend: function(isRule) { - var elements, e, index = i, option, extendList, extend; - - if (!(isRule ? $re(/^&:extend\(/) : $re(/^:extend\(/))) { return; } - - do { - option = null; - elements = null; - while (! (option = $re(/^(all)(?=\s*(\)|,))/))) { - e = this.element(); - if (!e) { break; } - if (elements) { elements.push(e); } else { elements = [ e ]; } - } - - option = option && option[1]; - if (!elements) - error("Missing target selector for :extend()."); - extend = new(tree.Extend)(new(tree.Selector)(elements), option, index); - if (extendList) { extendList.push(extend); } else { extendList = [ extend ]; } - - } while($char(",")); - - expect(/^\)/); - - if (isRule) { - expect(/^;/); - } - - return extendList; - }, - - // - // extendRule - used in a rule to extend all the parent selectors - // - extendRule: function() { - return this.extend(true); - }, - - // - // Mixins - // - mixin: { - // - // A Mixin call, with an optional argument list - // - // #mixins > .square(#fff); - // .rounded(4px, black); - // .button; - // - // The `while` loop is there because mixins can be - // namespaced, but we only support the child and descendant - // selector for now. - // - call: function () { - var s = input.charAt(i), important = false, index = i, elemIndex, - elements, elem, e, c, args; - - if (s !== '.' && s !== '#') { return; } - - save(); // stop us absorbing part of an invalid selector - - while (true) { - elemIndex = i; - e = $re(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/); - if (!e) { - break; - } - elem = new(tree.Element)(c, e, elemIndex, env.currentFileInfo); - if (elements) { elements.push(elem); } else { elements = [ elem ]; } - c = $char('>'); - } - - if (elements) { - if ($char('(')) { - args = this.args(true).args; - expectChar(')'); - } - - if (parsers.important()) { - important = true; - } - - if (parsers.end()) { - forget(); - return new(tree.mixin.Call)(elements, args, index, env.currentFileInfo, important); - } - } - - restore(); - }, - args: function (isCall) { - var parsers = parser.parsers, entities = parsers.entities, - returner = { args:null, variadic: false }, - expressions = [], argsSemiColon = [], argsComma = [], - isSemiColonSeperated, expressionContainsNamed, name, nameLoop, value, arg; - - save(); - - while (true) { - if (isCall) { - arg = parsers.detachedRuleset() || parsers.expression(); - } else { - parsers.comments(); - if (input.charAt(i) === '.' && $re(/^\.{3}/)) { - returner.variadic = true; - if ($char(";") && !isSemiColonSeperated) { - isSemiColonSeperated = true; - } - (isSemiColonSeperated ? argsSemiColon : argsComma) - .push({ variadic: true }); - break; - } - arg = entities.variable() || entities.literal() || entities.keyword(); - } - - if (!arg) { - break; - } - - nameLoop = null; - if (arg.throwAwayComments) { - arg.throwAwayComments(); - } - value = arg; - var val = null; - - if (isCall) { - // Variable - if (arg.value && arg.value.length == 1) { - val = arg.value[0]; - } - } else { - val = arg; - } - - if (val && val instanceof tree.Variable) { - if ($char(':')) { - if (expressions.length > 0) { - if (isSemiColonSeperated) { - error("Cannot mix ; and , as delimiter types"); - } - expressionContainsNamed = true; - } - - // we do not support setting a ruleset as a default variable - it doesn't make sense - // However if we do want to add it, there is nothing blocking it, just don't error - // and remove isCall dependency below - value = (isCall && parsers.detachedRuleset()) || parsers.expression(); - - if (!value) { - if (isCall) { - error("could not understand value for named argument"); - } else { - restore(); - returner.args = []; - return returner; - } - } - nameLoop = (name = val.name); - } else if (!isCall && $re(/^\.{3}/)) { - returner.variadic = true; - if ($char(";") && !isSemiColonSeperated) { - isSemiColonSeperated = true; - } - (isSemiColonSeperated ? argsSemiColon : argsComma) - .push({ name: arg.name, variadic: true }); - break; - } else if (!isCall) { - name = nameLoop = val.name; - value = null; - } - } - - if (value) { - expressions.push(value); - } - - argsComma.push({ name:nameLoop, value:value }); - - if ($char(',')) { - continue; - } - - if ($char(';') || isSemiColonSeperated) { - - if (expressionContainsNamed) { - error("Cannot mix ; and , as delimiter types"); - } - - isSemiColonSeperated = true; - - if (expressions.length > 1) { - value = new(tree.Value)(expressions); - } - argsSemiColon.push({ name:name, value:value }); - - name = null; - expressions = []; - expressionContainsNamed = false; - } - } - - forget(); - returner.args = isSemiColonSeperated ? argsSemiColon : argsComma; - return returner; - }, - // - // A Mixin definition, with a list of parameters - // - // .rounded (@radius: 2px, @color) { - // ... - // } - // - // Until we have a finer grained state-machine, we have to - // do a look-ahead, to make sure we don't have a mixin call. - // See the `rule` function for more information. - // - // We start by matching `.rounded (`, and then proceed on to - // the argument list, which has optional default values. - // We store the parameters in `params`, with a `value` key, - // if there is a value, such as in the case of `@radius`. - // - // Once we've got our params list, and a closing `)`, we parse - // the `{...}` block. - // - definition: function () { - var name, params = [], match, ruleset, cond, variadic = false; - if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') || - peek(/^[^{]*\}/)) { - return; - } - - save(); - - match = $re(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/); - if (match) { - name = match[1]; - - var argInfo = this.args(false); - params = argInfo.args; - variadic = argInfo.variadic; - - // .mixincall("@{a}"); - // looks a bit like a mixin definition.. - // also - // .mixincall(@a: {rule: set;}); - // so we have to be nice and restore - if (!$char(')')) { - furthest = i; - restore(); - return; - } - - parsers.comments(); - - if ($re(/^when/)) { // Guard - cond = expect(parsers.conditions, 'expected condition'); - } - - ruleset = parsers.block(); - - if (ruleset) { - forget(); - return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic); - } else { - restore(); - } - } else { - forget(); - } - } - }, - - // - // Entities are the smallest recognized token, - // and can be found inside a rule's value. - // - entity: function () { - var entities = this.entities; - - return entities.literal() || entities.variable() || entities.url() || - entities.call() || entities.keyword() || entities.javascript() || - this.comment(); - }, - - // - // A Rule terminator. Note that we use `peek()` to check for '}', - // because the `block` rule will be expecting it, but we still need to make sure - // it's there, if ';' was ommitted. - // - end: function () { - return $char(';') || peekChar('}'); - }, - - // - // IE's alpha function - // - // alpha(opacity=88) - // - alpha: function () { - var value; - - if (! $re(/^\(opacity=/i)) { return; } - value = $re(/^\d+/) || this.entities.variable(); - if (value) { - expectChar(')'); - return new(tree.Alpha)(value); - } - }, - - // - // A Selector Element - // - // div - // + h1 - // #socks - // input[type="text"] - // - // Elements are the building blocks for Selectors, - // they are made out of a `Combinator` (see combinator rule), - // and an element name, such as a tag a class, or `*`. - // - element: function () { - var e, c, v, index = i; - - c = this.combinator(); - - e = $re(/^(?:\d+\.\d+|\d+)%/) || $re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) || - $char('*') || $char('&') || this.attribute() || $re(/^\([^()@]+\)/) || $re(/^[\.#](?=@)/) || - this.entities.variableCurly(); - - if (! e) { - save(); - if ($char('(')) { - if ((v = this.selector()) && $char(')')) { - e = new(tree.Paren)(v); - forget(); - } else { - restore(); - } - } else { - forget(); - } - } - - if (e) { return new(tree.Element)(c, e, index, env.currentFileInfo); } - }, - - // - // Combinators combine elements together, in a Selector. - // - // Because our parser isn't white-space sensitive, special care - // has to be taken, when parsing the descendant combinator, ` `, - // as it's an empty space. We have to check the previous character - // in the input, to see if it's a ` ` character. More info on how - // we deal with this in *combinator.js*. - // - combinator: function () { - var c = input.charAt(i); - - if (c === '/') { - save(); - var slashedCombinator = $re(/^\/[a-z]+\//i); - if (slashedCombinator) { - forget(); - return new(tree.Combinator)(slashedCombinator); - } - restore(); - } - - if (c === '>' || c === '+' || c === '~' || c === '|' || c === '^') { - i++; - if (c === '^' && input.charAt(i) === '^') { - c = '^^'; - i++; - } - while (isWhitespace(input, i)) { i++; } - return new(tree.Combinator)(c); - } else if (isWhitespace(input, i - 1)) { - return new(tree.Combinator)(" "); - } else { - return new(tree.Combinator)(null); - } - }, - // - // A CSS selector (see selector below) - // with less extensions e.g. the ability to extend and guard - // - lessSelector: function () { - return this.selector(true); - }, - // - // A CSS Selector - // - // .class > div + h1 - // li a:hover - // - // Selectors are made out of one or more Elements, see above. - // - selector: function (isLess) { - var index = i, $re = _$re, elements, extendList, c, e, extend, when, condition; - - while ((isLess && (extend = this.extend())) || (isLess && (when = $re(/^when/))) || (e = this.element())) { - if (when) { - condition = expect(this.conditions, 'expected condition'); - } else if (condition) { - error("CSS guard can only be used at the end of selector"); - } else if (extend) { - if (extendList) { extendList.push(extend); } else { extendList = [ extend ]; } - } else { - if (extendList) { error("Extend can only be used at the end of selector"); } - c = input.charAt(i); - if (elements) { elements.push(e); } else { elements = [ e ]; } - e = null; - } - if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') { - break; - } - } - - if (elements) { return new(tree.Selector)(elements, extendList, condition, index, env.currentFileInfo); } - if (extendList) { error("Extend must be used to extend a selector, it cannot be used on its own"); } - }, - attribute: function () { - if (! $char('[')) { return; } - - var entities = this.entities, - key, val, op; - - if (!(key = entities.variableCurly())) { - key = expect(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/); - } - - op = $re(/^[|~*$^]?=/); - if (op) { - val = entities.quoted() || $re(/^[0-9]+%/) || $re(/^[\w-]+/) || entities.variableCurly(); - } - - expectChar(']'); - - return new(tree.Attribute)(key, op, val); - }, - - // - // The `block` rule is used by `ruleset` and `mixin.definition`. - // It's a wrapper around the `primary` rule, with added `{}`. - // - block: function () { - var content; - if ($char('{') && (content = this.primary()) && $char('}')) { - return content; - } - }, - - blockRuleset: function() { - var block = this.block(); - - if (block) { - block = new tree.Ruleset(null, block); - } - return block; - }, - - detachedRuleset: function() { - var blockRuleset = this.blockRuleset(); - if (blockRuleset) { - return new tree.DetachedRuleset(blockRuleset); - } - }, - - // - // div, .class, body > p {...} - // - ruleset: function () { - var selectors, s, rules, debugInfo; - - save(); - - if (env.dumpLineNumbers) { - debugInfo = getDebugInfo(i, input, env); - } - - while (true) { - s = this.lessSelector(); - if (!s) { - break; - } - if (selectors) { selectors.push(s); } else { selectors = [ s ]; } - this.comments(); - if (s.condition && selectors.length > 1) { - error("Guards are only currently allowed on a single selector."); - } - if (! $char(',')) { break; } - if (s.condition) { - error("Guards are only currently allowed on a single selector."); - } - this.comments(); - } - - if (selectors && (rules = this.block())) { - forget(); - var ruleset = new(tree.Ruleset)(selectors, rules, env.strictImports); - if (env.dumpLineNumbers) { - ruleset.debugInfo = debugInfo; - } - return ruleset; - } else { - // Backtrack - furthest = i; - restore(); - } - }, - rule: function (tryAnonymous) { - var name, value, startOfRule = i, c = input.charAt(startOfRule), important, merge, isVariable; - - if (c === '.' || c === '#' || c === '&') { return; } - - save(); - - name = this.variable() || this.ruleProperty(); - if (name) { - isVariable = typeof name === "string"; - - if (isVariable) { - value = this.detachedRuleset(); - } - - this.comments(); - if (!value) { - // prefer to try to parse first if its a variable or we are compressing - // but always fallback on the other one - value = !tryAnonymous && (env.compress || isVariable) ? - (this.value() || this.anonymousValue()) : - (this.anonymousValue() || this.value()); - - important = this.important(); - - // a name returned by this.ruleProperty() is always an array of the form: - // [string-1, ..., string-n, ""] or [string-1, ..., string-n, "+"] - // where each item is a tree.Keyword or tree.Variable - merge = !isVariable && name.pop().value; - } - - if (value && this.end()) { - forget(); - return new (tree.Rule)(name, value, important, merge, startOfRule, env.currentFileInfo); - } else { - furthest = i; - restore(); - if (value && !tryAnonymous) { - return this.rule(true); - } - } - } else { - forget(); - } - }, - anonymousValue: function () { - var match; - match = /^([^@+\/'"*`(;{}-]*);/.exec(current); - if (match) { - i += match[0].length - 1; - return new(tree.Anonymous)(match[1]); - } - }, - - // - // An @import directive - // - // @import "lib"; - // - // Depending on our environment, importing is done differently: - // In the browser, it's an XHR request, in Node, it would be a - // file-system operation. The function used for importing is - // stored in `import`, which we pass to the Import constructor. - // - "import": function () { - var path, features, index = i; - - var dir = $re(/^@import?\s+/); - - if (dir) { - var options = (dir ? this.importOptions() : null) || {}; - - if ((path = this.entities.quoted() || this.entities.url())) { - features = this.mediaFeatures(); - - if (!$(';')) { - i = index; - error("missing semi-colon or unrecognised media features on import"); - } - features = features && new(tree.Value)(features); - return new(tree.Import)(path, features, options, index, env.currentFileInfo); - } - else - { - i = index; - error("malformed import statement"); - } - } - }, - - importOptions: function() { - var o, options = {}, optionName, value; - - // list of options, surrounded by parens - if (! $char('(')) { return null; } - do { - o = this.importOption(); - if (o) { - optionName = o; - value = true; - switch(optionName) { - case "css": - optionName = "less"; - value = false; - break; - case "once": - optionName = "multiple"; - value = false; - break; - } - options[optionName] = value; - if (! $char(',')) { break; } - } - } while (o); - expectChar(')'); - return options; - }, - - importOption: function() { - var opt = $re(/^(less|css|multiple|once|inline|reference)/); - if (opt) { - return opt[1]; - } - }, - - mediaFeature: function () { - var entities = this.entities, nodes = [], e, p; - do { - e = entities.keyword() || entities.variable(); - if (e) { - nodes.push(e); - } else if ($char('(')) { - p = this.property(); - e = this.value(); - if ($char(')')) { - if (p && e) { - nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, null, i, env.currentFileInfo, true))); - } else if (e) { - nodes.push(new(tree.Paren)(e)); - } else { - return null; - } - } else { return null; } - } - } while (e); - - if (nodes.length > 0) { - return new(tree.Expression)(nodes); - } - }, - - mediaFeatures: function () { - var entities = this.entities, features = [], e; - do { - e = this.mediaFeature(); - if (e) { - features.push(e); - if (! $char(',')) { break; } - } else { - e = entities.variable(); - if (e) { - features.push(e); - if (! $char(',')) { break; } - } - } - } while (e); - - return features.length > 0 ? features : null; - }, - - media: function () { - var features, rules, media, debugInfo; - - if (env.dumpLineNumbers) { - debugInfo = getDebugInfo(i, input, env); - } - - if ($re(/^@media/)) { - features = this.mediaFeatures(); - - rules = this.block(); - if (rules) { - media = new(tree.Media)(rules, features, i, env.currentFileInfo); - if (env.dumpLineNumbers) { - media.debugInfo = debugInfo; - } - return media; - } - } - }, - - // - // A CSS Directive - // - // @charset "utf-8"; - // - directive: function () { - var index = i, name, value, rules, nonVendorSpecificName, - hasIdentifier, hasExpression, hasUnknown, hasBlock = true; - - if (input.charAt(i) !== '@') { return; } - - value = this['import']() || this.media(); - if (value) { - return value; - } - - save(); - - name = $re(/^@[a-z-]+/); - - if (!name) { return; } - - nonVendorSpecificName = name; - if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) { - nonVendorSpecificName = "@" + name.slice(name.indexOf('-', 2) + 1); - } - - switch(nonVendorSpecificName) { - /* - case "@font-face": - case "@viewport": - case "@top-left": - case "@top-left-corner": - case "@top-center": - case "@top-right": - case "@top-right-corner": - case "@bottom-left": - case "@bottom-left-corner": - case "@bottom-center": - case "@bottom-right": - case "@bottom-right-corner": - case "@left-top": - case "@left-middle": - case "@left-bottom": - case "@right-top": - case "@right-middle": - case "@right-bottom": - hasBlock = true; - break; - */ - case "@charset": - hasIdentifier = true; - hasBlock = false; - break; - case "@namespace": - hasExpression = true; - hasBlock = false; - break; - case "@keyframes": - hasIdentifier = true; - break; - case "@host": - case "@page": - case "@document": - case "@supports": - hasUnknown = true; - break; - } - - this.comments(); - - if (hasIdentifier) { - value = this.entity(); - if (!value) { - error("expected " + name + " identifier"); - } - } else if (hasExpression) { - value = this.expression(); - if (!value) { - error("expected " + name + " expression"); - } - } else if (hasUnknown) { - value = ($re(/^[^{;]+/) || '').trim(); - if (value) { - value = new(tree.Anonymous)(value); - } - } - - this.comments(); - - if (hasBlock) { - rules = this.blockRuleset(); - } - - if (rules || (!hasBlock && value && $char(';'))) { - forget(); - return new(tree.Directive)(name, value, rules, index, env.currentFileInfo, - env.dumpLineNumbers ? getDebugInfo(index, input, env) : null); - } - - restore(); - }, - - // - // A Value is a comma-delimited list of Expressions - // - // font-family: Baskerville, Georgia, serif; - // - // In a Rule, a Value represents everything after the `:`, - // and before the `;`. - // - value: function () { - var e, expressions = []; - - do { - e = this.expression(); - if (e) { - expressions.push(e); - if (! $char(',')) { break; } - } - } while(e); - - if (expressions.length > 0) { - return new(tree.Value)(expressions); - } - }, - important: function () { - if (input.charAt(i) === '!') { - return $re(/^! *important/); - } - }, - sub: function () { - var a, e; - - if ($char('(')) { - a = this.addition(); - if (a) { - e = new(tree.Expression)([a]); - expectChar(')'); - e.parens = true; - return e; - } - } - }, - multiplication: function () { - var m, a, op, operation, isSpaced; - m = this.operand(); - if (m) { - isSpaced = isWhitespace(input, i - 1); - while (true) { - if (peek(/^\/[*\/]/)) { - break; - } - - save(); - - op = $char('/') || $char('*'); - - if (!op) { forget(); break; } - - a = this.operand(); - - if (!a) { restore(); break; } - forget(); - - m.parensInOp = true; - a.parensInOp = true; - operation = new(tree.Operation)(op, [operation || m, a], isSpaced); - isSpaced = isWhitespace(input, i - 1); - } - return operation || m; - } - }, - addition: function () { - var m, a, op, operation, isSpaced; - m = this.multiplication(); - if (m) { - isSpaced = isWhitespace(input, i - 1); - while (true) { - op = $re(/^[-+]\s+/) || (!isSpaced && ($char('+') || $char('-'))); - if (!op) { - break; - } - a = this.multiplication(); - if (!a) { - break; - } - - m.parensInOp = true; - a.parensInOp = true; - operation = new(tree.Operation)(op, [operation || m, a], isSpaced); - isSpaced = isWhitespace(input, i - 1); - } - return operation || m; - } - }, - conditions: function () { - var a, b, index = i, condition; - - a = this.condition(); - if (a) { - while (true) { - if (!peek(/^,\s*(not\s*)?\(/) || !$char(',')) { - break; - } - b = this.condition(); - if (!b) { - break; - } - condition = new(tree.Condition)('or', condition || a, b, index); - } - return condition || a; - } - }, - condition: function () { - var entities = this.entities, index = i, negate = false, - a, b, c, op; - - if ($re(/^not/)) { negate = true; } - expectChar('('); - a = this.addition() || entities.keyword() || entities.quoted(); - if (a) { - op = $re(/^(?:>=|<=|=<|[<=>])/); - if (op) { - b = this.addition() || entities.keyword() || entities.quoted(); - if (b) { - c = new(tree.Condition)(op, a, b, index, negate); - } else { - error('expected expression'); - } - } else { - c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate); - } - expectChar(')'); - return $re(/^and/) ? new(tree.Condition)('and', c, this.condition()) : c; - } - }, - - // - // An operand is anything that can be part of an operation, - // such as a Color, or a Variable - // - operand: function () { - var entities = this.entities, - p = input.charAt(i + 1), negate; - - if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $char('-'); } - var o = this.sub() || entities.dimension() || - entities.color() || entities.variable() || - entities.call(); - - if (negate) { - o.parensInOp = true; - o = new(tree.Negative)(o); - } - - return o; - }, - - // - // Expressions either represent mathematical operations, - // or white-space delimited Entities. - // - // 1px solid black - // @var * 2 - // - expression: function () { - var entities = [], e, delim; - - do { - e = this.addition() || this.entity(); - if (e) { - entities.push(e); - // operations do not allow keyword "/" dimension (e.g. small/20px) so we support that here - if (!peek(/^\/[\/*]/)) { - delim = $char('/'); - if (delim) { - entities.push(new(tree.Anonymous)(delim)); - } - } - } - } while (e); - if (entities.length > 0) { - return new(tree.Expression)(entities); - } - }, - property: function () { - var name = $re(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/); - if (name) { - return name[1]; - } - }, - ruleProperty: function () { - var c = current, name = [], index = [], length = 0, s, k; - - function match(re) { - var a = re.exec(c); - if (a) { - index.push(i + length); - length += a[0].length; - c = c.slice(a[1].length); - return name.push(a[1]); - } - } - function cutOutBlockComments() { - //match block comments - var a = /^\s*\/\*(?:[^*]|\*+[^\/*])*\*+\//.exec(c); - if (a) { - length += a[0].length; - c = c.slice(a[0].length); - return true; - } - return false; - } - - match(/^(\*?)/); - while (match(/^((?:[\w-]+)|(?:@\{[\w-]+\}))/)); // ! - while (cutOutBlockComments()); - if ((name.length > 1) && match(/^\s*((?:\+_|\+)?)\s*:/)) { - // at last, we have the complete match now. move forward, - // convert name particles to tree objects and return: - skipWhitespace(length); - if (name[0] === '') { - name.shift(); - index.shift(); - } - for (k = 0; k < name.length; k++) { - s = name[k]; - name[k] = (s.charAt(0) !== '@') - ? new(tree.Keyword)(s) - : new(tree.Variable)('@' + s.slice(2, -1), - index[k], env.currentFileInfo); - } - return name; - } - } - } - }; - return parser; -}; -less.Parser.serializeVars = function(vars) { - var s = ''; - - for (var name in vars) { - if (Object.hasOwnProperty.call(vars, name)) { - var value = vars[name]; - s += ((name[0] === '@') ? '' : '@') + name +': '+ value + - ((('' + value).slice(-1) === ';') ? '' : ';'); - } - } - - return s; -}; - -(function (tree) { - -tree.functions = { - rgb: function (r, g, b) { - return this.rgba(r, g, b, 1.0); - }, - rgba: function (r, g, b, a) { - var rgb = [r, g, b].map(function (c) { return scaled(c, 255); }); - a = number(a); - return new(tree.Color)(rgb, a); - }, - hsl: function (h, s, l) { - return this.hsla(h, s, l, 1.0); - }, - hsla: function (h, s, l, a) { - function hue(h) { - h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h); - if (h * 6 < 1) { return m1 + (m2 - m1) * h * 6; } - else if (h * 2 < 1) { return m2; } - else if (h * 3 < 2) { return m1 + (m2 - m1) * (2/3 - h) * 6; } - else { return m1; } - } - - h = (number(h) % 360) / 360; - s = clamp(number(s)); l = clamp(number(l)); a = clamp(number(a)); - - var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s; - var m1 = l * 2 - m2; - - return this.rgba(hue(h + 1/3) * 255, - hue(h) * 255, - hue(h - 1/3) * 255, - a); - }, - - hsv: function(h, s, v) { - return this.hsva(h, s, v, 1.0); - }, - - hsva: function(h, s, v, a) { - h = ((number(h) % 360) / 360) * 360; - s = number(s); v = number(v); a = number(a); - - var i, f; - i = Math.floor((h / 60) % 6); - f = (h / 60) - i; - - var vs = [v, - v * (1 - s), - v * (1 - f * s), - v * (1 - (1 - f) * s)]; - var perm = [[0, 3, 1], - [2, 0, 1], - [1, 0, 3], - [1, 2, 0], - [3, 1, 0], - [0, 1, 2]]; - - return this.rgba(vs[perm[i][0]] * 255, - vs[perm[i][1]] * 255, - vs[perm[i][2]] * 255, - a); - }, - - hue: function (color) { - return new(tree.Dimension)(color.toHSL().h); - }, - saturation: function (color) { - return new(tree.Dimension)(color.toHSL().s * 100, '%'); - }, - lightness: function (color) { - return new(tree.Dimension)(color.toHSL().l * 100, '%'); - }, - hsvhue: function(color) { - return new(tree.Dimension)(color.toHSV().h); - }, - hsvsaturation: function (color) { - return new(tree.Dimension)(color.toHSV().s * 100, '%'); - }, - hsvvalue: function (color) { - return new(tree.Dimension)(color.toHSV().v * 100, '%'); - }, - red: function (color) { - return new(tree.Dimension)(color.rgb[0]); - }, - green: function (color) { - return new(tree.Dimension)(color.rgb[1]); - }, - blue: function (color) { - return new(tree.Dimension)(color.rgb[2]); - }, - alpha: function (color) { - return new(tree.Dimension)(color.toHSL().a); - }, - luma: function (color) { - return new(tree.Dimension)(color.luma() * color.alpha * 100, '%'); - }, - luminance: function (color) { - var luminance = - (0.2126 * color.rgb[0] / 255) - + (0.7152 * color.rgb[1] / 255) - + (0.0722 * color.rgb[2] / 255); - - return new(tree.Dimension)(luminance * color.alpha * 100, '%'); - }, - saturate: function (color, amount) { - // filter: saturate(3.2); - // should be kept as is, so check for color - if (!color.rgb) { - return null; - } - var hsl = color.toHSL(); - - hsl.s += amount.value / 100; - hsl.s = clamp(hsl.s); - return hsla(hsl); - }, - desaturate: function (color, amount) { - var hsl = color.toHSL(); - - hsl.s -= amount.value / 100; - hsl.s = clamp(hsl.s); - return hsla(hsl); - }, - lighten: function (color, amount) { - var hsl = color.toHSL(); - - hsl.l += amount.value / 100; - hsl.l = clamp(hsl.l); - return hsla(hsl); - }, - darken: function (color, amount) { - var hsl = color.toHSL(); - - hsl.l -= amount.value / 100; - hsl.l = clamp(hsl.l); - return hsla(hsl); - }, - fadein: function (color, amount) { - var hsl = color.toHSL(); - - hsl.a += amount.value / 100; - hsl.a = clamp(hsl.a); - return hsla(hsl); - }, - fadeout: function (color, amount) { - var hsl = color.toHSL(); - - hsl.a -= amount.value / 100; - hsl.a = clamp(hsl.a); - return hsla(hsl); - }, - fade: function (color, amount) { - var hsl = color.toHSL(); - - hsl.a = amount.value / 100; - hsl.a = clamp(hsl.a); - return hsla(hsl); - }, - spin: function (color, amount) { - var hsl = color.toHSL(); - var hue = (hsl.h + amount.value) % 360; - - hsl.h = hue < 0 ? 360 + hue : hue; - - return hsla(hsl); - }, - // - // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein - // http://sass-lang.com - // - mix: function (color1, color2, weight) { - if (!weight) { - weight = new(tree.Dimension)(50); - } - var p = weight.value / 100.0; - var w = p * 2 - 1; - var a = color1.toHSL().a - color2.toHSL().a; - - var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0; - var w2 = 1 - w1; - - var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2, - color1.rgb[1] * w1 + color2.rgb[1] * w2, - color1.rgb[2] * w1 + color2.rgb[2] * w2]; - - var alpha = color1.alpha * p + color2.alpha * (1 - p); - - return new(tree.Color)(rgb, alpha); - }, - greyscale: function (color) { - return this.desaturate(color, new(tree.Dimension)(100)); - }, - contrast: function (color, dark, light, threshold) { - // filter: contrast(3.2); - // should be kept as is, so check for color - if (!color.rgb) { - return null; - } - if (typeof light === 'undefined') { - light = this.rgba(255, 255, 255, 1.0); - } - if (typeof dark === 'undefined') { - dark = this.rgba(0, 0, 0, 1.0); - } - //Figure out which is actually light and dark! - if (dark.luma() > light.luma()) { - var t = light; - light = dark; - dark = t; - } - if (typeof threshold === 'undefined') { - threshold = 0.43; - } else { - threshold = number(threshold); - } - if (color.luma() < threshold) { - return light; - } else { - return dark; - } - }, - e: function (str) { - return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str.value); - }, - escape: function (str) { - return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29")); - }, - replace: function (string, pattern, replacement, flags) { - var result = string.value; - - result = result.replace(new RegExp(pattern.value, flags ? flags.value : ''), replacement.value); - return new(tree.Quoted)(string.quote || '', result, string.escaped); - }, - '%': function (string /* arg, arg, ...*/) { - var args = Array.prototype.slice.call(arguments, 1), - result = string.value; - - for (var i = 0; i < args.length; i++) { - /*jshint loopfunc:true */ - result = result.replace(/%[sda]/i, function(token) { - var value = token.match(/s/i) ? args[i].value : args[i].toCSS(); - return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value; - }); - } - result = result.replace(/%%/g, '%'); - return new(tree.Quoted)(string.quote || '', result, string.escaped); - }, - unit: function (val, unit) { - if(!(val instanceof tree.Dimension)) { - throw { type: "Argument", message: "the first argument to unit must be a number" + (val instanceof tree.Operation ? ". Have you forgotten parenthesis?" : "") }; - } - if (unit) { - if (unit instanceof tree.Keyword) { - unit = unit.value; - } else { - unit = unit.toCSS(); - } - } else { - unit = ""; - } - return new(tree.Dimension)(val.value, unit); - }, - convert: function (val, unit) { - return val.convertTo(unit.value); - }, - round: function (n, f) { - var fraction = typeof(f) === "undefined" ? 0 : f.value; - return _math(function(num) { return num.toFixed(fraction); }, null, n); - }, - pi: function () { - return new(tree.Dimension)(Math.PI); - }, - mod: function(a, b) { - return new(tree.Dimension)(a.value % b.value, a.unit); - }, - pow: function(x, y) { - if (typeof x === "number" && typeof y === "number") { - x = new(tree.Dimension)(x); - y = new(tree.Dimension)(y); - } else if (!(x instanceof tree.Dimension) || !(y instanceof tree.Dimension)) { - throw { type: "Argument", message: "arguments must be numbers" }; - } - - return new(tree.Dimension)(Math.pow(x.value, y.value), x.unit); - }, - _minmax: function (isMin, args) { - args = Array.prototype.slice.call(args); - switch(args.length) { - case 0: throw { type: "Argument", message: "one or more arguments required" }; - } - var i, j, current, currentUnified, referenceUnified, unit, unitStatic, unitClone, - order = [], // elems only contains original argument values. - values = {}; // key is the unit.toString() for unified tree.Dimension values, - // value is the index into the order array. - for (i = 0; i < args.length; i++) { - current = args[i]; - if (!(current instanceof tree.Dimension)) { - if(Array.isArray(args[i].value)) { - Array.prototype.push.apply(args, Array.prototype.slice.call(args[i].value)); - } - continue; - } - currentUnified = current.unit.toString() === "" && unitClone !== undefined ? new(tree.Dimension)(current.value, unitClone).unify() : current.unify(); - unit = currentUnified.unit.toString() === "" && unitStatic !== undefined ? unitStatic : currentUnified.unit.toString(); - unitStatic = unit !== "" && unitStatic === undefined || unit !== "" && order[0].unify().unit.toString() === "" ? unit : unitStatic; - unitClone = unit !== "" && unitClone === undefined ? current.unit.toString() : unitClone; - j = values[""] !== undefined && unit !== "" && unit === unitStatic ? values[""] : values[unit]; - if (j === undefined) { - if(unitStatic !== undefined && unit !== unitStatic) { - throw{ type: "Argument", message: "incompatible types" }; - } - values[unit] = order.length; - order.push(current); - continue; - } - referenceUnified = order[j].unit.toString() === "" && unitClone !== undefined ? new(tree.Dimension)(order[j].value, unitClone).unify() : order[j].unify(); - if ( isMin && currentUnified.value < referenceUnified.value || - !isMin && currentUnified.value > referenceUnified.value) { - order[j] = current; - } - } - if (order.length == 1) { - return order[0]; - } - args = order.map(function (a) { return a.toCSS(this.env); }).join(this.env.compress ? "," : ", "); - return new(tree.Anonymous)((isMin ? "min" : "max") + "(" + args + ")"); - }, - min: function () { - return this._minmax(true, arguments); - }, - max: function () { - return this._minmax(false, arguments); - }, - "get-unit": function (n) { - return new(tree.Anonymous)(n.unit); - }, - argb: function (color) { - return new(tree.Anonymous)(color.toARGB()); - }, - percentage: function (n) { - return new(tree.Dimension)(n.value * 100, '%'); - }, - color: function (n) { - if (n instanceof tree.Quoted) { - var colorCandidate = n.value, - returnColor; - returnColor = tree.Color.fromKeyword(colorCandidate); - if (returnColor) { - return returnColor; - } - if (/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/.test(colorCandidate)) { - return new(tree.Color)(colorCandidate.slice(1)); - } - throw { type: "Argument", message: "argument must be a color keyword or 3/6 digit hex e.g. #FFF" }; - } else { - throw { type: "Argument", message: "argument must be a string" }; - } - }, - iscolor: function (n) { - return this._isa(n, tree.Color); - }, - isnumber: function (n) { - return this._isa(n, tree.Dimension); - }, - isstring: function (n) { - return this._isa(n, tree.Quoted); - }, - iskeyword: function (n) { - return this._isa(n, tree.Keyword); - }, - isurl: function (n) { - return this._isa(n, tree.URL); - }, - ispixel: function (n) { - return this.isunit(n, 'px'); - }, - ispercentage: function (n) { - return this.isunit(n, '%'); - }, - isem: function (n) { - return this.isunit(n, 'em'); - }, - isunit: function (n, unit) { - return (n instanceof tree.Dimension) && n.unit.is(unit.value || unit) ? tree.True : tree.False; - }, - _isa: function (n, Type) { - return (n instanceof Type) ? tree.True : tree.False; - }, - tint: function(color, amount) { - return this.mix(this.rgb(255,255,255), color, amount); - }, - shade: function(color, amount) { - return this.mix(this.rgb(0, 0, 0), color, amount); - }, - extract: function(values, index) { - index = index.value - 1; // (1-based index) - // handle non-array values as an array of length 1 - // return 'undefined' if index is invalid - return Array.isArray(values.value) - ? values.value[index] : Array(values)[index]; - }, - length: function(values) { - var n = Array.isArray(values.value) ? values.value.length : 1; - return new tree.Dimension(n); - }, - - "data-uri": function(mimetypeNode, filePathNode) { - - if (typeof window !== 'undefined') { - return new tree.URL(filePathNode || mimetypeNode, this.currentFileInfo).eval(this.env); - } - - var mimetype = mimetypeNode.value; - var filePath = (filePathNode && filePathNode.value); - - var fs = require('./fs'), - path = require('path'), - useBase64 = false; - - if (arguments.length < 2) { - filePath = mimetype; - } - - var fragmentStart = filePath.indexOf('#'); - var fragment = ''; - if (fragmentStart!==-1) { - fragment = filePath.slice(fragmentStart); - filePath = filePath.slice(0, fragmentStart); - } - - if (this.env.isPathRelative(filePath)) { - if (this.currentFileInfo.relativeUrls) { - filePath = path.join(this.currentFileInfo.currentDirectory, filePath); - } else { - filePath = path.join(this.currentFileInfo.entryPath, filePath); - } - } - - // detect the mimetype if not given - if (arguments.length < 2) { - var mime; - try { - mime = require('mime'); - } catch (ex) { - mime = tree._mime; - } - - mimetype = mime.lookup(filePath); - - // use base 64 unless it's an ASCII or UTF-8 format - var charset = mime.charsets.lookup(mimetype); - useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0; - if (useBase64) { mimetype += ';base64'; } - } - else { - useBase64 = /;base64$/.test(mimetype); - } - - var buf = fs.readFileSync(filePath); - - // IE8 cannot handle a data-uri larger than 32KB. If this is exceeded - // and the --ieCompat flag is enabled, return a normal url() instead. - var DATA_URI_MAX_KB = 32, - fileSizeInKB = parseInt((buf.length / 1024), 10); - if (fileSizeInKB >= DATA_URI_MAX_KB) { - - if (this.env.ieCompat !== false) { - if (!this.env.silent) { - console.warn("Skipped data-uri embedding of %s because its size (%dKB) exceeds IE8-safe %dKB!", filePath, fileSizeInKB, DATA_URI_MAX_KB); - } - - return new tree.URL(filePathNode || mimetypeNode, this.currentFileInfo).eval(this.env); - } - } - - buf = useBase64 ? buf.toString('base64') - : encodeURIComponent(buf); - - var uri = "\"data:" + mimetype + ',' + buf + fragment + "\""; - return new(tree.URL)(new(tree.Anonymous)(uri)); - }, - - "svg-gradient": function(direction) { - - function throwArgumentDescriptor() { - throw { type: "Argument", message: "svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position]" }; - } - - if (arguments.length < 3) { - throwArgumentDescriptor(); - } - var stops = Array.prototype.slice.call(arguments, 1), - gradientDirectionSvg, - gradientType = "linear", - rectangleDimension = 'x="0" y="0" width="1" height="1"', - useBase64 = true, - renderEnv = {compress: false}, - returner, - directionValue = direction.toCSS(renderEnv), - i, color, position, positionValue, alpha; - - switch (directionValue) { - case "to bottom": - gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"'; - break; - case "to right": - gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="0%"'; - break; - case "to bottom right": - gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="100%"'; - break; - case "to top right": - gradientDirectionSvg = 'x1="0%" y1="100%" x2="100%" y2="0%"'; - break; - case "ellipse": - case "ellipse at center": - gradientType = "radial"; - gradientDirectionSvg = 'cx="50%" cy="50%" r="75%"'; - rectangleDimension = 'x="-50" y="-50" width="101" height="101"'; - break; - default: - throw { type: "Argument", message: "svg-gradient direction must be 'to bottom', 'to right', 'to bottom right', 'to top right' or 'ellipse at center'" }; - } - returner = '' + - '' + - '<' + gradientType + 'Gradient id="gradient" gradientUnits="userSpaceOnUse" ' + gradientDirectionSvg + '>'; - - for (i = 0; i < stops.length; i+= 1) { - if (stops[i].value) { - color = stops[i].value[0]; - position = stops[i].value[1]; - } else { - color = stops[i]; - position = undefined; - } - - if (!(color instanceof tree.Color) || (!((i === 0 || i+1 === stops.length) && position === undefined) && !(position instanceof tree.Dimension))) { - throwArgumentDescriptor(); - } - positionValue = position ? position.toCSS(renderEnv) : i === 0 ? "0%" : "100%"; - alpha = color.alpha; - returner += ''; - } - returner += '' + - ''; - - if (useBase64) { - try { - returner = require('./encoder').encodeBase64(returner); // TODO browser implementation - } catch(e) { - useBase64 = false; - } - } - - returner = "'data:image/svg+xml" + (useBase64 ? ";base64" : "") + "," + returner + "'"; - return new(tree.URL)(new(tree.Anonymous)(returner)); - } -}; - -// these static methods are used as a fallback when the optional 'mime' dependency is missing -tree._mime = { - // this map is intentionally incomplete - // if you want more, install 'mime' dep - _types: { - '.htm' : 'text/html', - '.html': 'text/html', - '.gif' : 'image/gif', - '.jpg' : 'image/jpeg', - '.jpeg': 'image/jpeg', - '.png' : 'image/png' - }, - lookup: function (filepath) { - var ext = require('path').extname(filepath), - type = tree._mime._types[ext]; - if (type === undefined) { - throw new Error('Optional dependency "mime" is required for ' + ext); - } - return type; - }, - charsets: { - lookup: function (type) { - // assumes all text types are UTF-8 - return type && (/^text\//).test(type) ? 'UTF-8' : ''; - } - } -}; - -// Math - -var mathFunctions = { - // name, unit - ceil: null, - floor: null, - sqrt: null, - abs: null, - tan: "", - sin: "", - cos: "", - atan: "rad", - asin: "rad", - acos: "rad" -}; - -function _math(fn, unit, n) { - if (!(n instanceof tree.Dimension)) { - throw { type: "Argument", message: "argument must be a number" }; - } - if (unit == null) { - unit = n.unit; - } else { - n = n.unify(); - } - return new(tree.Dimension)(fn(parseFloat(n.value)), unit); -} - -// ~ End of Math - -// Color Blending -// ref: http://www.w3.org/TR/compositing-1 - -function colorBlend(mode, color1, color2) { - var ab = color1.alpha, cb, // backdrop - as = color2.alpha, cs, // source - ar, cr, r = []; // result - - ar = as + ab * (1 - as); - for (var i = 0; i < 3; i++) { - cb = color1.rgb[i] / 255; - cs = color2.rgb[i] / 255; - cr = mode(cb, cs); - if (ar) { - cr = (as * cs + ab * (cb - - as * (cb + cs - cr))) / ar; - } - r[i] = cr * 255; - } - - return new(tree.Color)(r, ar); -} - -var colorBlendMode = { - multiply: function(cb, cs) { - return cb * cs; - }, - screen: function(cb, cs) { - return cb + cs - cb * cs; - }, - overlay: function(cb, cs) { - cb *= 2; - return (cb <= 1) - ? colorBlendMode.multiply(cb, cs) - : colorBlendMode.screen(cb - 1, cs); - }, - softlight: function(cb, cs) { - var d = 1, e = cb; - if (cs > 0.5) { - e = 1; - d = (cb > 0.25) ? Math.sqrt(cb) - : ((16 * cb - 12) * cb + 4) * cb; - } - return cb - (1 - 2 * cs) * e * (d - cb); - }, - hardlight: function(cb, cs) { - return colorBlendMode.overlay(cs, cb); - }, - difference: function(cb, cs) { - return Math.abs(cb - cs); - }, - exclusion: function(cb, cs) { - return cb + cs - 2 * cb * cs; - }, - - // non-w3c functions: - average: function(cb, cs) { - return (cb + cs) / 2; - }, - negation: function(cb, cs) { - return 1 - Math.abs(cb + cs - 1); - } -}; - -// ~ End of Color Blending - -tree.defaultFunc = { - eval: function () { - var v = this.value_, e = this.error_; - if (e) { - throw e; - } - if (v != null) { - return v ? tree.True : tree.False; - } - }, - value: function (v) { - this.value_ = v; - }, - error: function (e) { - this.error_ = e; - }, - reset: function () { - this.value_ = this.error_ = null; - } -}; - -function initFunctions() { - var f, tf = tree.functions; - - // math - for (f in mathFunctions) { - if (mathFunctions.hasOwnProperty(f)) { - tf[f] = _math.bind(null, Math[f], mathFunctions[f]); - } - } - - // color blending - for (f in colorBlendMode) { - if (colorBlendMode.hasOwnProperty(f)) { - tf[f] = colorBlend.bind(null, colorBlendMode[f]); - } - } - - // default - f = tree.defaultFunc; - tf["default"] = f.eval.bind(f); - -} initFunctions(); - -function hsla(color) { - return tree.functions.hsla(color.h, color.s, color.l, color.a); -} - -function scaled(n, size) { - if (n instanceof tree.Dimension && n.unit.is('%')) { - return parseFloat(n.value * size / 100); - } else { - return number(n); - } -} - -function number(n) { - if (n instanceof tree.Dimension) { - return parseFloat(n.unit.is('%') ? n.value / 100 : n.value); - } else if (typeof(n) === 'number') { - return n; - } else { - throw { - error: "RuntimeError", - message: "color functions take numbers as parameters" - }; - } -} - -function clamp(val) { - return Math.min(1, Math.max(0, val)); -} - -tree.fround = function(env, value) { - var p = env && env.numPrecision; - //add "epsilon" to ensure numbers like 1.000000005 (represented as 1.000000004999....) are properly rounded... - return (p == null) ? value : Number((value + 2e-16).toFixed(p)); -}; - -tree.functionCall = function(env, currentFileInfo) { - this.env = env; - this.currentFileInfo = currentFileInfo; -}; - -tree.functionCall.prototype = tree.functions; - -})(require('./tree')); - -(function (tree) { - tree.colors = { - 'aliceblue':'#f0f8ff', - 'antiquewhite':'#faebd7', - 'aqua':'#00ffff', - 'aquamarine':'#7fffd4', - 'azure':'#f0ffff', - 'beige':'#f5f5dc', - 'bisque':'#ffe4c4', - 'black':'#000000', - 'blanchedalmond':'#ffebcd', - 'blue':'#0000ff', - 'blueviolet':'#8a2be2', - 'brown':'#a52a2a', - 'burlywood':'#deb887', - 'cadetblue':'#5f9ea0', - 'chartreuse':'#7fff00', - 'chocolate':'#d2691e', - 'coral':'#ff7f50', - 'cornflowerblue':'#6495ed', - 'cornsilk':'#fff8dc', - 'crimson':'#dc143c', - 'cyan':'#00ffff', - 'darkblue':'#00008b', - 'darkcyan':'#008b8b', - 'darkgoldenrod':'#b8860b', - 'darkgray':'#a9a9a9', - 'darkgrey':'#a9a9a9', - 'darkgreen':'#006400', - 'darkkhaki':'#bdb76b', - 'darkmagenta':'#8b008b', - 'darkolivegreen':'#556b2f', - 'darkorange':'#ff8c00', - 'darkorchid':'#9932cc', - 'darkred':'#8b0000', - 'darksalmon':'#e9967a', - 'darkseagreen':'#8fbc8f', - 'darkslateblue':'#483d8b', - 'darkslategray':'#2f4f4f', - 'darkslategrey':'#2f4f4f', - 'darkturquoise':'#00ced1', - 'darkviolet':'#9400d3', - 'deeppink':'#ff1493', - 'deepskyblue':'#00bfff', - 'dimgray':'#696969', - 'dimgrey':'#696969', - 'dodgerblue':'#1e90ff', - 'firebrick':'#b22222', - 'floralwhite':'#fffaf0', - 'forestgreen':'#228b22', - 'fuchsia':'#ff00ff', - 'gainsboro':'#dcdcdc', - 'ghostwhite':'#f8f8ff', - 'gold':'#ffd700', - 'goldenrod':'#daa520', - 'gray':'#808080', - 'grey':'#808080', - 'green':'#008000', - 'greenyellow':'#adff2f', - 'honeydew':'#f0fff0', - 'hotpink':'#ff69b4', - 'indianred':'#cd5c5c', - 'indigo':'#4b0082', - 'ivory':'#fffff0', - 'khaki':'#f0e68c', - 'lavender':'#e6e6fa', - 'lavenderblush':'#fff0f5', - 'lawngreen':'#7cfc00', - 'lemonchiffon':'#fffacd', - 'lightblue':'#add8e6', - 'lightcoral':'#f08080', - 'lightcyan':'#e0ffff', - 'lightgoldenrodyellow':'#fafad2', - 'lightgray':'#d3d3d3', - 'lightgrey':'#d3d3d3', - 'lightgreen':'#90ee90', - 'lightpink':'#ffb6c1', - 'lightsalmon':'#ffa07a', - 'lightseagreen':'#20b2aa', - 'lightskyblue':'#87cefa', - 'lightslategray':'#778899', - 'lightslategrey':'#778899', - 'lightsteelblue':'#b0c4de', - 'lightyellow':'#ffffe0', - 'lime':'#00ff00', - 'limegreen':'#32cd32', - 'linen':'#faf0e6', - 'magenta':'#ff00ff', - 'maroon':'#800000', - 'mediumaquamarine':'#66cdaa', - 'mediumblue':'#0000cd', - 'mediumorchid':'#ba55d3', - 'mediumpurple':'#9370d8', - 'mediumseagreen':'#3cb371', - 'mediumslateblue':'#7b68ee', - 'mediumspringgreen':'#00fa9a', - 'mediumturquoise':'#48d1cc', - 'mediumvioletred':'#c71585', - 'midnightblue':'#191970', - 'mintcream':'#f5fffa', - 'mistyrose':'#ffe4e1', - 'moccasin':'#ffe4b5', - 'navajowhite':'#ffdead', - 'navy':'#000080', - 'oldlace':'#fdf5e6', - 'olive':'#808000', - 'olivedrab':'#6b8e23', - 'orange':'#ffa500', - 'orangered':'#ff4500', - 'orchid':'#da70d6', - 'palegoldenrod':'#eee8aa', - 'palegreen':'#98fb98', - 'paleturquoise':'#afeeee', - 'palevioletred':'#d87093', - 'papayawhip':'#ffefd5', - 'peachpuff':'#ffdab9', - 'peru':'#cd853f', - 'pink':'#ffc0cb', - 'plum':'#dda0dd', - 'powderblue':'#b0e0e6', - 'purple':'#800080', - 'red':'#ff0000', - 'rosybrown':'#bc8f8f', - 'royalblue':'#4169e1', - 'saddlebrown':'#8b4513', - 'salmon':'#fa8072', - 'sandybrown':'#f4a460', - 'seagreen':'#2e8b57', - 'seashell':'#fff5ee', - 'sienna':'#a0522d', - 'silver':'#c0c0c0', - 'skyblue':'#87ceeb', - 'slateblue':'#6a5acd', - 'slategray':'#708090', - 'slategrey':'#708090', - 'snow':'#fffafa', - 'springgreen':'#00ff7f', - 'steelblue':'#4682b4', - 'tan':'#d2b48c', - 'teal':'#008080', - 'thistle':'#d8bfd8', - 'tomato':'#ff6347', - 'turquoise':'#40e0d0', - 'violet':'#ee82ee', - 'wheat':'#f5deb3', - 'white':'#ffffff', - 'whitesmoke':'#f5f5f5', - 'yellow':'#ffff00', - 'yellowgreen':'#9acd32' - }; -})(require('./tree')); - -(function (tree) { - -tree.debugInfo = function(env, ctx, lineSeperator) { - var result=""; - if (env.dumpLineNumbers && !env.compress) { - switch(env.dumpLineNumbers) { - case 'comments': - result = tree.debugInfo.asComment(ctx); - break; - case 'mediaquery': - result = tree.debugInfo.asMediaQuery(ctx); - break; - case 'all': - result = tree.debugInfo.asComment(ctx) + (lineSeperator || "") + tree.debugInfo.asMediaQuery(ctx); - break; - } - } - return result; -}; - -tree.debugInfo.asComment = function(ctx) { - return '/* line ' + ctx.debugInfo.lineNumber + ', ' + ctx.debugInfo.fileName + ' */\n'; -}; - -tree.debugInfo.asMediaQuery = function(ctx) { - return '@media -sass-debug-info{filename{font-family:' + - ('file://' + ctx.debugInfo.fileName).replace(/([.:\/\\])/g, function (a) { - if (a == '\\') { - a = '\/'; - } - return '\\' + a; - }) + - '}line{font-family:\\00003' + ctx.debugInfo.lineNumber + '}}\n'; -}; - -tree.find = function (obj, fun) { - for (var i = 0, r; i < obj.length; i++) { - r = fun.call(obj, obj[i]); - if (r) { return r; } - } - return null; -}; - -tree.jsify = function (obj) { - if (Array.isArray(obj.value) && (obj.value.length > 1)) { - return '[' + obj.value.map(function (v) { return v.toCSS(); }).join(', ') + ']'; - } else { - return obj.toCSS(); - } -}; - -tree.toCSS = function (env) { - var strs = []; - this.genCSS(env, { - add: function(chunk, fileInfo, index) { - strs.push(chunk); - }, - isEmpty: function () { - return strs.length === 0; - } - }); - return strs.join(''); -}; - -tree.outputRuleset = function (env, output, rules) { - var ruleCnt = rules.length, i; - env.tabLevel = (env.tabLevel | 0) + 1; - - // Compressed - if (env.compress) { - output.add('{'); - for (i = 0; i < ruleCnt; i++) { - rules[i].genCSS(env, output); - } - output.add('}'); - env.tabLevel--; - return; - } - - // Non-compressed - var tabSetStr = '\n' + Array(env.tabLevel).join(" "), tabRuleStr = tabSetStr + " "; - if (!ruleCnt) { - output.add(" {" + tabSetStr + '}'); - } else { - output.add(" {" + tabRuleStr); - rules[0].genCSS(env, output); - for (i = 1; i < ruleCnt; i++) { - output.add(tabRuleStr); - rules[i].genCSS(env, output); - } - output.add(tabSetStr + '}'); - } - - env.tabLevel--; -}; - -})(require('./tree')); - -(function (tree) { - -tree.Alpha = function (val) { - this.value = val; -}; -tree.Alpha.prototype = { - type: "Alpha", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - eval: function (env) { - if (this.value.eval) { return new tree.Alpha(this.value.eval(env)); } - return this; - }, - genCSS: function (env, output) { - output.add("alpha(opacity="); - - if (this.value.genCSS) { - this.value.genCSS(env, output); - } else { - output.add(this.value); - } - - output.add(")"); - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -tree.Anonymous = function (value, index, currentFileInfo, mapLines, rulesetLike) { - this.value = value; - this.index = index; - this.mapLines = mapLines; - this.currentFileInfo = currentFileInfo; - this.rulesetLike = (typeof rulesetLike === 'undefined')? false : rulesetLike; -}; -tree.Anonymous.prototype = { - type: "Anonymous", - eval: function () { - return new tree.Anonymous(this.value, this.index, this.currentFileInfo, this.mapLines, this.rulesetLike); - }, - compare: function (x) { - if (!x.toCSS) { - return -1; - } - - var left = this.toCSS(), - right = x.toCSS(); - - if (left === right) { - return 0; - } - - return left < right ? -1 : 1; - }, - isRulesetLike: function() { - return this.rulesetLike; - }, - genCSS: function (env, output) { - output.add(this.value, this.currentFileInfo, this.index, this.mapLines); - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -tree.Assignment = function (key, val) { - this.key = key; - this.value = val; -}; -tree.Assignment.prototype = { - type: "Assignment", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - eval: function (env) { - if (this.value.eval) { - return new(tree.Assignment)(this.key, this.value.eval(env)); - } - return this; - }, - genCSS: function (env, output) { - output.add(this.key + '='); - if (this.value.genCSS) { - this.value.genCSS(env, output); - } else { - output.add(this.value); - } - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -// -// A function call node. -// -tree.Call = function (name, args, index, currentFileInfo) { - this.name = name; - this.args = args; - this.index = index; - this.currentFileInfo = currentFileInfo; -}; -tree.Call.prototype = { - type: "Call", - accept: function (visitor) { - if (this.args) { - this.args = visitor.visitArray(this.args); - } - }, - // - // When evaluating a function call, - // we either find the function in `tree.functions` [1], - // in which case we call it, passing the evaluated arguments, - // if this returns null or we cannot find the function, we - // simply print it out as it appeared originally [2]. - // - // The *functions.js* file contains the built-in functions. - // - // The reason why we evaluate the arguments, is in the case where - // we try to pass a variable to a function, like: `saturate(@color)`. - // The function should receive the value, not the variable. - // - eval: function (env) { - var args = this.args.map(function (a) { return a.eval(env); }), - nameLC = this.name.toLowerCase(), - result, func; - - if (nameLC in tree.functions) { // 1. - try { - func = new tree.functionCall(env, this.currentFileInfo); - result = func[nameLC].apply(func, args); - if (result != null) { - return result; - } - } catch (e) { - throw { type: e.type || "Runtime", - message: "error evaluating function `" + this.name + "`" + - (e.message ? ': ' + e.message : ''), - index: this.index, filename: this.currentFileInfo.filename }; - } - } - - return new tree.Call(this.name, args, this.index, this.currentFileInfo); - }, - - genCSS: function (env, output) { - output.add(this.name + "(", this.currentFileInfo, this.index); - - for(var i = 0; i < this.args.length; i++) { - this.args[i].genCSS(env, output); - if (i + 1 < this.args.length) { - output.add(", "); - } - } - - output.add(")"); - }, - - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { -// -// RGB Colors - #ff0014, #eee -// -tree.Color = function (rgb, a) { - // - // The end goal here, is to parse the arguments - // into an integer triplet, such as `128, 255, 0` - // - // This facilitates operations and conversions. - // - if (Array.isArray(rgb)) { - this.rgb = rgb; - } else if (rgb.length == 6) { - this.rgb = rgb.match(/.{2}/g).map(function (c) { - return parseInt(c, 16); - }); - } else { - this.rgb = rgb.split('').map(function (c) { - return parseInt(c + c, 16); - }); - } - this.alpha = typeof(a) === 'number' ? a : 1; -}; - -var transparentKeyword = "transparent"; - -tree.Color.prototype = { - type: "Color", - eval: function () { return this; }, - luma: function () { - var r = this.rgb[0] / 255, - g = this.rgb[1] / 255, - b = this.rgb[2] / 255; - - r = (r <= 0.03928) ? r / 12.92 : Math.pow(((r + 0.055) / 1.055), 2.4); - g = (g <= 0.03928) ? g / 12.92 : Math.pow(((g + 0.055) / 1.055), 2.4); - b = (b <= 0.03928) ? b / 12.92 : Math.pow(((b + 0.055) / 1.055), 2.4); - - return 0.2126 * r + 0.7152 * g + 0.0722 * b; - }, - - genCSS: function (env, output) { - output.add(this.toCSS(env)); - }, - toCSS: function (env, doNotCompress) { - var compress = env && env.compress && !doNotCompress, - alpha = tree.fround(env, this.alpha); - - // If we have some transparency, the only way to represent it - // is via `rgba`. Otherwise, we use the hex representation, - // which has better compatibility with older browsers. - // Values are capped between `0` and `255`, rounded and zero-padded. - if (alpha < 1) { - if (alpha === 0 && this.isTransparentKeyword) { - return transparentKeyword; - } - return "rgba(" + this.rgb.map(function (c) { - return clamp(Math.round(c), 255); - }).concat(clamp(alpha, 1)) - .join(',' + (compress ? '' : ' ')) + ")"; - } else { - var color = this.toRGB(); - - if (compress) { - var splitcolor = color.split(''); - - // Convert color to short format - if (splitcolor[1] === splitcolor[2] && splitcolor[3] === splitcolor[4] && splitcolor[5] === splitcolor[6]) { - color = '#' + splitcolor[1] + splitcolor[3] + splitcolor[5]; - } - } - - return color; - } - }, - - // - // Operations have to be done per-channel, if not, - // channels will spill onto each other. Once we have - // our result, in the form of an integer triplet, - // we create a new Color node to hold the result. - // - operate: function (env, op, other) { - var rgb = []; - var alpha = this.alpha * (1 - other.alpha) + other.alpha; - for (var c = 0; c < 3; c++) { - rgb[c] = tree.operate(env, op, this.rgb[c], other.rgb[c]); - } - return new(tree.Color)(rgb, alpha); - }, - - toRGB: function () { - return toHex(this.rgb); - }, - - toHSL: function () { - var r = this.rgb[0] / 255, - g = this.rgb[1] / 255, - b = this.rgb[2] / 255, - a = this.alpha; - - var max = Math.max(r, g, b), min = Math.min(r, g, b); - var h, s, l = (max + min) / 2, d = max - min; - - if (max === min) { - h = s = 0; - } else { - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - - switch (max) { - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; - } - h /= 6; - } - return { h: h * 360, s: s, l: l, a: a }; - }, - //Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript - toHSV: function () { - var r = this.rgb[0] / 255, - g = this.rgb[1] / 255, - b = this.rgb[2] / 255, - a = this.alpha; - - var max = Math.max(r, g, b), min = Math.min(r, g, b); - var h, s, v = max; - - var d = max - min; - if (max === 0) { - s = 0; - } else { - s = d / max; - } - - if (max === min) { - h = 0; - } else { - switch(max){ - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; - } - h /= 6; - } - return { h: h * 360, s: s, v: v, a: a }; - }, - toARGB: function () { - return toHex([this.alpha * 255].concat(this.rgb)); - }, - compare: function (x) { - if (!x.rgb) { - return -1; - } - - return (x.rgb[0] === this.rgb[0] && - x.rgb[1] === this.rgb[1] && - x.rgb[2] === this.rgb[2] && - x.alpha === this.alpha) ? 0 : -1; - } -}; - -tree.Color.fromKeyword = function(keyword) { - keyword = keyword.toLowerCase(); - - if (tree.colors.hasOwnProperty(keyword)) { - // detect named color - return new(tree.Color)(tree.colors[keyword].slice(1)); - } - if (keyword === transparentKeyword) { - var transparent = new(tree.Color)([0, 0, 0], 0); - transparent.isTransparentKeyword = true; - return transparent; - } -}; - -function toHex(v) { - return '#' + v.map(function (c) { - c = clamp(Math.round(c), 255); - return (c < 16 ? '0' : '') + c.toString(16); - }).join(''); -} - -function clamp(v, max) { - return Math.min(Math.max(v, 0), max); -} - -})(require('../tree')); - -(function (tree) { - -tree.Comment = function (value, silent, index, currentFileInfo) { - this.value = value; - this.silent = !!silent; - this.currentFileInfo = currentFileInfo; -}; -tree.Comment.prototype = { - type: "Comment", - genCSS: function (env, output) { - if (this.debugInfo) { - output.add(tree.debugInfo(env, this), this.currentFileInfo, this.index); - } - output.add(this.value.trim()); //TODO shouldn't need to trim, we shouldn't grab the \n - }, - toCSS: tree.toCSS, - isSilent: function(env) { - var isReference = (this.currentFileInfo && this.currentFileInfo.reference && !this.isReferenced), - isCompressed = env.compress && !this.value.match(/^\/\*!/); - return this.silent || isReference || isCompressed; - }, - eval: function () { return this; }, - markReferenced: function () { - this.isReferenced = true; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Condition = function (op, l, r, i, negate) { - this.op = op.trim(); - this.lvalue = l; - this.rvalue = r; - this.index = i; - this.negate = negate; -}; -tree.Condition.prototype = { - type: "Condition", - accept: function (visitor) { - this.lvalue = visitor.visit(this.lvalue); - this.rvalue = visitor.visit(this.rvalue); - }, - eval: function (env) { - var a = this.lvalue.eval(env), - b = this.rvalue.eval(env); - - var i = this.index, result; - - result = (function (op) { - switch (op) { - case 'and': - return a && b; - case 'or': - return a || b; - default: - if (a.compare) { - result = a.compare(b); - } else if (b.compare) { - result = b.compare(a); - } else { - throw { type: "Type", - message: "Unable to perform comparison", - index: i }; - } - switch (result) { - case -1: return op === '<' || op === '=<' || op === '<='; - case 0: return op === '=' || op === '>=' || op === '=<' || op === '<='; - case 1: return op === '>' || op === '>='; - } - } - })(this.op); - return this.negate ? !result : result; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.DetachedRuleset = function (ruleset, frames) { - this.ruleset = ruleset; - this.frames = frames; -}; -tree.DetachedRuleset.prototype = { - type: "DetachedRuleset", - accept: function (visitor) { - this.ruleset = visitor.visit(this.ruleset); - }, - eval: function (env) { - var frames = this.frames || env.frames.slice(0); - return new tree.DetachedRuleset(this.ruleset, frames); - }, - callEval: function (env) { - return this.ruleset.eval(this.frames ? new(tree.evalEnv)(env, this.frames.concat(env.frames)) : env); - } -}; -})(require('../tree')); - -(function (tree) { - -// -// A number with a unit -// -tree.Dimension = function (value, unit) { - this.value = parseFloat(value); - this.unit = (unit && unit instanceof tree.Unit) ? unit : - new(tree.Unit)(unit ? [unit] : undefined); -}; - -tree.Dimension.prototype = { - type: "Dimension", - accept: function (visitor) { - this.unit = visitor.visit(this.unit); - }, - eval: function (env) { - return this; - }, - toColor: function () { - return new(tree.Color)([this.value, this.value, this.value]); - }, - genCSS: function (env, output) { - if ((env && env.strictUnits) && !this.unit.isSingular()) { - throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: "+this.unit.toString()); - } - - var value = tree.fround(env, this.value), - strValue = String(value); - - if (value !== 0 && value < 0.000001 && value > -0.000001) { - // would be output 1e-6 etc. - strValue = value.toFixed(20).replace(/0+$/, ""); - } - - if (env && env.compress) { - // Zero values doesn't need a unit - if (value === 0 && this.unit.isLength()) { - output.add(strValue); - return; - } - - // Float values doesn't need a leading zero - if (value > 0 && value < 1) { - strValue = (strValue).substr(1); - } - } - - output.add(strValue); - this.unit.genCSS(env, output); - }, - toCSS: tree.toCSS, - - // In an operation between two Dimensions, - // we default to the first Dimension's unit, - // so `1px + 2` will yield `3px`. - operate: function (env, op, other) { - /*jshint noempty:false */ - var value = tree.operate(env, op, this.value, other.value), - unit = this.unit.clone(); - - if (op === '+' || op === '-') { - if (unit.numerator.length === 0 && unit.denominator.length === 0) { - unit.numerator = other.unit.numerator.slice(0); - unit.denominator = other.unit.denominator.slice(0); - } else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) { - // do nothing - } else { - other = other.convertTo(this.unit.usedUnits()); - - if(env.strictUnits && other.unit.toString() !== unit.toString()) { - throw new Error("Incompatible units. Change the units or use the unit function. Bad units: '" + unit.toString() + - "' and '" + other.unit.toString() + "'."); - } - - value = tree.operate(env, op, this.value, other.value); - } - } else if (op === '*') { - unit.numerator = unit.numerator.concat(other.unit.numerator).sort(); - unit.denominator = unit.denominator.concat(other.unit.denominator).sort(); - unit.cancel(); - } else if (op === '/') { - unit.numerator = unit.numerator.concat(other.unit.denominator).sort(); - unit.denominator = unit.denominator.concat(other.unit.numerator).sort(); - unit.cancel(); - } - return new(tree.Dimension)(value, unit); - }, - - compare: function (other) { - if (other instanceof tree.Dimension) { - var a, b, - aValue, bValue; - - if (this.unit.isEmpty() || other.unit.isEmpty()) { - a = this; - b = other; - } else { - a = this.unify(); - b = other.unify(); - if (a.unit.compare(b.unit) !== 0) { - return -1; - } - } - aValue = a.value; - bValue = b.value; - - if (bValue > aValue) { - return -1; - } else if (bValue < aValue) { - return 1; - } else { - return 0; - } - } else { - return -1; - } - }, - - unify: function () { - return this.convertTo({ length: 'px', duration: 's', angle: 'rad' }); - }, - - convertTo: function (conversions) { - var value = this.value, unit = this.unit.clone(), - i, groupName, group, targetUnit, derivedConversions = {}, applyUnit; - - if (typeof conversions === 'string') { - for(i in tree.UnitConversions) { - if (tree.UnitConversions[i].hasOwnProperty(conversions)) { - derivedConversions = {}; - derivedConversions[i] = conversions; - } - } - conversions = derivedConversions; - } - applyUnit = function (atomicUnit, denominator) { - /*jshint loopfunc:true */ - if (group.hasOwnProperty(atomicUnit)) { - if (denominator) { - value = value / (group[atomicUnit] / group[targetUnit]); - } else { - value = value * (group[atomicUnit] / group[targetUnit]); - } - - return targetUnit; - } - - return atomicUnit; - }; - - for (groupName in conversions) { - if (conversions.hasOwnProperty(groupName)) { - targetUnit = conversions[groupName]; - group = tree.UnitConversions[groupName]; - - unit.map(applyUnit); - } - } - - unit.cancel(); - - return new(tree.Dimension)(value, unit); - } -}; - -// http://www.w3.org/TR/css3-values/#absolute-lengths -tree.UnitConversions = { - length: { - 'm': 1, - 'cm': 0.01, - 'mm': 0.001, - 'in': 0.0254, - 'px': 0.0254 / 96, - 'pt': 0.0254 / 72, - 'pc': 0.0254 / 72 * 12 - }, - duration: { - 's': 1, - 'ms': 0.001 - }, - angle: { - 'rad': 1/(2*Math.PI), - 'deg': 1/360, - 'grad': 1/400, - 'turn': 1 - } -}; - -tree.Unit = function (numerator, denominator, backupUnit) { - this.numerator = numerator ? numerator.slice(0).sort() : []; - this.denominator = denominator ? denominator.slice(0).sort() : []; - this.backupUnit = backupUnit; -}; - -tree.Unit.prototype = { - type: "Unit", - clone: function () { - return new tree.Unit(this.numerator.slice(0), this.denominator.slice(0), this.backupUnit); - }, - genCSS: function (env, output) { - if (this.numerator.length >= 1) { - output.add(this.numerator[0]); - } else - if (this.denominator.length >= 1) { - output.add(this.denominator[0]); - } else - if ((!env || !env.strictUnits) && this.backupUnit) { - output.add(this.backupUnit); - } - }, - toCSS: tree.toCSS, - - toString: function () { - var i, returnStr = this.numerator.join("*"); - for (i = 0; i < this.denominator.length; i++) { - returnStr += "/" + this.denominator[i]; - } - return returnStr; - }, - - compare: function (other) { - return this.is(other.toString()) ? 0 : -1; - }, - - is: function (unitString) { - return this.toString() === unitString; - }, - - isLength: function () { - return Boolean(this.toCSS().match(/px|em|%|in|cm|mm|pc|pt|ex/)); - }, - - isEmpty: function () { - return this.numerator.length === 0 && this.denominator.length === 0; - }, - - isSingular: function() { - return this.numerator.length <= 1 && this.denominator.length === 0; - }, - - map: function(callback) { - var i; - - for (i = 0; i < this.numerator.length; i++) { - this.numerator[i] = callback(this.numerator[i], false); - } - - for (i = 0; i < this.denominator.length; i++) { - this.denominator[i] = callback(this.denominator[i], true); - } - }, - - usedUnits: function() { - var group, result = {}, mapUnit; - - mapUnit = function (atomicUnit) { - /*jshint loopfunc:true */ - if (group.hasOwnProperty(atomicUnit) && !result[groupName]) { - result[groupName] = atomicUnit; - } - - return atomicUnit; - }; - - for (var groupName in tree.UnitConversions) { - if (tree.UnitConversions.hasOwnProperty(groupName)) { - group = tree.UnitConversions[groupName]; - - this.map(mapUnit); - } - } - - return result; - }, - - cancel: function () { - var counter = {}, atomicUnit, i, backup; - - for (i = 0; i < this.numerator.length; i++) { - atomicUnit = this.numerator[i]; - if (!backup) { - backup = atomicUnit; - } - counter[atomicUnit] = (counter[atomicUnit] || 0) + 1; - } - - for (i = 0; i < this.denominator.length; i++) { - atomicUnit = this.denominator[i]; - if (!backup) { - backup = atomicUnit; - } - counter[atomicUnit] = (counter[atomicUnit] || 0) - 1; - } - - this.numerator = []; - this.denominator = []; - - for (atomicUnit in counter) { - if (counter.hasOwnProperty(atomicUnit)) { - var count = counter[atomicUnit]; - - if (count > 0) { - for (i = 0; i < count; i++) { - this.numerator.push(atomicUnit); - } - } else if (count < 0) { - for (i = 0; i < -count; i++) { - this.denominator.push(atomicUnit); - } - } - } - } - - if (this.numerator.length === 0 && this.denominator.length === 0 && backup) { - this.backupUnit = backup; - } - - this.numerator.sort(); - this.denominator.sort(); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Directive = function (name, value, rules, index, currentFileInfo, debugInfo) { - this.name = name; - this.value = value; - if (rules) { - this.rules = rules; - this.rules.allowImports = true; - } - this.index = index; - this.currentFileInfo = currentFileInfo; - this.debugInfo = debugInfo; -}; - -tree.Directive.prototype = { - type: "Directive", - accept: function (visitor) { - var value = this.value, rules = this.rules; - if (rules) { - rules = visitor.visit(rules); - } - if (value) { - value = visitor.visit(value); - } - }, - isRulesetLike: function() { - return !this.isCharset(); - }, - isCharset: function() { - return "@charset" === this.name; - }, - genCSS: function (env, output) { - var value = this.value, rules = this.rules; - output.add(this.name, this.currentFileInfo, this.index); - if (value) { - output.add(' '); - value.genCSS(env, output); - } - if (rules) { - tree.outputRuleset(env, output, [rules]); - } else { - output.add(';'); - } - }, - toCSS: tree.toCSS, - eval: function (env) { - var value = this.value, rules = this.rules; - if (value) { - value = value.eval(env); - } - if (rules) { - rules = rules.eval(env); - rules.root = true; - } - return new(tree.Directive)(this.name, value, rules, - this.index, this.currentFileInfo, this.debugInfo); - }, - variable: function (name) { if (this.rules) return tree.Ruleset.prototype.variable.call(this.rules, name); }, - find: function () { if (this.rules) return tree.Ruleset.prototype.find.apply(this.rules, arguments); }, - rulesets: function () { if (this.rules) return tree.Ruleset.prototype.rulesets.apply(this.rules); }, - markReferenced: function () { - var i, rules; - this.isReferenced = true; - if (this.rules) { - rules = this.rules.rules; - for (i = 0; i < rules.length; i++) { - if (rules[i].markReferenced) { - rules[i].markReferenced(); - } - } - } - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Element = function (combinator, value, index, currentFileInfo) { - this.combinator = combinator instanceof tree.Combinator ? - combinator : new(tree.Combinator)(combinator); - - if (typeof(value) === 'string') { - this.value = value.trim(); - } else if (value) { - this.value = value; - } else { - this.value = ""; - } - this.index = index; - this.currentFileInfo = currentFileInfo; -}; -tree.Element.prototype = { - type: "Element", - accept: function (visitor) { - var value = this.value; - this.combinator = visitor.visit(this.combinator); - if (typeof value === "object") { - this.value = visitor.visit(value); - } - }, - eval: function (env) { - return new(tree.Element)(this.combinator, - this.value.eval ? this.value.eval(env) : this.value, - this.index, - this.currentFileInfo); - }, - genCSS: function (env, output) { - output.add(this.toCSS(env), this.currentFileInfo, this.index); - }, - toCSS: function (env) { - var value = (this.value.toCSS ? this.value.toCSS(env) : this.value); - if (value === '' && this.combinator.value.charAt(0) === '&') { - return ''; - } else { - return this.combinator.toCSS(env || {}) + value; - } - } -}; - -tree.Attribute = function (key, op, value) { - this.key = key; - this.op = op; - this.value = value; -}; -tree.Attribute.prototype = { - type: "Attribute", - eval: function (env) { - return new(tree.Attribute)(this.key.eval ? this.key.eval(env) : this.key, - this.op, (this.value && this.value.eval) ? this.value.eval(env) : this.value); - }, - genCSS: function (env, output) { - output.add(this.toCSS(env)); - }, - toCSS: function (env) { - var value = this.key.toCSS ? this.key.toCSS(env) : this.key; - - if (this.op) { - value += this.op; - value += (this.value.toCSS ? this.value.toCSS(env) : this.value); - } - - return '[' + value + ']'; - } -}; - -tree.Combinator = function (value) { - if (value === ' ') { - this.value = ' '; - } else { - this.value = value ? value.trim() : ""; - } -}; -tree.Combinator.prototype = { - type: "Combinator", - _noSpaceCombinators: { - '': true, - ' ': true, - '|': true - }, - genCSS: function (env, output) { - var spaceOrEmpty = (env.compress || this._noSpaceCombinators[this.value]) ? '' : ' '; - output.add(spaceOrEmpty + this.value + spaceOrEmpty); - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -tree.Expression = function (value) { this.value = value; }; -tree.Expression.prototype = { - type: "Expression", - accept: function (visitor) { - if (this.value) { - this.value = visitor.visitArray(this.value); - } - }, - eval: function (env) { - var returnValue, - inParenthesis = this.parens && !this.parensInOp, - doubleParen = false; - if (inParenthesis) { - env.inParenthesis(); - } - if (this.value.length > 1) { - returnValue = new(tree.Expression)(this.value.map(function (e) { - return e.eval(env); - })); - } else if (this.value.length === 1) { - if (this.value[0].parens && !this.value[0].parensInOp) { - doubleParen = true; - } - returnValue = this.value[0].eval(env); - } else { - returnValue = this; - } - if (inParenthesis) { - env.outOfParenthesis(); - } - if (this.parens && this.parensInOp && !(env.isMathOn()) && !doubleParen) { - returnValue = new(tree.Paren)(returnValue); - } - return returnValue; - }, - genCSS: function (env, output) { - for(var i = 0; i < this.value.length; i++) { - this.value[i].genCSS(env, output); - if (i + 1 < this.value.length) { - output.add(" "); - } - } - }, - toCSS: tree.toCSS, - throwAwayComments: function () { - this.value = this.value.filter(function(v) { - return !(v instanceof tree.Comment); - }); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Extend = function Extend(selector, option, index) { - this.selector = selector; - this.option = option; - this.index = index; - this.object_id = tree.Extend.next_id++; - this.parent_ids = [this.object_id]; - - switch(option) { - case "all": - this.allowBefore = true; - this.allowAfter = true; - break; - default: - this.allowBefore = false; - this.allowAfter = false; - break; - } -}; -tree.Extend.next_id = 0; - -tree.Extend.prototype = { - type: "Extend", - accept: function (visitor) { - this.selector = visitor.visit(this.selector); - }, - eval: function (env) { - return new(tree.Extend)(this.selector.eval(env), this.option, this.index); - }, - clone: function (env) { - return new(tree.Extend)(this.selector, this.option, this.index); - }, - findSelfSelectors: function (selectors) { - var selfElements = [], - i, - selectorElements; - - for(i = 0; i < selectors.length; i++) { - selectorElements = selectors[i].elements; - // duplicate the logic in genCSS function inside the selector node. - // future TODO - move both logics into the selector joiner visitor - if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === "") { - selectorElements[0].combinator.value = ' '; - } - selfElements = selfElements.concat(selectors[i].elements); - } - - this.selfSelectors = [{ elements: selfElements }]; - } -}; - -})(require('../tree')); - -(function (tree) { -// -// CSS @import node -// -// The general strategy here is that we don't want to wait -// for the parsing to be completed, before we start importing -// the file. That's because in the context of a browser, -// most of the time will be spent waiting for the server to respond. -// -// On creation, we push the import path to our import queue, though -// `import,push`, we also pass it a callback, which it'll call once -// the file has been fetched, and parsed. -// -tree.Import = function (path, features, options, index, currentFileInfo) { - this.options = options; - this.index = index; - this.path = path; - this.features = features; - this.currentFileInfo = currentFileInfo; - - if (this.options.less !== undefined || this.options.inline) { - this.css = !this.options.less || this.options.inline; - } else { - var pathValue = this.getPath(); - if (pathValue && /css([\?;].*)?$/.test(pathValue)) { - this.css = true; - } - } -}; - -// -// The actual import node doesn't return anything, when converted to CSS. -// The reason is that it's used at the evaluation stage, so that the rules -// it imports can be treated like any other rules. -// -// In `eval`, we make sure all Import nodes get evaluated, recursively, so -// we end up with a flat structure, which can easily be imported in the parent -// ruleset. -// -tree.Import.prototype = { - type: "Import", - accept: function (visitor) { - if (this.features) { - this.features = visitor.visit(this.features); - } - this.path = visitor.visit(this.path); - if (!this.options.inline && this.root) { - this.root = visitor.visit(this.root); - } - }, - genCSS: function (env, output) { - if (this.css) { - output.add("@import ", this.currentFileInfo, this.index); - this.path.genCSS(env, output); - if (this.features) { - output.add(" "); - this.features.genCSS(env, output); - } - output.add(';'); - } - }, - toCSS: tree.toCSS, - getPath: function () { - if (this.path instanceof tree.Quoted) { - var path = this.path.value; - return (this.css !== undefined || /(\.[a-z]*$)|([\?;].*)$/.test(path)) ? path : path + '.less'; - } else if (this.path instanceof tree.URL) { - return this.path.value.value; - } - return null; - }, - evalForImport: function (env) { - return new(tree.Import)(this.path.eval(env), this.features, this.options, this.index, this.currentFileInfo); - }, - evalPath: function (env) { - var path = this.path.eval(env); - var rootpath = this.currentFileInfo && this.currentFileInfo.rootpath; - - if (!(path instanceof tree.URL)) { - if (rootpath) { - var pathValue = path.value; - // Add the base path if the import is relative - if (pathValue && env.isPathRelative(pathValue)) { - path.value = rootpath +pathValue; - } - } - path.value = env.normalizePath(path.value); - } - - return path; - }, - eval: function (env) { - var ruleset, features = this.features && this.features.eval(env); - - if (this.skip) { - if (typeof this.skip === "function") { - this.skip = this.skip(); - } - if (this.skip) { - return []; - } - } - - if (this.options.inline) { - //todo needs to reference css file not import - var contents = new(tree.Anonymous)(this.root, 0, {filename: this.importedFilename}, true, true); - return this.features ? new(tree.Media)([contents], this.features.value) : [contents]; - } else if (this.css) { - var newImport = new(tree.Import)(this.evalPath(env), features, this.options, this.index); - if (!newImport.css && this.error) { - throw this.error; - } - return newImport; - } else { - ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0)); - - ruleset.evalImports(env); - - return this.features ? new(tree.Media)(ruleset.rules, this.features.value) : ruleset.rules; - } - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.JavaScript = function (string, index, escaped) { - this.escaped = escaped; - this.expression = string; - this.index = index; -}; -tree.JavaScript.prototype = { - type: "JavaScript", - eval: function (env) { - var result, - that = this, - context = {}; - - var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) { - return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env)); - }); - - try { - expression = new(Function)('return (' + expression + ')'); - } catch (e) { - throw { message: "JavaScript evaluation error: " + e.message + " from `" + expression + "`" , - index: this.index }; - } - - var variables = env.frames[0].variables(); - for (var k in variables) { - if (variables.hasOwnProperty(k)) { - /*jshint loopfunc:true */ - context[k.slice(1)] = { - value: variables[k].value, - toJS: function () { - return this.value.eval(env).toCSS(); - } - }; - } - } - - try { - result = expression.call(context); - } catch (e) { - throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message.replace(/["]/g, "'") + "'" , - index: this.index }; - } - if (typeof(result) === 'number') { - return new(tree.Dimension)(result); - } else if (typeof(result) === 'string') { - return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index); - } else if (Array.isArray(result)) { - return new(tree.Anonymous)(result.join(', ')); - } else { - return new(tree.Anonymous)(result); - } - } -}; - -})(require('../tree')); - - -(function (tree) { - -tree.Keyword = function (value) { this.value = value; }; -tree.Keyword.prototype = { - type: "Keyword", - eval: function () { return this; }, - genCSS: function (env, output) { - if (this.value === '%') { throw { type: "Syntax", message: "Invalid % without number" }; } - output.add(this.value); - }, - toCSS: tree.toCSS, - compare: function (other) { - if (other instanceof tree.Keyword) { - return other.value === this.value ? 0 : 1; - } else { - return -1; - } - } -}; - -tree.True = new(tree.Keyword)('true'); -tree.False = new(tree.Keyword)('false'); - -})(require('../tree')); - -(function (tree) { - -tree.Media = function (value, features, index, currentFileInfo) { - this.index = index; - this.currentFileInfo = currentFileInfo; - - var selectors = this.emptySelectors(); - - this.features = new(tree.Value)(features); - this.rules = [new(tree.Ruleset)(selectors, value)]; - this.rules[0].allowImports = true; -}; -tree.Media.prototype = { - type: "Media", - accept: function (visitor) { - if (this.features) { - this.features = visitor.visit(this.features); - } - if (this.rules) { - this.rules = visitor.visitArray(this.rules); - } - }, - genCSS: function (env, output) { - output.add('@media ', this.currentFileInfo, this.index); - this.features.genCSS(env, output); - tree.outputRuleset(env, output, this.rules); - }, - toCSS: tree.toCSS, - eval: function (env) { - if (!env.mediaBlocks) { - env.mediaBlocks = []; - env.mediaPath = []; - } - - var media = new(tree.Media)(null, [], this.index, this.currentFileInfo); - if(this.debugInfo) { - this.rules[0].debugInfo = this.debugInfo; - media.debugInfo = this.debugInfo; - } - var strictMathBypass = false; - if (!env.strictMath) { - strictMathBypass = true; - env.strictMath = true; - } - try { - media.features = this.features.eval(env); - } - finally { - if (strictMathBypass) { - env.strictMath = false; - } - } - - env.mediaPath.push(media); - env.mediaBlocks.push(media); - - env.frames.unshift(this.rules[0]); - media.rules = [this.rules[0].eval(env)]; - env.frames.shift(); - - env.mediaPath.pop(); - - return env.mediaPath.length === 0 ? media.evalTop(env) : - media.evalNested(env); - }, - variable: function (name) { return tree.Ruleset.prototype.variable.call(this.rules[0], name); }, - find: function () { return tree.Ruleset.prototype.find.apply(this.rules[0], arguments); }, - rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.rules[0]); }, - emptySelectors: function() { - var el = new(tree.Element)('', '&', this.index, this.currentFileInfo), - sels = [new(tree.Selector)([el], null, null, this.index, this.currentFileInfo)]; - sels[0].mediaEmpty = true; - return sels; - }, - markReferenced: function () { - var i, rules = this.rules[0].rules; - this.rules[0].markReferenced(); - this.isReferenced = true; - for (i = 0; i < rules.length; i++) { - if (rules[i].markReferenced) { - rules[i].markReferenced(); - } - } - }, - - evalTop: function (env) { - var result = this; - - // Render all dependent Media blocks. - if (env.mediaBlocks.length > 1) { - var selectors = this.emptySelectors(); - result = new(tree.Ruleset)(selectors, env.mediaBlocks); - result.multiMedia = true; - } - - delete env.mediaBlocks; - delete env.mediaPath; - - return result; - }, - evalNested: function (env) { - var i, value, - path = env.mediaPath.concat([this]); - - // Extract the media-query conditions separated with `,` (OR). - for (i = 0; i < path.length; i++) { - value = path[i].features instanceof tree.Value ? - path[i].features.value : path[i].features; - path[i] = Array.isArray(value) ? value : [value]; - } - - // Trace all permutations to generate the resulting media-query. - // - // (a, b and c) with nested (d, e) -> - // a and d - // a and e - // b and c and d - // b and c and e - this.features = new(tree.Value)(this.permute(path).map(function (path) { - path = path.map(function (fragment) { - return fragment.toCSS ? fragment : new(tree.Anonymous)(fragment); - }); - - for(i = path.length - 1; i > 0; i--) { - path.splice(i, 0, new(tree.Anonymous)("and")); - } - - return new(tree.Expression)(path); - })); - - // Fake a tree-node that doesn't output anything. - return new(tree.Ruleset)([], []); - }, - permute: function (arr) { - if (arr.length === 0) { - return []; - } else if (arr.length === 1) { - return arr[0]; - } else { - var result = []; - var rest = this.permute(arr.slice(1)); - for (var i = 0; i < rest.length; i++) { - for (var j = 0; j < arr[0].length; j++) { - result.push([arr[0][j]].concat(rest[i])); - } - } - return result; - } - }, - bubbleSelectors: function (selectors) { - if (!selectors) - return; - this.rules = [new(tree.Ruleset)(selectors.slice(0), [this.rules[0]])]; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.mixin = {}; -tree.mixin.Call = function (elements, args, index, currentFileInfo, important) { - this.selector = new(tree.Selector)(elements); - this.arguments = (args && args.length) ? args : null; - this.index = index; - this.currentFileInfo = currentFileInfo; - this.important = important; -}; -tree.mixin.Call.prototype = { - type: "MixinCall", - accept: function (visitor) { - if (this.selector) { - this.selector = visitor.visit(this.selector); - } - if (this.arguments) { - this.arguments = visitor.visitArray(this.arguments); - } - }, - eval: function (env) { - var mixins, mixin, args, rules = [], match = false, i, m, f, isRecursive, isOneFound, rule, - candidates = [], candidate, conditionResult = [], defaultFunc = tree.defaultFunc, - defaultResult, defNone = 0, defTrue = 1, defFalse = 2, count, originalRuleset; - - args = this.arguments && this.arguments.map(function (a) { - return { name: a.name, value: a.value.eval(env) }; - }); - - for (i = 0; i < env.frames.length; i++) { - if ((mixins = env.frames[i].find(this.selector)).length > 0) { - isOneFound = true; - - // To make `default()` function independent of definition order we have two "subpasses" here. - // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`), - // and build candidate list with corresponding flags. Then, when we know all possible matches, - // we make a final decision. - - for (m = 0; m < mixins.length; m++) { - mixin = mixins[m]; - isRecursive = false; - for(f = 0; f < env.frames.length; f++) { - if ((!(mixin instanceof tree.mixin.Definition)) && mixin === (env.frames[f].originalRuleset || env.frames[f])) { - isRecursive = true; - break; - } - } - if (isRecursive) { - continue; - } - - if (mixin.matchArgs(args, env)) { - candidate = {mixin: mixin, group: defNone}; - - if (mixin.matchCondition) { - for (f = 0; f < 2; f++) { - defaultFunc.value(f); - conditionResult[f] = mixin.matchCondition(args, env); - } - if (conditionResult[0] || conditionResult[1]) { - if (conditionResult[0] != conditionResult[1]) { - candidate.group = conditionResult[1] ? - defTrue : defFalse; - } - - candidates.push(candidate); - } - } - else { - candidates.push(candidate); - } - - match = true; - } - } - - defaultFunc.reset(); - - count = [0, 0, 0]; - for (m = 0; m < candidates.length; m++) { - count[candidates[m].group]++; - } - - if (count[defNone] > 0) { - defaultResult = defFalse; - } else { - defaultResult = defTrue; - if ((count[defTrue] + count[defFalse]) > 1) { - throw { type: 'Runtime', - message: 'Ambiguous use of `default()` found when matching for `' - + this.format(args) + '`', - index: this.index, filename: this.currentFileInfo.filename }; - } - } - - for (m = 0; m < candidates.length; m++) { - candidate = candidates[m].group; - if ((candidate === defNone) || (candidate === defaultResult)) { - try { - mixin = candidates[m].mixin; - if (!(mixin instanceof tree.mixin.Definition)) { - originalRuleset = mixin.originalRuleset || mixin; - mixin = new tree.mixin.Definition("", [], mixin.rules, null, false); - mixin.originalRuleset = originalRuleset; - } - Array.prototype.push.apply( - rules, mixin.evalCall(env, args, this.important).rules); - } catch (e) { - throw { message: e.message, index: this.index, filename: this.currentFileInfo.filename, stack: e.stack }; - } - } - } - - if (match) { - if (!this.currentFileInfo || !this.currentFileInfo.reference) { - for (i = 0; i < rules.length; i++) { - rule = rules[i]; - if (rule.markReferenced) { - rule.markReferenced(); - } - } - } - return rules; - } - } - } - if (isOneFound) { - throw { type: 'Runtime', - message: 'No matching definition was found for `' + this.format(args) + '`', - index: this.index, filename: this.currentFileInfo.filename }; - } else { - throw { type: 'Name', - message: this.selector.toCSS().trim() + " is undefined", - index: this.index, filename: this.currentFileInfo.filename }; - } - }, - format: function (args) { - return this.selector.toCSS().trim() + '(' + - (args ? args.map(function (a) { - var argValue = ""; - if (a.name) { - argValue += a.name + ":"; - } - if (a.value.toCSS) { - argValue += a.value.toCSS(); - } else { - argValue += "???"; - } - return argValue; - }).join(', ') : "") + ")"; - } -}; - -tree.mixin.Definition = function (name, params, rules, condition, variadic, frames) { - this.name = name; - this.selectors = [new(tree.Selector)([new(tree.Element)(null, name, this.index, this.currentFileInfo)])]; - this.params = params; - this.condition = condition; - this.variadic = variadic; - this.arity = params.length; - this.rules = rules; - this._lookups = {}; - this.required = params.reduce(function (count, p) { - if (!p.name || (p.name && !p.value)) { return count + 1; } - else { return count; } - }, 0); - this.parent = tree.Ruleset.prototype; - this.frames = frames; -}; -tree.mixin.Definition.prototype = { - type: "MixinDefinition", - accept: function (visitor) { - if (this.params && this.params.length) { - this.params = visitor.visitArray(this.params); - } - this.rules = visitor.visitArray(this.rules); - if (this.condition) { - this.condition = visitor.visit(this.condition); - } - }, - variable: function (name) { return this.parent.variable.call(this, name); }, - variables: function () { return this.parent.variables.call(this); }, - find: function () { return this.parent.find.apply(this, arguments); }, - rulesets: function () { return this.parent.rulesets.apply(this); }, - - evalParams: function (env, mixinEnv, args, evaldArguments) { - /*jshint boss:true */ - var frame = new(tree.Ruleset)(null, null), - varargs, arg, - params = this.params.slice(0), - i, j, val, name, isNamedFound, argIndex, argsLength = 0; - - mixinEnv = new tree.evalEnv(mixinEnv, [frame].concat(mixinEnv.frames)); - - if (args) { - args = args.slice(0); - argsLength = args.length; - - for(i = 0; i < argsLength; i++) { - arg = args[i]; - if (name = (arg && arg.name)) { - isNamedFound = false; - for(j = 0; j < params.length; j++) { - if (!evaldArguments[j] && name === params[j].name) { - evaldArguments[j] = arg.value.eval(env); - frame.prependRule(new(tree.Rule)(name, arg.value.eval(env))); - isNamedFound = true; - break; - } - } - if (isNamedFound) { - args.splice(i, 1); - i--; - continue; - } else { - throw { type: 'Runtime', message: "Named argument for " + this.name + - ' ' + args[i].name + ' not found' }; - } - } - } - } - argIndex = 0; - for (i = 0; i < params.length; i++) { - if (evaldArguments[i]) { continue; } - - arg = args && args[argIndex]; - - if (name = params[i].name) { - if (params[i].variadic) { - varargs = []; - for (j = argIndex; j < argsLength; j++) { - varargs.push(args[j].value.eval(env)); - } - frame.prependRule(new(tree.Rule)(name, new(tree.Expression)(varargs).eval(env))); - } else { - val = arg && arg.value; - if (val) { - val = val.eval(env); - } else if (params[i].value) { - val = params[i].value.eval(mixinEnv); - frame.resetCache(); - } else { - throw { type: 'Runtime', message: "wrong number of arguments for " + this.name + - ' (' + argsLength + ' for ' + this.arity + ')' }; - } - - frame.prependRule(new(tree.Rule)(name, val)); - evaldArguments[i] = val; - } - } - - if (params[i].variadic && args) { - for (j = argIndex; j < argsLength; j++) { - evaldArguments[j] = args[j].value.eval(env); - } - } - argIndex++; - } - - return frame; - }, - eval: function (env) { - return new tree.mixin.Definition(this.name, this.params, this.rules, this.condition, this.variadic, this.frames || env.frames.slice(0)); - }, - evalCall: function (env, args, important) { - var _arguments = [], - mixinFrames = this.frames ? this.frames.concat(env.frames) : env.frames, - frame = this.evalParams(env, new(tree.evalEnv)(env, mixinFrames), args, _arguments), - rules, ruleset; - - frame.prependRule(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env))); - - rules = this.rules.slice(0); - - ruleset = new(tree.Ruleset)(null, rules); - ruleset.originalRuleset = this; - ruleset = ruleset.eval(new(tree.evalEnv)(env, [this, frame].concat(mixinFrames))); - if (important) { - ruleset = this.parent.makeImportant.apply(ruleset); - } - return ruleset; - }, - matchCondition: function (args, env) { - if (this.condition && !this.condition.eval( - new(tree.evalEnv)(env, - [this.evalParams(env, new(tree.evalEnv)(env, this.frames ? this.frames.concat(env.frames) : env.frames), args, [])] // the parameter variables - .concat(this.frames) // the parent namespace/mixin frames - .concat(env.frames)))) { // the current environment frames - return false; - } - return true; - }, - matchArgs: function (args, env) { - var argsLength = (args && args.length) || 0, len; - - if (! this.variadic) { - if (argsLength < this.required) { return false; } - if (argsLength > this.params.length) { return false; } - } else { - if (argsLength < (this.required - 1)) { return false; } - } - - len = Math.min(argsLength, this.arity); - - for (var i = 0; i < len; i++) { - if (!this.params[i].name && !this.params[i].variadic) { - if (args[i].value.eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) { - return false; - } - } - } - return true; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Negative = function (node) { - this.value = node; -}; -tree.Negative.prototype = { - type: "Negative", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add('-'); - this.value.genCSS(env, output); - }, - toCSS: tree.toCSS, - eval: function (env) { - if (env.isMathOn()) { - return (new(tree.Operation)('*', [new(tree.Dimension)(-1), this.value])).eval(env); - } - return new(tree.Negative)(this.value.eval(env)); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Operation = function (op, operands, isSpaced) { - this.op = op.trim(); - this.operands = operands; - this.isSpaced = isSpaced; -}; -tree.Operation.prototype = { - type: "Operation", - accept: function (visitor) { - this.operands = visitor.visit(this.operands); - }, - eval: function (env) { - var a = this.operands[0].eval(env), - b = this.operands[1].eval(env); - - if (env.isMathOn()) { - if (a instanceof tree.Dimension && b instanceof tree.Color) { - a = a.toColor(); - } - if (b instanceof tree.Dimension && a instanceof tree.Color) { - b = b.toColor(); - } - if (!a.operate) { - throw { type: "Operation", - message: "Operation on an invalid type" }; - } - - return a.operate(env, this.op, b); - } else { - return new(tree.Operation)(this.op, [a, b], this.isSpaced); - } - }, - genCSS: function (env, output) { - this.operands[0].genCSS(env, output); - if (this.isSpaced) { - output.add(" "); - } - output.add(this.op); - if (this.isSpaced) { - output.add(" "); - } - this.operands[1].genCSS(env, output); - }, - toCSS: tree.toCSS -}; - -tree.operate = function (env, op, a, b) { - switch (op) { - case '+': return a + b; - case '-': return a - b; - case '*': return a * b; - case '/': return a / b; - } -}; - -})(require('../tree')); - - -(function (tree) { - -tree.Paren = function (node) { - this.value = node; -}; -tree.Paren.prototype = { - type: "Paren", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add('('); - this.value.genCSS(env, output); - output.add(')'); - }, - toCSS: tree.toCSS, - eval: function (env) { - return new(tree.Paren)(this.value.eval(env)); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Quoted = function (str, content, escaped, index, currentFileInfo) { - this.escaped = escaped; - this.value = content || ''; - this.quote = str.charAt(0); - this.index = index; - this.currentFileInfo = currentFileInfo; -}; -tree.Quoted.prototype = { - type: "Quoted", - genCSS: function (env, output) { - if (!this.escaped) { - output.add(this.quote, this.currentFileInfo, this.index); - } - output.add(this.value); - if (!this.escaped) { - output.add(this.quote); - } - }, - toCSS: tree.toCSS, - eval: function (env) { - var that = this; - var value = this.value.replace(/`([^`]+)`/g, function (_, exp) { - return new(tree.JavaScript)(exp, that.index, true).eval(env).value; - }).replace(/@\{([\w-]+)\}/g, function (_, name) { - var v = new(tree.Variable)('@' + name, that.index, that.currentFileInfo).eval(env, true); - return (v instanceof tree.Quoted) ? v.value : v.toCSS(); - }); - return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index, this.currentFileInfo); - }, - compare: function (x) { - if (!x.toCSS) { - return -1; - } - - var left, right; - - // when comparing quoted strings allow the quote to differ - if (x.type === "Quoted" && !this.escaped && !x.escaped) { - left = x.value; - right = this.value; - } else { - left = this.toCSS(); - right = x.toCSS(); - } - - if (left === right) { - return 0; - } - - return left < right ? -1 : 1; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Rule = function (name, value, important, merge, index, currentFileInfo, inline, variable) { - this.name = name; - this.value = (value instanceof tree.Value || value instanceof tree.Ruleset) ? value : new(tree.Value)([value]); - this.important = important ? ' ' + important.trim() : ''; - this.merge = merge; - this.index = index; - this.currentFileInfo = currentFileInfo; - this.inline = inline || false; - this.variable = (variable !== undefined) ? variable - : (name.charAt && (name.charAt(0) === '@')); -}; - -tree.Rule.prototype = { - type: "Rule", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add(this.name + (env.compress ? ':' : ': '), this.currentFileInfo, this.index); - try { - this.value.genCSS(env, output); - } - catch(e) { - e.index = this.index; - e.filename = this.currentFileInfo.filename; - throw e; - } - output.add(this.important + ((this.inline || (env.lastRule && env.compress)) ? "" : ";"), this.currentFileInfo, this.index); - }, - toCSS: tree.toCSS, - eval: function (env) { - var strictMathBypass = false, name = this.name, variable = this.variable, evaldValue; - if (typeof name !== "string") { - // expand 'primitive' name directly to get - // things faster (~10% for benchmark.less): - name = (name.length === 1) - && (name[0] instanceof tree.Keyword) - ? name[0].value : evalName(env, name); - variable = false; // never treat expanded interpolation as new variable name - } - if (name === "font" && !env.strictMath) { - strictMathBypass = true; - env.strictMath = true; - } - try { - evaldValue = this.value.eval(env); - - if (!this.variable && evaldValue.type === "DetachedRuleset") { - throw { message: "Rulesets cannot be evaluated on a property.", - index: this.index, filename: this.currentFileInfo.filename }; - } - - return new(tree.Rule)(name, - evaldValue, - this.important, - this.merge, - this.index, this.currentFileInfo, this.inline, - variable); - } - catch(e) { - if (typeof e.index !== 'number') { - e.index = this.index; - e.filename = this.currentFileInfo.filename; - } - throw e; - } - finally { - if (strictMathBypass) { - env.strictMath = false; - } - } - }, - makeImportant: function () { - return new(tree.Rule)(this.name, - this.value, - "!important", - this.merge, - this.index, this.currentFileInfo, this.inline); - } -}; - -function evalName(env, name) { - var value = "", i, n = name.length, - output = {add: function (s) {value += s;}}; - for (i = 0; i < n; i++) { - name[i].eval(env).genCSS(env, output); - } - return value; -} - -})(require('../tree')); - -(function (tree) { - -tree.RulesetCall = function (variable) { - this.variable = variable; -}; -tree.RulesetCall.prototype = { - type: "RulesetCall", - accept: function (visitor) { - }, - eval: function (env) { - var detachedRuleset = new(tree.Variable)(this.variable).eval(env); - return detachedRuleset.callEval(env); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Ruleset = function (selectors, rules, strictImports) { - this.selectors = selectors; - this.rules = rules; - this._lookups = {}; - this.strictImports = strictImports; -}; -tree.Ruleset.prototype = { - type: "Ruleset", - accept: function (visitor) { - if (this.paths) { - visitor.visitArray(this.paths, true); - } else if (this.selectors) { - this.selectors = visitor.visitArray(this.selectors); - } - if (this.rules && this.rules.length) { - this.rules = visitor.visitArray(this.rules); - } - }, - eval: function (env) { - var thisSelectors = this.selectors, selectors, - selCnt, selector, i, defaultFunc = tree.defaultFunc, hasOnePassingSelector = false; - - if (thisSelectors && (selCnt = thisSelectors.length)) { - selectors = []; - defaultFunc.error({ - type: "Syntax", - message: "it is currently only allowed in parametric mixin guards," - }); - for (i = 0; i < selCnt; i++) { - selector = thisSelectors[i].eval(env); - selectors.push(selector); - if (selector.evaldCondition) { - hasOnePassingSelector = true; - } - } - defaultFunc.reset(); - } else { - hasOnePassingSelector = true; - } - - var rules = this.rules ? this.rules.slice(0) : null, - ruleset = new(tree.Ruleset)(selectors, rules, this.strictImports), - rule, subRule; - - ruleset.originalRuleset = this; - ruleset.root = this.root; - ruleset.firstRoot = this.firstRoot; - ruleset.allowImports = this.allowImports; - - if(this.debugInfo) { - ruleset.debugInfo = this.debugInfo; - } - - if (!hasOnePassingSelector) { - rules.length = 0; - } - - // push the current ruleset to the frames stack - var envFrames = env.frames; - envFrames.unshift(ruleset); - - // currrent selectors - var envSelectors = env.selectors; - if (!envSelectors) { - env.selectors = envSelectors = []; - } - envSelectors.unshift(this.selectors); - - // Evaluate imports - if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) { - ruleset.evalImports(env); - } - - // Store the frames around mixin definitions, - // so they can be evaluated like closures when the time comes. - var rsRules = ruleset.rules, rsRuleCnt = rsRules ? rsRules.length : 0; - for (i = 0; i < rsRuleCnt; i++) { - if (rsRules[i] instanceof tree.mixin.Definition || rsRules[i] instanceof tree.DetachedRuleset) { - rsRules[i] = rsRules[i].eval(env); - } - } - - var mediaBlockCount = (env.mediaBlocks && env.mediaBlocks.length) || 0; - - // Evaluate mixin calls. - for (i = 0; i < rsRuleCnt; i++) { - if (rsRules[i] instanceof tree.mixin.Call) { - /*jshint loopfunc:true */ - rules = rsRules[i].eval(env).filter(function(r) { - if ((r instanceof tree.Rule) && r.variable) { - // do not pollute the scope if the variable is - // already there. consider returning false here - // but we need a way to "return" variable from mixins - return !(ruleset.variable(r.name)); - } - return true; - }); - rsRules.splice.apply(rsRules, [i, 1].concat(rules)); - rsRuleCnt += rules.length - 1; - i += rules.length-1; - ruleset.resetCache(); - } else if (rsRules[i] instanceof tree.RulesetCall) { - /*jshint loopfunc:true */ - rules = rsRules[i].eval(env).rules.filter(function(r) { - if ((r instanceof tree.Rule) && r.variable) { - // do not pollute the scope at all - return false; - } - return true; - }); - rsRules.splice.apply(rsRules, [i, 1].concat(rules)); - rsRuleCnt += rules.length - 1; - i += rules.length-1; - ruleset.resetCache(); - } - } - - // Evaluate everything else - for (i = 0; i < rsRules.length; i++) { - rule = rsRules[i]; - if (! (rule instanceof tree.mixin.Definition || rule instanceof tree.DetachedRuleset)) { - rsRules[i] = rule = rule.eval ? rule.eval(env) : rule; - } - } - - // Evaluate everything else - for (i = 0; i < rsRules.length; i++) { - rule = rsRules[i]; - // for rulesets, check if it is a css guard and can be removed - if (rule instanceof tree.Ruleset && rule.selectors && rule.selectors.length === 1) { - // check if it can be folded in (e.g. & where) - if (rule.selectors[0].isJustParentSelector()) { - rsRules.splice(i--, 1); - - for(var j = 0; j < rule.rules.length; j++) { - subRule = rule.rules[j]; - if (!(subRule instanceof tree.Rule) || !subRule.variable) { - rsRules.splice(++i, 0, subRule); - } - } - } - } - } - - // Pop the stack - envFrames.shift(); - envSelectors.shift(); - - if (env.mediaBlocks) { - for (i = mediaBlockCount; i < env.mediaBlocks.length; i++) { - env.mediaBlocks[i].bubbleSelectors(selectors); - } - } - - return ruleset; - }, - evalImports: function(env) { - var rules = this.rules, i, importRules; - if (!rules) { return; } - - for (i = 0; i < rules.length; i++) { - if (rules[i] instanceof tree.Import) { - importRules = rules[i].eval(env); - if (importRules && importRules.length) { - rules.splice.apply(rules, [i, 1].concat(importRules)); - i+= importRules.length-1; - } else { - rules.splice(i, 1, importRules); - } - this.resetCache(); - } - } - }, - makeImportant: function() { - return new tree.Ruleset(this.selectors, this.rules.map(function (r) { - if (r.makeImportant) { - return r.makeImportant(); - } else { - return r; - } - }), this.strictImports); - }, - matchArgs: function (args) { - return !args || args.length === 0; - }, - // lets you call a css selector with a guard - matchCondition: function (args, env) { - var lastSelector = this.selectors[this.selectors.length-1]; - if (!lastSelector.evaldCondition) { - return false; - } - if (lastSelector.condition && - !lastSelector.condition.eval( - new(tree.evalEnv)(env, - env.frames))) { - return false; - } - return true; - }, - resetCache: function () { - this._rulesets = null; - this._variables = null; - this._lookups = {}; - }, - variables: function () { - if (!this._variables) { - this._variables = !this.rules ? {} : this.rules.reduce(function (hash, r) { - if (r instanceof tree.Rule && r.variable === true) { - hash[r.name] = r; - } - return hash; - }, {}); - } - return this._variables; - }, - variable: function (name) { - return this.variables()[name]; - }, - rulesets: function () { - if (!this.rules) { return null; } - - var _Ruleset = tree.Ruleset, _MixinDefinition = tree.mixin.Definition, - filtRules = [], rules = this.rules, cnt = rules.length, - i, rule; - - for (i = 0; i < cnt; i++) { - rule = rules[i]; - if ((rule instanceof _Ruleset) || (rule instanceof _MixinDefinition)) { - filtRules.push(rule); - } - } - - return filtRules; - }, - prependRule: function (rule) { - var rules = this.rules; - if (rules) { rules.unshift(rule); } else { this.rules = [ rule ]; } - }, - find: function (selector, self) { - self = self || this; - var rules = [], match, - key = selector.toCSS(); - - if (key in this._lookups) { return this._lookups[key]; } - - this.rulesets().forEach(function (rule) { - if (rule !== self) { - for (var j = 0; j < rule.selectors.length; j++) { - match = selector.match(rule.selectors[j]); - if (match) { - if (selector.elements.length > match) { - Array.prototype.push.apply(rules, rule.find( - new(tree.Selector)(selector.elements.slice(match)), self)); - } else { - rules.push(rule); - } - break; - } - } - } - }); - this._lookups[key] = rules; - return rules; - }, - genCSS: function (env, output) { - var i, j, - charsetRuleNodes = [], - ruleNodes = [], - rulesetNodes = [], - rulesetNodeCnt, - debugInfo, // Line number debugging - rule, - path; - - env.tabLevel = (env.tabLevel || 0); - - if (!this.root) { - env.tabLevel++; - } - - var tabRuleStr = env.compress ? '' : Array(env.tabLevel + 1).join(" "), - tabSetStr = env.compress ? '' : Array(env.tabLevel).join(" "), - sep; - - function isRulesetLikeNode(rule, root) { - // if it has nested rules, then it should be treated like a ruleset - if (rule.rules) - return true; - - // medias and comments do not have nested rules, but should be treated like rulesets anyway - if ( (rule instanceof tree.Media) || (root && rule instanceof tree.Comment)) - return true; - - // some directives and anonumoust nodes are ruleset like, others are not - if ((rule instanceof tree.Directive) || (rule instanceof tree.Anonymous)) { - return rule.isRulesetLike(); - } - - //anything else is assumed to be a rule - return false; - } - - for (i = 0; i < this.rules.length; i++) { - rule = this.rules[i]; - if (isRulesetLikeNode(rule, this.root)) { - rulesetNodes.push(rule); - } else { - //charsets should float on top of everything - if (rule.isCharset && rule.isCharset()) { - charsetRuleNodes.push(rule); - } else { - ruleNodes.push(rule); - } - } - } - ruleNodes = charsetRuleNodes.concat(ruleNodes); - - // If this is the root node, we don't render - // a selector, or {}. - if (!this.root) { - debugInfo = tree.debugInfo(env, this, tabSetStr); - - if (debugInfo) { - output.add(debugInfo); - output.add(tabSetStr); - } - - var paths = this.paths, pathCnt = paths.length, - pathSubCnt; - - sep = env.compress ? ',' : (',\n' + tabSetStr); - - for (i = 0; i < pathCnt; i++) { - path = paths[i]; - if (!(pathSubCnt = path.length)) { continue; } - if (i > 0) { output.add(sep); } - - env.firstSelector = true; - path[0].genCSS(env, output); - - env.firstSelector = false; - for (j = 1; j < pathSubCnt; j++) { - path[j].genCSS(env, output); - } - } - - output.add((env.compress ? '{' : ' {\n') + tabRuleStr); - } - - // Compile rules and rulesets - for (i = 0; i < ruleNodes.length; i++) { - rule = ruleNodes[i]; - - // @page{ directive ends up with root elements inside it, a mix of rules and rulesets - // In this instance we do not know whether it is the last property - if (i + 1 === ruleNodes.length && (!this.root || rulesetNodes.length === 0 || this.firstRoot)) { - env.lastRule = true; - } - - if (rule.genCSS) { - rule.genCSS(env, output); - } else if (rule.value) { - output.add(rule.value.toString()); - } - - if (!env.lastRule) { - output.add(env.compress ? '' : ('\n' + tabRuleStr)); - } else { - env.lastRule = false; - } - } - - if (!this.root) { - output.add((env.compress ? '}' : '\n' + tabSetStr + '}')); - env.tabLevel--; - } - - sep = (env.compress ? "" : "\n") + (this.root ? tabRuleStr : tabSetStr); - rulesetNodeCnt = rulesetNodes.length; - if (rulesetNodeCnt) { - if (ruleNodes.length && sep) { output.add(sep); } - rulesetNodes[0].genCSS(env, output); - for (i = 1; i < rulesetNodeCnt; i++) { - if (sep) { output.add(sep); } - rulesetNodes[i].genCSS(env, output); - } - } - - if (!output.isEmpty() && !env.compress && this.firstRoot) { - output.add('\n'); - } - }, - - toCSS: tree.toCSS, - - markReferenced: function () { - if (!this.selectors) { - return; - } - for (var s = 0; s < this.selectors.length; s++) { - this.selectors[s].markReferenced(); - } - }, - - joinSelectors: function (paths, context, selectors) { - for (var s = 0; s < selectors.length; s++) { - this.joinSelector(paths, context, selectors[s]); - } - }, - - joinSelector: function (paths, context, selector) { - - var i, j, k, - hasParentSelector, newSelectors, el, sel, parentSel, - newSelectorPath, afterParentJoin, newJoinedSelector, - newJoinedSelectorEmpty, lastSelector, currentElements, - selectorsMultiplied; - - for (i = 0; i < selector.elements.length; i++) { - el = selector.elements[i]; - if (el.value === '&') { - hasParentSelector = true; - } - } - - if (!hasParentSelector) { - if (context.length > 0) { - for (i = 0; i < context.length; i++) { - paths.push(context[i].concat(selector)); - } - } - else { - paths.push([selector]); - } - return; - } - - // The paths are [[Selector]] - // The first list is a list of comma seperated selectors - // The inner list is a list of inheritance seperated selectors - // e.g. - // .a, .b { - // .c { - // } - // } - // == [[.a] [.c]] [[.b] [.c]] - // - - // the elements from the current selector so far - currentElements = []; - // the current list of new selectors to add to the path. - // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors - // by the parents - newSelectors = [[]]; - - for (i = 0; i < selector.elements.length; i++) { - el = selector.elements[i]; - // non parent reference elements just get added - if (el.value !== "&") { - currentElements.push(el); - } else { - // the new list of selectors to add - selectorsMultiplied = []; - - // merge the current list of non parent selector elements - // on to the current list of selectors to add - if (currentElements.length > 0) { - this.mergeElementsOnToSelectors(currentElements, newSelectors); - } - - // loop through our current selectors - for (j = 0; j < newSelectors.length; j++) { - sel = newSelectors[j]; - // if we don't have any parent paths, the & might be in a mixin so that it can be used - // whether there are parents or not - if (context.length === 0) { - // the combinator used on el should now be applied to the next element instead so that - // it is not lost - if (sel.length > 0) { - sel[0].elements = sel[0].elements.slice(0); - sel[0].elements.push(new(tree.Element)(el.combinator, '', el.index, el.currentFileInfo)); - } - selectorsMultiplied.push(sel); - } - else { - // and the parent selectors - for (k = 0; k < context.length; k++) { - parentSel = context[k]; - // We need to put the current selectors - // then join the last selector's elements on to the parents selectors - - // our new selector path - newSelectorPath = []; - // selectors from the parent after the join - afterParentJoin = []; - newJoinedSelectorEmpty = true; - - //construct the joined selector - if & is the first thing this will be empty, - // if not newJoinedSelector will be the last set of elements in the selector - if (sel.length > 0) { - newSelectorPath = sel.slice(0); - lastSelector = newSelectorPath.pop(); - newJoinedSelector = selector.createDerived(lastSelector.elements.slice(0)); - newJoinedSelectorEmpty = false; - } - else { - newJoinedSelector = selector.createDerived([]); - } - - //put together the parent selectors after the join - if (parentSel.length > 1) { - afterParentJoin = afterParentJoin.concat(parentSel.slice(1)); - } - - if (parentSel.length > 0) { - newJoinedSelectorEmpty = false; - - // join the elements so far with the first part of the parent - newJoinedSelector.elements.push(new(tree.Element)(el.combinator, parentSel[0].elements[0].value, el.index, el.currentFileInfo)); - newJoinedSelector.elements = newJoinedSelector.elements.concat(parentSel[0].elements.slice(1)); - } - - if (!newJoinedSelectorEmpty) { - // now add the joined selector - newSelectorPath.push(newJoinedSelector); - } - - // and the rest of the parent - newSelectorPath = newSelectorPath.concat(afterParentJoin); - - // add that to our new set of selectors - selectorsMultiplied.push(newSelectorPath); - } - } - } - - // our new selectors has been multiplied, so reset the state - newSelectors = selectorsMultiplied; - currentElements = []; - } - } - - // if we have any elements left over (e.g. .a& .b == .b) - // add them on to all the current selectors - if (currentElements.length > 0) { - this.mergeElementsOnToSelectors(currentElements, newSelectors); - } - - for (i = 0; i < newSelectors.length; i++) { - if (newSelectors[i].length > 0) { - paths.push(newSelectors[i]); - } - } - }, - - mergeElementsOnToSelectors: function(elements, selectors) { - var i, sel; - - if (selectors.length === 0) { - selectors.push([ new(tree.Selector)(elements) ]); - return; - } - - for (i = 0; i < selectors.length; i++) { - sel = selectors[i]; - - // if the previous thing in sel is a parent this needs to join on to it - if (sel.length > 0) { - sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements)); - } - else { - sel.push(new(tree.Selector)(elements)); - } - } - } -}; -})(require('../tree')); - -(function (tree) { - -tree.Selector = function (elements, extendList, condition, index, currentFileInfo, isReferenced) { - this.elements = elements; - this.extendList = extendList; - this.condition = condition; - this.currentFileInfo = currentFileInfo || {}; - this.isReferenced = isReferenced; - if (!condition) { - this.evaldCondition = true; - } -}; -tree.Selector.prototype = { - type: "Selector", - accept: function (visitor) { - if (this.elements) { - this.elements = visitor.visitArray(this.elements); - } - if (this.extendList) { - this.extendList = visitor.visitArray(this.extendList); - } - if (this.condition) { - this.condition = visitor.visit(this.condition); - } - }, - createDerived: function(elements, extendList, evaldCondition) { - evaldCondition = (evaldCondition != null) ? evaldCondition : this.evaldCondition; - var newSelector = new(tree.Selector)(elements, extendList || this.extendList, null, this.index, this.currentFileInfo, this.isReferenced); - newSelector.evaldCondition = evaldCondition; - newSelector.mediaEmpty = this.mediaEmpty; - return newSelector; - }, - match: function (other) { - var elements = this.elements, - len = elements.length, - olen, i; - - other.CacheElements(); - - olen = other._elements.length; - if (olen === 0 || len < olen) { - return 0; - } else { - for (i = 0; i < olen; i++) { - if (elements[i].value !== other._elements[i]) { - return 0; - } - } - } - - return olen; // return number of matched elements - }, - CacheElements: function(){ - var css = '', len, v, i; - - if( !this._elements ){ - - len = this.elements.length; - for(i = 0; i < len; i++){ - - v = this.elements[i]; - css += v.combinator.value; - - if( !v.value.value ){ - css += v.value; - continue; - } - - if( typeof v.value.value !== "string" ){ - css = ''; - break; - } - css += v.value.value; - } - - this._elements = css.match(/[,&#\*\.\w-]([\w-]|(\\.))*/g); - - if (this._elements) { - if (this._elements[0] === "&") { - this._elements.shift(); - } - - } else { - this._elements = []; - } - - } - }, - isJustParentSelector: function() { - return !this.mediaEmpty && - this.elements.length === 1 && - this.elements[0].value === '&' && - (this.elements[0].combinator.value === ' ' || this.elements[0].combinator.value === ''); - }, - eval: function (env) { - var evaldCondition = this.condition && this.condition.eval(env), - elements = this.elements, extendList = this.extendList; - - elements = elements && elements.map(function (e) { return e.eval(env); }); - extendList = extendList && extendList.map(function(extend) { return extend.eval(env); }); - - return this.createDerived(elements, extendList, evaldCondition); - }, - genCSS: function (env, output) { - var i, element; - if ((!env || !env.firstSelector) && this.elements[0].combinator.value === "") { - output.add(' ', this.currentFileInfo, this.index); - } - if (!this._css) { - //TODO caching? speed comparison? - for(i = 0; i < this.elements.length; i++) { - element = this.elements[i]; - element.genCSS(env, output); - } - } - }, - toCSS: tree.toCSS, - markReferenced: function () { - this.isReferenced = true; - }, - getIsReferenced: function() { - return !this.currentFileInfo.reference || this.isReferenced; - }, - getIsOutput: function() { - return this.evaldCondition; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.UnicodeDescriptor = function (value) { - this.value = value; -}; -tree.UnicodeDescriptor.prototype = { - type: "UnicodeDescriptor", - genCSS: function (env, output) { - output.add(this.value); - }, - toCSS: tree.toCSS, - eval: function () { return this; } -}; - -})(require('../tree')); - -(function (tree) { - -tree.URL = function (val, currentFileInfo, isEvald) { - this.value = val; - this.currentFileInfo = currentFileInfo; - this.isEvald = isEvald; -}; -tree.URL.prototype = { - type: "Url", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add("url("); - this.value.genCSS(env, output); - output.add(")"); - }, - toCSS: tree.toCSS, - eval: function (ctx) { - var val = this.value.eval(ctx), - rootpath; - - if (!this.isEvald) { - // Add the base path if the URL is relative - rootpath = this.currentFileInfo && this.currentFileInfo.rootpath; - if (rootpath && typeof val.value === "string" && ctx.isPathRelative(val.value)) { - if (!val.quote) { - rootpath = rootpath.replace(/[\(\)'"\s]/g, function(match) { return "\\"+match; }); - } - val.value = rootpath + val.value; - } - - val.value = ctx.normalizePath(val.value); - - // Add url args if enabled - if (ctx.urlArgs) { - if (!val.value.match(/^\s*data:/)) { - var delimiter = val.value.indexOf('?') === -1 ? '?' : '&'; - var urlArgs = delimiter + ctx.urlArgs; - if (val.value.indexOf('#') !== -1) { - val.value = val.value.replace('#', urlArgs + '#'); - } else { - val.value += urlArgs; - } - } - } - } - - return new(tree.URL)(val, this.currentFileInfo, true); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Value = function (value) { - this.value = value; -}; -tree.Value.prototype = { - type: "Value", - accept: function (visitor) { - if (this.value) { - this.value = visitor.visitArray(this.value); - } - }, - eval: function (env) { - if (this.value.length === 1) { - return this.value[0].eval(env); - } else { - return new(tree.Value)(this.value.map(function (v) { - return v.eval(env); - })); - } - }, - genCSS: function (env, output) { - var i; - for(i = 0; i < this.value.length; i++) { - this.value[i].genCSS(env, output); - if (i+1 < this.value.length) { - output.add((env && env.compress) ? ',' : ', '); - } - } - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -tree.Variable = function (name, index, currentFileInfo) { - this.name = name; - this.index = index; - this.currentFileInfo = currentFileInfo || {}; -}; -tree.Variable.prototype = { - type: "Variable", - eval: function (env) { - var variable, name = this.name; - - if (name.indexOf('@@') === 0) { - name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value; - } - - if (this.evaluating) { - throw { type: 'Name', - message: "Recursive variable definition for " + name, - filename: this.currentFileInfo.file, - index: this.index }; - } - - this.evaluating = true; - - variable = tree.find(env.frames, function (frame) { - var v = frame.variable(name); - if (v) { - return v.value.eval(env); - } - }); - if (variable) { - this.evaluating = false; - return variable; - } else { - throw { type: 'Name', - message: "variable " + name + " is undefined", - filename: this.currentFileInfo.filename, - index: this.index }; - } - } -}; - -})(require('../tree')); - -(function (tree) { - - var parseCopyProperties = [ - 'paths', // option - unmodified - paths to search for imports on - 'optimization', // option - optimization level (for the chunker) - 'files', // list of files that have been imported, used for import-once - 'contents', // map - filename to contents of all the files - 'contentsIgnoredChars', // map - filename to lines at the begining of each file to ignore - 'relativeUrls', // option - whether to adjust URL's to be relative - 'rootpath', // option - rootpath to append to URL's - 'strictImports', // option - - 'insecure', // option - whether to allow imports from insecure ssl hosts - 'dumpLineNumbers', // option - whether to dump line numbers - 'compress', // option - whether to compress - 'processImports', // option - whether to process imports. if false then imports will not be imported - 'syncImport', // option - whether to import synchronously - 'javascriptEnabled',// option - whether JavaScript is enabled. if undefined, defaults to true - 'mime', // browser only - mime type for sheet import - 'useFileCache', // browser only - whether to use the per file session cache - 'currentFileInfo' // information about the current file - for error reporting and importing and making urls relative etc. - ]; - - //currentFileInfo = { - // 'relativeUrls' - option - whether to adjust URL's to be relative - // 'filename' - full resolved filename of current file - // 'rootpath' - path to append to normal URLs for this node - // 'currentDirectory' - path to the current file, absolute - // 'rootFilename' - filename of the base file - // 'entryPath' - absolute path to the entry file - // 'reference' - whether the file should not be output and only output parts that are referenced - - tree.parseEnv = function(options) { - copyFromOriginal(options, this, parseCopyProperties); - - if (!this.contents) { this.contents = {}; } - if (!this.contentsIgnoredChars) { this.contentsIgnoredChars = {}; } - if (!this.files) { this.files = {}; } - - if (typeof this.paths === "string") { this.paths = [this.paths]; } - - if (!this.currentFileInfo) { - var filename = (options && options.filename) || "input"; - var entryPath = filename.replace(/[^\/\\]*$/, ""); - if (options) { - options.filename = null; - } - this.currentFileInfo = { - filename: filename, - relativeUrls: this.relativeUrls, - rootpath: (options && options.rootpath) || "", - currentDirectory: entryPath, - entryPath: entryPath, - rootFilename: filename - }; - } - }; - - var evalCopyProperties = [ - 'silent', // whether to swallow errors and warnings - 'verbose', // whether to log more activity - 'compress', // whether to compress - 'yuicompress', // whether to compress with the outside tool yui compressor - 'ieCompat', // whether to enforce IE compatibility (IE8 data-uri) - 'strictMath', // whether math has to be within parenthesis - 'strictUnits', // whether units need to evaluate correctly - 'cleancss', // whether to compress with clean-css - 'sourceMap', // whether to output a source map - 'importMultiple', // whether we are currently importing multiple copies - 'urlArgs' // whether to add args into url tokens - ]; - - tree.evalEnv = function(options, frames) { - copyFromOriginal(options, this, evalCopyProperties); - - this.frames = frames || []; - }; - - tree.evalEnv.prototype.inParenthesis = function () { - if (!this.parensStack) { - this.parensStack = []; - } - this.parensStack.push(true); - }; - - tree.evalEnv.prototype.outOfParenthesis = function () { - this.parensStack.pop(); - }; - - tree.evalEnv.prototype.isMathOn = function () { - return this.strictMath ? (this.parensStack && this.parensStack.length) : true; - }; - - tree.evalEnv.prototype.isPathRelative = function (path) { - return !/^(?:[a-z-]+:|\/)/.test(path); - }; - - tree.evalEnv.prototype.normalizePath = function( path ) { - var - segments = path.split("/").reverse(), - segment; - - path = []; - while (segments.length !== 0 ) { - segment = segments.pop(); - switch( segment ) { - case ".": - break; - case "..": - if ((path.length === 0) || (path[path.length - 1] === "..")) { - path.push( segment ); - } else { - path.pop(); - } - break; - default: - path.push( segment ); - break; - } - } - - return path.join("/"); - }; - - //todo - do the same for the toCSS env - //tree.toCSSEnv = function (options) { - //}; - - var copyFromOriginal = function(original, destination, propertiesToCopy) { - if (!original) { return; } - - for(var i = 0; i < propertiesToCopy.length; i++) { - if (original.hasOwnProperty(propertiesToCopy[i])) { - destination[propertiesToCopy[i]] = original[propertiesToCopy[i]]; - } - } - }; - -})(require('./tree')); - -(function (tree) { - - var _visitArgs = { visitDeeper: true }, - _hasIndexed = false; - - function _noop(node) { - return node; - } - - function indexNodeTypes(parent, ticker) { - // add .typeIndex to tree node types for lookup table - var key, child; - for (key in parent) { - if (parent.hasOwnProperty(key)) { - child = parent[key]; - switch (typeof child) { - case "function": - // ignore bound functions directly on tree which do not have a prototype - // or aren't nodes - if (child.prototype && child.prototype.type) { - child.prototype.typeIndex = ticker++; - } - break; - case "object": - ticker = indexNodeTypes(child, ticker); - break; - } - } - } - return ticker; - } - - tree.visitor = function(implementation) { - this._implementation = implementation; - this._visitFnCache = []; - - if (!_hasIndexed) { - indexNodeTypes(tree, 1); - _hasIndexed = true; - } - }; - - tree.visitor.prototype = { - visit: function(node) { - if (!node) { - return node; - } - - var nodeTypeIndex = node.typeIndex; - if (!nodeTypeIndex) { - return node; - } - - var visitFnCache = this._visitFnCache, - impl = this._implementation, - aryIndx = nodeTypeIndex << 1, - outAryIndex = aryIndx | 1, - func = visitFnCache[aryIndx], - funcOut = visitFnCache[outAryIndex], - visitArgs = _visitArgs, - fnName; - - visitArgs.visitDeeper = true; - - if (!func) { - fnName = "visit" + node.type; - func = impl[fnName] || _noop; - funcOut = impl[fnName + "Out"] || _noop; - visitFnCache[aryIndx] = func; - visitFnCache[outAryIndex] = funcOut; - } - - if (func !== _noop) { - var newNode = func.call(impl, node, visitArgs); - if (impl.isReplacing) { - node = newNode; - } - } - - if (visitArgs.visitDeeper && node && node.accept) { - node.accept(this); - } - - if (funcOut != _noop) { - funcOut.call(impl, node); - } - - return node; - }, - visitArray: function(nodes, nonReplacing) { - if (!nodes) { - return nodes; - } - - var cnt = nodes.length, i; - - // Non-replacing - if (nonReplacing || !this._implementation.isReplacing) { - for (i = 0; i < cnt; i++) { - this.visit(nodes[i]); - } - return nodes; - } - - // Replacing - var out = []; - for (i = 0; i < cnt; i++) { - var evald = this.visit(nodes[i]); - if (!evald.splice) { - out.push(evald); - } else if (evald.length) { - this.flatten(evald, out); - } - } - return out; - }, - flatten: function(arr, out) { - if (!out) { - out = []; - } - - var cnt, i, item, - nestedCnt, j, nestedItem; - - for (i = 0, cnt = arr.length; i < cnt; i++) { - item = arr[i]; - if (!item.splice) { - out.push(item); - continue; - } - - for (j = 0, nestedCnt = item.length; j < nestedCnt; j++) { - nestedItem = item[j]; - if (!nestedItem.splice) { - out.push(nestedItem); - } else if (nestedItem.length) { - this.flatten(nestedItem, out); - } - } - } - - return out; - } - }; - -})(require('./tree')); -(function (tree) { - tree.importVisitor = function(importer, finish, evalEnv, onceFileDetectionMap, recursionDetector) { - this._visitor = new tree.visitor(this); - this._importer = importer; - this._finish = finish; - this.env = evalEnv || new tree.evalEnv(); - this.importCount = 0; - this.onceFileDetectionMap = onceFileDetectionMap || {}; - this.recursionDetector = {}; - if (recursionDetector) { - for(var fullFilename in recursionDetector) { - if (recursionDetector.hasOwnProperty(fullFilename)) { - this.recursionDetector[fullFilename] = true; - } - } - } - }; - - tree.importVisitor.prototype = { - isReplacing: true, - run: function (root) { - var error; - try { - // process the contents - this._visitor.visit(root); - } - catch(e) { - error = e; - } - - this.isFinished = true; - - if (this.importCount === 0) { - this._finish(error); - } - }, - visitImport: function (importNode, visitArgs) { - var importVisitor = this, - evaldImportNode, - inlineCSS = importNode.options.inline; - - if (!importNode.css || inlineCSS) { - - try { - evaldImportNode = importNode.evalForImport(this.env); - } catch(e){ - if (!e.filename) { e.index = importNode.index; e.filename = importNode.currentFileInfo.filename; } - // attempt to eval properly and treat as css - importNode.css = true; - // if that fails, this error will be thrown - importNode.error = e; - } - - if (evaldImportNode && (!evaldImportNode.css || inlineCSS)) { - importNode = evaldImportNode; - this.importCount++; - var env = new tree.evalEnv(this.env, this.env.frames.slice(0)); - - if (importNode.options.multiple) { - env.importMultiple = true; - } - - this._importer.push(importNode.getPath(), importNode.currentFileInfo, importNode.options, function (e, root, importedAtRoot, fullPath) { - if (e && !e.filename) { - e.index = importNode.index; e.filename = importNode.currentFileInfo.filename; - } - - var duplicateImport = importedAtRoot || fullPath in importVisitor.recursionDetector; - if (!env.importMultiple) { - if (duplicateImport) { - importNode.skip = true; - } else { - importNode.skip = function() { - if (fullPath in importVisitor.onceFileDetectionMap) { - return true; - } - importVisitor.onceFileDetectionMap[fullPath] = true; - return false; - }; - } - } - - var subFinish = function(e) { - importVisitor.importCount--; - - if (importVisitor.importCount === 0 && importVisitor.isFinished) { - importVisitor._finish(e); - } - }; - - if (root) { - importNode.root = root; - importNode.importedFilename = fullPath; - - if (!inlineCSS && (env.importMultiple || !duplicateImport)) { - importVisitor.recursionDetector[fullPath] = true; - new(tree.importVisitor)(importVisitor._importer, subFinish, env, importVisitor.onceFileDetectionMap, importVisitor.recursionDetector) - .run(root); - return; - } - } - - subFinish(); - }); - } - } - visitArgs.visitDeeper = false; - return importNode; - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - return ruleNode; - }, - visitDirective: function (directiveNode, visitArgs) { - this.env.frames.unshift(directiveNode); - return directiveNode; - }, - visitDirectiveOut: function (directiveNode) { - this.env.frames.shift(); - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - this.env.frames.unshift(mixinDefinitionNode); - return mixinDefinitionNode; - }, - visitMixinDefinitionOut: function (mixinDefinitionNode) { - this.env.frames.shift(); - }, - visitRuleset: function (rulesetNode, visitArgs) { - this.env.frames.unshift(rulesetNode); - return rulesetNode; - }, - visitRulesetOut: function (rulesetNode) { - this.env.frames.shift(); - }, - visitMedia: function (mediaNode, visitArgs) { - this.env.frames.unshift(mediaNode.rules[0]); - return mediaNode; - }, - visitMediaOut: function (mediaNode) { - this.env.frames.shift(); - } - }; - -})(require('./tree')); -(function (tree) { - tree.joinSelectorVisitor = function() { - this.contexts = [[]]; - this._visitor = new tree.visitor(this); - }; - - tree.joinSelectorVisitor.prototype = { - run: function (root) { - return this._visitor.visit(root); - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - - visitRuleset: function (rulesetNode, visitArgs) { - var context = this.contexts[this.contexts.length - 1], - paths = [], selectors; - - this.contexts.push(paths); - - if (! rulesetNode.root) { - selectors = rulesetNode.selectors; - if (selectors) { - selectors = selectors.filter(function(selector) { return selector.getIsOutput(); }); - rulesetNode.selectors = selectors.length ? selectors : (selectors = null); - if (selectors) { rulesetNode.joinSelectors(paths, context, selectors); } - } - if (!selectors) { rulesetNode.rules = null; } - rulesetNode.paths = paths; - } - }, - visitRulesetOut: function (rulesetNode) { - this.contexts.length = this.contexts.length - 1; - }, - visitMedia: function (mediaNode, visitArgs) { - var context = this.contexts[this.contexts.length - 1]; - mediaNode.rules[0].root = (context.length === 0 || context[0].multiMedia); - } - }; - -})(require('./tree')); -(function (tree) { - tree.toCSSVisitor = function(env) { - this._visitor = new tree.visitor(this); - this._env = env; - }; - - tree.toCSSVisitor.prototype = { - isReplacing: true, - run: function (root) { - return this._visitor.visit(root); - }, - - visitRule: function (ruleNode, visitArgs) { - if (ruleNode.variable) { - return []; - } - return ruleNode; - }, - - visitMixinDefinition: function (mixinNode, visitArgs) { - // mixin definitions do not get eval'd - this means they keep state - // so we have to clear that state here so it isn't used if toCSS is called twice - mixinNode.frames = []; - return []; - }, - - visitExtend: function (extendNode, visitArgs) { - return []; - }, - - visitComment: function (commentNode, visitArgs) { - if (commentNode.isSilent(this._env)) { - return []; - } - return commentNode; - }, - - visitMedia: function(mediaNode, visitArgs) { - mediaNode.accept(this._visitor); - visitArgs.visitDeeper = false; - - if (!mediaNode.rules.length) { - return []; - } - return mediaNode; - }, - - visitDirective: function(directiveNode, visitArgs) { - if (directiveNode.currentFileInfo.reference && !directiveNode.isReferenced) { - return []; - } - if (directiveNode.name === "@charset") { - // Only output the debug info together with subsequent @charset definitions - // a comment (or @media statement) before the actual @charset directive would - // be considered illegal css as it has to be on the first line - if (this.charset) { - if (directiveNode.debugInfo) { - var comment = new tree.Comment("/* " + directiveNode.toCSS(this._env).replace(/\n/g, "")+" */\n"); - comment.debugInfo = directiveNode.debugInfo; - return this._visitor.visit(comment); - } - return []; - } - this.charset = true; - } - if (directiveNode.rules && directiveNode.rules.rules) { - this._mergeRules(directiveNode.rules.rules); - } - return directiveNode; - }, - - checkPropertiesInRoot: function(rules) { - var ruleNode; - for(var i = 0; i < rules.length; i++) { - ruleNode = rules[i]; - if (ruleNode instanceof tree.Rule && !ruleNode.variable) { - throw { message: "properties must be inside selector blocks, they cannot be in the root.", - index: ruleNode.index, filename: ruleNode.currentFileInfo ? ruleNode.currentFileInfo.filename : null}; - } - } - }, - - visitRuleset: function (rulesetNode, visitArgs) { - var rule, rulesets = []; - if (rulesetNode.firstRoot) { - this.checkPropertiesInRoot(rulesetNode.rules); - } - if (! rulesetNode.root) { - if (rulesetNode.paths) { - rulesetNode.paths = rulesetNode.paths - .filter(function(p) { - var i; - if (p[0].elements[0].combinator.value === ' ') { - p[0].elements[0].combinator = new(tree.Combinator)(''); - } - for(i = 0; i < p.length; i++) { - if (p[i].getIsReferenced() && p[i].getIsOutput()) { - return true; - } - } - return false; - }); - } - - // Compile rules and rulesets - var nodeRules = rulesetNode.rules, nodeRuleCnt = nodeRules ? nodeRules.length : 0; - for (var i = 0; i < nodeRuleCnt; ) { - rule = nodeRules[i]; - if (rule && rule.rules) { - // visit because we are moving them out from being a child - rulesets.push(this._visitor.visit(rule)); - nodeRules.splice(i, 1); - nodeRuleCnt--; - continue; - } - i++; - } - // accept the visitor to remove rules and refactor itself - // then we can decide now whether we want it or not - if (nodeRuleCnt > 0) { - rulesetNode.accept(this._visitor); - } else { - rulesetNode.rules = null; - } - visitArgs.visitDeeper = false; - - nodeRules = rulesetNode.rules; - if (nodeRules) { - this._mergeRules(nodeRules); - nodeRules = rulesetNode.rules; - } - if (nodeRules) { - this._removeDuplicateRules(nodeRules); - nodeRules = rulesetNode.rules; - } - - // now decide whether we keep the ruleset - if (nodeRules && nodeRules.length > 0 && rulesetNode.paths.length > 0) { - rulesets.splice(0, 0, rulesetNode); - } - } else { - rulesetNode.accept(this._visitor); - visitArgs.visitDeeper = false; - if (rulesetNode.firstRoot || (rulesetNode.rules && rulesetNode.rules.length > 0)) { - rulesets.splice(0, 0, rulesetNode); - } - } - if (rulesets.length === 1) { - return rulesets[0]; - } - return rulesets; - }, - - _removeDuplicateRules: function(rules) { - if (!rules) { return; } - - // remove duplicates - var ruleCache = {}, - ruleList, rule, i; - - for(i = rules.length - 1; i >= 0 ; i--) { - rule = rules[i]; - if (rule instanceof tree.Rule) { - if (!ruleCache[rule.name]) { - ruleCache[rule.name] = rule; - } else { - ruleList = ruleCache[rule.name]; - if (ruleList instanceof tree.Rule) { - ruleList = ruleCache[rule.name] = [ruleCache[rule.name].toCSS(this._env)]; - } - var ruleCSS = rule.toCSS(this._env); - if (ruleList.indexOf(ruleCSS) !== -1) { - rules.splice(i, 1); - } else { - ruleList.push(ruleCSS); - } - } - } - } - }, - - _mergeRules: function (rules) { - if (!rules) { return; } - - var groups = {}, - parts, - rule, - key; - - for (var i = 0; i < rules.length; i++) { - rule = rules[i]; - - if ((rule instanceof tree.Rule) && rule.merge) { - key = [rule.name, - rule.important ? "!" : ""].join(","); - - if (!groups[key]) { - groups[key] = []; - } else { - rules.splice(i--, 1); - } - - groups[key].push(rule); - } - } - - Object.keys(groups).map(function (k) { - - function toExpression(values) { - return new (tree.Expression)(values.map(function (p) { - return p.value; - })); - } - - function toValue(values) { - return new (tree.Value)(values.map(function (p) { - return p; - })); - } - - parts = groups[k]; - - if (parts.length > 1) { - rule = parts[0]; - var spacedGroups = []; - var lastSpacedGroup = []; - parts.map(function (p) { - if (p.merge==="+") { - if (lastSpacedGroup.length > 0) { - spacedGroups.push(toExpression(lastSpacedGroup)); - } - lastSpacedGroup = []; - } - lastSpacedGroup.push(p); - }); - spacedGroups.push(toExpression(lastSpacedGroup)); - rule.value = toValue(spacedGroups); - } - }); - } - }; - -})(require('./tree')); -(function (tree) { - /*jshint loopfunc:true */ - - tree.extendFinderVisitor = function() { - this._visitor = new tree.visitor(this); - this.contexts = []; - this.allExtendsStack = [[]]; - }; - - tree.extendFinderVisitor.prototype = { - run: function (root) { - root = this._visitor.visit(root); - root.allExtends = this.allExtendsStack[0]; - return root; - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitRuleset: function (rulesetNode, visitArgs) { - if (rulesetNode.root) { - return; - } - - var i, j, extend, allSelectorsExtendList = [], extendList; - - // get &:extend(.a); rules which apply to all selectors in this ruleset - var rules = rulesetNode.rules, ruleCnt = rules ? rules.length : 0; - for(i = 0; i < ruleCnt; i++) { - if (rulesetNode.rules[i] instanceof tree.Extend) { - allSelectorsExtendList.push(rules[i]); - rulesetNode.extendOnEveryPath = true; - } - } - - // now find every selector and apply the extends that apply to all extends - // and the ones which apply to an individual extend - var paths = rulesetNode.paths; - for(i = 0; i < paths.length; i++) { - var selectorPath = paths[i], - selector = selectorPath[selectorPath.length - 1], - selExtendList = selector.extendList; - - extendList = selExtendList ? selExtendList.slice(0).concat(allSelectorsExtendList) - : allSelectorsExtendList; - - if (extendList) { - extendList = extendList.map(function(allSelectorsExtend) { - return allSelectorsExtend.clone(); - }); - } - - for(j = 0; j < extendList.length; j++) { - this.foundExtends = true; - extend = extendList[j]; - extend.findSelfSelectors(selectorPath); - extend.ruleset = rulesetNode; - if (j === 0) { extend.firstExtendOnThisSelectorPath = true; } - this.allExtendsStack[this.allExtendsStack.length-1].push(extend); - } - } - - this.contexts.push(rulesetNode.selectors); - }, - visitRulesetOut: function (rulesetNode) { - if (!rulesetNode.root) { - this.contexts.length = this.contexts.length - 1; - } - }, - visitMedia: function (mediaNode, visitArgs) { - mediaNode.allExtends = []; - this.allExtendsStack.push(mediaNode.allExtends); - }, - visitMediaOut: function (mediaNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - }, - visitDirective: function (directiveNode, visitArgs) { - directiveNode.allExtends = []; - this.allExtendsStack.push(directiveNode.allExtends); - }, - visitDirectiveOut: function (directiveNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - } - }; - - tree.processExtendsVisitor = function() { - this._visitor = new tree.visitor(this); - }; - - tree.processExtendsVisitor.prototype = { - run: function(root) { - var extendFinder = new tree.extendFinderVisitor(); - extendFinder.run(root); - if (!extendFinder.foundExtends) { return root; } - root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends)); - this.allExtendsStack = [root.allExtends]; - return this._visitor.visit(root); - }, - doExtendChaining: function (extendsList, extendsListTarget, iterationCount) { - // - // chaining is different from normal extension.. if we extend an extend then we are not just copying, altering and pasting - // the selector we would do normally, but we are also adding an extend with the same target selector - // this means this new extend can then go and alter other extends - // - // this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors - // this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already processed if - // we look at each selector at a time, as is done in visitRuleset - - var extendIndex, targetExtendIndex, matches, extendsToAdd = [], newSelector, extendVisitor = this, selectorPath, extend, targetExtend, newExtend; - - iterationCount = iterationCount || 0; - - //loop through comparing every extend with every target extend. - // a target extend is the one on the ruleset we are looking at copy/edit/pasting in place - // e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one - // and the second is the target. - // the seperation into two lists allows us to process a subset of chains with a bigger set, as is the - // case when processing media queries - for(extendIndex = 0; extendIndex < extendsList.length; extendIndex++){ - for(targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++){ - - extend = extendsList[extendIndex]; - targetExtend = extendsListTarget[targetExtendIndex]; - - // look for circular references - if( extend.parent_ids.indexOf( targetExtend.object_id ) >= 0 ){ continue; } - - // find a match in the target extends self selector (the bit before :extend) - selectorPath = [targetExtend.selfSelectors[0]]; - matches = extendVisitor.findMatch(extend, selectorPath); - - if (matches.length) { - - // we found a match, so for each self selector.. - extend.selfSelectors.forEach(function(selfSelector) { - - // process the extend as usual - newSelector = extendVisitor.extendSelector(matches, selectorPath, selfSelector); - - // but now we create a new extend from it - newExtend = new(tree.Extend)(targetExtend.selector, targetExtend.option, 0); - newExtend.selfSelectors = newSelector; - - // add the extend onto the list of extends for that selector - newSelector[newSelector.length-1].extendList = [newExtend]; - - // record that we need to add it. - extendsToAdd.push(newExtend); - newExtend.ruleset = targetExtend.ruleset; - - //remember its parents for circular references - newExtend.parent_ids = newExtend.parent_ids.concat(targetExtend.parent_ids, extend.parent_ids); - - // only process the selector once.. if we have :extend(.a,.b) then multiple - // extends will look at the same selector path, so when extending - // we know that any others will be duplicates in terms of what is added to the css - if (targetExtend.firstExtendOnThisSelectorPath) { - newExtend.firstExtendOnThisSelectorPath = true; - targetExtend.ruleset.paths.push(newSelector); - } - }); - } - } - } - - if (extendsToAdd.length) { - // try to detect circular references to stop a stack overflow. - // may no longer be needed. - this.extendChainCount++; - if (iterationCount > 100) { - var selectorOne = "{unable to calculate}"; - var selectorTwo = "{unable to calculate}"; - try - { - selectorOne = extendsToAdd[0].selfSelectors[0].toCSS(); - selectorTwo = extendsToAdd[0].selector.toCSS(); - } - catch(e) {} - throw {message: "extend circular reference detected. One of the circular extends is currently:"+selectorOne+":extend(" + selectorTwo+")"}; - } - - // now process the new extends on the existing rules so that we can handle a extending b extending c ectending d extending e... - return extendsToAdd.concat(extendVisitor.doExtendChaining(extendsToAdd, extendsListTarget, iterationCount+1)); - } else { - return extendsToAdd; - } - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitSelector: function (selectorNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitRuleset: function (rulesetNode, visitArgs) { - if (rulesetNode.root) { - return; - } - var matches, pathIndex, extendIndex, allExtends = this.allExtendsStack[this.allExtendsStack.length-1], selectorsToAdd = [], extendVisitor = this, selectorPath; - - // look at each selector path in the ruleset, find any extend matches and then copy, find and replace - - for(extendIndex = 0; extendIndex < allExtends.length; extendIndex++) { - for(pathIndex = 0; pathIndex < rulesetNode.paths.length; pathIndex++) { - selectorPath = rulesetNode.paths[pathIndex]; - - // extending extends happens initially, before the main pass - if (rulesetNode.extendOnEveryPath) { continue; } - var extendList = selectorPath[selectorPath.length-1].extendList; - if (extendList && extendList.length) { continue; } - - matches = this.findMatch(allExtends[extendIndex], selectorPath); - - if (matches.length) { - - allExtends[extendIndex].selfSelectors.forEach(function(selfSelector) { - selectorsToAdd.push(extendVisitor.extendSelector(matches, selectorPath, selfSelector)); - }); - } - } - } - rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd); - }, - findMatch: function (extend, haystackSelectorPath) { - // - // look through the haystack selector path to try and find the needle - extend.selector - // returns an array of selector matches that can then be replaced - // - var haystackSelectorIndex, hackstackSelector, hackstackElementIndex, haystackElement, - targetCombinator, i, - extendVisitor = this, - needleElements = extend.selector.elements, - potentialMatches = [], potentialMatch, matches = []; - - // loop through the haystack elements - for(haystackSelectorIndex = 0; haystackSelectorIndex < haystackSelectorPath.length; haystackSelectorIndex++) { - hackstackSelector = haystackSelectorPath[haystackSelectorIndex]; - - for(hackstackElementIndex = 0; hackstackElementIndex < hackstackSelector.elements.length; hackstackElementIndex++) { - - haystackElement = hackstackSelector.elements[hackstackElementIndex]; - - // if we allow elements before our match we can add a potential match every time. otherwise only at the first element. - if (extend.allowBefore || (haystackSelectorIndex === 0 && hackstackElementIndex === 0)) { - potentialMatches.push({pathIndex: haystackSelectorIndex, index: hackstackElementIndex, matched: 0, initialCombinator: haystackElement.combinator}); - } - - for(i = 0; i < potentialMatches.length; i++) { - potentialMatch = potentialMatches[i]; - - // selectors add " " onto the first element. When we use & it joins the selectors together, but if we don't - // then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to work out - // what the resulting combinator will be - targetCombinator = haystackElement.combinator.value; - if (targetCombinator === '' && hackstackElementIndex === 0) { - targetCombinator = ' '; - } - - // if we don't match, null our match to indicate failure - if (!extendVisitor.isElementValuesEqual(needleElements[potentialMatch.matched].value, haystackElement.value) || - (potentialMatch.matched > 0 && needleElements[potentialMatch.matched].combinator.value !== targetCombinator)) { - potentialMatch = null; - } else { - potentialMatch.matched++; - } - - // if we are still valid and have finished, test whether we have elements after and whether these are allowed - if (potentialMatch) { - potentialMatch.finished = potentialMatch.matched === needleElements.length; - if (potentialMatch.finished && - (!extend.allowAfter && (hackstackElementIndex+1 < hackstackSelector.elements.length || haystackSelectorIndex+1 < haystackSelectorPath.length))) { - potentialMatch = null; - } - } - // if null we remove, if not, we are still valid, so either push as a valid match or continue - if (potentialMatch) { - if (potentialMatch.finished) { - potentialMatch.length = needleElements.length; - potentialMatch.endPathIndex = haystackSelectorIndex; - potentialMatch.endPathElementIndex = hackstackElementIndex + 1; // index after end of match - potentialMatches.length = 0; // we don't allow matches to overlap, so start matching again - matches.push(potentialMatch); - } - } else { - potentialMatches.splice(i, 1); - i--; - } - } - } - } - return matches; - }, - isElementValuesEqual: function(elementValue1, elementValue2) { - if (typeof elementValue1 === "string" || typeof elementValue2 === "string") { - return elementValue1 === elementValue2; - } - if (elementValue1 instanceof tree.Attribute) { - if (elementValue1.op !== elementValue2.op || elementValue1.key !== elementValue2.key) { - return false; - } - if (!elementValue1.value || !elementValue2.value) { - if (elementValue1.value || elementValue2.value) { - return false; - } - return true; - } - elementValue1 = elementValue1.value.value || elementValue1.value; - elementValue2 = elementValue2.value.value || elementValue2.value; - return elementValue1 === elementValue2; - } - elementValue1 = elementValue1.value; - elementValue2 = elementValue2.value; - if (elementValue1 instanceof tree.Selector) { - if (!(elementValue2 instanceof tree.Selector) || elementValue1.elements.length !== elementValue2.elements.length) { - return false; - } - for(var i = 0; i currentSelectorPathIndex && currentSelectorPathElementIndex > 0) { - path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); - currentSelectorPathElementIndex = 0; - currentSelectorPathIndex++; - } - - newElements = selector.elements - .slice(currentSelectorPathElementIndex, match.index) - .concat([firstElement]) - .concat(replacementSelector.elements.slice(1)); - - if (currentSelectorPathIndex === match.pathIndex && matchIndex > 0) { - path[path.length - 1].elements = - path[path.length - 1].elements.concat(newElements); - } else { - path = path.concat(selectorPath.slice(currentSelectorPathIndex, match.pathIndex)); - - path.push(new tree.Selector( - newElements - )); - } - currentSelectorPathIndex = match.endPathIndex; - currentSelectorPathElementIndex = match.endPathElementIndex; - if (currentSelectorPathElementIndex >= selectorPath[currentSelectorPathIndex].elements.length) { - currentSelectorPathElementIndex = 0; - currentSelectorPathIndex++; - } - } - - if (currentSelectorPathIndex < selectorPath.length && currentSelectorPathElementIndex > 0) { - path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); - currentSelectorPathIndex++; - } - - path = path.concat(selectorPath.slice(currentSelectorPathIndex, selectorPath.length)); - - return path; - }, - visitRulesetOut: function (rulesetNode) { - }, - visitMedia: function (mediaNode, visitArgs) { - var newAllExtends = mediaNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]); - newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, mediaNode.allExtends)); - this.allExtendsStack.push(newAllExtends); - }, - visitMediaOut: function (mediaNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - }, - visitDirective: function (directiveNode, visitArgs) { - var newAllExtends = directiveNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]); - newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, directiveNode.allExtends)); - this.allExtendsStack.push(newAllExtends); - }, - visitDirectiveOut: function (directiveNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - } - }; - -})(require('./tree')); - -(function (tree) { - - tree.sourceMapOutput = function (options) { - this._css = []; - this._rootNode = options.rootNode; - this._writeSourceMap = options.writeSourceMap; - this._contentsMap = options.contentsMap; - this._contentsIgnoredCharsMap = options.contentsIgnoredCharsMap; - this._sourceMapFilename = options.sourceMapFilename; - this._outputFilename = options.outputFilename; - this._sourceMapURL = options.sourceMapURL; - if (options.sourceMapBasepath) { - this._sourceMapBasepath = options.sourceMapBasepath.replace(/\\/g, '/'); - } - this._sourceMapRootpath = options.sourceMapRootpath; - this._outputSourceFiles = options.outputSourceFiles; - this._sourceMapGeneratorConstructor = options.sourceMapGenerator || require("source-map").SourceMapGenerator; - - if (this._sourceMapRootpath && this._sourceMapRootpath.charAt(this._sourceMapRootpath.length-1) !== '/') { - this._sourceMapRootpath += '/'; - } - - this._lineNumber = 0; - this._column = 0; - }; - - tree.sourceMapOutput.prototype.normalizeFilename = function(filename) { - filename = filename.replace(/\\/g, '/'); - - if (this._sourceMapBasepath && filename.indexOf(this._sourceMapBasepath) === 0) { - filename = filename.substring(this._sourceMapBasepath.length); - if (filename.charAt(0) === '\\' || filename.charAt(0) === '/') { - filename = filename.substring(1); - } - } - return (this._sourceMapRootpath || "") + filename; - }; - - tree.sourceMapOutput.prototype.add = function(chunk, fileInfo, index, mapLines) { - - //ignore adding empty strings - if (!chunk) { - return; - } - - var lines, - sourceLines, - columns, - sourceColumns, - i; - - if (fileInfo) { - var inputSource = this._contentsMap[fileInfo.filename]; - - // remove vars/banner added to the top of the file - if (this._contentsIgnoredCharsMap[fileInfo.filename]) { - // adjust the index - index -= this._contentsIgnoredCharsMap[fileInfo.filename]; - if (index < 0) { index = 0; } - // adjust the source - inputSource = inputSource.slice(this._contentsIgnoredCharsMap[fileInfo.filename]); - } - inputSource = inputSource.substring(0, index); - sourceLines = inputSource.split("\n"); - sourceColumns = sourceLines[sourceLines.length-1]; - } - - lines = chunk.split("\n"); - columns = lines[lines.length-1]; - - if (fileInfo) { - if (!mapLines) { - this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + 1, column: this._column}, - original: { line: sourceLines.length, column: sourceColumns.length}, - source: this.normalizeFilename(fileInfo.filename)}); - } else { - for(i = 0; i < lines.length; i++) { - this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + i + 1, column: i === 0 ? this._column : 0}, - original: { line: sourceLines.length + i, column: i === 0 ? sourceColumns.length : 0}, - source: this.normalizeFilename(fileInfo.filename)}); - } - } - } - - if (lines.length === 1) { - this._column += columns.length; - } else { - this._lineNumber += lines.length - 1; - this._column = columns.length; - } - - this._css.push(chunk); - }; - - tree.sourceMapOutput.prototype.isEmpty = function() { - return this._css.length === 0; - }; - - tree.sourceMapOutput.prototype.toCSS = function(env) { - this._sourceMapGenerator = new this._sourceMapGeneratorConstructor({ file: this._outputFilename, sourceRoot: null }); - - if (this._outputSourceFiles) { - for(var filename in this._contentsMap) { - if (this._contentsMap.hasOwnProperty(filename)) - { - var source = this._contentsMap[filename]; - if (this._contentsIgnoredCharsMap[filename]) { - source = source.slice(this._contentsIgnoredCharsMap[filename]); - } - this._sourceMapGenerator.setSourceContent(this.normalizeFilename(filename), source); - } - } - } - - this._rootNode.genCSS(env, this); - - if (this._css.length > 0) { - var sourceMapURL, - sourceMapContent = JSON.stringify(this._sourceMapGenerator.toJSON()); - - if (this._sourceMapURL) { - sourceMapURL = this._sourceMapURL; - } else if (this._sourceMapFilename) { - sourceMapURL = this.normalizeFilename(this._sourceMapFilename); - } - - if (this._writeSourceMap) { - this._writeSourceMap(sourceMapContent); - } else { - sourceMapURL = "data:application/json;base64," + require('./encoder.js').encodeBase64(sourceMapContent); - } - - if (sourceMapURL) { - this._css.push("/*# sourceMappingURL=" + sourceMapURL + " */"); - } - } - - return this._css.join(''); - }; - -})(require('./tree')); - -// -// browser.js - client-side engine -// -/*global less, window, document, XMLHttpRequest, location */ - -var isFileProtocol = /^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol); - -less.env = less.env || (location.hostname == '127.0.0.1' || - location.hostname == '0.0.0.0' || - location.hostname == 'localhost' || - (location.port && - location.port.length > 0) || - isFileProtocol ? 'development' - : 'production'); - -var logLevel = { - debug: 3, - info: 2, - errors: 1, - none: 0 -}; - -// The amount of logging in the javascript console. -// 3 - Debug, information and errors -// 2 - Information and errors -// 1 - Errors -// 0 - None -// Defaults to 2 -less.logLevel = typeof(less.logLevel) != 'undefined' ? less.logLevel : (less.env === 'development' ? logLevel.debug : logLevel.errors); - -// Load styles asynchronously (default: false) -// -// This is set to `false` by default, so that the body -// doesn't start loading before the stylesheets are parsed. -// Setting this to `true` can result in flickering. -// -less.async = less.async || false; -less.fileAsync = less.fileAsync || false; - -// Interval between watch polls -less.poll = less.poll || (isFileProtocol ? 1000 : 1500); - -//Setup user functions -if (less.functions) { - for(var func in less.functions) { - if (less.functions.hasOwnProperty(func)) { - less.tree.functions[func] = less.functions[func]; - } - } -} - -var dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(location.hash); -if (dumpLineNumbers) { - less.dumpLineNumbers = dumpLineNumbers[1]; -} - -var typePattern = /^text\/(x-)?less$/; -var cache = null; -var fileCache = {}; - -function log(str, level) { - if (typeof(console) !== 'undefined' && less.logLevel >= level) { - console.log('less: ' + str); - } -} - -function extractId(href) { - return href.replace(/^[a-z-]+:\/+?[^\/]+/, '' ) // Remove protocol & domain - .replace(/^\//, '' ) // Remove root / - .replace(/\.[a-zA-Z]+$/, '' ) // Remove simple extension - .replace(/[^\.\w-]+/g, '-') // Replace illegal characters - .replace(/\./g, ':'); // Replace dots with colons(for valid id) -} - -function errorConsole(e, rootHref) { - var template = '{line} {content}'; - var filename = e.filename || rootHref; - var errors = []; - var content = (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') + - " in " + filename + " "; - - var errorline = function (e, i, classname) { - if (e.extract[i] !== undefined) { - errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1)) - .replace(/\{class\}/, classname) - .replace(/\{content\}/, e.extract[i])); - } - }; - - if (e.extract) { - errorline(e, 0, ''); - errorline(e, 1, 'line'); - errorline(e, 2, ''); - content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':\n' + - errors.join('\n'); - } else if (e.stack) { - content += e.stack; - } - log(content, logLevel.errors); -} - -function createCSS(styles, sheet, lastModified) { - // Strip the query-string - var href = sheet.href || ''; - - // If there is no title set, use the filename, minus the extension - var id = 'less:' + (sheet.title || extractId(href)); - - // If this has already been inserted into the DOM, we may need to replace it - var oldCss = document.getElementById(id); - var keepOldCss = false; - - // Create a new stylesheet node for insertion or (if necessary) replacement - var css = document.createElement('style'); - css.setAttribute('type', 'text/css'); - if (sheet.media) { - css.setAttribute('media', sheet.media); - } - css.id = id; - - if (!css.styleSheet) { - css.appendChild(document.createTextNode(styles)); - - // If new contents match contents of oldCss, don't replace oldCss - keepOldCss = (oldCss !== null && oldCss.childNodes.length > 0 && css.childNodes.length > 0 && - oldCss.firstChild.nodeValue === css.firstChild.nodeValue); - } - - var head = document.getElementsByTagName('head')[0]; - - // If there is no oldCss, just append; otherwise, only append if we need - // to replace oldCss with an updated stylesheet - if (oldCss === null || keepOldCss === false) { - var nextEl = sheet && sheet.nextSibling || null; - if (nextEl) { - nextEl.parentNode.insertBefore(css, nextEl); - } else { - head.appendChild(css); - } - } - if (oldCss && keepOldCss === false) { - oldCss.parentNode.removeChild(oldCss); - } - - // For IE. - // This needs to happen *after* the style element is added to the DOM, otherwise IE 7 and 8 may crash. - // See http://social.msdn.microsoft.com/Forums/en-US/7e081b65-878a-4c22-8e68-c10d39c2ed32/internet-explorer-crashes-appending-style-element-to-head - if (css.styleSheet) { - try { - css.styleSheet.cssText = styles; - } catch (e) { - throw new(Error)("Couldn't reassign styleSheet.cssText."); - } - } - - // Don't update the local store if the file wasn't modified - if (lastModified && cache) { - log('saving ' + href + ' to cache.', logLevel.info); - try { - cache.setItem(href, styles); - cache.setItem(href + ':timestamp', lastModified); - } catch(e) { - //TODO - could do with adding more robust error handling - log('failed to save', logLevel.errors); - } - } -} - -function postProcessCSS(styles) { - if (less.postProcessor && typeof less.postProcessor === 'function') { - styles = less.postProcessor.call(styles, styles) || styles; - } - return styles; -} - -function errorHTML(e, rootHref) { - var id = 'less-error-message:' + extractId(rootHref || ""); - var template = '
  • {content}
  • '; - var elem = document.createElement('div'), timer, content, errors = []; - var filename = e.filename || rootHref; - var filenameNoPath = filename.match(/([^\/]+(\?.*)?)$/)[1]; - - elem.id = id; - elem.className = "less-error-message"; - - content = '

    ' + (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') + - '

    ' + '

    in ' + filenameNoPath + " "; - - var errorline = function (e, i, classname) { - if (e.extract[i] !== undefined) { - errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1)) - .replace(/\{class\}/, classname) - .replace(/\{content\}/, e.extract[i])); - } - }; - - if (e.extract) { - errorline(e, 0, ''); - errorline(e, 1, 'line'); - errorline(e, 2, ''); - content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':

    ' + - '
      ' + errors.join('') + '
    '; - } else if (e.stack) { - content += '
    ' + e.stack.split('\n').slice(1).join('
    '); - } - elem.innerHTML = content; - - // CSS for error messages - createCSS([ - '.less-error-message ul, .less-error-message li {', - 'list-style-type: none;', - 'margin-right: 15px;', - 'padding: 4px 0;', - 'margin: 0;', - '}', - '.less-error-message label {', - 'font-size: 12px;', - 'margin-right: 15px;', - 'padding: 4px 0;', - 'color: #cc7777;', - '}', - '.less-error-message pre {', - 'color: #dd6666;', - 'padding: 4px 0;', - 'margin: 0;', - 'display: inline-block;', - '}', - '.less-error-message pre.line {', - 'color: #ff0000;', - '}', - '.less-error-message h3 {', - 'font-size: 20px;', - 'font-weight: bold;', - 'padding: 15px 0 5px 0;', - 'margin: 0;', - '}', - '.less-error-message a {', - 'color: #10a', - '}', - '.less-error-message .error {', - 'color: red;', - 'font-weight: bold;', - 'padding-bottom: 2px;', - 'border-bottom: 1px dashed red;', - '}' - ].join('\n'), { title: 'error-message' }); - - elem.style.cssText = [ - "font-family: Arial, sans-serif", - "border: 1px solid #e00", - "background-color: #eee", - "border-radius: 5px", - "-webkit-border-radius: 5px", - "-moz-border-radius: 5px", - "color: #e00", - "padding: 15px", - "margin-bottom: 15px" - ].join(';'); - - if (less.env == 'development') { - timer = setInterval(function () { - if (document.body) { - if (document.getElementById(id)) { - document.body.replaceChild(elem, document.getElementById(id)); - } else { - document.body.insertBefore(elem, document.body.firstChild); - } - clearInterval(timer); - } - }, 10); - } -} - -function error(e, rootHref) { - if (!less.errorReporting || less.errorReporting === "html") { - errorHTML(e, rootHref); - } else if (less.errorReporting === "console") { - errorConsole(e, rootHref); - } else if (typeof less.errorReporting === 'function') { - less.errorReporting("add", e, rootHref); - } -} - -function removeErrorHTML(path) { - var node = document.getElementById('less-error-message:' + extractId(path)); - if (node) { - node.parentNode.removeChild(node); - } -} - -function removeErrorConsole(path) { - //no action -} - -function removeError(path) { - if (!less.errorReporting || less.errorReporting === "html") { - removeErrorHTML(path); - } else if (less.errorReporting === "console") { - removeErrorConsole(path); - } else if (typeof less.errorReporting === 'function') { - less.errorReporting("remove", path); - } -} - -function loadStyles(modifyVars) { - var styles = document.getElementsByTagName('style'), - style; - for (var i = 0; i < styles.length; i++) { - style = styles[i]; - if (style.type.match(typePattern)) { - var env = new less.tree.parseEnv(less), - lessText = style.innerHTML || ''; - env.filename = document.location.href.replace(/#.*$/, ''); - - if (modifyVars || less.globalVars) { - env.useFileCache = true; - } - - /*jshint loopfunc:true */ - // use closure to store current value of i - var callback = (function(style) { - return function (e, cssAST) { - if (e) { - return error(e, "inline"); - } - var css = cssAST.toCSS(less); - style.type = 'text/css'; - if (style.styleSheet) { - style.styleSheet.cssText = css; - } else { - style.innerHTML = css; - } - }; - })(style); - new(less.Parser)(env).parse(lessText, callback, {globalVars: less.globalVars, modifyVars: modifyVars}); - } - } -} - -function extractUrlParts(url, baseUrl) { - // urlParts[1] = protocol&hostname || / - // urlParts[2] = / if path relative to host base - // urlParts[3] = directories - // urlParts[4] = filename - // urlParts[5] = parameters - - var urlPartsRegex = /^((?:[a-z-]+:)?\/+?(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i, - urlParts = url.match(urlPartsRegex), - returner = {}, directories = [], i, baseUrlParts; - - if (!urlParts) { - throw new Error("Could not parse sheet href - '"+url+"'"); - } - - // Stylesheets in IE don't always return the full path - if (!urlParts[1] || urlParts[2]) { - baseUrlParts = baseUrl.match(urlPartsRegex); - if (!baseUrlParts) { - throw new Error("Could not parse page url - '"+baseUrl+"'"); - } - urlParts[1] = urlParts[1] || baseUrlParts[1] || ""; - if (!urlParts[2]) { - urlParts[3] = baseUrlParts[3] + urlParts[3]; - } - } - - if (urlParts[3]) { - directories = urlParts[3].replace(/\\/g, "/").split("/"); - - // extract out . before .. so .. doesn't absorb a non-directory - for(i = 0; i < directories.length; i++) { - if (directories[i] === ".") { - directories.splice(i, 1); - i -= 1; - } - } - - for(i = 0; i < directories.length; i++) { - if (directories[i] === ".." && i > 0) { - directories.splice(i-1, 2); - i -= 2; - } - } - } - - returner.hostPart = urlParts[1]; - returner.directories = directories; - returner.path = urlParts[1] + directories.join("/"); - returner.fileUrl = returner.path + (urlParts[4] || ""); - returner.url = returner.fileUrl + (urlParts[5] || ""); - return returner; -} - -function pathDiff(url, baseUrl) { - // diff between two paths to create a relative path - - var urlParts = extractUrlParts(url), - baseUrlParts = extractUrlParts(baseUrl), - i, max, urlDirectories, baseUrlDirectories, diff = ""; - if (urlParts.hostPart !== baseUrlParts.hostPart) { - return ""; - } - max = Math.max(baseUrlParts.directories.length, urlParts.directories.length); - for(i = 0; i < max; i++) { - if (baseUrlParts.directories[i] !== urlParts.directories[i]) { break; } - } - baseUrlDirectories = baseUrlParts.directories.slice(i); - urlDirectories = urlParts.directories.slice(i); - for(i = 0; i < baseUrlDirectories.length-1; i++) { - diff += "../"; - } - for(i = 0; i < urlDirectories.length-1; i++) { - diff += urlDirectories[i] + "/"; - } - return diff; -} - -function getXMLHttpRequest() { - if (window.XMLHttpRequest && (window.location.protocol !== "file:" || !("ActiveXObject" in window))) { - return new XMLHttpRequest(); - } else { - try { - /*global ActiveXObject */ - return new ActiveXObject("Microsoft.XMLHTTP"); - } catch (e) { - log("browser doesn't support AJAX.", logLevel.errors); - return null; - } - } -} - -function doXHR(url, type, callback, errback) { - var xhr = getXMLHttpRequest(); - var async = isFileProtocol ? less.fileAsync : less.async; - - if (typeof(xhr.overrideMimeType) === 'function') { - xhr.overrideMimeType('text/css'); - } - log("XHR: Getting '" + url + "'", logLevel.debug); - xhr.open('GET', url, async); - xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5'); - xhr.send(null); - - function handleResponse(xhr, callback, errback) { - if (xhr.status >= 200 && xhr.status < 300) { - callback(xhr.responseText, - xhr.getResponseHeader("Last-Modified")); - } else if (typeof(errback) === 'function') { - errback(xhr.status, url); - } - } - - if (isFileProtocol && !less.fileAsync) { - if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) { - callback(xhr.responseText); - } else { - errback(xhr.status, url); - } - } else if (async) { - xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - handleResponse(xhr, callback, errback); - } - }; - } else { - handleResponse(xhr, callback, errback); - } -} - -function loadFile(originalHref, currentFileInfo, callback, env, modifyVars) { - - if (currentFileInfo && currentFileInfo.currentDirectory && !/^([A-Za-z-]+:)?\//.test(originalHref)) { - originalHref = currentFileInfo.currentDirectory + originalHref; - } - - // sheet may be set to the stylesheet for the initial load or a collection of properties including - // some env variables for imports - var hrefParts = extractUrlParts(originalHref, window.location.href); - var href = hrefParts.url; - var newFileInfo = { - currentDirectory: hrefParts.path, - filename: href - }; - - if (currentFileInfo) { - newFileInfo.entryPath = currentFileInfo.entryPath; - newFileInfo.rootpath = currentFileInfo.rootpath; - newFileInfo.rootFilename = currentFileInfo.rootFilename; - newFileInfo.relativeUrls = currentFileInfo.relativeUrls; - } else { - newFileInfo.entryPath = hrefParts.path; - newFileInfo.rootpath = less.rootpath || hrefParts.path; - newFileInfo.rootFilename = href; - newFileInfo.relativeUrls = env.relativeUrls; - } - - if (newFileInfo.relativeUrls) { - if (env.rootpath) { - newFileInfo.rootpath = extractUrlParts(env.rootpath + pathDiff(hrefParts.path, newFileInfo.entryPath)).path; - } else { - newFileInfo.rootpath = hrefParts.path; - } - } - - if (env.useFileCache && fileCache[href]) { - try { - var lessText = fileCache[href]; - callback(null, lessText, href, newFileInfo, { lastModified: new Date() }); - } catch (e) { - callback(e, null, href); - } - return; - } - - doXHR(href, env.mime, function (data, lastModified) { - // per file cache - fileCache[href] = data; - - // Use remote copy (re-parse) - try { - callback(null, data, href, newFileInfo, { lastModified: lastModified }); - } catch (e) { - callback(e, null, href); - } - }, function (status, url) { - callback({ type: 'File', message: "'" + url + "' wasn't found (" + status + ")" }, null, href); - }); -} - -function loadStyleSheet(sheet, callback, reload, remaining, modifyVars) { - - var env = new less.tree.parseEnv(less); - env.mime = sheet.type; - - if (modifyVars || less.globalVars) { - env.useFileCache = true; - } - - loadFile(sheet.href, null, function(e, data, path, newFileInfo, webInfo) { - - if (webInfo) { - webInfo.remaining = remaining; - - var css = cache && cache.getItem(path), - timestamp = cache && cache.getItem(path + ':timestamp'); - - if (!reload && timestamp && webInfo.lastModified && - (new(Date)(webInfo.lastModified).valueOf() === - new(Date)(timestamp).valueOf())) { - // Use local copy - createCSS(css, sheet); - webInfo.local = true; - callback(null, null, data, sheet, webInfo, path); - return; - } - } - - //TODO add tests around how this behaves when reloading - removeError(path); - - if (data) { - env.currentFileInfo = newFileInfo; - new(less.Parser)(env).parse(data, function (e, root) { - if (e) { return callback(e, null, null, sheet); } - try { - callback(e, root, data, sheet, webInfo, path); - } catch (e) { - callback(e, null, null, sheet); - } - }, {modifyVars: modifyVars, globalVars: less.globalVars}); - } else { - callback(e, null, null, sheet, webInfo, path); - } - }, env, modifyVars); -} - -function loadStyleSheets(callback, reload, modifyVars) { - for (var i = 0; i < less.sheets.length; i++) { - loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1), modifyVars); - } -} - -function initRunningMode(){ - if (less.env === 'development') { - less.optimization = 0; - less.watchTimer = setInterval(function () { - if (less.watchMode) { - loadStyleSheets(function (e, root, _, sheet, env) { - if (e) { - error(e, sheet.href); - } else if (root) { - var styles = root.toCSS(less); - styles = postProcessCSS(styles); - createCSS(styles, sheet, env.lastModified); - } - }); - } - }, less.poll); - } else { - less.optimization = 3; - } -} - - - -// -// Watch mode -// -less.watch = function () { - if (!less.watchMode ){ - less.env = 'development'; - initRunningMode(); - } - this.watchMode = true; - return true; -}; - -less.unwatch = function () {clearInterval(less.watchTimer); this.watchMode = false; return false; }; - -if (/!watch/.test(location.hash)) { - less.watch(); -} - -if (less.env != 'development') { - try { - cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage; - } catch (_) {} -} - -// -// Get all tags with the 'rel' attribute set to "stylesheet/less" -// -var links = document.getElementsByTagName('link'); - -less.sheets = []; - -for (var i = 0; i < links.length; i++) { - if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) && - (links[i].type.match(typePattern)))) { - less.sheets.push(links[i]); - } -} - -// -// With this function, it's possible to alter variables and re-render -// CSS without reloading less-files -// -less.modifyVars = function(record) { - less.refresh(false, record); -}; - -less.refresh = function (reload, modifyVars) { - var startTime, endTime; - startTime = endTime = new Date(); - - loadStyleSheets(function (e, root, _, sheet, env) { - if (e) { - return error(e, sheet.href); - } - if (env.local) { - log("loading " + sheet.href + " from cache.", logLevel.info); - } else { - //log("parsed " + sheet.href + " successfully.", logLevel.debug); - //var styles = root.toCSS(less); - //styles = postProcessCSS(styles); - //createCSS(styles, sheet, env.lastModified); - - - // less.php changes - var css = root.toCSS(less); - function totextarea(){ - var textarea = document.getElementById('lessjs_textarea'); - if( textarea ){ - textarea.value = css; - diffUsingJS(0); - }else{ - window.setTimeout(totextarea,300); - } - } - totextarea(); - - } - log("css for " + sheet.href + " generated in " + (new Date() - endTime) + 'ms', logLevel.info); - if (env.remaining === 0) { - log("less has finished. css generated in " + (new Date() - startTime) + 'ms', logLevel.info); - } - endTime = new Date(); - }, reload, modifyVars); - - loadStyles(modifyVars); -}; - -less.refreshStyles = loadStyles; - -less.Parser.fileLoader = loadFile; - -less.refresh(less.env === 'development'); - -// amd.js -// -// Define Less as an AMD module. -if (typeof define === "function" && define.amd) { - define(function () { return less; } ); -} - -})(window);

    in ' + filenameNoPath + " "; - - var errorline = function (e, i, classname) { - if (e.extract[i] !== undefined) { - errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1)) - .replace(/\{class\}/, classname) - .replace(/\{content\}/, e.extract[i])); - } - }; - - if (e.extract) { - errorline(e, 0, ''); - errorline(e, 1, 'line'); - errorline(e, 2, ''); - content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':