classiccms 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/classiccms/application.rb +2 -3
- data/lib/classiccms/cli.rb +6 -0
- data/lib/classiccms/scaffold/Gemfile +4 -0
- data/lib/classiccms/{mongoid.yml → scaffold/config/mongoid.yml} +3 -4
- data/lib/classiccms/scaffold/spec/models/article_spec.rb +8 -0
- data/lib/classiccms/scaffold/spec/spec_helper.rb +24 -0
- data/lib/classiccms/version.rb +1 -1
- data/spec/cli_spec.rb +8 -0
- data/vendor/bundle/gems/libv8-3.3.10.4-x86_64-darwin-11/lib/libv8/build/v8/libv8.a +0 -0
- data/vendor/bundle/gems/libv8-3.3.10.4-x86_64-darwin-11/lib/libv8/build/v8/libv8preparser.a +0 -0
- data/vendor/bundle/gems/libv8-3.3.10.4-x86_64-darwin-11/lib/libv8/v8/include/v8-debug.h +395 -0
- data/vendor/bundle/gems/libv8-3.3.10.4-x86_64-darwin-11/lib/libv8/v8/include/v8-preparser.h +117 -0
- data/vendor/bundle/gems/libv8-3.3.10.4-x86_64-darwin-11/lib/libv8/v8/include/v8-profiler.h +505 -0
- data/vendor/bundle/gems/libv8-3.3.10.4-x86_64-darwin-11/lib/libv8/v8/include/v8-testing.h +104 -0
- data/vendor/bundle/gems/libv8-3.3.10.4-x86_64-darwin-11/lib/libv8/v8/include/v8.h +4124 -0
- data/vendor/bundle/gems/libv8-3.3.10.4-x86_64-darwin-11/lib/libv8/v8/include/v8stdint.h +53 -0
- data/vendor/bundle/gems/libv8-3.3.10.4-x86_64-darwin-11/lib/libv8/version.rb +6 -0
- data/vendor/bundle/gems/libv8-3.3.10.4-x86_64-darwin-11/lib/libv8.rb +15 -0
- data/vendor/bundle/gems/sass-3.1.19/.yardopts +11 -0
- data/vendor/bundle/gems/sass-3.1.19/CONTRIBUTING +3 -0
- data/vendor/bundle/gems/sass-3.1.19/MIT-LICENSE +20 -0
- data/vendor/bundle/gems/sass-3.1.19/README.md +200 -0
- data/vendor/bundle/gems/sass-3.1.19/REVISION +1 -0
- data/vendor/bundle/gems/sass-3.1.19/Rakefile +339 -0
- data/vendor/bundle/gems/sass-3.1.19/VERSION +1 -0
- data/vendor/bundle/gems/sass-3.1.19/VERSION_NAME +1 -0
- data/vendor/bundle/gems/sass-3.1.19/bin/sass +8 -0
- data/vendor/bundle/gems/sass-3.1.19/bin/sass-convert +7 -0
- data/vendor/bundle/gems/sass-3.1.19/bin/scss +8 -0
- data/vendor/bundle/gems/sass-3.1.19/extra/update_watch.rb +13 -0
- data/vendor/bundle/gems/sass-3.1.19/init.rb +18 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/cache_stores/base.rb +86 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/cache_stores/chain.rb +33 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/cache_stores/filesystem.rb +61 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/cache_stores/memory.rb +47 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/cache_stores/null.rb +25 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/cache_stores.rb +15 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/callbacks.rb +66 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/css.rb +390 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/engine.rb +880 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/environment.rb +180 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/error.rb +201 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/exec.rb +682 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/importers/base.rb +139 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/importers/filesystem.rb +149 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/importers.rb +22 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/less.rb +382 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/logger/base.rb +32 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/logger/log_level.rb +49 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/logger.rb +15 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/plugin/compiler.rb +384 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/plugin/configuration.rb +123 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/plugin/generic.rb +15 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/plugin/merb.rb +48 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/plugin/rack.rb +60 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/plugin/rails.rb +47 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/plugin/staleness_checker.rb +183 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/plugin.rb +132 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/railtie.rb +9 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/repl.rb +57 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/root.rb +7 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/bool.rb +18 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/color.rb +475 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/css_lexer.rb +29 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/css_parser.rb +31 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/funcall.rb +175 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/functions.rb +1381 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/interpolation.rb +79 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/lexer.rb +337 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/list.rb +84 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/literal.rb +230 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/node.rb +99 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/number.rb +452 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/operation.rb +107 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/parser.rb +474 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/string.rb +51 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/string_interpolation.rb +103 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/unary_operation.rb +64 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/variable.rb +58 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/script.rb +39 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/scss/css_parser.rb +46 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/scss/parser.rb +1055 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/scss/rx.rb +137 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/scss/sass_parser.rb +11 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/scss/script_lexer.rb +15 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/scss/script_parser.rb +25 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/scss/static_parser.rb +40 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/scss.rb +17 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/selector/abstract_sequence.rb +71 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/selector/comma_sequence.rb +86 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/selector/sequence.rb +296 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/selector/simple.rb +119 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/selector/simple_sequence.rb +154 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/selector.rb +373 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/shared.rb +76 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/charset_node.rb +22 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/comment_node.rb +90 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/debug_node.rb +18 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/directive_node.rb +28 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/each_node.rb +24 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/extend_node.rb +29 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/for_node.rb +36 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/function_node.rb +27 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/if_node.rb +52 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/import_node.rb +68 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/media_node.rb +32 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/mixin_def_node.rb +27 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/mixin_node.rb +32 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/node.rb +188 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/prop_node.rb +148 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/return_node.rb +18 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/root_node.rb +28 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/rule_node.rb +127 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/variable_node.rb +30 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/visitors/base.rb +75 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/visitors/check_nesting.rb +127 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/visitors/convert.rb +262 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/visitors/cssize.rb +206 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/visitors/deep_copy.rb +87 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/visitors/extend.rb +42 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/visitors/perform.rb +357 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/visitors/set_options.rb +97 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/visitors/to_css.rb +219 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/warn_node.rb +18 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/while_node.rb +18 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/util/multibyte_string_scanner.rb +134 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/util/subset_map.rb +101 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/util.rb +800 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass/version.rb +112 -0
- data/vendor/bundle/gems/sass-3.1.19/lib/sass.rb +73 -0
- data/vendor/bundle/gems/sass-3.1.19/rails/init.rb +1 -0
- data/vendor/bundle/gems/sass-3.1.19/test/Gemfile +4 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/cache_test.rb +89 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/callbacks_test.rb +61 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/conversion_test.rb +1245 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/css2sass_test.rb +397 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/data/hsl-rgb.txt +319 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/engine_test.rb +2730 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/extend_test.rb +1663 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/fixtures/test_staleness_check_across_importers.css +1 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/fixtures/test_staleness_check_across_importers.scss +1 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/functions_test.rb +1047 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/importer_test.rb +192 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/less_conversion_test.rb +653 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/logger_test.rb +58 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/mock_importer.rb +49 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/more_results/more1.css +9 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/more_results/more1_with_line_comments.css +26 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/more_results/more_import.css +29 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/more_templates/_more_partial.sass +2 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/more_templates/more1.sass +23 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/more_templates/more_import.sass +11 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/plugin_test.rb +496 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/alt.css +4 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/basic.css +9 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/compact.css +5 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/complex.css +86 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/compressed.css +1 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/expanded.css +19 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/if.css +3 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/import.css +31 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/import_charset.css +5 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/import_charset_1_8.css +5 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/import_charset_ibm866.css +5 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/line_numbers.css +49 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/mixins.css +95 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/multiline.css +24 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/nested.css +22 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/options.css +1 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/parent_ref.css +13 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/script.css +16 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/scss_import.css +31 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/scss_importee.css +2 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/subdir/subdir.css +3 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/units.css +11 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/warn.css +0 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/results/warn_imported.css +0 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/script_conversion_test.rb +285 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/script_test.rb +519 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/scss/css_test.rb +975 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/scss/rx_test.rb +156 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/scss/scss_test.rb +1308 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/scss/test_helper.rb +37 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/_double_import_loop2.sass +1 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/_imported_charset_ibm866.sass +4 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/_imported_charset_utf8.sass +4 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/_partial.sass +2 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/alt.sass +16 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/basic.sass +23 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/bork1.sass +2 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/bork2.sass +2 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/bork3.sass +2 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/bork4.sass +2 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/bork5.sass +3 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/compact.sass +17 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/complex.sass +305 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/compressed.sass +15 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/double_import_loop1.sass +1 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/expanded.sass +17 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/if.sass +11 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/import.sass +12 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/import_charset.sass +9 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/import_charset_1_8.sass +6 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/import_charset_ibm866.sass +11 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/importee.less +2 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/importee.sass +19 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/line_numbers.sass +13 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/mixin_bork.sass +5 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/mixins.sass +76 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/multiline.sass +20 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/nested.sass +25 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/nested_bork1.sass +2 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/nested_bork2.sass +2 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/nested_bork3.sass +2 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/nested_bork4.sass +2 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/nested_bork5.sass +2 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/nested_import.sass +2 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/nested_mixin_bork.sass +6 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/options.sass +2 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/parent_ref.sass +25 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/script.sass +101 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/scss_import.scss +11 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/scss_importee.scss +1 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/single_import_loop.sass +1 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/subdir/subdir.sass +6 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/units.sass +11 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/warn.sass +3 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/warn_imported.sass +4 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/test_helper.rb +8 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/util/multibyte_string_scanner_test.rb +147 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/util/subset_map_test.rb +91 -0
- data/vendor/bundle/gems/sass-3.1.19/test/sass/util_test.rb +282 -0
- data/vendor/bundle/gems/sass-3.1.19/test/test_helper.rb +70 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/CHANGELOG.md +90 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/Gemfile +35 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/Guardfile +8 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/LICENSE +20 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/README.md +312 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/Rakefile +47 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/Vagrantfile +96 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/lib/listen/adapter.rb +167 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/lib/listen/adapters/darwin.rb +84 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/lib/listen/adapters/linux.rb +110 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/lib/listen/adapters/polling.rb +66 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/lib/listen/adapters/windows.rb +81 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/lib/listen/directory_record.rb +317 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/lib/listen/listener.rb +203 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/lib/listen/multi_listener.rb +121 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/lib/listen/turnstile.rb +28 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/lib/listen/version.rb +3 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/lib/listen.rb +38 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/listen.gemspec +26 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/listen/adapter_spec.rb +142 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/listen/adapters/darwin_spec.rb +31 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/listen/adapters/linux_spec.rb +41 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/listen/adapters/polling_spec.rb +68 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/listen/adapters/windows_spec.rb +24 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/listen/directory_record_spec.rb +1034 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/listen/listener_spec.rb +155 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/listen/multi_listener_spec.rb +156 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/listen/turnstile_spec.rb +56 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/listen_spec.rb +73 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/spec_helper.rb +16 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/support/adapter_helper.rb +716 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/support/directory_record_helper.rb +55 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/support/fixtures_helper.rb +29 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/support/listeners_helper.rb +144 -0
- data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/support/platform_helper.rb +11 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/.gitignore +13 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/.gitmodules +3 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/.travis.yml +9 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/.yardopts +1 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/Changelog.md +196 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/Gemfile +1 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/README.md +167 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/Rakefile +23 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/bin/therubyracer +11 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/Makefile +213 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/extconf.rb +26 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/gem_make.out +156 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/rr.cpp +189 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/rr.h +41 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8.cpp +48 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_array.cpp +48 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_array.h +8 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_callbacks.cpp +81 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_callbacks.h +8 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_context.cpp +92 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_context.h +6 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_date.cpp +34 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_date.h +6 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_debug.cpp +17 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_debug.h +6 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_exception.cpp +133 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_exception.h +11 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_external.cpp +70 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_external.h +8 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_function.cpp +69 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_function.h +11 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_handle.cpp +186 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_handle.h +48 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_locker.cpp +139 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_locker.h +6 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_message.cpp +67 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_message.h +10 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_object.cpp +122 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_object.h +10 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_script.cpp +36 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_script.h +8 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_string.cpp +52 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_string.h +9 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_template.cpp +344 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_template.h +8 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_try_catch.cpp +70 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_try_catch.h +5 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_v8.cpp +35 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_v8.h +6 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_value.cpp +175 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_value.h +10 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_weakref.cpp +61 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_weakref.h +29 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/access.rb +87 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/array.rb +17 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/c/locker.rb +18 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/cli.rb +133 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/context.rb +111 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/error.rb +130 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/function.rb +44 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/object.rb +69 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/portal/caller.rb +37 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/portal/constructor.rb +98 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/portal/function.rb +63 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/portal/interceptors.rb +152 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/portal/proxies.rb +151 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/portal/templates.rb +73 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/portal.rb +86 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/stack.rb +66 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/tap.rb +9 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/version.rb +3 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8.rb +23 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/spec/ext/array_spec.rb +15 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/spec/ext/cxt_spec.rb +57 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/spec/ext/ext_spec_helper.rb +27 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/spec/ext/func_spec.rb +64 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/spec/ext/object_spec.rb +10 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/spec/ext/string_spec.rb +11 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/spec/ext/try_catch_spec.rb +60 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/spec/redjs/.gitignore +1 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/spec/redjs/README.txt +8 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/spec/redjs/jsapi_spec.rb +922 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/spec/redjs/loadme.js +1 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/spec/redjs_helper.rb +3 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/spec/spec_helper.rb +9 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/spec/v8/error_spec.rb +131 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/spec/v8/portal/proxies_spec.rb +106 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/specmem/handle_memspec.rb +41 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/specmem/object_memspec.rb +14 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/specmem/proxies_memspec.rb +49 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/specmem/spec_helper.rb +24 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/specthread/spec_helper.rb +2 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/specthread/threading_spec.rb +13 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/thefrontside.png +0 -0
- data/vendor/bundle/gems/therubyracer-0.10.1/therubyracer.gemspec +29 -0
- data/vendor/bundle/specifications/libv8-3.3.10.4-x86_64-darwin-11.gemspec +33 -0
- data/vendor/bundle/specifications/sass-3.1.19.gemspec +35 -0
- metadata +365 -3
|
@@ -0,0 +1,1055 @@
|
|
|
1
|
+
require 'set'
|
|
2
|
+
|
|
3
|
+
module Sass
|
|
4
|
+
module SCSS
|
|
5
|
+
# The parser for SCSS.
|
|
6
|
+
# It parses a string of code into a tree of {Sass::Tree::Node}s.
|
|
7
|
+
class Parser
|
|
8
|
+
# @param str [String, StringScanner] The source document to parse.
|
|
9
|
+
# Note that `Parser` *won't* raise a nice error message if this isn't properly parsed;
|
|
10
|
+
# for that, you should use the higher-level {Sass::Engine} or {Sass::CSS}.
|
|
11
|
+
# @param filename [String] The name of the file being parsed. Used for warnings.
|
|
12
|
+
# @param line [Fixnum] The line on which the source string appeared,
|
|
13
|
+
# if it's part of another document.
|
|
14
|
+
def initialize(str, filename, line = 1)
|
|
15
|
+
@template = str
|
|
16
|
+
@filename = filename
|
|
17
|
+
@line = line
|
|
18
|
+
@strs = []
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Parses an SCSS document.
|
|
22
|
+
#
|
|
23
|
+
# @return [Sass::Tree::RootNode] The root node of the document tree
|
|
24
|
+
# @raise [Sass::SyntaxError] if there's a syntax error in the document
|
|
25
|
+
def parse
|
|
26
|
+
init_scanner!
|
|
27
|
+
root = stylesheet
|
|
28
|
+
expected("selector or at-rule") unless @scanner.eos?
|
|
29
|
+
root
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Parses an identifier with interpolation.
|
|
33
|
+
# Note that this won't assert that the identifier takes up the entire input string;
|
|
34
|
+
# it's meant to be used with `StringScanner`s as part of other parsers.
|
|
35
|
+
#
|
|
36
|
+
# @return [Array<String, Sass::Script::Node>, nil]
|
|
37
|
+
# The interpolated identifier, or nil if none could be parsed
|
|
38
|
+
def parse_interp_ident
|
|
39
|
+
init_scanner!
|
|
40
|
+
interp_ident
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
include Sass::SCSS::RX
|
|
46
|
+
|
|
47
|
+
def init_scanner!
|
|
48
|
+
@scanner =
|
|
49
|
+
if @template.is_a?(StringScanner)
|
|
50
|
+
@template
|
|
51
|
+
else
|
|
52
|
+
Sass::Util::MultibyteStringScanner.new(@template.gsub("\r", ""))
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def stylesheet
|
|
57
|
+
node = node(Sass::Tree::RootNode.new(@scanner.string))
|
|
58
|
+
block_contents(node, :stylesheet) {s(node)}
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def s(node)
|
|
62
|
+
while tok(S) || tok(CDC) || tok(CDO) || (c = tok(SINGLE_LINE_COMMENT)) || (c = tok(COMMENT))
|
|
63
|
+
next unless c
|
|
64
|
+
process_comment c, node
|
|
65
|
+
c = nil
|
|
66
|
+
end
|
|
67
|
+
true
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def ss
|
|
71
|
+
nil while tok(S) || tok(SINGLE_LINE_COMMENT) || tok(COMMENT)
|
|
72
|
+
true
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def ss_comments(node)
|
|
76
|
+
while tok(S) || (c = tok(SINGLE_LINE_COMMENT)) || (c = tok(COMMENT))
|
|
77
|
+
next unless c
|
|
78
|
+
process_comment c, node
|
|
79
|
+
c = nil
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
true
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def whitespace
|
|
86
|
+
return unless tok(S) || tok(SINGLE_LINE_COMMENT) || tok(COMMENT)
|
|
87
|
+
ss
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def process_comment(text, node)
|
|
91
|
+
silent = text =~ /^\/\//
|
|
92
|
+
line = @line - text.count("\n")
|
|
93
|
+
if loud = text =~ %r{^/[/*]!}
|
|
94
|
+
value = Sass::Engine.parse_interp(text, line, @scanner.pos - text.size, :filename => @filename)
|
|
95
|
+
value[0].slice!(2) # get rid of the "!"
|
|
96
|
+
else
|
|
97
|
+
value = [text]
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
if silent
|
|
101
|
+
value = Sass::Util.with_extracted_values(value) do |str|
|
|
102
|
+
str.sub(/^\s*\/\//, '/*').gsub(/^\s*\/\//, ' *') + ' */'
|
|
103
|
+
end
|
|
104
|
+
else
|
|
105
|
+
value.unshift(@scanner.
|
|
106
|
+
string[0...@scanner.pos].
|
|
107
|
+
reverse[/.*?\*\/(.*?)($|\Z)/, 1].
|
|
108
|
+
reverse.gsub(/[^\s]/, ' '))
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
comment = Sass::Tree::CommentNode.new(value, silent, loud)
|
|
112
|
+
comment.line = line
|
|
113
|
+
node << comment
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
DIRECTIVES = Set[:mixin, :include, :function, :return, :debug, :warn, :for,
|
|
117
|
+
:each, :while, :if, :else, :extend, :import, :media, :charset, :_moz_document]
|
|
118
|
+
|
|
119
|
+
PREFIXED_DIRECTIVES = Set[:supports]
|
|
120
|
+
|
|
121
|
+
def directive
|
|
122
|
+
return unless tok(/@/)
|
|
123
|
+
name = tok!(IDENT)
|
|
124
|
+
ss
|
|
125
|
+
|
|
126
|
+
if dir = special_directive(name)
|
|
127
|
+
return dir
|
|
128
|
+
elsif dir = prefixed_directive(name)
|
|
129
|
+
return dir
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Most at-rules take expressions (e.g. @import),
|
|
133
|
+
# but some (e.g. @page) take selector-like arguments
|
|
134
|
+
val = str {break unless expr}
|
|
135
|
+
val ||= CssParser.new(@scanner, @line).parse_selector_string
|
|
136
|
+
directive_body("@#{name} #{val}")
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def directive_body(value)
|
|
140
|
+
node = node(Sass::Tree::DirectiveNode.new(value.strip))
|
|
141
|
+
|
|
142
|
+
if tok(/\{/)
|
|
143
|
+
node.has_children = true
|
|
144
|
+
block_contents(node, :directive)
|
|
145
|
+
tok!(/\}/)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
node
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def special_directive(name)
|
|
152
|
+
sym = name.gsub('-', '_').to_sym
|
|
153
|
+
DIRECTIVES.include?(sym) && send("#{sym}_directive")
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def prefixed_directive(name)
|
|
157
|
+
sym = name.gsub(/^-[a-z0-9]+-/i, '').gsub('-', '_').to_sym
|
|
158
|
+
PREFIXED_DIRECTIVES.include?(sym) && send("#{sym}_directive", name)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def mixin_directive
|
|
162
|
+
name = tok! IDENT
|
|
163
|
+
args = sass_script(:parse_mixin_definition_arglist)
|
|
164
|
+
ss
|
|
165
|
+
block(node(Sass::Tree::MixinDefNode.new(name, args)), :directive)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def include_directive
|
|
169
|
+
name = tok! IDENT
|
|
170
|
+
args, keywords = sass_script(:parse_mixin_include_arglist)
|
|
171
|
+
ss
|
|
172
|
+
node(Sass::Tree::MixinNode.new(name, args, keywords))
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def function_directive
|
|
176
|
+
name = tok! IDENT
|
|
177
|
+
args = sass_script(:parse_function_definition_arglist)
|
|
178
|
+
ss
|
|
179
|
+
block(node(Sass::Tree::FunctionNode.new(name, args)), :function)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def return_directive
|
|
183
|
+
node(Sass::Tree::ReturnNode.new(sass_script(:parse)))
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def debug_directive
|
|
187
|
+
node(Sass::Tree::DebugNode.new(sass_script(:parse)))
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def warn_directive
|
|
191
|
+
node(Sass::Tree::WarnNode.new(sass_script(:parse)))
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def for_directive
|
|
195
|
+
tok!(/\$/)
|
|
196
|
+
var = tok! IDENT
|
|
197
|
+
ss
|
|
198
|
+
|
|
199
|
+
tok!(/from/)
|
|
200
|
+
from = sass_script(:parse_until, Set["to", "through"])
|
|
201
|
+
ss
|
|
202
|
+
|
|
203
|
+
@expected = '"to" or "through"'
|
|
204
|
+
exclusive = (tok(/to/) || tok!(/through/)) == 'to'
|
|
205
|
+
to = sass_script(:parse)
|
|
206
|
+
ss
|
|
207
|
+
|
|
208
|
+
block(node(Sass::Tree::ForNode.new(var, from, to, exclusive)), :directive)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def each_directive
|
|
212
|
+
tok!(/\$/)
|
|
213
|
+
var = tok! IDENT
|
|
214
|
+
ss
|
|
215
|
+
|
|
216
|
+
tok!(/in/)
|
|
217
|
+
list = sass_script(:parse)
|
|
218
|
+
ss
|
|
219
|
+
|
|
220
|
+
block(node(Sass::Tree::EachNode.new(var, list)), :directive)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def while_directive
|
|
224
|
+
expr = sass_script(:parse)
|
|
225
|
+
ss
|
|
226
|
+
block(node(Sass::Tree::WhileNode.new(expr)), :directive)
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def if_directive
|
|
230
|
+
expr = sass_script(:parse)
|
|
231
|
+
ss
|
|
232
|
+
node = block(node(Sass::Tree::IfNode.new(expr)), :directive)
|
|
233
|
+
pos = @scanner.pos
|
|
234
|
+
line = @line
|
|
235
|
+
ss
|
|
236
|
+
|
|
237
|
+
else_block(node) ||
|
|
238
|
+
begin
|
|
239
|
+
# Backtrack in case there are any comments we want to parse
|
|
240
|
+
@scanner.pos = pos
|
|
241
|
+
@line = line
|
|
242
|
+
node
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def else_block(node)
|
|
247
|
+
return unless tok(/@else/)
|
|
248
|
+
ss
|
|
249
|
+
else_node = block(
|
|
250
|
+
Sass::Tree::IfNode.new((sass_script(:parse) if tok(/if/))),
|
|
251
|
+
:directive)
|
|
252
|
+
node.add_else(else_node)
|
|
253
|
+
pos = @scanner.pos
|
|
254
|
+
line = @line
|
|
255
|
+
ss
|
|
256
|
+
|
|
257
|
+
else_block(node) ||
|
|
258
|
+
begin
|
|
259
|
+
# Backtrack in case there are any comments we want to parse
|
|
260
|
+
@scanner.pos = pos
|
|
261
|
+
@line = line
|
|
262
|
+
node
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def else_directive
|
|
267
|
+
err("Invalid CSS: @else must come after @if")
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def extend_directive
|
|
271
|
+
node(Sass::Tree::ExtendNode.new(expr!(:selector_sequence)))
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
def import_directive
|
|
275
|
+
values = []
|
|
276
|
+
|
|
277
|
+
loop do
|
|
278
|
+
values << expr!(:import_arg)
|
|
279
|
+
break if use_css_import? || !tok(/,\s*/)
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
return values
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def import_arg
|
|
286
|
+
return unless arg = tok(STRING) || (uri = tok!(URI))
|
|
287
|
+
path = @scanner[1] || @scanner[2] || @scanner[3]
|
|
288
|
+
ss
|
|
289
|
+
|
|
290
|
+
media = str {media_query_list}.strip
|
|
291
|
+
|
|
292
|
+
if uri || path =~ /^http:\/\// || !media.strip.empty? || use_css_import?
|
|
293
|
+
return node(Sass::Tree::DirectiveNode.new("@import #{arg} #{media}".strip))
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
node(Sass::Tree::ImportNode.new(path.strip))
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
def use_css_import?; false; end
|
|
300
|
+
|
|
301
|
+
def media_directive
|
|
302
|
+
block(node(Sass::Tree::MediaNode.new(media_query_list)), :directive)
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
# http://www.w3.org/TR/css3-mediaqueries/#syntax
|
|
306
|
+
def media_query_list
|
|
307
|
+
has_q = false
|
|
308
|
+
q = str {has_q = media_query}
|
|
309
|
+
|
|
310
|
+
return unless has_q
|
|
311
|
+
queries = [q.strip]
|
|
312
|
+
|
|
313
|
+
ss
|
|
314
|
+
while tok(/,/)
|
|
315
|
+
ss; queries << str {expr!(:media_query)}.strip; ss
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
queries
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
def media_query
|
|
322
|
+
if tok(/only|not/i)
|
|
323
|
+
ss
|
|
324
|
+
@expected = "media type (e.g. print, screen)"
|
|
325
|
+
tok!(IDENT)
|
|
326
|
+
ss
|
|
327
|
+
elsif !tok(IDENT) && !media_expr
|
|
328
|
+
return
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
ss
|
|
332
|
+
while tok(/and/i)
|
|
333
|
+
ss; expr!(:media_expr); ss
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
true
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
def media_expr
|
|
340
|
+
return unless tok(/\(/)
|
|
341
|
+
ss
|
|
342
|
+
@expected = "media feature (e.g. min-device-width, color)"
|
|
343
|
+
tok!(IDENT)
|
|
344
|
+
ss
|
|
345
|
+
|
|
346
|
+
if tok(/:/)
|
|
347
|
+
ss; expr!(:expr)
|
|
348
|
+
end
|
|
349
|
+
tok!(/\)/)
|
|
350
|
+
ss
|
|
351
|
+
|
|
352
|
+
true
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
def charset_directive
|
|
356
|
+
tok! STRING
|
|
357
|
+
name = @scanner[1] || @scanner[2]
|
|
358
|
+
ss
|
|
359
|
+
node(Sass::Tree::CharsetNode.new(name))
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
# The document directive is specified in
|
|
363
|
+
# http://www.w3.org/TR/css3-conditional/, but Gecko allows the
|
|
364
|
+
# `url-prefix` and `domain` functions to omit quotation marks, contrary to
|
|
365
|
+
# the standard.
|
|
366
|
+
#
|
|
367
|
+
# We could parse all document directives according to Mozilla's syntax,
|
|
368
|
+
# but if someone's using e.g. @-webkit-document we don't want them to
|
|
369
|
+
# think WebKit works sans quotes.
|
|
370
|
+
def _moz_document_directive
|
|
371
|
+
value = str do
|
|
372
|
+
begin
|
|
373
|
+
ss
|
|
374
|
+
expr!(:moz_document_function)
|
|
375
|
+
end while tok(/,/)
|
|
376
|
+
end
|
|
377
|
+
directive_body("@-moz-document #{value}")
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
def moz_document_function
|
|
381
|
+
return unless tok(URI) || tok(URL_PREFIX) || tok(DOMAIN) || function
|
|
382
|
+
ss
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
# http://www.w3.org/TR/css3-conditional/
|
|
386
|
+
def supports_directive(name)
|
|
387
|
+
value = str {expr!(:supports_condition)}
|
|
388
|
+
directive_body("@#{name} #{value}")
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
def supports_condition
|
|
392
|
+
supports_negation || supports_operator || supports_declaration_condition
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
def supports_negation
|
|
396
|
+
return unless tok(/not/i)
|
|
397
|
+
ss
|
|
398
|
+
expr!(:supports_condition_in_parens)
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
def supports_operator
|
|
402
|
+
return unless supports_condition_in_parens
|
|
403
|
+
tok!(/and|or/i)
|
|
404
|
+
begin
|
|
405
|
+
ss
|
|
406
|
+
expr!(:supports_condition_in_parens)
|
|
407
|
+
end while tok(/and|or/i)
|
|
408
|
+
true
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
def supports_condition_in_parens
|
|
412
|
+
return unless tok(/\(/); ss
|
|
413
|
+
if supports_condition
|
|
414
|
+
tok!(/\)/); ss
|
|
415
|
+
else
|
|
416
|
+
supports_declaration_body
|
|
417
|
+
end
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
def supports_declaration_condition
|
|
421
|
+
return unless tok(/\(/); ss
|
|
422
|
+
supports_declaration_body
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
def supports_declaration_body
|
|
426
|
+
tok!(IDENT); ss
|
|
427
|
+
tok!(/:/); ss
|
|
428
|
+
expr!(:expr); ss
|
|
429
|
+
tok!(/\)/); ss
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
def variable
|
|
433
|
+
return unless tok(/\$/)
|
|
434
|
+
name = tok!(IDENT)
|
|
435
|
+
ss; tok!(/:/); ss
|
|
436
|
+
|
|
437
|
+
expr = sass_script(:parse)
|
|
438
|
+
guarded = tok(DEFAULT)
|
|
439
|
+
node(Sass::Tree::VariableNode.new(name, expr, guarded))
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
def operator
|
|
443
|
+
# Many of these operators (all except / and ,)
|
|
444
|
+
# are disallowed by the CSS spec,
|
|
445
|
+
# but they're included here for compatibility
|
|
446
|
+
# with some proprietary MS properties
|
|
447
|
+
str {ss if tok(/[\/,:.=]/)}
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
def unary_operator
|
|
451
|
+
tok(/[+-]/)
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
def ruleset
|
|
455
|
+
return unless rules = selector_sequence
|
|
456
|
+
block(node(Sass::Tree::RuleNode.new(rules.flatten.compact)), :ruleset)
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
def block(node, context)
|
|
460
|
+
node.has_children = true
|
|
461
|
+
tok!(/\{/)
|
|
462
|
+
block_contents(node, context)
|
|
463
|
+
tok!(/\}/)
|
|
464
|
+
node
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
# A block may contain declarations and/or rulesets
|
|
468
|
+
def block_contents(node, context)
|
|
469
|
+
block_given? ? yield : ss_comments(node)
|
|
470
|
+
node << (child = block_child(context))
|
|
471
|
+
while tok(/;/) || has_children?(child)
|
|
472
|
+
block_given? ? yield : ss_comments(node)
|
|
473
|
+
node << (child = block_child(context))
|
|
474
|
+
end
|
|
475
|
+
node
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
def block_child(context)
|
|
479
|
+
return variable || directive if context == :function
|
|
480
|
+
return variable || directive || ruleset if context == :stylesheet
|
|
481
|
+
variable || directive || declaration_or_ruleset
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
def has_children?(child_or_array)
|
|
485
|
+
return false unless child_or_array
|
|
486
|
+
return child_or_array.last.has_children if child_or_array.is_a?(Array)
|
|
487
|
+
return child_or_array.has_children
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
# This is a nasty hack, and the only place in the parser
|
|
491
|
+
# that requires backtracking.
|
|
492
|
+
# The reason is that we can't figure out if certain strings
|
|
493
|
+
# are declarations or rulesets with fixed finite lookahead.
|
|
494
|
+
# For example, "foo:bar baz baz baz..." could be either a property
|
|
495
|
+
# or a selector.
|
|
496
|
+
#
|
|
497
|
+
# To handle this, we simply check if it works as a property
|
|
498
|
+
# (which is the most common case)
|
|
499
|
+
# and, if it doesn't, try it as a ruleset.
|
|
500
|
+
#
|
|
501
|
+
# We could eke some more efficiency out of this
|
|
502
|
+
# by handling some easy cases (first token isn't an identifier,
|
|
503
|
+
# no colon after the identifier, whitespace after the colon),
|
|
504
|
+
# but I'm not sure the gains would be worth the added complexity.
|
|
505
|
+
def declaration_or_ruleset
|
|
506
|
+
old_use_property_exception, @use_property_exception =
|
|
507
|
+
@use_property_exception, false
|
|
508
|
+
decl_err = catch_error do
|
|
509
|
+
decl = declaration
|
|
510
|
+
unless decl && decl.has_children
|
|
511
|
+
# We want an exception if it's not there,
|
|
512
|
+
# but we don't want to consume if it is
|
|
513
|
+
tok!(/[;}]/) unless tok?(/[;}]/)
|
|
514
|
+
end
|
|
515
|
+
return decl
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
ruleset_err = catch_error {return ruleset}
|
|
519
|
+
rethrow(@use_property_exception ? decl_err : ruleset_err)
|
|
520
|
+
ensure
|
|
521
|
+
@use_property_exception = old_use_property_exception
|
|
522
|
+
end
|
|
523
|
+
|
|
524
|
+
def selector_sequence
|
|
525
|
+
if sel = tok(STATIC_SELECTOR, true)
|
|
526
|
+
return [sel]
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
rules = []
|
|
530
|
+
return unless v = selector
|
|
531
|
+
rules.concat v
|
|
532
|
+
|
|
533
|
+
ws = ''
|
|
534
|
+
while tok(/,/)
|
|
535
|
+
ws << str {ss}
|
|
536
|
+
if v = selector
|
|
537
|
+
rules << ',' << ws
|
|
538
|
+
rules.concat v
|
|
539
|
+
ws = ''
|
|
540
|
+
end
|
|
541
|
+
end
|
|
542
|
+
rules
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
def selector
|
|
546
|
+
return unless sel = _selector
|
|
547
|
+
sel.to_a
|
|
548
|
+
end
|
|
549
|
+
|
|
550
|
+
def selector_comma_sequence
|
|
551
|
+
return unless sel = _selector
|
|
552
|
+
selectors = [sel]
|
|
553
|
+
ws = ''
|
|
554
|
+
while tok(/,/)
|
|
555
|
+
ws << str{ss}
|
|
556
|
+
if sel = _selector
|
|
557
|
+
selectors << sel
|
|
558
|
+
selectors[-1] = Selector::Sequence.new(["\n"] + selectors.last.members) if ws.include?("\n")
|
|
559
|
+
ws = ''
|
|
560
|
+
end
|
|
561
|
+
end
|
|
562
|
+
Selector::CommaSequence.new(selectors)
|
|
563
|
+
end
|
|
564
|
+
|
|
565
|
+
def _selector
|
|
566
|
+
# The combinator here allows the "> E" hack
|
|
567
|
+
return unless val = combinator || simple_selector_sequence
|
|
568
|
+
nl = str{ss}.include?("\n")
|
|
569
|
+
res = []
|
|
570
|
+
res << val
|
|
571
|
+
res << "\n" if nl
|
|
572
|
+
|
|
573
|
+
while val = combinator || simple_selector_sequence
|
|
574
|
+
res << val
|
|
575
|
+
res << "\n" if str{ss}.include?("\n")
|
|
576
|
+
end
|
|
577
|
+
Selector::Sequence.new(res.compact)
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
def combinator
|
|
581
|
+
tok(PLUS) || tok(GREATER) || tok(TILDE)
|
|
582
|
+
end
|
|
583
|
+
|
|
584
|
+
def simple_selector_sequence
|
|
585
|
+
# This allows for stuff like http://www.w3.org/TR/css3-animations/#keyframes-
|
|
586
|
+
return expr unless e = element_name || id_selector || class_selector ||
|
|
587
|
+
attrib || negation || pseudo || parent_selector || interpolation_selector
|
|
588
|
+
res = [e]
|
|
589
|
+
|
|
590
|
+
# The tok(/\*/) allows the "E*" hack
|
|
591
|
+
while v = id_selector || class_selector || attrib || negation || pseudo ||
|
|
592
|
+
interpolation_selector || (tok(/\*/) && Selector::Universal.new(nil))
|
|
593
|
+
res << v
|
|
594
|
+
end
|
|
595
|
+
|
|
596
|
+
pos = @scanner.pos
|
|
597
|
+
line = @line
|
|
598
|
+
if sel = str? {simple_selector_sequence}
|
|
599
|
+
@scanner.pos = pos
|
|
600
|
+
@line = line
|
|
601
|
+
|
|
602
|
+
if sel =~ /^&/
|
|
603
|
+
begin
|
|
604
|
+
throw_error {expected('"{"')}
|
|
605
|
+
rescue Sass::SyntaxError => e
|
|
606
|
+
e.message << "\n\n\"#{sel}\" may only be used at the beginning of a selector."
|
|
607
|
+
raise e
|
|
608
|
+
end
|
|
609
|
+
else
|
|
610
|
+
Sass::Util.sass_warn(<<MESSAGE)
|
|
611
|
+
DEPRECATION WARNING:
|
|
612
|
+
On line #{@line}#{" of \"#{@filename}\"" if @filename}, after "#{self.class.prior_snippet(@scanner)}"
|
|
613
|
+
Starting in Sass 3.2, "#{sel}" may only be used at the beginning of a selector.
|
|
614
|
+
MESSAGE
|
|
615
|
+
end
|
|
616
|
+
end
|
|
617
|
+
|
|
618
|
+
Selector::SimpleSequence.new(res)
|
|
619
|
+
end
|
|
620
|
+
|
|
621
|
+
def parent_selector
|
|
622
|
+
return unless tok(/&/)
|
|
623
|
+
Selector::Parent.new
|
|
624
|
+
end
|
|
625
|
+
|
|
626
|
+
def class_selector
|
|
627
|
+
return unless tok(/\./)
|
|
628
|
+
@expected = "class name"
|
|
629
|
+
Selector::Class.new(merge(expr!(:interp_ident)))
|
|
630
|
+
end
|
|
631
|
+
|
|
632
|
+
def id_selector
|
|
633
|
+
return unless tok(/#(?!\{)/)
|
|
634
|
+
@expected = "id name"
|
|
635
|
+
Selector::Id.new(merge(expr!(:interp_name)))
|
|
636
|
+
end
|
|
637
|
+
|
|
638
|
+
def element_name
|
|
639
|
+
return unless name = interp_ident || tok(/\*/) || (tok?(/\|/) && "")
|
|
640
|
+
if tok(/\|/)
|
|
641
|
+
@expected = "element name or *"
|
|
642
|
+
ns = name
|
|
643
|
+
name = interp_ident || tok!(/\*/)
|
|
644
|
+
end
|
|
645
|
+
|
|
646
|
+
if name == '*'
|
|
647
|
+
Selector::Universal.new(merge(ns))
|
|
648
|
+
else
|
|
649
|
+
Selector::Element.new(merge(name), merge(ns))
|
|
650
|
+
end
|
|
651
|
+
end
|
|
652
|
+
|
|
653
|
+
def interpolation_selector
|
|
654
|
+
return unless script = interpolation
|
|
655
|
+
Selector::Interpolation.new(script)
|
|
656
|
+
end
|
|
657
|
+
|
|
658
|
+
def attrib
|
|
659
|
+
return unless tok(/\[/)
|
|
660
|
+
ss
|
|
661
|
+
ns, name = attrib_name!
|
|
662
|
+
ss
|
|
663
|
+
|
|
664
|
+
if op = tok(/=/) ||
|
|
665
|
+
tok(INCLUDES) ||
|
|
666
|
+
tok(DASHMATCH) ||
|
|
667
|
+
tok(PREFIXMATCH) ||
|
|
668
|
+
tok(SUFFIXMATCH) ||
|
|
669
|
+
tok(SUBSTRINGMATCH)
|
|
670
|
+
@expected = "identifier or string"
|
|
671
|
+
ss
|
|
672
|
+
val = interp_ident || expr!(:interp_string)
|
|
673
|
+
ss
|
|
674
|
+
end
|
|
675
|
+
tok(/\]/)
|
|
676
|
+
|
|
677
|
+
Selector::Attribute.new(merge(name), merge(ns), op, merge(val))
|
|
678
|
+
end
|
|
679
|
+
|
|
680
|
+
def attrib_name!
|
|
681
|
+
if name_or_ns = interp_ident
|
|
682
|
+
# E, E|E
|
|
683
|
+
if tok(/\|(?!=)/)
|
|
684
|
+
ns = name_or_ns
|
|
685
|
+
name = interp_ident
|
|
686
|
+
else
|
|
687
|
+
name = name_or_ns
|
|
688
|
+
end
|
|
689
|
+
else
|
|
690
|
+
# *|E or |E
|
|
691
|
+
ns = [tok(/\*/) || ""]
|
|
692
|
+
tok!(/\|/)
|
|
693
|
+
name = expr!(:interp_ident)
|
|
694
|
+
end
|
|
695
|
+
return ns, name
|
|
696
|
+
end
|
|
697
|
+
|
|
698
|
+
def pseudo
|
|
699
|
+
return unless s = tok(/::?/)
|
|
700
|
+
@expected = "pseudoclass or pseudoelement"
|
|
701
|
+
name = expr!(:interp_ident)
|
|
702
|
+
if tok(/\(/)
|
|
703
|
+
ss
|
|
704
|
+
arg = expr!(:pseudo_expr)
|
|
705
|
+
tok!(/\)/)
|
|
706
|
+
end
|
|
707
|
+
Selector::Pseudo.new(s == ':' ? :class : :element, merge(name), merge(arg))
|
|
708
|
+
end
|
|
709
|
+
|
|
710
|
+
def pseudo_expr
|
|
711
|
+
return unless e = tok(PLUS) || tok(/-/) || tok(NUMBER) ||
|
|
712
|
+
interp_string || tok(IDENT) || interpolation
|
|
713
|
+
res = [e, str{ss}]
|
|
714
|
+
while e = tok(PLUS) || tok(/-/) || tok(NUMBER) ||
|
|
715
|
+
interp_string || tok(IDENT) || interpolation
|
|
716
|
+
res << e << str{ss}
|
|
717
|
+
end
|
|
718
|
+
res
|
|
719
|
+
end
|
|
720
|
+
|
|
721
|
+
def negation
|
|
722
|
+
return unless name = tok(NOT) || tok(MOZ_ANY)
|
|
723
|
+
ss
|
|
724
|
+
@expected = "selector"
|
|
725
|
+
sel = selector_comma_sequence
|
|
726
|
+
tok!(/\)/)
|
|
727
|
+
Selector::SelectorPseudoClass.new(name[1...-1], sel)
|
|
728
|
+
end
|
|
729
|
+
|
|
730
|
+
def declaration
|
|
731
|
+
# This allows the "*prop: val", ":prop: val", and ".prop: val" hacks
|
|
732
|
+
if s = tok(/[:\*\.]|\#(?!\{)/)
|
|
733
|
+
@use_property_exception = s !~ /[\.\#]/
|
|
734
|
+
name = [s, str{ss}, *expr!(:interp_ident)]
|
|
735
|
+
else
|
|
736
|
+
return unless name = interp_ident
|
|
737
|
+
name = [name] if name.is_a?(String)
|
|
738
|
+
end
|
|
739
|
+
if comment = tok(COMMENT)
|
|
740
|
+
name << comment
|
|
741
|
+
end
|
|
742
|
+
ss
|
|
743
|
+
|
|
744
|
+
tok!(/:/)
|
|
745
|
+
space, value = value!
|
|
746
|
+
ss
|
|
747
|
+
require_block = tok?(/\{/)
|
|
748
|
+
|
|
749
|
+
node = node(Sass::Tree::PropNode.new(name.flatten.compact, value, :new))
|
|
750
|
+
|
|
751
|
+
return node unless require_block
|
|
752
|
+
nested_properties! node, space
|
|
753
|
+
end
|
|
754
|
+
|
|
755
|
+
def value!
|
|
756
|
+
space = !str {ss}.empty?
|
|
757
|
+
@use_property_exception ||= space || !tok?(IDENT)
|
|
758
|
+
|
|
759
|
+
return true, Sass::Script::String.new("") if tok?(/\{/)
|
|
760
|
+
# This is a bit of a dirty trick:
|
|
761
|
+
# if the value is completely static,
|
|
762
|
+
# we don't parse it at all, and instead return a plain old string
|
|
763
|
+
# containing the value.
|
|
764
|
+
# This results in a dramatic speed increase.
|
|
765
|
+
if val = tok(STATIC_VALUE, true)
|
|
766
|
+
return space, Sass::Script::String.new(val.strip)
|
|
767
|
+
end
|
|
768
|
+
return space, sass_script(:parse)
|
|
769
|
+
end
|
|
770
|
+
|
|
771
|
+
def plain_value
|
|
772
|
+
return unless tok(/:/)
|
|
773
|
+
space = !str {ss}.empty?
|
|
774
|
+
@use_property_exception ||= space || !tok?(IDENT)
|
|
775
|
+
|
|
776
|
+
expression = expr
|
|
777
|
+
expression << tok(IMPORTANT) if expression
|
|
778
|
+
# expression, space, value
|
|
779
|
+
return expression, space, expression || [""]
|
|
780
|
+
end
|
|
781
|
+
|
|
782
|
+
def nested_properties!(node, space)
|
|
783
|
+
err(<<MESSAGE) unless space
|
|
784
|
+
Invalid CSS: a space is required between a property and its definition
|
|
785
|
+
when it has other properties nested beneath it.
|
|
786
|
+
MESSAGE
|
|
787
|
+
|
|
788
|
+
@use_property_exception = true
|
|
789
|
+
@expected = 'expression (e.g. 1px, bold) or "{"'
|
|
790
|
+
block(node, :property)
|
|
791
|
+
end
|
|
792
|
+
|
|
793
|
+
def expr
|
|
794
|
+
return unless t = term
|
|
795
|
+
res = [t, str{ss}]
|
|
796
|
+
|
|
797
|
+
while (o = operator) && (t = term)
|
|
798
|
+
res << o << t << str{ss}
|
|
799
|
+
end
|
|
800
|
+
|
|
801
|
+
res
|
|
802
|
+
end
|
|
803
|
+
|
|
804
|
+
def term
|
|
805
|
+
unless e = tok(NUMBER) ||
|
|
806
|
+
tok(URI) ||
|
|
807
|
+
function ||
|
|
808
|
+
tok(STRING) ||
|
|
809
|
+
tok(UNICODERANGE) ||
|
|
810
|
+
tok(IDENT) ||
|
|
811
|
+
tok(HEXCOLOR)
|
|
812
|
+
|
|
813
|
+
return unless op = unary_operator
|
|
814
|
+
@expected = "number or function"
|
|
815
|
+
return [op, tok(NUMBER) || expr!(:function)]
|
|
816
|
+
end
|
|
817
|
+
e
|
|
818
|
+
end
|
|
819
|
+
|
|
820
|
+
def function
|
|
821
|
+
return unless name = tok(FUNCTION)
|
|
822
|
+
if name == "expression(" || name == "calc("
|
|
823
|
+
str, _ = Sass::Shared.balance(@scanner, ?(, ?), 1)
|
|
824
|
+
[name, str]
|
|
825
|
+
else
|
|
826
|
+
[name, str{ss}, expr, tok!(/\)/)]
|
|
827
|
+
end
|
|
828
|
+
end
|
|
829
|
+
|
|
830
|
+
def interpolation
|
|
831
|
+
return unless tok(INTERP_START)
|
|
832
|
+
sass_script(:parse_interpolated)
|
|
833
|
+
end
|
|
834
|
+
|
|
835
|
+
def interp_string
|
|
836
|
+
_interp_string(:double) || _interp_string(:single)
|
|
837
|
+
end
|
|
838
|
+
|
|
839
|
+
def _interp_string(type)
|
|
840
|
+
return unless start = tok(Sass::Script::Lexer::STRING_REGULAR_EXPRESSIONS[[type, false]])
|
|
841
|
+
res = [start]
|
|
842
|
+
|
|
843
|
+
mid_re = Sass::Script::Lexer::STRING_REGULAR_EXPRESSIONS[[type, true]]
|
|
844
|
+
# @scanner[2].empty? means we've started an interpolated section
|
|
845
|
+
while @scanner[2] == '#{'
|
|
846
|
+
@scanner.pos -= 2 # Don't consume the #{
|
|
847
|
+
res.last.slice!(-2..-1)
|
|
848
|
+
res << expr!(:interpolation) << tok(mid_re)
|
|
849
|
+
end
|
|
850
|
+
res
|
|
851
|
+
end
|
|
852
|
+
|
|
853
|
+
def interp_ident(start = IDENT)
|
|
854
|
+
return unless val = tok(start) || interpolation || tok(IDENT_HYPHEN_INTERP, true)
|
|
855
|
+
res = [val]
|
|
856
|
+
while val = tok(NAME) || interpolation
|
|
857
|
+
res << val
|
|
858
|
+
end
|
|
859
|
+
res
|
|
860
|
+
end
|
|
861
|
+
|
|
862
|
+
def interp_name
|
|
863
|
+
interp_ident NAME
|
|
864
|
+
end
|
|
865
|
+
|
|
866
|
+
def str
|
|
867
|
+
@strs.push ""
|
|
868
|
+
yield
|
|
869
|
+
@strs.last
|
|
870
|
+
ensure
|
|
871
|
+
@strs.pop
|
|
872
|
+
end
|
|
873
|
+
|
|
874
|
+
def str?
|
|
875
|
+
pos = @scanner.pos
|
|
876
|
+
line = @line
|
|
877
|
+
@strs.push ""
|
|
878
|
+
throw_error {yield} && @strs.last
|
|
879
|
+
rescue Sass::SyntaxError => e
|
|
880
|
+
@scanner.pos = pos
|
|
881
|
+
@line = line
|
|
882
|
+
nil
|
|
883
|
+
ensure
|
|
884
|
+
@strs.pop
|
|
885
|
+
end
|
|
886
|
+
|
|
887
|
+
def node(node)
|
|
888
|
+
node.line = @line
|
|
889
|
+
node
|
|
890
|
+
end
|
|
891
|
+
|
|
892
|
+
@sass_script_parser = Class.new(Sass::Script::Parser)
|
|
893
|
+
@sass_script_parser.send(:include, ScriptParser)
|
|
894
|
+
# @private
|
|
895
|
+
def self.sass_script_parser; @sass_script_parser; end
|
|
896
|
+
|
|
897
|
+
def sass_script(*args)
|
|
898
|
+
parser = self.class.sass_script_parser.new(@scanner, @line,
|
|
899
|
+
@scanner.pos - (@scanner.string[0...@scanner.pos].rindex("\n") || 0))
|
|
900
|
+
result = parser.send(*args)
|
|
901
|
+
@line = parser.line
|
|
902
|
+
result
|
|
903
|
+
rescue Sass::SyntaxError => e
|
|
904
|
+
throw(:_sass_parser_error, true) if @throw_error
|
|
905
|
+
raise e
|
|
906
|
+
end
|
|
907
|
+
|
|
908
|
+
def merge(arr)
|
|
909
|
+
arr && Sass::Util.merge_adjacent_strings([arr].flatten)
|
|
910
|
+
end
|
|
911
|
+
|
|
912
|
+
EXPR_NAMES = {
|
|
913
|
+
:media_query => "media query (e.g. print, screen, print and screen)",
|
|
914
|
+
:media_expr => "media expression (e.g. (min-device-width: 800px)))",
|
|
915
|
+
:pseudo_expr => "expression (e.g. fr, 2n+1)",
|
|
916
|
+
:interp_ident => "identifier",
|
|
917
|
+
:interp_name => "identifier",
|
|
918
|
+
:expr => "expression (e.g. 1px, bold)",
|
|
919
|
+
:_selector => "selector",
|
|
920
|
+
:selector_comma_sequence => "selector",
|
|
921
|
+
:simple_selector_sequence => "selector",
|
|
922
|
+
:import_arg => "file to import (string or url())",
|
|
923
|
+
:moz_document_function => "matching function (e.g. url-prefix(), domain())",
|
|
924
|
+
:supports_condition => "@supports condition (e.g. (display: flexbox))",
|
|
925
|
+
:supports_condition_in_parens => "@supports condition (e.g. (display: flexbox))",
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
TOK_NAMES = Sass::Util.to_hash(
|
|
929
|
+
Sass::SCSS::RX.constants.map {|c| [Sass::SCSS::RX.const_get(c), c.downcase]}).
|
|
930
|
+
merge(IDENT => "identifier", /[;}]/ => '";"')
|
|
931
|
+
|
|
932
|
+
def tok?(rx)
|
|
933
|
+
@scanner.match?(rx)
|
|
934
|
+
end
|
|
935
|
+
|
|
936
|
+
def expr!(name)
|
|
937
|
+
(e = send(name)) && (return e)
|
|
938
|
+
expected(EXPR_NAMES[name] || name.to_s)
|
|
939
|
+
end
|
|
940
|
+
|
|
941
|
+
def tok!(rx)
|
|
942
|
+
(t = tok(rx)) && (return t)
|
|
943
|
+
name = TOK_NAMES[rx]
|
|
944
|
+
|
|
945
|
+
unless name
|
|
946
|
+
# Display basic regexps as plain old strings
|
|
947
|
+
string = rx.source.gsub(/\\(.)/, '\1')
|
|
948
|
+
name = rx.source == Regexp.escape(string) ? string.inspect : rx.inspect
|
|
949
|
+
end
|
|
950
|
+
|
|
951
|
+
expected(name)
|
|
952
|
+
end
|
|
953
|
+
|
|
954
|
+
def expected(name)
|
|
955
|
+
throw(:_sass_parser_error, true) if @throw_error
|
|
956
|
+
self.class.expected(@scanner, @expected || name, @line)
|
|
957
|
+
end
|
|
958
|
+
|
|
959
|
+
def err(msg)
|
|
960
|
+
throw(:_sass_parser_error, true) if @throw_error
|
|
961
|
+
raise Sass::SyntaxError.new(msg, :line => @line)
|
|
962
|
+
end
|
|
963
|
+
|
|
964
|
+
def throw_error
|
|
965
|
+
old_throw_error, @throw_error = @throw_error, false
|
|
966
|
+
yield
|
|
967
|
+
ensure
|
|
968
|
+
@throw_error = old_throw_error
|
|
969
|
+
end
|
|
970
|
+
|
|
971
|
+
def catch_error(&block)
|
|
972
|
+
old_throw_error, @throw_error = @throw_error, true
|
|
973
|
+
pos = @scanner.pos
|
|
974
|
+
line = @line
|
|
975
|
+
expected = @expected
|
|
976
|
+
if catch(:_sass_parser_error, &block)
|
|
977
|
+
@scanner.pos = pos
|
|
978
|
+
@line = line
|
|
979
|
+
@expected = expected
|
|
980
|
+
{:pos => pos, :line => line, :expected => @expected, :block => block}
|
|
981
|
+
end
|
|
982
|
+
ensure
|
|
983
|
+
@throw_error = old_throw_error
|
|
984
|
+
end
|
|
985
|
+
|
|
986
|
+
def rethrow(err)
|
|
987
|
+
if @throw_err
|
|
988
|
+
throw :_sass_parser_error, err
|
|
989
|
+
else
|
|
990
|
+
@scanner = Sass::Util::MultibyteStringScanner.new(@scanner.string)
|
|
991
|
+
@scanner.pos = err[:pos]
|
|
992
|
+
@line = err[:line]
|
|
993
|
+
@expected = err[:expected]
|
|
994
|
+
err[:block].call
|
|
995
|
+
end
|
|
996
|
+
end
|
|
997
|
+
|
|
998
|
+
# @private
|
|
999
|
+
def self.expected(scanner, expected, line)
|
|
1000
|
+
was = scanner.rest.dup
|
|
1001
|
+
# Get rid of whitespace between pos and the next token,
|
|
1002
|
+
# but only if there's a newline in there
|
|
1003
|
+
was.gsub!(/^\s*\n\s*/, '')
|
|
1004
|
+
# Also get rid of stuff after the next newline
|
|
1005
|
+
was.gsub!(/\n.*/, '')
|
|
1006
|
+
was = was[0...15] + "..." if was.size > 18
|
|
1007
|
+
|
|
1008
|
+
raise Sass::SyntaxError.new(
|
|
1009
|
+
"Invalid CSS after \"#{prior_snippet(scanner)}\": expected #{expected}, was \"#{was}\"",
|
|
1010
|
+
:line => line)
|
|
1011
|
+
end
|
|
1012
|
+
|
|
1013
|
+
# @private
|
|
1014
|
+
def self.prior_snippet(scanner)
|
|
1015
|
+
pos = scanner.pos
|
|
1016
|
+
|
|
1017
|
+
after = scanner.string[0...pos]
|
|
1018
|
+
# Get rid of whitespace between pos and the last token,
|
|
1019
|
+
# but only if there's a newline in there
|
|
1020
|
+
after.gsub!(/\s*\n\s*$/, '')
|
|
1021
|
+
# Also get rid of stuff before the last newline
|
|
1022
|
+
after.gsub!(/.*\n/, '')
|
|
1023
|
+
after = "..." + after[-15..-1] if after.size > 18
|
|
1024
|
+
after
|
|
1025
|
+
end
|
|
1026
|
+
|
|
1027
|
+
# Avoid allocating lots of new strings for `#tok`.
|
|
1028
|
+
# This is important because `#tok` is called all the time.
|
|
1029
|
+
NEWLINE = "\n"
|
|
1030
|
+
|
|
1031
|
+
def tok(rx, last_group_lookahead = false)
|
|
1032
|
+
res = @scanner.scan(rx)
|
|
1033
|
+
if res
|
|
1034
|
+
# This fixes https://github.com/nex3/sass/issues/104, which affects
|
|
1035
|
+
# Ruby 1.8.7 and REE. This fix is to replace the ?= zero-width
|
|
1036
|
+
# positive lookahead operator in the Regexp (which matches without
|
|
1037
|
+
# consuming the matched group), with a match that does consume the
|
|
1038
|
+
# group, but then rewinds the scanner and removes the group from the
|
|
1039
|
+
# end of the matched string. This fix makes the assumption that the
|
|
1040
|
+
# matched group will always occur at the end of the match.
|
|
1041
|
+
if last_group_lookahead && @scanner[-1]
|
|
1042
|
+
@scanner.pos -= @scanner[-1].length
|
|
1043
|
+
res.slice!(-@scanner[-1].length..-1)
|
|
1044
|
+
end
|
|
1045
|
+
@line += res.count(NEWLINE)
|
|
1046
|
+
@expected = nil
|
|
1047
|
+
if !@strs.empty? && rx != COMMENT && rx != SINGLE_LINE_COMMENT
|
|
1048
|
+
@strs.each {|s| s << res}
|
|
1049
|
+
end
|
|
1050
|
+
res
|
|
1051
|
+
end
|
|
1052
|
+
end
|
|
1053
|
+
end
|
|
1054
|
+
end
|
|
1055
|
+
end
|