mirror of
https://github.com/haml/haml.git
synced 2022-11-09 12:33:31 -05:00
Added multiline selector support to Sass. Thanks to Max Muermann for pointing this out.
git-svn-id: svn://hamptoncatlin.com/haml/trunk@579 7063305b-7217-0410-af8c-cdc13e5119b9
This commit is contained in:
parent
b9880f13d3
commit
b83cbfa3b3
4 changed files with 55 additions and 9 deletions
|
@ -75,6 +75,15 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
|
||||||
# <attribute>
|
# <attribute>
|
||||||
# ...
|
# ...
|
||||||
#
|
#
|
||||||
|
# Like CSS, you can stretch rules over multiple lines.
|
||||||
|
# However, unlike CSS, you can only do this if each line but the last
|
||||||
|
# ends with a comma.
|
||||||
|
# For example:
|
||||||
|
#
|
||||||
|
# .users #userTab,
|
||||||
|
# .posts #postsTab
|
||||||
|
# <attributes>
|
||||||
|
#
|
||||||
# === Attributes
|
# === Attributes
|
||||||
#
|
#
|
||||||
# There are two different ways to write CSS attrbibutes.
|
# There are two different ways to write CSS attrbibutes.
|
||||||
|
|
|
@ -22,17 +22,28 @@ module Sass
|
||||||
children.each do |child|
|
children.each do |child|
|
||||||
if child.is_a? AttrNode
|
if child.is_a? AttrNode
|
||||||
raise SyntaxError.new('Attributes aren\'t allowed at the root of a document.', child.line)
|
raise SyntaxError.new('Attributes aren\'t allowed at the root of a document.', child.line)
|
||||||
end
|
elsif child.is_a?(RuleNode) && child.continued?
|
||||||
|
check_multiline_rule(child)
|
||||||
|
result << child.to_s(1)
|
||||||
|
else
|
||||||
begin
|
begin
|
||||||
result += "#{child.to_s(1)}\n"
|
result << "#{child.to_s(1)}\n"
|
||||||
rescue SyntaxError => e
|
rescue SyntaxError => e
|
||||||
raise e
|
raise e
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
result[0...-1]
|
result[0...-1]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def check_multiline_rule(rule)
|
||||||
|
unless rule.children.empty?
|
||||||
|
raise SyntaxError.new('Rules can\'t end in commas.', rule.line)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# This method should be overridden by subclasses to return an error message
|
# This method should be overridden by subclasses to return an error message
|
||||||
|
|
|
@ -9,9 +9,17 @@ module Sass::Tree
|
||||||
alias_method :rule, :value
|
alias_method :rule, :value
|
||||||
alias_method :rule=, :value=
|
alias_method :rule=, :value=
|
||||||
|
|
||||||
|
def continued?
|
||||||
|
rule[-1] == ?,
|
||||||
|
end
|
||||||
|
|
||||||
def to_s(tabs, super_rules = nil)
|
def to_s(tabs, super_rules = nil)
|
||||||
attributes = []
|
attributes = []
|
||||||
sub_rules = []
|
sub_rules = []
|
||||||
|
|
||||||
|
# Save this because the comma's removed by the super_rule additions
|
||||||
|
was_continued = continued?
|
||||||
|
|
||||||
total_rule = if super_rules
|
total_rule = if super_rules
|
||||||
super_rules.split(/,\s*/).collect! do |s|
|
super_rules.split(/,\s*/).collect! do |s|
|
||||||
self.rule.split(/,\s*/).collect do |r|
|
self.rule.split(/,\s*/).collect do |r|
|
||||||
|
@ -21,7 +29,7 @@ module Sass::Tree
|
||||||
"#{s} #{r}"
|
"#{s} #{r}"
|
||||||
end
|
end
|
||||||
end.join(", ")
|
end.join(", ")
|
||||||
end.join(", ")
|
end.join(", ") + (was_continued ? ',' : '')
|
||||||
elsif self.rule.include?(PARENT)
|
elsif self.rule.include?(PARENT)
|
||||||
raise Sass::SyntaxError.new("Base-level rules cannot contain the parent-selector-referencing character '#{PARENT}'", line)
|
raise Sass::SyntaxError.new("Base-level rules cannot contain the parent-selector-referencing character '#{PARENT}'", line)
|
||||||
else
|
else
|
||||||
|
@ -37,7 +45,7 @@ module Sass::Tree
|
||||||
end
|
end
|
||||||
|
|
||||||
to_return = ''
|
to_return = ''
|
||||||
unless attributes.empty?
|
if !attributes.empty?
|
||||||
if @style == :compact
|
if @style == :compact
|
||||||
to_return << "#{total_rule} { #{attributes.join(' ')} }\n"
|
to_return << "#{total_rule} { #{attributes.join(' ')} }\n"
|
||||||
else
|
else
|
||||||
|
@ -49,10 +57,18 @@ module Sass::Tree
|
||||||
end_attrs = (@style == :expanded ? "\n" : ' ')
|
end_attrs = (@style == :expanded ? "\n" : ' ')
|
||||||
to_return << "#{old_spaces}#{total_rule} {\n#{spaces}#{attributes}#{end_attrs}}\n"
|
to_return << "#{old_spaces}#{total_rule} {\n#{spaces}#{attributes}#{end_attrs}}\n"
|
||||||
end
|
end
|
||||||
|
elsif continued?
|
||||||
|
to_return << total_rule + (@style == :compact ? ' ' : "\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
tabs += 1 unless attributes.empty?
|
tabs += 1 unless attributes.empty?
|
||||||
sub_rules.each { |sub| to_return << sub.to_s(tabs, total_rule) }
|
sub_rules.each do |sub|
|
||||||
|
if sub.continued?
|
||||||
|
check_multiline_rule(sub)
|
||||||
|
end
|
||||||
|
|
||||||
|
to_return << sub.to_s(tabs, total_rule)
|
||||||
|
end
|
||||||
to_return
|
to_return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -39,6 +39,7 @@ class SassEngineTest < Test::Unit::TestCase
|
||||||
"!a = 1b + 2c" => "Incompatible units: b and c",
|
"!a = 1b + 2c" => "Incompatible units: b and c",
|
||||||
"& a\n :b c" => "Base-level rules cannot contain the parent-selector-referencing character '&'",
|
"& a\n :b c" => "Base-level rules cannot contain the parent-selector-referencing character '&'",
|
||||||
"a\n :b\n c" => "Illegal nesting: Only attributes may be nested beneath attributes.",
|
"a\n :b\n c" => "Illegal nesting: Only attributes may be nested beneath attributes.",
|
||||||
|
"a,\n :b c" => "Rules can\'t end in commas.",
|
||||||
"!a = b\n :c d\n" => "Illegal nesting: Nothing may be nested beneath constants.",
|
"!a = b\n :c d\n" => "Illegal nesting: Nothing may be nested beneath constants.",
|
||||||
"@import foo.sass" => "File to import not found or unreadable: foo.sass",
|
"@import foo.sass" => "File to import not found or unreadable: foo.sass",
|
||||||
"@import templates/basic\n foo" => "Illegal nesting: Nothing may be nested beneath import directives.",
|
"@import templates/basic\n foo" => "Illegal nesting: Nothing may be nested beneath import directives.",
|
||||||
|
@ -100,6 +101,15 @@ class SassEngineTest < Test::Unit::TestCase
|
||||||
render("foo\n bar = url(foo.png)\n"));
|
render("foo\n bar = url(foo.png)\n"));
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_multiline_selector
|
||||||
|
assert_equal("#foo #bar,\n#baz #boom {\n foo: bar; }\n",
|
||||||
|
render("#foo #bar,\n#baz #boom\n :foo bar"))
|
||||||
|
assert_equal("#foo #bar,\n#foo #baz {\n foo: bar; }\n",
|
||||||
|
render("#foo\n #bar,\n #baz\n :foo bar"))
|
||||||
|
assert_equal("#foo #bar, #baz #boom { foo: bar; }\n",
|
||||||
|
render("#foo #bar,\n#baz #boom\n :foo bar", :style => :compact))
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def render(sass, options = {})
|
def render(sass, options = {})
|
||||||
|
|
Loading…
Add table
Reference in a new issue