sass 3.3.0 → 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.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +58 -50
- data/Rakefile +1 -4
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/VERSION_NAME +1 -1
- data/bin/sass +1 -1
- data/bin/scss +1 -1
- data/lib/sass/cache_stores/filesystem.rb +6 -2
- data/lib/sass/css.rb +1 -3
- data/lib/sass/engine.rb +37 -46
- data/lib/sass/environment.rb +13 -17
- data/lib/sass/error.rb +6 -9
- data/lib/sass/exec/base.rb +187 -0
- data/lib/sass/exec/sass_convert.rb +264 -0
- data/lib/sass/exec/sass_scss.rb +424 -0
- data/lib/sass/exec.rb +5 -771
- data/lib/sass/features.rb +7 -0
- data/lib/sass/importers/base.rb +7 -2
- data/lib/sass/importers/filesystem.rb +9 -25
- data/lib/sass/importers.rb +0 -1
- data/lib/sass/media.rb +1 -4
- data/lib/sass/plugin/compiler.rb +200 -83
- data/lib/sass/plugin/staleness_checker.rb +1 -1
- data/lib/sass/plugin.rb +3 -3
- data/lib/sass/script/css_lexer.rb +1 -1
- data/lib/sass/script/functions.rb +622 -268
- data/lib/sass/script/lexer.rb +99 -34
- data/lib/sass/script/parser.rb +24 -23
- data/lib/sass/script/tree/funcall.rb +1 -1
- data/lib/sass/script/tree/interpolation.rb +20 -2
- data/lib/sass/script/tree/selector.rb +26 -0
- data/lib/sass/script/tree/string_interpolation.rb +1 -1
- data/lib/sass/script/tree.rb +1 -0
- data/lib/sass/script/value/base.rb +7 -5
- data/lib/sass/script/value/bool.rb +0 -5
- data/lib/sass/script/value/color.rb +39 -21
- data/lib/sass/script/value/helpers.rb +107 -0
- data/lib/sass/script/value/list.rb +0 -15
- data/lib/sass/script/value/null.rb +0 -5
- data/lib/sass/script/value/number.rb +62 -14
- data/lib/sass/script/value/string.rb +59 -11
- data/lib/sass/script/value.rb +0 -1
- data/lib/sass/scss/css_parser.rb +8 -2
- data/lib/sass/scss/parser.rb +190 -328
- data/lib/sass/scss/rx.rb +15 -6
- data/lib/sass/scss/static_parser.rb +298 -1
- data/lib/sass/selector/abstract_sequence.rb +28 -13
- data/lib/sass/selector/comma_sequence.rb +92 -13
- data/lib/sass/selector/pseudo.rb +256 -0
- data/lib/sass/selector/sequence.rb +94 -24
- data/lib/sass/selector/simple.rb +14 -25
- data/lib/sass/selector/simple_sequence.rb +97 -33
- data/lib/sass/selector.rb +57 -194
- data/lib/sass/shared.rb +1 -1
- data/lib/sass/source/map.rb +26 -12
- data/lib/sass/stack.rb +0 -6
- data/lib/sass/supports.rb +2 -3
- data/lib/sass/tree/at_root_node.rb +1 -0
- data/lib/sass/tree/charset_node.rb +1 -1
- data/lib/sass/tree/directive_node.rb +8 -2
- data/lib/sass/tree/error_node.rb +18 -0
- data/lib/sass/tree/extend_node.rb +1 -1
- data/lib/sass/tree/function_node.rb +4 -0
- data/lib/sass/tree/keyframe_rule_node.rb +15 -0
- data/lib/sass/tree/prop_node.rb +1 -1
- data/lib/sass/tree/rule_node.rb +12 -7
- data/lib/sass/tree/visitors/check_nesting.rb +38 -10
- data/lib/sass/tree/visitors/convert.rb +16 -18
- data/lib/sass/tree/visitors/cssize.rb +29 -29
- data/lib/sass/tree/visitors/deep_copy.rb +5 -0
- data/lib/sass/tree/visitors/perform.rb +45 -33
- data/lib/sass/tree/visitors/set_options.rb +14 -0
- data/lib/sass/tree/visitors/to_css.rb +15 -14
- data/lib/sass/util/subset_map.rb +1 -1
- data/lib/sass/util.rb +222 -99
- data/lib/sass/version.rb +5 -5
- data/lib/sass.rb +0 -5
- data/test/sass/cache_test.rb +62 -20
- data/test/sass/callbacks_test.rb +1 -1
- data/test/sass/compiler_test.rb +19 -10
- data/test/sass/conversion_test.rb +58 -1
- data/test/sass/css2sass_test.rb +23 -4
- data/test/sass/encoding_test.rb +219 -0
- data/test/sass/engine_test.rb +136 -199
- data/test/sass/exec_test.rb +2 -2
- data/test/sass/extend_test.rb +236 -19
- data/test/sass/functions_test.rb +295 -253
- data/test/sass/importer_test.rb +31 -21
- data/test/sass/logger_test.rb +1 -1
- data/test/sass/more_results/more_import.css +1 -1
- data/test/sass/plugin_test.rb +14 -13
- data/test/sass/results/compact.css +1 -1
- data/test/sass/results/complex.css +4 -4
- data/test/sass/results/expanded.css +1 -1
- data/test/sass/results/import.css +1 -1
- data/test/sass/results/import_charset_ibm866.css +2 -2
- data/test/sass/results/mixins.css +17 -17
- data/test/sass/results/nested.css +1 -1
- data/test/sass/results/parent_ref.css +2 -2
- data/test/sass/results/script.css +3 -3
- data/test/sass/results/scss_import.css +1 -1
- data/test/sass/script_conversion_test.rb +10 -7
- data/test/sass/script_test.rb +288 -74
- data/test/sass/scss/css_test.rb +141 -24
- data/test/sass/scss/rx_test.rb +4 -4
- data/test/sass/scss/scss_test.rb +457 -18
- data/test/sass/source_map_test.rb +115 -25
- data/test/sass/superselector_test.rb +191 -0
- data/test/sass/templates/scss_import.scss +2 -1
- data/test/sass/test_helper.rb +1 -1
- data/test/sass/util/multibyte_string_scanner_test.rb +1 -1
- data/test/sass/util/normalized_map_test.rb +1 -1
- data/test/sass/util/subset_map_test.rb +2 -2
- data/test/sass/util_test.rb +31 -1
- data/test/sass/value_helpers_test.rb +5 -7
- data/test/test_helper.rb +2 -2
- data/vendor/listen/CHANGELOG.md +1 -228
- data/vendor/listen/Gemfile +5 -15
- data/vendor/listen/README.md +111 -77
- data/vendor/listen/Rakefile +0 -42
- data/vendor/listen/lib/listen/adapter.rb +195 -82
- data/vendor/listen/lib/listen/adapters/bsd.rb +27 -64
- data/vendor/listen/lib/listen/adapters/darwin.rb +21 -58
- data/vendor/listen/lib/listen/adapters/linux.rb +23 -55
- data/vendor/listen/lib/listen/adapters/polling.rb +25 -34
- data/vendor/listen/lib/listen/adapters/windows.rb +50 -46
- data/vendor/listen/lib/listen/directory_record.rb +96 -61
- data/vendor/listen/lib/listen/listener.rb +135 -37
- data/vendor/listen/lib/listen/turnstile.rb +9 -5
- data/vendor/listen/lib/listen/version.rb +1 -1
- data/vendor/listen/lib/listen.rb +33 -19
- data/vendor/listen/listen.gemspec +6 -0
- data/vendor/listen/spec/listen/adapter_spec.rb +43 -77
- data/vendor/listen/spec/listen/adapters/polling_spec.rb +8 -8
- data/vendor/listen/spec/listen/directory_record_spec.rb +81 -56
- data/vendor/listen/spec/listen/listener_spec.rb +128 -39
- data/vendor/listen/spec/listen_spec.rb +15 -21
- data/vendor/listen/spec/spec_helper.rb +4 -0
- data/vendor/listen/spec/support/adapter_helper.rb +52 -15
- data/vendor/listen/spec/support/directory_record_helper.rb +7 -5
- data/vendor/listen/spec/support/listeners_helper.rb +30 -7
- metadata +25 -22
- data/ext/mkrf_conf.rb +0 -27
- data/lib/sass/importers/deprecated_path.rb +0 -51
- data/lib/sass/script/value/deprecated_false.rb +0 -55
- data/vendor/listen/lib/listen/dependency_manager.rb +0 -126
- data/vendor/listen/lib/listen/multi_listener.rb +0 -143
- data/vendor/listen/spec/listen/dependency_manager_spec.rb +0 -107
- data/vendor/listen/spec/listen/multi_listener_spec.rb +0 -174
@@ -43,11 +43,16 @@ module Sass
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def pseudo_elements
|
46
|
-
@pseudo_elements ||=
|
47
|
-
select {|sel| sel.is_a?(Pseudo) && sel.type == :element}
|
46
|
+
@pseudo_elements ||= members.select {|sel| sel.is_a?(Pseudo) && sel.type == :element}
|
48
47
|
end
|
49
48
|
|
50
|
-
|
49
|
+
def selector_pseudo_classes
|
50
|
+
@selector_pseudo_classes ||= members.
|
51
|
+
select {|sel| sel.is_a?(Pseudo) && sel.type == :class && sel.selector}.
|
52
|
+
group_by {|sel| sel.normalized_name}
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns the non-base, non-pseudo-element selectors in this sequence.
|
51
56
|
#
|
52
57
|
# @return [Set<Simple>]
|
53
58
|
def rest
|
@@ -86,18 +91,18 @@ module Sass
|
|
86
91
|
return CommaSequence.new([Sequence.new([self])])
|
87
92
|
end
|
88
93
|
|
89
|
-
return super_cseq if @members.size == 1 && parent.suffix.
|
94
|
+
return super_cseq if @members.size == 1 && parent.suffix.nil?
|
90
95
|
|
91
96
|
CommaSequence.new(super_cseq.members.map do |super_seq|
|
92
97
|
members = super_seq.members.dup
|
93
98
|
newline = members.pop if members.last == "\n"
|
94
99
|
unless members.last.is_a?(SimpleSequence)
|
95
100
|
raise Sass::SyntaxError.new("Invalid parent selector for \"#{self}\": \"" +
|
96
|
-
super_seq.
|
101
|
+
super_seq.to_s + '"')
|
97
102
|
end
|
98
103
|
|
99
104
|
parent_sub = members.last.members
|
100
|
-
unless parent.suffix.
|
105
|
+
unless parent.suffix.nil?
|
101
106
|
parent_sub = parent_sub.dup
|
102
107
|
parent_sub[-1] = parent_sub.last.dup
|
103
108
|
case parent_sub.last
|
@@ -108,17 +113,17 @@ module Sass
|
|
108
113
|
parent_sub.last.name + parent.suffix,
|
109
114
|
parent_sub.last.namespace)
|
110
115
|
when Sass::Selector::Pseudo
|
111
|
-
if parent_sub.last.arg
|
116
|
+
if parent_sub.last.arg || parent_sub.last.selector
|
112
117
|
raise Sass::SyntaxError.new("Invalid parent selector for \"#{self}\": \"" +
|
113
|
-
super_seq.
|
118
|
+
super_seq.to_s + '"')
|
114
119
|
end
|
115
|
-
parent_sub[-1] =
|
120
|
+
parent_sub[-1] = Sass::Selector::Pseudo.new(
|
116
121
|
parent_sub.last.type,
|
117
122
|
parent_sub.last.name + parent.suffix,
|
118
|
-
nil)
|
123
|
+
nil, nil)
|
119
124
|
else
|
120
125
|
raise Sass::SyntaxError.new("Invalid parent selector for \"#{self}\": \"" +
|
121
|
-
super_seq.
|
126
|
+
super_seq.to_s + '"')
|
122
127
|
end
|
123
128
|
end
|
124
129
|
|
@@ -128,19 +133,38 @@ module Sass
|
|
128
133
|
end)
|
129
134
|
end
|
130
135
|
|
131
|
-
# Non-
|
136
|
+
# Non-destructively extends this selector with the extensions specified in a hash
|
132
137
|
# (which should come from {Sass::Tree::Visitors::Cssize}).
|
133
138
|
#
|
134
|
-
# @overload def do_extend(extends, parent_directives)
|
135
139
|
# @param extends [{Selector::Simple =>
|
136
140
|
# Sass::Tree::Visitors::Cssize::Extend}]
|
137
141
|
# The extensions to perform on this selector
|
138
142
|
# @param parent_directives [Array<Sass::Tree::DirectiveNode>]
|
139
143
|
# The directives containing this selector.
|
144
|
+
# @param seen [Set<Array<Selector::Simple>>]
|
145
|
+
# The set of simple sequences that are currently being replaced.
|
146
|
+
# @param original [Boolean]
|
147
|
+
# Whether this is the original selector being extended, as opposed to
|
148
|
+
# the result of a previous extension that's being re-extended.
|
140
149
|
# @return [Array<Sequence>] A list of selectors generated
|
141
150
|
# by extending this selector with `extends`.
|
142
151
|
# @see CommaSequence#do_extend
|
143
|
-
def do_extend(extends, parent_directives, seen
|
152
|
+
def do_extend(extends, parent_directives, replace, seen)
|
153
|
+
seen_with_pseudo_selectors = seen.dup
|
154
|
+
|
155
|
+
modified_original = false
|
156
|
+
members = Sass::Util.enum_with_index(self.members).map do |sel, i|
|
157
|
+
next sel unless sel.is_a?(Pseudo) && sel.selector
|
158
|
+
next sel if seen.include?([sel])
|
159
|
+
extended = sel.selector.do_extend(extends, parent_directives, replace, seen, !:original)
|
160
|
+
next sel if extended == sel.selector
|
161
|
+
extended.members.reject! {|seq| seq.has_placeholder?}
|
162
|
+
modified_original = true
|
163
|
+
result = sel.with_selector(extended)
|
164
|
+
seen_with_pseudo_selectors << [result]
|
165
|
+
result
|
166
|
+
end
|
167
|
+
|
144
168
|
groups = Sass::Util.group_by_to_a(extends[members.to_set]) {|ex| ex.extender}
|
145
169
|
groups.map! do |seq, group|
|
146
170
|
sels = group.map {|e| e.target}.flatten
|
@@ -149,7 +173,7 @@ module Sass
|
|
149
173
|
|
150
174
|
self_without_sel = Sass::Util.array_minus(members, sels)
|
151
175
|
group.each {|e| e.result = :failed_to_unify unless e.result == :succeeded}
|
152
|
-
unified = seq.members.last.unify(self_without_sel, subject?)
|
176
|
+
unified = seq.members.last.unify(SimpleSequence.new(self_without_sel, subject?))
|
153
177
|
next unless unified
|
154
178
|
group.each {|e| e.result = :succeeded}
|
155
179
|
group.each {|e| check_directives_match!(e, parent_directives)}
|
@@ -159,19 +183,30 @@ module Sass
|
|
159
183
|
end
|
160
184
|
groups.compact!
|
161
185
|
groups.map! do |sels, seq|
|
162
|
-
|
186
|
+
next [] if seen.include?(sels)
|
187
|
+
seq.do_extend(
|
188
|
+
extends, parent_directives, !:replace, seen_with_pseudo_selectors + [sels], !:original)
|
163
189
|
end
|
164
190
|
groups.flatten!
|
191
|
+
|
192
|
+
if modified_original || !replace || groups.empty?
|
193
|
+
# First Law of Extend: the result of extending a selector should
|
194
|
+
# (almost) always contain the base selector.
|
195
|
+
#
|
196
|
+
# See https://github.com/nex3/sass/issues/324.
|
197
|
+
original = Sequence.new([SimpleSequence.new(members, @subject, source_range)])
|
198
|
+
original.add_sources! sources
|
199
|
+
groups.unshift original
|
200
|
+
end
|
165
201
|
groups.uniq!
|
166
202
|
groups
|
167
203
|
end
|
168
204
|
|
169
|
-
# Unifies this selector with another {SimpleSequence}
|
170
|
-
#
|
171
|
-
#
|
205
|
+
# Unifies this selector with another {SimpleSequence}, returning
|
206
|
+
# another `SimpleSequence` that is a subselector of both input
|
207
|
+
# selectors.
|
172
208
|
#
|
173
|
-
# @param
|
174
|
-
# @param other_subject [Boolean] Whether the other {SimpleSequence} being merged is a subject.
|
209
|
+
# @param other [SimpleSequence]
|
175
210
|
# @return [SimpleSequence, nil] A {SimpleSequence} matching both `sels` and this selector,
|
176
211
|
# or `nil` if this is impossible (e.g. unifying `#foo` and `#bar`)
|
177
212
|
# @raise [Sass::SyntaxError] If this selector cannot be unified.
|
@@ -180,13 +215,13 @@ module Sass
|
|
180
215
|
# Since these selectors should be resolved
|
181
216
|
# by the time extension and unification happen,
|
182
217
|
# this exception will only ever be raised as a result of programmer error
|
183
|
-
def unify(
|
184
|
-
sseq = members.inject(
|
218
|
+
def unify(other)
|
219
|
+
sseq = members.inject(other.members) do |member, sel|
|
185
220
|
return unless member
|
186
221
|
sel.unify(member)
|
187
222
|
end
|
188
223
|
return unless sseq
|
189
|
-
SimpleSequence.new(sseq,
|
224
|
+
SimpleSequence.new(sseq, other.subject? || subject?)
|
190
225
|
end
|
191
226
|
|
192
227
|
# Returns whether or not this selector matches all elements
|
@@ -195,17 +230,44 @@ module Sass
|
|
195
230
|
# @example
|
196
231
|
# (.foo).superselector?(.foo.bar) #=> true
|
197
232
|
# (.foo).superselector?(.bar) #=> false
|
198
|
-
# @param
|
233
|
+
# @param their_sseq [SimpleSequence]
|
234
|
+
# @param parents [Array<SimpleSequence, String>] The parent selectors of `their_sseq`, if any.
|
199
235
|
# @return [Boolean]
|
200
|
-
def superselector?(
|
201
|
-
|
202
|
-
|
203
|
-
|
236
|
+
def superselector?(their_sseq, parents = [])
|
237
|
+
return false unless base.nil? || base.eql?(their_sseq.base)
|
238
|
+
return false unless pseudo_elements.eql?(their_sseq.pseudo_elements)
|
239
|
+
our_spcs = selector_pseudo_classes
|
240
|
+
their_spcs = their_sseq.selector_pseudo_classes
|
241
|
+
|
242
|
+
# Some psuedo-selectors can be subselectors of non-pseudo selectors.
|
243
|
+
# Pull those out here so we can efficiently check against them below.
|
244
|
+
their_subselector_pseudos = %w[matches any nth-child nth-last-child].
|
245
|
+
map {|name| their_spcs[name] || []}.flatten
|
246
|
+
|
247
|
+
# If `self`'s non-pseudo simple selectors aren't a subset of `their_sseq`'s,
|
248
|
+
# it's definitely not a superselector. This also considers being matched
|
249
|
+
# by `:matches` or `:any`.
|
250
|
+
return false unless rest.all? do |our_sel|
|
251
|
+
next true if our_sel.is_a?(Pseudo) && our_sel.selector
|
252
|
+
next true if their_sseq.rest.include?(our_sel)
|
253
|
+
their_subselector_pseudos.any? do |their_pseudo|
|
254
|
+
their_pseudo.selector.members.all? do |their_seq|
|
255
|
+
next false unless their_seq.members.length == 1
|
256
|
+
their_sseq = their_seq.members.first
|
257
|
+
next false unless their_sseq.is_a?(SimpleSequence)
|
258
|
+
their_sseq.rest.include?(our_sel)
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
our_spcs.all? do |name, pseudos|
|
264
|
+
pseudos.all? {|pseudo| pseudo.superselector?(their_sseq, parents)}
|
265
|
+
end
|
204
266
|
end
|
205
267
|
|
206
|
-
# @see Simple#
|
207
|
-
def
|
208
|
-
res = @members.
|
268
|
+
# @see Simple#to_s
|
269
|
+
def to_s
|
270
|
+
res = @members.join
|
209
271
|
res << '!' if subject?
|
210
272
|
res
|
211
273
|
end
|
@@ -215,7 +277,9 @@ module Sass
|
|
215
277
|
#
|
216
278
|
# @return [String]
|
217
279
|
def inspect
|
218
|
-
members.map {|m| m.inspect}.join
|
280
|
+
res = members.map {|m| m.inspect}.join
|
281
|
+
res << '!' if subject?
|
282
|
+
res
|
219
283
|
end
|
220
284
|
|
221
285
|
# Return a copy of this simple sequence with `sources` merged into the
|
data/lib/sass/selector.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
require 'sass/selector/simple'
|
2
2
|
require 'sass/selector/abstract_sequence'
|
3
3
|
require 'sass/selector/comma_sequence'
|
4
|
+
require 'sass/selector/pseudo'
|
4
5
|
require 'sass/selector/sequence'
|
5
6
|
require 'sass/selector/simple_sequence'
|
6
7
|
|
7
8
|
module Sass
|
8
9
|
# A namespace for nodes in the parse tree for selectors.
|
9
10
|
#
|
10
|
-
# {CommaSequence} is the toplevel
|
11
|
+
# {CommaSequence} is the toplevel selector,
|
11
12
|
# representing a comma-separated sequence of {Sequence}s,
|
12
13
|
# such as `foo bar, baz bang`.
|
13
14
|
# {Sequence} is the next level,
|
@@ -27,19 +28,19 @@ module Sass
|
|
27
28
|
# The function of this is to be replaced by the parent selector
|
28
29
|
# in the nested hierarchy.
|
29
30
|
class Parent < Simple
|
30
|
-
# The identifier following the `&`.
|
31
|
+
# The identifier following the `&`. `nil` indicates no suffix.
|
31
32
|
#
|
32
|
-
# @return [
|
33
|
+
# @return [String, nil]
|
33
34
|
attr_reader :suffix
|
34
35
|
|
35
|
-
# @param name [
|
36
|
-
def initialize(suffix =
|
36
|
+
# @param name [String, nil] See \{#suffix}
|
37
|
+
def initialize(suffix = nil)
|
37
38
|
@suffix = suffix
|
38
39
|
end
|
39
40
|
|
40
|
-
# @see Selector#
|
41
|
-
def
|
42
|
-
|
41
|
+
# @see Selector#to_s
|
42
|
+
def to_s
|
43
|
+
"&" + (@suffix || '')
|
43
44
|
end
|
44
45
|
|
45
46
|
# Always raises an exception.
|
@@ -55,17 +56,17 @@ module Sass
|
|
55
56
|
class Class < Simple
|
56
57
|
# The class name.
|
57
58
|
#
|
58
|
-
# @return [
|
59
|
+
# @return [String]
|
59
60
|
attr_reader :name
|
60
61
|
|
61
|
-
# @param name [
|
62
|
+
# @param name [String] The class name
|
62
63
|
def initialize(name)
|
63
64
|
@name = name
|
64
65
|
end
|
65
66
|
|
66
|
-
# @see Selector#
|
67
|
-
def
|
68
|
-
|
67
|
+
# @see Selector#to_s
|
68
|
+
def to_s
|
69
|
+
"." + @name
|
69
70
|
end
|
70
71
|
|
71
72
|
# @see AbstractSequence#specificity
|
@@ -78,17 +79,17 @@ module Sass
|
|
78
79
|
class Id < Simple
|
79
80
|
# The id name.
|
80
81
|
#
|
81
|
-
# @return [
|
82
|
+
# @return [String]
|
82
83
|
attr_reader :name
|
83
84
|
|
84
|
-
# @param name [
|
85
|
+
# @param name [String] The id name
|
85
86
|
def initialize(name)
|
86
87
|
@name = name
|
87
88
|
end
|
88
89
|
|
89
|
-
# @see Selector#
|
90
|
-
def
|
91
|
-
|
90
|
+
# @see Selector#to_s
|
91
|
+
def to_s
|
92
|
+
"#" + @name
|
92
93
|
end
|
93
94
|
|
94
95
|
# Returns `nil` if `sels` contains an {Id} selector
|
@@ -113,17 +114,17 @@ module Sass
|
|
113
114
|
class Placeholder < Simple
|
114
115
|
# The placeholder name.
|
115
116
|
#
|
116
|
-
# @return [
|
117
|
+
# @return [String]
|
117
118
|
attr_reader :name
|
118
119
|
|
119
|
-
# @param name [
|
120
|
+
# @param name [String] The placeholder name
|
120
121
|
def initialize(name)
|
121
122
|
@name = name
|
122
123
|
end
|
123
124
|
|
124
|
-
# @see Selector#
|
125
|
-
def
|
126
|
-
|
125
|
+
# @see Selector#to_s
|
126
|
+
def to_s
|
127
|
+
"%" + @name
|
127
128
|
end
|
128
129
|
|
129
130
|
# @see AbstractSequence#specificity
|
@@ -134,22 +135,20 @@ module Sass
|
|
134
135
|
|
135
136
|
# A universal selector (`*` in CSS).
|
136
137
|
class Universal < Simple
|
137
|
-
# The selector namespace.
|
138
|
-
# `
|
139
|
-
# `[""]` means no namespace,
|
140
|
-
# `["*"]` means any namespace.
|
138
|
+
# The selector namespace. `nil` means the default namespace, `""` means no
|
139
|
+
# namespace, `"*"` means any namespace.
|
141
140
|
#
|
142
|
-
# @return [
|
141
|
+
# @return [String, nil]
|
143
142
|
attr_reader :namespace
|
144
143
|
|
145
|
-
# @param namespace [
|
144
|
+
# @param namespace [String, nil] See \{#namespace}
|
146
145
|
def initialize(namespace)
|
147
146
|
@namespace = namespace
|
148
147
|
end
|
149
148
|
|
150
|
-
# @see Selector#
|
151
|
-
def
|
152
|
-
@namespace ? @namespace
|
149
|
+
# @see Selector#to_s
|
150
|
+
def to_s
|
151
|
+
@namespace ? "#{@namespace}|*" : "*"
|
153
152
|
end
|
154
153
|
|
155
154
|
# Unification of a universal selector is somewhat complicated,
|
@@ -183,7 +182,7 @@ module Sass
|
|
183
182
|
when Universal; :universal
|
184
183
|
when Element; sels.first.name
|
185
184
|
else
|
186
|
-
return [self] + sels unless namespace.nil? || namespace ==
|
185
|
+
return [self] + sels unless namespace.nil? || namespace == '*'
|
187
186
|
return sels unless sels.empty?
|
188
187
|
return [self]
|
189
188
|
end
|
@@ -203,27 +202,25 @@ module Sass
|
|
203
202
|
class Element < Simple
|
204
203
|
# The element name.
|
205
204
|
#
|
206
|
-
# @return [
|
205
|
+
# @return [String]
|
207
206
|
attr_reader :name
|
208
207
|
|
209
|
-
# The selector namespace.
|
210
|
-
# `
|
211
|
-
# `[""]` means no namespace,
|
212
|
-
# `["*"]` means any namespace.
|
208
|
+
# The selector namespace. `nil` means the default namespace, `""` means no
|
209
|
+
# namespace, `"*"` means any namespace.
|
213
210
|
#
|
214
|
-
# @return [
|
211
|
+
# @return [String, nil]
|
215
212
|
attr_reader :namespace
|
216
213
|
|
217
|
-
# @param name [
|
218
|
-
# @param namespace [
|
214
|
+
# @param name [String] The element name
|
215
|
+
# @param namespace [String, nil] See \{#namespace}
|
219
216
|
def initialize(name, namespace)
|
220
217
|
@name = name
|
221
218
|
@namespace = namespace
|
222
219
|
end
|
223
220
|
|
224
|
-
# @see Selector#
|
225
|
-
def
|
226
|
-
@namespace ? @namespace
|
221
|
+
# @see Selector#to_s
|
222
|
+
def to_s
|
223
|
+
@namespace ? "#{@namespace}|#{@name}" : @name
|
227
224
|
end
|
228
225
|
|
229
226
|
# Unification of an element selector is somewhat complicated,
|
@@ -266,32 +263,6 @@ module Sass
|
|
266
263
|
end
|
267
264
|
end
|
268
265
|
|
269
|
-
# Selector interpolation (`#{}` in Sass).
|
270
|
-
class Interpolation < Simple
|
271
|
-
# The script to run.
|
272
|
-
#
|
273
|
-
# @return [Sass::Script::Tree::Node]
|
274
|
-
attr_reader :script
|
275
|
-
|
276
|
-
# @param script [Sass::Script::Tree::Node] The script to run
|
277
|
-
def initialize(script)
|
278
|
-
@script = script
|
279
|
-
end
|
280
|
-
|
281
|
-
# @see Selector#to_a
|
282
|
-
def to_a
|
283
|
-
[@script]
|
284
|
-
end
|
285
|
-
|
286
|
-
# Always raises an exception.
|
287
|
-
#
|
288
|
-
# @raise [Sass::SyntaxError] Interpolation selectors should be resolved before unification
|
289
|
-
# @see Selector#unify
|
290
|
-
def unify(sels)
|
291
|
-
raise Sass::SyntaxError.new("[BUG] Cannot unify interpolation selectors.")
|
292
|
-
end
|
293
|
-
end
|
294
|
-
|
295
266
|
# An attribute selector (e.g. `[href^="http://"]`).
|
296
267
|
class Attribute < Simple
|
297
268
|
# The attribute name.
|
@@ -299,12 +270,10 @@ module Sass
|
|
299
270
|
# @return [Array<String, Sass::Script::Tree::Node>]
|
300
271
|
attr_reader :name
|
301
272
|
|
302
|
-
# The attribute namespace.
|
303
|
-
# `
|
304
|
-
# `[""]` means no namespace,
|
305
|
-
# `["*"]` means any namespace.
|
273
|
+
# The attribute namespace. `nil` means the default namespace, `""` means
|
274
|
+
# no namespace, `"*"` means any namespace.
|
306
275
|
#
|
307
|
-
# @return [
|
276
|
+
# @return [String, nil]
|
308
277
|
attr_reader :namespace
|
309
278
|
|
310
279
|
# The matching operator, e.g. `"="` or `"^="`.
|
@@ -314,19 +283,19 @@ module Sass
|
|
314
283
|
|
315
284
|
# The right-hand side of the operator.
|
316
285
|
#
|
317
|
-
# @return [
|
286
|
+
# @return [String]
|
318
287
|
attr_reader :value
|
319
288
|
|
320
289
|
# Flags for the attribute selector (e.g. `i`).
|
321
290
|
#
|
322
|
-
# @return [
|
291
|
+
# @return [String]
|
323
292
|
attr_reader :flags
|
324
293
|
|
325
|
-
# @param name [
|
326
|
-
# @param namespace [
|
294
|
+
# @param name [String] The attribute name
|
295
|
+
# @param namespace [String, nil] See \{#namespace}
|
327
296
|
# @param operator [String] The matching operator, e.g. `"="` or `"^="`
|
328
|
-
# @param value [
|
329
|
-
# @param flags [
|
297
|
+
# @param value [String] See \{#value}
|
298
|
+
# @param flags [String] See \{#flags}
|
330
299
|
# @comment
|
331
300
|
# rubocop:disable ParameterLists
|
332
301
|
def initialize(name, namespace, operator, value, flags)
|
@@ -338,13 +307,13 @@ module Sass
|
|
338
307
|
@flags = flags
|
339
308
|
end
|
340
309
|
|
341
|
-
# @see Selector#
|
342
|
-
def
|
343
|
-
res =
|
344
|
-
res
|
345
|
-
res
|
346
|
-
|
347
|
-
|
310
|
+
# @see Selector#to_s
|
311
|
+
def to_s
|
312
|
+
res = "["
|
313
|
+
res << @namespace << "|" if @namespace
|
314
|
+
res << @name
|
315
|
+
res << @operator << @value if @value
|
316
|
+
res << " " << @flags if @flags
|
348
317
|
res << "]"
|
349
318
|
end
|
350
319
|
|
@@ -353,111 +322,5 @@ module Sass
|
|
353
322
|
SPECIFICITY_BASE
|
354
323
|
end
|
355
324
|
end
|
356
|
-
|
357
|
-
# A pseudoclass (e.g. `:visited`) or pseudoelement (e.g. `::first-line`) selector.
|
358
|
-
# It can have arguments (e.g. `:nth-child(2n+1)`).
|
359
|
-
class Pseudo < Simple
|
360
|
-
# Some psuedo-class-syntax selectors are actually considered
|
361
|
-
# pseudo-elements and must be treated differently. This is a list of such
|
362
|
-
# selectors
|
363
|
-
#
|
364
|
-
# @return [Array<String>]
|
365
|
-
ACTUALLY_ELEMENTS = %w[after before first-line first-letter]
|
366
|
-
|
367
|
-
# Like \{#type}, but returns the type of selector this looks like, rather
|
368
|
-
# than the type it is semantically. This only differs from type for
|
369
|
-
# selectors in \{ACTUALLY\_ELEMENTS}.
|
370
|
-
#
|
371
|
-
# @return [Symbol]
|
372
|
-
attr_reader :syntactic_type
|
373
|
-
|
374
|
-
# The name of the selector.
|
375
|
-
#
|
376
|
-
# @return [Array<String, Sass::Script::Tree::Node>]
|
377
|
-
attr_reader :name
|
378
|
-
|
379
|
-
# The argument to the selector,
|
380
|
-
# or `nil` if no argument was given.
|
381
|
-
#
|
382
|
-
# This may include SassScript nodes that will be run during resolution.
|
383
|
-
# Note that this should not include SassScript nodes
|
384
|
-
# after resolution has taken place.
|
385
|
-
#
|
386
|
-
# @return [Array<String, Sass::Script::Tree::Node>, nil]
|
387
|
-
attr_reader :arg
|
388
|
-
|
389
|
-
# @param type [Symbol] See \{#type}
|
390
|
-
# @param name [Array<String, Sass::Script::Tree::Node>] The name of the selector
|
391
|
-
# @param arg [nil, Array<String, Sass::Script::Tree::Node>] The argument to the selector,
|
392
|
-
# or nil if no argument was given
|
393
|
-
def initialize(type, name, arg)
|
394
|
-
@syntactic_type = type
|
395
|
-
@name = name
|
396
|
-
@arg = arg
|
397
|
-
end
|
398
|
-
|
399
|
-
# The type of the selector. `:class` if this is a pseudoclass selector,
|
400
|
-
# `:element` if it's a pseudoelement.
|
401
|
-
#
|
402
|
-
# @return [Symbol]
|
403
|
-
def type
|
404
|
-
ACTUALLY_ELEMENTS.include?(name.first) ? :element : syntactic_type
|
405
|
-
end
|
406
|
-
|
407
|
-
# @see Selector#to_a
|
408
|
-
def to_a
|
409
|
-
res = [syntactic_type == :class ? ":" : "::"] + @name
|
410
|
-
(res << "(").concat(Sass::Util.strip_string_array(@arg)) << ")" if @arg
|
411
|
-
res
|
412
|
-
end
|
413
|
-
|
414
|
-
# Returns `nil` if this is a pseudoelement selector
|
415
|
-
# and `sels` contains a pseudoelement selector different than this one.
|
416
|
-
#
|
417
|
-
# @see Selector#unify
|
418
|
-
def unify(sels)
|
419
|
-
return if type == :element && sels.any? do |sel|
|
420
|
-
sel.is_a?(Pseudo) && sel.type == :element &&
|
421
|
-
(sel.name != name || sel.arg != arg)
|
422
|
-
end
|
423
|
-
super
|
424
|
-
end
|
425
|
-
|
426
|
-
# @see AbstractSequence#specificity
|
427
|
-
def specificity
|
428
|
-
type == :class ? SPECIFICITY_BASE : 1
|
429
|
-
end
|
430
|
-
end
|
431
|
-
|
432
|
-
# A pseudoclass selector whose argument is itself a selector
|
433
|
-
# (e.g. `:not(.foo)` or `:-moz-all(.foo, .bar)`).
|
434
|
-
class SelectorPseudoClass < Simple
|
435
|
-
# The name of the pseudoclass.
|
436
|
-
#
|
437
|
-
# @return [String]
|
438
|
-
attr_reader :name
|
439
|
-
|
440
|
-
# The selector argument.
|
441
|
-
#
|
442
|
-
# @return [Selector::Sequence]
|
443
|
-
attr_reader :selector
|
444
|
-
|
445
|
-
# @param name [String] The name of the pseudoclass
|
446
|
-
# @param selector [Selector::CommaSequence] The selector argument
|
447
|
-
def initialize(name, selector)
|
448
|
-
@name = name
|
449
|
-
@selector = selector
|
450
|
-
end
|
451
|
-
|
452
|
-
# @see Selector#to_a
|
453
|
-
def to_a
|
454
|
-
[":", @name, "("] + @selector.to_a + [")"]
|
455
|
-
end
|
456
|
-
|
457
|
-
# @see AbstractSequence#specificity
|
458
|
-
def specificity
|
459
|
-
SPECIFICITY_BASE
|
460
|
-
end
|
461
|
-
end
|
462
325
|
end
|
463
326
|
end
|
data/lib/sass/shared.rb
CHANGED