sass 3.1.21 → 3.2.0.alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +5 -4
- data/REVISION +1 -1
- data/Rakefile +6 -15
- data/VERSION +1 -1
- data/VERSION_NAME +1 -1
- data/lib/sass.rb +0 -1
- data/lib/sass/cache_stores/base.rb +1 -3
- data/lib/sass/cache_stores/filesystem.rb +0 -3
- data/lib/sass/css.rb +49 -145
- data/lib/sass/engine.rb +23 -47
- data/lib/sass/environment.rb +5 -30
- data/lib/sass/exec.rb +7 -30
- data/lib/sass/importers/base.rb +1 -2
- data/lib/sass/importers/filesystem.rb +13 -18
- data/lib/sass/less.rb +1 -1
- data/lib/sass/plugin.rb +8 -4
- data/lib/sass/plugin/compiler.rb +67 -93
- data/lib/sass/plugin/configuration.rb +2 -0
- data/lib/sass/plugin/staleness_checker.rb +4 -14
- data/lib/sass/repl.rb +3 -2
- data/lib/sass/script.rb +1 -0
- data/lib/sass/script/color.rb +9 -4
- data/lib/sass/script/funcall.rb +3 -16
- data/lib/sass/script/functions.rb +55 -98
- data/lib/sass/script/interpolation.rb +0 -9
- data/lib/sass/script/lexer.rb +4 -2
- data/lib/sass/script/list.rb +0 -8
- data/lib/sass/script/literal.rb +20 -5
- data/lib/sass/script/node.rb +0 -8
- data/lib/sass/script/number.rb +11 -35
- data/lib/sass/script/operation.rb +0 -16
- data/lib/sass/script/parser.rb +5 -12
- data/lib/sass/script/string_interpolation.rb +0 -9
- data/lib/sass/script/unary_operation.rb +0 -7
- data/lib/sass/script/variable.rb +1 -5
- data/lib/sass/scss/parser.rb +54 -191
- data/lib/sass/scss/rx.rb +3 -15
- data/lib/sass/scss/static_parser.rb +3 -3
- data/lib/sass/selector.rb +3 -15
- data/lib/sass/selector/abstract_sequence.rb +2 -11
- data/lib/sass/selector/comma_sequence.rb +3 -8
- data/lib/sass/selector/sequence.rb +11 -74
- data/lib/sass/selector/simple.rb +1 -7
- data/lib/sass/selector/simple_sequence.rb +8 -28
- data/lib/sass/shared.rb +5 -3
- data/lib/sass/tree/comment_node.rb +12 -25
- data/lib/sass/tree/debug_node.rb +1 -1
- data/lib/sass/tree/directive_node.rb +0 -5
- data/lib/sass/tree/each_node.rb +1 -1
- data/lib/sass/tree/extend_node.rb +1 -1
- data/lib/sass/tree/for_node.rb +2 -2
- data/lib/sass/tree/function_node.rb +1 -1
- data/lib/sass/tree/if_node.rb +14 -1
- data/lib/sass/tree/media_node.rb +4 -4
- data/lib/sass/tree/mixin_def_node.rb +1 -1
- data/lib/sass/tree/mixin_node.rb +2 -2
- data/lib/sass/tree/node.rb +26 -10
- data/lib/sass/tree/return_node.rb +1 -1
- data/lib/sass/tree/root_node.rb +1 -1
- data/lib/sass/tree/rule_node.rb +11 -9
- data/lib/sass/tree/variable_node.rb +1 -1
- data/lib/sass/tree/visitors/base.rb +1 -1
- data/lib/sass/tree/visitors/check_nesting.rb +36 -29
- data/lib/sass/tree/visitors/convert.rb +9 -16
- data/lib/sass/tree/visitors/cssize.rb +9 -40
- data/lib/sass/tree/visitors/perform.rb +23 -79
- data/lib/sass/tree/visitors/to_css.rb +21 -23
- data/lib/sass/tree/warn_node.rb +1 -1
- data/lib/sass/tree/while_node.rb +1 -1
- data/lib/sass/util.rb +9 -147
- data/lib/sass/version.rb +0 -14
- data/test/sass/cache_test.rb +0 -15
- data/test/sass/conversion_test.rb +8 -50
- data/test/sass/css2sass_test.rb +0 -33
- data/test/sass/engine_test.rb +32 -283
- data/test/sass/extend_test.rb +0 -315
- data/test/sass/functions_test.rb +23 -60
- data/test/sass/importer_test.rb +0 -110
- data/test/sass/more_results/more_import.css +2 -2
- data/test/sass/plugin_test.rb +13 -40
- data/test/sass/results/import.css +2 -2
- data/test/sass/results/import_charset.css +0 -1
- data/test/sass/results/import_charset_1_8.css +0 -1
- data/test/sass/results/import_charset_ibm866.css +0 -1
- data/test/sass/results/scss_import.css +2 -2
- data/test/sass/results/units.css +1 -1
- data/test/sass/script_conversion_test.rb +0 -2
- data/test/sass/script_test.rb +4 -28
- data/test/sass/scss/css_test.rb +1 -79
- data/test/sass/scss/scss_test.rb +16 -96
- data/test/sass/templates/import_charset.sass +0 -2
- data/test/sass/templates/import_charset_1_8.sass +0 -2
- data/test/sass/templates/import_charset_ibm866.sass +0 -2
- data/test/sass/test_helper.rb +1 -1
- data/test/sass/util_test.rb +0 -28
- data/test/test_helper.rb +0 -2
- data/vendor/{listen → fssm}/LICENSE +1 -1
- data/vendor/fssm/README.markdown +55 -0
- data/vendor/fssm/Rakefile +59 -0
- data/vendor/fssm/VERSION.yml +5 -0
- data/vendor/fssm/example.rb +9 -0
- data/vendor/fssm/fssm.gemspec +77 -0
- data/vendor/fssm/lib/fssm.rb +33 -0
- data/vendor/fssm/lib/fssm/backends/fsevents.rb +36 -0
- data/vendor/fssm/lib/fssm/backends/inotify.rb +26 -0
- data/vendor/fssm/lib/fssm/backends/polling.rb +25 -0
- data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +131 -0
- data/vendor/fssm/lib/fssm/monitor.rb +26 -0
- data/vendor/fssm/lib/fssm/path.rb +91 -0
- data/vendor/fssm/lib/fssm/pathname.rb +502 -0
- data/vendor/fssm/lib/fssm/state/directory.rb +57 -0
- data/vendor/fssm/lib/fssm/state/file.rb +24 -0
- data/vendor/fssm/lib/fssm/support.rb +63 -0
- data/vendor/fssm/lib/fssm/tree.rb +176 -0
- data/vendor/fssm/profile/prof-cache.rb +40 -0
- data/vendor/fssm/profile/prof-fssm-pathname.html +1231 -0
- data/vendor/fssm/profile/prof-pathname.rb +68 -0
- data/vendor/fssm/profile/prof-plain-pathname.html +988 -0
- data/vendor/fssm/profile/prof.html +2379 -0
- data/vendor/fssm/spec/path_spec.rb +75 -0
- 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 +14 -0
- metadata +246 -281
- data/VERSION_DATE +0 -1
- data/lib/sass/logger.rb +0 -15
- data/lib/sass/logger/base.rb +0 -32
- data/lib/sass/logger/log_level.rb +0 -49
- data/lib/sass/tree/visitors/deep_copy.rb +0 -87
- data/lib/sass/tree/visitors/extend.rb +0 -42
- data/lib/sass/tree/visitors/set_options.rb +0 -97
- data/lib/sass/util/multibyte_string_scanner.rb +0 -134
- data/test/Gemfile +0 -4
- data/test/Gemfile.lock +0 -19
- data/test/sass/fixtures/test_staleness_check_across_importers.css +0 -1
- data/test/sass/fixtures/test_staleness_check_across_importers.scss +0 -1
- data/test/sass/logger_test.rb +0 -58
- data/test/sass/templates/_double_import_loop2.sass +0 -1
- data/test/sass/templates/bork5.sass +0 -3
- data/test/sass/templates/double_import_loop1.sass +0 -1
- data/test/sass/templates/nested_bork5.sass +0 -2
- data/test/sass/templates/single_import_loop.sass +0 -1
- data/test/sass/util/multibyte_string_scanner_test.rb +0 -147
- data/vendor/listen/CHANGELOG.md +0 -147
- data/vendor/listen/Gemfile +0 -23
- data/vendor/listen/Guardfile +0 -8
- data/vendor/listen/README.md +0 -312
- data/vendor/listen/Rakefile +0 -47
- data/vendor/listen/Vagrantfile +0 -96
- data/vendor/listen/lib/listen.rb +0 -38
- data/vendor/listen/lib/listen/adapter.rb +0 -167
- data/vendor/listen/lib/listen/adapters/darwin.rb +0 -84
- data/vendor/listen/lib/listen/adapters/linux.rb +0 -110
- data/vendor/listen/lib/listen/adapters/polling.rb +0 -66
- data/vendor/listen/lib/listen/adapters/windows.rb +0 -81
- data/vendor/listen/lib/listen/directory_record.rb +0 -318
- data/vendor/listen/lib/listen/listener.rb +0 -203
- data/vendor/listen/lib/listen/multi_listener.rb +0 -121
- data/vendor/listen/lib/listen/turnstile.rb +0 -28
- data/vendor/listen/lib/listen/version.rb +0 -3
- data/vendor/listen/listen.gemspec +0 -26
- data/vendor/listen/spec/listen/adapter_spec.rb +0 -142
- data/vendor/listen/spec/listen/adapters/darwin_spec.rb +0 -31
- data/vendor/listen/spec/listen/adapters/linux_spec.rb +0 -41
- data/vendor/listen/spec/listen/adapters/polling_spec.rb +0 -68
- data/vendor/listen/spec/listen/adapters/windows_spec.rb +0 -24
- data/vendor/listen/spec/listen/directory_record_spec.rb +0 -1138
- data/vendor/listen/spec/listen/listener_spec.rb +0 -155
- data/vendor/listen/spec/listen/multi_listener_spec.rb +0 -156
- data/vendor/listen/spec/listen/turnstile_spec.rb +0 -56
- data/vendor/listen/spec/listen_spec.rb +0 -73
- data/vendor/listen/spec/spec_helper.rb +0 -18
- data/vendor/listen/spec/support/adapter_helper.rb +0 -716
- data/vendor/listen/spec/support/directory_record_helper.rb +0 -55
- data/vendor/listen/spec/support/fixtures_helper.rb +0 -29
- data/vendor/listen/spec/support/listeners_helper.rb +0 -144
- data/vendor/listen/spec/support/platform_helper.rb +0 -11
data/lib/sass/scss/rx.rb
CHANGED
@@ -51,8 +51,6 @@ module Sass
|
|
51
51
|
UNICODE = /\\#{H}{1,6}[ \t\r\n\f]?/
|
52
52
|
s = if Sass::Util.ruby1_8?
|
53
53
|
'\200-\377'
|
54
|
-
elsif Sass::Util.macruby?
|
55
|
-
'\u0080-\uD7FF\uE000-\uFFFD\U00010000-\U0010FFFF'
|
56
54
|
else
|
57
55
|
'\u{80}-\u{D7FF}\u{E000}-\u{FFFD}\u{10000}-\u{10FFFF}'
|
58
56
|
end
|
@@ -109,17 +107,11 @@ module Sass
|
|
109
107
|
TILDE = /#{W}~/
|
110
108
|
NOT = quote(":not(", Regexp::IGNORECASE)
|
111
109
|
|
112
|
-
# Defined in https://developer.mozilla.org/en/CSS/@-moz-document as a
|
113
|
-
# non-standard version of http://www.w3.org/TR/css3-conditional/
|
114
|
-
URL_PREFIX = /url-prefix\(#{W}(?:#{STRING}|#{URL})#{W}\)/i
|
115
|
-
DOMAIN = /domain\(#{W}(?:#{STRING}|#{URL})#{W}\)/i
|
116
|
-
|
117
110
|
# Custom
|
118
111
|
HEXCOLOR = /\#[0-9a-fA-F]+/
|
119
112
|
INTERP_START = /#\{/
|
120
113
|
MOZ_ANY = quote(":-moz-any(", Regexp::IGNORECASE)
|
121
114
|
|
122
|
-
IDENT_HYPHEN_INTERP = /-(#\{)/
|
123
115
|
STRING1_NOINTERP = /\"((?:[^\n\r\f\\"#]|#(?!\{)|\\#{NL}|#{ESCAPE})*)\"/
|
124
116
|
STRING2_NOINTERP = /\'((?:[^\n\r\f\\'#]|#(?!\{)|\\#{NL}|#{ESCAPE})*)\'/
|
125
117
|
STRING_NOINTERP = /#{STRING1_NOINTERP}|#{STRING2_NOINTERP}/
|
@@ -127,13 +119,9 @@ module Sass
|
|
127
119
|
# We could use it for 1.9 only, but I don't want to introduce a cross-version
|
128
120
|
# behavior difference.
|
129
121
|
# In any case, almost all CSS idents will be matched by this.
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
# time when a value has a long string of valid, parsable content followed
|
134
|
-
# by something invalid.
|
135
|
-
STATIC_VALUE = /(-?#{NMSTART}|#{STRING_NOINTERP}|[ \t](?!%)|#[a-f0-9]|[,%]|#{NUM}|\!important){0,50}([;}])/i
|
136
|
-
STATIC_SELECTOR = /(#{NMCHAR}|[ \t]|[,>+*]|[:#.]#{NMSTART}){0,50}([{])/i
|
122
|
+
STATIC_VALUE = /(-?#{NMSTART}|#{STRING_NOINTERP}|\s(?!%)|#[a-f0-9]|[,%]|#{NUM}|\!important)+(?=[;}])/i
|
123
|
+
|
124
|
+
STATIC_SELECTOR = /(#{NMCHAR}|\s|[,>+*]|[:#.]#{NMSTART})+(?=[{])/i
|
137
125
|
end
|
138
126
|
end
|
139
127
|
end
|
@@ -13,12 +13,12 @@ module Sass
|
|
13
13
|
# Used for error reporting.
|
14
14
|
# @return [Selector::CommaSequence] The parsed selector
|
15
15
|
# @raise [Sass::SyntaxError] if there's a syntax error in the selector
|
16
|
-
def parse_selector
|
16
|
+
def parse_selector(filename)
|
17
17
|
init_scanner!
|
18
18
|
seq = expr!(:selector_comma_sequence)
|
19
19
|
expected("selector") unless @scanner.eos?
|
20
20
|
seq.line = @line
|
21
|
-
seq.filename =
|
21
|
+
seq.filename = filename
|
22
22
|
seq
|
23
23
|
end
|
24
24
|
|
@@ -32,7 +32,7 @@ module Sass
|
|
32
32
|
def use_css_import?; true; end
|
33
33
|
|
34
34
|
def special_directive(name)
|
35
|
-
return unless
|
35
|
+
return unless %w[media import charset].include?(name)
|
36
36
|
super
|
37
37
|
end
|
38
38
|
end
|
data/lib/sass/selector.rb
CHANGED
@@ -287,13 +287,6 @@ module Sass
|
|
287
287
|
# @return [Symbol]
|
288
288
|
attr_reader :type
|
289
289
|
|
290
|
-
# Some psuedo-class-syntax selectors (`:after` and `:before)
|
291
|
-
# are actually considered pseudo-elements
|
292
|
-
# and must be at the end of the selector to function properly.
|
293
|
-
#
|
294
|
-
# @return [Array<String>]
|
295
|
-
FINAL_SELECTORS = %w[after before]
|
296
|
-
|
297
290
|
# The name of the selector.
|
298
291
|
#
|
299
292
|
# @return [Array<String, Sass::Script::Node>]
|
@@ -319,10 +312,6 @@ module Sass
|
|
319
312
|
@arg = arg
|
320
313
|
end
|
321
314
|
|
322
|
-
def final?
|
323
|
-
type == :class && FINAL_SELECTORS.include?(name.first)
|
324
|
-
end
|
325
|
-
|
326
315
|
# @see Selector#to_a
|
327
316
|
def to_a
|
328
317
|
res = [@type == :class ? ":" : "::"] + @name
|
@@ -330,8 +319,8 @@ module Sass
|
|
330
319
|
res
|
331
320
|
end
|
332
321
|
|
333
|
-
# Returns `nil` if this is a
|
334
|
-
# and `sels` contains a
|
322
|
+
# Returns `nil` if this is a pseudoclass selector
|
323
|
+
# and `sels` contains a pseudoclass selector different than this one.
|
335
324
|
#
|
336
325
|
# @see Selector#unify
|
337
326
|
def unify(sels)
|
@@ -339,7 +328,6 @@ module Sass
|
|
339
328
|
sel.is_a?(Pseudo) && sel.type == :element &&
|
340
329
|
(sel.name != self.name || sel.arg != self.arg)
|
341
330
|
end
|
342
|
-
return sels + [self] if final?
|
343
331
|
super
|
344
332
|
end
|
345
333
|
end
|
@@ -358,7 +346,7 @@ module Sass
|
|
358
346
|
attr_reader :selector
|
359
347
|
|
360
348
|
# @param [String] The name of the pseudoclass
|
361
|
-
# @param [Selector::
|
349
|
+
# @param [Selector::Sequence] The selector argument
|
362
350
|
def initialize(name, selector)
|
363
351
|
@name = name
|
364
352
|
@selector = selector
|
@@ -2,9 +2,8 @@ module Sass
|
|
2
2
|
module Selector
|
3
3
|
# The abstract parent class of the various selector sequence classes.
|
4
4
|
#
|
5
|
-
# All subclasses should implement a `members` method
|
6
|
-
# of object that respond to `#line=` and `#filename
|
7
|
-
# method that returns an array of strings and script nodes.
|
5
|
+
# All subclasses should implement a `members` method
|
6
|
+
# that returns an array of object that respond to `#line=` and `#filename=`.
|
8
7
|
class AbstractSequence
|
9
8
|
# The line of the Sass template on which this selector was declared.
|
10
9
|
#
|
@@ -58,14 +57,6 @@ module Sass
|
|
58
57
|
other.class == self.class && other.hash == self.hash && _eql?(other)
|
59
58
|
end
|
60
59
|
alias_method :==, :eql?
|
61
|
-
|
62
|
-
# Converts the selector into a string. This is the standard selector
|
63
|
-
# string, along with any SassScript interpolation that may exist.
|
64
|
-
#
|
65
|
-
# @return [String]
|
66
|
-
def to_s
|
67
|
-
to_a.map {|e| e.is_a?(Sass::Script::Node) ? "\#{#{e.to_sass}}" : e}.join
|
68
|
-
end
|
69
60
|
end
|
70
61
|
end
|
71
62
|
end
|
@@ -44,17 +44,12 @@ module Sass
|
|
44
44
|
# @todo Link this to the reference documentation on `@extend`
|
45
45
|
# when such a thing exists.
|
46
46
|
#
|
47
|
-
# @param extends [Sass::Util::SubsetMap{Selector::Simple =>
|
48
|
-
# Sass::Tree::Visitors::Cssize::Extend}]
|
47
|
+
# @param extends [Sass::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
|
49
48
|
# The extensions to perform on this selector
|
50
|
-
# @param parent_directives [Array<Sass::Tree::DirectiveNode>]
|
51
|
-
# The directives containing this selector.
|
52
49
|
# @return [CommaSequence] A copy of this selector,
|
53
50
|
# with extensions made according to `extends`
|
54
|
-
def do_extend(extends
|
55
|
-
CommaSequence.new(members.map
|
56
|
-
seq.do_extend(extends, parent_directives)
|
57
|
-
end.flatten)
|
51
|
+
def do_extend(extends)
|
52
|
+
CommaSequence.new(members.map {|seq| seq.do_extend(extends)}.flatten)
|
58
53
|
end
|
59
54
|
|
60
55
|
# Returns a string representation of the sequence.
|
@@ -47,15 +47,15 @@ module Sass
|
|
47
47
|
# @return [Sequence] This selector, with parent references resolved
|
48
48
|
# @raise [Sass::SyntaxError] If a parent selector is invalid
|
49
49
|
def resolve_parent_refs(super_seq)
|
50
|
-
members = @members
|
50
|
+
members = @members
|
51
51
|
nl = (members.first == "\n" && members.shift)
|
52
52
|
unless members.any? do |seq_or_op|
|
53
53
|
seq_or_op.is_a?(SimpleSequence) && seq_or_op.members.first.is_a?(Parent)
|
54
54
|
end
|
55
|
-
|
55
|
+
members = []
|
56
56
|
members << nl if nl
|
57
57
|
members << SimpleSequence.new([Parent.new])
|
58
|
-
members +=
|
58
|
+
members += @members
|
59
59
|
end
|
60
60
|
|
61
61
|
Sequence.new(
|
@@ -69,19 +69,16 @@ module Sass
|
|
69
69
|
# (which should come from {Sass::Tree::Visitors::Cssize}).
|
70
70
|
#
|
71
71
|
# @overload def do_extend(extends)
|
72
|
-
# @param extends [Sass::Util::SubsetMap{Selector::Simple =>
|
73
|
-
# Sass::Tree::Visitors::Cssize::Extend}]
|
72
|
+
# @param extends [Sass::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
|
74
73
|
# The extensions to perform on this selector
|
75
|
-
# @param parent_directives [Array<Sass::Tree::DirectiveNode>]
|
76
|
-
# The directives containing this selector.
|
77
74
|
# @return [Array<Sequence>] A list of selectors generated
|
78
75
|
# by extending this selector with `extends`.
|
79
76
|
# These correspond to a {CommaSequence}'s {CommaSequence#members members array}.
|
80
77
|
# @see CommaSequence#do_extend
|
81
|
-
def do_extend(extends,
|
78
|
+
def do_extend(extends, seen = Set.new)
|
82
79
|
paths = Sass::Util.paths(members.map do |sseq_or_op|
|
83
80
|
next [[sseq_or_op]] unless sseq_or_op.is_a?(SimpleSequence)
|
84
|
-
extended = sseq_or_op.do_extend(extends,
|
81
|
+
extended = sseq_or_op.do_extend(extends, seen)
|
85
82
|
choices = extended.map {|seq| seq.members}
|
86
83
|
choices.unshift([sseq_or_op]) unless extended.any? {|seq| seq.superselector?(sseq_or_op)}
|
87
84
|
choices
|
@@ -137,11 +134,10 @@ module Sass
|
|
137
134
|
last_current.unshift(current.pop)
|
138
135
|
end
|
139
136
|
befores = Sass::Util.flatten(befores.map do |before|
|
140
|
-
|
141
|
-
sub.map {|seqs| seqs + last_current}
|
137
|
+
subweave(before, current).map {|seqs| seqs + last_current}
|
142
138
|
end, 1)
|
139
|
+
return befores if afters.empty?
|
143
140
|
end
|
144
|
-
return befores
|
145
141
|
end
|
146
142
|
|
147
143
|
# This interweaves two lists of selectors,
|
@@ -153,14 +149,14 @@ module Sass
|
|
153
149
|
# `.foo .baz .bar .bang`, `.foo .baz .bar.bang`, `.foo .baz .bang .bar`,
|
154
150
|
# and so on until `.baz .bang .foo .bar`.
|
155
151
|
#
|
152
|
+
# @overload def subweave(seq1, seq2)
|
156
153
|
# @param seq1 [Array<SimpleSequence or String>]
|
157
154
|
# @param seq2 [Array<SimpleSequence or String>]
|
158
155
|
# @return [Array<Array<SimpleSequence or String>>]
|
159
|
-
def subweave(seq1, seq2)
|
156
|
+
def subweave(seq1, seq2, cache = {})
|
160
157
|
return [seq2] if seq1.empty?
|
161
158
|
return [seq1] if seq2.empty?
|
162
159
|
|
163
|
-
return unless init = merge_initial_ops(seq1, seq2)
|
164
160
|
seq1 = group_selectors(seq1)
|
165
161
|
seq2 = group_selectors(seq2)
|
166
162
|
lcs = Sass::Util.lcs(seq2, seq1) do |s1, s2|
|
@@ -170,7 +166,7 @@ module Sass
|
|
170
166
|
next s1 if subweave_superselector?(s2, s1)
|
171
167
|
end
|
172
168
|
|
173
|
-
diff = [
|
169
|
+
diff = []
|
174
170
|
until lcs.empty?
|
175
171
|
diff << chunks(seq1, seq2) {|s| subweave_superselector?(s.first, lcs.first)} << [lcs.shift]
|
176
172
|
seq1.shift
|
@@ -182,50 +178,6 @@ module Sass
|
|
182
178
|
Sass::Util.paths(diff).map {|p| p.flatten}
|
183
179
|
end
|
184
180
|
|
185
|
-
# Extracts initial selector operators (`"+"`, `">"`, `"~"`, and `"\n"`)
|
186
|
-
# from two sequences and merges them together into a single array of
|
187
|
-
# selector operators.
|
188
|
-
#
|
189
|
-
# @param seq1 [Array<SimpleSequence or String>]
|
190
|
-
# @param seq2 [Array<SimpleSequence or String>]
|
191
|
-
# @return [Array<String>, nil] If there are no operators in the merged
|
192
|
-
# sequence, this will be the empty array. If the operators cannot be
|
193
|
-
# merged, this will be nil.
|
194
|
-
def merge_initial_ops(seq1, seq2)
|
195
|
-
ops1, ops2 = [], []
|
196
|
-
ops1 << seq1.shift while seq1.first.is_a?(String)
|
197
|
-
ops2 << seq2.shift while seq2.first.is_a?(String)
|
198
|
-
|
199
|
-
newline = false
|
200
|
-
newline ||= !!ops1.shift if ops1.first == "\n"
|
201
|
-
newline ||= !!ops2.shift if ops2.first == "\n"
|
202
|
-
|
203
|
-
# If neither sequence is a subsequence of the other, they cannot be
|
204
|
-
# merged successfully
|
205
|
-
lcs = Sass::Util.lcs(ops1, ops2)
|
206
|
-
return unless lcs == ops1 || lcs == ops2
|
207
|
-
return (newline ? ["\n"] : []) + (ops1.size > ops2.size ? ops1 : ops2)
|
208
|
-
end
|
209
|
-
|
210
|
-
# Takes initial subsequences of `seq1` and `seq2` and returns all
|
211
|
-
# orderings of those subsequences. The initial subsequences are determined
|
212
|
-
# by a block.
|
213
|
-
#
|
214
|
-
# Destructively removes the initial subsequences of `seq1` and `seq2`.
|
215
|
-
#
|
216
|
-
# For example, given `(A B C | D E)` and `(1 2 | 3 4 5)` (with `|`
|
217
|
-
# denoting the boundary of the initial subsequence), this would return
|
218
|
-
# `[(A B C 1 2), (1 2 A B C)]`. The sequences would then be `(D E)` and
|
219
|
-
# `(3 4 5)`.
|
220
|
-
#
|
221
|
-
# @param seq1 [Array]
|
222
|
-
# @param seq2 [Array]
|
223
|
-
# @yield [a] Used to determine when to cut off the initial subsequences.
|
224
|
-
# Called repeatedly for each sequence until it returns true.
|
225
|
-
# @yieldparam a [Array] A final subsequence of one input sequence after
|
226
|
-
# cutting off some initial subsequence.
|
227
|
-
# @yieldreturn [Boolean] Whether or not to cut off the initial subsequence
|
228
|
-
# here.
|
229
181
|
def chunks(seq1, seq2)
|
230
182
|
chunk1 = []
|
231
183
|
chunk1 << seq1.shift until yield seq1
|
@@ -237,15 +189,6 @@ module Sass
|
|
237
189
|
[chunk1 + chunk2, chunk2 + chunk1]
|
238
190
|
end
|
239
191
|
|
240
|
-
# Groups a sequence into subsequences. The subsequences are determined by
|
241
|
-
# strings; adjacent non-string elements will be put into separate groups,
|
242
|
-
# but any element adjacent to a string will be grouped with that string.
|
243
|
-
#
|
244
|
-
# For example, `(A B "C" D E "F" G "H" "I" J)` will become `[(A) (B "C" D)
|
245
|
-
# (E "F" G "H" "I" J)]`.
|
246
|
-
#
|
247
|
-
# @param seq [Array]
|
248
|
-
# @return [Array<Array>]
|
249
192
|
def group_selectors(seq)
|
250
193
|
newseq = []
|
251
194
|
tail = seq.dup
|
@@ -259,12 +202,6 @@ module Sass
|
|
259
202
|
return newseq
|
260
203
|
end
|
261
204
|
|
262
|
-
# Given two sequences of simple selectors, returns whether `sseq1` is a
|
263
|
-
# superselector of `sseq2`.
|
264
|
-
#
|
265
|
-
# @param sseq1 [Array<SimpleSelector or String>]
|
266
|
-
# @param sseq2 [Array<SimpleSelector or String>]
|
267
|
-
# @return [Boolean]
|
268
205
|
def subweave_superselector?(sseq1, sseq2)
|
269
206
|
if sseq1.size > 1
|
270
207
|
# More complex selectors are never superselectors of less complex ones
|
data/lib/sass/selector/simple.rb
CHANGED
@@ -33,12 +33,6 @@ module Sass
|
|
33
33
|
to_a.map {|e| e.is_a?(Sass::Script::Node) ? "\#{#{e.to_sass}}" : e}.join
|
34
34
|
end
|
35
35
|
|
36
|
-
# @see \{#inspect}
|
37
|
-
# @return [String]
|
38
|
-
def to_s
|
39
|
-
inspect
|
40
|
-
end
|
41
|
-
|
42
36
|
# Returns a hash code for this selector object.
|
43
37
|
#
|
44
38
|
# By default, this is based on the value of \{#to\_a},
|
@@ -85,7 +79,7 @@ module Sass
|
|
85
79
|
sels_with_ix = Sass::Util.enum_with_index(sels)
|
86
80
|
_, i =
|
87
81
|
if self.is_a?(Pseudo) || self.is_a?(SelectorPseudoClass)
|
88
|
-
sels_with_ix.find {|sel, _| sel.is_a?(Pseudo) &&
|
82
|
+
sels_with_ix.find {|sel, _| sel.is_a?(Pseudo) && sels.last.type == :element}
|
89
83
|
else
|
90
84
|
sels_with_ix.find {|sel, _| sel.is_a?(Pseudo) || sel.is_a?(SelectorPseudoClass)}
|
91
85
|
end
|
@@ -54,28 +54,23 @@ module Sass
|
|
54
54
|
# Non-destrucively extends this selector with the extensions specified in a hash
|
55
55
|
# (which should come from {Sass::Tree::Visitors::Cssize}).
|
56
56
|
#
|
57
|
-
# @overload def do_extend(extends
|
58
|
-
# @param extends [{Selector::Simple =>
|
59
|
-
# Sass::Tree::Visitors::Cssize::Extend}]
|
57
|
+
# @overload def do_extend(extends)
|
58
|
+
# @param extends [{Selector::Simple => Selector::Sequence}]
|
60
59
|
# The extensions to perform on this selector
|
61
|
-
# @param parent_directives [Array<Sass::Tree::DirectiveNode>]
|
62
|
-
# The directives containing this selector.
|
63
60
|
# @return [Array<Sequence>] A list of selectors generated
|
64
61
|
# by extending this selector with `extends`.
|
65
62
|
# @see CommaSequence#do_extend
|
66
|
-
def do_extend(extends,
|
67
|
-
extends.get(members.to_set).map do |
|
63
|
+
def do_extend(extends, seen = Set.new)
|
64
|
+
extends.get(members.to_set).map do |seq, sels|
|
68
65
|
# If A {@extend B} and C {...},
|
69
|
-
#
|
66
|
+
# seq is A, sels is B, and self is C
|
70
67
|
|
71
68
|
self_without_sel = self.members - sels
|
72
|
-
next unless unified =
|
73
|
-
|
74
|
-
[sels, ex.extender.members[0...-1] + [unified]]
|
69
|
+
next unless unified = seq.members.last.unify(self_without_sel)
|
70
|
+
[sels, seq.members[0...-1] + [unified]]
|
75
71
|
end.compact.map do |sels, seq|
|
76
72
|
seq = Sequence.new(seq)
|
77
|
-
|
78
|
-
seq.do_extend(extends, parent_directives, seen + [sels])
|
73
|
+
seen.include?(sels) ? [] : seq.do_extend(extends, seen + [sels])
|
79
74
|
end.flatten.uniq
|
80
75
|
end
|
81
76
|
|
@@ -127,21 +122,6 @@ module Sass
|
|
127
122
|
|
128
123
|
private
|
129
124
|
|
130
|
-
def check_directives_match!(extend, parent_directives)
|
131
|
-
dirs1 = extend.directives.map {|d| d.value}
|
132
|
-
dirs2 = parent_directives.map {|d| d.value}
|
133
|
-
return true if Sass::Util.subsequence?(dirs1, dirs2)
|
134
|
-
|
135
|
-
Sass::Util.sass_warn <<WARNING
|
136
|
-
DEPRECATION WARNING on line #{extend.node.line}#{" of #{extend.node.filename}" if extend.node.filename}:
|
137
|
-
@extending an outer selector from within #{extend.directives.last.name} is deprecated.
|
138
|
-
You may only @extend selectors within the same directive.
|
139
|
-
This will be an error in Sass 3.3.
|
140
|
-
It can only work once @extend is supported natively in the browser.
|
141
|
-
WARNING
|
142
|
-
return false
|
143
|
-
end
|
144
|
-
|
145
125
|
def _hash
|
146
126
|
[base, Sass::Util.set_hash(rest)].hash
|
147
127
|
end
|
data/lib/sass/shared.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'strscan'
|
2
|
+
|
1
3
|
module Sass
|
2
4
|
# This module contains functionality that's shared between Haml and Sass.
|
3
5
|
module Shared
|
@@ -14,8 +16,8 @@ module Sass
|
|
14
16
|
# @yieldparam scan [StringScanner] The scanner scanning through the string
|
15
17
|
# @return [String] The text remaining in the scanner after all `#{`s have been processed
|
16
18
|
def handle_interpolation(str)
|
17
|
-
scan =
|
18
|
-
yield scan while scan.scan(/(.*?)(\\*)\#\{/
|
19
|
+
scan = StringScanner.new(str)
|
20
|
+
yield scan while scan.scan(/(.*?)(\\*)\#\{/)
|
19
21
|
scan.rest
|
20
22
|
end
|
21
23
|
|
@@ -38,7 +40,7 @@ module Sass
|
|
38
40
|
# `["Foo (Bar (Baz bang) bop)", " (Bang (bop bip))"]` in the example above.
|
39
41
|
def balance(scanner, start, finish, count = 0)
|
40
42
|
str = ''
|
41
|
-
scanner =
|
43
|
+
scanner = StringScanner.new(scanner) unless scanner.is_a? StringScanner
|
42
44
|
regexp = Regexp.new("(.*?)[\\#{start.chr}\\#{finish.chr}]", Regexp::MULTILINE)
|
43
45
|
while scanner.scan(regexp)
|
44
46
|
str << scanner.matched
|
@@ -6,18 +6,9 @@ module Sass::Tree
|
|
6
6
|
# @see Sass::Tree
|
7
7
|
class CommentNode < Node
|
8
8
|
# The text of the comment, not including `/*` and `*/`.
|
9
|
-
# Interspersed with {Sass::Script::Node}s representing `#{}`-interpolation
|
10
|
-
# if this is a loud comment.
|
11
|
-
#
|
12
|
-
# @return [Array<String, Sass::Script::Node>]
|
13
|
-
attr_accessor :value
|
14
|
-
|
15
|
-
# The text of the comment
|
16
|
-
# after any interpolated SassScript has been resolved.
|
17
|
-
# Only set once \{Tree::Visitors::Perform} has been run.
|
18
9
|
#
|
19
10
|
# @return [String]
|
20
|
-
attr_accessor :
|
11
|
+
attr_accessor :value
|
21
12
|
|
22
13
|
# Whether the comment is loud.
|
23
14
|
#
|
@@ -32,13 +23,14 @@ module Sass::Tree
|
|
32
23
|
# @return [Boolean]
|
33
24
|
attr_accessor :silent
|
34
25
|
|
35
|
-
# @param value [
|
26
|
+
# @param value [String] See \{#value}
|
36
27
|
# @param silent [Boolean] See \{#silent}
|
37
|
-
|
38
|
-
|
39
|
-
@value = Sass::Util.with_extracted_values(value) {|str| normalize_indentation str}
|
28
|
+
def initialize(value, silent)
|
29
|
+
@lines = []
|
40
30
|
@silent = silent
|
41
|
-
@
|
31
|
+
@value = normalize_indentation value
|
32
|
+
@loud = @value =~ %r{^(/[\/\*])?!}
|
33
|
+
@value.sub!("#{$1}!", $1.to_s) if @loud
|
42
34
|
super()
|
43
35
|
end
|
44
36
|
|
@@ -48,7 +40,7 @@ module Sass::Tree
|
|
48
40
|
# @return [Boolean] Whether or not this node and the other object
|
49
41
|
# are the same
|
50
42
|
def ==(other)
|
51
|
-
self.class == other.class && value == other.value && silent == other.silent
|
43
|
+
self.class == other.class && value == other.value && silent == other.silent
|
52
44
|
end
|
53
45
|
|
54
46
|
# Returns `true` if this is a silent comment
|
@@ -65,14 +57,9 @@ module Sass::Tree
|
|
65
57
|
end
|
66
58
|
end
|
67
59
|
|
68
|
-
# Returns
|
69
|
-
|
70
|
-
|
71
|
-
def lines
|
72
|
-
@value.inject(0) do |s, e|
|
73
|
-
next s + e.count("\n") if e.is_a?(String)
|
74
|
-
next s
|
75
|
-
end
|
60
|
+
# Returns whether this comment should be interpolated for dynamic comment generation.
|
61
|
+
def evaluated?
|
62
|
+
@loud
|
76
63
|
end
|
77
64
|
|
78
65
|
private
|
@@ -81,7 +68,7 @@ module Sass::Tree
|
|
81
68
|
pre = str.split("\n").inject(str[/^[ \t]*/].split("")) do |pre, line|
|
82
69
|
line[/^[ \t]*/].split("").zip(pre).inject([]) do |arr, (a, b)|
|
83
70
|
break arr if a != b
|
84
|
-
arr
|
71
|
+
arr + [a]
|
85
72
|
end
|
86
73
|
end.join
|
87
74
|
str.gsub(/^#{pre}/, '')
|