diff --git a/doc-src/SASS_CHANGELOG.md b/doc-src/SASS_CHANGELOG.md index 87ff3613..8b9f1d26 100644 --- a/doc-src/SASS_CHANGELOG.md +++ b/doc-src/SASS_CHANGELOG.md @@ -3,6 +3,11 @@ * Table of contents {:toc} +## 2.2.11 (Unreleased) + +* Added a note to errors on properties that could be pseudo-classes (e.g. `:focus`) + indicating that they should be backslash-escaped. + ## [2.2.10](http://github.com/nex3/haml/commit/2.2.10) * Add support for attribute selectors with spaces around the `=`. diff --git a/lib/sass/tree/node.rb b/lib/sass/tree/node.rb index 5b435552..262bea2a 100644 --- a/lib/sass/tree/node.rb +++ b/lib/sass/tree/node.rb @@ -123,7 +123,9 @@ module Sass result = String.new children.each do |child| if child.is_a? PropNode - raise Sass::SyntaxError.new('Properties aren\'t allowed at the root of a document.', child.line) + message = "Properties aren't allowed at the root of a document." + + child.pseudo_class_selector_message + raise Sass::SyntaxError.new(message, child.line) else next if child.invisible? child_str = child.to_s(1) diff --git a/lib/sass/tree/prop_node.rb b/lib/sass/tree/prop_node.rb index 07a0c64f..a392b7b8 100644 --- a/lib/sass/tree/prop_node.rb +++ b/lib/sass/tree/prop_node.rb @@ -54,7 +54,9 @@ module Sass::Tree real_name = "#{parent_name}-#{real_name}" if parent_name if value.empty? && children.empty? - raise Sass::SyntaxError.new("Invalid property: #{declaration.dump} (no value).", @line) + message = "Invalid property: #{declaration.dump} (no value)." + + pseudo_class_selector_message + raise Sass::SyntaxError.new(message, @line) end join_string = case style @@ -76,6 +78,16 @@ module Sass::Tree (style == :compressed && parent_name) ? to_return : to_return[0...-1] end + # Returns a appropriate message indicating how to escape pseudo-class selectors. + # This only applies for old-style properties with no value, + # so returns the empty string if this is new-style. + # + # @return [String] The message + def pseudo_class_selector_message + return "" if @prop_syntax == :new || !value.empty? + "\nIf #{declaration.dump} should be a selector, use \"\\#{declaration}\" instead." + end + protected # Runs any SassScript that may be embedded in the property. @@ -103,7 +115,7 @@ module Sass::Tree private def declaration - @prop_syntax == :new ? "#{name}: #{value}" : ":#{name} #{value}" + (@prop_syntax == :new ? "#{name}: #{value}" : ":#{name} #{value}").strip end end end diff --git a/test/sass/engine_test.rb b/test/sass/engine_test.rb index e1b2c9ea..1c0e9e48 100755 --- a/test/sass/engine_test.rb +++ b/test/sass/engine_test.rb @@ -18,8 +18,11 @@ class SassEngineTest < Test::Unit::TestCase ":" => 'Invalid property: ":".', ": a" => 'Invalid property: ": a".', ":= a" => 'Invalid property: ":= a".', - "a\n :b" => 'Invalid property: ":b " (no value).', - "a\n b:" => 'Invalid property: "b: " (no value).', + "a\n :b" => < 'Invalid property: "b:" (no value).', "a\n :b: c" => 'Invalid property: ":b: c".', "a\n :b:c d" => 'Invalid property: ":b:c d".', "a\n :b=c d" => 'Invalid property: ":b=c d".', @@ -27,7 +30,12 @@ class SassEngineTest < Test::Unit::TestCase "a\n b: c;" => 'Invalid property: "b: c;" (no ";" required at end-of-line).', "a\n b : c" => 'Invalid property: "b : c".', "a\n b=c: d" => 'Invalid property: "b=c: d".', - ":a" => 'Properties aren\'t allowed at the root of a document.', + ":a b" => 'Properties aren\'t allowed at the root of a document.', + "a:" => 'Properties aren\'t allowed at the root of a document.', + ":a" => < 'Invalid variable: "!".', "!a" => 'Invalid variable: "!a".', "! a" => 'Invalid variable: "! a".', @@ -134,7 +142,7 @@ class SassEngineTest < Test::Unit::TestCase rescue Sass::SyntaxError => err value = [value] unless value.is_a?(Array) - assert_equal(value.first, err.message, "Line: #{key}") + assert_equal(value.first.rstrip, err.message, "Line: #{key}") assert_equal(__FILE__, err.sass_filename) assert_equal((value[1] || key.split("\n").length) + line - 1, err.sass_line, "Line: #{key}") assert_match(/#{Regexp.escape(__FILE__)}:[0-9]+/, err.backtrace[0], "Line: #{key}")