Microdata: itemType[index] must be undefined for out-of-range index.
[WebKit.git] / LayoutTests / fast / dom / HTMLElement / script-tests / class-list.js
1 description('Tests the classList attribute and its properties.');
2
3 var element;
4
5 function createElement(className)
6 {
7     element = document.createElement('p');
8     element.className = className;
9 }
10
11 debug('Tests from http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/');
12
13 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/setting/001.htm
14 // Firefox throws here but WebKit does not throw on setting readonly idl
15 // attributes.
16 createElement('x');
17 try {
18     element.classList = 'y';
19     shouldBeEqualToString('String(element.classList)', 'x');
20 } catch (ex) {
21     testPassed('Throwing on set is acceptable');
22 }
23
24 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/001.htm
25 createElement('');
26 shouldEvaluateTo('element.classList.length', 0);
27
28 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/002.htm
29 createElement('x');
30 shouldEvaluateTo('element.classList.length', 1);
31
32 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/003.htm
33 createElement('x x');
34 shouldEvaluateTo('element.classList.length', 2);
35
36 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/004.htm
37 createElement('x y');
38 shouldEvaluateTo('element.classList.length', 2);
39
40 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/005.htm
41 createElement('');
42 element.classList.add('x');
43 shouldBeEqualToString('element.className', 'x');
44
45 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/006.htm
46 createElement('x');
47 element.classList.add('x');
48 shouldBeEqualToString('element.className', 'x');
49
50 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/007.htm
51 createElement('x  x');
52 element.classList.add('x');
53 shouldBeEqualToString('element.className', 'x  x');
54
55 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/008.htm
56 createElement('y');
57 element.classList.add('x');
58 shouldBeEqualToString('element.className', 'y x');
59
60 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/009.htm
61 createElement('');
62 element.classList.remove('x');
63 shouldBeEqualToString('element.className', '');
64
65 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/010.htm
66 createElement('x');
67 element.classList.remove('x');
68 shouldBeEqualToString('element.className', '');
69
70 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/011.htm
71 createElement(' y x  y ');
72 element.classList.remove('x');
73 shouldBeEqualToString('element.className', ' y y ');
74
75 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/012.htm
76 createElement(' x y  x ');
77 element.classList.remove('x');
78 shouldBeEqualToString('element.className', 'y');
79
80
81 debug('Ensure that we can handle empty class name correctly');
82 element = document.createElement('span');
83 element.classList.toggle('x');
84 shouldBeEqualToString('element.className', 'x');
85 element.classList.toggle('x');
86 shouldBeEqualToString('element.className', '');
87
88 element = document.createElement('span');
89 shouldBeFalse('element.classList.contains(\'x\')');
90 shouldBeUndefined('element.classList[1]');
91 element.classList.remove('x');
92 element.classList.add('x')
93
94
95 debug('Testing add in presence of trailing white spaces.');
96
97 createElement('x ');
98 element.classList.add('y');
99 shouldBeEqualToString('element.className', 'x y');
100
101 createElement('x\t');
102 element.classList.add('y');
103 shouldBeEqualToString('element.className', 'x\t y');
104
105 createElement(' ');
106 element.classList.add('y');
107 shouldBeEqualToString('element.className', ' y');
108
109
110 debug('Test invalid tokens');
111
112 // Testing exception due to invalid token
113
114 // shouldThrow from js-test-pre.js is not sufficient.
115 function shouldThrowDOMException(f, ec)
116 {
117     try {
118         f();
119         testFailed('Expected an exception');
120     } catch (ex) {
121         if (!(ex instanceof DOMException)) {
122             testFailed('Exception is not an instance of DOMException, found: ' +
123                        Object.toString.call(ex));
124             return;
125         }
126         if (ec !== ex.code) {
127             testFailed('Wrong exception code: ' + ex.code);
128             return;
129         }
130     }
131     var formattedFunction = String(f).replace(/^function.+\{\s*/m, '').
132         replace(/;?\s+\}/m, '');
133     testPassed(formattedFunction + ' threw expected DOMException with code ' + ec);
134 }
135
136 createElement('x');
137 shouldThrowDOMException(function() {
138     element.classList.contains('');
139 }, DOMException.SYNTAX_ERR);
140
141 createElement('x y');
142 shouldThrowDOMException(function() {
143     element.classList.contains('x y');
144 }, DOMException.INVALID_CHARACTER_ERR);
145
146 createElement('');
147 shouldThrowDOMException(function() {
148     element.classList.add('');
149 }, DOMException.SYNTAX_ERR);
150
151 createElement('');
152 shouldThrowDOMException(function() {
153     element.classList.add('x y');
154 }, DOMException.INVALID_CHARACTER_ERR);
155
156 createElement('');
157 shouldThrow("element.classList.add()");
158
159 createElement('');
160 shouldThrowDOMException(function() {
161     element.classList.remove('');
162 }, DOMException.SYNTAX_ERR);
163
164 createElement('');
165 shouldThrowDOMException(function() {
166     element.classList.remove('x y');
167 }, DOMException.INVALID_CHARACTER_ERR);
168
169 createElement('');
170 shouldThrow("element.classList.remove()");
171
172 createElement('');
173 shouldThrowDOMException(function() {
174     element.classList.toggle('');
175 }, DOMException.SYNTAX_ERR);
176
177 createElement('x y');
178 shouldThrowDOMException(function() {
179     element.classList.toggle('x y');
180 }, DOMException.INVALID_CHARACTER_ERR);
181
182 createElement('');
183 shouldThrow("element.classList.toggle()");
184
185 debug('Indexing');
186
187 createElement('x');
188 shouldBeEqualToString('element.classList[0]', 'x');
189 shouldBeEqualToString('element.classList.item(0)', 'x');
190
191 createElement('x x');
192 shouldBeEqualToString('element.classList[1]', 'x');
193 shouldBeEqualToString('element.classList.item(1)', 'x');
194
195 createElement('x y');
196 shouldBeEqualToString('element.classList[1]', 'y');
197 shouldBeEqualToString('element.classList.item(1)', 'y');
198
199 createElement('');
200 shouldBeUndefined('element.classList[0]');
201 shouldBeNull('element.classList.item(0)');
202
203 createElement('x y z');
204 shouldBeUndefined('element.classList[4]');
205 shouldBeNull('element.classList.item(4)');
206 shouldBeUndefined('element.classList[-1]');  // Not a valid index so should not trigger item().
207 shouldBeNull('element.classList.item(-1)');
208 shouldThrow('element.classList.item()');
209
210 debug('Test case since DOMTokenList is case sensitive');
211
212 createElement('x');
213 shouldBeTrue('element.classList.contains(\'x\')');
214 shouldBeFalse('element.classList.contains(\'X\')');
215 shouldBeEqualToString('element.classList[0]', 'x');
216 shouldThrow('element.classList.contains()');
217
218 createElement('X');
219 shouldBeTrue('element.classList.contains(\'X\')');
220 shouldBeFalse('element.classList.contains(\'x\')');
221 shouldBeEqualToString('element.classList[0]', 'X');
222
223
224 debug('Testing whitespace');
225 // U+0020 SPACE, U+0009 CHARACTER TABULATION (tab), U+000A LINE FEED (LF),
226 // U+000C FORM FEED (FF), and U+000D CARRIAGE RETURN (CR)
227
228 createElement('x\u0020y');
229 shouldEvaluateTo('element.classList.length', 2);
230
231 createElement('x\u0009y');
232 shouldEvaluateTo('element.classList.length', 2);
233
234 createElement('x\u000Ay');
235 shouldEvaluateTo('element.classList.length', 2);
236
237 createElement('x\u000Cy');
238 shouldEvaluateTo('element.classList.length', 2);
239
240 createElement('x\u000Dy');
241 shouldEvaluateTo('element.classList.length', 2);
242
243
244 debug('DOMTokenList presence and type');
245
246
247 // Safari returns object
248 // Firefox returns object
249 // IE8 returns object
250 // Chrome returns function
251 // assertEquals('object', typeof DOMTokenList);
252 shouldBeTrue('\'undefined\' != typeof DOMTokenList');
253
254 shouldBeEqualToString('typeof DOMTokenList.prototype', 'object');
255
256 createElement('x');
257 shouldBeEqualToString('typeof element.classList', 'object');
258
259 shouldEvaluateTo('element.classList.constructor', 'DOMTokenList');
260
261 shouldBeTrue('element.classList === element.classList');