Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: qunit/tests/cssEscaping.js

Issue 5989801094283264: Issue 1587 - Escape curly brackets for elemhide filters (Closed)
Left Patch Set: Created Nov. 20, 2014, 2:03 p.m.
Right Patch Set: Call require() in IFEE instead in the setup hook Created Nov. 20, 2014, 3:47 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « include.postload.js ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 module( 1 (function()
2 "CSS escaping", 2 {
3 var filterClasses = require("filterClasses");
4 var Filter = filterClasses.Filter;
5 var ElemHideFilter = filterClasses.ElemHideFilter;
6
7 module(
8 "CSS escaping",
9 {
10 setup: function()
11 {
12 var frame = document.createElement("iframe");
13 frame.srcdoc = '<script src="../include.postload.js"></script>';
14
15 stop();
16 frame.addEventListener("load", function()
17 {
18 start();
19
20 this.escapeCSS = frame.contentWindow.escapeCSS;
21 this.quote = frame.contentWindow.quote;
22
23 document.body.removeChild(frame);
24 }.bind(this));
25
26 document.body.appendChild(frame);
27 }
28 }
29 );
30
31 test("CSS escaping", function()
3 { 32 {
4 setup: function() 33 var escapeCSS = this.escapeCSS;
34 var quote = this.quote;
35
36 function testSelector(opts)
5 { 37 {
6 var frame = document.createElement("iframe"); 38 var mustMatch = opts.mustMatch !== false;
7 frame.srcdoc = '<script src="../include.postload.js"></script>'; 39 var doc = document.implementation.createHTMLDocument();
8 40
9 stop(); 41 var style = doc.createElement("style");
10 frame.addEventListener("load", function() 42 doc.documentElement.appendChild(style);
43 style.sheet.insertRule(opts.selector + " {}", 0);
44
45 var element;
46 try
11 { 47 {
12 start(); 48 element = doc.createElement(opts.tagName || "div");
49 }
50 catch (e)
51 {
52 // Some characters we are going to test can not occur in tag names,
53 // but we still have to make sure that no exception is thrown when
54 // calling .querySelector() and .insertRule()
55 element = null;
56 mustMatch = false;
57 }
13 58
14 this.escapeCSS = frame.contentWindow.escapeCSS; 59 if (element)
15 this.quote = frame.contentWindow.quote; 60 {
61 for (var attr in opts.attributes)
62 element.setAttribute(attr, opts.attributes[attr]);
16 63
17 document.body.removeChild(frame); 64 doc.documentElement.appendChild(element);
18 }.bind(this)); 65 }
19 66
20 document.body.appendChild(frame); 67 var foundElement = doc.querySelector(opts.selector);
68 var filter = Filter.fromText("##" + opts.selector);
21 69
22 this.filterClasses = require("filterClasses"); 70 if (!(filter instanceof ElemHideFilter))
Wladimir Palant 2014/11/20 14:33:05 As with the other review, no point having this in
Sebastian Noack 2014/11/20 15:47:27 Done, using an IFEE.
23 } 71 {
24 } 72 ok(false, opts.selector + " (not allowed in elemhide filters)");
25 ); 73 }
26 74 else
27 test("CSS escaping", function() 75 {
28 { 76 if (mustMatch)
29 var escapeCSS = this.escapeCSS; 77 equal(foundElement, element, opts.selector);
30 var quote = this.quote; 78 else
31 79 ok(true, opts.selector);
32 var Filter = this.filterClasses.Filter; 80 }
33 var ElemHideFilter = this.filterClasses.ElemHideFilter;
34
35 function testSelector(opts)
36 {
37 var mustMatch = opts.mustMatch !== false;
38 var doc = document.implementation.createHTMLDocument();
39
40 var style = doc.createElement("style");
41 doc.documentElement.appendChild(style);
42 style.sheet.insertRule(opts.selector + " {}", 0);
43
44 var element;
45 try
46 {
47 element = doc.createElement(opts.tagName || "div");
48 }
49 catch (e)
50 {
51 // Some characters we are going to test can not occur in tag names,
52 // but we still have to make sure that no exception is thrown when
53 // calling .querySelector() and .insertRule()
54 element = null;
55 mustMatch = false;
56 } 81 }
57 82
58 if (element) 83 function testEscape(s)
59 { 84 {
60 for (var attr in opts.attributes) 85 testSelector({
61 element.setAttribute(attr, opts.attributes[attr]); 86 selector: escapeCSS(s),
87 tagName: s
88 });
62 89
63 doc.documentElement.appendChild(element); 90 testSelector({
91 selector: "#" + escapeCSS(s),
92 attributes: {id: s}
93 });
94
95 testSelector({
96 selector: "." + escapeCSS(s),
97 attributes: {class: s},
98
99 // Whitespace characters split the class name, hence the selector
100 // won't match. But we still have to make sure that no exception
101 // is thrown when calling .querySelector() and .insertRule()
102 mustMatch: !/\s/.test(s)
103 });
104
105 testSelector({
106 selector: "[foo=" + quote(s) + "]",
107 attributes: {foo: s}
108 });
64 } 109 }
65 110
66 var foundElement = doc.querySelector(opts.selector); 111 for (var i = 0; i < 0x80; i++)
67 var filter = Filter.fromText("##" + opts.selector); 112 {
113 var chr = String.fromCharCode(i);
68 114
69 if (!(filter instanceof ElemHideFilter)) 115 // Make sure that all ASCII characters are correctly escaped.
70 { 116 testEscape(chr);
71 ok(false, opts.selector + " (not allowed in elemhide filters)"); 117
Wladimir Palant 2014/11/20 14:33:05 There are very few cases where code like this is j
Sebastian Noack 2014/11/20 15:47:27 So far testSelector() only generates one assert pe
Wladimir Palant 2014/11/20 17:01:20 Not sure I agree but not really that important...
118 // Some characters are only escaped when in the first positon,
119 // so we still have to make sure that everything is correctly escaped
120 // in subsequent positions.
121 testEscape("x" + chr);
122
123 // Leading dashes must be escaped, when followed by certain characters.
124 testEscape("-" + chr);
72 } 125 }
73 else
74 {
75 if (mustMatch)
76 equal(foundElement, element, opts.selector);
77 else
78 ok(true, opts.selector);
79 }
80 }
81 126
82 function testEscape(s) 127 // Test some non-ASCII characters. However, those shouldn't require escaping .
83 { 128 testEscape("\uD83D\uDE3B\u2665\u00E4");
84 testSelector({ 129 });
85 selector: escapeCSS(s), 130 })();
86 tagName: s
87 });
88
89 testSelector({
90 selector: "#" + escapeCSS(s),
91 attributes: {id: s}
92 });
93
94 testSelector({
95 selector: "." + escapeCSS(s),
96 attributes: {class: s},
97
98 // Whitespace characters split the class name, hence the selector
99 // won't match. But we still have to make sure that no exception
100 // is thrown when calling .querySelector() and .insertRule()
101 mustMatch: !/\s/.test(s)
102 });
103
104 testSelector({
105 selector: "[foo=" + quote(s) + "]",
106 attributes: {foo: s}
107 });
108 }
109
110 for (var i = 0; i < 0x80; i++)
111 {
112 var chr = String.fromCharCode(i);
113
114 // Make sure that all ASCII characters are correctly escaped.
115 testEscape(chr);
116
117 // Some characters are only escaped when in the first positon,
118 // so we still have to make sure that everything is correctly escaped
119 // in subsequent positions.
120 testEscape("x" + chr);
121
122 // Leading dashes must be escaped, when followed by certain characters.
123 testEscape("-" + chr);
124 }
125
126 // Test some non-ASCII characters. However, those shouldn't require escaping.
127 testEscape("\uD83D\uDE3B\u2665\u00E4");
128 });
LEFTRIGHT

Powered by Google App Engine
This is Rietveld