haml-edge 2.3.100 → 2.3.148
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/.yardopts +3 -0
- data/EDGE_GEM_VERSION +1 -1
- data/Rakefile +14 -2
- data/VERSION +1 -1
- data/extra/haml-mode.el +97 -11
- data/extra/sass-mode.el +2 -2
- data/lib/haml/engine.rb +2 -2
- data/lib/haml/exec.rb +121 -25
- data/lib/haml/filters.rb +1 -1
- data/lib/haml/helpers/action_view_mods.rb +2 -1
- data/lib/haml/helpers/xss_mods.rb +43 -13
- data/lib/haml/helpers.rb +38 -17
- data/lib/haml/html.rb +13 -4
- data/lib/haml/precompiler.rb +24 -3
- data/lib/haml/template/plugin.rb +7 -3
- data/lib/haml/template.rb +3 -3
- data/lib/haml/util.rb +40 -0
- data/lib/sass/callbacks.rb +50 -0
- data/lib/sass/css.rb +1 -1
- data/lib/sass/engine.rb +45 -5
- data/lib/sass/error.rb +6 -3
- data/lib/sass/files.rb +8 -1
- data/lib/sass/plugin/rails.rb +2 -2
- data/lib/sass/plugin.rb +260 -28
- data/lib/sass/script/color.rb +216 -30
- data/lib/sass/script/functions.rb +356 -74
- data/lib/sass/script/lexer.rb +7 -4
- data/lib/sass/script/number.rb +2 -0
- data/lib/sass/script/parser.rb +1 -1
- data/lib/sass/script.rb +3 -0
- data/lib/sass/tree/node.rb +1 -1
- data/lib/sass/tree/root_node.rb +6 -0
- data/lib/sass/tree/rule_node.rb +1 -0
- data/lib/sass.rb +4 -0
- data/test/haml/engine_test.rb +25 -0
- data/test/haml/helper_test.rb +81 -1
- data/test/haml/html2haml_test.rb +13 -0
- data/test/haml/spec/README.md +97 -0
- data/test/haml/spec/lua_haml_spec.lua +30 -0
- data/test/haml/spec/ruby_haml_test.rb +19 -0
- data/test/haml/spec/tests.json +534 -0
- data/test/haml/spec_test.rb +0 -0
- data/test/haml/template_test.rb +18 -4
- data/test/haml/util_test.rb +0 -0
- data/test/sass/callbacks_test.rb +61 -0
- data/test/sass/css2sass_test.rb +1 -0
- data/test/sass/engine_test.rb +70 -14
- data/test/sass/functions_test.rb +223 -3
- data/test/sass/plugin_test.rb +193 -25
- data/test/sass/results/options.css +1 -0
- data/test/sass/script_test.rb +5 -5
- data/test/sass/templates/options.sass +2 -0
- data/test/test_helper.rb +12 -5
- metadata +19 -9
@@ -0,0 +1,534 @@
|
|
1
|
+
{
|
2
|
+
"headers" : {
|
3
|
+
|
4
|
+
"an XHTML XML prolog" : {
|
5
|
+
"haml" : "!!! XML",
|
6
|
+
"html" : "<?xml version='1.0' encoding='utf-8' ?>"
|
7
|
+
},
|
8
|
+
|
9
|
+
"an XHTML default (transitional) doctype" : {
|
10
|
+
"haml" : "!!!",
|
11
|
+
"html" : "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"
|
12
|
+
},
|
13
|
+
|
14
|
+
"an XHTML 1.1 doctype" : {
|
15
|
+
"haml" : "!!! 1.1",
|
16
|
+
"html" : "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">"
|
17
|
+
},
|
18
|
+
|
19
|
+
"an XHTML 1.2 mobile doctype" : {
|
20
|
+
"haml" : "!!! mobile",
|
21
|
+
"html" : "<!DOCTYPE html PUBLIC \"-//WAPFORUM//DTD XHTML Mobile 1.2//EN\" \"http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd\">"
|
22
|
+
},
|
23
|
+
|
24
|
+
"an XHTML 1.1 basic doctype" : {
|
25
|
+
"haml" : "!!! basic",
|
26
|
+
"html" : "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML Basic 1.1//EN\" \"http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd\">"
|
27
|
+
},
|
28
|
+
|
29
|
+
"an XHTML 1.0 frameset doctype" : {
|
30
|
+
"haml" : "!!! frameset",
|
31
|
+
"html" : "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">"
|
32
|
+
},
|
33
|
+
|
34
|
+
"an HTML 5 doctype with XHTML syntax" : {
|
35
|
+
"haml" : "!!! 5",
|
36
|
+
"html" : "<!DOCTYPE html>"
|
37
|
+
},
|
38
|
+
|
39
|
+
"an HTML 5 XML prolog (silent)" : {
|
40
|
+
"haml" : "!!! XML",
|
41
|
+
"html" : "",
|
42
|
+
"config" : {
|
43
|
+
"format" : "html5"
|
44
|
+
}
|
45
|
+
},
|
46
|
+
|
47
|
+
"an HTML 5 doctype" : {
|
48
|
+
"haml" : "!!!",
|
49
|
+
"html" : "<!DOCTYPE html>",
|
50
|
+
"config" : {
|
51
|
+
"format" : "html5"
|
52
|
+
}
|
53
|
+
},
|
54
|
+
|
55
|
+
"an HTML 4 XML prolog (silent)" : {
|
56
|
+
"haml" : "!!! XML",
|
57
|
+
"html" : "",
|
58
|
+
"config" : {
|
59
|
+
"format" : "html4"
|
60
|
+
}
|
61
|
+
},
|
62
|
+
|
63
|
+
"an HTML 4 default (transitional) doctype" : {
|
64
|
+
"haml" : "!!!",
|
65
|
+
"html" : "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">",
|
66
|
+
"config" : {
|
67
|
+
"format" : "html4"
|
68
|
+
}
|
69
|
+
},
|
70
|
+
|
71
|
+
"an HTML 4 frameset doctype" : {
|
72
|
+
"haml" : "!!! frameset",
|
73
|
+
"html" : "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\" \"http://www.w3.org/TR/html4/frameset.dtd\">",
|
74
|
+
"config" : {
|
75
|
+
"format" : "html4"
|
76
|
+
}
|
77
|
+
},
|
78
|
+
|
79
|
+
"an HTML 4 strict doctype" : {
|
80
|
+
"haml" : "!!! strict",
|
81
|
+
"html" : "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">",
|
82
|
+
"config" : {
|
83
|
+
"format" : "html4"
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
},
|
88
|
+
|
89
|
+
"basic Haml tags and CSS": {
|
90
|
+
|
91
|
+
"a simple Haml tag" : {
|
92
|
+
"haml" : "%p",
|
93
|
+
"html" : "<p></p>"
|
94
|
+
},
|
95
|
+
|
96
|
+
"a self-closing tag (XHTML)" : {
|
97
|
+
"haml" : "%meta",
|
98
|
+
"html" : "<meta />"
|
99
|
+
},
|
100
|
+
|
101
|
+
"a self-closing tag (HTML4)" : {
|
102
|
+
"haml" : "%meta",
|
103
|
+
"html" : "<meta>",
|
104
|
+
"config" : {
|
105
|
+
"format" : "html4"
|
106
|
+
}
|
107
|
+
},
|
108
|
+
|
109
|
+
"a self-closing tag (HTML5)" : {
|
110
|
+
"haml" : "%meta",
|
111
|
+
"html" : "<meta>",
|
112
|
+
"config" : {
|
113
|
+
"format" : "html5"
|
114
|
+
}
|
115
|
+
},
|
116
|
+
|
117
|
+
"a tag with a CSS class" : {
|
118
|
+
"haml" : "%p.class1",
|
119
|
+
"html" : "<p class='class1'></p>"
|
120
|
+
},
|
121
|
+
|
122
|
+
"a tag with multiple CSS classes" : {
|
123
|
+
"haml" : "%p.class1.class2",
|
124
|
+
"html" : "<p class='class1 class2'></p>"
|
125
|
+
},
|
126
|
+
|
127
|
+
"a tag with a CSS id" : {
|
128
|
+
"haml" : "%p#id1",
|
129
|
+
"html" : "<p id='id1'></p>"
|
130
|
+
},
|
131
|
+
|
132
|
+
"a tag with multiple CSS id's" : {
|
133
|
+
"haml" : "%p#id1#id2",
|
134
|
+
"html" : "<p id='id2'></p>"
|
135
|
+
},
|
136
|
+
|
137
|
+
"a tag with a class followed by an id" : {
|
138
|
+
"haml" : "%p.class1#id1",
|
139
|
+
"html" : "<p class='class1' id='id1'></p>"
|
140
|
+
},
|
141
|
+
|
142
|
+
"a tag with an id followed by a class" : {
|
143
|
+
"haml" : "%p#id1.class1",
|
144
|
+
"html" : "<p class='class1' id='id1'></p>"
|
145
|
+
},
|
146
|
+
|
147
|
+
"an implicit div with a CSS id" : {
|
148
|
+
"haml" : "#id1",
|
149
|
+
"html" : "<div id='id1'></div>"
|
150
|
+
},
|
151
|
+
|
152
|
+
"an implicit div with a CSS class" : {
|
153
|
+
"haml" : ".class1",
|
154
|
+
"html" : "<div class='class1'></div>"
|
155
|
+
},
|
156
|
+
|
157
|
+
"multiple simple Haml tags" : {
|
158
|
+
"haml" : "%div\n %div\n %p",
|
159
|
+
"html" : "<div>\n <div>\n <p></p>\n </div>\n</div>"
|
160
|
+
}
|
161
|
+
},
|
162
|
+
|
163
|
+
"tags with unusual HTML characters" : {
|
164
|
+
|
165
|
+
"a tag with colons" : {
|
166
|
+
"haml" : "%ns:tag",
|
167
|
+
"html" : "<ns:tag></ns:tag>"
|
168
|
+
},
|
169
|
+
|
170
|
+
"a tag with underscores" : {
|
171
|
+
"haml" : "%snake_case",
|
172
|
+
"html" : "<snake_case></snake_case>"
|
173
|
+
},
|
174
|
+
|
175
|
+
"a tag with dashes" : {
|
176
|
+
"haml" : "%dashed-tag",
|
177
|
+
"html" : "<dashed-tag></dashed-tag>"
|
178
|
+
},
|
179
|
+
|
180
|
+
"a tag with camelCase" : {
|
181
|
+
"haml" : "%camelCase",
|
182
|
+
"html" : "<camelCase></camelCase>"
|
183
|
+
},
|
184
|
+
|
185
|
+
"a tag with PascalCase" : {
|
186
|
+
"haml" : "%PascalCase",
|
187
|
+
"html" : "<PascalCase></PascalCase>"
|
188
|
+
}
|
189
|
+
},
|
190
|
+
|
191
|
+
"tags with unusual CSS identifiers" : {
|
192
|
+
|
193
|
+
"an all-numeric class" : {
|
194
|
+
"haml" : ".123",
|
195
|
+
"html" : "<div class='123'></div>"
|
196
|
+
},
|
197
|
+
|
198
|
+
"a class with underscores" : {
|
199
|
+
"haml" : ".__",
|
200
|
+
"html" : "<div class='__'></div>"
|
201
|
+
},
|
202
|
+
|
203
|
+
"a class with dashes" : {
|
204
|
+
"haml" : ".--",
|
205
|
+
"html" : "<div class='--'></div>"
|
206
|
+
}
|
207
|
+
|
208
|
+
},
|
209
|
+
|
210
|
+
"tags with inline content" : {
|
211
|
+
|
212
|
+
"a simple tag" : {
|
213
|
+
"haml" : "%p hello",
|
214
|
+
"html" : "<p>hello</p>"
|
215
|
+
},
|
216
|
+
|
217
|
+
"a tag with CSS" : {
|
218
|
+
"haml" : "%p.class1 hello",
|
219
|
+
"html" : "<p class='class1'>hello</p>"
|
220
|
+
},
|
221
|
+
|
222
|
+
"multiple simple tags" : {
|
223
|
+
"haml" : "%div\n %div\n %p text",
|
224
|
+
"html" : "<div>\n <div>\n <p>text</p>\n </div>\n</div>"
|
225
|
+
}
|
226
|
+
},
|
227
|
+
|
228
|
+
"tags with nested content" : {
|
229
|
+
|
230
|
+
"a simple tag" : {
|
231
|
+
"haml" : "%p\n hello",
|
232
|
+
"html" : "<p>\n hello\n</p>"
|
233
|
+
},
|
234
|
+
|
235
|
+
"a tag with CSS" : {
|
236
|
+
"haml" : "%p.class1\n hello",
|
237
|
+
"html" : "<p class='class1'>\n hello\n</p>"
|
238
|
+
},
|
239
|
+
|
240
|
+
"multiple simple tags" : {
|
241
|
+
"haml" : "%div\n %div\n %p\n text",
|
242
|
+
"html" : "<div>\n <div>\n <p>\n text\n </p>\n </div>\n</div>"
|
243
|
+
}
|
244
|
+
|
245
|
+
},
|
246
|
+
|
247
|
+
"tags with HTML-style attributes": {
|
248
|
+
|
249
|
+
"one attribute" : {
|
250
|
+
"haml" : "%p(a='b')",
|
251
|
+
"html" : "<p a='b'></p>"
|
252
|
+
},
|
253
|
+
|
254
|
+
"multiple attributes" : {
|
255
|
+
"haml" : "%p(a='b' c='d')",
|
256
|
+
"html" : "<p a='b' c='d'></p>"
|
257
|
+
},
|
258
|
+
|
259
|
+
"attributes separated with newlines" : {
|
260
|
+
"haml" : "%p(a='b'\n c='d')",
|
261
|
+
"html" : "<p a='b' c='d'></p>"
|
262
|
+
},
|
263
|
+
|
264
|
+
"an interpolated attribute" : {
|
265
|
+
"haml" : "%p(a=\"#{var}\")",
|
266
|
+
"html" : "<p a='value'></p>",
|
267
|
+
"locals" : {
|
268
|
+
"var" : "value"
|
269
|
+
}
|
270
|
+
},
|
271
|
+
|
272
|
+
"'class' as an attribute" : {
|
273
|
+
"haml" : "%p(class='class1')",
|
274
|
+
"html" : "<p class='class1'></p>"
|
275
|
+
},
|
276
|
+
|
277
|
+
"a tag with a CSS class and 'class' as an attribute" : {
|
278
|
+
"haml" : "%p.class2(class='class1')",
|
279
|
+
"html" : "<p class='class1 class2'></p>"
|
280
|
+
},
|
281
|
+
|
282
|
+
"a tag with 'id' as an attribute" : {
|
283
|
+
"haml" : "%p(id='1')",
|
284
|
+
"html" : "<p id='1'></p>"
|
285
|
+
},
|
286
|
+
|
287
|
+
"a tag with a CSS id and 'id' as an attribute" : {
|
288
|
+
"haml" : "%p#id(id='1')",
|
289
|
+
"html" : "<p id='id_1'></p>"
|
290
|
+
},
|
291
|
+
|
292
|
+
"a tag with a variable attribute" : {
|
293
|
+
"haml" : "%p(class=var)",
|
294
|
+
"html" : "<p class='hello'></p>",
|
295
|
+
"locals" : {
|
296
|
+
"var" : "hello"
|
297
|
+
}
|
298
|
+
},
|
299
|
+
|
300
|
+
"a tag with a CSS class and 'class' as a variable attribute" : {
|
301
|
+
"haml" : ".hello(class=var)",
|
302
|
+
"html" : "<div class='hello world'></div>",
|
303
|
+
"locals" : {
|
304
|
+
"var" : "world"
|
305
|
+
}
|
306
|
+
},
|
307
|
+
|
308
|
+
"a tag multiple CSS classes (sorted correctly)" : {
|
309
|
+
"haml" : ".z(class=var)",
|
310
|
+
"html" : "<div class='a z'></div>",
|
311
|
+
"locals" : {
|
312
|
+
"var" : "a"
|
313
|
+
}
|
314
|
+
}
|
315
|
+
|
316
|
+
},
|
317
|
+
|
318
|
+
"tags with Ruby-style attributes": {
|
319
|
+
|
320
|
+
"one attribute" : {
|
321
|
+
"haml" : "%p{:a => 'b'}",
|
322
|
+
"html" : "<p a='b'></p>"
|
323
|
+
},
|
324
|
+
|
325
|
+
"attributes hash with whitespace" : {
|
326
|
+
"haml" : "%p{ :a => 'b' }",
|
327
|
+
"html" : "<p a='b'></p>"
|
328
|
+
},
|
329
|
+
|
330
|
+
"an interpolated attribute" : {
|
331
|
+
"haml" : "%p{:a =>\"#{var}\"}",
|
332
|
+
"html" : "<p a='value'></p>",
|
333
|
+
"locals" : {
|
334
|
+
"var" : "value"
|
335
|
+
}
|
336
|
+
},
|
337
|
+
|
338
|
+
"multiple attributes" : {
|
339
|
+
"haml" : "%p{ :a => 'b', 'c' => 'd' }",
|
340
|
+
"html" : "<p a='b' c='d'></p>"
|
341
|
+
},
|
342
|
+
|
343
|
+
"attributes separated with newlines" : {
|
344
|
+
"haml" : "%p{ :a => 'b',\n 'c' => 'd' }",
|
345
|
+
"html" : "<p a='b' c='d'></p>"
|
346
|
+
},
|
347
|
+
|
348
|
+
"'class' as an attribute" : {
|
349
|
+
"haml" : "%p{:class => 'class1'}",
|
350
|
+
"html" : "<p class='class1'></p>"
|
351
|
+
},
|
352
|
+
|
353
|
+
"a tag with a CSS class and 'class' as an attribute" : {
|
354
|
+
"haml" : "%p.class2{:class => 'class1'}",
|
355
|
+
"html" : "<p class='class1 class2'></p>"
|
356
|
+
},
|
357
|
+
|
358
|
+
"a tag with 'id' as an attribute" : {
|
359
|
+
"haml" : "%p{:id => '1'}",
|
360
|
+
"html" : "<p id='1'></p>"
|
361
|
+
},
|
362
|
+
|
363
|
+
"a tag with a CSS id and 'id' as an attribute" : {
|
364
|
+
"haml" : "%p#id{:id => '1'}",
|
365
|
+
"html" : "<p id='id_1'></p>"
|
366
|
+
},
|
367
|
+
|
368
|
+
"a tag with a CSS id and a numeric 'id' as an attribute" : {
|
369
|
+
"haml" : "%p#id{:id => 1}",
|
370
|
+
"html" : "<p id='id_1'></p>"
|
371
|
+
},
|
372
|
+
|
373
|
+
"a tag with a variable attribute" : {
|
374
|
+
"haml" : "%p{:class => var}",
|
375
|
+
"html" : "<p class='hello'></p>",
|
376
|
+
"locals" : {
|
377
|
+
"var" : "hello"
|
378
|
+
}
|
379
|
+
},
|
380
|
+
|
381
|
+
"a tag with a CSS class and 'class' as a variable attribute" : {
|
382
|
+
"haml" : ".hello{:class => var}",
|
383
|
+
"html" : "<div class='hello world'></div>",
|
384
|
+
"locals" : {
|
385
|
+
"var" : "world"
|
386
|
+
}
|
387
|
+
},
|
388
|
+
|
389
|
+
"a tag multiple CSS classes (sorted correctly)" : {
|
390
|
+
"haml" : ".z{:class => var}",
|
391
|
+
"html" : "<div class='a z'></div>",
|
392
|
+
"locals" : {
|
393
|
+
"var" : "a"
|
394
|
+
}
|
395
|
+
}
|
396
|
+
|
397
|
+
},
|
398
|
+
|
399
|
+
"silent comments" : {
|
400
|
+
|
401
|
+
"an inline comment" : {
|
402
|
+
"haml" : "-# hello",
|
403
|
+
"html" : ""
|
404
|
+
},
|
405
|
+
|
406
|
+
"a nested comment" : {
|
407
|
+
"haml" : "-#\n hello",
|
408
|
+
"html" : ""
|
409
|
+
}
|
410
|
+
|
411
|
+
},
|
412
|
+
|
413
|
+
"markup comments" : {
|
414
|
+
|
415
|
+
"an inline comment" : {
|
416
|
+
"haml" : "/ comment",
|
417
|
+
"html" : "<!-- comment -->"
|
418
|
+
},
|
419
|
+
|
420
|
+
"a nested comment" : {
|
421
|
+
"haml" : "/\n comment\n comment2",
|
422
|
+
"html" : "<!--\n comment\n comment2\n-->"
|
423
|
+
}
|
424
|
+
},
|
425
|
+
|
426
|
+
"conditional comments": {
|
427
|
+
"a conditional comment" : {
|
428
|
+
"haml" : "/[if IE]\n %p a",
|
429
|
+
"html" : "<!--[if IE]>\n <p>a</p>\n<![endif]-->"
|
430
|
+
}
|
431
|
+
},
|
432
|
+
|
433
|
+
"internal filters": {
|
434
|
+
|
435
|
+
"content in an 'escaped' filter" : {
|
436
|
+
"haml" : ":escaped\n <&\">",
|
437
|
+
"html" : "<&">"
|
438
|
+
},
|
439
|
+
|
440
|
+
"content in a 'preserve' filter" : {
|
441
|
+
"haml" : ":preserve\n hello\n\n%p",
|
442
|
+
"html" : "hello
\n<p></p>"
|
443
|
+
},
|
444
|
+
|
445
|
+
"content in a 'plain' filter" : {
|
446
|
+
"haml" : ":plain\n hello\n\n%p",
|
447
|
+
"html" : "hello\n<p></p>"
|
448
|
+
},
|
449
|
+
|
450
|
+
"content in a 'javascript' filter" : {
|
451
|
+
"haml" : ":javascript\n a();\n%p",
|
452
|
+
"html" : "<script type='text/javascript'>\n //<![CDATA[\n a();\n //]]>\n</script>\n<p></p>"
|
453
|
+
}
|
454
|
+
|
455
|
+
},
|
456
|
+
|
457
|
+
"interpolation": {
|
458
|
+
|
459
|
+
"interpolation inside inline content" : {
|
460
|
+
"haml" : "%p #{var}",
|
461
|
+
"html" : "<p>value</p>",
|
462
|
+
"locals" : {
|
463
|
+
"var" : "value"
|
464
|
+
}
|
465
|
+
},
|
466
|
+
|
467
|
+
"no interpolation when escaped" : {
|
468
|
+
"haml" : "%p \\#{var}",
|
469
|
+
"html" : "<p>#{var}</p>"
|
470
|
+
},
|
471
|
+
|
472
|
+
"interpolation when the escape character is escaped" : {
|
473
|
+
"haml" : "%p \\\\#{var}",
|
474
|
+
"html" : "<p>\\value</p>",
|
475
|
+
"locals" : {
|
476
|
+
"var" : "value"
|
477
|
+
}
|
478
|
+
},
|
479
|
+
|
480
|
+
"interpolation inside filtered content" : {
|
481
|
+
"haml" : ":plain\n #{var} interpolated: #{var}",
|
482
|
+
"html" : "value interpolated: value",
|
483
|
+
"locals" : {
|
484
|
+
"var" : "value"
|
485
|
+
}
|
486
|
+
}
|
487
|
+
|
488
|
+
},
|
489
|
+
|
490
|
+
"HTML escaping" : {
|
491
|
+
|
492
|
+
"code following '&='" : {
|
493
|
+
"haml" : "&= '<\"&>'",
|
494
|
+
"html" : "<"&>"
|
495
|
+
},
|
496
|
+
|
497
|
+
"code following '=' when escape_haml is set to true" : {
|
498
|
+
"haml" : "= '<\"&>'",
|
499
|
+
"html" : "<"&>",
|
500
|
+
"config" : {
|
501
|
+
"escape_html" : "true"
|
502
|
+
}
|
503
|
+
},
|
504
|
+
|
505
|
+
"code following '!=' when escape_haml is set to true" : {
|
506
|
+
"haml" : "!= '<\"&>'",
|
507
|
+
"html" : "<\"&>",
|
508
|
+
"config" : {
|
509
|
+
"escape_html" : "true"
|
510
|
+
}
|
511
|
+
}
|
512
|
+
|
513
|
+
},
|
514
|
+
|
515
|
+
"Boolean attributes" : {
|
516
|
+
|
517
|
+
"boolean attribute with XHTML" : {
|
518
|
+
"haml" : "%input(checked=true)",
|
519
|
+
"html" : "<input checked='checked' />",
|
520
|
+
"config" : {
|
521
|
+
"format" : "xhtml"
|
522
|
+
}
|
523
|
+
},
|
524
|
+
|
525
|
+
"boolean attribute with HTML" : {
|
526
|
+
"haml" : "%input(checked=true)",
|
527
|
+
"html" : "<input checked>",
|
528
|
+
"config" : {
|
529
|
+
"format" : "html5"
|
530
|
+
}
|
531
|
+
}
|
532
|
+
}
|
533
|
+
|
534
|
+
}
|
data/test/haml/spec_test.rb
CHANGED
File without changes
|
data/test/haml/template_test.rb
CHANGED
@@ -109,7 +109,7 @@ class TemplateTest < Test::Unit::TestCase
|
|
109
109
|
message = "template: #{name}\nline: #{line}"
|
110
110
|
assert_equal(pair.first, pair.last, message)
|
111
111
|
end
|
112
|
-
rescue
|
112
|
+
rescue Haml::Util.av_template_class(:Error) => e
|
113
113
|
if e.message =~ /Can't run [\w:]+ filter; required (one of|file) ((?:'\w+'(?: or )?)+)(, but none were found| not found)/
|
114
114
|
puts "\nCouldn't require #{$2}; skipping a test."
|
115
115
|
else
|
@@ -258,7 +258,7 @@ END
|
|
258
258
|
end
|
259
259
|
|
260
260
|
def test_xss_protection_with_safe_strings
|
261
|
-
assert_equal("Foo & Bar\n", render('= "Foo & Bar"
|
261
|
+
assert_equal("Foo & Bar\n", render('= Haml::Util.html_safe("Foo & Bar")', :action_view))
|
262
262
|
end
|
263
263
|
|
264
264
|
def test_xss_protection_with_bang
|
@@ -274,11 +274,11 @@ END
|
|
274
274
|
end
|
275
275
|
|
276
276
|
def test_xss_protection_with_safe_strings_in_interpolation
|
277
|
-
assert_equal("Foo & Bar\n", render('Foo #{"&"
|
277
|
+
assert_equal("Foo & Bar\n", render('Foo #{Haml::Util.html_safe("&")} Bar', :action_view))
|
278
278
|
end
|
279
279
|
|
280
280
|
def test_xss_protection_with_mixed_strings_in_interpolation
|
281
|
-
assert_equal("Foo & Bar & Baz\n", render('Foo #{"&"
|
281
|
+
assert_equal("Foo & Bar & Baz\n", render('Foo #{Haml::Util.html_safe("&")} Bar #{"&"} Baz', :action_view))
|
282
282
|
end
|
283
283
|
|
284
284
|
def test_rendered_string_is_html_safe
|
@@ -292,5 +292,19 @@ END
|
|
292
292
|
def test_xss_html_escaping_with_non_strings
|
293
293
|
assert_equal("4\n", render("= html_escape(4)"))
|
294
294
|
end
|
295
|
+
|
296
|
+
def test_xss_protection_with_concat
|
297
|
+
assert_equal("Foo & Bar", render('- concat "Foo & Bar"', :action_view))
|
298
|
+
end
|
299
|
+
|
300
|
+
def test_xss_protection_with_concat_with_safe_string
|
301
|
+
assert_equal("Foo & Bar", render('- concat(Haml::Util.html_safe("Foo & Bar"))', :action_view))
|
302
|
+
end
|
303
|
+
|
304
|
+
if Haml::Util.has?(:instance_method, ActionView::Helpers::TextHelper, :safe_concat)
|
305
|
+
def test_xss_protection_with_safe_concat
|
306
|
+
assert_equal("Foo & Bar", render('- safe_concat "Foo & Bar"', :action_view))
|
307
|
+
end
|
308
|
+
end
|
295
309
|
end
|
296
310
|
end
|
data/test/haml/util_test.rb
CHANGED
File without changes
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
3
|
+
require 'sass/callbacks'
|
4
|
+
|
5
|
+
class CallerBack
|
6
|
+
extend Sass::Callbacks
|
7
|
+
define_callback :foo
|
8
|
+
define_callback :bar
|
9
|
+
|
10
|
+
def do_foo
|
11
|
+
run_foo
|
12
|
+
end
|
13
|
+
|
14
|
+
def do_bar
|
15
|
+
run_bar 12
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module ClassLevelCallerBack
|
20
|
+
extend Sass::Callbacks
|
21
|
+
define_callback :foo
|
22
|
+
extend self
|
23
|
+
|
24
|
+
def do_foo
|
25
|
+
run_foo
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class SassCallbacksTest < Test::Unit::TestCase
|
30
|
+
def test_simple_callback
|
31
|
+
cb = CallerBack.new
|
32
|
+
there = false
|
33
|
+
cb.on_foo {there = true}
|
34
|
+
cb.do_foo
|
35
|
+
assert there, "Expected callback to be called."
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_multiple_callbacks
|
39
|
+
cb = CallerBack.new
|
40
|
+
str = ""
|
41
|
+
cb.on_foo {str += "first"}
|
42
|
+
cb.on_foo {str += " second"}
|
43
|
+
cb.do_foo
|
44
|
+
assert_equal "first second", str
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_callback_with_arg
|
48
|
+
cb = CallerBack.new
|
49
|
+
val = nil
|
50
|
+
cb.on_bar {|a| val = a}
|
51
|
+
cb.do_bar
|
52
|
+
assert_equal 12, val
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_class_level_callback
|
56
|
+
there = false
|
57
|
+
ClassLevelCallerBack.on_foo {there = true}
|
58
|
+
ClassLevelCallerBack.do_foo
|
59
|
+
assert there, "Expected callback to be called."
|
60
|
+
end
|
61
|
+
end
|
data/test/sass/css2sass_test.rb
CHANGED