haml 1.8.2 → 2.0.0
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/FAQ +138 -0
- data/MIT-LICENSE +1 -1
- data/{README → README.rdoc} +66 -3
- data/Rakefile +111 -147
- data/VERSION +1 -1
- data/bin/css2sass +0 -0
- data/bin/haml +0 -0
- data/bin/html2haml +0 -0
- data/bin/sass +0 -0
- data/init.rb +6 -1
- data/lib/haml.rb +464 -201
- data/lib/haml/buffer.rb +117 -63
- data/lib/haml/engine.rb +63 -44
- data/lib/haml/error.rb +16 -6
- data/lib/haml/exec.rb +37 -7
- data/lib/haml/filters.rb +213 -68
- data/lib/haml/helpers.rb +95 -60
- data/lib/haml/helpers/action_view_extensions.rb +1 -1
- data/lib/haml/helpers/action_view_mods.rb +54 -6
- data/lib/haml/html.rb +6 -6
- data/lib/haml/precompiler.rb +254 -133
- data/lib/haml/template.rb +3 -6
- data/lib/haml/template/patch.rb +9 -2
- data/lib/haml/template/plugin.rb +52 -23
- data/lib/sass.rb +157 -12
- data/lib/sass/constant.rb +22 -22
- data/lib/sass/constant/color.rb +13 -13
- data/lib/sass/constant/literal.rb +7 -7
- data/lib/sass/constant/number.rb +9 -9
- data/lib/sass/constant/operation.rb +4 -4
- data/lib/sass/constant/string.rb +3 -3
- data/lib/sass/css.rb +104 -31
- data/lib/sass/engine.rb +120 -39
- data/lib/sass/error.rb +1 -1
- data/lib/sass/plugin.rb +14 -3
- data/lib/sass/plugin/merb.rb +6 -2
- data/lib/sass/tree/attr_node.rb +5 -5
- data/lib/sass/tree/directive_node.rb +2 -7
- data/lib/sass/tree/node.rb +1 -12
- data/lib/sass/tree/rule_node.rb +39 -31
- data/lib/sass/tree/value_node.rb +1 -1
- data/test/benchmark.rb +67 -80
- data/test/haml/engine_test.rb +284 -84
- data/test/haml/helper_test.rb +51 -15
- data/test/haml/results/content_for_layout.xhtml +1 -2
- data/test/haml/results/eval_suppressed.xhtml +2 -4
- data/test/haml/results/filters.xhtml +44 -15
- data/test/haml/results/helpers.xhtml +2 -3
- data/test/haml/results/just_stuff.xhtml +2 -6
- data/test/haml/results/nuke_inner_whitespace.xhtml +34 -0
- data/test/haml/results/nuke_outer_whitespace.xhtml +148 -0
- data/test/haml/results/original_engine.xhtml +3 -7
- data/test/haml/results/partials.xhtml +1 -0
- data/test/haml/results/tag_parsing.xhtml +1 -6
- data/test/haml/results/very_basic.xhtml +2 -4
- data/test/haml/results/whitespace_handling.xhtml +13 -21
- data/test/haml/template_test.rb +8 -15
- data/test/haml/templates/_partial.haml +1 -0
- data/test/haml/templates/filters.haml +48 -7
- data/test/haml/templates/just_stuff.haml +1 -2
- data/test/haml/templates/nuke_inner_whitespace.haml +26 -0
- data/test/haml/templates/nuke_outer_whitespace.haml +144 -0
- data/test/haml/templates/tag_parsing.haml +0 -3
- data/test/haml/test_helper.rb +15 -0
- data/test/sass/engine_test.rb +80 -34
- data/test/sass/plugin_test.rb +1 -1
- data/test/sass/results/import.css +2 -2
- data/test/sass/results/mixins.css +95 -0
- data/test/sass/results/multiline.css +24 -0
- data/test/sass/templates/import.sass +4 -1
- data/test/sass/templates/importee.sass +4 -0
- data/test/sass/templates/mixins.sass +76 -0
- data/test/sass/templates/multiline.sass +20 -0
- metadata +65 -51
- data/lib/haml/util.rb +0 -18
- data/test/haml/runner.rb +0 -16
- data/test/profile.rb +0 -65
@@ -0,0 +1,15 @@
|
|
1
|
+
# allows testing with edge Rails by creating a test/rails symlink
|
2
|
+
linked_rails = File.dirname(__FILE__) + '/../rails'
|
3
|
+
|
4
|
+
if File.exists? linked_rails
|
5
|
+
puts "[ using linked Rails ]"
|
6
|
+
$:.unshift linked_rails + '/activesupport/lib'
|
7
|
+
$:.unshift linked_rails + '/actionpack/lib'
|
8
|
+
else
|
9
|
+
require 'rubygems'
|
10
|
+
end
|
11
|
+
require 'action_controller'
|
12
|
+
require 'action_view'
|
13
|
+
|
14
|
+
require 'test/unit'
|
15
|
+
require File.dirname(__FILE__) + '/../../lib/haml'
|
data/test/sass/engine_test.rb
CHANGED
@@ -5,53 +5,73 @@ require File.dirname(__FILE__) + '/../../lib/sass'
|
|
5
5
|
require 'sass/engine'
|
6
6
|
|
7
7
|
class SassEngineTest < Test::Unit::TestCase
|
8
|
+
# A map of erroneous Sass documents to the error messages they should produce.
|
9
|
+
# The error messages may be arrays;
|
10
|
+
# if so, the second element should be the line number that should be reported for the error.
|
11
|
+
# If this isn't provided, the tests will assume the line number should be the last line of the document.
|
8
12
|
EXCEPTION_MAP = {
|
9
|
-
"!a = 1 + " => 'Constant arithmetic error: "1 +"',
|
10
|
-
"!a = 1 + 2 +" => 'Constant arithmetic error: "1 + 2 +"',
|
11
|
-
"!a = \"b" => 'Unterminated string: "\\"b"',
|
12
|
-
"!a = #aaa - a" => 'Undefined operation: "#aaaaaa minus a"',
|
13
|
-
"!a = #aaa / a" => 'Undefined operation: "#aaaaaa div a"',
|
14
|
-
"!a = #aaa * a" => 'Undefined operation: "#aaaaaa times a"',
|
15
|
-
"!a = #aaa % a" => 'Undefined operation: "#aaaaaa mod a"',
|
16
|
-
"!a = 1 - a" => 'Undefined operation: "1 minus a"',
|
17
|
-
"!a = 1 * a" => 'Undefined operation: "1 times a"',
|
18
|
-
"!a = 1 / a" => 'Undefined operation: "1 div a"',
|
19
|
-
"!a = 1 % a" => 'Undefined operation: "1 mod a"',
|
20
|
-
":" => 'Invalid attribute: ":"',
|
21
|
-
": a" => 'Invalid attribute: ": a"',
|
22
|
-
":= a" => 'Invalid attribute: ":= a"',
|
23
|
-
"a\n :b" => 'Invalid attribute: ":b "',
|
24
|
-
"a\n :b: c" => 'Invalid attribute: ":b: c"',
|
25
|
-
"a\n :b:c d" => 'Invalid attribute: ":b:c d"',
|
26
|
-
"a\n :b=c d" => 'Invalid attribute: ":b=c d"',
|
27
|
-
"a\n :b c;" => 'Invalid attribute: ":b c;" (This isn\'t CSS!)',
|
28
|
-
"a\n b : c" => 'Invalid attribute: "b : c"',
|
29
|
-
"a\n b=c: d" => 'Invalid attribute: "b=c: d"',
|
13
|
+
"!a = 1 + " => 'Constant arithmetic error: "1 +".',
|
14
|
+
"!a = 1 + 2 +" => 'Constant arithmetic error: "1 + 2 +".',
|
15
|
+
"!a = \"b" => 'Unterminated string: "\\"b".',
|
16
|
+
"!a = #aaa - a" => 'Undefined operation: "#aaaaaa minus a".',
|
17
|
+
"!a = #aaa / a" => 'Undefined operation: "#aaaaaa div a".',
|
18
|
+
"!a = #aaa * a" => 'Undefined operation: "#aaaaaa times a".',
|
19
|
+
"!a = #aaa % a" => 'Undefined operation: "#aaaaaa mod a".',
|
20
|
+
"!a = 1 - a" => 'Undefined operation: "1 minus a".',
|
21
|
+
"!a = 1 * a" => 'Undefined operation: "1 times a".',
|
22
|
+
"!a = 1 / a" => 'Undefined operation: "1 div a".',
|
23
|
+
"!a = 1 % a" => 'Undefined operation: "1 mod a".',
|
24
|
+
":" => 'Invalid attribute: ":".',
|
25
|
+
": a" => 'Invalid attribute: ": a".',
|
26
|
+
":= a" => 'Invalid attribute: ":= a".',
|
27
|
+
"a\n :b" => 'Invalid attribute: ":b ".',
|
28
|
+
"a\n :b: c" => 'Invalid attribute: ":b: c".',
|
29
|
+
"a\n :b:c d" => 'Invalid attribute: ":b:c d".',
|
30
|
+
"a\n :b=c d" => 'Invalid attribute: ":b=c d".',
|
31
|
+
"a\n :b c;" => 'Invalid attribute: ":b c;" (This isn\'t CSS!).',
|
32
|
+
"a\n b : c" => 'Invalid attribute: "b : c".',
|
33
|
+
"a\n b=c: d" => 'Invalid attribute: "b=c: d".',
|
30
34
|
":a" => 'Attributes aren\'t allowed at the root of a document.',
|
31
|
-
"!" => 'Invalid constant: "!"',
|
32
|
-
"!a" => 'Invalid constant: "!a"',
|
33
|
-
"! a" => 'Invalid constant: "! a"',
|
34
|
-
"!a b" => 'Invalid constant: "!a b"',
|
35
|
-
"a\n\t:b c" =>
|
36
|
-
|
37
|
-
|
35
|
+
"!" => 'Invalid constant: "!".',
|
36
|
+
"!a" => 'Invalid constant: "!a".',
|
37
|
+
"! a" => 'Invalid constant: "! a".',
|
38
|
+
"!a b" => 'Invalid constant: "!a b".',
|
39
|
+
"a\n\t:b c" => <<END.strip,
|
40
|
+
A tab character was used for indentation. Sass must be indented using two spaces.
|
41
|
+
Are you sure you have soft tabs enabled in your editor?
|
42
|
+
END
|
43
|
+
"a\n :b c" => "1 space was used for indentation. Sass must be indented using two spaces.",
|
44
|
+
"a\n :b c" => "4 spaces were used for indentation. Sass must be indented using two spaces.",
|
38
45
|
"a\n :b c\n !d = 3" => "Constants may only be declared at the root of a document.",
|
39
|
-
"!a = 1b + 2c" => "Incompatible units: b and c",
|
40
|
-
"& a\n :b c" => "Base-level rules cannot contain the parent-selector-referencing character '&'",
|
46
|
+
"!a = 1b + 2c" => "Incompatible units: b and c.",
|
47
|
+
"& a\n :b c" => "Base-level rules cannot contain the parent-selector-referencing character '&'.",
|
41
48
|
"a\n :b\n c" => "Illegal nesting: Only attributes may be nested beneath attributes.",
|
42
49
|
"a,\n :b c" => "Rules can\'t end in commas.",
|
50
|
+
"a," => "Rules can\'t end in commas.",
|
51
|
+
"a,\n!b = c" => "Rules can\'t end in commas.",
|
43
52
|
"!a = b\n :c d\n" => "Illegal nesting: Nothing may be nested beneath constants.",
|
44
|
-
"@import foo.sass" => "File to import not found or unreadable: foo.sass",
|
53
|
+
"@import foo.sass" => "File to import not found or unreadable: foo.sass.",
|
45
54
|
"@import templates/basic\n foo" => "Illegal nesting: Nothing may be nested beneath import directives.",
|
46
55
|
"foo\n @import templates/basic" => "Import directives may only be used at the root of a document.",
|
47
56
|
"!foo = bar baz !" => "Unterminated constant.",
|
48
57
|
"!foo = !(foo)" => "Invalid constant.",
|
58
|
+
"=foo\n :color red\n.bar\n +bang" => "Undefined mixin 'bang'.",
|
59
|
+
".bar\n =foo\n :color red\n" => "Mixins may only be defined at the root of a document.",
|
60
|
+
"=foo\n :color red\n.bar\n +foo\n :color red" => "Illegal nesting: Nothing may be nested beneath mixin directives.",
|
61
|
+
|
62
|
+
# Regression tests
|
63
|
+
"a\n b:\n c\n d" => ["Illegal nesting: Only attributes may be nested beneath attributes.", 3]
|
49
64
|
}
|
50
65
|
|
51
66
|
def test_basic_render
|
52
67
|
renders_correctly "basic", { :style => :compact }
|
53
68
|
end
|
54
69
|
|
70
|
+
def test_multiple_calls_to_render
|
71
|
+
sass = Sass::Engine.new("a\n b: c")
|
72
|
+
assert_equal sass.render, sass.render
|
73
|
+
end
|
74
|
+
|
55
75
|
def test_alternate_styles
|
56
76
|
renders_correctly "expanded", { :style => :expanded }
|
57
77
|
renders_correctly "compact", { :style => :compact }
|
@@ -64,8 +84,10 @@ class SassEngineTest < Test::Unit::TestCase
|
|
64
84
|
begin
|
65
85
|
Sass::Engine.new(key).render
|
66
86
|
rescue Sass::SyntaxError => err
|
67
|
-
|
68
|
-
|
87
|
+
value = [value] unless value.is_a?(Array)
|
88
|
+
|
89
|
+
assert_equal(value.first, err.message, "Line: #{key}")
|
90
|
+
assert_equal(value[1] || key.split("\n").length, err.sass_line, "Line: #{key}")
|
69
91
|
assert_match(/\(sass\):[0-9]+/, err.backtrace[0], "Line: #{key}")
|
70
92
|
else
|
71
93
|
assert(false, "Exception not raised for\n#{key}")
|
@@ -98,16 +120,27 @@ class SassEngineTest < Test::Unit::TestCase
|
|
98
120
|
end
|
99
121
|
end
|
100
122
|
|
123
|
+
def test_css_import
|
124
|
+
assert_equal("@import url(./fonts.css) screen;", render("@import url(./fonts.css) screen"))
|
125
|
+
assert_equal("@import \"./fonts.css\" screen;", render("@import \"./fonts.css\" screen"))
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_sass_import
|
129
|
+
renders_correctly "import", { :style => :compact, :load_paths => [File.dirname(__FILE__) + "/templates"] }
|
130
|
+
end
|
131
|
+
|
101
132
|
def test_default_function
|
102
133
|
assert_equal("foo {\n bar: url(foo.png); }\n",
|
103
134
|
render("foo\n bar = url(foo.png)\n"));
|
104
135
|
end
|
105
136
|
|
106
|
-
def
|
137
|
+
def test_basic_multiline_selector
|
107
138
|
assert_equal("#foo #bar,\n#baz #boom {\n foo: bar; }\n",
|
108
139
|
render("#foo #bar,\n#baz #boom\n :foo bar"))
|
109
140
|
assert_equal("#foo #bar,\n#foo #baz {\n foo: bar; }\n",
|
110
141
|
render("#foo\n #bar,\n #baz\n :foo bar"))
|
142
|
+
assert_equal("#foo,\n#bar {\n foo: bar; }\n #foo #baz,\n #bar #baz {\n foo: bar; }\n",
|
143
|
+
render("#foo,\n#bar\n :foo bar\n #baz\n :foo bar"))
|
111
144
|
assert_equal("#foo #bar, #baz #boom { foo: bar; }\n",
|
112
145
|
render("#foo #bar,\n#baz #boom\n :foo bar", :style => :compact))
|
113
146
|
|
@@ -115,6 +148,10 @@ class SassEngineTest < Test::Unit::TestCase
|
|
115
148
|
render("#foo #bar,\n#baz #boom\n :foo bar", :style => :compressed))
|
116
149
|
end
|
117
150
|
|
151
|
+
def test_complex_multiline_selector
|
152
|
+
renders_correctly "multiline"
|
153
|
+
end
|
154
|
+
|
118
155
|
def test_colon_only
|
119
156
|
begin
|
120
157
|
render("a\n b: c", :attribute_syntax => :normal)
|
@@ -208,7 +245,16 @@ END
|
|
208
245
|
def test_cr_newline
|
209
246
|
assert_equal("foo {\n a: b;\n c: d;\n e: f; }\n", render("foo\r a: b\r\n c: d\n\r e: f"))
|
210
247
|
end
|
248
|
+
|
249
|
+
def test_or_eq
|
250
|
+
assert_equal("foo {\n a: b; }\n", render("!foo = b\n!foo ||= c\nfoo\n a = !foo"))
|
251
|
+
assert_equal("foo {\n a: b; }\n", render("!foo ||= b\nfoo\n a = !foo"))
|
252
|
+
end
|
211
253
|
|
254
|
+
def test_mixins
|
255
|
+
renders_correctly "mixins", { :style => :expanded }
|
256
|
+
end
|
257
|
+
|
212
258
|
private
|
213
259
|
|
214
260
|
def render(sass, options = {})
|
data/test/sass/plugin_test.rb
CHANGED
@@ -58,7 +58,7 @@ class SassPluginTest < Test::Unit::TestCase
|
|
58
58
|
File.delete(tempfile_loc('bork'))
|
59
59
|
Sass::Plugin.update_stylesheets
|
60
60
|
File.open(tempfile_loc('bork')) do |file|
|
61
|
-
assert_equal("/*\nSass::SyntaxError: Undefined constant: \"!bork\"
|
61
|
+
assert_equal("/*\nSass::SyntaxError: Undefined constant: \"!bork\".\non line 2 of #{File.dirname(__FILE__) + '/templates/bork.sass'}\n\n1: bork\n2: :bork= !bork", file.read.split("\n")[0...6].join("\n"))
|
62
62
|
end
|
63
63
|
File.delete(tempfile_loc('bork'))
|
64
64
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
imported { otherconst: hello; myconst: goodbye; }
|
1
|
+
imported { otherconst: hello; myconst: goodbye; pre-mixin: here; }
|
2
2
|
|
3
3
|
body { font: Arial; background: blue; }
|
4
4
|
|
@@ -26,4 +26,4 @@ body { font: Arial; background: blue; }
|
|
26
26
|
@import url(../results/complex.css);
|
27
27
|
#foo { background-color: #baf; }
|
28
28
|
|
29
|
-
nonimported { myconst: hello; otherconst: goodbye; }
|
29
|
+
nonimported { myconst: hello; otherconst: goodbye; post-mixin: here; }
|
@@ -0,0 +1,95 @@
|
|
1
|
+
#main {
|
2
|
+
width: 15em;
|
3
|
+
color: #0000ff;
|
4
|
+
}
|
5
|
+
#main p {
|
6
|
+
border-top-width: 2px;
|
7
|
+
border-top-color: #ffcc00;
|
8
|
+
border-left-width: 1px;
|
9
|
+
border-left-color: #000;
|
10
|
+
-moz-border-radius: 10px;
|
11
|
+
border-style: dotted;
|
12
|
+
border-width: 2px;
|
13
|
+
}
|
14
|
+
#main .cool {
|
15
|
+
width: 100px;
|
16
|
+
}
|
17
|
+
|
18
|
+
#left {
|
19
|
+
border-top-width: 2px;
|
20
|
+
border-top-color: #ffcc00;
|
21
|
+
border-left-width: 1px;
|
22
|
+
border-left-color: #000;
|
23
|
+
-moz-border-radius: 10px;
|
24
|
+
font-size: 2em;
|
25
|
+
font-weight: bold;
|
26
|
+
float: left;
|
27
|
+
}
|
28
|
+
|
29
|
+
#right {
|
30
|
+
border-top-width: 2px;
|
31
|
+
border-top-color: #ffcc00;
|
32
|
+
border-left-width: 1px;
|
33
|
+
border-left-color: #000;
|
34
|
+
-moz-border-radius: 10px;
|
35
|
+
color: #f00;
|
36
|
+
font-size: 20px;
|
37
|
+
float: right;
|
38
|
+
}
|
39
|
+
|
40
|
+
.bordered {
|
41
|
+
border-top-width: 2px;
|
42
|
+
border-top-color: #ffcc00;
|
43
|
+
border-left-width: 1px;
|
44
|
+
border-left-color: #000;
|
45
|
+
-moz-border-radius: 10px;
|
46
|
+
}
|
47
|
+
|
48
|
+
.complex {
|
49
|
+
color: #f00;
|
50
|
+
font-size: 20px;
|
51
|
+
text-decoration: none;
|
52
|
+
}
|
53
|
+
.complex:after {
|
54
|
+
content: ".";
|
55
|
+
display: block;
|
56
|
+
height: 0;
|
57
|
+
clear: both;
|
58
|
+
visibility: hidden;
|
59
|
+
}
|
60
|
+
* html .complex {
|
61
|
+
height: 1px;
|
62
|
+
color: #f00;
|
63
|
+
font-size: 20px;
|
64
|
+
}
|
65
|
+
|
66
|
+
.more-complex {
|
67
|
+
color: #f00;
|
68
|
+
font-size: 20px;
|
69
|
+
text-decoration: none;
|
70
|
+
display: inline;
|
71
|
+
-webkit-nonsense-top-right: 1px;
|
72
|
+
-webkit-nonsense-bottom-left: 1px;
|
73
|
+
}
|
74
|
+
.more-complex:after {
|
75
|
+
content: ".";
|
76
|
+
display: block;
|
77
|
+
height: 0;
|
78
|
+
clear: both;
|
79
|
+
visibility: hidden;
|
80
|
+
}
|
81
|
+
* html .more-complex {
|
82
|
+
height: 1px;
|
83
|
+
color: #f00;
|
84
|
+
font-size: 20px;
|
85
|
+
}
|
86
|
+
.more-complex a:hover {
|
87
|
+
text-decoration: underline;
|
88
|
+
color: #f00;
|
89
|
+
font-size: 20px;
|
90
|
+
border-top-width: 2px;
|
91
|
+
border-top-color: #ffcc00;
|
92
|
+
border-left-width: 1px;
|
93
|
+
border-left-color: #000;
|
94
|
+
-moz-border-radius: 10px;
|
95
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#main,
|
2
|
+
#header {
|
3
|
+
height: 50px; }
|
4
|
+
#main div,
|
5
|
+
#header div {
|
6
|
+
width: 100px; }
|
7
|
+
#main div a span,
|
8
|
+
#main div em span,
|
9
|
+
#header div a span,
|
10
|
+
#header div em span {
|
11
|
+
color: pink; }
|
12
|
+
|
13
|
+
#one div.nested,
|
14
|
+
#one span.nested,
|
15
|
+
#one p.nested,
|
16
|
+
#two div.nested,
|
17
|
+
#two span.nested,
|
18
|
+
#two p.nested,
|
19
|
+
#three div.nested,
|
20
|
+
#three span.nested,
|
21
|
+
#three p.nested {
|
22
|
+
font-weight: bold;
|
23
|
+
border-color: red;
|
24
|
+
display: block; }
|
@@ -0,0 +1,76 @@
|
|
1
|
+
!yellow = #fc0
|
2
|
+
|
3
|
+
=bordered
|
4
|
+
:border
|
5
|
+
:top
|
6
|
+
:width 2px
|
7
|
+
:color = !yellow
|
8
|
+
:left
|
9
|
+
:width 1px
|
10
|
+
:color #000
|
11
|
+
-moz-border-radius: 10px
|
12
|
+
|
13
|
+
=header-font
|
14
|
+
:color #f00
|
15
|
+
:font
|
16
|
+
:size 20px
|
17
|
+
|
18
|
+
=compound
|
19
|
+
+header-font
|
20
|
+
+bordered
|
21
|
+
|
22
|
+
=complex
|
23
|
+
+header-font
|
24
|
+
text:
|
25
|
+
decoration: none
|
26
|
+
&:after
|
27
|
+
content: "."
|
28
|
+
display: block
|
29
|
+
height: 0
|
30
|
+
clear: both
|
31
|
+
visibility: hidden
|
32
|
+
* html &
|
33
|
+
height: 1px
|
34
|
+
+header-font
|
35
|
+
=deep
|
36
|
+
a:hover
|
37
|
+
:text-decoration underline
|
38
|
+
+compound
|
39
|
+
|
40
|
+
|
41
|
+
#main
|
42
|
+
:width 15em
|
43
|
+
:color #0000ff
|
44
|
+
p
|
45
|
+
+bordered
|
46
|
+
:border
|
47
|
+
:style dotted
|
48
|
+
:width 2px
|
49
|
+
.cool
|
50
|
+
:width 100px
|
51
|
+
|
52
|
+
#left
|
53
|
+
+bordered
|
54
|
+
:font
|
55
|
+
:size 2em
|
56
|
+
:weight bold
|
57
|
+
:float left
|
58
|
+
|
59
|
+
#right
|
60
|
+
+bordered
|
61
|
+
+header-font
|
62
|
+
:float right
|
63
|
+
|
64
|
+
.bordered
|
65
|
+
+bordered
|
66
|
+
|
67
|
+
.complex
|
68
|
+
+complex
|
69
|
+
|
70
|
+
.more-complex
|
71
|
+
+complex
|
72
|
+
+deep
|
73
|
+
display: inline
|
74
|
+
-webkit-nonsense:
|
75
|
+
top-right: 1px
|
76
|
+
bottom-left: 1px
|