haml 3.0.25 → 3.1.0.alpha.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of haml might be problematic. Click here for more details.

Files changed (212) hide show
  1. data/.yardopts +1 -1
  2. data/CONTRIBUTING +0 -1
  3. data/EDGE_GEM_VERSION +1 -0
  4. data/MIT-LICENSE +1 -1
  5. data/README.md +10 -175
  6. data/Rakefile +56 -84
  7. data/VERSION +1 -1
  8. data/VERSION_NAME +1 -1
  9. data/init.rb +1 -1
  10. data/lib/haml.rb +14 -12
  11. data/lib/haml/engine.rb +1 -1
  12. data/lib/haml/exec.rb +19 -316
  13. data/lib/haml/helpers/action_view_extensions.rb +1 -1
  14. data/lib/haml/html.rb +69 -76
  15. data/lib/haml/precompiler.rb +34 -41
  16. data/lib/haml/railtie.rb +4 -6
  17. data/lib/haml/template/plugin.rb +6 -16
  18. data/lib/haml/util.rb +91 -107
  19. data/lib/haml/version.rb +7 -0
  20. data/test/benchmark.rb +2 -9
  21. data/test/haml/engine_test.rb +195 -92
  22. data/test/haml/html2haml/erb_tests.rb +0 -14
  23. data/test/haml/util_test.rb +32 -0
  24. data/test/test_helper.rb +0 -39
  25. metadata +96 -324
  26. data/bin/css2sass +0 -13
  27. data/bin/sass +0 -8
  28. data/bin/sass-convert +0 -7
  29. data/extra/haml-mode.el +0 -753
  30. data/extra/sass-mode.el +0 -207
  31. data/lib/haml/util/subset_map.rb +0 -101
  32. data/lib/sass.rb +0 -29
  33. data/lib/sass/callbacks.rb +0 -52
  34. data/lib/sass/css.rb +0 -294
  35. data/lib/sass/engine.rb +0 -720
  36. data/lib/sass/environment.rb +0 -143
  37. data/lib/sass/error.rb +0 -198
  38. data/lib/sass/files.rb +0 -160
  39. data/lib/sass/less.rb +0 -382
  40. data/lib/sass/plugin.rb +0 -279
  41. data/lib/sass/plugin/configuration.rb +0 -221
  42. data/lib/sass/plugin/generic.rb +0 -15
  43. data/lib/sass/plugin/merb.rb +0 -37
  44. data/lib/sass/plugin/rack.rb +0 -47
  45. data/lib/sass/plugin/rails.rb +0 -32
  46. data/lib/sass/plugin/staleness_checker.rb +0 -123
  47. data/lib/sass/repl.rb +0 -58
  48. data/lib/sass/script.rb +0 -63
  49. data/lib/sass/script/bool.rb +0 -18
  50. data/lib/sass/script/color.rb +0 -491
  51. data/lib/sass/script/css_lexer.rb +0 -29
  52. data/lib/sass/script/css_parser.rb +0 -31
  53. data/lib/sass/script/funcall.rb +0 -77
  54. data/lib/sass/script/functions.rb +0 -861
  55. data/lib/sass/script/interpolation.rb +0 -70
  56. data/lib/sass/script/lexer.rb +0 -337
  57. data/lib/sass/script/literal.rb +0 -236
  58. data/lib/sass/script/node.rb +0 -112
  59. data/lib/sass/script/number.rb +0 -423
  60. data/lib/sass/script/operation.rb +0 -95
  61. data/lib/sass/script/parser.rb +0 -401
  62. data/lib/sass/script/string.rb +0 -67
  63. data/lib/sass/script/string_interpolation.rb +0 -93
  64. data/lib/sass/script/unary_operation.rb +0 -57
  65. data/lib/sass/script/variable.rb +0 -48
  66. data/lib/sass/scss.rb +0 -17
  67. data/lib/sass/scss/css_parser.rb +0 -46
  68. data/lib/sass/scss/parser.rb +0 -855
  69. data/lib/sass/scss/rx.rb +0 -126
  70. data/lib/sass/scss/sass_parser.rb +0 -11
  71. data/lib/sass/scss/script_lexer.rb +0 -15
  72. data/lib/sass/scss/script_parser.rb +0 -25
  73. data/lib/sass/scss/static_parser.rb +0 -40
  74. data/lib/sass/selector.rb +0 -361
  75. data/lib/sass/selector/abstract_sequence.rb +0 -62
  76. data/lib/sass/selector/comma_sequence.rb +0 -82
  77. data/lib/sass/selector/sequence.rb +0 -237
  78. data/lib/sass/selector/simple.rb +0 -113
  79. data/lib/sass/selector/simple_sequence.rb +0 -136
  80. data/lib/sass/tree/charset_node.rb +0 -37
  81. data/lib/sass/tree/comment_node.rb +0 -128
  82. data/lib/sass/tree/debug_node.rb +0 -36
  83. data/lib/sass/tree/directive_node.rb +0 -75
  84. data/lib/sass/tree/extend_node.rb +0 -65
  85. data/lib/sass/tree/for_node.rb +0 -55
  86. data/lib/sass/tree/if_node.rb +0 -69
  87. data/lib/sass/tree/import_node.rb +0 -102
  88. data/lib/sass/tree/mixin_def_node.rb +0 -48
  89. data/lib/sass/tree/mixin_node.rb +0 -111
  90. data/lib/sass/tree/node.rb +0 -464
  91. data/lib/sass/tree/prop_node.rb +0 -220
  92. data/lib/sass/tree/root_node.rb +0 -163
  93. data/lib/sass/tree/rule_node.rb +0 -261
  94. data/lib/sass/tree/variable_node.rb +0 -39
  95. data/lib/sass/tree/warn_node.rb +0 -42
  96. data/lib/sass/tree/while_node.rb +0 -36
  97. data/test/haml/util/subset_map_test.rb +0 -91
  98. data/test/sass/callbacks_test.rb +0 -61
  99. data/test/sass/conversion_test.rb +0 -1218
  100. data/test/sass/css2sass_test.rb +0 -364
  101. data/test/sass/data/hsl-rgb.txt +0 -319
  102. data/test/sass/engine_test.rb +0 -2267
  103. data/test/sass/extend_test.rb +0 -1348
  104. data/test/sass/functions_test.rb +0 -556
  105. data/test/sass/less_conversion_test.rb +0 -653
  106. data/test/sass/more_results/more1.css +0 -9
  107. data/test/sass/more_results/more1_with_line_comments.css +0 -26
  108. data/test/sass/more_results/more_import.css +0 -29
  109. data/test/sass/more_templates/_more_partial.sass +0 -2
  110. data/test/sass/more_templates/more1.sass +0 -23
  111. data/test/sass/more_templates/more_import.sass +0 -11
  112. data/test/sass/plugin_test.rb +0 -433
  113. data/test/sass/results/alt.css +0 -4
  114. data/test/sass/results/basic.css +0 -9
  115. data/test/sass/results/compact.css +0 -5
  116. data/test/sass/results/complex.css +0 -86
  117. data/test/sass/results/compressed.css +0 -1
  118. data/test/sass/results/expanded.css +0 -19
  119. data/test/sass/results/import.css +0 -31
  120. data/test/sass/results/import_charset.css +0 -4
  121. data/test/sass/results/import_charset_1_8.css +0 -4
  122. data/test/sass/results/import_charset_ibm866.css +0 -4
  123. data/test/sass/results/line_numbers.css +0 -49
  124. data/test/sass/results/mixins.css +0 -95
  125. data/test/sass/results/multiline.css +0 -24
  126. data/test/sass/results/nested.css +0 -22
  127. data/test/sass/results/options.css +0 -1
  128. data/test/sass/results/parent_ref.css +0 -13
  129. data/test/sass/results/script.css +0 -16
  130. data/test/sass/results/scss_import.css +0 -31
  131. data/test/sass/results/scss_importee.css +0 -2
  132. data/test/sass/results/subdir/nested_subdir/nested_subdir.css +0 -1
  133. data/test/sass/results/subdir/subdir.css +0 -3
  134. data/test/sass/results/units.css +0 -11
  135. data/test/sass/results/warn.css +0 -0
  136. data/test/sass/results/warn_imported.css +0 -0
  137. data/test/sass/script_conversion_test.rb +0 -314
  138. data/test/sass/script_test.rb +0 -470
  139. data/test/sass/scss/css_test.rb +0 -916
  140. data/test/sass/scss/rx_test.rb +0 -156
  141. data/test/sass/scss/scss_test.rb +0 -1122
  142. data/test/sass/scss/test_helper.rb +0 -37
  143. data/test/sass/templates/_imported_charset_ibm866.sass +0 -4
  144. data/test/sass/templates/_imported_charset_utf8.sass +0 -4
  145. data/test/sass/templates/_partial.sass +0 -2
  146. data/test/sass/templates/alt.sass +0 -16
  147. data/test/sass/templates/basic.sass +0 -23
  148. data/test/sass/templates/bork1.sass +0 -2
  149. data/test/sass/templates/bork2.sass +0 -2
  150. data/test/sass/templates/bork3.sass +0 -2
  151. data/test/sass/templates/bork4.sass +0 -2
  152. data/test/sass/templates/compact.sass +0 -17
  153. data/test/sass/templates/complex.sass +0 -305
  154. data/test/sass/templates/compressed.sass +0 -15
  155. data/test/sass/templates/expanded.sass +0 -17
  156. data/test/sass/templates/import.sass +0 -12
  157. data/test/sass/templates/import_charset.sass +0 -7
  158. data/test/sass/templates/import_charset_1_8.sass +0 -4
  159. data/test/sass/templates/import_charset_ibm866.sass +0 -9
  160. data/test/sass/templates/importee.less +0 -2
  161. data/test/sass/templates/importee.sass +0 -19
  162. data/test/sass/templates/line_numbers.sass +0 -13
  163. data/test/sass/templates/mixin_bork.sass +0 -5
  164. data/test/sass/templates/mixins.sass +0 -76
  165. data/test/sass/templates/multiline.sass +0 -20
  166. data/test/sass/templates/nested.sass +0 -25
  167. data/test/sass/templates/nested_bork1.sass +0 -2
  168. data/test/sass/templates/nested_bork2.sass +0 -2
  169. data/test/sass/templates/nested_bork3.sass +0 -2
  170. data/test/sass/templates/nested_bork4.sass +0 -2
  171. data/test/sass/templates/nested_mixin_bork.sass +0 -6
  172. data/test/sass/templates/options.sass +0 -2
  173. data/test/sass/templates/parent_ref.sass +0 -25
  174. data/test/sass/templates/script.sass +0 -101
  175. data/test/sass/templates/scss_import.scss +0 -11
  176. data/test/sass/templates/scss_importee.scss +0 -1
  177. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +0 -2
  178. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +0 -3
  179. data/test/sass/templates/subdir/subdir.sass +0 -6
  180. data/test/sass/templates/units.sass +0 -11
  181. data/test/sass/templates/warn.sass +0 -3
  182. data/test/sass/templates/warn_imported.sass +0 -4
  183. data/vendor/fssm/LICENSE +0 -20
  184. data/vendor/fssm/README.markdown +0 -55
  185. data/vendor/fssm/Rakefile +0 -59
  186. data/vendor/fssm/VERSION.yml +0 -5
  187. data/vendor/fssm/example.rb +0 -9
  188. data/vendor/fssm/fssm.gemspec +0 -77
  189. data/vendor/fssm/lib/fssm.rb +0 -33
  190. data/vendor/fssm/lib/fssm/backends/fsevents.rb +0 -36
  191. data/vendor/fssm/lib/fssm/backends/inotify.rb +0 -26
  192. data/vendor/fssm/lib/fssm/backends/polling.rb +0 -25
  193. data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +0 -131
  194. data/vendor/fssm/lib/fssm/monitor.rb +0 -26
  195. data/vendor/fssm/lib/fssm/path.rb +0 -91
  196. data/vendor/fssm/lib/fssm/pathname.rb +0 -502
  197. data/vendor/fssm/lib/fssm/state/directory.rb +0 -57
  198. data/vendor/fssm/lib/fssm/state/file.rb +0 -24
  199. data/vendor/fssm/lib/fssm/support.rb +0 -63
  200. data/vendor/fssm/lib/fssm/tree.rb +0 -176
  201. data/vendor/fssm/profile/prof-cache.rb +0 -40
  202. data/vendor/fssm/profile/prof-fssm-pathname.html +0 -1231
  203. data/vendor/fssm/profile/prof-pathname.rb +0 -68
  204. data/vendor/fssm/profile/prof-plain-pathname.html +0 -988
  205. data/vendor/fssm/profile/prof.html +0 -2379
  206. data/vendor/fssm/spec/path_spec.rb +0 -75
  207. data/vendor/fssm/spec/root/duck/quack.txt +0 -0
  208. data/vendor/fssm/spec/root/file.css +0 -0
  209. data/vendor/fssm/spec/root/file.rb +0 -0
  210. data/vendor/fssm/spec/root/file.yml +0 -0
  211. data/vendor/fssm/spec/root/moo/cow.txt +0 -0
  212. data/vendor/fssm/spec/spec_helper.rb +0 -14
@@ -1,126 +0,0 @@
1
- module Sass
2
- module SCSS
3
- # A module containing regular expressions used
4
- # for lexing tokens in an SCSS document.
5
- # Most of these are taken from [the CSS3 spec](http://www.w3.org/TR/css3-syntax/#lexical),
6
- # although some have been modified for various reasons.
7
- module RX
8
- # Takes a string and returns a CSS identifier
9
- # that will have the value of the given string.
10
- #
11
- # @param str [String] The string to escape
12
- # @return [String] The escaped string
13
- def self.escape_ident(str)
14
- return "" if str.empty?
15
- return "\\#{str}" if str == '-' || str == '_'
16
- out = ""
17
- value = str.dup
18
- out << value.slice!(0...1) if value =~ /^[-_]/
19
- if value[0...1] =~ NMSTART
20
- out << value.slice!(0...1)
21
- else
22
- out << escape_char(value.slice!(0...1))
23
- end
24
- out << value.gsub(/[^a-zA-Z0-9_-]/) {|c| escape_char c}
25
- return out
26
- end
27
-
28
- # Escapes a single character for a CSS identifier.
29
- #
30
- # @param c [String] The character to escape. Should have length 1
31
- # @return [String] The escaped character
32
- # @private
33
- def self.escape_char(c)
34
- return "\\%06x" % Haml::Util.ord(c) unless c =~ /[ -\/:-~]/
35
- return "\\#{c}"
36
- end
37
-
38
- # Creates a Regexp from a plain text string,
39
- # escaping all significant characters.
40
- #
41
- # @param str [String] The text of the regexp
42
- # @param flags [Fixnum] Flags for the created regular expression
43
- # @return [Regexp]
44
- # @private
45
- def self.quote(str, flags = 0)
46
- Regexp.new(Regexp.quote(str), flags)
47
- end
48
-
49
- H = /[0-9a-fA-F]/
50
- NL = /\n|\r\n|\r|\f/
51
- UNICODE = /\\#{H}{1,6}[ \t\r\n\f]?/
52
- s = if Haml::Util.ruby1_8?
53
- '\200-\377'
54
- else
55
- '\u{80}-\u{D7FF}\u{E000}-\u{FFFD}\u{10000}-\u{10FFFF}'
56
- end
57
- NONASCII = /[#{s}]/
58
- ESCAPE = /#{UNICODE}|\\[ -~#{s}]/
59
- NMSTART = /[_a-zA-Z]|#{NONASCII}|#{ESCAPE}/
60
- NMCHAR = /[a-zA-Z0-9_-]|#{NONASCII}|#{ESCAPE}/
61
- STRING1 = /\"((?:[^\n\r\f\\"]|\\#{NL}|#{ESCAPE})*)\"/
62
- STRING2 = /\'((?:[^\n\r\f\\']|\\#{NL}|#{ESCAPE})*)\'/
63
-
64
- IDENT = /-?#{NMSTART}#{NMCHAR}*/
65
- NAME = /#{NMCHAR}+/
66
- NUM = /[0-9]+|[0-9]*\.[0-9]+/
67
- STRING = /#{STRING1}|#{STRING2}/
68
- URLCHAR = /[#%&*-~]|#{NONASCII}|#{ESCAPE}/
69
- URL = /(#{URLCHAR}*)/
70
- W = /[ \t\r\n\f]*/
71
-
72
- # This is more liberal than the spec's definition,
73
- # but that definition didn't work well with the greediness rules
74
- RANGE = /(?:#{H}|\?){1,6}/
75
-
76
- ##
77
-
78
- S = /[ \t\r\n\f]+/
79
-
80
- COMMENT = /\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\//
81
- SINGLE_LINE_COMMENT = /\/\/.*(\n[ \t]*\/\/.*)*/
82
-
83
- CDO = quote("<!--")
84
- CDC = quote("-->")
85
- INCLUDES = quote("~=")
86
- DASHMATCH = quote("|=")
87
- PREFIXMATCH = quote("^=")
88
- SUFFIXMATCH = quote("$=")
89
- SUBSTRINGMATCH = quote("*=")
90
-
91
- HASH = /##{NAME}/
92
-
93
- IMPORTANT = /!#{W}important/i
94
- DEFAULT = /!#{W}default/i
95
-
96
- NUMBER = /#{NUM}(?:#{IDENT}|%)?/
97
-
98
- URI = /url\(#{W}(?:#{STRING}|#{URL})#{W}\)/i
99
- FUNCTION = /#{IDENT}\(/
100
-
101
- UNICODERANGE = /u\+(?:#{H}{1,6}-#{H}{1,6}|#{RANGE})/i
102
-
103
- # Defined in http://www.w3.org/TR/css3-selectors/#lex
104
- PLUS = /#{W}\+/
105
- GREATER = /#{W}>/
106
- TILDE = /#{W}~/
107
- NOT = quote(":not(", Regexp::IGNORECASE)
108
-
109
- # Custom
110
- HEXCOLOR = /\#[0-9a-fA-F]+/
111
- INTERP_START = /#\{/
112
- MOZ_ANY = quote(":-moz-any(", Regexp::IGNORECASE)
113
-
114
- STRING1_NOINTERP = /\"((?:[^\n\r\f\\"#]|#(?!\{)|\\#{NL}|#{ESCAPE})*)\"/
115
- STRING2_NOINTERP = /\'((?:[^\n\r\f\\'#]|#(?!\{)|\\#{NL}|#{ESCAPE})*)\'/
116
- STRING_NOINTERP = /#{STRING1_NOINTERP}|#{STRING2_NOINTERP}/
117
- # Can't use IDENT here, because it seems to take exponential time on 1.8.
118
- # We could use it for 1.9 only, but I don't want to introduce a cross-version
119
- # behavior difference.
120
- # In any case, almost all CSS idents will be matched by this.
121
- STATIC_VALUE = /(-?#{NMSTART}|#{STRING_NOINTERP}|\s(?!%)|#[a-f0-9]|[,%]|#{NUM}|\!important)+(?=[;}])/i
122
-
123
- STATIC_SELECTOR = /(#{NMCHAR}|\s|[,>+*]|[:#.]#{NMSTART})+(?=[{])/i
124
- end
125
- end
126
- end
@@ -1,11 +0,0 @@
1
- module Sass
2
- module SCSS
3
- # A subclass of {Parser} that parses code in Sass documents
4
- # using some SCSS constructs.
5
- # This is necessary because SassScript in Sass supports `!`-style variables,
6
- # whereas in SCSS it doesn't.
7
- class SassParser < Parser
8
- @sass_script_parser = Sass::Script::Parser
9
- end
10
- end
11
- end
@@ -1,15 +0,0 @@
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::IDENT})/)
12
- end
13
- end
14
- end
15
- end
@@ -1,25 +0,0 @@
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
@@ -1,40 +0,0 @@
1
- module Sass
2
- module SCSS
3
- # A parser for a static SCSS tree.
4
- # Parses with SCSS extensions, like nested rules and parent selectors,
5
- # but without dynamic SassScript.
6
- # This is useful for e.g. \{#parse\_selector parsing selectors}
7
- # after resolving the interpolation.
8
- class StaticParser < Parser
9
- # Parses the text as a selector.
10
- #
11
- # @param filename [String, nil] The file in which the selector appears,
12
- # or nil if there is no such file.
13
- # Used for error reporting.
14
- # @return [Selector::CommaSequence] The parsed selector
15
- # @raise [Sass::SyntaxError] if there's a syntax error in the selector
16
- def parse_selector(filename)
17
- init_scanner!
18
- seq = expr!(:selector_comma_sequence)
19
- expected("selector") unless @scanner.eos?
20
- seq.line = @line
21
- seq.filename = filename
22
- seq
23
- end
24
-
25
- private
26
-
27
- def variable; nil; end
28
- def script_value; nil; end
29
- def interpolation; nil; end
30
- def interp_string; s = tok(STRING) and [s]; end
31
- def interp_ident(ident = IDENT); s = tok(ident) and [s]; end
32
- def use_css_import?; true; end
33
-
34
- def special_directive(name)
35
- return unless %w[media import charset].include?(name)
36
- super
37
- end
38
- end
39
- end
40
- end
@@ -1,361 +0,0 @@
1
- require 'sass/selector/simple'
2
- require 'sass/selector/abstract_sequence'
3
- require 'sass/selector/comma_sequence'
4
- require 'sass/selector/sequence'
5
- require 'sass/selector/simple_sequence'
6
-
7
- module Sass
8
- # A namespace for nodes in the parse tree for selectors.
9
- #
10
- # {CommaSequence} is the toplevel seelctor,
11
- # representing a comma-separated sequence of {Sequence}s,
12
- # such as `foo bar, baz bang`.
13
- # {Sequence} is the next level,
14
- # representing {SimpleSequence}s separated by combinators (e.g. descendant or child),
15
- # such as `foo bar` or `foo > bar baz`.
16
- # {SimpleSequence} is a sequence of selectors that all apply to a single element,
17
- # such as `foo.bar[attr=val]`.
18
- # Finally, {Simple} is the superclass of the simplest selectors,
19
- # such as `.foo` or `#bar`.
20
- module Selector
21
- # A parent-referencing selector (`&` in Sass).
22
- # The function of this is to be replaced by the parent selector
23
- # in the nested hierarchy.
24
- class Parent < Simple
25
- # @see Selector#to_a
26
- def to_a
27
- ["&"]
28
- end
29
-
30
- # Always raises an exception.
31
- #
32
- # @raise [Sass::SyntaxError] Parent selectors should be resolved before unification
33
- # @see Selector#unify
34
- def unify(sels)
35
- raise Sass::SyntaxError.new("[BUG] Cannot unify parent selectors.")
36
- end
37
- end
38
-
39
- # A class selector (e.g. `.foo`).
40
- class Class < Simple
41
- # The class name.
42
- #
43
- # @return [Array<String, Sass::Script::Node>]
44
- attr_reader :name
45
-
46
- # @param name [Array<String, Sass::Script::Node>] The class name
47
- def initialize(name)
48
- @name = name
49
- end
50
-
51
- # @see Selector#to_a
52
- def to_a
53
- [".", *@name]
54
- end
55
- end
56
-
57
- # An id selector (e.g. `#foo`).
58
- class Id < Simple
59
- # The id name.
60
- #
61
- # @return [Array<String, Sass::Script::Node>]
62
- attr_reader :name
63
-
64
- # @param name [Array<String, Sass::Script::Node>] The id name
65
- def initialize(name)
66
- @name = name
67
- end
68
-
69
- # @see Selector#to_a
70
- def to_a
71
- ["#", *@name]
72
- end
73
-
74
- # Returns `nil` if `sels` contains an {Id} selector
75
- # with a different name than this one.
76
- #
77
- # @see Selector#unify
78
- def unify(sels)
79
- return if sels.any? {|sel2| sel2.is_a?(Id) && self.name != sel2.name}
80
- super
81
- end
82
- end
83
-
84
- # A universal selector (`*` in CSS).
85
- class Universal < Simple
86
- # The selector namespace.
87
- # `nil` means the default namespace,
88
- # `[""]` means no namespace,
89
- # `["*"]` means any namespace.
90
- #
91
- # @return [Array<String, Sass::Script::Node>, nil]
92
- attr_reader :namespace
93
-
94
- # @param namespace [Array<String, Sass::Script::Node>, nil] See \{#namespace}
95
- def initialize(namespace)
96
- @namespace = namespace
97
- end
98
-
99
- # @see Selector#to_a
100
- def to_a
101
- @namespace ? @namespace + ["|*"] : ["*"]
102
- end
103
-
104
- # Unification of a universal selector is somewhat complicated,
105
- # especially when a namespace is specified.
106
- # If there is no namespace specified
107
- # or any namespace is specified (namespace `"*"`),
108
- # then `sel` is returned without change
109
- # (unless it's empty, in which case `"*"` is required).
110
- #
111
- # If a namespace is specified
112
- # but `sel` does not specify a namespace,
113
- # then the given namespace is applied to `sel`,
114
- # either by adding this {Universal} selector
115
- # or applying this namespace to an existing {Element} selector.
116
- #
117
- # If both this selector *and* `sel` specify namespaces,
118
- # those namespaces are unified via {Simple#unify_namespaces}
119
- # and the unified namespace is used, if possible.
120
- #
121
- # @todo There are lots of cases that this documentation specifies;
122
- # make sure we thoroughly test **all of them**.
123
- # @todo Keep track of whether a default namespace has been declared
124
- # and handle namespace-unspecified selectors accordingly.
125
- # @todo If any branch of a CommaSequence ends up being just `"*"`,
126
- # then all other branches should be eliminated
127
- #
128
- # @see Selector#unify
129
- def unify(sels)
130
- name =
131
- case sels.first
132
- when Universal; :universal
133
- when Element; sels.first.name
134
- else
135
- return [self] + sels unless namespace.nil? || namespace == ['*']
136
- return sels unless sels.empty?
137
- return [self]
138
- end
139
-
140
- ns, accept = unify_namespaces(namespace, sels.first.namespace)
141
- return unless accept
142
- [name == :universal ? Universal.new(ns) : Element.new(name, ns)] + sels[1..-1]
143
- end
144
- end
145
-
146
- # An element selector (e.g. `h1`).
147
- class Element < Simple
148
- # The element name.
149
- #
150
- # @return [Array<String, Sass::Script::Node>]
151
- attr_reader :name
152
-
153
- # The selector namespace.
154
- # `nil` means the default namespace,
155
- # `[""]` means no namespace,
156
- # `["*"]` means any namespace.
157
- #
158
- # @return [Array<String, Sass::Script::Node>, nil]
159
- attr_reader :namespace
160
-
161
- # @param name [Array<String, Sass::Script::Node>] The element name
162
- # @param namespace [Array<String, Sass::Script::Node>, nil] See \{#namespace}
163
- def initialize(name, namespace)
164
- @name = name
165
- @namespace = namespace
166
- end
167
-
168
- # @see Selector#to_a
169
- def to_a
170
- @namespace ? @namespace + ["|"] + @name : @name
171
- end
172
-
173
- # Unification of an element selector is somewhat complicated,
174
- # especially when a namespace is specified.
175
- # First, if `sel` contains another {Element} with a different \{#name},
176
- # then the selectors can't be unified and `nil` is returned.
177
- #
178
- # Otherwise, if `sel` doesn't specify a namespace,
179
- # or it specifies any namespace (via `"*"`),
180
- # then it's returned with this element selector
181
- # (e.g. `.foo` becomes `a.foo` or `svg|a.foo`).
182
- # Similarly, if this selector doesn't specify a namespace,
183
- # the namespace from `sel` is used.
184
- #
185
- # If both this selector *and* `sel` specify namespaces,
186
- # those namespaces are unified via {Simple#unify_namespaces}
187
- # and the unified namespace is used, if possible.
188
- #
189
- # @todo There are lots of cases that this documentation specifies;
190
- # make sure we thoroughly test **all of them**.
191
- # @todo Keep track of whether a default namespace has been declared
192
- # and handle namespace-unspecified selectors accordingly.
193
- #
194
- # @see Selector#unify
195
- def unify(sels)
196
- case sels.first
197
- when Universal;
198
- when Element; return unless name == sels.first.name
199
- else return [self] + sels
200
- end
201
-
202
- ns, accept = unify_namespaces(namespace, sels.first.namespace)
203
- return unless accept
204
- [Element.new(name, ns)] + sels[1..-1]
205
- end
206
- end
207
-
208
- # Selector interpolation (`#{}` in Sass).
209
- class Interpolation < Simple
210
- # The script to run.
211
- #
212
- # @return [Sass::Script::Node]
213
- attr_reader :script
214
-
215
- # @param script [Sass::Script::Node] The script to run
216
- def initialize(script)
217
- @script = script
218
- end
219
-
220
- # @see Selector#to_a
221
- def to_a
222
- [@script]
223
- end
224
-
225
- # Always raises an exception.
226
- #
227
- # @raise [Sass::SyntaxError] Interpolation selectors should be resolved before unification
228
- # @see Selector#unify
229
- def unify(sels)
230
- raise Sass::SyntaxError.new("[BUG] Cannot unify interpolation selectors.")
231
- end
232
- end
233
-
234
- # An attribute selector (e.g. `[href^="http://"]`).
235
- class Attribute < Simple
236
- # The attribute name.
237
- #
238
- # @return [Array<String, Sass::Script::Node>]
239
- attr_reader :name
240
-
241
- # The attribute namespace.
242
- # `nil` means the default namespace,
243
- # `[""]` means no namespace,
244
- # `["*"]` means any namespace.
245
- #
246
- # @return [Array<String, Sass::Script::Node>, nil]
247
- attr_reader :namespace
248
-
249
- # The matching operator, e.g. `"="` or `"^="`.
250
- #
251
- # @return [String]
252
- attr_reader :operator
253
-
254
- # The right-hand side of the operator.
255
- #
256
- # @return [Array<String, Sass::Script::Node>]
257
- attr_reader :value
258
-
259
- # @param name [Array<String, Sass::Script::Node>] The attribute name
260
- # @param namespace [Array<String, Sass::Script::Node>, nil] See \{#namespace}
261
- # @param operator [String] The matching operator, e.g. `"="` or `"^="`
262
- # @param value [Array<String, Sass::Script::Node>] See \{#value}
263
- def initialize(name, namespace, operator, value)
264
- @name = name
265
- @namespace = namespace
266
- @operator = operator
267
- @value = value
268
- end
269
-
270
- # @see Selector#to_a
271
- def to_a
272
- res = ["["]
273
- res.concat(@namespace) << "|" if @namespace
274
- res.concat @name
275
- (res << @operator).concat @value if @value
276
- res << "]"
277
- end
278
- end
279
-
280
- # A pseudoclass (e.g. `:visited`) or pseudoelement (e.g. `::first-line`) selector.
281
- # It can have arguments (e.g. `:nth-child(2n+1)`).
282
- class Pseudo < Simple
283
- # The type of the selector.
284
- # `:class` if this is a pseudoclass selector,
285
- # `:element` if it's a pseudoelement.
286
- #
287
- # @return [Symbol]
288
- attr_reader :type
289
-
290
- # The name of the selector.
291
- #
292
- # @return [Array<String, Sass::Script::Node>]
293
- attr_reader :name
294
-
295
- # The argument to the selector,
296
- # or `nil` if no argument was given.
297
- #
298
- # This may include SassScript nodes that will be run during resolution.
299
- # Note that this should not include SassScript nodes
300
- # after resolution has taken place.
301
- #
302
- # @return [Array<String, Sass::Script::Node>, nil]
303
- attr_reader :arg
304
-
305
- # @param type [Symbol] See \{#type}
306
- # @param name [Array<String, Sass::Script::Node>] The name of the selector
307
- # @param arg [nil, Array<String, Sass::Script::Node>] The argument to the selector,
308
- # or nil if no argument was given
309
- def initialize(type, name, arg)
310
- @type = type
311
- @name = name
312
- @arg = arg
313
- end
314
-
315
- # @see Selector#to_a
316
- def to_a
317
- res = [@type == :class ? ":" : "::"] + @name
318
- (res << "(").concat(Haml::Util.strip_string_array(@arg)) << ")" if @arg
319
- res
320
- end
321
-
322
- # Returns `nil` if this is a pseudoclass selector
323
- # and `sels` contains a pseudoclass selector different than this one.
324
- #
325
- # @see Selector#unify
326
- def unify(sels)
327
- return if type == :element && sels.any? do |sel|
328
- sel.is_a?(Pseudo) && sel.type == :element &&
329
- (sel.name != self.name || sel.arg != self.arg)
330
- end
331
- super
332
- end
333
- end
334
-
335
- # A pseudoclass selector whose argument is itself a selector
336
- # (e.g. `:not(.foo)` or `:-moz-all(.foo, .bar)`).
337
- class SelectorPseudoClass < Simple
338
- # The name of the pseudoclass.
339
- #
340
- # @return [String]
341
- attr_reader :name
342
-
343
- # The selector argument.
344
- #
345
- # @return [Selector::Sequence]
346
- attr_reader :selector
347
-
348
- # @param [String] The name of the pseudoclass
349
- # @param [Selector::Sequence] The selector argument
350
- def initialize(name, selector)
351
- @name = name
352
- @selector = selector
353
- end
354
-
355
- # @see Selector#to_a
356
- def to_a
357
- [":", @name, "("] + @selector.to_a + [")"]
358
- end
359
- end
360
- end
361
- end