sass 3.3.0.rc.1 → 3.3.0.rc.2
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/Rakefile +1 -1
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/lib/sass.rb +5 -0
- data/lib/sass/engine.rb +3 -5
- data/lib/sass/plugin.rb +0 -1
- data/lib/sass/plugin/compiler.rb +1 -2
- data/lib/sass/script/functions.rb +16 -2
- data/lib/sass/script/lexer.rb +22 -12
- data/lib/sass/script/parser.rb +27 -14
- data/lib/sass/script/tree/variable.rb +1 -1
- data/lib/sass/script/value/base.rb +1 -1
- data/lib/sass/script/value/color.rb +29 -17
- data/lib/sass/script/value/list.rb +1 -1
- data/lib/sass/script/value/number.rb +8 -1
- data/lib/sass/scss/parser.rb +2 -2
- data/lib/sass/selector/sequence.rb +18 -19
- data/lib/sass/selector/simple_sequence.rb +5 -5
- data/lib/sass/source/map.rb +1 -1
- data/lib/sass/tree/node.rb +25 -0
- data/lib/sass/tree/variable_node.rb +5 -0
- data/lib/sass/tree/visitors/base.rb +4 -7
- data/lib/sass/tree/visitors/check_nesting.rb +2 -2
- data/lib/sass/tree/visitors/perform.rb +12 -7
- data/lib/sass/util.rb +95 -50
- data/lib/sass/util/normalized_map.rb +63 -14
- data/lib/sass/util/ordered_hash.rb +9 -5
- data/lib/sass/version.rb +10 -12
- data/test/sass/engine_test.rb +37 -0
- data/test/sass/functions_test.rb +9 -2
- data/test/sass/importer_test.rb +3 -3
- data/test/sass/script_test.rb +12 -10
- data/test/sass/source_map_test.rb +8 -8
- data/test/sass/util/normalized_map_test.rb +22 -1
- data/test/sass/util_test.rb +18 -0
- data/test/test_helper.rb +16 -0
- data/vendor/listen/CHANGELOG.md +228 -0
- data/vendor/listen/CONTRIBUTING.md +38 -0
- data/vendor/listen/Gemfile +30 -0
- data/vendor/listen/Guardfile +8 -0
- data/vendor/listen/LICENSE +20 -0
- data/vendor/listen/README.md +315 -0
- data/vendor/listen/Rakefile +47 -0
- data/vendor/listen/Vagrantfile +96 -0
- data/vendor/listen/lib/listen.rb +40 -0
- data/vendor/listen/lib/listen/adapter.rb +214 -0
- data/vendor/listen/lib/listen/adapters/bsd.rb +112 -0
- data/vendor/listen/lib/listen/adapters/darwin.rb +85 -0
- data/vendor/listen/lib/listen/adapters/linux.rb +113 -0
- data/vendor/listen/lib/listen/adapters/polling.rb +67 -0
- data/vendor/listen/lib/listen/adapters/windows.rb +87 -0
- data/vendor/listen/lib/listen/dependency_manager.rb +126 -0
- data/vendor/listen/lib/listen/directory_record.rb +371 -0
- data/vendor/listen/lib/listen/listener.rb +225 -0
- data/vendor/listen/lib/listen/multi_listener.rb +143 -0
- data/vendor/listen/lib/listen/turnstile.rb +28 -0
- data/vendor/listen/lib/listen/version.rb +3 -0
- data/vendor/listen/listen.gemspec +22 -0
- data/vendor/listen/spec/listen/adapter_spec.rb +183 -0
- data/vendor/listen/spec/listen/adapters/bsd_spec.rb +36 -0
- data/vendor/listen/spec/listen/adapters/darwin_spec.rb +37 -0
- data/vendor/listen/spec/listen/adapters/linux_spec.rb +47 -0
- data/vendor/listen/spec/listen/adapters/polling_spec.rb +68 -0
- data/vendor/listen/spec/listen/adapters/windows_spec.rb +30 -0
- data/vendor/listen/spec/listen/dependency_manager_spec.rb +107 -0
- data/vendor/listen/spec/listen/directory_record_spec.rb +1225 -0
- data/vendor/listen/spec/listen/listener_spec.rb +169 -0
- data/vendor/listen/spec/listen/multi_listener_spec.rb +174 -0
- data/vendor/listen/spec/listen/turnstile_spec.rb +56 -0
- data/vendor/listen/spec/listen_spec.rb +73 -0
- data/vendor/listen/spec/spec_helper.rb +21 -0
- data/vendor/listen/spec/support/adapter_helper.rb +629 -0
- data/vendor/listen/spec/support/directory_record_helper.rb +55 -0
- data/vendor/listen/spec/support/fixtures_helper.rb +29 -0
- data/vendor/listen/spec/support/listeners_helper.rb +156 -0
- data/vendor/listen/spec/support/platform_helper.rb +15 -0
- metadata +318 -300
- data/test/Gemfile.lock +0 -10
@@ -93,7 +93,7 @@ module Sass
|
|
93
93
|
choices
|
94
94
|
end
|
95
95
|
weaves = Sass::Util.paths(extended_not_expanded).map {|path| weave(path)}
|
96
|
-
|
96
|
+
trim(weaves).map {|p| Sequence.new(p)}
|
97
97
|
end
|
98
98
|
|
99
99
|
# Returns whether or not this selector matches all elements
|
@@ -137,32 +137,31 @@ module Sass
|
|
137
137
|
|
138
138
|
private
|
139
139
|
|
140
|
-
# Conceptually, this expands "parenthesized selectors".
|
141
|
-
#
|
142
|
-
#
|
143
|
-
#
|
140
|
+
# Conceptually, this expands "parenthesized selectors". That is, if we
|
141
|
+
# have `.A .B {@extend .C}` and `.D .C {...}`, this conceptually expands
|
142
|
+
# into `.D .C, .D (.A .B)`, and this function translates `.D (.A .B)` into
|
143
|
+
# `.D .A .B, .A .D .B`. For thoroughness, `.A.D .B` would also be
|
144
|
+
# required, but including merged selectors results in exponential output
|
145
|
+
# for very little gain.
|
144
146
|
#
|
145
147
|
# @param path [Array<Array<SimpleSequence or String>>]
|
146
148
|
# A list of parenthesized selector groups.
|
147
149
|
# @return [Array<Array<SimpleSequence or String>>] A list of fully-expanded selectors.
|
148
150
|
def weave(path)
|
149
151
|
# This function works by moving through the selector path left-to-right,
|
150
|
-
# building all possible prefixes simultaneously.
|
151
|
-
|
152
|
-
befores = [[]]
|
153
|
-
afters = path.dup
|
152
|
+
# building all possible prefixes simultaneously.
|
153
|
+
prefixes = [[]]
|
154
154
|
|
155
|
-
|
156
|
-
current =
|
155
|
+
path.each do |current|
|
156
|
+
current = current.dup
|
157
157
|
last_current = [current.pop]
|
158
|
-
|
159
|
-
sub = subweave(
|
158
|
+
prefixes = Sass::Util.flatten(prefixes.map do |prefix|
|
159
|
+
sub = subweave(prefix, current)
|
160
160
|
next [] unless sub
|
161
161
|
sub.map {|seqs| seqs + last_current}
|
162
|
-
end
|
163
|
-
befores = Sass::Util.flatten(befores, 1)
|
162
|
+
end, 1)
|
164
163
|
end
|
165
|
-
|
164
|
+
prefixes
|
166
165
|
end
|
167
166
|
|
168
167
|
# This interweaves two lists of selectors,
|
@@ -455,11 +454,11 @@ module Sass
|
|
455
454
|
# the other. The more specific selector is removed.
|
456
455
|
#
|
457
456
|
# @param seqses [Array<Array<Array<SimpleSequence or String>>>]
|
458
|
-
# @return [Array<Array<
|
457
|
+
# @return [Array<Array<SimpleSequence or String>>]
|
459
458
|
def trim(seqses)
|
460
459
|
# Avoid truly horrific quadratic behavior. TODO: I think there
|
461
460
|
# may be a way to get perfect trimming without going quadratic.
|
462
|
-
return seqses if seqses.size > 100
|
461
|
+
return Sass::Util.flatten(seqses, 1) if seqses.size > 100
|
463
462
|
|
464
463
|
# Keep the results in a separate array so we can be sure we aren't
|
465
464
|
# comparing against an already-trimmed selector. This ensures that two
|
@@ -482,7 +481,7 @@ module Sass
|
|
482
481
|
end
|
483
482
|
end
|
484
483
|
end
|
485
|
-
result
|
484
|
+
Sass::Util.flatten(result, 1)
|
486
485
|
end
|
487
486
|
|
488
487
|
def _hash
|
@@ -107,18 +107,18 @@ module Sass
|
|
107
107
|
# by extending this selector with `extends`.
|
108
108
|
# @see CommaSequence#do_extend
|
109
109
|
def do_extend(extends, parent_directives, seen = Set.new)
|
110
|
-
groups = Sass::Util.group_by_to_a(extends
|
110
|
+
groups = Sass::Util.group_by_to_a(extends[members.to_set]) {|ex| ex.extender}
|
111
111
|
groups.map! do |seq, group|
|
112
|
-
sels = group.map {|
|
112
|
+
sels = group.map {|e| e.target}.flatten
|
113
113
|
# If A {@extend B} and C {...},
|
114
114
|
# seq is A, sels is B, and self is C
|
115
115
|
|
116
116
|
self_without_sel = Sass::Util.array_minus(members, sels)
|
117
|
-
group.each {|e
|
117
|
+
group.each {|e| e.result = :failed_to_unify unless e.result == :succeeded}
|
118
118
|
unified = seq.members.last.unify(self_without_sel, subject?)
|
119
119
|
next unless unified
|
120
|
-
group.each {|e
|
121
|
-
group.each {|e
|
120
|
+
group.each {|e| e.result = :succeeded}
|
121
|
+
group.each {|e| check_directives_match!(e, parent_directives)}
|
122
122
|
new_seq = Sequence.new(seq.members[0...-1] + [unified])
|
123
123
|
new_seq.add_sources!(sources + [seq])
|
124
124
|
[sels, new_seq]
|
data/lib/sass/source/map.rb
CHANGED
@@ -104,7 +104,7 @@ module Sass::Source
|
|
104
104
|
css_uri ||= css_path.relative_path_from(sourcemap_path.dirname).to_s
|
105
105
|
|
106
106
|
result = "{\n"
|
107
|
-
write_json_field(result, "version",
|
107
|
+
write_json_field(result, "version", 3, true)
|
108
108
|
|
109
109
|
source_uri_to_id = {}
|
110
110
|
id_to_source_uri = {}
|
data/lib/sass/tree/node.rb
CHANGED
@@ -30,6 +30,31 @@ module Sass
|
|
30
30
|
class Node
|
31
31
|
include Enumerable
|
32
32
|
|
33
|
+
def self.inherited(base)
|
34
|
+
node_name = base.name.gsub(/.*::(.*?)Node$/, '\\1').downcase
|
35
|
+
base.instance_eval <<-METHODS
|
36
|
+
# @return [Symbol] The name that is used for this node when visiting.
|
37
|
+
def node_name
|
38
|
+
:#{node_name}
|
39
|
+
end
|
40
|
+
|
41
|
+
# @return [Symbol] The method that is used on the visitor to visit nodes of this type.
|
42
|
+
def visit_method
|
43
|
+
:visit_#{node_name}
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return [Symbol] The method name that determines if the parent is invalid.
|
47
|
+
def invalid_child_method_name
|
48
|
+
:"invalid_#{node_name}_child?"
|
49
|
+
end
|
50
|
+
|
51
|
+
# @return [Symbol] The method name that determines if the node is an invalid parent.
|
52
|
+
def invalid_parent_method_name
|
53
|
+
:"invalid_#{node_name}_parent?"
|
54
|
+
end
|
55
|
+
METHODS
|
56
|
+
end
|
57
|
+
|
33
58
|
# The child nodes of this node.
|
34
59
|
#
|
35
60
|
# @return [Array<Tree::Node>]
|
@@ -20,6 +20,11 @@ module Sass
|
|
20
20
|
# @return [Boolean]
|
21
21
|
attr_reader :global
|
22
22
|
|
23
|
+
# Whether we've warned about deprecated global variable
|
24
|
+
# assignment yet for this node.
|
25
|
+
# @return [Boolean]
|
26
|
+
attr_accessor :global_warning_given
|
27
|
+
|
23
28
|
# @param name [String] The name of the variable
|
24
29
|
# @param expr [Script::Tree::Node] See \{#expr}
|
25
30
|
# @param guarded [Boolean] See \{#guarded}
|
@@ -32,9 +32,8 @@ module Sass::Tree::Visitors
|
|
32
32
|
# @param node [Tree::Node] The node to visit.
|
33
33
|
# @return [Object] The return value of the `visit_*` method for this node.
|
34
34
|
def visit(node)
|
35
|
-
|
36
|
-
|
37
|
-
send(method, node) {visit_children(node)}
|
35
|
+
if respond_to?(node.class.visit_method, true)
|
36
|
+
send(node.class.visit_method, node) {visit_children(node)}
|
38
37
|
else
|
39
38
|
visit_children(node)
|
40
39
|
end
|
@@ -53,15 +52,13 @@ module Sass::Tree::Visitors
|
|
53
52
|
parent.children.map {|c| visit(c)}
|
54
53
|
end
|
55
54
|
|
56
|
-
NODE_NAME_RE = /.*::(.*?)Node$/
|
57
|
-
|
58
55
|
# Returns the name of a node as used in the `visit_*` method.
|
59
56
|
#
|
60
57
|
# @param [Tree::Node] node The node.
|
61
58
|
# @return [String] The name.
|
62
59
|
def self.node_name(node)
|
63
|
-
|
64
|
-
|
60
|
+
Sass::Util.deprecated(self, "Call node.class.node_name instead.")
|
61
|
+
node.class.node_name
|
65
62
|
end
|
66
63
|
|
67
64
|
# `yield`s, then runs the visitor on the `@else` clause if the node has one.
|
@@ -9,8 +9,8 @@ class Sass::Tree::Visitors::CheckNesting < Sass::Tree::Visitors::Base
|
|
9
9
|
|
10
10
|
def visit(node)
|
11
11
|
if (error = @parent && (
|
12
|
-
try_send(
|
13
|
-
try_send(
|
12
|
+
try_send(@parent.class.invalid_child_method_name, @parent, node) ||
|
13
|
+
try_send(node.class.invalid_parent_method_name, @parent, node)))
|
14
14
|
raise Sass::SyntaxError.new(error)
|
15
15
|
end
|
16
16
|
super
|
@@ -99,7 +99,7 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
99
99
|
# @api private
|
100
100
|
# @return [Sass::Script::Value::ArgList]
|
101
101
|
def perform_splat(splat, performed_keywords, kwarg_splat, environment)
|
102
|
-
args, kwargs, separator = [],
|
102
|
+
args, kwargs, separator = [], nil, :comma
|
103
103
|
|
104
104
|
if splat
|
105
105
|
splat = splat.perform(environment)
|
@@ -113,8 +113,8 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
113
113
|
args = splat.to_a
|
114
114
|
end
|
115
115
|
end
|
116
|
-
|
117
|
-
kwargs
|
116
|
+
kwargs ||= Sass::Util.ordered_hash
|
117
|
+
kwargs.update(performed_keywords)
|
118
118
|
|
119
119
|
if kwarg_splat
|
120
120
|
kwarg_splat = kwarg_splat.perform(environment)
|
@@ -122,7 +122,7 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
122
122
|
raise Sass::SyntaxError.new("Variable keyword arguments must be a map " +
|
123
123
|
"(was #{kwarg_splat.inspect}).")
|
124
124
|
end
|
125
|
-
kwargs
|
125
|
+
kwargs.update(arg_hash(kwarg_splat))
|
126
126
|
end
|
127
127
|
|
128
128
|
Sass::Script::Value::ArgList.new(args, kwargs, separator)
|
@@ -195,7 +195,11 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
195
195
|
# Prints the expression to STDERR.
|
196
196
|
def visit_debug(node)
|
197
197
|
res = node.expr.perform(@environment)
|
198
|
-
|
198
|
+
if res.is_a?(Sass::Script::Value::String)
|
199
|
+
res = res.value
|
200
|
+
else
|
201
|
+
res = res.to_sass
|
202
|
+
end
|
199
203
|
if node.filename
|
200
204
|
Sass::Util.sass_warn "#{node.filename}:#{node.line} DEBUG: #{res}"
|
201
205
|
else
|
@@ -325,7 +329,7 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
325
329
|
end
|
326
330
|
|
327
331
|
args = node.args.map {|a| a.perform(@environment)}
|
328
|
-
keywords = Sass::Util.
|
332
|
+
keywords = Sass::Util.map_vals(node.keywords) {|v| v.perform(@environment)}
|
329
333
|
splat = self.class.perform_splat(node.splat, keywords, node.kwarg_splat, @environment)
|
330
334
|
|
331
335
|
self.class.perform_arguments(mixin, args, splat) do |env|
|
@@ -419,7 +423,8 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
419
423
|
env = @environment
|
420
424
|
if node.global
|
421
425
|
env = env.global_env
|
422
|
-
elsif env.parent && env.is_var_global?(node.name)
|
426
|
+
elsif env.parent && env.is_var_global?(node.name) && !node.global_warning_given
|
427
|
+
node.global_warning_given = true
|
423
428
|
var_expr = "$#{node.name}: #{node.expr.to_sass(env.options)} !global"
|
424
429
|
var_expr << " !default" if node.guarded
|
425
430
|
location = "on line #{node.line}"
|
data/lib/sass/util.rb
CHANGED
@@ -31,36 +31,6 @@ module Sass
|
|
31
31
|
File.join(Sass::ROOT_DIR, file)
|
32
32
|
end
|
33
33
|
|
34
|
-
# Converts a hash or a list of pairs into an order-preserving hash.
|
35
|
-
#
|
36
|
-
# On Ruby 1.8.7, this uses the orderedhash gem to simulate an
|
37
|
-
# order-preserving hash. On Ruby 1.9 and up, it just uses the native Hash
|
38
|
-
# class, since that preserves the order itself.
|
39
|
-
#
|
40
|
-
# @overload ordered_hash(hash)
|
41
|
-
# @param hash [Hash] a normal hash to convert to an ordered hash
|
42
|
-
# @return [Hash]
|
43
|
-
# @overload ordered_hash(*pairs)
|
44
|
-
# @example
|
45
|
-
# ordered_hash([:foo, "bar"], [:baz, "bang"])
|
46
|
-
# #=> {:foo => "bar", :baz => "bang"}
|
47
|
-
# ordered_hash #=> {}
|
48
|
-
# @param pairs [Array<(Object, Object)>] the list of key/value pairs for
|
49
|
-
# the hash.
|
50
|
-
# @return [Hash]
|
51
|
-
def ordered_hash(*pairs_or_hash)
|
52
|
-
require 'sass/util/ordered_hash' if ruby1_8?
|
53
|
-
|
54
|
-
if pairs_or_hash.length == 1 && pairs_or_hash.first.is_a?(Hash)
|
55
|
-
hash = pairs_or_hash.first
|
56
|
-
return hash unless ruby1_8?
|
57
|
-
return OrderedHash.new.merge hash
|
58
|
-
end
|
59
|
-
|
60
|
-
return Hash[pairs_or_hash] unless ruby1_8?
|
61
|
-
OrderedHash[*flatten(pairs_or_hash, 1)]
|
62
|
-
end
|
63
|
-
|
64
34
|
# Converts an array of `[key, value]` pairs to a hash.
|
65
35
|
#
|
66
36
|
# @example
|
@@ -85,7 +55,7 @@ module Sass
|
|
85
55
|
# @see #map_vals
|
86
56
|
# @see #map_hash
|
87
57
|
def map_keys(hash)
|
88
|
-
|
58
|
+
map_hash(hash) {|k, v| [yield(k), v]}
|
89
59
|
end
|
90
60
|
|
91
61
|
# Maps the values in a hash according to a block.
|
@@ -101,7 +71,13 @@ module Sass
|
|
101
71
|
# @see #map_keys
|
102
72
|
# @see #map_hash
|
103
73
|
def map_vals(hash)
|
104
|
-
|
74
|
+
# We don't delegate to map_hash for performance here
|
75
|
+
# because map_hash does more than is necessary.
|
76
|
+
rv = hash.class.new
|
77
|
+
hash.each do |k, v|
|
78
|
+
rv[k] = yield(v)
|
79
|
+
end
|
80
|
+
rv
|
105
81
|
end
|
106
82
|
|
107
83
|
# Maps the key-value pairs of a hash according to a block.
|
@@ -118,8 +94,15 @@ module Sass
|
|
118
94
|
# @see #map_keys
|
119
95
|
# @see #map_vals
|
120
96
|
def map_hash(hash)
|
121
|
-
#
|
122
|
-
to_hash
|
97
|
+
# Copy and modify is more performant than mapping to an array and using
|
98
|
+
# to_hash on the result.
|
99
|
+
rv = hash.class.new
|
100
|
+
hash.each do |k, v|
|
101
|
+
new_key, new_value = yield(k, v)
|
102
|
+
rv.delete(k)
|
103
|
+
rv[new_key] = new_value
|
104
|
+
end
|
105
|
+
rv
|
123
106
|
end
|
124
107
|
|
125
108
|
# Computes the powerset of the given array.
|
@@ -272,12 +255,12 @@ module Sass
|
|
272
255
|
#
|
273
256
|
# @param enum [Enumerable]
|
274
257
|
# @return [Array<[Object, Array]>] An array of pairs.
|
275
|
-
def group_by_to_a(enum
|
276
|
-
return enum.group_by(
|
258
|
+
def group_by_to_a(enum)
|
259
|
+
return enum.group_by {|e| yield(e)}.to_a unless ruby1_8?
|
277
260
|
order = {}
|
278
261
|
arr = []
|
279
262
|
groups = enum.group_by do |e|
|
280
|
-
res =
|
263
|
+
res = yield(e)
|
281
264
|
unless order.include?(res)
|
282
265
|
order[res] = order.size
|
283
266
|
end
|
@@ -415,6 +398,17 @@ module Sass
|
|
415
398
|
raise NotImplementedError.new("#{obj.class} must implement ##{caller_info[2]}")
|
416
399
|
end
|
417
400
|
|
401
|
+
# Prints a deprecation warning for the caller method.
|
402
|
+
#
|
403
|
+
# @param obj [Object] `self`
|
404
|
+
# @param message [String] A message describing what to do instead.
|
405
|
+
def deprecated(obj, message = nil)
|
406
|
+
obj_class = obj.is_a?(Class) ? "#{obj}." : "#{obj.class}#"
|
407
|
+
full_message = "DEPRECATION WARNING: #{obj_class}#{caller_info[2]} " +
|
408
|
+
"will be removed in a future version of Sass.#{("\n" + message) if message}"
|
409
|
+
Sass::Util.sass_warn full_message
|
410
|
+
end
|
411
|
+
|
418
412
|
# Silence all output to STDERR within a block.
|
419
413
|
#
|
420
414
|
# @yield A block in which no output will be printed to STDERR
|
@@ -507,33 +501,40 @@ module Sass
|
|
507
501
|
end
|
508
502
|
|
509
503
|
## Cross-OS Compatibility
|
504
|
+
#
|
505
|
+
# These methods are cached because some of them are called quite frequently
|
506
|
+
# and even basic checks like String#== are too costly to be called repeatedly.
|
510
507
|
|
511
508
|
# Whether or not this is running on Windows.
|
512
509
|
#
|
513
510
|
# @return [Boolean]
|
514
511
|
def windows?
|
515
|
-
|
512
|
+
return @windows if defined?(@windows)
|
513
|
+
@windows = (RbConfig::CONFIG['host_os'] =~ /mswin|windows|mingw/i)
|
516
514
|
end
|
517
515
|
|
518
516
|
# Whether or not this is running on IronRuby.
|
519
517
|
#
|
520
518
|
# @return [Boolean]
|
521
519
|
def ironruby?
|
522
|
-
|
520
|
+
return @ironruby if defined?(@ironruby)
|
521
|
+
@ironruby = RUBY_ENGINE == "ironruby"
|
523
522
|
end
|
524
523
|
|
525
524
|
# Whether or not this is running on Rubinius.
|
526
525
|
#
|
527
526
|
# @return [Boolean]
|
528
527
|
def rbx?
|
529
|
-
|
528
|
+
return @rbx if defined?(@rbx)
|
529
|
+
@rbx = RUBY_ENGINE == "rbx"
|
530
530
|
end
|
531
531
|
|
532
532
|
# Whether or not this is running on JRuby.
|
533
533
|
#
|
534
534
|
# @return [Boolean]
|
535
535
|
def jruby?
|
536
|
-
|
536
|
+
return @jruby if defined?(@jruby)
|
537
|
+
@jruby = RUBY_PLATFORM =~ /java/
|
537
538
|
end
|
538
539
|
|
539
540
|
# @see #jruby_version-class_method
|
@@ -551,9 +552,13 @@ module Sass
|
|
551
552
|
# Like `Dir.glob`, but works with backslash-separated paths on Windows.
|
552
553
|
#
|
553
554
|
# @param path [String]
|
554
|
-
def glob(path
|
555
|
+
def glob(path)
|
555
556
|
path = path.gsub('\\', '/') if windows?
|
556
|
-
|
557
|
+
if block_given?
|
558
|
+
Dir.glob(path) {|f| yield(f)}
|
559
|
+
else
|
560
|
+
Dir.glob(path)
|
561
|
+
end
|
557
562
|
end
|
558
563
|
|
559
564
|
# Prepare a value for a destructuring assignment (e.g. `a, b =
|
@@ -575,7 +580,8 @@ module Sass
|
|
575
580
|
#
|
576
581
|
# @return [Boolean]
|
577
582
|
def ruby1?
|
578
|
-
|
583
|
+
return @ruby1 if defined?(@ruby1)
|
584
|
+
@ruby1 = Sass::Util::RUBY_VERSION[0] <= 1
|
579
585
|
end
|
580
586
|
|
581
587
|
# Whether or not this is running under Ruby 1.8 or lower.
|
@@ -587,7 +593,9 @@ module Sass
|
|
587
593
|
def ruby1_8?
|
588
594
|
# IronRuby says its version is 1.9, but doesn't support any of the encoding APIs.
|
589
595
|
# We have to fall back to 1.8 behavior.
|
590
|
-
|
596
|
+
return @ruby1_8 if defined?(@ruby1_8)
|
597
|
+
@ruby1_8 = ironruby? ||
|
598
|
+
(Sass::Util::RUBY_VERSION[0] == 1 && Sass::Util::RUBY_VERSION[1] < 9)
|
591
599
|
end
|
592
600
|
|
593
601
|
# Whether or not this is running under Ruby 1.8.6 or lower.
|
@@ -595,21 +603,55 @@ module Sass
|
|
595
603
|
#
|
596
604
|
# @return [Boolean]
|
597
605
|
def ruby1_8_6?
|
598
|
-
|
606
|
+
return @ruby1_8_6 if defined?(@ruby1_8_6)
|
607
|
+
@ruby1_8_6 = ruby1_8? && Sass::Util::RUBY_VERSION[2] < 7
|
599
608
|
end
|
600
609
|
|
601
610
|
# Wehter or not this is running under JRuby 1.6 or lower.
|
602
611
|
def jruby1_6?
|
603
|
-
|
612
|
+
return @jruby1_6 if defined?(@jruby1_6)
|
613
|
+
@jruby1_6 = jruby? && jruby_version[0] == 1 && jruby_version[1] < 7
|
604
614
|
end
|
605
615
|
|
606
616
|
# Whether or not this is running under MacRuby.
|
607
617
|
#
|
608
618
|
# @return [Boolean]
|
609
619
|
def macruby?
|
610
|
-
|
620
|
+
return @macruby if defined?(@macruby)
|
621
|
+
@macruby = RUBY_ENGINE == 'macruby'
|
611
622
|
end
|
612
623
|
|
624
|
+
require 'sass/util/ordered_hash' if ruby1_8?
|
625
|
+
|
626
|
+
# Converts a hash or a list of pairs into an order-preserving hash.
|
627
|
+
#
|
628
|
+
# On Ruby 1.8.7, this uses the orderedhash gem to simulate an
|
629
|
+
# order-preserving hash. On Ruby 1.9 and up, it just uses the native Hash
|
630
|
+
# class, since that preserves the order itself.
|
631
|
+
#
|
632
|
+
# @overload ordered_hash(hash)
|
633
|
+
# @param hash [Hash] a normal hash to convert to an ordered hash
|
634
|
+
# @return [Hash]
|
635
|
+
# @overload ordered_hash(*pairs)
|
636
|
+
# @example
|
637
|
+
# ordered_hash([:foo, "bar"], [:baz, "bang"])
|
638
|
+
# #=> {:foo => "bar", :baz => "bang"}
|
639
|
+
# ordered_hash #=> {}
|
640
|
+
# @param pairs [Array<(Object, Object)>] the list of key/value pairs for
|
641
|
+
# the hash.
|
642
|
+
# @return [Hash]
|
643
|
+
def ordered_hash(*pairs_or_hash)
|
644
|
+
if pairs_or_hash.length == 1 && pairs_or_hash.first.is_a?(Hash)
|
645
|
+
hash = pairs_or_hash.first
|
646
|
+
return hash unless ruby1_8?
|
647
|
+
return OrderedHash.new.merge hash
|
648
|
+
end
|
649
|
+
|
650
|
+
return Hash[pairs_or_hash] unless ruby1_8?
|
651
|
+
(pairs_or_hash.is_a?(NormalizedMap) ? NormalizedMap : OrderedHash)[*flatten(pairs_or_hash, 1)]
|
652
|
+
end
|
653
|
+
|
654
|
+
|
613
655
|
# Checks that the encoding of a string is valid in Ruby 1.9
|
614
656
|
# and cleans up potential encoding gotchas like the UTF-8 BOM.
|
615
657
|
# If it's not, yields an error string describing the invalid character
|
@@ -1011,8 +1053,8 @@ MSG
|
|
1011
1053
|
#
|
1012
1054
|
# @param name [Symbol] The name of the variable
|
1013
1055
|
# @return [Boolean]
|
1014
|
-
def method_missing(name, *args
|
1015
|
-
super unless args.empty? &&
|
1056
|
+
def method_missing(name, *args)
|
1057
|
+
super unless args.empty? && !block_given?
|
1016
1058
|
@set.include?(name)
|
1017
1059
|
end
|
1018
1060
|
end
|
@@ -1053,6 +1095,7 @@ MSG
|
|
1053
1095
|
# Calculates the memoization table for the Least Common Subsequence algorithm.
|
1054
1096
|
# Algorithm from [Wikipedia](http://en.wikipedia.org/wiki/Longest_common_subsequence_problem#Computing_the_length_of_the_LCS)
|
1055
1097
|
def lcs_table(x, y)
|
1098
|
+
# This method does not take a block as an explicit parameter for performance reasons.
|
1056
1099
|
# rubocop:enable LineLength
|
1057
1100
|
c = Array.new(x.size) {[]}
|
1058
1101
|
x.size.times {|i| c[i][0] = 0}
|
@@ -1085,6 +1128,8 @@ MSG
|
|
1085
1128
|
return lcs_backtrace(c, x, y, i, j - 1, &block) if c[i][j - 1] > c[i - 1][j]
|
1086
1129
|
lcs_backtrace(c, x, y, i - 1, j, &block)
|
1087
1130
|
end
|
1131
|
+
|
1132
|
+
(Sass::Util.methods - Module.methods).each {|method| module_function method}
|
1088
1133
|
end
|
1089
1134
|
end
|
1090
1135
|
|