wysihtml5_with_ps 0.0.1
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/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
|
+
}
|