sass 3.1.0.alpha.12 → 3.1.0.alpha.13

Sign up to get free protection for your applications and to get access to all the features.
data/EDGE_GEM_VERSION CHANGED
@@ -1 +1 @@
1
- 3.1.0.alpha.12
1
+ 3.1.0.alpha.13
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.1.0.alpha.12
1
+ 3.1.0.alpha.13
@@ -22,12 +22,12 @@ module Sass
22
22
 
23
23
  # @param parent [Environment] See \{#parent}
24
24
  def initialize(parent = nil)
25
- @vars = {}
26
- @mixins = {}
27
25
  @parent = parent
28
- @stack = [] unless parent
29
- @mixins_in_use = Set.new unless parent
30
- set_var("important", Script::String.new("!important")) unless @parent
26
+ unless parent
27
+ @stack = []
28
+ @mixins_in_use = Set.new
29
+ set_var("important", Script::String.new("!important"))
30
+ end
31
31
  end
32
32
 
33
33
  # The options hash.
@@ -35,7 +35,7 @@ module Sass
35
35
  #
36
36
  # @return [{Symbol => Object}]
37
37
  def options
38
- @options || (parent && parent.options) || {}
38
+ @options || parent_options || {}
39
39
  end
40
40
 
41
41
  # Push a new stack frame onto the mixin/include stack.
@@ -53,13 +53,13 @@ module Sass
53
53
  # `:line`
54
54
  # : The line of the file on which the lexical scope changed. Never nil.
55
55
  def push_frame(frame_info)
56
- if stack.last && stack.last[:prepared]
57
- stack.last.delete(:prepared)
58
- stack.last.merge!(frame_info)
56
+ top_of_stack = stack.last
57
+ if top_of_stack && top_of_stack.delete(:prepared)
58
+ top_of_stack.merge!(frame_info)
59
59
  else
60
- stack.push(frame_info)
60
+ stack.push(top_of_stack = frame_info)
61
61
  end
62
- mixins_in_use << stack.last[:mixin] if stack.last[:mixin] && !stack.last[:prepared]
62
+ mixins_in_use << top_of_stack[:mixin] if top_of_stack[:mixin] && !top_of_stack[:prepared]
63
63
  end
64
64
 
65
65
  # Like \{#push\_frame}, but next time a stack frame is pushed,
@@ -93,28 +93,36 @@ module Sass
93
93
  @mixins_in_use ||= @parent.mixins_in_use
94
94
  end
95
95
 
96
+ private
97
+
98
+ def parent_options
99
+ @parent_options ||= @parent && @parent.options
100
+ end
101
+
96
102
  class << self
97
103
  private
104
+ UNDERSCORE, DASH = '_', '-'
98
105
 
99
106
  # Note: when updating this,
100
107
  # update sass/yard/inherited_hash.rb as well.
101
108
  def inherited_hash(name)
102
109
  class_eval <<RUBY, __FILE__, __LINE__ + 1
103
110
  def #{name}(name)
104
- _#{name}(name.gsub('_', '-'))
111
+ _#{name}(name.tr(UNDERSCORE, DASH))
105
112
  end
106
113
 
107
114
  def _#{name}(name)
108
- @#{name}s[name] || @parent && @parent._#{name}(name)
115
+ (@#{name}s && @#{name}s[name]) || @parent && @parent._#{name}(name)
109
116
  end
110
117
  protected :_#{name}
111
118
 
112
119
  def set_#{name}(name, value)
113
- name = name.gsub('_', '-')
120
+ name = name.tr(UNDERSCORE, DASH)
114
121
  @#{name}s[name] = value unless try_set_#{name}(name, value)
115
122
  end
116
123
 
117
124
  def try_set_#{name}(name, value)
125
+ @#{name}s ||= {}
118
126
  if @#{name}s.include?(name)
119
127
  @#{name}s[name] = value
120
128
  true
@@ -127,7 +135,8 @@ module Sass
127
135
  protected :try_set_#{name}
128
136
 
129
137
  def set_local_#{name}(name, value)
130
- @#{name}s[name.gsub('_', '-')] = value
138
+ @#{name}s ||= {}
139
+ @#{name}s[name.tr(UNDERSCORE, DASH)] = value
131
140
  end
132
141
  RUBY
133
142
  end
@@ -60,12 +60,12 @@ module Sass
60
60
  # @return [Literal] The SassScript object that is the value of the function call
61
61
  # @raise [Sass::SyntaxError] if the function call raises an ArgumentError
62
62
  def _perform(environment)
63
- args = self.args.map {|a| a.perform(environment)}
64
- ruby_name = name.gsub('-', '_')
63
+ performed_args = @args.map {|a| a.perform(environment)}
64
+ ruby_name = @name.tr('-', '_')
65
65
  unless Sass::Util.has?(:public_instance_method, Functions, ruby_name) && ruby_name !~ /^__/
66
- opts(Script::String.new("#{name}(#{args.map {|a| a.perform(environment)}.join(', ')})"))
66
+ opts(Script::String.new("#{name}(#{performed_args.join(', ')})"))
67
67
  else
68
- opts(Functions::EvaluationContext.new(environment.options).send(ruby_name, *args))
68
+ opts(Functions::EvaluationContext.new(environment.options).send(ruby_name, *performed_args))
69
69
  end
70
70
  rescue ArgumentError => e
71
71
  raise e unless e.backtrace.any? {|t| t =~ /:in `(block in )?(#{name}|perform)'$/}
@@ -41,10 +41,13 @@ module Sass::Script
41
41
  # @api public
42
42
  PRECISION = 1000.0
43
43
 
44
+ # Used so we don't allocate two new arrays for each new number.
45
+ NO_UNITS = []
46
+
44
47
  # @param value [Numeric] The value of the number
45
48
  # @param numerator_units [Array<String>] See \{#numerator\_units}
46
49
  # @param denominator_units [Array<String>] See \{#denominator\_units}
47
- def initialize(value, numerator_units = [], denominator_units = [])
50
+ def initialize(value, numerator_units = NO_UNITS, denominator_units = NO_UNITS)
48
51
  super(value)
49
52
  @numerator_units = numerator_units
50
53
  @denominator_units = denominator_units
@@ -107,7 +110,7 @@ module Sass::Script
107
110
  #
108
111
  # @return [Number] The negative value of this number
109
112
  def unary_minus
110
- Number.new(-value, numerator_units, denominator_units)
113
+ Number.new(-value, @numerator_units, @denominator_units)
111
114
  end
112
115
 
113
116
  # The SassScript `*` operation.
@@ -183,7 +186,7 @@ module Sass::Script
183
186
  if unitless?
184
187
  this = this.coerce(other.numerator_units, other.denominator_units)
185
188
  else
186
- other = other.coerce(numerator_units, denominator_units)
189
+ other = other.coerce(@numerator_units, @denominator_units)
187
190
  end
188
191
  rescue Sass::UnitConversionError
189
192
  return Sass::Script::Bool.new(false)
@@ -248,7 +251,8 @@ module Sass::Script
248
251
  #
249
252
  # @return [String] The representation
250
253
  def inspect(opts = {})
251
- "#{self.class.round(self.value)}#{unit_str}"
254
+ value = self.class.round(self.value)
255
+ unitless? ? value.to_s : "#{value}#{unit_str}"
252
256
  end
253
257
  alias_method :to_sass, :inspect
254
258
 
@@ -266,13 +270,13 @@ module Sass::Script
266
270
 
267
271
  # @return [Boolean] Whether or not this number has no units.
268
272
  def unitless?
269
- numerator_units.empty? && denominator_units.empty?
273
+ @numerator_units.empty? && @denominator_units.empty?
270
274
  end
271
275
 
272
276
  # @return [Boolean] Whether or not this number has units that can be represented in CSS
273
277
  # (that is, zero or one \{#numerator\_units}).
274
278
  def legal_units?
275
- (numerator_units.empty? || numerator_units.size == 1) && denominator_units.empty?
279
+ (@numerator_units.empty? || @numerator_units.size == 1) && @denominator_units.empty?
276
280
  end
277
281
 
278
282
  # Returns this number converted to other units.
@@ -295,8 +299,8 @@ module Sass::Script
295
299
  Number.new(if unitless?
296
300
  self.value
297
301
  else
298
- self.value * coercion_factor(self.numerator_units, num_units) /
299
- coercion_factor(self.denominator_units, den_units)
302
+ self.value * coercion_factor(@numerator_units, num_units) /
303
+ coercion_factor(@denominator_units, den_units)
300
304
  end, num_units, den_units)
301
305
  end
302
306
 
@@ -316,10 +320,10 @@ module Sass::Script
316
320
  # numerator_unit1 * numerator_unit2 / denominator_unit1 * denominator_unit2
317
321
  # @return [String] a string that represents the units in this number
318
322
  def unit_str
319
- rv = numerator_units.sort.join("*")
320
- if denominator_units.any?
323
+ rv = @numerator_units.sort.join("*")
324
+ if @denominator_units.any?
321
325
  rv << "/"
322
- rv << denominator_units.sort.join("*")
326
+ rv << @denominator_units.sort.join("*")
323
327
  end
324
328
  rv
325
329
  end
@@ -337,13 +341,15 @@ module Sass::Script
337
341
  end
338
342
  end
339
343
 
344
+ OPERATIONS = [:+, :-, :<=, :<, :>, :>=]
345
+
340
346
  def operate(other, operation)
341
347
  this = self
342
- if [:+, :-, :<=, :<, :>, :>=].include?(operation)
348
+ if OPERATIONS.include?(operation)
343
349
  if unitless?
344
350
  this = this.coerce(other.numerator_units, other.denominator_units)
345
351
  else
346
- other = other.coerce(numerator_units, denominator_units)
352
+ other = other.coerce(@numerator_units, @denominator_units)
347
353
  end
348
354
  end
349
355
  # avoid integer division
@@ -381,7 +387,7 @@ module Sass::Script
381
387
 
382
388
  def normalize!
383
389
  return if unitless?
384
- @numerator_units, @denominator_units = sans_common_units(numerator_units, denominator_units)
390
+ @numerator_units, @denominator_units = sans_common_units(@numerator_units, @denominator_units)
385
391
 
386
392
  @denominator_units.each_with_index do |d, i|
387
393
  if convertable?(d) && (u = @numerator_units.detect(&method(:convertable?)))
@@ -407,7 +413,7 @@ module Sass::Script
407
413
  end
408
414
 
409
415
  def convertable?(units)
410
- Array(units).all?(&CONVERTABLE_UNITS.method(:include?))
416
+ Array(units).all? {|u| CONVERTABLE_UNITS.include?(u)}
411
417
  end
412
418
 
413
419
  def sans_common_units(units1, units2)
@@ -41,9 +41,8 @@ module Sass::Script
41
41
 
42
42
  # @see Node#to_s
43
43
  def to_s(opts = {})
44
- if self.type == :identifier
45
- return %q{""} if context == :equals && self.value.size == 0
46
- return self.value.gsub("\n", " ")
44
+ if @type == :identifier
45
+ return @context == :equals && @value.empty? ? %q{""} : @value.tr("\n", " ")
47
46
  end
48
47
 
49
48
  return "\"#{value.gsub('"', "\\\"")}\"" if opts[:quote] == %q{"}
@@ -821,17 +821,20 @@ MESSAGE
821
821
  :line => line)
822
822
  end
823
823
 
824
+ # Avoid allocating lots of new strings for `#tok`.
825
+ # This is important because `#tok` is called all the time.
826
+ NEWLINE = "\n"
827
+
824
828
  def tok(rx)
825
829
  res = @scanner.scan(rx)
826
830
  if res
827
- @line += res.count("\n")
831
+ @line += res.count(NEWLINE)
828
832
  @expected = nil
829
833
  if !@strs.empty? && rx != COMMENT && rx != SINGLE_LINE_COMMENT
830
834
  @strs.each {|s| s << res}
831
835
  end
836
+ res
832
837
  end
833
-
834
- res
835
838
  end
836
839
  end
837
840
  end
@@ -48,12 +48,12 @@ module Sass
48
48
  # @raise [Sass::SyntaxError] If a parent selector is invalid
49
49
  def resolve_parent_refs(super_seq)
50
50
  members = @members
51
- members.slice!(0) if nl = (members.first == "\n")
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
- members << "\n" if nl
56
+ members << nl if nl
57
57
  members << SimpleSequence.new([Parent.new])
58
58
  members += @members
59
59
  end
@@ -148,8 +148,8 @@ module Sass
148
148
  # @param args [Array] Passed on to \{#\_to\_s}
149
149
  # @return [String, nil] The resulting CSS
150
150
  # @see Sass::Tree
151
- def to_s(*args)
152
- _to_s(*args)
151
+ def to_s(opts = nil)
152
+ _to_s(opts)
153
153
  rescue Sass::SyntaxError => e
154
154
  e.modify_backtrace(:filename => filename, :line => line)
155
155
  raise e
@@ -88,8 +88,12 @@ module Sass::Tree
88
88
  # @param tabs [Fixnum] The level of indentation for the CSS
89
89
  # @return [String] The resulting CSS
90
90
  def _to_s(tabs)
91
- to_return = ' ' * (tabs - 1 + self.tabs) + resolved_name + ":" +
92
- (style == :compressed ? '' : ' ') + resolved_value + (style == :compressed ? "" : ";")
91
+ tab_str = ' ' * (tabs - 1 + self.tabs)
92
+ if style == :compressed
93
+ "#{tab_str}#{resolved_name}:#{resolved_value}"
94
+ else
95
+ "#{tab_str}#{resolved_name}: #{resolved_value};"
96
+ end
93
97
  end
94
98
 
95
99
  # Converts nested properties into flat properties.
@@ -154,10 +158,9 @@ module Sass::Tree
154
158
  private
155
159
 
156
160
  def check!
157
- if @options[:property_syntax] == :old && @prop_syntax == :new
158
- raise Sass::SyntaxError.new("Illegal property syntax: can't use new syntax when :property_syntax => :old is set.")
159
- elsif @options[:property_syntax] == :new && @prop_syntax == :old
160
- raise Sass::SyntaxError.new("Illegal property syntax: can't use old syntax when :property_syntax => :new is set.")
161
+ if @options[:property_syntax] && @options[:property_syntax] != @prop_syntax
162
+ raise Sass::SyntaxError.new(
163
+ "Illegal property syntax: can't use #{@prop_syntax} syntax when :property_syntax => #{@options[:property_syntax].inspect} is set.")
161
164
  elsif resolved_value.empty?
162
165
  raise Sass::SyntaxError.new("Invalid property: #{declaration.dump} (no value)." +
163
166
  pseudo_class_selector_message)
@@ -121,17 +121,18 @@ module Sass::Tree
121
121
  # @param tabs [Fixnum] The level of indentation for the CSS
122
122
  # @return [String] The resulting CSS
123
123
  def _to_s(tabs)
124
+ output_style = style
124
125
  tabs = tabs + self.tabs
125
126
 
126
- rule_separator = style == :compressed ? ',' : ', '
127
+ rule_separator = output_style == :compressed ? ',' : ', '
127
128
  line_separator =
128
- case style
129
+ case output_style
129
130
  when :nested, :expanded; "\n"
130
131
  when :compressed; ""
131
132
  else; " "
132
133
  end
133
134
  rule_indent = ' ' * (tabs - 1)
134
- per_rule_indent, total_indent = [:nested, :expanded].include?(style) ? [rule_indent, ''] : ['', rule_indent]
135
+ per_rule_indent, total_indent = [:nested, :expanded].include?(output_style) ? [rule_indent, ''] : ['', rule_indent]
135
136
 
136
137
  total_rule = total_indent + resolved_rules.members.
137
138
  map {|seq| seq.to_a.join.gsub(/([^,])\n/m, style == :compressed ? '\1 ' : "\\1\n")}.
@@ -142,7 +143,7 @@ module Sass::Tree
142
143
  to_return = ''
143
144
  old_spaces = ' ' * (tabs - 1)
144
145
  spaces = ' ' * tabs
145
- if style != :compressed
146
+ if output_style != :compressed
146
147
  if @options[:debug_info]
147
148
  to_return << debug_info_rule.to_s(tabs) << "\n"
148
149
  elsif @options[:line_comments]
@@ -165,15 +166,15 @@ module Sass::Tree
165
166
  end
166
167
  end
167
168
 
168
- if style == :compact
169
+ if output_style == :compact
169
170
  properties = children.map { |a| a.to_s(1) }.join(' ')
170
171
  to_return << "#{total_rule} { #{properties} }#{"\n" if group_end}"
171
- elsif style == :compressed
172
+ elsif output_style == :compressed
172
173
  properties = children.map { |a| a.to_s(1) }.join(';')
173
174
  to_return << "#{total_rule}{#{properties}}"
174
175
  else
175
176
  properties = children.map { |a| a.to_s(tabs + 1) }.join("\n")
176
- end_props = (style == :expanded ? "\n" + old_spaces : ' ')
177
+ end_props = (output_style == :expanded ? "\n" + old_spaces : ' ')
177
178
  to_return << "#{total_rule} {\n#{properties}#{end_props}}#{"\n" if group_end}"
178
179
  end
179
180
 
@@ -199,7 +200,7 @@ module Sass::Tree
199
200
  # or nil if the parent isn't a {RuleNode}
200
201
  def _cssize(extends, parent)
201
202
  node = super
202
- rules = node.children.select {|c| c.is_a?(RuleNode)}
203
+ rules = node.children.grep(RuleNode)
203
204
  props = node.children.reject {|c| c.is_a?(RuleNode) || c.invisible?}
204
205
 
205
206
  unless props.empty?
data/lib/sass/util.rb CHANGED
@@ -121,10 +121,12 @@ module Sass
121
121
  # @example
122
122
  # merge_adjacent_strings([1, "foo", "bar", 2, "baz"])
123
123
  # #=> [1, "foobar", 2, "baz"]
124
- # @param enum [Enumerable]
124
+ # @param arr [Array]
125
125
  # @return [Array] The enumerable with strings merged
126
- def merge_adjacent_strings(enum)
127
- enum.inject([]) do |a, e|
126
+ def merge_adjacent_strings(arr)
127
+ # Optimize for the common case of one element
128
+ return arr if arr.size < 2
129
+ arr.inject([]) do |a, e|
128
130
  if e.is_a?(String)
129
131
  if a.last.is_a?(String)
130
132
  a.last << e
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sass
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0.alpha.12
4
+ version: 3.1.0.alpha.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Weizenbaum
@@ -11,7 +11,7 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2010-10-01 00:00:00 -04:00
14
+ date: 2010-10-03 00:00:00 -04:00
15
15
  default_executable:
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency