OLD | NEW |
| (Empty) |
1 description("This tests element.dataset."); | |
2 | |
3 function testGet(attr, expected) | |
4 { | |
5 var d = document.createElement("div"); | |
6 d.setAttribute(attr, "value"); | |
7 return d.dataset[expected] == "value"; | |
8 } | |
9 | |
10 shouldBeTrue("testGet('data-foo', 'foo')"); | |
11 shouldBeTrue("testGet('data-foo-bar', 'fooBar')"); | |
12 shouldBeTrue("testGet('data--', '-')"); | |
13 shouldBeTrue("testGet('data--foo', 'Foo')"); | |
14 shouldBeTrue("testGet('data---foo', '-Foo')"); | |
15 shouldBeTrue("testGet('data---foo--bar', '-Foo-Bar')"); | |
16 shouldBeTrue("testGet('data---foo---bar', '-Foo--Bar')"); | |
17 shouldBeTrue("testGet('data-foo-', 'foo-')"); | |
18 shouldBeTrue("testGet('data-foo--', 'foo--')"); | |
19 shouldBeTrue("testGet('data-Foo', 'foo')"); // HTML lowercases all attributes. | |
20 shouldBeTrue("testGet('data-', '')"); | |
21 shouldBeTrue("testGet('data-\xE0', '\xE0')"); | |
22 shouldBeTrue("testGet('data-1', '1')"); | |
23 shouldBeTrue("testGet('data-01', '01')"); | |
24 shouldBeTrue("testGet('data-zx81', 'zx81')"); | |
25 shouldBeTrue("testGet('data-i4770k', 'i4770k')"); | |
26 shouldBeTrue("testGet('data-r-7', 'r-7')"); | |
27 shouldBeTrue("testGet('data-r-7-k', 'r-7K')"); | |
28 shouldBeUndefined("document.body.dataset.nonExisting"); | |
29 debug(""); | |
30 | |
31 function testIsUndefined(attr, prop) | |
32 { | |
33 var d = document.createElement("div"); | |
34 d.setAttribute(attr, "value"); | |
35 return d.dataset[prop] === undefined; | |
36 } | |
37 | |
38 shouldBeTrue("testIsUndefined('data-022', '22')"); | |
39 shouldBeTrue("testIsUndefined('data-22', '022')"); | |
40 | |
41 debug(""); | |
42 | |
43 function matchesNothingInDataset(attr) | |
44 { | |
45 var d = document.createElement("div"); | |
46 d.setAttribute(attr, "value"); | |
47 | |
48 var count = 0; | |
49 for (var item in d.dataset) | |
50 count++; | |
51 return count == 0; | |
52 } | |
53 | |
54 shouldBeTrue("matchesNothingInDataset('dataFoo')"); | |
55 debug(""); | |
56 | |
57 function testSet(prop, expected) | |
58 { | |
59 var d = document.createElement("div"); | |
60 d.dataset[prop] = "value"; | |
61 return d.getAttribute(expected) == "value"; | |
62 } | |
63 | |
64 shouldBeTrue("testSet('foo', 'data-foo')"); | |
65 shouldBeTrue("testSet('fooBar', 'data-foo-bar')"); | |
66 shouldBeTrue("testSet('-', 'data--')"); | |
67 shouldBeTrue("testSet('Foo', 'data--foo')"); | |
68 shouldBeTrue("testSet('-Foo', 'data---foo')"); | |
69 shouldBeTrue("testSet('', 'data-')"); | |
70 shouldBeTrue("testSet('\xE0', 'data-\xE0')"); | |
71 shouldBeTrue("testSet('32', 'data-32')"); | |
72 shouldBeTrue("testSet('0032', 'data-0032')"); | |
73 shouldBeTrue("testSet('i18n', 'data-i18n')"); | |
74 shouldBeTrue("testSet('d2', 'data-d2')"); | |
75 shouldBeTrue("testSet('2d', 'data-2d')"); | |
76 shouldBeTrue("testSet('d-2', 'data-d-2')"); | |
77 shouldBeTrue("testSet('A--S', 'data--a---s')"); | |
78 debug(""); | |
79 | |
80 function testIsNull(prop, attr) | |
81 { | |
82 var d = document.createElement("div"); | |
83 d.dataset[prop] = "value"; | |
84 return d.getAttribute(attr) === null; | |
85 } | |
86 | |
87 shouldBeTrue("testIsNull('0123', 'data-123')"); | |
88 shouldBeTrue("testIsNull('123', 'data-0123')"); | |
89 debug(""); | |
90 | |
91 shouldThrow("testSet('-foo', 'dummy')", '"SyntaxError: Failed to set the \'-foo\
' property on \'DOMStringMap\': \'-foo\' is not a valid property name."'); | |
92 shouldThrow("testSet('foo\x20', 'dummy')", '"InvalidCharacterError: Failed to se
t the \'foo\x20\' property on \'DOMStringMap\': \'data-foo\x20\' is not a valid
attribute name."'); | |
93 shouldThrow("testSet('foo\uF900', 'dummy')", '"InvalidCharacterError: Failed to
set the \'foo\uF900\' property on \'DOMStringMap\': \'data-foo\uF900\' is not a
valid attribute name."'); | |
94 debug(""); | |
95 | |
96 function testDelete(attr, prop) | |
97 { | |
98 var d = document.createElement("div"); | |
99 d.setAttribute(attr, "value"); | |
100 delete d.dataset[prop]; | |
101 return d.getAttribute(attr) != "value"; | |
102 } | |
103 | |
104 shouldBeTrue("testDelete('data-foo', 'foo')"); | |
105 shouldBeTrue("testDelete('data-foo-bar', 'fooBar')"); | |
106 shouldBeTrue("testDelete('data--', '-')"); | |
107 shouldBeTrue("testDelete('data--foo', 'Foo')"); | |
108 shouldBeTrue("testDelete('data---foo', '-Foo')"); | |
109 shouldBeTrue("testDelete('data-', '')"); | |
110 shouldBeTrue("testDelete('data-\xE0', '\xE0')"); | |
111 shouldBeTrue("testDelete('data-33', '33')"); | |
112 shouldBeTrue("testDelete('data-00033', '00033')"); | |
113 shouldBeTrue("testDelete('data-r2', 'r2')"); | |
114 shouldBeTrue("testDelete('data-2r', '2r')"); | |
115 shouldBeTrue("testDelete('data-r-2', 'r-2')"); | |
116 shouldBeTrue("testDelete('data--r-2-', 'R-2-')"); | |
117 shouldBeTrue("testDelete('data--r-2r', 'R-2r')"); | |
118 shouldBeTrue("testDelete('data--r-2-----r', 'R-2----R')"); | |
119 | |
120 // The element.dataset deleter is only applied to properties | |
121 // that are present; check that any underlying native property | |
122 // is deleted instead. | |
123 function testNativeDelete(prop, isConfigurable) | |
124 { | |
125 var d = document.createElement("div"); | |
126 Object.defineProperty(d.dataset, prop, {configurable: isConfigurable, value:
"native_value"}); | |
127 delete d.dataset[prop]; | |
128 return isConfigurable ? !(prop in d.dataset) : (d.dataset[prop] === "native_
value"); | |
129 } | |
130 | |
131 // TODO(jochen): Reenable this once it behaves correctly | |
132 //shouldBeTrue("testNativeDelete('-r-2-', false)"); | |
133 shouldBeTrue("testNativeDelete('foo', true)"); | |
134 | |
135 debug(""); | |
136 | |
137 shouldBeFalse("testDelete('dummy', '-foo')"); | |
138 debug(""); | |
139 | |
140 function testForIn(array) | |
141 { | |
142 var d = document.createElement("div"); | |
143 for (var i = 0; i < array.length; ++i) { | |
144 d.setAttribute(array[i], "value"); | |
145 } | |
146 | |
147 var count = 0; | |
148 for (var item in d.dataset) | |
149 count++; | |
150 | |
151 return count; | |
152 } | |
153 | |
154 shouldBe("testForIn(['data-foo', 'data-bar', 'data-baz'])", "3"); | |
155 shouldBe("testForIn(['data-foo', 'data-bar', 'dataFoo'])", "2"); | |
156 shouldBe("testForIn(['data-foo', 'data-bar', 'style'])", "2"); | |
157 shouldBe("testForIn(['data-foo', 'data-bar', 'data-'])", "3"); | |
158 shouldBe("testForIn(['data-foo', 'data-bar', 'data-43'])", "3"); | |
159 shouldBe("testForIn(['data-foo', 'data-oric1', 'data-bar'])", "3"); | |
160 shouldBe("testForIn(['data-foo', 'data-oric-1', 'data-bar'])", "3"); | |
161 shouldBe("testForIn(['data-foo', 'data-oric-1x', 'data-bar'])", "3"); | |
162 | |
163 | |
164 debug(""); | |
165 debug("Property override:"); | |
166 var div = document.createElement("div"); | |
167 // If the Object prototype already has "foo", dataset doesn't create the | |
168 // corresponding attribute for "foo". | |
169 shouldBe("Object.prototype.foo = 'on Object'; div.dataset.foo", "'on Object'"); | |
170 shouldBe("div.dataset['foo'] = 'on dataset'; div.dataset.foo", "'on dataset'"); | |
171 shouldBeTrue("div.hasAttribute('data-foo')"); | |
172 shouldBe("div.setAttribute('data-foo', 'attr'); div.dataset.foo", "'attr'"); | |
173 debug("Update the JavaScript property:"); | |
174 shouldBe("div.dataset.foo = 'updated'; div.dataset.foo", "'updated'"); | |
175 shouldBe("div.getAttribute('data-foo')", "'updated'"); | |
176 // "Bar" can't be represented as a data- attribute. | |
177 shouldBe("div.dataset.Bar = 'on dataset'; div.dataset.Bar", "'on dataset'"); | |
178 shouldBeFalse("div.hasAttribute('data-Bar')"); | |
179 debug("Make the JavaScript property empty:"); | |
180 shouldBe("div.dataset.foo = ''; div.dataset.foo", "''"); | |
181 shouldBe("div.getAttribute('data-foo')", "''"); | |
182 debug("Remove the attribute:"); | |
183 shouldBe("div.removeAttribute('data-foo'); div.dataset.foo", "'on Object'"); | |
184 debug("Remove the JavaScript property:"); | |
185 shouldBe("div.setAttribute('data-foo', 'attr'); delete div.dataset.foo; div.data
set.foo", "'on Object'"); | |
186 shouldBeFalse("div.hasAttribute('foo')"); | |
187 shouldBeUndefined("delete div.dataset.Bar; div.dataset.Bar"); | |
188 | |
189 shouldBe("Object.prototype[11] = 'on Object'; div.dataset[11]", "'on Object'"); | |
190 shouldBe("div.dataset['11'] = 'on dataset'; div.dataset[11]", "'on dataset'"); | |
191 shouldBeTrue("div.hasAttribute('data-11')"); | |
192 shouldBe("div.setAttribute('data-11', 'attr'); div.dataset[11]", "'attr'"); | |
193 debug("Update the JavaScript property:"); | |
194 shouldBe("div.dataset[11] = 'updated'; div.dataset[11]", "'updated'"); | |
195 shouldBe("div.getAttribute('data-11')", "'updated'"); | |
196 | |
197 shouldBe("Object.prototype['a500'] = 'on Object'; div.dataset['a500']", "'on Obj
ect'"); | |
198 shouldBe("div.dataset['a500'] = 'on dataset'; div.dataset['a500']", "'on dataset
'"); | |
199 shouldBeTrue("div.hasAttribute('data-a500')"); | |
200 shouldBe("div.setAttribute('data-a500', 'attr'); div.dataset['a500']", "'attr'")
; | |
201 debug("Update the JavaScript property:"); | |
202 shouldBe("div.dataset['a500'] = 'updated'; div.dataset['a500']", "'updated'"); | |
203 shouldBe("div.getAttribute('data-a500')", "'updated'"); | |
204 | |
205 shouldBe("Object.prototype['a-500k'] = 'on Object'; div.dataset['a-500k']", "'on
Object'"); | |
206 shouldBe("div.dataset['a-500k'] = 'on dataset'; div.dataset['a-500k']", "'on dat
aset'"); | |
207 shouldBeTrue("div.hasAttribute('data-a-500k')"); | |
208 shouldBe("div.setAttribute('data-a-500k', 'attr'); div.dataset['a-500k']", "'att
r'"); | |
209 debug("Update the JavaScript property:"); | |
210 shouldBe("div.dataset['a-500k'] = 'updated'; div.dataset['a-500k']", "'updated'"
); | |
211 shouldBe("div.getAttribute('data-a-500k')", "'updated'"); | |
212 | |
213 debug(""); | |
214 debug("Set null:"); | |
215 | |
216 var d = document.createElement("div"); | |
217 d.dataset.foo = null; | |
218 shouldBe("d.dataset.foo", "'null'"); | |
219 | |
220 debug(""); | |
OLD | NEW |