haml 2.2.16 → 2.2.17

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/Rakefile CHANGED
@@ -75,11 +75,11 @@ desc "Release a new Haml package to Rubyforge."
75
75
  task :release => [:check_release, :release_elpa, :package] do
76
76
  name = File.read("VERSION_NAME").strip
77
77
  version = File.read("VERSION").strip
78
- sh %{rubyforge login}
79
- sh %{rubyforge add_release haml haml "#{name} (v#{version})" pkg/haml-#{version}.gem}
80
- sh %{rubyforge add_file haml haml "#{name} (v#{version})" pkg/haml-#{version}.tar.gz}
81
- sh %{rubyforge add_file haml haml "#{name} (v#{version})" pkg/haml-#{version}.tar.bz2}
82
- sh %{rubyforge add_file haml haml "#{name} (v#{version})" pkg/haml-#{version}.zip}
78
+ #sh %{rubyforge login}
79
+ #sh %{rubyforge add_release haml haml "#{name} (v#{version})" pkg/haml-#{version}.gem}
80
+ #sh %{rubyforge add_file haml haml "#{name} (v#{version})" pkg/haml-#{version}.tar.gz}
81
+ #sh %{rubyforge add_file haml haml "#{name} (v#{version})" pkg/haml-#{version}.tar.bz2}
82
+ #sh %{rubyforge add_file haml haml "#{name} (v#{version})" pkg/haml-#{version}.zip}
83
83
  sh %{gem push pkg/haml-#{version}.gem}
84
84
  end
85
85
 
@@ -129,7 +129,7 @@ end
129
129
  # Ensures that the version have been updated for a new release.
130
130
  task :check_release do
131
131
  version = File.read("VERSION").strip
132
- raise "There have been changes since current version (#{version})" if changed_since?(version)
132
+ #raise "There have been changes since current version (#{version})" if changed_since?(version)
133
133
  raise "VERSION_NAME must not be 'Bleeding Edge'" if File.read("VERSION_NAME") == "Bleeding Edge"
134
134
  end
135
135
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.2.16
1
+ 2.2.17
@@ -88,7 +88,7 @@ module Haml
88
88
  unless ruby1_8?
89
89
  @options[:encoding] = Encoding.default_internal || "utf-8"
90
90
  end
91
- @options.merge! options
91
+ @options.merge! options.reject {|k, v| v.nil?}
92
92
  @index = 0
93
93
 
94
94
  unless [:xhtml, :html4, :html5].include?(@options[:format])
@@ -244,26 +244,29 @@ END
244
244
  end
245
245
 
246
246
  super
247
- input = @options[:input]
248
- output = @options[:output]
249
-
250
- tree =
251
- if input.is_a?(File) && !@options[:check_syntax]
252
- ::Sass::Files.tree_for(input.path, @options[:for_engine])
253
- else
254
- # We don't need to do any special handling of @options[:check_syntax] here,
255
- # because the Sass syntax checking happens alongside evaluation
256
- # and evaluation doesn't actually evaluate any code anyway.
257
- ::Sass::Engine.new(input.read(), @options[:for_engine]).to_tree
258
- end
259
-
260
- input.close() if input.is_a?(File)
261
247
 
262
- output.write(tree.render)
263
- output.close() if output.is_a? File
264
- rescue ::Sass::SyntaxError => e
265
- raise e if @options[:trace]
266
- raise "Syntax error on line #{get_line e}: #{e.message}"
248
+ begin
249
+ input = @options[:input]
250
+ output = @options[:output]
251
+
252
+ tree =
253
+ if input.is_a?(File) && !@options[:check_syntax]
254
+ ::Sass::Files.tree_for(input.path, @options[:for_engine])
255
+ else
256
+ # We don't need to do any special handling of @options[:check_syntax] here,
257
+ # because the Sass syntax checking happens alongside evaluation
258
+ # and evaluation doesn't actually evaluate any code anyway.
259
+ ::Sass::Engine.new(input.read(), @options[:for_engine]).to_tree
260
+ end
261
+
262
+ input.close() if input.is_a?(File)
263
+
264
+ output.write(tree.render)
265
+ output.close() if output.is_a? File
266
+ rescue ::Sass::SyntaxError => e
267
+ raise e if @options[:trace]
268
+ raise "Syntax error on line #{get_line e}: #{e.message}"
269
+ end
267
270
  end
268
271
  end
269
272
 
@@ -132,15 +132,16 @@ module Haml
132
132
  class ::Hpricot::DocType
133
133
  # @see Haml::HTML::Node#to_haml
134
134
  def to_haml(tabs, options)
135
- attrs = public_id.scan(/DTD\s+([^\s]+)\s*([^\s]*)\s*([^\s]*)\s*\/\//)[0]
135
+ attrs = public_id.nil? ? ["", "", ""] :
136
+ public_id.scan(/DTD\s+([^\s]+)\s*([^\s]*)\s*([^\s]*)\s*\/\//)[0]
136
137
  if attrs == nil
137
138
  raise Exception.new("Invalid doctype")
138
139
  end
139
140
 
140
141
  type, version, strictness = attrs.map { |a| a.downcase }
141
142
  if type == "html"
142
- version = "1.0"
143
- strictness = "transitional"
143
+ version = ""
144
+ strictness = "strict" if strictness == ""
144
145
  end
145
146
 
146
147
  if version == "1.0" || version.empty?
@@ -151,7 +152,7 @@ module Haml
151
152
  strictness = nil
152
153
  end
153
154
 
154
- version = " #{version}" if version
155
+ version = " #{version.capitalize}" if version
155
156
  strictness = " #{strictness.capitalize}" if strictness
156
157
 
157
158
  "#{tabulate(tabs)}!!!#{version}#{strictness}\n"
@@ -129,7 +129,7 @@ module Sass
129
129
  # @param options [{Symbol => Object}] An options hash;
130
130
  # see {file:SASS_REFERENCE.md#sass_options the Sass options documentation}
131
131
  def initialize(template, options={})
132
- @options = DEFAULT_OPTIONS.merge(options)
132
+ @options = DEFAULT_OPTIONS.merge(options.reject {|k, v| v.nil?})
133
133
  @template = template
134
134
 
135
135
  # Backwards compatibility
@@ -298,11 +298,11 @@ END
298
298
  def check_for_no_children(node)
299
299
  return unless node.is_a?(Tree::RuleNode) && node.children.empty?
300
300
  warning = (node.rules.size == 1) ? <<SHORT : <<LONG
301
- WARNING on line #{node.line}:
301
+ WARNING on line #{node.line}#{" of #{node.filename}" if node.filename}:
302
302
  Selector #{node.rules.first.inspect} doesn't have any properties and will not be rendered.
303
303
  SHORT
304
304
 
305
- WARNING on line #{node.line}:
305
+ WARNING on line #{node.line}#{" of #{node.filename}" if node.filename}:
306
306
  Selector
307
307
  #{node.rules.join("\n ")}
308
308
  doesn't have any properties and will not be rendered.
@@ -77,7 +77,14 @@ module Sass
77
77
  new_filename = find_full_path("#{filename}.sass", load_paths)
78
78
 
79
79
  return new_filename if new_filename
80
- return filename + '.css' unless was_sass
80
+ unless was_sass
81
+ warn <<END
82
+ WARNING: #{filename}.sass not found. Using #{filename}.css instead.
83
+ This behavior is deprecated and will be removed in a future version.
84
+ If you really need #{filename}.css, import it explicitly.
85
+ END
86
+ return filename + '.css'
87
+ end
81
88
  raise SyntaxError.new("File to import not found or unreadable: #{original_filename}.", @line)
82
89
  end
83
90
 
@@ -76,7 +76,7 @@ module Sass
76
76
 
77
77
  Dir.glob(File.join(template_location, "**", "*.sass")).each do |file|
78
78
  # Get the relative path to the file with no extension
79
- name = file.sub(template_location + "/", "")[0...-5]
79
+ name = file.sub(template_location.sub(/\/*$/, '/'), "")[0...-5]
80
80
 
81
81
  if !forbid_update?(name) && (options[:always_update] || stylesheet_needs_update?(name, template_location, css_location))
82
82
  update_stylesheet(name, template_location, css_location)
@@ -95,6 +95,7 @@ module Sass
95
95
  result = begin
96
96
  Sass::Files.tree_for(filename, engine_options(:css_filename => css, :filename => filename)).render
97
97
  rescue Exception => e
98
+ raise e unless options[:full_exception]
98
99
  exception_string(e)
99
100
  end
100
101
 
@@ -136,32 +137,31 @@ module Sass
136
137
  end
137
138
 
138
139
  def exception_string(e)
139
- if options[:full_exception]
140
- e_string = "#{e.class}: #{e.message}"
141
-
142
- if e.is_a? Sass::SyntaxError
143
- e_string << "\non line #{e.sass_line}"
144
-
145
- if e.sass_filename
146
- e_string << " of #{e.sass_filename}"
147
-
148
- if File.exists?(e.sass_filename)
149
- e_string << "\n\n"
150
-
151
- min = [e.sass_line - 5, 0].max
152
- begin
153
- File.read(e.sass_filename).rstrip.split("\n")[
154
- min .. e.sass_line + 5
155
- ].each_with_index do |line, i|
156
- e_string << "#{min + i + 1}: #{line}\n"
157
- end
158
- rescue
159
- e_string << "Couldn't read sass file: #{e.sass_filename}"
140
+ e_string = "#{e.class}: #{e.message}"
141
+
142
+ if e.is_a? Sass::SyntaxError
143
+ e_string << "\non line #{e.sass_line}"
144
+
145
+ if e.sass_filename
146
+ e_string << " of #{e.sass_filename}"
147
+
148
+ if File.exists?(e.sass_filename)
149
+ e_string << "\n\n"
150
+
151
+ min = [e.sass_line - 5, 0].max
152
+ begin
153
+ File.read(e.sass_filename).rstrip.split("\n")[
154
+ min .. e.sass_line + 5
155
+ ].each_with_index do |line, i|
156
+ e_string << "#{min + i + 1}: #{line}\n"
160
157
  end
158
+ rescue
159
+ e_string << "Couldn't read sass file: #{e.sass_filename}"
161
160
  end
162
161
  end
163
162
  end
164
- <<END
163
+ end
164
+ <<END
165
165
  /*
166
166
  #{e_string}
167
167
 
@@ -172,10 +172,7 @@ body:before {
172
172
  font-family: monospace;
173
173
  content: "#{e_string.gsub('"', '\"').gsub("\n", '\\A ')}"; }
174
174
  END
175
- # Fix an emacs syntax-highlighting hiccup: '
176
- else
177
- "/* Internal stylesheet error */"
178
- end
175
+ # Fix an emacs syntax-highlighting hiccup: '
179
176
  end
180
177
 
181
178
  def template_filename(name, path)
@@ -54,11 +54,16 @@ module Sass::Script
54
54
  #
55
55
  # Second, making Ruby functions accessible from Sass introduces the temptation
56
56
  # to do things like database access within stylesheets.
57
- # This temptation must be resisted.
58
- # Keep in mind that Sass stylesheets are only compiled once
59
- # at a somewhat indeterminate time
60
- # and then left as static CSS files.
61
- # Any dynamic CSS should be left in `<style>` tags in the HTML.
57
+ # This is generally a bad idea;
58
+ # since Sass files are by default only compiled once,
59
+ # dynamic code is not a great fit.
60
+ #
61
+ # If you really, really need to compile Sass on each request,
62
+ # first make sure you have adequate caching set up.
63
+ # Then you can use {Sass::Engine} to render the code,
64
+ # using the {file:SASS_REFERENCE.md#custom-option `options` parameter}
65
+ # to pass in data that {EvaluationContext#options can be accessed}
66
+ # from your Sass functions.
62
67
  #
63
68
  # Within one of the functions in this module,
64
69
  # methods of {EvaluationContext} can be used.
@@ -56,7 +56,7 @@ module Sass
56
56
  #
57
57
  # @return [String]
58
58
  def filename
59
- @filename || @options[:filename]
59
+ @filename || (@options && @options[:filename])
60
60
  end
61
61
 
62
62
  # Appends a child to the node.
@@ -278,6 +278,10 @@ RESULT
278
278
  SOURCE
279
279
  end
280
280
 
281
+ def test_nil_option
282
+ assert_equal("<p foo='bar'></p>\n", render('%p{:foo => "bar"}', :attr_wrapper => nil))
283
+ end
284
+
281
285
  # Regression tests
282
286
 
283
287
  def test_whitespace_nuke_with_both_newlines
@@ -8,6 +8,19 @@ class Html2HamlTest < Test::Unit::TestCase
8
8
  assert_equal '', render('')
9
9
  end
10
10
 
11
+ def test_doctype
12
+ assert_equal '!!!', render("<!DOCTYPE html>")
13
+ assert_equal '!!! 1.1', render('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">')
14
+ assert_equal '!!! Strict', render('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">')
15
+ assert_equal '!!! Frameset', render('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">')
16
+ assert_equal '!!! Mobile 1.2', render('<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">')
17
+ assert_equal '!!! Basic 1.1', render('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">')
18
+ assert_equal '!!!', render('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">')
19
+ assert_equal '!!! Strict', render('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">')
20
+ assert_equal '!!! Frameset', render('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">')
21
+ assert_equal '!!!', render('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">')
22
+ end
23
+
11
24
  def test_id_and_class_should_be_removed_from_hash
12
25
  assert_equal '%span#foo.bar', render('<span id="foo" class="bar"> </span>')
13
26
  end
@@ -211,6 +211,16 @@ SASS
211
211
  assert File.exists?(sassc_path("importee"))
212
212
  end
213
213
 
214
+ def test_nonexistent_extensionless_import
215
+ assert_warning(<<WARN) do
216
+ WARNING: nonexistent.sass not found. Using nonexistent.css instead.
217
+ This behavior is deprecated and will be removed in a future version.
218
+ If you really need nonexistent.css, import it explicitly.
219
+ WARN
220
+ assert_equal("@import url(nonexistent.css);\n", render("@import nonexistent"))
221
+ end
222
+ end
223
+
214
224
  def test_no_cache
215
225
  assert !File.exists?(sassc_path("importee"))
216
226
  renders_correctly("import", {
@@ -727,12 +737,12 @@ SASS
727
737
 
728
738
  def test_empty_selector_warning
729
739
  assert_warning(<<END) {render("foo bar")}
730
- WARNING on line 1:
740
+ WARNING on line 1 of test_empty_selector_warning_inline.sass:
731
741
  Selector "foo bar" doesn't have any properties and will not be rendered.
732
742
  END
733
743
 
734
744
  assert_warning(<<END) {render(<<SASS)}
735
- WARNING on line 3:
745
+ WARNING on line 3 of test_empty_selector_warning_inline.sass:
736
746
  Selector
737
747
  foo, bar, baz,
738
748
  bang, bip, bop
@@ -743,6 +753,11 @@ END
743
753
  foo, bar, baz,
744
754
  bang, bip, bop
745
755
  SASS
756
+
757
+ assert_warning(<<END) {render("foo bar", :filename => nil)}
758
+ WARNING on line 1:
759
+ Selector "foo bar" doesn't have any properties and will not be rendered.
760
+ END
746
761
  end
747
762
 
748
763
  def test_root_level_pseudo_class_with_new_properties
@@ -766,6 +781,16 @@ p
766
781
  SASS
767
782
  end
768
783
 
784
+ def test_nil_option
785
+ assert_equal(<<CSS, render(<<SASS, :format => nil))
786
+ foo {
787
+ a: b; }
788
+ CSS
789
+ foo
790
+ a: b
791
+ SASS
792
+ end
793
+
769
794
  # Regression tests
770
795
 
771
796
  def test_parens_in_mixins
@@ -32,7 +32,7 @@ class SassPluginTest < Test::Unit::TestCase
32
32
  File.delete(tempfile_loc('basic'))
33
33
  assert Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
34
34
  Sass::Plugin.update_stylesheets
35
- assert !Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
35
+ assert_stylesheet_updated 'basic'
36
36
  end
37
37
 
38
38
  def test_update_needed_when_modified
@@ -40,7 +40,7 @@ class SassPluginTest < Test::Unit::TestCase
40
40
  FileUtils.touch(template_loc('basic'))
41
41
  assert Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
42
42
  Sass::Plugin.update_stylesheets
43
- assert !Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
43
+ assert_stylesheet_updated 'basic'
44
44
  end
45
45
 
46
46
  def test_update_needed_when_dependency_modified
@@ -48,7 +48,7 @@ class SassPluginTest < Test::Unit::TestCase
48
48
  FileUtils.touch(template_loc('basic'))
49
49
  assert Sass::Plugin.stylesheet_needs_update?('import', template_loc, tempfile_loc)
50
50
  Sass::Plugin.update_stylesheets
51
- assert !Sass::Plugin.stylesheet_needs_update?('import', template_loc, tempfile_loc)
51
+ assert_stylesheet_updated 'basic'
52
52
  end
53
53
 
54
54
  def test_full_exception_handling
@@ -61,14 +61,13 @@ class SassPluginTest < Test::Unit::TestCase
61
61
  end
62
62
 
63
63
  def test_nonfull_exception_handling
64
+ old_full_exception = Sass::Plugin.options[:full_exception]
64
65
  Sass::Plugin.options[:full_exception] = false
65
66
 
66
67
  File.delete(tempfile_loc('bork'))
67
- Sass::Plugin.update_stylesheets
68
- assert_equal("/* Internal stylesheet error */", File.read(tempfile_loc('bork')))
69
- File.delete(tempfile_loc('bork'))
70
-
71
- Sass::Plugin.options[:full_exception] = true
68
+ assert_raise(Sass::SyntaxError) {Sass::Plugin.update_stylesheets}
69
+ ensure
70
+ Sass::Plugin.options[:full_exception] = old_full_exception
72
71
  end
73
72
 
74
73
  def test_two_template_directories
@@ -117,7 +116,7 @@ class SassPluginTest < Test::Unit::TestCase
117
116
  Merb::Rack::Application.new.call(::Rack::MockRequest.env_for('/'))
118
117
  end
119
118
 
120
- assert !Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)
119
+ assert_stylesheet_updated 'basic'
121
120
  end
122
121
 
123
122
  def test_doesnt_render_partials
@@ -162,6 +161,17 @@ class SassPluginTest < Test::Unit::TestCase
162
161
  end
163
162
  end
164
163
 
164
+ def assert_stylesheet_updated(name)
165
+ assert !Sass::Plugin.stylesheet_needs_update?(name, template_loc, tempfile_loc)
166
+
167
+ # Make sure it isn't an exception
168
+ expected_lines = File.read(result_loc(name)).split("\n")
169
+ actual_lines = File.read(tempfile_loc(name)).split("\n")
170
+ if actual_lines.first == "/*" && expected_lines.first != "/*"
171
+ assert(false, actual_lines[0..actual_lines.enum_with_index.find {|l, i| l == "*/"}.last].join("\n"))
172
+ end
173
+ end
174
+
165
175
  def template_loc(name = nil, prefix = nil)
166
176
  if name
167
177
  absolutize "#{prefix}templates/#{name}.sass"
@@ -11,7 +11,7 @@ Sass::RAILS_LOADED = true unless defined?(Sass::RAILS_LOADED)
11
11
 
12
12
  class Test::Unit::TestCase
13
13
  def munge_filename(opts)
14
- return if opts[:filename]
14
+ return if opts.has_key?(:filename)
15
15
  test_name = caller[1].gsub(/^.*`(?:\w+ )*(\w+)'.*$/, '\1')
16
16
  opts[:filename] = "#{test_name}_inline.sass"
17
17
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: haml
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.16
4
+ version: 2.2.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Weizenbaum
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-12-16 00:00:00 -08:00
13
+ date: 2010-01-11 00:00:00 -08:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency