oreorenasass 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (268) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +11 -0
  3. data/CONTRIBUTING +3 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +221 -0
  6. data/Rakefile +370 -0
  7. data/VERSION +1 -0
  8. data/VERSION_NAME +1 -0
  9. data/bin/sass +13 -0
  10. data/bin/sass-convert +12 -0
  11. data/bin/scss +13 -0
  12. data/extra/update_watch.rb +13 -0
  13. data/init.rb +18 -0
  14. data/lib/sass/cache_stores/base.rb +88 -0
  15. data/lib/sass/cache_stores/chain.rb +34 -0
  16. data/lib/sass/cache_stores/filesystem.rb +60 -0
  17. data/lib/sass/cache_stores/memory.rb +47 -0
  18. data/lib/sass/cache_stores/null.rb +25 -0
  19. data/lib/sass/cache_stores.rb +15 -0
  20. data/lib/sass/callbacks.rb +67 -0
  21. data/lib/sass/css.rb +407 -0
  22. data/lib/sass/engine.rb +1181 -0
  23. data/lib/sass/environment.rb +191 -0
  24. data/lib/sass/error.rb +198 -0
  25. data/lib/sass/exec/base.rb +187 -0
  26. data/lib/sass/exec/sass_convert.rb +264 -0
  27. data/lib/sass/exec/sass_scss.rb +424 -0
  28. data/lib/sass/exec.rb +9 -0
  29. data/lib/sass/features.rb +47 -0
  30. data/lib/sass/importers/base.rb +182 -0
  31. data/lib/sass/importers/filesystem.rb +211 -0
  32. data/lib/sass/importers.rb +22 -0
  33. data/lib/sass/logger/base.rb +30 -0
  34. data/lib/sass/logger/log_level.rb +45 -0
  35. data/lib/sass/logger.rb +12 -0
  36. data/lib/sass/media.rb +210 -0
  37. data/lib/sass/plugin/compiler.rb +565 -0
  38. data/lib/sass/plugin/configuration.rb +118 -0
  39. data/lib/sass/plugin/generic.rb +15 -0
  40. data/lib/sass/plugin/merb.rb +48 -0
  41. data/lib/sass/plugin/rack.rb +60 -0
  42. data/lib/sass/plugin/rails.rb +47 -0
  43. data/lib/sass/plugin/staleness_checker.rb +199 -0
  44. data/lib/sass/plugin.rb +133 -0
  45. data/lib/sass/railtie.rb +10 -0
  46. data/lib/sass/repl.rb +57 -0
  47. data/lib/sass/root.rb +7 -0
  48. data/lib/sass/script/css_lexer.rb +33 -0
  49. data/lib/sass/script/css_parser.rb +34 -0
  50. data/lib/sass/script/functions.rb +2626 -0
  51. data/lib/sass/script/lexer.rb +449 -0
  52. data/lib/sass/script/parser.rb +637 -0
  53. data/lib/sass/script/tree/funcall.rb +306 -0
  54. data/lib/sass/script/tree/interpolation.rb +118 -0
  55. data/lib/sass/script/tree/list_literal.rb +77 -0
  56. data/lib/sass/script/tree/literal.rb +45 -0
  57. data/lib/sass/script/tree/map_literal.rb +64 -0
  58. data/lib/sass/script/tree/node.rb +109 -0
  59. data/lib/sass/script/tree/operation.rb +103 -0
  60. data/lib/sass/script/tree/selector.rb +26 -0
  61. data/lib/sass/script/tree/string_interpolation.rb +104 -0
  62. data/lib/sass/script/tree/unary_operation.rb +69 -0
  63. data/lib/sass/script/tree/variable.rb +57 -0
  64. data/lib/sass/script/tree.rb +16 -0
  65. data/lib/sass/script/value/arg_list.rb +36 -0
  66. data/lib/sass/script/value/base.rb +240 -0
  67. data/lib/sass/script/value/bool.rb +35 -0
  68. data/lib/sass/script/value/color.rb +680 -0
  69. data/lib/sass/script/value/helpers.rb +262 -0
  70. data/lib/sass/script/value/list.rb +113 -0
  71. data/lib/sass/script/value/map.rb +70 -0
  72. data/lib/sass/script/value/null.rb +44 -0
  73. data/lib/sass/script/value/number.rb +530 -0
  74. data/lib/sass/script/value/string.rb +97 -0
  75. data/lib/sass/script/value.rb +11 -0
  76. data/lib/sass/script.rb +66 -0
  77. data/lib/sass/scss/css_parser.rb +42 -0
  78. data/lib/sass/scss/parser.rb +1209 -0
  79. data/lib/sass/scss/rx.rb +141 -0
  80. data/lib/sass/scss/script_lexer.rb +15 -0
  81. data/lib/sass/scss/script_parser.rb +25 -0
  82. data/lib/sass/scss/static_parser.rb +368 -0
  83. data/lib/sass/scss.rb +16 -0
  84. data/lib/sass/selector/abstract_sequence.rb +109 -0
  85. data/lib/sass/selector/comma_sequence.rb +175 -0
  86. data/lib/sass/selector/pseudo.rb +256 -0
  87. data/lib/sass/selector/sequence.rb +600 -0
  88. data/lib/sass/selector/simple.rb +117 -0
  89. data/lib/sass/selector/simple_sequence.rb +325 -0
  90. data/lib/sass/selector.rb +326 -0
  91. data/lib/sass/shared.rb +76 -0
  92. data/lib/sass/source/map.rb +210 -0
  93. data/lib/sass/source/position.rb +39 -0
  94. data/lib/sass/source/range.rb +41 -0
  95. data/lib/sass/stack.rb +120 -0
  96. data/lib/sass/supports.rb +227 -0
  97. data/lib/sass/tree/at_root_node.rb +83 -0
  98. data/lib/sass/tree/charset_node.rb +22 -0
  99. data/lib/sass/tree/comment_node.rb +82 -0
  100. data/lib/sass/tree/content_node.rb +9 -0
  101. data/lib/sass/tree/css_import_node.rb +60 -0
  102. data/lib/sass/tree/debug_node.rb +18 -0
  103. data/lib/sass/tree/directive_node.rb +59 -0
  104. data/lib/sass/tree/each_node.rb +24 -0
  105. data/lib/sass/tree/error_node.rb +18 -0
  106. data/lib/sass/tree/extend_node.rb +43 -0
  107. data/lib/sass/tree/for_node.rb +36 -0
  108. data/lib/sass/tree/function_node.rb +39 -0
  109. data/lib/sass/tree/if_node.rb +52 -0
  110. data/lib/sass/tree/import_node.rb +74 -0
  111. data/lib/sass/tree/keyframe_rule_node.rb +15 -0
  112. data/lib/sass/tree/media_node.rb +48 -0
  113. data/lib/sass/tree/mixin_def_node.rb +38 -0
  114. data/lib/sass/tree/mixin_node.rb +52 -0
  115. data/lib/sass/tree/node.rb +238 -0
  116. data/lib/sass/tree/prop_node.rb +171 -0
  117. data/lib/sass/tree/return_node.rb +19 -0
  118. data/lib/sass/tree/root_node.rb +44 -0
  119. data/lib/sass/tree/rule_node.rb +145 -0
  120. data/lib/sass/tree/supports_node.rb +38 -0
  121. data/lib/sass/tree/trace_node.rb +33 -0
  122. data/lib/sass/tree/variable_node.rb +36 -0
  123. data/lib/sass/tree/visitors/base.rb +72 -0
  124. data/lib/sass/tree/visitors/check_nesting.rb +177 -0
  125. data/lib/sass/tree/visitors/convert.rb +334 -0
  126. data/lib/sass/tree/visitors/cssize.rb +369 -0
  127. data/lib/sass/tree/visitors/deep_copy.rb +107 -0
  128. data/lib/sass/tree/visitors/extend.rb +68 -0
  129. data/lib/sass/tree/visitors/perform.rb +539 -0
  130. data/lib/sass/tree/visitors/set_options.rb +139 -0
  131. data/lib/sass/tree/visitors/to_css.rb +381 -0
  132. data/lib/sass/tree/warn_node.rb +18 -0
  133. data/lib/sass/tree/while_node.rb +18 -0
  134. data/lib/sass/util/cross_platform_random.rb +19 -0
  135. data/lib/sass/util/multibyte_string_scanner.rb +157 -0
  136. data/lib/sass/util/normalized_map.rb +130 -0
  137. data/lib/sass/util/ordered_hash.rb +192 -0
  138. data/lib/sass/util/subset_map.rb +110 -0
  139. data/lib/sass/util/test.rb +9 -0
  140. data/lib/sass/util.rb +1318 -0
  141. data/lib/sass/version.rb +124 -0
  142. data/lib/sass.rb +102 -0
  143. data/rails/init.rb +1 -0
  144. data/test/sass/cache_test.rb +131 -0
  145. data/test/sass/callbacks_test.rb +61 -0
  146. data/test/sass/compiler_test.rb +232 -0
  147. data/test/sass/conversion_test.rb +2054 -0
  148. data/test/sass/css2sass_test.rb +477 -0
  149. data/test/sass/data/hsl-rgb.txt +319 -0
  150. data/test/sass/encoding_test.rb +219 -0
  151. data/test/sass/engine_test.rb +3301 -0
  152. data/test/sass/exec_test.rb +86 -0
  153. data/test/sass/extend_test.rb +1661 -0
  154. data/test/sass/fixtures/test_staleness_check_across_importers.css +1 -0
  155. data/test/sass/fixtures/test_staleness_check_across_importers.scss +1 -0
  156. data/test/sass/functions_test.rb +1926 -0
  157. data/test/sass/importer_test.rb +412 -0
  158. data/test/sass/logger_test.rb +58 -0
  159. data/test/sass/mock_importer.rb +49 -0
  160. data/test/sass/more_results/more1.css +9 -0
  161. data/test/sass/more_results/more1_with_line_comments.css +26 -0
  162. data/test/sass/more_results/more_import.css +29 -0
  163. data/test/sass/more_templates/_more_partial.sass +2 -0
  164. data/test/sass/more_templates/more1.sass +23 -0
  165. data/test/sass/more_templates/more_import.sass +11 -0
  166. data/test/sass/plugin_test.rb +554 -0
  167. data/test/sass/results/alt.css +4 -0
  168. data/test/sass/results/basic.css +9 -0
  169. data/test/sass/results/cached_import_option.css +3 -0
  170. data/test/sass/results/compact.css +5 -0
  171. data/test/sass/results/complex.css +86 -0
  172. data/test/sass/results/compressed.css +1 -0
  173. data/test/sass/results/expanded.css +19 -0
  174. data/test/sass/results/filename_fn.css +3 -0
  175. data/test/sass/results/if.css +3 -0
  176. data/test/sass/results/import.css +31 -0
  177. data/test/sass/results/import_charset.css +5 -0
  178. data/test/sass/results/import_charset_1_8.css +5 -0
  179. data/test/sass/results/import_charset_ibm866.css +5 -0
  180. data/test/sass/results/import_content.css +1 -0
  181. data/test/sass/results/line_numbers.css +49 -0
  182. data/test/sass/results/mixins.css +95 -0
  183. data/test/sass/results/multiline.css +24 -0
  184. data/test/sass/results/nested.css +22 -0
  185. data/test/sass/results/options.css +1 -0
  186. data/test/sass/results/parent_ref.css +13 -0
  187. data/test/sass/results/script.css +16 -0
  188. data/test/sass/results/scss_import.css +31 -0
  189. data/test/sass/results/scss_importee.css +2 -0
  190. data/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
  191. data/test/sass/results/subdir/subdir.css +3 -0
  192. data/test/sass/results/units.css +11 -0
  193. data/test/sass/results/warn.css +0 -0
  194. data/test/sass/results/warn_imported.css +0 -0
  195. data/test/sass/script_conversion_test.rb +328 -0
  196. data/test/sass/script_test.rb +1054 -0
  197. data/test/sass/scss/css_test.rb +1215 -0
  198. data/test/sass/scss/rx_test.rb +156 -0
  199. data/test/sass/scss/scss_test.rb +3900 -0
  200. data/test/sass/scss/test_helper.rb +37 -0
  201. data/test/sass/source_map_test.rb +977 -0
  202. data/test/sass/superselector_test.rb +191 -0
  203. data/test/sass/templates/_cached_import_option_partial.scss +1 -0
  204. data/test/sass/templates/_double_import_loop2.sass +1 -0
  205. data/test/sass/templates/_filename_fn_import.scss +11 -0
  206. data/test/sass/templates/_imported_charset_ibm866.sass +4 -0
  207. data/test/sass/templates/_imported_charset_utf8.sass +4 -0
  208. data/test/sass/templates/_imported_content.sass +3 -0
  209. data/test/sass/templates/_partial.sass +2 -0
  210. data/test/sass/templates/_same_name_different_partiality.scss +1 -0
  211. data/test/sass/templates/alt.sass +16 -0
  212. data/test/sass/templates/basic.sass +23 -0
  213. data/test/sass/templates/bork1.sass +2 -0
  214. data/test/sass/templates/bork2.sass +2 -0
  215. data/test/sass/templates/bork3.sass +2 -0
  216. data/test/sass/templates/bork4.sass +2 -0
  217. data/test/sass/templates/bork5.sass +3 -0
  218. data/test/sass/templates/cached_import_option.scss +3 -0
  219. data/test/sass/templates/compact.sass +17 -0
  220. data/test/sass/templates/complex.sass +305 -0
  221. data/test/sass/templates/compressed.sass +15 -0
  222. data/test/sass/templates/double_import_loop1.sass +1 -0
  223. data/test/sass/templates/expanded.sass +17 -0
  224. data/test/sass/templates/filename_fn.scss +18 -0
  225. data/test/sass/templates/if.sass +11 -0
  226. data/test/sass/templates/import.sass +12 -0
  227. data/test/sass/templates/import_charset.sass +9 -0
  228. data/test/sass/templates/import_charset_1_8.sass +6 -0
  229. data/test/sass/templates/import_charset_ibm866.sass +11 -0
  230. data/test/sass/templates/import_content.sass +4 -0
  231. data/test/sass/templates/importee.less +2 -0
  232. data/test/sass/templates/importee.sass +19 -0
  233. data/test/sass/templates/line_numbers.sass +13 -0
  234. data/test/sass/templates/mixin_bork.sass +5 -0
  235. data/test/sass/templates/mixins.sass +76 -0
  236. data/test/sass/templates/multiline.sass +20 -0
  237. data/test/sass/templates/nested.sass +25 -0
  238. data/test/sass/templates/nested_bork1.sass +2 -0
  239. data/test/sass/templates/nested_bork2.sass +2 -0
  240. data/test/sass/templates/nested_bork3.sass +2 -0
  241. data/test/sass/templates/nested_bork4.sass +2 -0
  242. data/test/sass/templates/nested_import.sass +2 -0
  243. data/test/sass/templates/nested_mixin_bork.sass +6 -0
  244. data/test/sass/templates/options.sass +2 -0
  245. data/test/sass/templates/parent_ref.sass +25 -0
  246. data/test/sass/templates/same_name_different_ext.sass +2 -0
  247. data/test/sass/templates/same_name_different_ext.scss +1 -0
  248. data/test/sass/templates/same_name_different_partiality.scss +1 -0
  249. data/test/sass/templates/script.sass +101 -0
  250. data/test/sass/templates/scss_import.scss +12 -0
  251. data/test/sass/templates/scss_importee.scss +1 -0
  252. data/test/sass/templates/single_import_loop.sass +1 -0
  253. data/test/sass/templates/subdir/import_up1.scss +1 -0
  254. data/test/sass/templates/subdir/import_up2.scss +1 -0
  255. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
  256. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
  257. data/test/sass/templates/subdir/subdir.sass +6 -0
  258. data/test/sass/templates/units.sass +11 -0
  259. data/test/sass/templates/warn.sass +3 -0
  260. data/test/sass/templates/warn_imported.sass +4 -0
  261. data/test/sass/test_helper.rb +8 -0
  262. data/test/sass/util/multibyte_string_scanner_test.rb +147 -0
  263. data/test/sass/util/normalized_map_test.rb +51 -0
  264. data/test/sass/util/subset_map_test.rb +91 -0
  265. data/test/sass/util_test.rb +467 -0
  266. data/test/sass/value_helpers_test.rb +179 -0
  267. data/test/test_helper.rb +109 -0
  268. metadata +386 -0
@@ -0,0 +1,141 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Sass
3
+ module SCSS
4
+ # A module containing regular expressions used
5
+ # for lexing tokens in an SCSS document.
6
+ # Most of these are taken from [the CSS3 spec](http://www.w3.org/TR/css3-syntax/#lexical),
7
+ # although some have been modified for various reasons.
8
+ module RX
9
+ # Takes a string and returns a CSS identifier
10
+ # that will have the value of the given string.
11
+ #
12
+ # @param str [String] The string to escape
13
+ # @return [String] The escaped string
14
+ def self.escape_ident(str)
15
+ return "" if str.empty?
16
+ return "\\#{str}" if str == '-' || str == '_'
17
+ out = ""
18
+ value = str.dup
19
+ out << value.slice!(0...1) if value =~ /^[-_]/
20
+ if value[0...1] =~ NMSTART
21
+ out << value.slice!(0...1)
22
+ else
23
+ out << escape_char(value.slice!(0...1))
24
+ end
25
+ out << value.gsub(/[^a-zA-Z0-9_-]/) {|c| escape_char c}
26
+ out
27
+ end
28
+
29
+ # Escapes a single character for a CSS identifier.
30
+ #
31
+ # @param c [String] The character to escape. Should have length 1
32
+ # @return [String] The escaped character
33
+ # @private
34
+ def self.escape_char(c)
35
+ return "\\%06x" % Sass::Util.ord(c) unless c =~ /[ -\/:-~]/
36
+ "\\#{c}"
37
+ end
38
+
39
+ # Creates a Regexp from a plain text string,
40
+ # escaping all significant characters.
41
+ #
42
+ # @param str [String] The text of the regexp
43
+ # @param flags [Fixnum] Flags for the created regular expression
44
+ # @return [Regexp]
45
+ # @private
46
+ def self.quote(str, flags = 0)
47
+ Regexp.new(Regexp.quote(str), flags)
48
+ end
49
+
50
+ H = /[0-9a-fA-F]/
51
+ NL = /\n|\r\n|\r|\f/
52
+ UNICODE = /\\#{H}{1,6}[ \t\r\n\f]?/
53
+ s = if Sass::Util.ruby1_8?
54
+ '\200-\377'
55
+ elsif Sass::Util.macruby?
56
+ '\u0080-\uD7FF\uE000-\uFFFD\U00010000-\U0010FFFF'
57
+ else
58
+ '\u{80}-\u{D7FF}\u{E000}-\u{FFFD}\u{10000}-\u{10FFFF}'
59
+ end
60
+ NONASCII = /[#{s}]/
61
+ ESCAPE = /#{UNICODE}|\\[ -~#{s}]/
62
+ NMSTART = /[_a-zA-Z]|#{NONASCII}|#{ESCAPE}/
63
+ NMCHAR = /[a-zA-Z0-9_-]|#{NONASCII}|#{ESCAPE}/
64
+ STRING1 = /\"((?:[^\n\r\f\\"]|\\#{NL}|#{ESCAPE})*)\"/
65
+ STRING2 = /\'((?:[^\n\r\f\\']|\\#{NL}|#{ESCAPE})*)\'/
66
+
67
+ IDENT = /-*#{NMSTART}#{NMCHAR}*/
68
+ NAME = /#{NMCHAR}+/
69
+ NUM = //
70
+ STRING = /#{STRING1}|#{STRING2}/
71
+ URLCHAR = /[#%&*-~]|#{NONASCII}|#{ESCAPE}/
72
+ URL = /(#{URLCHAR}*)/
73
+ W = /[ \t\r\n\f]*/
74
+ VARIABLE = /(\$)(#{Sass::SCSS::RX::IDENT})/
75
+
76
+ # This is more liberal than the spec's definition,
77
+ # but that definition didn't work well with the greediness rules
78
+ RANGE = /(?:#{H}|\?){1,6}/
79
+
80
+ ##
81
+
82
+ S = /[ \t\r\n\f]+/
83
+
84
+ COMMENT = %r{/\*([^*]|\*+[^/*])*\**\*/}
85
+ SINGLE_LINE_COMMENT = %r{//.*(\n[ \t]*//.*)*}
86
+
87
+ CDO = quote("<!--")
88
+ CDC = quote("-->")
89
+ INCLUDES = quote("~=")
90
+ DASHMATCH = quote("|=")
91
+ PREFIXMATCH = quote("^=")
92
+ SUFFIXMATCH = quote("$=")
93
+ SUBSTRINGMATCH = quote("*=")
94
+
95
+ HASH = /##{NAME}/
96
+
97
+ IMPORTANT = /!#{W}important/i
98
+
99
+ UNITLESS_NUMBER = /(?:[0-9]+|[0-9]*\.[0-9]+)(?:[eE][+-]?\d+)?/
100
+ NUMBER = /#{UNITLESS_NUMBER}(?:#{IDENT}|%)?/
101
+ PERCENTAGE = /#{UNITLESS_NUMBER}%/
102
+
103
+ URI = /url\(#{W}(?:#{STRING}|#{URL})#{W}\)/i
104
+ FUNCTION = /#{IDENT}\(/
105
+
106
+ UNICODERANGE = /u\+(?:#{H}{1,6}-#{H}{1,6}|#{RANGE})/i
107
+
108
+ # Defined in http://www.w3.org/TR/css3-selectors/#lex
109
+ PLUS = /#{W}\+/
110
+ GREATER = /#{W}>/
111
+ TILDE = /#{W}~/
112
+ NOT = quote(":not(", Regexp::IGNORECASE)
113
+
114
+ # Defined in https://developer.mozilla.org/en/CSS/@-moz-document as a
115
+ # non-standard version of http://www.w3.org/TR/css3-conditional/
116
+ URL_PREFIX = /url-prefix\(#{W}(?:#{STRING}|#{URL})#{W}\)/i
117
+ DOMAIN = /domain\(#{W}(?:#{STRING}|#{URL})#{W}\)/i
118
+
119
+ # Custom
120
+ HEXCOLOR = /\#[0-9a-fA-F]+/
121
+ INTERP_START = /#\{/
122
+ ANY = /:(-[-\w]+-)?any\(/i
123
+ OPTIONAL = /!#{W}optional/i
124
+ IDENT_START = /-|#{NMSTART}/
125
+
126
+ # A unit is like an IDENT, but disallows a hyphen followed by a digit.
127
+ # This allows "1px-2px" to be interpreted as subtraction rather than "1"
128
+ # with the unit "px-2px". It also allows "%".
129
+ UNIT = /-?#{NMSTART}(?:[a-zA-Z0-9_]|#{NONASCII}|#{ESCAPE}|-(?!\d))*|%/
130
+
131
+ IDENT_HYPHEN_INTERP = /-(#\{)/
132
+ STRING1_NOINTERP = /\"((?:[^\n\r\f\\"#]|#(?!\{)|#{ESCAPE})*)\"/
133
+ STRING2_NOINTERP = /\'((?:[^\n\r\f\\'#]|#(?!\{)|#{ESCAPE})*)\'/
134
+ STRING_NOINTERP = /#{STRING1_NOINTERP}|#{STRING2_NOINTERP}/
135
+
136
+ STATIC_COMPONENT = /#{IDENT}|#{STRING_NOINTERP}|#{HEXCOLOR}|[+-]?#{NUMBER}|\!important/i
137
+ STATIC_VALUE = /#{STATIC_COMPONENT}(\s*[\s,\/]\s*#{STATIC_COMPONENT})*([;}])/i
138
+ STATIC_SELECTOR = /(#{NMCHAR}|[ \t]|[,>+*]|[:#.]#{NMSTART}){1,50}([{])/i
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,15 @@
1
+ module Sass
2
+ module SCSS
3
+ # A mixin for subclasses of {Sass::Script::Lexer}
4
+ # that makes them usable by {SCSS::Parser} to parse SassScript.
5
+ # In particular, the lexer doesn't support `!` for a variable prefix.
6
+ module ScriptLexer
7
+ private
8
+
9
+ def variable
10
+ return [:raw, "!important"] if scan(Sass::SCSS::RX::IMPORTANT)
11
+ _variable(Sass::SCSS::RX::VARIABLE)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,25 @@
1
+ module Sass
2
+ module SCSS
3
+ # A mixin for subclasses of {Sass::Script::Parser}
4
+ # that makes them usable by {SCSS::Parser} to parse SassScript.
5
+ # In particular, the parser won't raise an error
6
+ # when there's more content in the lexer once lexing is done.
7
+ # In addition, the parser doesn't support `!` for a variable prefix.
8
+ module ScriptParser
9
+ private
10
+
11
+ # @private
12
+ def lexer_class
13
+ klass = Class.new(super)
14
+ klass.send(:include, ScriptLexer)
15
+ klass
16
+ end
17
+
18
+ # Instead of raising an error when the parser is done,
19
+ # rewind the StringScanner so that it hasn't consumed the final token.
20
+ def assert_done
21
+ @lexer.unpeek!
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,368 @@
1
+ require 'sass/script/css_parser'
2
+
3
+ module Sass
4
+ module SCSS
5
+ # A parser for a static SCSS tree.
6
+ # Parses with SCSS extensions, like nested rules and parent selectors,
7
+ # but without dynamic SassScript.
8
+ # This is useful for e.g. \{#parse\_selector parsing selectors}
9
+ # after resolving the interpolation.
10
+ class StaticParser < Parser
11
+ # Parses the text as a selector.
12
+ #
13
+ # @param filename [String, nil] The file in which the selector appears,
14
+ # or nil if there is no such file.
15
+ # Used for error reporting.
16
+ # @return [Selector::CommaSequence] The parsed selector
17
+ # @raise [Sass::SyntaxError] if there's a syntax error in the selector
18
+ def parse_selector
19
+ init_scanner!
20
+ seq = expr!(:selector_comma_sequence)
21
+ expected("selector") unless @scanner.eos?
22
+ seq.line = @line
23
+ seq.filename = @filename
24
+ seq
25
+ end
26
+
27
+ # Parses a static at-root query.
28
+ #
29
+ # @return [(Symbol, Array<String>)] The type of the query
30
+ # (`:with` or `:without`) and the values that are being filtered.
31
+ # @raise [Sass::SyntaxError] if there's a syntax error in the query,
32
+ # or if it doesn't take up the entire input string.
33
+ def parse_static_at_root_query
34
+ init_scanner!
35
+ tok!(/\(/); ss
36
+ type = tok!(/\b(without|with)\b/).to_sym; ss
37
+ tok!(/:/); ss
38
+ directives = expr!(:at_root_directive_list); ss
39
+ tok!(/\)/)
40
+ expected("@at-root query list") unless @scanner.eos?
41
+ return type, directives
42
+ end
43
+
44
+ def parse_keyframes_selector
45
+ init_scanner!
46
+ sel = expr!(:keyframes_selector)
47
+ expected("keyframes selector") unless @scanner.eos?
48
+ sel
49
+ end
50
+
51
+ # @see Parser#initialize
52
+ # @param allow_parent_ref [Boolean] Whether to allow the
53
+ # parent-reference selector, `&`, when parsing the document.
54
+ # @comment
55
+ # rubocop:disable ParameterLists
56
+ def initialize(str, filename, importer, line = 1, offset = 1, allow_parent_ref = true)
57
+ # rubocop:enable ParameterLists
58
+ super(str, filename, importer, line, offset)
59
+ @allow_parent_ref = allow_parent_ref
60
+ end
61
+
62
+ private
63
+
64
+ def moz_document_function
65
+ val = tok(URI) || tok(URL_PREFIX) || tok(DOMAIN) || function(!:allow_var)
66
+ return unless val
67
+ ss
68
+ [val]
69
+ end
70
+
71
+ def variable; nil; end
72
+ def script_value; nil; end
73
+ def interpolation(warn_for_color = false); nil; end
74
+ def var_expr; nil; end
75
+ def interp_string; (s = tok(STRING)) && [s]; end
76
+ def interp_uri; (s = tok(URI)) && [s]; end
77
+ def interp_ident(ident = IDENT); (s = tok(ident)) && [s]; end
78
+ def use_css_import?; true; end
79
+
80
+ def special_directive(name, start_pos)
81
+ return unless %w[media import charset -moz-document].include?(name)
82
+ super
83
+ end
84
+
85
+ def selector_comma_sequence
86
+ sel = selector
87
+ return unless sel
88
+ selectors = [sel]
89
+ ws = ''
90
+ while tok(/,/)
91
+ ws << str {ss}
92
+ if (sel = selector)
93
+ selectors << sel
94
+ if ws.include?("\n")
95
+ selectors[-1] = Selector::Sequence.new(["\n"] + selectors.last.members)
96
+ end
97
+ ws = ''
98
+ end
99
+ end
100
+ Selector::CommaSequence.new(selectors)
101
+ end
102
+
103
+ def selector_string
104
+ sel = selector
105
+ return unless sel
106
+ sel.to_s
107
+ end
108
+
109
+ def selector
110
+ start_pos = source_position
111
+ # The combinator here allows the "> E" hack
112
+ val = combinator || simple_selector_sequence
113
+ return unless val
114
+ nl = str {ss}.include?("\n")
115
+ res = []
116
+ res << val
117
+ res << "\n" if nl
118
+
119
+ while (val = combinator || simple_selector_sequence)
120
+ res << val
121
+ res << "\n" if str {ss}.include?("\n")
122
+ end
123
+ seq = Selector::Sequence.new(res.compact)
124
+
125
+ if seq.members.any? {|sseq| sseq.is_a?(Selector::SimpleSequence) && sseq.subject?}
126
+ location = " of #{@filename}" if @filename
127
+ Sass::Util.sass_warn <<MESSAGE
128
+ DEPRECATION WARNING on line #{start_pos.line}, column #{start_pos.offset}#{location}:
129
+ The subject selector operator "!" is deprecated and will be removed in a future release.
130
+ This operator has been replaced by ":has()" in the CSS spec.
131
+ For example: #{seq.subjectless}
132
+ MESSAGE
133
+ end
134
+
135
+ seq
136
+ end
137
+
138
+ def combinator
139
+ tok(PLUS) || tok(GREATER) || tok(TILDE) || reference_combinator
140
+ end
141
+
142
+ def reference_combinator
143
+ return unless tok(/\//)
144
+ res = '/'
145
+ ns, name = expr!(:qualified_name)
146
+ res << ns << '|' if ns
147
+ res << name << tok!(/\//)
148
+ res
149
+ end
150
+
151
+ def simple_selector_sequence
152
+ start_pos = source_position
153
+ e = element_name || id_selector || class_selector || placeholder_selector || attrib ||
154
+ pseudo || parent_selector
155
+ return unless e
156
+ res = [e]
157
+
158
+ # The tok(/\*/) allows the "E*" hack
159
+ while (v = id_selector || class_selector || placeholder_selector ||
160
+ attrib || pseudo || (tok(/\*/) && Selector::Universal.new(nil)))
161
+ res << v
162
+ end
163
+
164
+ pos = @scanner.pos
165
+ line = @line
166
+ if (sel = str? {simple_selector_sequence})
167
+ @scanner.pos = pos
168
+ @line = line
169
+ begin
170
+ # If we see "*E", don't force a throw because this could be the
171
+ # "*prop: val" hack.
172
+ expected('"{"') if res.length == 1 && res[0].is_a?(Selector::Universal)
173
+ throw_error {expected('"{"')}
174
+ rescue Sass::SyntaxError => e
175
+ e.message << "\n\n\"#{sel}\" may only be used at the beginning of a compound selector."
176
+ raise e
177
+ end
178
+ end
179
+
180
+ Selector::SimpleSequence.new(res, tok(/!/), range(start_pos))
181
+ end
182
+
183
+ def parent_selector
184
+ return unless @allow_parent_ref && tok(/&/)
185
+ Selector::Parent.new(tok(NAME))
186
+ end
187
+
188
+ def class_selector
189
+ return unless tok(/\./)
190
+ @expected = "class name"
191
+ Selector::Class.new(tok!(IDENT))
192
+ end
193
+
194
+ def id_selector
195
+ return unless tok(/#(?!\{)/)
196
+ @expected = "id name"
197
+ Selector::Id.new(tok!(NAME))
198
+ end
199
+
200
+ def placeholder_selector
201
+ return unless tok(/%/)
202
+ @expected = "placeholder name"
203
+ Selector::Placeholder.new(tok!(IDENT))
204
+ end
205
+
206
+ def element_name
207
+ ns, name = Sass::Util.destructure(qualified_name(:allow_star_name))
208
+ return unless ns || name
209
+
210
+ if name == '*'
211
+ Selector::Universal.new(ns)
212
+ else
213
+ Selector::Element.new(name, ns)
214
+ end
215
+ end
216
+
217
+ def qualified_name(allow_star_name = false)
218
+ name = tok(IDENT) || tok(/\*/) || (tok?(/\|/) && "")
219
+ return unless name
220
+ return nil, name unless tok(/\|/)
221
+
222
+ return name, tok!(IDENT) unless allow_star_name
223
+ @expected = "identifier or *"
224
+ return name, tok(IDENT) || tok!(/\*/)
225
+ end
226
+
227
+ def attrib
228
+ return unless tok(/\[/)
229
+ ss
230
+ ns, name = attrib_name!
231
+ ss
232
+
233
+ op = tok(/=/) ||
234
+ tok(INCLUDES) ||
235
+ tok(DASHMATCH) ||
236
+ tok(PREFIXMATCH) ||
237
+ tok(SUFFIXMATCH) ||
238
+ tok(SUBSTRINGMATCH)
239
+ if op
240
+ @expected = "identifier or string"
241
+ ss
242
+ val = tok(IDENT) || tok!(STRING)
243
+ ss
244
+ end
245
+ flags = tok(IDENT) || tok(STRING)
246
+ tok!(/\]/)
247
+
248
+ Selector::Attribute.new(name, ns, op, val, flags)
249
+ end
250
+
251
+ def attrib_name!
252
+ if (name_or_ns = tok(IDENT))
253
+ # E, E|E
254
+ if tok(/\|(?!=)/)
255
+ ns = name_or_ns
256
+ name = tok(IDENT)
257
+ else
258
+ name = name_or_ns
259
+ end
260
+ else
261
+ # *|E or |E
262
+ ns = tok(/\*/) || ""
263
+ tok!(/\|/)
264
+ name = tok!(IDENT)
265
+ end
266
+ return ns, name
267
+ end
268
+
269
+ SELECTOR_PSEUDO_CLASSES = %w[not matches current any has host host-context].to_set
270
+
271
+ PREFIXED_SELECTOR_PSEUDO_CLASSES = %w[nth-child nth-last-child].to_set
272
+
273
+ def pseudo
274
+ s = tok(/::?/)
275
+ return unless s
276
+ @expected = "pseudoclass or pseudoelement"
277
+ name = tok!(IDENT)
278
+ if tok(/\(/)
279
+ ss
280
+ deprefixed = deprefix(name)
281
+ if s == ':' && SELECTOR_PSEUDO_CLASSES.include?(deprefixed)
282
+ sel = selector_comma_sequence
283
+ elsif s == ':' && PREFIXED_SELECTOR_PSEUDO_CLASSES.include?(deprefixed)
284
+ arg, sel = prefixed_selector_pseudo
285
+ else
286
+ arg = expr!(:pseudo_args)
287
+ end
288
+
289
+ tok!(/\)/)
290
+ end
291
+ Selector::Pseudo.new(s == ':' ? :class : :element, name, arg, sel)
292
+ end
293
+
294
+ def pseudo_args
295
+ arg = expr!(:pseudo_expr)
296
+ while tok(/,/)
297
+ arg << ',' << str {ss}
298
+ arg.concat expr!(:pseudo_expr)
299
+ end
300
+ arg
301
+ end
302
+
303
+ def pseudo_expr
304
+ res = pseudo_expr_token
305
+ return unless res
306
+ res << str {ss}
307
+ while (e = pseudo_expr_token)
308
+ res << e << str {ss}
309
+ end
310
+ res
311
+ end
312
+
313
+ def pseudo_expr_token
314
+ tok(PLUS) || tok(/[-*]/) || tok(NUMBER) || tok(STRING) || tok(IDENT)
315
+ end
316
+
317
+ def prefixed_selector_pseudo
318
+ prefix = str do
319
+ expr = str {expr!(:a_n_plus_b)}
320
+ ss
321
+ return expr, nil unless tok(/of/)
322
+ ss
323
+ end
324
+ return prefix, expr!(:selector_comma_sequence)
325
+ end
326
+
327
+ def a_n_plus_b
328
+ if (parity = tok(/even|odd/i))
329
+ return parity
330
+ end
331
+
332
+ if tok(/[+-]?[0-9]+/)
333
+ ss
334
+ return true unless tok(/n/)
335
+ else
336
+ return unless tok(/[+-]?n/i)
337
+ end
338
+ ss
339
+
340
+ return true unless tok(/[+-]/)
341
+ ss
342
+ @expected = "number"
343
+ tok!(/[0-9]+/)
344
+ true
345
+ end
346
+
347
+ def keyframes_selector
348
+ ss
349
+ str do
350
+ return unless keyframes_selector_component
351
+ ss
352
+ while tok(/,/)
353
+ ss
354
+ expr!(:keyframes_selector_component)
355
+ ss
356
+ end
357
+ end
358
+ end
359
+
360
+ def keyframes_selector_component
361
+ tok(/from|to/i) || tok(PERCENTAGE)
362
+ end
363
+
364
+ @sass_script_parser = Class.new(Sass::Script::CssParser)
365
+ @sass_script_parser.send(:include, ScriptParser)
366
+ end
367
+ end
368
+ end