Skip to content

Commit d89950e

Browse files
committed
Implements margin shorthand parsing
Per specs on http://www.w3.org/TR/CSS21/box.html#propdef-margin and http://www.w3.org/TR/CSS/
1 parent 7f58f7b commit d89950e

File tree

4 files changed

+111
-0
lines changed

4 files changed

+111
-0
lines changed

lib/csscss.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@
1717
require "csscss/parser/base"
1818
require "csscss/parser/background"
1919
require "csscss/parser/list_style"
20+
require "csscss/parser/margin"

lib/csscss/parser/margin.rb

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
module Csscss
2+
module Parser
3+
module Margin
4+
extend Parser::Base
5+
6+
class Parser < Parslet::Parser
7+
include Common
8+
9+
rule(:margin_side) {
10+
length | percent | symbol_list(%w(inherit auto))
11+
}
12+
13+
rule(:margin) {
14+
(
15+
symbol("inherit") >> eof | (
16+
margin_side.maybe.as(:top) >>
17+
margin_side.maybe.as(:right) >>
18+
margin_side.maybe.as(:bottom) >>
19+
margin_side.maybe.as(:left)
20+
)
21+
).as(:margin)
22+
}
23+
root(:margin)
24+
end
25+
26+
class Transformer < Parslet::Transform
27+
rule(margin: simple(:inherit)) {[]}
28+
29+
SIDE = proc {|side, value| Declaration.from_parser("margin-#{side}", value) }
30+
31+
rule(margin: {
32+
top:simple(:top),
33+
right:simple(:right),
34+
bottom:simple(:bottom),
35+
left:simple(:left)
36+
}) {
37+
values = [top, right, bottom, left].compact
38+
case values.size
39+
when 4
40+
%w(top right bottom left).zip(values).map {|side, value| SIDE[side, value] }
41+
when 3
42+
%w(top right bottom).zip(values).map {|side, value| SIDE[side, value] }.tap do |declarations|
43+
declarations << SIDE["left", values[1]]
44+
end
45+
when 2
46+
%w(top right).zip(values).map {|side, value| SIDE[side, value] }.tap do |declarations|
47+
declarations << SIDE["bottom", values[0]]
48+
declarations << SIDE["left", values[1]]
49+
end
50+
when 1
51+
%w(top right bottom left).map do |side|
52+
SIDE[side, values[0]]
53+
end
54+
end
55+
}
56+
end
57+
end
58+
end
59+
end

lib/csscss/redundancy_analyzer.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ def shorthand_parser(property)
8888
case property
8989
when "background" then Parser::Background
9090
when "list-style" then Parser::ListStyle
91+
when "margin" then Parser::Margin
9192
end
9293
end
9394
end

test/csscss/parser/margin_test.rb

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
require "test_helper"
2+
3+
module Csscss::Parser
4+
module Margin
5+
describe Margin do
6+
include CommonParserTests
7+
8+
before do
9+
@parser = Parser.new
10+
@trans = Transformer.new
11+
end
12+
13+
it "converts shorthand rules to longhand" do
14+
trans("1px 10% inherit auto").must_equal([
15+
dec("margin-top", "1px"),
16+
dec("margin-right", "10%"),
17+
dec("margin-bottom", "inherit"),
18+
dec("margin-left", "auto")
19+
])
20+
21+
trans("1px 10% inherit").must_equal([
22+
dec("margin-top", "1px"),
23+
dec("margin-right", "10%"),
24+
dec("margin-bottom", "inherit"),
25+
dec("margin-left", "10%")
26+
])
27+
28+
trans("1px 10%").must_equal([
29+
dec("margin-top", "1px"),
30+
dec("margin-right", "10%"),
31+
dec("margin-bottom", "1px"),
32+
dec("margin-left", "10%")
33+
])
34+
35+
trans("1px").must_equal([
36+
dec("margin-top", "1px"),
37+
dec("margin-right", "1px"),
38+
dec("margin-bottom", "1px"),
39+
dec("margin-left", "1px")
40+
])
41+
end
42+
43+
it "tries the parse and returns false if it doesn't work" do
44+
@parser.try_parse("foo").must_equal(false)
45+
parsed = @parser.try_parse("1px")
46+
parsed[:margin][:top].must_equal("1px")
47+
end
48+
end
49+
end
50+
end

0 commit comments

Comments
 (0)