MutationObserver-attributes.html (18415B)
1 <!DOCTYPE HTML> 2 <meta charset=utf-8> 3 <title>MutationObservers: attributes mutations</title> 4 <script src="/resources/testharness.js"></script> 5 <script src="/resources/testharnessreport.js"></script> 6 <script src="mutationobservers.js"></script> 7 <h1>MutationObservers: attributes mutations</h1> 8 <div id="log"></div> 9 10 <section style="display: none"> 11 <p id='n'></p> 12 13 <p id='n00'></p> 14 <p id='n01'></p> 15 <p id='n02'></p> 16 <p id='n03'></p> 17 <input id="n04" type="text"> 18 19 <p id='n10'></p> 20 <p id='n11'></p> 21 <p id='n12' class='c01'></p> 22 <p id='n13' class='c01 c02'></p> 23 24 <p id='n20'></p> 25 <p id='n21'></p> 26 <p id='n22'></p> 27 <p id='n23'></p> 28 <p id='n24' class="c01 c02"></p> 29 30 <p id='n30' class="c01 c02"></p> 31 <p id='n31' class="c01 c02"></p> 32 <p id='n32' class="c01 c02"></p> 33 34 <p id='n40' class="c01 c02"></p> 35 <p id='n41' class="c01 c02"></p> 36 <p id='n42' class="c01 c02"></p> 37 <p id='n43' class="c01 c02"></p> 38 <p id='n44' class="c01 c02"></p> 39 <p id='n45' class="c01 c02"></p> 40 41 <p id='n50' class="c01 c02"></p> 42 <p id='n51'></p> 43 44 <p id='n60'></p> 45 <p id='n61' class="c01"></p> 46 <p id='n62'></p> 47 48 <p id='n70' class="c01"></p> 49 <p id='n71'></p> 50 <input id="n72" type="text"> 51 52 <p id='n80'></p> 53 <p id='n81'></p> 54 55 <p id='n90'></p> 56 <p id='n91'></p> 57 <p id='n92'></p> 58 59 <p id='n1000'></p> 60 <p id='n1001' class='c01'></p> 61 62 <p id='n2000'></p> 63 <p id='n2001' class='c01'></p> 64 65 <p id='n3000'></p> 66 67 </section> 68 69 <script> 70 71 var n = document.getElementById('n'); 72 73 runMutationTest(n, 74 {"attributes":true}, 75 [{type: "attributes", attributeName: "id"}], 76 function() { n.id = "n000";}, 77 "attributes Element.id: update, no oldValue, mutation"); 78 79 var n00 = document.getElementById('n00'); 80 runMutationTest(n00, 81 {"attributes":true, "attributeOldValue": true}, 82 [{type: "attributes", oldValue: "n00", attributeName: "id"}], 83 function() { n00.id = "n000";}, 84 "attributes Element.id: update mutation"); 85 86 var n01 = document.getElementById('n01'); 87 runMutationTest(n01, 88 {"attributes":true, "attributeOldValue": true}, 89 [{type: "attributes", oldValue: "n01", attributeName: "id"}], 90 function() { n01.id = "";}, 91 "attributes Element.id: empty string update mutation"); 92 93 var n02 = document.getElementById('n02'); 94 runMutationTest(n02, 95 {"attributes":true, "attributeOldValue": true}, 96 [{type: "attributes", oldValue: "n02", attributeName: "id"}, {type: "attributes", attributeName: "class"}], 97 function() { n02.id = "n02"; n02.setAttribute("class", "c01");}, 98 "attributes Element.id: same value mutation"); 99 100 var n03 = document.getElementById('n03'); 101 runMutationTest(n03, 102 {"attributes":true, "attributeOldValue": true}, 103 [{type: "attributes", oldValue: "n03", attributeName: "id"}], 104 function() { n03.unknown = "c02"; n03.id = "n030";}, 105 "attributes Element.unknown: IDL attribute no mutation"); 106 107 var n04 = document.getElementById('n04'); 108 runMutationTest(n04, 109 {"attributes":true, "attributeOldValue": true}, 110 [{type: "attributes", oldValue: "text", attributeName: "type"}, {type: "attributes", oldValue: "n04", attributeName: "id"}], 111 function() { n04.type = "unknown"; n04.id = "n040";}, 112 "attributes HTMLInputElement.type: type update mutation"); 113 114 var n10 = document.getElementById('n10'); 115 runMutationTest(n10, 116 {"attributes":true, "attributeOldValue": true}, 117 [{type: "attributes", attributeName: "class"}], 118 function() { n10.className = "c01";}, 119 "attributes Element.className: new value mutation"); 120 121 var n11 = document.getElementById('n11'); 122 runMutationTest(n11, 123 {"attributes":true, "attributeOldValue": true}, 124 [{type: "attributes", attributeName: "class"}], 125 function() { n11.className = "";}, 126 "attributes Element.className: empty string update mutation"); 127 128 var n12 = document.getElementById('n12'); 129 runMutationTest(n12, 130 {"attributes":true, "attributeOldValue": true}, 131 [{type: "attributes", oldValue: "c01", attributeName: "class"}], 132 function() { n12.className = "c01";}, 133 "attributes Element.className: same value mutation"); 134 135 var n13 = document.getElementById('n13'); 136 runMutationTest(n13, 137 {"attributes":true, "attributeOldValue": true}, 138 [{type: "attributes", oldValue: "c01 c02", attributeName: "class"}], 139 function() { n13.className = "c01 c02";}, 140 "attributes Element.className: same multiple values mutation"); 141 142 var n20 = document.getElementById('n20'); 143 runMutationTest(n20, 144 {"attributes":true, "attributeOldValue": true}, 145 [{type: "attributes", attributeName: "class"}], 146 function() { n20.classList.add("c01");}, 147 "attributes Element.classList.add: single token addition mutation"); 148 149 var n21 = document.getElementById('n21'); 150 runMutationTest(n21, 151 {"attributes":true, "attributeOldValue": true}, 152 [{type: "attributes", attributeName: "class"}], 153 function() { n21.classList.add("c01", "c02", "c03");}, 154 "attributes Element.classList.add: multiple tokens addition mutation"); 155 156 var n22 = document.getElementById('n22'); 157 runMutationTest(n22, 158 {"attributes":true, "attributeOldValue": true}, 159 [{type: "attributes", oldValue: "n22", attributeName: "id"}], 160 function() { try { n22.classList.add("c01", "", "c03"); } catch (e) { }; 161 n22.id = "n220"; }, 162 "attributes Element.classList.add: syntax err/no mutation"); 163 164 var n23 = document.getElementById('n23'); 165 runMutationTest(n23, 166 {"attributes":true, "attributeOldValue": true}, 167 [{type: "attributes", oldValue: "n23", attributeName: "id"}], 168 function() { try { n23.classList.add("c01", "c 02", "c03"); } catch (e) { }; 169 n23.id = "n230"; }, 170 "attributes Element.classList.add: invalid character/no mutation"); 171 172 var n24 = document.getElementById('n24'); 173 runMutationTest(n24, 174 {"attributes":true, "attributeOldValue": true}, 175 [{type: "attributes", oldValue: "c01 c02", attributeName: "class"}, {type: "attributes", oldValue: "n24", attributeName: "id"}], 176 function() { n24.classList.add("c02"); n24.id = "n240";}, 177 "attributes Element.classList.add: same value mutation"); 178 179 var n30 = document.getElementById('n30'); 180 runMutationTest(n30, 181 {"attributes":true, "attributeOldValue": true}, 182 [{type: "attributes", oldValue: "c01 c02", attributeName: "class"}], 183 function() { n30.classList.remove("c01");}, 184 "attributes Element.classList.remove: single token removal mutation"); 185 186 var n31 = document.getElementById('n31'); 187 runMutationTest(n31, 188 {"attributes":true, "attributeOldValue": true}, 189 [{type: "attributes", oldValue: "c01 c02", attributeName: "class"}], 190 function() { n31.classList.remove("c01", "c02");}, 191 "attributes Element.classList.remove: multiple tokens removal mutation"); 192 193 var n32 = document.getElementById('n32'); 194 runMutationTest(n32, 195 {"attributes":true, "attributeOldValue": true}, 196 [{type: "attributes", oldValue: "c01 c02", attributeName: "class"}, {type: "attributes", oldValue: "n32", attributeName: "id"}], 197 function() { n32.classList.remove("c03"); n32.id = "n320";}, 198 "attributes Element.classList.remove: missing token removal mutation"); 199 200 var n40 = document.getElementById('n40'); 201 runMutationTest(n40, 202 {"attributes":true, "attributeOldValue": true}, 203 [{type: "attributes", oldValue: "c01 c02", attributeName: "class"}], 204 function() { n40.classList.toggle("c01");}, 205 "attributes Element.classList.toggle: token removal mutation"); 206 207 var n41 = document.getElementById('n41'); 208 runMutationTest(n41, 209 {"attributes":true, "attributeOldValue": true}, 210 [{type: "attributes", oldValue: "c01 c02", attributeName: "class"}], 211 function() { n41.classList.toggle("c03");}, 212 "attributes Element.classList.toggle: token addition mutation"); 213 214 var n42 = document.getElementById('n42'); 215 runMutationTest(n42, 216 {"attributes":true, "attributeOldValue": true}, 217 [{type: "attributes", oldValue: "c01 c02", attributeName: "class"}], 218 function() { n42.classList.toggle("c01", false);}, 219 "attributes Element.classList.toggle: forced token removal mutation"); 220 221 var n43 = document.getElementById('n43'); 222 runMutationTest(n43, 223 {"attributes":true, "attributeOldValue": true}, 224 [{type: "attributes", oldValue: "n43", attributeName: "id"}], 225 function() { n43.classList.toggle("c03", false); n43.id = "n430"; }, 226 "attributes Element.classList.toggle: forced missing token removal no mutation"); 227 228 var n44 = document.getElementById('n44'); 229 runMutationTest(n44, 230 {"attributes":true, "attributeOldValue": true}, 231 [{type: "attributes", oldValue: "n44", attributeName: "id"}], 232 function() { n44.classList.toggle("c01", true); n44.id = "n440"; }, 233 "attributes Element.classList.toggle: forced existing token addition no mutation"); 234 235 var n45 = document.getElementById('n45'); 236 runMutationTest(n45, 237 {"attributes":true, "attributeOldValue": true}, 238 [{type: "attributes", oldValue: "c01 c02", attributeName: "class"}], 239 function() { n45.classList.toggle("c03", true);}, 240 "attributes Element.classList.toggle: forced token addition mutation"); 241 242 var n50 = document.getElementById('n50'); 243 runMutationTest(n50, 244 {"attributes":true, "attributeOldValue": true}, 245 [{type: "attributes", oldValue: "c01 c02", attributeName: "class"}], 246 function() { 247 for (var i = 0; i < n50.attributes.length; i++) { 248 var attr = n50.attributes[i]; 249 if (attr.localName === "class") { 250 attr.value = "c03"; 251 } 252 }; 253 }, 254 "attributes Element.attributes.value: update mutation"); 255 256 var n51 = document.getElementById('n51'); 257 runMutationTest(n51, 258 {"attributes":true, "attributeOldValue": true}, 259 [{type: "attributes", oldValue: "n51", attributeName: "id"}], 260 function() { 261 n51.attributes[0].value = "n51"; 262 }, 263 "attributes Element.attributes.value: same id mutation"); 264 265 var n60 = document.getElementById('n60'); 266 runMutationTest(n60, 267 {"attributes":true, "attributeOldValue": true}, 268 [{type: "attributes", oldValue: "n60", attributeName: "id"}], 269 function() { 270 n60.setAttribute("id", "n601"); 271 }, 272 "attributes Element.setAttribute: id mutation"); 273 274 var n61 = document.getElementById('n61'); 275 runMutationTest(n61, 276 {"attributes":true, "attributeOldValue": true}, 277 [{type: "attributes", oldValue: "c01", attributeName: "class"}], 278 function() { 279 n61.setAttribute("class", "c01"); 280 }, 281 "attributes Element.setAttribute: same class mutation"); 282 283 var n62 = document.getElementById('n62'); 284 runMutationTest(n62, 285 {"attributes":true, "attributeOldValue": true}, 286 [{type: "attributes", attributeName: "classname"}], 287 function() { 288 n62.setAttribute("classname", "c01"); 289 }, 290 "attributes Element.setAttribute: classname mutation"); 291 292 var n70 = document.getElementById('n70'); 293 runMutationTest(n70, 294 {"attributes":true, "attributeOldValue": true}, 295 [{type: "attributes", oldValue: "c01", attributeName: "class"}], 296 function() { 297 n70.removeAttribute("class"); 298 }, 299 "attributes Element.removeAttribute: removal mutation"); 300 301 var n71 = document.getElementById('n71'); 302 runMutationTest(n71, 303 {"attributes":true, "attributeOldValue": true}, 304 [{type: "attributes", oldValue: "n71", attributeName: "id"}], 305 function() { 306 n71.removeAttribute("class"); 307 n71.id = "n710"; 308 }, 309 "attributes Element.removeAttribute: removal no mutation"); 310 311 var n72 = document.getElementById('n72'); 312 runMutationTest(n72, 313 {"attributes":true, "attributeOldValue": true}, 314 [{type: "attributes", oldValue: "text", attributeName: "type"}, {type: "attributes", oldValue: "n72", attributeName: "id"}], 315 function() { 316 n72.removeAttribute("type"); 317 n72.id = "n720"; 318 }, 319 "childList HTMLInputElement.removeAttribute: type removal mutation"); 320 321 var n80 = document.getElementById('n80'); 322 runMutationTest(n80, 323 {"attributes":true, "attributeOldValue": true}, 324 [{type: "attributes", attributeName: "private", attributeNamespace: "http://example.org/"}], 325 function() { 326 n80.setAttributeNS("http://example.org/", "private", "42"); 327 }, 328 "attributes Element.setAttributeNS: creation mutation"); 329 330 var n81 = document.getElementById('n81'); 331 runMutationTest(n81, 332 {"attributes":true, "attributeOldValue": true}, 333 [{type: "attributes", attributeName: "lang", attributeNamespace: "http://www.w3.org/XML/1998/namespace"}], 334 function() { 335 n81.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:lang", "42"); 336 }, 337 "attributes Element.setAttributeNS: prefixed attribute creation mutation"); 338 339 var n90 = document.getElementById('n90'); 340 n90.setAttributeNS("http://example.org/", "private", "42"); 341 runMutationTest(n90, 342 {"attributes":true, "attributeOldValue": true}, 343 [{type: "attributes", oldValue: "42", attributeName: "private", attributeNamespace: "http://example.org/"}], 344 function() { 345 n90.removeAttributeNS("http://example.org/", "private"); 346 }, 347 "attributes Element.removeAttributeNS: removal mutation"); 348 349 var n91 = document.getElementById('n91'); 350 runMutationTest(n91, 351 {"attributes":true, "attributeOldValue": true}, 352 [{type: "attributes", oldValue: "n91", attributeName: "id"}], 353 function() { 354 n91.removeAttributeNS("http://example.org/", "private"); 355 n91.id = "n910"; 356 }, 357 "attributes Element.removeAttributeNS: removal no mutation"); 358 359 var n92 = document.getElementById('n92'); 360 runMutationTest(n92, 361 {"attributes":true, "attributeOldValue": true}, 362 [{type: "attributes", oldValue: "n92", attributeName: "id"}], 363 function() { 364 n92.removeAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:lang"); 365 n92.id = "n920"; 366 }, 367 "attributes Element.removeAttributeNS: prefixed attribute removal no mutation"); 368 369 var n1000 = document.getElementById('n1000'); 370 runMutationTest(n1000, 371 {"attributes":true, "attributeOldValue": true,"attributeFilter": ["id"]}, 372 [{type: "attributes", oldValue: "n1000", attributeName: "id"}], 373 function() { n1000.id = "abc"; n1000.className = "c01"}, 374 "attributes/attributeFilter Element.id/Element.className: update mutation"); 375 376 var n1001 = document.getElementById('n1001'); 377 runMutationTest(n1001, 378 {"attributes":true, "attributeOldValue": true,"attributeFilter": ["id", "class"]}, 379 [{type: "attributes", oldValue: "n1001", attributeName: "id"}, 380 {type: "attributes", oldValue: "c01", attributeName: "class"}], 381 function() { n1001.id = "abc"; n1001.className = "c02"; n1001.setAttribute("lang", "fr");}, 382 "attributes/attributeFilter Element.id/Element.className: multiple filter update mutation"); 383 384 var n2000 = document.getElementById('n2000'); 385 runMutationTest(n2000, 386 {"attributeOldValue": true}, 387 [{type: "attributes", oldValue: "n2000", attributeName: "id"}], 388 function() { n2000.id = "abc";}, 389 "attributeOldValue alone Element.id: update mutation"); 390 391 var n2001 = document.getElementById('n2001'); 392 runMutationTest(n2001, 393 {"attributeFilter": ["id", "class"]}, 394 [{type: "attributes", attributeName: "id"}, 395 {type: "attributes", attributeName: "class"}], 396 function() { n2001.id = "abcd"; n2001.className = "c02"; n2001.setAttribute("lang", "fr");}, 397 "attributeFilter alone Element.id/Element.className: multiple filter update mutation"); 398 399 var n3000 = document.getElementById('n3000'); 400 runMutationTest(n3000, 401 {"subtree": true, "childList":false, "attributes" : true}, 402 [{type: "attributes", attributeName: "id" }], 403 function() { n3000.textContent = "CHANGED"; n3000.id = "abc";}, 404 "childList false: no childList mutation"); 405 406 </script>