wysihtml5_with_ps 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Makefile +98 -0
- data/Rakefile +38 -0
- data/lib/base/base.js +139 -0
- data/lib/rangy/rangy-core.js +3211 -0
- data/lib/wysihtml5_with_ps/version.rb +3 -0
- data/test/assert/html_equal_test.js +32 -0
- data/test/browser_test.js +85 -0
- data/test/dom/auto_link_test.js +105 -0
- data/test/dom/contains_test.js +18 -0
- data/test/dom/convert_to_list_test.js +101 -0
- data/test/dom/copy_attributes_test.js +51 -0
- data/test/dom/copy_styles_test.js +110 -0
- data/test/dom/delegate_test.js +62 -0
- data/test/dom/get_as_dom_test.js +55 -0
- data/test/dom/get_parent_element_test.js +161 -0
- data/test/dom/get_style_test.js +54 -0
- data/test/dom/has_element_with_class_name_test.js +29 -0
- data/test/dom/has_element_with_tag_name_test.js +25 -0
- data/test/dom/insert_css_test.js +31 -0
- data/test/dom/observe_test.js +83 -0
- data/test/dom/parse_test.js +614 -0
- data/test/dom/rename_element_test.js +28 -0
- data/test/dom/resolve_list_test.js +46 -0
- data/test/dom/sandbox_test.js +184 -0
- data/test/dom/set_attributes_test.js +15 -0
- data/test/dom/set_styles_test.js +19 -0
- data/test/editor_test.js +547 -0
- data/test/incompatible_test.js +60 -0
- data/test/index.html +126 -0
- data/test/lang/array_test.js +22 -0
- data/test/lang/object_test.js +22 -0
- data/test/lang/string_test.js +19 -0
- data/test/quirks/clean_pasted_html_test.js +11 -0
- data/test/undo_manager_test.js +94 -0
- metadata +116 -0
@@ -0,0 +1,614 @@
|
|
1
|
+
if (wysihtml5.browser.supported()) {
|
2
|
+
|
3
|
+
module("wysihtml5.dom.parse", {
|
4
|
+
sanitize: function(html, rules, context, cleanUp) {
|
5
|
+
return wysihtml5.dom.parse(html, rules, context, cleanUp);
|
6
|
+
},
|
7
|
+
|
8
|
+
equal: function(actual, expected, message) {
|
9
|
+
return wysihtml5.assert.htmlEqual(actual, expected, message);
|
10
|
+
}
|
11
|
+
});
|
12
|
+
|
13
|
+
test("Simple tests using plain tags only", function() {
|
14
|
+
var rules = {
|
15
|
+
tags: {
|
16
|
+
p: "div",
|
17
|
+
script: undefined,
|
18
|
+
div: {}
|
19
|
+
}
|
20
|
+
};
|
21
|
+
|
22
|
+
this.equal(
|
23
|
+
this.sanitize("<i id=\"foo\">bar</i>", rules),
|
24
|
+
"<span>bar</span>",
|
25
|
+
"Unknown tag gets renamed to span"
|
26
|
+
);
|
27
|
+
|
28
|
+
this.equal(
|
29
|
+
this.sanitize("<p>foo</p>", rules),
|
30
|
+
"<div>foo</div>",
|
31
|
+
"Known tag gets renamed to it's corresponding conversion"
|
32
|
+
);
|
33
|
+
|
34
|
+
this.equal(
|
35
|
+
this.sanitize("<script>window;</script>", rules),
|
36
|
+
"",
|
37
|
+
"Forbidden tag gets correctly removed"
|
38
|
+
);
|
39
|
+
|
40
|
+
this.equal(
|
41
|
+
this.sanitize("foobar", rules),
|
42
|
+
"foobar",
|
43
|
+
"Plain text is kept"
|
44
|
+
);
|
45
|
+
|
46
|
+
this.equal(
|
47
|
+
this.sanitize("<table><tbody><tr><td>I'm a table!</td></tr></tbody></table>"),
|
48
|
+
"<span><span><span><span>I'm a table!</span></span></span></span>",
|
49
|
+
"Passing no conversion renames all into <span> elements"
|
50
|
+
);
|
51
|
+
|
52
|
+
this.equal(
|
53
|
+
this.sanitize("<p>foobar<br></p>", { tags: { p: true, br: true } }),
|
54
|
+
"<p>foobar<br></p>",
|
55
|
+
"Didn't rewrite the HTML"
|
56
|
+
);
|
57
|
+
|
58
|
+
this.equal(
|
59
|
+
this.sanitize("<div><!-- COMMENT -->foo</div>"),
|
60
|
+
"<span>foo</span>",
|
61
|
+
"Stripped out comments"
|
62
|
+
);
|
63
|
+
|
64
|
+
this.equal(
|
65
|
+
this.sanitize("<article>foo</article>", { tags: { article: true } }),
|
66
|
+
"<article>foo</article>",
|
67
|
+
"Check html5 tags"
|
68
|
+
);
|
69
|
+
|
70
|
+
this.equal(
|
71
|
+
this.sanitize("<!DOCTYPE html><p>html5 doctype</p>", { tags: { p: true } }),
|
72
|
+
"<p>html5 doctype</p>",
|
73
|
+
"Stripped out doctype"
|
74
|
+
);
|
75
|
+
});
|
76
|
+
|
77
|
+
|
78
|
+
test("Advanced tests using tags and attributes", function() {
|
79
|
+
var rules = {
|
80
|
+
tags: {
|
81
|
+
img: {
|
82
|
+
set_attributes: { alt: "foo", border: "1" },
|
83
|
+
check_attributes: { src: "url", width: "numbers", height: "numbers", border: "numbers" }
|
84
|
+
},
|
85
|
+
a: {
|
86
|
+
rename_tag: "i",
|
87
|
+
set_attributes: { title: "" }
|
88
|
+
},
|
89
|
+
video: undefined,
|
90
|
+
h1: { rename_tag: "h2" },
|
91
|
+
h2: true,
|
92
|
+
h3: undefined
|
93
|
+
}
|
94
|
+
};
|
95
|
+
|
96
|
+
this.equal(
|
97
|
+
this.sanitize(
|
98
|
+
'<h1 id="main-headline" >take this you snorty little sanitizer</h1>' +
|
99
|
+
'<h2>yes, you!</h2>' +
|
100
|
+
'<h3>i\'m old and ready to die</h3>' +
|
101
|
+
'<div><video src="pr0n.avi">foobar</video><img src="http://foo.gif" height="10" width="10"><img src="/foo.gif"></div>' +
|
102
|
+
'<div><a href="http://www.google.de"></a></div>',
|
103
|
+
rules
|
104
|
+
),
|
105
|
+
'<h2>take this you snorty little sanitizer</h2>' +
|
106
|
+
'<h2>yes, you!</h2>' +
|
107
|
+
'<span><img alt="foo" border="1" src="http://foo.gif" height="10" width="10"><img alt="foo" border="1"></span>' +
|
108
|
+
'<span><i title=""></i></span>'
|
109
|
+
);
|
110
|
+
});
|
111
|
+
|
112
|
+
test("Attribute check of 'url' cleans up", function() {
|
113
|
+
var rules = {
|
114
|
+
tags: {
|
115
|
+
img: {
|
116
|
+
check_attributes: { src: "url" }
|
117
|
+
}
|
118
|
+
}
|
119
|
+
};
|
120
|
+
|
121
|
+
this.equal(
|
122
|
+
this.sanitize(
|
123
|
+
'<img src="http://url.gif">' +
|
124
|
+
'<img src="/path/to/absolute%20href.gif">' +
|
125
|
+
'<img src="mango time">',
|
126
|
+
rules
|
127
|
+
),
|
128
|
+
'<img src="http://url.gif"><img><img>'
|
129
|
+
);
|
130
|
+
});
|
131
|
+
|
132
|
+
test("Attribute check of 'src' cleans up", function() {
|
133
|
+
var rules = {
|
134
|
+
tags: {
|
135
|
+
img: {
|
136
|
+
check_attributes: { src: "src" }
|
137
|
+
}
|
138
|
+
}
|
139
|
+
};
|
140
|
+
|
141
|
+
this.equal(
|
142
|
+
this.sanitize(
|
143
|
+
'<img src="HTTP://url.gif">' +
|
144
|
+
'<img src="/path/to/absolute%20href.gif">' +
|
145
|
+
'<img src="mailto:christopher@foobar.com">' +
|
146
|
+
'<img src="mango time">',
|
147
|
+
rules
|
148
|
+
),
|
149
|
+
'<img src="http://url.gif">' +
|
150
|
+
'<img src="/path/to/absolute%20href.gif">' +
|
151
|
+
'<img>' +
|
152
|
+
'<img>'
|
153
|
+
);
|
154
|
+
});
|
155
|
+
|
156
|
+
test("Attribute check of 'href' cleans up", function() {
|
157
|
+
var rules = {
|
158
|
+
tags: {
|
159
|
+
a: {
|
160
|
+
check_attributes: { href: "href" }
|
161
|
+
}
|
162
|
+
}
|
163
|
+
};
|
164
|
+
|
165
|
+
this.equal(
|
166
|
+
this.sanitize(
|
167
|
+
'<a href="/foobar"></a>' +
|
168
|
+
'<a href="HTTPS://google.com"></a>' +
|
169
|
+
'<a href="http://google.com"></a>' +
|
170
|
+
'<a href="MAILTO:christopher@foobar.com"></a>' +
|
171
|
+
'<a href="mango time"></a>' +
|
172
|
+
'<a href="ftp://google.com"></a>',
|
173
|
+
rules
|
174
|
+
),
|
175
|
+
'<a href="/foobar"></a>' +
|
176
|
+
'<a href="https://google.com"></a>' +
|
177
|
+
'<a href="http://google.com"></a>' +
|
178
|
+
'<a href="mailto:christopher@foobar.com"></a>' +
|
179
|
+
'<a></a>' +
|
180
|
+
'<a></a>'
|
181
|
+
);
|
182
|
+
});
|
183
|
+
|
184
|
+
test("Bug in IE8 where invalid html causes duplicated content", function() {
|
185
|
+
var rules = {
|
186
|
+
tags: { p: true, span: true, div: true }
|
187
|
+
};
|
188
|
+
|
189
|
+
var result = this.sanitize('<SPAN><P><SPAN><div>FOO</div>', rules);
|
190
|
+
ok(result.indexOf("FOO") === result.lastIndexOf("FOO"));
|
191
|
+
});
|
192
|
+
|
193
|
+
|
194
|
+
test("Bug in IE8 where elements are duplicated when multiple parsed", function() {
|
195
|
+
var rules = {
|
196
|
+
tags: { p: true, span: true, div: true }
|
197
|
+
};
|
198
|
+
|
199
|
+
var firstResult = this.sanitize('<SPAN><P><SPAN>foo<P></P>', rules);
|
200
|
+
var secondResult = this.sanitize(firstResult, rules);
|
201
|
+
|
202
|
+
ok(secondResult.indexOf("foo") !== -1);
|
203
|
+
this.equal(firstResult, secondResult);
|
204
|
+
|
205
|
+
firstResult = this.sanitize('<SPAN><DIV><SPAN>foo<DIV></DIV>', rules);
|
206
|
+
secondResult = this.sanitize(firstResult, rules);
|
207
|
+
|
208
|
+
ok(secondResult.indexOf("foo") !== -1);
|
209
|
+
this.equal(firstResult, secondResult);
|
210
|
+
});
|
211
|
+
|
212
|
+
test("Test cleanup mode", function() {
|
213
|
+
var rules = {
|
214
|
+
tags: { span: true, div: true }
|
215
|
+
};
|
216
|
+
|
217
|
+
this.equal(
|
218
|
+
this.sanitize("<div><span>foo</span></div>", rules, null, true),
|
219
|
+
"<div>foo</div>"
|
220
|
+
);
|
221
|
+
|
222
|
+
this.equal(
|
223
|
+
this.sanitize("<span><p>foo</p></span>", rules, null, true),
|
224
|
+
"foo"
|
225
|
+
);
|
226
|
+
});
|
227
|
+
|
228
|
+
|
229
|
+
test("Advanced tests for 'img' elements", function() {
|
230
|
+
var rules = {
|
231
|
+
classes: {
|
232
|
+
"wysiwyg-float-right": 1,
|
233
|
+
"wysiwyg-float-left": 1
|
234
|
+
},
|
235
|
+
tags: {
|
236
|
+
img: {
|
237
|
+
check_attributes: {
|
238
|
+
width: "numbers",
|
239
|
+
alt: "alt",
|
240
|
+
src: "url",
|
241
|
+
height: "numbers"
|
242
|
+
},
|
243
|
+
add_class: {
|
244
|
+
align: "align_img"
|
245
|
+
}
|
246
|
+
}
|
247
|
+
}
|
248
|
+
};
|
249
|
+
|
250
|
+
this.equal(
|
251
|
+
this.sanitize(
|
252
|
+
'<img src="https://www.xing.com/img/users/1/2/7/f98db1f73.6149675_s4.jpg" alt="Christopher Blum" width="57" height="75" class="wysiwyg-float-right">',
|
253
|
+
rules
|
254
|
+
),
|
255
|
+
'<img alt="Christopher Blum" class="wysiwyg-float-right" height="75" src="https://www.xing.com/img/users/1/2/7/f98db1f73.6149675_s4.jpg" width="57">'
|
256
|
+
);
|
257
|
+
|
258
|
+
this.equal(
|
259
|
+
this.sanitize(
|
260
|
+
'<img src="https://www.xing.com/img/users/1/2/7/f98db1f73.6149675_s4.jpg" alt="Christopher Blum" width="57" height="75" ALIGN="RIGHT">',
|
261
|
+
rules
|
262
|
+
),
|
263
|
+
'<img alt="Christopher Blum" class="wysiwyg-float-right" height="75" src="https://www.xing.com/img/users/1/2/7/f98db1f73.6149675_s4.jpg" width="57">'
|
264
|
+
);
|
265
|
+
|
266
|
+
this.equal(
|
267
|
+
this.sanitize(
|
268
|
+
'<img src="https://www.xing.com/img/users/1/2/7/f98db1f73.6149675_s4.jpg" alt="Christopher Blum" width="57" height="75" align="left">',
|
269
|
+
rules
|
270
|
+
),
|
271
|
+
'<img alt="Christopher Blum" class="wysiwyg-float-left" height="75" src="https://www.xing.com/img/users/1/2/7/f98db1f73.6149675_s4.jpg" width="57">'
|
272
|
+
);
|
273
|
+
|
274
|
+
this.equal(
|
275
|
+
this.sanitize(
|
276
|
+
'<img src="https://www.xing.com/img/users/1/2/7/f98db1f73.6149675_s4.jpg" alt="Christopher Blum" width="57" height="75" align="">',
|
277
|
+
rules
|
278
|
+
),
|
279
|
+
'<img alt="Christopher Blum" height="75" src="https://www.xing.com/img/users/1/2/7/f98db1f73.6149675_s4.jpg" width="57">'
|
280
|
+
);
|
281
|
+
|
282
|
+
this.equal(
|
283
|
+
this.sanitize(
|
284
|
+
'<img src="/img/users/1/2/7/f98db1f73.6149675_s4.jpg" alt="Christopher Blum" width="57" height="75">',
|
285
|
+
rules
|
286
|
+
),
|
287
|
+
'<img alt="Christopher Blum" height="75" width="57">'
|
288
|
+
);
|
289
|
+
|
290
|
+
this.equal(
|
291
|
+
this.sanitize(
|
292
|
+
'<img src="file://foobar.jpg" alt="Christopher Blum" width="57" height="75">',
|
293
|
+
rules
|
294
|
+
),
|
295
|
+
'<img alt="Christopher Blum" height="75" width="57">'
|
296
|
+
);
|
297
|
+
|
298
|
+
this.equal(
|
299
|
+
this.sanitize(
|
300
|
+
'<img src="https://www.xing.com/img/users/1/2/7/f98db1f73.6149675_s4.jpg" width="57" height="75">',
|
301
|
+
rules
|
302
|
+
),
|
303
|
+
'<img alt="" height="75" src="https://www.xing.com/img/users/1/2/7/f98db1f73.6149675_s4.jpg" width="57">'
|
304
|
+
);
|
305
|
+
|
306
|
+
this.equal(
|
307
|
+
this.sanitize(
|
308
|
+
'<img>',
|
309
|
+
rules
|
310
|
+
),
|
311
|
+
'<img alt="">'
|
312
|
+
);
|
313
|
+
});
|
314
|
+
|
315
|
+
|
316
|
+
test("Advanced tests for 'br' elements", function() {
|
317
|
+
var rules = {
|
318
|
+
classes: {
|
319
|
+
"wysiwyg-clear-both": 1,
|
320
|
+
"wysiwyg-clear-left": 1,
|
321
|
+
"wysiwyg-clear-right": 1
|
322
|
+
},
|
323
|
+
tags: {
|
324
|
+
div: true,
|
325
|
+
br: {
|
326
|
+
add_class: {
|
327
|
+
clear: "clear_br"
|
328
|
+
}
|
329
|
+
}
|
330
|
+
}
|
331
|
+
};
|
332
|
+
|
333
|
+
this.equal(
|
334
|
+
this.sanitize(
|
335
|
+
'<div>foo<br clear="both">bar</div>',
|
336
|
+
rules
|
337
|
+
),
|
338
|
+
'<div>foo<br class="wysiwyg-clear-both">bar</div>'
|
339
|
+
);
|
340
|
+
|
341
|
+
this.equal(
|
342
|
+
this.sanitize(
|
343
|
+
'<div>foo<br clear="all">bar</div>',
|
344
|
+
rules
|
345
|
+
),
|
346
|
+
'<div>foo<br class="wysiwyg-clear-both">bar</div>'
|
347
|
+
);
|
348
|
+
|
349
|
+
this.equal(
|
350
|
+
this.sanitize(
|
351
|
+
'<div>foo<br clear="left" id="foo">bar</div>',
|
352
|
+
rules
|
353
|
+
),
|
354
|
+
'<div>foo<br class="wysiwyg-clear-left">bar</div>'
|
355
|
+
);
|
356
|
+
|
357
|
+
this.equal(
|
358
|
+
this.sanitize(
|
359
|
+
'<br clear="right">',
|
360
|
+
rules
|
361
|
+
),
|
362
|
+
'<br class="wysiwyg-clear-right">'
|
363
|
+
);
|
364
|
+
|
365
|
+
this.equal(
|
366
|
+
this.sanitize(
|
367
|
+
'<br clear="">',
|
368
|
+
rules
|
369
|
+
),
|
370
|
+
'<br>'
|
371
|
+
);
|
372
|
+
|
373
|
+
this.equal(
|
374
|
+
this.sanitize(
|
375
|
+
'<br clear="LEFT">',
|
376
|
+
rules
|
377
|
+
),
|
378
|
+
'<br class="wysiwyg-clear-left">'
|
379
|
+
);
|
380
|
+
|
381
|
+
this.equal(
|
382
|
+
this.sanitize(
|
383
|
+
'<br class="wysiwyg-clear-left">',
|
384
|
+
rules
|
385
|
+
),
|
386
|
+
'<br class="wysiwyg-clear-left">'
|
387
|
+
);
|
388
|
+
|
389
|
+
this.equal(
|
390
|
+
this.sanitize(
|
391
|
+
'<br clear="left" class="wysiwyg-clear-left">',
|
392
|
+
rules
|
393
|
+
),
|
394
|
+
'<br class="wysiwyg-clear-left">'
|
395
|
+
);
|
396
|
+
|
397
|
+
this.equal(
|
398
|
+
this.sanitize(
|
399
|
+
'<br clear="left" class="wysiwyg-clear-left wysiwyg-clear-right">',
|
400
|
+
rules
|
401
|
+
),
|
402
|
+
'<br class="wysiwyg-clear-left wysiwyg-clear-right">'
|
403
|
+
);
|
404
|
+
|
405
|
+
this.equal(
|
406
|
+
this.sanitize(
|
407
|
+
'<br clear="left" class="wysiwyg-clear-right">',
|
408
|
+
rules
|
409
|
+
),
|
410
|
+
'<br class="wysiwyg-clear-left wysiwyg-clear-right">'
|
411
|
+
);
|
412
|
+
});
|
413
|
+
|
414
|
+
|
415
|
+
test("Advanced tests for 'font' elements", function() {
|
416
|
+
var rules = {
|
417
|
+
classes: {
|
418
|
+
"wysiwyg-font-size-xx-small": 1,
|
419
|
+
"wysiwyg-font-size-small": 1,
|
420
|
+
"wysiwyg-font-size-medium": 1,
|
421
|
+
"wysiwyg-font-size-large": 1,
|
422
|
+
"wysiwyg-font-size-x-large": 1,
|
423
|
+
"wysiwyg-font-size-xx-large": 1,
|
424
|
+
"wysiwyg-font-size-smaller": 1,
|
425
|
+
"wysiwyg-font-size-larger": 1
|
426
|
+
},
|
427
|
+
tags: {
|
428
|
+
font: {
|
429
|
+
add_class: { size: "size_font" },
|
430
|
+
rename_tag: "span"
|
431
|
+
}
|
432
|
+
}
|
433
|
+
};
|
434
|
+
|
435
|
+
this.equal(
|
436
|
+
this.sanitize(
|
437
|
+
'<font size="1">foo</font>',
|
438
|
+
rules
|
439
|
+
),
|
440
|
+
'<span class="wysiwyg-font-size-xx-small">foo</span>'
|
441
|
+
);
|
442
|
+
|
443
|
+
this.equal(
|
444
|
+
this.sanitize(
|
445
|
+
'<font size="2">foo</font>',
|
446
|
+
rules
|
447
|
+
),
|
448
|
+
'<span class="wysiwyg-font-size-small">foo</span>'
|
449
|
+
);
|
450
|
+
|
451
|
+
this.equal(
|
452
|
+
this.sanitize(
|
453
|
+
'<font size="3">foo</font>',
|
454
|
+
rules
|
455
|
+
),
|
456
|
+
'<span class="wysiwyg-font-size-medium">foo</span>'
|
457
|
+
);
|
458
|
+
|
459
|
+
this.equal(
|
460
|
+
this.sanitize(
|
461
|
+
'<font size="4">foo</font>',
|
462
|
+
rules
|
463
|
+
),
|
464
|
+
'<span class="wysiwyg-font-size-large">foo</span>'
|
465
|
+
);
|
466
|
+
|
467
|
+
this.equal(
|
468
|
+
this.sanitize(
|
469
|
+
'<font size="5">foo</font>',
|
470
|
+
rules
|
471
|
+
),
|
472
|
+
'<span class="wysiwyg-font-size-x-large">foo</span>'
|
473
|
+
);
|
474
|
+
|
475
|
+
this.equal(
|
476
|
+
this.sanitize(
|
477
|
+
'<font size="6">foo</font>',
|
478
|
+
rules
|
479
|
+
),
|
480
|
+
'<span class="wysiwyg-font-size-xx-large">foo</span>'
|
481
|
+
);
|
482
|
+
|
483
|
+
this.equal(
|
484
|
+
this.sanitize(
|
485
|
+
'<font size="7">foo</font>',
|
486
|
+
rules
|
487
|
+
),
|
488
|
+
'<span class="wysiwyg-font-size-xx-large">foo</span>'
|
489
|
+
);
|
490
|
+
|
491
|
+
this.equal(
|
492
|
+
this.sanitize(
|
493
|
+
'<font size="+1">foo</font>',
|
494
|
+
rules
|
495
|
+
),
|
496
|
+
'<span class="wysiwyg-font-size-larger">foo</span>'
|
497
|
+
);
|
498
|
+
|
499
|
+
this.equal(
|
500
|
+
this.sanitize(
|
501
|
+
'<font size="-1">foo</font>',
|
502
|
+
rules
|
503
|
+
),
|
504
|
+
'<span class="wysiwyg-font-size-smaller">foo</span>'
|
505
|
+
);
|
506
|
+
});
|
507
|
+
|
508
|
+
|
509
|
+
test("Check whether namespaces are handled correctly", function() {
|
510
|
+
var rules = {
|
511
|
+
tags: {
|
512
|
+
p: true
|
513
|
+
}
|
514
|
+
};
|
515
|
+
|
516
|
+
this.equal(
|
517
|
+
this.sanitize("<o:p>foo</o:p>", rules),
|
518
|
+
"<span>foo</span>",
|
519
|
+
"Unknown tag with namespace gets renamed to span"
|
520
|
+
);
|
521
|
+
});
|
522
|
+
|
523
|
+
|
524
|
+
test("Check whether classes are correctly treated", function() {
|
525
|
+
var rules = {
|
526
|
+
classes: {
|
527
|
+
a: 1,
|
528
|
+
c: 1
|
529
|
+
},
|
530
|
+
tags: {
|
531
|
+
footer: "div"
|
532
|
+
}
|
533
|
+
};
|
534
|
+
|
535
|
+
this.equal(
|
536
|
+
this.sanitize('<header class="a b c">foo</header>', rules),
|
537
|
+
'<span class="a c">foo</span>',
|
538
|
+
"Allowed classes 'a' and 'c' are correctly kept and unknown class 'b' is correctly removed."
|
539
|
+
);
|
540
|
+
|
541
|
+
this.equal(
|
542
|
+
this.sanitize('<footer class="ab c d" class="a">foo</footer>', rules),
|
543
|
+
'<div class="c">foo</div>',
|
544
|
+
"Allowed classes 'c' is correctly kept and unknown class 'b' is correctly removed."
|
545
|
+
);
|
546
|
+
});
|
547
|
+
|
548
|
+
test("Check mailto links", function() {
|
549
|
+
var rules = {
|
550
|
+
tags: {
|
551
|
+
a: {
|
552
|
+
check_attributes: {
|
553
|
+
href: "href"
|
554
|
+
}
|
555
|
+
}
|
556
|
+
}
|
557
|
+
};
|
558
|
+
|
559
|
+
|
560
|
+
this.equal(
|
561
|
+
this.sanitize('<a href="mailto:foo@bar.com">foo</a>', rules),
|
562
|
+
'<a href="mailto:foo@bar.com">foo</a>',
|
563
|
+
"'mailto:' urls are not stripped"
|
564
|
+
);
|
565
|
+
});
|
566
|
+
|
567
|
+
test("Check custom data attributes", function() {
|
568
|
+
var rules = {
|
569
|
+
tags: {
|
570
|
+
span: {
|
571
|
+
check_attributes: {
|
572
|
+
"data-max-width": "numbers"
|
573
|
+
}
|
574
|
+
}
|
575
|
+
}
|
576
|
+
};
|
577
|
+
|
578
|
+
|
579
|
+
this.equal(
|
580
|
+
this.sanitize('<span data-max-width="24px" data-min-width="25">foo</span>', rules),
|
581
|
+
'<span data-max-width="24">foo</span>',
|
582
|
+
"custom data attributes are not stripped"
|
583
|
+
);
|
584
|
+
});
|
585
|
+
|
586
|
+
test("Check Firefox misbehavior with tilde characters in urls", function() {
|
587
|
+
var rules = {
|
588
|
+
tags: {
|
589
|
+
a: {
|
590
|
+
set_attributes: {
|
591
|
+
target: "_blank",
|
592
|
+
rel: "nofollow"
|
593
|
+
},
|
594
|
+
check_attributes: {
|
595
|
+
href: "url"
|
596
|
+
}
|
597
|
+
}
|
598
|
+
}
|
599
|
+
};
|
600
|
+
|
601
|
+
// See https://bugzilla.mozilla.org/show_bug.cgi?id=664398
|
602
|
+
//
|
603
|
+
// In Firefox this:
|
604
|
+
// var d = document.createElement("div");
|
605
|
+
// d.innerHTML ='<a href="~"></a>';
|
606
|
+
// d.innerHTML;
|
607
|
+
// will result in:
|
608
|
+
// <a href="%7E"></a>
|
609
|
+
// which is wrong
|
610
|
+
ok(
|
611
|
+
this.sanitize('<a href="http://google.com/~foo"></a>', rules).indexOf("~") !== -1
|
612
|
+
);
|
613
|
+
});
|
614
|
+
}
|