| 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 |