haml 1.8.0 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/FAQ +138 -0
- data/MIT-LICENSE +1 -1
- data/{README → README.rdoc} +66 -3
- data/REVISION +1 -0
- data/Rakefile +115 -147
- data/VERSION +1 -1
- data/bin/css2sass +0 -0
- data/bin/haml +2 -1
- data/bin/html2haml +0 -0
- data/bin/sass +0 -0
- data/init.rb +6 -1
- data/lib/haml/buffer.rb +122 -64
- data/lib/haml/engine.rb +77 -46
- data/lib/haml/error.rb +15 -6
- data/lib/haml/exec.rb +61 -10
- data/lib/haml/filters.rb +229 -74
- data/lib/haml/helpers/action_view_extensions.rb +1 -1
- data/lib/haml/helpers/action_view_mods.rb +109 -24
- data/lib/haml/helpers.rb +137 -76
- data/lib/haml/html.rb +8 -8
- data/lib/haml/precompiler.rb +280 -153
- data/lib/haml/template/patch.rb +10 -3
- data/lib/haml/template/plugin.rb +61 -10
- data/lib/haml/template.rb +14 -9
- data/lib/haml.rb +483 -214
- data/lib/sass/constant/color.rb +13 -13
- data/lib/sass/constant/literal.rb +8 -7
- data/lib/sass/constant/nil.rb +9 -0
- data/lib/sass/constant/number.rb +10 -10
- data/lib/sass/constant/operation.rb +4 -4
- data/lib/sass/constant/string.rb +3 -3
- data/lib/sass/constant.rb +46 -77
- data/lib/sass/css.rb +130 -56
- data/lib/sass/engine.rb +131 -43
- data/lib/sass/plugin/merb.rb +48 -12
- data/lib/sass/plugin/rails.rb +10 -4
- data/lib/sass/plugin.rb +33 -10
- 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/lib/sass.rb +194 -19
- data/rails/init.rb +1 -0
- data/test/benchmark.rb +67 -80
- data/test/haml/engine_test.rb +368 -152
- data/test/haml/helper_test.rb +68 -16
- data/test/haml/html2haml_test.rb +3 -4
- 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 +38 -30
- data/test/haml/results/helpers.xhtml +4 -8
- data/test/haml/results/just_stuff.xhtml +8 -7
- data/test/haml/results/nuke_inner_whitespace.xhtml +40 -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 +42 -57
- data/test/haml/templates/_partial.haml +1 -0
- data/test/haml/templates/filters.haml +39 -21
- data/test/haml/templates/helpers.haml +10 -10
- data/test/haml/templates/just_stuff.haml +8 -3
- data/test/haml/templates/nuke_inner_whitespace.haml +32 -0
- data/test/haml/templates/nuke_outer_whitespace.haml +144 -0
- data/test/haml/templates/partials.haml +1 -1
- data/test/haml/templates/tag_parsing.haml +0 -3
- data/test/haml/templates/whitespace_handling.haml +10 -10
- data/test/sass/engine_test.rb +97 -39
- data/test/sass/plugin_test.rb +4 -7
- data/test/sass/results/constants.css +2 -0
- 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/constants.sass +3 -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
- data/test/test_helper.rb +18 -0
- metadata +70 -53
- data/lib/haml/helpers/action_view_mods.rb.rej +0 -30
- data/lib/haml/util.rb +0 -18
- data/lib/sass/constant.rb.rej +0 -42
- data/test/haml/runner.rb +0 -16
- data/test/profile.rb +0 -65
- data/test/sass/engine_test.rb.rej +0 -18
data/test/sass/engine_test.rb
CHANGED
|
@@ -1,57 +1,79 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
-
|
|
3
|
-
require 'test/unit'
|
|
4
|
-
require File.dirname(__FILE__) + '/../../lib/sass'
|
|
2
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
|
5
3
|
require 'sass/engine'
|
|
6
4
|
|
|
7
5
|
class SassEngineTest < Test::Unit::TestCase
|
|
6
|
+
# A map of erroneous Sass documents to the error messages they should produce.
|
|
7
|
+
# The error messages may be arrays;
|
|
8
|
+
# if so, the second element should be the line number that should be reported for the error.
|
|
9
|
+
# If this isn't provided, the tests will assume the line number should be the last line of the document.
|
|
8
10
|
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"',
|
|
11
|
+
"!a = 1 + " => 'Constant arithmetic error: "1 +".',
|
|
12
|
+
"!a = 1 + 2 +" => 'Constant arithmetic error: "1 + 2 +".',
|
|
13
|
+
"!a = \"b" => 'Unterminated string: "\\"b".',
|
|
14
|
+
"!a = #aaa - a" => 'Undefined operation: "#aaaaaa minus a".',
|
|
15
|
+
"!a = #aaa / a" => 'Undefined operation: "#aaaaaa div a".',
|
|
16
|
+
"!a = #aaa * a" => 'Undefined operation: "#aaaaaa times a".',
|
|
17
|
+
"!a = #aaa % a" => 'Undefined operation: "#aaaaaa mod a".',
|
|
18
|
+
"!a = 1 - a" => 'Undefined operation: "1 minus a".',
|
|
19
|
+
"!a = 1 * a" => 'Undefined operation: "1 times a".',
|
|
20
|
+
"!a = 1 / a" => 'Undefined operation: "1 div a".',
|
|
21
|
+
"!a = 1 % a" => 'Undefined operation: "1 mod a".',
|
|
22
|
+
":" => 'Invalid attribute: ":".',
|
|
23
|
+
": a" => 'Invalid attribute: ": a".',
|
|
24
|
+
":= a" => 'Invalid attribute: ":= a".',
|
|
25
|
+
"a\n :b" => 'Invalid attribute: ":b ".',
|
|
26
|
+
"a\n :b: c" => 'Invalid attribute: ":b: c".',
|
|
27
|
+
"a\n :b:c d" => 'Invalid attribute: ":b:c d".',
|
|
28
|
+
"a\n :b=c d" => 'Invalid attribute: ":b=c d".',
|
|
29
|
+
"a\n :b c;" => 'Invalid attribute: ":b c;" (This isn\'t CSS!).',
|
|
30
|
+
"a\n b : c" => 'Invalid attribute: "b : c".',
|
|
31
|
+
"a\n b=c: d" => 'Invalid attribute: "b=c: d".',
|
|
30
32
|
":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
|
-
|
|
33
|
+
"!" => 'Invalid constant: "!".',
|
|
34
|
+
"!a" => 'Invalid constant: "!a".',
|
|
35
|
+
"! a" => 'Invalid constant: "! a".',
|
|
36
|
+
"!a b" => 'Invalid constant: "!a b".',
|
|
37
|
+
"a\n\t:b c" => <<END.strip,
|
|
38
|
+
A tab character was used for indentation. Sass must be indented using two spaces.
|
|
39
|
+
Are you sure you have soft tabs enabled in your editor?
|
|
40
|
+
END
|
|
41
|
+
"a\n :b c" => "1 space was used for indentation. Sass must be indented using two spaces.",
|
|
42
|
+
"a\n :b c" => "4 spaces were used for indentation. Sass must be indented using two spaces.",
|
|
38
43
|
"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 '&'",
|
|
44
|
+
"!a = 1b + 2c" => "Incompatible units: b and c.",
|
|
45
|
+
"& a\n :b c" => ["Base-level rules cannot contain the parent-selector-referencing character '&'.", 1],
|
|
41
46
|
"a\n :b\n c" => "Illegal nesting: Only attributes may be nested beneath attributes.",
|
|
42
47
|
"a,\n :b c" => "Rules can\'t end in commas.",
|
|
48
|
+
"a," => "Rules can\'t end in commas.",
|
|
49
|
+
"a,\n!b = c" => "Rules can\'t end in commas.",
|
|
43
50
|
"!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",
|
|
51
|
+
"@import foo.sass" => "File to import not found or unreadable: foo.sass.",
|
|
45
52
|
"@import templates/basic\n foo" => "Illegal nesting: Nothing may be nested beneath import directives.",
|
|
46
53
|
"foo\n @import templates/basic" => "Import directives may only be used at the root of a document.",
|
|
47
54
|
"!foo = bar baz !" => "Unterminated constant.",
|
|
48
55
|
"!foo = !(foo)" => "Invalid constant.",
|
|
56
|
+
"=foo\n :color red\n.bar\n +bang" => "Undefined mixin 'bang'.",
|
|
57
|
+
".bar\n =foo\n :color red\n" => "Mixins may only be defined at the root of a document.",
|
|
58
|
+
"=foo\n :color red\n.bar\n +foo\n :color red" => "Illegal nesting: Nothing may be nested beneath mixin directives.",
|
|
59
|
+
" a\n b: c" => ["Indenting at the beginning of the document is illegal.", 1],
|
|
60
|
+
" \n \n\t\n a\n b: c" => ["Indenting at the beginning of the document is illegal.", 4],
|
|
61
|
+
|
|
62
|
+
# Regression tests
|
|
63
|
+
"a\n b:\n c\n d" => ["Illegal nesting: Only attributes may be nested beneath attributes.", 3],
|
|
64
|
+
"& foo\n bar: baz\n blat: bang" => ["Base-level rules cannot contain the parent-selector-referencing character '&'.", 1],
|
|
65
|
+
"a\n b: c\n& foo\n bar: baz\n blat: bang" => ["Base-level rules cannot contain the parent-selector-referencing character '&'.", 3],
|
|
49
66
|
}
|
|
50
67
|
|
|
51
68
|
def test_basic_render
|
|
52
69
|
renders_correctly "basic", { :style => :compact }
|
|
53
70
|
end
|
|
54
71
|
|
|
72
|
+
def test_multiple_calls_to_render
|
|
73
|
+
sass = Sass::Engine.new("a\n b: c")
|
|
74
|
+
assert_equal sass.render, sass.render
|
|
75
|
+
end
|
|
76
|
+
|
|
55
77
|
def test_alternate_styles
|
|
56
78
|
renders_correctly "expanded", { :style => :expanded }
|
|
57
79
|
renders_correctly "compact", { :style => :compact }
|
|
@@ -64,8 +86,10 @@ class SassEngineTest < Test::Unit::TestCase
|
|
|
64
86
|
begin
|
|
65
87
|
Sass::Engine.new(key).render
|
|
66
88
|
rescue Sass::SyntaxError => err
|
|
67
|
-
|
|
68
|
-
|
|
89
|
+
value = [value] unless value.is_a?(Array)
|
|
90
|
+
|
|
91
|
+
assert_equal(value.first, err.message, "Line: #{key}")
|
|
92
|
+
assert_equal(value[1] || key.split("\n").length, err.sass_line, "Line: #{key}")
|
|
69
93
|
assert_match(/\(sass\):[0-9]+/, err.backtrace[0], "Line: #{key}")
|
|
70
94
|
else
|
|
71
95
|
assert(false, "Exception not raised for\n#{key}")
|
|
@@ -98,16 +122,27 @@ class SassEngineTest < Test::Unit::TestCase
|
|
|
98
122
|
end
|
|
99
123
|
end
|
|
100
124
|
|
|
125
|
+
def test_css_import
|
|
126
|
+
assert_equal("@import url(./fonts.css) screen;", render("@import url(./fonts.css) screen"))
|
|
127
|
+
assert_equal("@import \"./fonts.css\" screen;", render("@import \"./fonts.css\" screen"))
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def test_sass_import
|
|
131
|
+
renders_correctly "import", { :style => :compact, :load_paths => [File.dirname(__FILE__) + "/templates"] }
|
|
132
|
+
end
|
|
133
|
+
|
|
101
134
|
def test_default_function
|
|
102
|
-
assert_equal("foo {\n bar: url(foo.png); }\n",
|
|
103
|
-
|
|
135
|
+
assert_equal("foo {\n bar: url(foo.png); }\n", render("foo\n bar = url(foo.png)\n"));
|
|
136
|
+
assert_equal("foo {\n bar: url(); }\n", render("foo\n bar = url()\n"));
|
|
104
137
|
end
|
|
105
138
|
|
|
106
|
-
def
|
|
139
|
+
def test_basic_multiline_selector
|
|
107
140
|
assert_equal("#foo #bar,\n#baz #boom {\n foo: bar; }\n",
|
|
108
141
|
render("#foo #bar,\n#baz #boom\n :foo bar"))
|
|
109
142
|
assert_equal("#foo #bar,\n#foo #baz {\n foo: bar; }\n",
|
|
110
143
|
render("#foo\n #bar,\n #baz\n :foo bar"))
|
|
144
|
+
assert_equal("#foo,\n#bar {\n foo: bar; }\n #foo #baz,\n #bar #baz {\n foo: bar; }\n",
|
|
145
|
+
render("#foo,\n#bar\n :foo bar\n #baz\n :foo bar"))
|
|
111
146
|
assert_equal("#foo #bar, #baz #boom { foo: bar; }\n",
|
|
112
147
|
render("#foo #bar,\n#baz #boom\n :foo bar", :style => :compact))
|
|
113
148
|
|
|
@@ -115,6 +150,10 @@ class SassEngineTest < Test::Unit::TestCase
|
|
|
115
150
|
render("#foo #bar,\n#baz #boom\n :foo bar", :style => :compressed))
|
|
116
151
|
end
|
|
117
152
|
|
|
153
|
+
def test_complex_multiline_selector
|
|
154
|
+
renders_correctly "multiline"
|
|
155
|
+
end
|
|
156
|
+
|
|
118
157
|
def test_colon_only
|
|
119
158
|
begin
|
|
120
159
|
render("a\n b: c", :attribute_syntax => :normal)
|
|
@@ -204,7 +243,26 @@ END
|
|
|
204
243
|
assert_equal(":focus {\n a: b; }\n", render("\\:focus\n a: b"))
|
|
205
244
|
assert_equal("a {\n b: c; }\n a :focus {\n d: e; }\n", render("\\a\n b: c\n \\:focus\n d: e"))
|
|
206
245
|
end
|
|
246
|
+
|
|
247
|
+
def test_cr_newline
|
|
248
|
+
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"))
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def test_or_eq
|
|
252
|
+
assert_equal("foo {\n a: b; }\n", render("!foo = b\n!foo ||= c\nfoo\n a = !foo"))
|
|
253
|
+
assert_equal("foo {\n a: b; }\n", render("!foo ||= b\nfoo\n a = !foo"))
|
|
254
|
+
end
|
|
207
255
|
|
|
256
|
+
def test_mixins
|
|
257
|
+
renders_correctly "mixins", { :style => :expanded }
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def test_mixins_dont_interfere_with_sibling_combinator
|
|
261
|
+
assert_equal("foo + bar {\n a: b; }\n", render("foo\n + bar\n a: b"))
|
|
262
|
+
assert_equal("foo + bar {\n a: b; }\nfoo + baz {\n c: d; }\n",
|
|
263
|
+
render("foo\n +\n bar\n a: b\n baz\n c: d"))
|
|
264
|
+
end
|
|
265
|
+
|
|
208
266
|
private
|
|
209
267
|
|
|
210
268
|
def render(sass, options = {})
|
data/test/sass/plugin_test.rb
CHANGED
|
@@ -3,13 +3,9 @@
|
|
|
3
3
|
MERB_ENV = RAILS_ENV = 'testing'
|
|
4
4
|
RAILS_ROOT = '.'
|
|
5
5
|
|
|
6
|
-
require '
|
|
7
|
-
require 'fileutils'
|
|
8
|
-
require File.dirname(__FILE__) + '/../../lib/sass'
|
|
9
|
-
require 'rubygems'
|
|
10
|
-
|
|
11
|
-
require 'action_controller'
|
|
6
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
|
12
7
|
require 'sass/plugin'
|
|
8
|
+
require 'fileutils'
|
|
13
9
|
|
|
14
10
|
class SassPluginTest < Test::Unit::TestCase
|
|
15
11
|
@@templates = %w{
|
|
@@ -58,7 +54,7 @@ class SassPluginTest < Test::Unit::TestCase
|
|
|
58
54
|
File.delete(tempfile_loc('bork'))
|
|
59
55
|
Sass::Plugin.update_stylesheets
|
|
60
56
|
File.open(tempfile_loc('bork')) do |file|
|
|
61
|
-
assert_equal("/*\nSass::SyntaxError: Undefined constant: \"!bork\"
|
|
57
|
+
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
58
|
end
|
|
63
59
|
File.delete(tempfile_loc('bork'))
|
|
64
60
|
end
|
|
@@ -155,5 +151,6 @@ class Sass::Engine
|
|
|
155
151
|
end
|
|
156
152
|
|
|
157
153
|
class ActionController::Base
|
|
154
|
+
undef :sass_old_process
|
|
158
155
|
def sass_old_process(*args); end
|
|
159
156
|
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
|
data/test/test_helper.rb
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
lib_dir = File.dirname(__FILE__) + '/../lib'
|
|
2
|
+
# allows testing with edge Rails by creating a test/rails symlink
|
|
3
|
+
linked_rails = File.dirname(__FILE__) + '/rails'
|
|
4
|
+
|
|
5
|
+
if File.exists?(linked_rails) && !$:.include?(linked_rails + '/activesupport/lib')
|
|
6
|
+
puts "[ using linked Rails ]"
|
|
7
|
+
$:.unshift linked_rails + '/activesupport/lib'
|
|
8
|
+
$:.unshift linked_rails + '/actionpack/lib'
|
|
9
|
+
else
|
|
10
|
+
require 'rubygems'
|
|
11
|
+
end
|
|
12
|
+
require 'action_controller'
|
|
13
|
+
require 'action_view'
|
|
14
|
+
|
|
15
|
+
require 'test/unit'
|
|
16
|
+
$:.unshift lib_dir unless $:.include?(lib_dir)
|
|
17
|
+
require 'haml'
|
|
18
|
+
require 'sass'
|