haml 3.0.24 → 3.0.25

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of haml might be problematic. Click here for more details.

data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.0.24
1
+ 3.0.25
@@ -3,81 +3,90 @@ require File.dirname(__FILE__) + '/../haml'
3
3
  require 'haml/engine'
4
4
  require 'rubygems'
5
5
  require 'cgi'
6
+ require 'hpricot'
6
7
 
7
8
  module Haml
8
9
  class HTML
9
10
  # A module containing utility methods that every Hpricot node
10
11
  # should have.
11
12
  module Node
12
- # Whether this node has already been converted to Haml.
13
- # Only used for text nodes and elements.
14
- #
15
- # @return [Boolean]
16
- attr_accessor :converted_to_haml
17
-
18
- # Returns the Haml representation of the given node.
19
- #
20
- # @param tabs [Fixnum] The indentation level of the resulting Haml.
21
- # @option options (see Haml::HTML#initialize)
22
- def to_haml(tabs, options)
23
- return "" if converted_to_haml || to_s.strip.empty?
24
- text = uninterp(self.to_s)
25
- node = next_node
26
- while node.is_a?(::Hpricot::Elem) && node.name == "haml:loud"
27
- node.converted_to_haml = true
28
- text << '#{' <<
29
- CGI.unescapeHTML(node.inner_text).gsub(/\n\s*/, ' ').strip << '}'
30
-
31
- if node.next_node.is_a?(::Hpricot::Text)
32
- node = node.next_node
33
- text << uninterp(node.to_s)
34
- node.converted_to_haml = true
35
- end
36
-
37
- node = node.next_node
38
- end
39
- return parse_text_with_interpolation(text, tabs)
40
- end
13
+ # We have to do everything in `#included`
14
+ # rather than including the methods in the module itself
15
+ # because if we do that, they don't propagate to the already-defined subclasses
16
+ # of the modules including this.
17
+ def self.included(base)
18
+ base.class_eval do
19
+ # Whether this node has already been converted to Haml.
20
+ # Only used for text nodes and elements.
21
+ #
22
+ # @return [Boolean]
23
+ attr_accessor :converted_to_haml
24
+
25
+ # Returns the Haml representation of the given node.
26
+ #
27
+ # @param tabs [Fixnum] The indentation level of the resulting Haml.
28
+ # @option options (see Haml::HTML#initialize)
29
+ def to_haml(tabs, options)
30
+ return "" if converted_to_haml || to_s.strip.empty?
31
+ text = uninterp(self.to_s)
32
+ node = next_node
33
+ while node.is_a?(::Hpricot::Elem) && node.name == "haml:loud"
34
+ node.converted_to_haml = true
35
+ text << '#{' <<
36
+ CGI.unescapeHTML(node.inner_text).gsub(/\n\s*/, ' ').strip << '}'
37
+
38
+ if node.next_node.is_a?(::Hpricot::Text)
39
+ node = node.next_node
40
+ text << uninterp(node.to_s)
41
+ node.converted_to_haml = true
42
+ end
41
43
 
42
- private
44
+ node = node.next_node
45
+ end
46
+ return parse_text_with_interpolation(text, tabs)
47
+ end
43
48
 
44
- def erb_to_interpolation(text, options)
45
- return text unless options[:erb]
46
- text = CGI.escapeHTML(uninterp(text))
47
- %w[<haml:loud> </haml:loud>].each {|str| text.gsub!(CGI.escapeHTML(str), str)}
48
- ::Hpricot::XML(text).children.inject("") do |str, elem|
49
- if elem.is_a?(::Hpricot::Text)
50
- str + CGI.unescapeHTML(elem.to_s)
51
- else # <haml:loud> element
52
- str + '#{' + CGI.unescapeHTML(elem.innerText.strip) + '}'
49
+ private
50
+
51
+ def erb_to_interpolation(text, options)
52
+ return text unless options[:erb]
53
+ text = CGI.escapeHTML(uninterp(text))
54
+ %w[<haml:loud> </haml:loud>].each {|str| text.gsub!(CGI.escapeHTML(str), str)}
55
+ ::Hpricot::XML(text).children.inject("") do |str, elem|
56
+ if elem.is_a?(::Hpricot::Text)
57
+ str + CGI.unescapeHTML(elem.to_s)
58
+ else # <haml:loud> element
59
+ str + '#{' + CGI.unescapeHTML(elem.innerText.strip) + '}'
60
+ end
61
+ end
53
62
  end
54
- end
55
- end
56
63
 
57
- def tabulate(tabs)
58
- ' ' * tabs
59
- end
64
+ def tabulate(tabs)
65
+ ' ' * tabs
66
+ end
60
67
 
61
- def uninterp(text)
62
- text.gsub('#{', '\#{') #'
63
- end
68
+ def uninterp(text)
69
+ text.gsub('#{', '\#{') #'
70
+ end
64
71
 
65
- def attr_hash
66
- attributes.to_hash
67
- end
72
+ def attr_hash
73
+ attributes.to_hash
74
+ end
68
75
 
69
- def parse_text(text, tabs)
70
- parse_text_with_interpolation(uninterp(text), tabs)
71
- end
76
+ def parse_text(text, tabs)
77
+ parse_text_with_interpolation(uninterp(text), tabs)
78
+ end
72
79
 
73
- def parse_text_with_interpolation(text, tabs)
74
- text.strip!
75
- return "" if text.empty?
80
+ def parse_text_with_interpolation(text, tabs)
81
+ text.strip!
82
+ return "" if text.empty?
76
83
 
77
- text.split("\n").map do |line|
78
- line.strip!
79
- "#{tabulate(tabs)}#{'\\' if Haml::Engine::SPECIAL_CHARACTERS.include?(line[0])}#{line}\n"
80
- end.join
84
+ text.split("\n").map do |line|
85
+ line.strip!
86
+ "#{tabulate(tabs)}#{'\\' if Haml::Engine::SPECIAL_CHARACTERS.include?(line[0])}#{line}\n"
87
+ end.join
88
+ end
89
+ end
81
90
  end
82
91
  end
83
92
  end
@@ -98,8 +107,6 @@ module Hpricot
98
107
  end
99
108
  end
100
109
 
101
- require 'hpricot'
102
-
103
110
  # @private
104
111
  HAML_TAGS = %w[haml:block haml:loud haml:silent]
105
112
 
@@ -237,7 +237,7 @@ module Sass
237
237
  comment_tab_str = nil
238
238
  first = true
239
239
  lines = []
240
- string.gsub(/\r|\n|\r\n|\r\n/, "\n").scan(/^.*?$/).each_with_index do |line, index|
240
+ string.gsub(/\r|\n|\r\n|\r\n/, "\n").scan(/^[^\n]*?$/).each_with_index do |line, index|
241
241
  index += (@options[:line] || 1)
242
242
  if line.strip.empty?
243
243
  lines.last.text << "\n" if lines.last && lines.last.comment?
@@ -67,12 +67,15 @@ module Sass
67
67
  return if options[:never_update]
68
68
 
69
69
  run_updating_stylesheets individual_files
70
-
71
- individual_files.each {|t, c| update_stylesheet(t, c)}
72
-
73
70
  @checked_for_updates = true
74
71
  staleness_checker = StalenessChecker.new
75
72
 
73
+ individual_files.each do |t, c|
74
+ if options[:always_update] || staleness_checker.stylesheet_needs_update?(c, t)
75
+ update_stylesheet(t, c)
76
+ end
77
+ end
78
+
76
79
  template_location_array.each do |template_location, css_location|
77
80
 
78
81
  Dir.glob(File.join(template_location, "**", "*.s[ca]ss")).sort.each do |file|
@@ -92,7 +92,7 @@ module Sass
92
92
  :number => /(-)?(?:(\d*\.\d+)|(\d+))([a-zA-Z%]+)?/,
93
93
  :color => HEXCOLOR,
94
94
  :bool => /(true|false)\b/,
95
- :ident_op => %r{(#{Regexp.union(*IDENT_OP_NAMES.map{|s| Regexp.new(Regexp.escape(s) + "(?!#{NMCHAR}|$)")})})},
95
+ :ident_op => %r{(#{Regexp.union(*IDENT_OP_NAMES.map{|s| Regexp.new(Regexp.escape(s) + "(?!#{NMCHAR}|\Z)")})})},
96
96
  :op => %r{(#{Regexp.union(*OP_NAMES)})},
97
97
  }
98
98
 
@@ -51,17 +51,5 @@ module Sass::Tree
51
51
  end
52
52
  children
53
53
  end
54
-
55
- # Returns an error message if the given child node is invalid,
56
- # and false otherwise.
57
- #
58
- # {ExtendNode}s are valid within {ForNode}s.
59
- #
60
- # @param child [Tree::Node] A potential child node.
61
- # @return [Boolean, String] Whether or not the child node is valid,
62
- # as well as the error message to display if it is invalid
63
- def invalid_child?(child)
64
- super unless child.is_a?(ExtendNode)
65
- end
66
54
  end
67
55
  end
@@ -65,17 +65,5 @@ module Sass::Tree
65
65
  return @else.perform(environment) if @else
66
66
  []
67
67
  end
68
-
69
- # Returns an error message if the given child node is invalid,
70
- # and false otherwise.
71
- #
72
- # {ExtendNode}s are valid within {IfNode}s.
73
- #
74
- # @param child [Tree::Node] A potential child node.
75
- # @return [Boolean, String] Whether or not the child node is valid,
76
- # as well as the error message to display if it is invalid
77
- def invalid_child?(child)
78
- super unless child.is_a?(ExtendNode)
79
- end
80
68
  end
81
69
  end
@@ -43,18 +43,6 @@ module Sass
43
43
  environment.set_mixin(@name, Sass::Mixin.new(@name, @args, environment, children))
44
44
  []
45
45
  end
46
-
47
- # Returns an error message if the given child node is invalid,
48
- # and false otherwise.
49
- #
50
- # {ExtendNode}s are valid within {MixinDefNode}s.
51
- #
52
- # @param child [Tree::Node] A potential child node.
53
- # @return [Boolean, String] Whether or not the child node is valid,
54
- # as well as the error message to display if it is invalid
55
- def invalid_child?(child)
56
- super unless child.is_a?(ExtendNode)
57
- end
58
46
  end
59
47
  end
60
48
  end
@@ -28,18 +28,6 @@ module Sass::Tree
28
28
 
29
29
  protected
30
30
 
31
- # Returns an error message if the given child node is invalid,
32
- # and false otherwise.
33
- #
34
- # {ExtendNode}s are valid within {MixinNode}s.
35
- #
36
- # @param child [Tree::Node] A potential child node
37
- # @return [Boolean, String] Whether or not the child node is valid,
38
- # as well as the error message to display if it is invalid
39
- def invalid_child?(child)
40
- super unless child.is_a?(ExtendNode)
41
- end
42
-
43
31
  # @see Node#to_src
44
32
  def to_src(tabs, opts, fmt)
45
33
  args = '(' + @args.map {|a| a.to_sass(opts)}.join(", ") + ')' unless @args.empty?
@@ -315,6 +315,7 @@ module Sass
315
315
  # @see #perform
316
316
  def perform!(environment)
317
317
  self.children = perform_children(Environment.new(environment))
318
+ self.children.each {|c| check_child! c}
318
319
  end
319
320
 
320
321
  # Non-destructively runs \{#perform} on all children of the current node.
@@ -368,8 +369,6 @@ module Sass
368
369
  "Mixins may only be defined at the root of a document."
369
370
  when Tree::ImportNode
370
371
  "Import directives may only be used at the root of a document."
371
- when Tree::ExtendNode
372
- "Extend directives may only be used within rules."
373
372
  end
374
373
  end
375
374
 
@@ -17,7 +17,7 @@ module Sass
17
17
  def to_s(*args)
18
18
  super
19
19
  rescue Sass::SyntaxError => e
20
- e.sass_template = @template
20
+ e.sass_template ||= @template
21
21
  raise e
22
22
  end
23
23
 
@@ -36,7 +36,7 @@ module Sass
36
36
  environment.options = @options if environment.options.nil? || environment.options.empty?
37
37
  super
38
38
  rescue Sass::SyntaxError => e
39
- e.sass_template = @template
39
+ e.sass_template ||= @template
40
40
  raise e
41
41
  end
42
42
 
@@ -49,7 +49,7 @@ module Sass
49
49
  def cssize(extends = Haml::Util::SubsetMap.new, parent = nil)
50
50
  return super(extends, parent), extends
51
51
  rescue Sass::SyntaxError => e
52
- e.sass_template = @template
52
+ e.sass_template ||= @template
53
53
  raise e
54
54
  end
55
55
 
@@ -148,9 +148,15 @@ module Sass
148
148
  #
149
149
  # @see Node#invalid_child?
150
150
  def invalid_child?(child)
151
- return unless child.is_a?(Tree::PropNode)
152
- "Properties aren't allowed at the root of a document." +
153
- child.pseudo_class_selector_message
151
+ case child
152
+ when Tree::ExtendNode
153
+ "Extend directives may only be used within rules."
154
+ when Tree::PropNode
155
+ "Properties aren't allowed at the root of a document." +
156
+ child.pseudo_class_selector_message
157
+ else
158
+ return
159
+ end
154
160
  end
155
161
  end
156
162
  end
@@ -226,18 +226,6 @@ module Sass::Tree
226
226
  super
227
227
  end
228
228
 
229
- # Returns an error message if the given child node is invalid,
230
- # and false otherwise.
231
- #
232
- # {ExtendNode}s are valid within {RuleNode}s.
233
- #
234
- # @param child [Tree::Node] A potential child node.
235
- # @return [Boolean, String] Whether or not the child node is valid,
236
- # as well as the error message to display if it is invalid
237
- def invalid_child?(child)
238
- super unless child.is_a?(ExtendNode)
239
- end
240
-
241
229
  # A hash that will be associated with this rule in the CSS document
242
230
  # if the {file:SASS_REFERENCE.md#debug_info-option `:debug_info` option} is enabled.
243
231
  # This data is used by e.g. [the FireSass Firebug extension](https://addons.mozilla.org/en-US/firefox/addon/103988).
@@ -32,17 +32,5 @@ module Sass::Tree
32
32
  end
33
33
  children
34
34
  end
35
-
36
- # Returns an error message if the given child node is invalid,
37
- # and false otherwise.
38
- #
39
- # {ExtendNode}s are valid within {WhileNode}s.
40
- #
41
- # @param child [Tree::Node] A potential child node.
42
- # @return [Boolean, String] Whether or not the child node is valid,
43
- # as well as the error message to display if it is invalid
44
- def invalid_child?(child)
45
- super unless child.is_a?(ExtendNode)
46
- end
47
35
  end
48
36
  end
@@ -114,6 +114,10 @@ MSG
114
114
  '@warn' => "Invalid warn directive '@warn': expected expression.",
115
115
  %Q{@warn "a message"\n "nested message"} => "Illegal nesting: Nothing may be nested beneath warn directives.",
116
116
  "/* foo\n bar\n baz" => "Inconsistent indentation: previous line was indented by 4 spaces, but this line was indented by 2 spaces.",
117
+ "@if foo\n @extend .bar" => ["Extend directives may only be used within rules.", 2],
118
+ "$var: true\n@while $var\n @extend .bar\n $var: false" => ["Extend directives may only be used within rules.", 3],
119
+ "@for $i from 0 to 1\n @extend .bar" => ["Extend directives may only be used within rules.", 2],
120
+ "@mixin foo\n @extend .bar\n@include foo" => ["Extend directives may only be used within rules.", 2],
117
121
 
118
122
  # Regression tests
119
123
  "a\n b:\n c\n d" => ["Illegal nesting: Only properties may be nested beneath properties.", 3],
@@ -1097,6 +1097,26 @@ SCSS
1097
1097
  assert_raise_line(2) {render(<<SCSS)}
1098
1098
  @if true {foo: bar}
1099
1099
  }
1100
+ SCSS
1101
+ end
1102
+
1103
+ def test_multiline_var
1104
+ assert_equal <<CSS, render(<<SCSS)
1105
+ foo {
1106
+ a: 3;
1107
+ b: false;
1108
+ c: a b c; }
1109
+ CSS
1110
+ foo {
1111
+ $var1: 1 +
1112
+ 2;
1113
+ $var2: true and
1114
+ false;
1115
+ $var3: a b
1116
+ c;
1117
+ a: $var1;
1118
+ b: $var2;
1119
+ c: $var3; }
1100
1120
  SCSS
1101
1121
  end
1102
1122
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: haml
3
3
  version: !ruby/object:Gem::Version
4
- hash: 55
4
+ hash: 53
5
5
  prerelease: false
6
6
  segments:
7
7
  - 3
8
8
  - 0
9
- - 24
10
- version: 3.0.24
9
+ - 25
10
+ version: 3.0.25
11
11
  platform: ruby
12
12
  authors:
13
13
  - Nathan Weizenbaum
@@ -17,7 +17,7 @@ autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
19
 
20
- date: 2010-11-15 00:00:00 -08:00
20
+ date: 2010-12-17 00:00:00 -05:00
21
21
  default_executable:
22
22
  dependencies:
23
23
  - !ruby/object:Gem::Dependency