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.
- data/.yardopts +1 -1
- data/CONTRIBUTING +0 -1
- data/EDGE_GEM_VERSION +1 -0
- data/MIT-LICENSE +1 -1
- data/README.md +10 -175
- data/Rakefile +56 -84
- data/VERSION +1 -1
- data/VERSION_NAME +1 -1
- data/init.rb +1 -1
- data/lib/haml.rb +14 -12
- data/lib/haml/engine.rb +1 -1
- data/lib/haml/exec.rb +19 -316
- data/lib/haml/helpers/action_view_extensions.rb +1 -1
- data/lib/haml/html.rb +69 -76
- data/lib/haml/precompiler.rb +34 -41
- data/lib/haml/railtie.rb +4 -6
- data/lib/haml/template/plugin.rb +6 -16
- data/lib/haml/util.rb +91 -107
- data/lib/haml/version.rb +7 -0
- data/test/benchmark.rb +2 -9
- data/test/haml/engine_test.rb +195 -92
- data/test/haml/html2haml/erb_tests.rb +0 -14
- data/test/haml/util_test.rb +32 -0
- data/test/test_helper.rb +0 -39
- metadata +96 -324
- data/bin/css2sass +0 -13
- data/bin/sass +0 -8
- data/bin/sass-convert +0 -7
- data/extra/haml-mode.el +0 -753
- data/extra/sass-mode.el +0 -207
- data/lib/haml/util/subset_map.rb +0 -101
- data/lib/sass.rb +0 -29
- data/lib/sass/callbacks.rb +0 -52
- data/lib/sass/css.rb +0 -294
- data/lib/sass/engine.rb +0 -720
- data/lib/sass/environment.rb +0 -143
- data/lib/sass/error.rb +0 -198
- data/lib/sass/files.rb +0 -160
- data/lib/sass/less.rb +0 -382
- data/lib/sass/plugin.rb +0 -279
- data/lib/sass/plugin/configuration.rb +0 -221
- data/lib/sass/plugin/generic.rb +0 -15
- data/lib/sass/plugin/merb.rb +0 -37
- data/lib/sass/plugin/rack.rb +0 -47
- data/lib/sass/plugin/rails.rb +0 -32
- data/lib/sass/plugin/staleness_checker.rb +0 -123
- data/lib/sass/repl.rb +0 -58
- data/lib/sass/script.rb +0 -63
- data/lib/sass/script/bool.rb +0 -18
- data/lib/sass/script/color.rb +0 -491
- data/lib/sass/script/css_lexer.rb +0 -29
- data/lib/sass/script/css_parser.rb +0 -31
- data/lib/sass/script/funcall.rb +0 -77
- data/lib/sass/script/functions.rb +0 -861
- data/lib/sass/script/interpolation.rb +0 -70
- data/lib/sass/script/lexer.rb +0 -337
- data/lib/sass/script/literal.rb +0 -236
- data/lib/sass/script/node.rb +0 -112
- data/lib/sass/script/number.rb +0 -423
- data/lib/sass/script/operation.rb +0 -95
- data/lib/sass/script/parser.rb +0 -401
- data/lib/sass/script/string.rb +0 -67
- data/lib/sass/script/string_interpolation.rb +0 -93
- data/lib/sass/script/unary_operation.rb +0 -57
- data/lib/sass/script/variable.rb +0 -48
- data/lib/sass/scss.rb +0 -17
- data/lib/sass/scss/css_parser.rb +0 -46
- data/lib/sass/scss/parser.rb +0 -855
- data/lib/sass/scss/rx.rb +0 -126
- data/lib/sass/scss/sass_parser.rb +0 -11
- data/lib/sass/scss/script_lexer.rb +0 -15
- data/lib/sass/scss/script_parser.rb +0 -25
- data/lib/sass/scss/static_parser.rb +0 -40
- data/lib/sass/selector.rb +0 -361
- data/lib/sass/selector/abstract_sequence.rb +0 -62
- data/lib/sass/selector/comma_sequence.rb +0 -82
- data/lib/sass/selector/sequence.rb +0 -237
- data/lib/sass/selector/simple.rb +0 -113
- data/lib/sass/selector/simple_sequence.rb +0 -136
- data/lib/sass/tree/charset_node.rb +0 -37
- data/lib/sass/tree/comment_node.rb +0 -128
- data/lib/sass/tree/debug_node.rb +0 -36
- data/lib/sass/tree/directive_node.rb +0 -75
- data/lib/sass/tree/extend_node.rb +0 -65
- data/lib/sass/tree/for_node.rb +0 -55
- data/lib/sass/tree/if_node.rb +0 -69
- data/lib/sass/tree/import_node.rb +0 -102
- data/lib/sass/tree/mixin_def_node.rb +0 -48
- data/lib/sass/tree/mixin_node.rb +0 -111
- data/lib/sass/tree/node.rb +0 -464
- data/lib/sass/tree/prop_node.rb +0 -220
- data/lib/sass/tree/root_node.rb +0 -163
- data/lib/sass/tree/rule_node.rb +0 -261
- data/lib/sass/tree/variable_node.rb +0 -39
- data/lib/sass/tree/warn_node.rb +0 -42
- data/lib/sass/tree/while_node.rb +0 -36
- data/test/haml/util/subset_map_test.rb +0 -91
- data/test/sass/callbacks_test.rb +0 -61
- data/test/sass/conversion_test.rb +0 -1218
- data/test/sass/css2sass_test.rb +0 -364
- data/test/sass/data/hsl-rgb.txt +0 -319
- data/test/sass/engine_test.rb +0 -2267
- data/test/sass/extend_test.rb +0 -1348
- data/test/sass/functions_test.rb +0 -556
- data/test/sass/less_conversion_test.rb +0 -653
- data/test/sass/more_results/more1.css +0 -9
- data/test/sass/more_results/more1_with_line_comments.css +0 -26
- data/test/sass/more_results/more_import.css +0 -29
- data/test/sass/more_templates/_more_partial.sass +0 -2
- data/test/sass/more_templates/more1.sass +0 -23
- data/test/sass/more_templates/more_import.sass +0 -11
- data/test/sass/plugin_test.rb +0 -433
- data/test/sass/results/alt.css +0 -4
- data/test/sass/results/basic.css +0 -9
- data/test/sass/results/compact.css +0 -5
- data/test/sass/results/complex.css +0 -86
- data/test/sass/results/compressed.css +0 -1
- data/test/sass/results/expanded.css +0 -19
- data/test/sass/results/import.css +0 -31
- data/test/sass/results/import_charset.css +0 -4
- data/test/sass/results/import_charset_1_8.css +0 -4
- data/test/sass/results/import_charset_ibm866.css +0 -4
- data/test/sass/results/line_numbers.css +0 -49
- data/test/sass/results/mixins.css +0 -95
- data/test/sass/results/multiline.css +0 -24
- data/test/sass/results/nested.css +0 -22
- data/test/sass/results/options.css +0 -1
- data/test/sass/results/parent_ref.css +0 -13
- data/test/sass/results/script.css +0 -16
- data/test/sass/results/scss_import.css +0 -31
- data/test/sass/results/scss_importee.css +0 -2
- data/test/sass/results/subdir/nested_subdir/nested_subdir.css +0 -1
- data/test/sass/results/subdir/subdir.css +0 -3
- data/test/sass/results/units.css +0 -11
- data/test/sass/results/warn.css +0 -0
- data/test/sass/results/warn_imported.css +0 -0
- data/test/sass/script_conversion_test.rb +0 -314
- data/test/sass/script_test.rb +0 -470
- data/test/sass/scss/css_test.rb +0 -916
- data/test/sass/scss/rx_test.rb +0 -156
- data/test/sass/scss/scss_test.rb +0 -1122
- data/test/sass/scss/test_helper.rb +0 -37
- data/test/sass/templates/_imported_charset_ibm866.sass +0 -4
- data/test/sass/templates/_imported_charset_utf8.sass +0 -4
- data/test/sass/templates/_partial.sass +0 -2
- data/test/sass/templates/alt.sass +0 -16
- data/test/sass/templates/basic.sass +0 -23
- data/test/sass/templates/bork1.sass +0 -2
- data/test/sass/templates/bork2.sass +0 -2
- data/test/sass/templates/bork3.sass +0 -2
- data/test/sass/templates/bork4.sass +0 -2
- data/test/sass/templates/compact.sass +0 -17
- data/test/sass/templates/complex.sass +0 -305
- data/test/sass/templates/compressed.sass +0 -15
- data/test/sass/templates/expanded.sass +0 -17
- data/test/sass/templates/import.sass +0 -12
- data/test/sass/templates/import_charset.sass +0 -7
- data/test/sass/templates/import_charset_1_8.sass +0 -4
- data/test/sass/templates/import_charset_ibm866.sass +0 -9
- data/test/sass/templates/importee.less +0 -2
- data/test/sass/templates/importee.sass +0 -19
- data/test/sass/templates/line_numbers.sass +0 -13
- data/test/sass/templates/mixin_bork.sass +0 -5
- data/test/sass/templates/mixins.sass +0 -76
- data/test/sass/templates/multiline.sass +0 -20
- data/test/sass/templates/nested.sass +0 -25
- data/test/sass/templates/nested_bork1.sass +0 -2
- data/test/sass/templates/nested_bork2.sass +0 -2
- data/test/sass/templates/nested_bork3.sass +0 -2
- data/test/sass/templates/nested_bork4.sass +0 -2
- data/test/sass/templates/nested_mixin_bork.sass +0 -6
- data/test/sass/templates/options.sass +0 -2
- data/test/sass/templates/parent_ref.sass +0 -25
- data/test/sass/templates/script.sass +0 -101
- data/test/sass/templates/scss_import.scss +0 -11
- data/test/sass/templates/scss_importee.scss +0 -1
- data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +0 -2
- data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +0 -3
- data/test/sass/templates/subdir/subdir.sass +0 -6
- data/test/sass/templates/units.sass +0 -11
- data/test/sass/templates/warn.sass +0 -3
- data/test/sass/templates/warn_imported.sass +0 -4
- data/vendor/fssm/LICENSE +0 -20
- data/vendor/fssm/README.markdown +0 -55
- data/vendor/fssm/Rakefile +0 -59
- data/vendor/fssm/VERSION.yml +0 -5
- data/vendor/fssm/example.rb +0 -9
- data/vendor/fssm/fssm.gemspec +0 -77
- data/vendor/fssm/lib/fssm.rb +0 -33
- data/vendor/fssm/lib/fssm/backends/fsevents.rb +0 -36
- data/vendor/fssm/lib/fssm/backends/inotify.rb +0 -26
- data/vendor/fssm/lib/fssm/backends/polling.rb +0 -25
- data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +0 -131
- data/vendor/fssm/lib/fssm/monitor.rb +0 -26
- data/vendor/fssm/lib/fssm/path.rb +0 -91
- data/vendor/fssm/lib/fssm/pathname.rb +0 -502
- data/vendor/fssm/lib/fssm/state/directory.rb +0 -57
- data/vendor/fssm/lib/fssm/state/file.rb +0 -24
- data/vendor/fssm/lib/fssm/support.rb +0 -63
- data/vendor/fssm/lib/fssm/tree.rb +0 -176
- data/vendor/fssm/profile/prof-cache.rb +0 -40
- data/vendor/fssm/profile/prof-fssm-pathname.html +0 -1231
- data/vendor/fssm/profile/prof-pathname.rb +0 -68
- data/vendor/fssm/profile/prof-plain-pathname.html +0 -988
- data/vendor/fssm/profile/prof.html +0 -2379
- data/vendor/fssm/spec/path_spec.rb +0 -75
- data/vendor/fssm/spec/root/duck/quack.txt +0 -0
- data/vendor/fssm/spec/root/file.css +0 -0
- data/vendor/fssm/spec/root/file.rb +0 -0
- data/vendor/fssm/spec/root/file.yml +0 -0
- data/vendor/fssm/spec/root/moo/cow.txt +0 -0
- data/vendor/fssm/spec/spec_helper.rb +0 -14
data/lib/sass/scss/rx.rb
DELETED
@@ -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
|
data/lib/sass/selector.rb
DELETED
@@ -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
|