OLD | NEW |
1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
2 <meta charset=utf-8> | 2 <meta charset=utf-8> |
3 <title>Attributes tests</title> | 3 <title>Attributes tests</title> |
4 <link rel=help href="https://dom.spec.whatwg.org/#attr"> | 4 <link rel=help href="https://dom.spec.whatwg.org/#attr"> |
5 <link rel=help href="https://dom.spec.whatwg.org/#dom-element-setattribute"> | 5 <link rel=help href="https://dom.spec.whatwg.org/#dom-element-setattribute"> |
6 <link rel=help href="https://dom.spec.whatwg.org/#dom-element-setattributens"> | 6 <link rel=help href="https://dom.spec.whatwg.org/#dom-element-setattributens"> |
7 <script src="../../../../resources/testharness.js"></script> | 7 <script src="../../../../resources/testharness.js"></script> |
8 <script src="../../../../resources/testharnessreport.js"></script> | 8 <script src="../../../../resources/testharnessreport.js"></script> |
9 <script src="attributes.js"></script> | 9 <script src="attributes.js"></script> |
10 <script src="productions.js"></script> | 10 <script src="productions.js"></script> |
11 <div id="log"></div> | 11 <div id="log"></div> |
12 <span id="test1"></span> | 12 <span id="test1"></span> |
13 <span class="&<>foo"></span> | 13 <span class="&<>foo"></span> |
14 <script> | 14 <script> |
15 var XML = "http://www.w3.org/XML/1998/namespace" | 15 var XML = "http://www.w3.org/XML/1998/namespace" |
16 var XMLNS = "http://www.w3.org/2000/xmlns/" | 16 var XMLNS = "http://www.w3.org/2000/xmlns/" |
17 | 17 |
18 // AttrExodus | 18 // AttrExodus |
19 test(function() { | 19 test(function() { |
20 document.body.setAttribute("abc", "pass") | 20 document.body.setAttribute("abc", "pass") |
21 var attr = document.body.attributes[0] | 21 var attr = document.body.attributes[0] |
22 assert_true(attr instanceof Attr) | 22 assert_true(attr instanceof Attr, "should be an Attr") |
23 assert_false(attr instanceof Node) | 23 assert_false(attr instanceof Node, "should not be a Node") |
24 assert_throws(new TypeError(), function() { attr.appendChild(document.createTe
xtNode("fail")) }) | 24 var removed_members = [ |
25 assert_throws(new TypeError(), function() { attr.appendChild(null) }) | 25 "appendChild", |
| 26 "insertBefore", |
| 27 "childNodes", |
| 28 ] |
| 29 removed_members.forEach(function(m) { |
| 30 assert_false(m in attr, m + " should not be supported") |
| 31 }) |
26 assert_equals(attr.value, "pass") | 32 assert_equals(attr.value, "pass") |
27 assert_false("childNodes" in attr, "Should not have childNodes") | |
28 }, "AttrExodus") | 33 }, "AttrExodus") |
29 | 34 |
30 // setAttribute exhaustive tests | 35 // setAttribute exhaustive tests |
31 // Step 1 | 36 // Step 1 |
32 test(function() { | 37 test(function() { |
33 var el = document.createElement("foo") | 38 var el = document.createElement("foo") |
34 for (var i = 0; i < invalid_names.length; i++) { | 39 for (var i = 0; i < invalid_names.length; i++) { |
35 assert_throws("INVALID_CHARACTER_ERR", function() { el.setAttribute(invalid_
names[i], "test") }) | 40 assert_throws("INVALID_CHARACTER_ERR", function() { el.setAttribute(invalid_
names[i], "test") }) |
36 } | 41 } |
37 }, "When qualifiedName does not match the Name production, an " + | 42 }, "When qualifiedName does not match the Name production, an " + |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 el.setAttributeNS("x", "foo", "bar") | 440 el.setAttributeNS("x", "foo", "bar") |
436 var attrNode = el.getAttributeNodeNS("x", "foo"); | 441 var attrNode = el.getAttributeNodeNS("x", "foo"); |
437 el.removeAttribute("foo"); | 442 el.removeAttribute("foo"); |
438 var el2 = document.createElement("div"); | 443 var el2 = document.createElement("div"); |
439 el2.setAttributeNS("x", "foo", "baz"); | 444 el2.setAttributeNS("x", "foo", "baz"); |
440 el2.setAttributeNodeNS(attrNode); | 445 el2.setAttributeNodeNS(attrNode); |
441 assert_equals(el2.getAttributeNS("x", "foo"), "bar"); | 446 assert_equals(el2.getAttributeNS("x", "foo"), "bar"); |
442 }, "Basic functionality of setAttributeNodeNS") | 447 }, "Basic functionality of setAttributeNodeNS") |
443 | 448 |
444 test(function() { | 449 test(function() { |
| 450 var el = document.createElement("div"); |
| 451 var other = document.createElement("div"); |
| 452 attr = document.createAttribute("foo"); |
| 453 assert_equals(el.setAttributeNode(attr), null); |
| 454 assert_equals(attr.ownerElement, el); |
| 455 assert_throws("INUSE_ATTRIBUTE_ERR", |
| 456 function() { other.setAttributeNode(attr) }, |
| 457 "Attribute already associated with el") |
| 458 }, "If attr’s element is neither null nor element, throw an InUseAttributeError.
"); |
| 459 |
| 460 test(function() { |
| 461 var el = document.createElement("div"); |
| 462 attr = document.createAttribute("foo"); |
| 463 assert_equals(el.setAttributeNode(attr), null); |
| 464 el.setAttribute("bar", "qux"); |
| 465 assert_equals(el.setAttributeNode(attr), attr); |
| 466 assert_equals(el.attributes[0], attr); |
| 467 }, "Replacing an attr by itself"); |
| 468 |
| 469 test(function() { |
445 var el = document.createElement("div") | 470 var el = document.createElement("div") |
446 el.setAttribute("foo", "bar") | 471 el.setAttribute("foo", "bar") |
447 var attrNode = el.getAttributeNode("foo"); | 472 var attrNode = el.getAttributeNode("foo"); |
448 el.removeAttributeNode(attrNode); | 473 el.removeAttributeNode(attrNode); |
449 var el2 = document.createElement("div"); | 474 var el2 = document.createElement("div"); |
450 el2.setAttributeNode(attrNode); | 475 el2.setAttributeNode(attrNode); |
451 assert_equals(el2.attributes[0], attrNode); | 476 assert_equals(el2.attributes[0], attrNode); |
452 assert_equals(el.attributes.length, 0); | 477 assert_equals(el.attributes.length, 0); |
453 }, "Basic functionality of removeAttributeNode") | 478 }, "Basic functionality of removeAttributeNode") |
454 | 479 |
455 test(function() { | 480 test(function() { |
456 var el = document.createElement("div") | 481 var el = document.createElement("div") |
457 el.setAttribute("foo", "bar") | 482 el.setAttribute("foo", "bar") |
458 var attrNode = el.getAttributeNode("foo"); | 483 var attrNode = el.getAttributeNode("foo"); |
459 var el2 = document.createElement("div"); | 484 var el2 = document.createElement("div"); |
460 assert_throws("INUSE_ATTRIBUTE_ERR", function(){el2.setAttributeNode(attrNode)
}); | 485 assert_throws("INUSE_ATTRIBUTE_ERR", function(){el2.setAttributeNode(attrNode)
}); |
461 }, "setAttributeNode on bound attribute should throw InUseAttributeError") | 486 }, "setAttributeNode on bound attribute should throw InUseAttributeError") |
462 | 487 |
| 488 // Have to use an async_test to see what a DOMAttrModified listener sees, |
| 489 // because otherwise the event dispatch code will swallow our exceptions. And |
| 490 // we want to make sure this test always happens, even when no mutation events |
| 491 // run. |
| 492 var setAttributeNode_mutation_test = async_test("setAttributeNode, if it fires m
utation events, should fire one with the new node when resetting an existing att
ribute"); |
| 493 |
| 494 test(function(){ |
| 495 var el = document.createElement("div") |
| 496 var attrNode1 = document.createAttribute("foo"); |
| 497 attrNode1.value = "bar"; |
| 498 el.setAttributeNode(attrNode1); |
| 499 var attrNode2 = document.createAttribute("foo"); |
| 500 attrNode2.value = "baz"; |
| 501 |
| 502 el.addEventListener("DOMAttrModified", function(e) { |
| 503 // If this never gets called, that's OK, I guess. But if it gets called, it |
| 504 // better represent a single modification with attrNode2 as the relatedNode. |
| 505 // We have to do an inner test() call here, because otherwise the exceptions |
| 506 // our asserts trigger will get swallowed by the event dispatch code. |
| 507 setAttributeNode_mutation_test.step(function() { |
| 508 assert_equals(e.attrName, "foo"); |
| 509 assert_equals(e.attrChange, MutationEvent.MODIFICATION); |
| 510 assert_equals(e.prevValue, "bar"); |
| 511 assert_equals(e.newValue, "baz"); |
| 512 assert_equals(e.relatedNode, attrNode2); |
| 513 }); |
| 514 }); |
| 515 |
| 516 var oldNode = el.setAttributeNode(attrNode2); |
| 517 assert_equals(oldNode, attrNode1, |
| 518 "Must return the old attr node from a setAttributeNode call"); |
| 519 }, "setAttributeNode, if it fires mutation events, should fire one with the new
node when resetting an existing attribute (outer shell)"); |
| 520 setAttributeNode_mutation_test.done(); |
| 521 |
| 522 test(function(){ |
| 523 var el = document.createElement("div") |
| 524 el.setAttribute("a", "b"); |
| 525 el.setAttribute("c", "d"); |
| 526 |
| 527 assert_array_equals(Array.prototype.map.call(el.attributes, function(a) { retu
rn a.name }), |
| 528 ["a", "c"]); |
| 529 assert_array_equals(Array.prototype.map.call(el.attributes, function(a) { retu
rn a.value }), |
| 530 ["b", "d"]); |
| 531 |
| 532 var attrNode = document.createAttribute("a"); |
| 533 attrNode.value = "e"; |
| 534 el.setAttributeNode(attrNode); |
| 535 |
| 536 assert_array_equals(Array.prototype.map.call(el.attributes, function(a) { retu
rn a.name }), |
| 537 ["a", "c"]); |
| 538 assert_array_equals(Array.prototype.map.call(el.attributes, function(a) { retu
rn a.value }), |
| 539 ["e", "d"]); |
| 540 }, "setAttributeNode called with an Attr that has the same name as an existing o
ne should not change attribute order"); |
| 541 |
463 test(function() { | 542 test(function() { |
464 var el = document.createElement("div"); | 543 var el = document.createElement("div"); |
465 el.setAttribute("foo", "bar"); | 544 el.setAttribute("foo", "bar"); |
466 assert_equals(el.getAttributeNames().length, 1); | 545 assert_equals(el.getAttributeNames().length, 1); |
467 assert_equals(el.getAttributeNames()[0], el.attributes[0].name); | 546 assert_equals(el.getAttributeNames()[0], el.attributes[0].name); |
468 assert_equals(el.getAttributeNames()[0], "foo"); | 547 assert_equals(el.getAttributeNames()[0], "foo"); |
469 | 548 |
470 el.removeAttribute("foo"); | 549 el.removeAttribute("foo"); |
471 assert_equals(el.getAttributeNames().length, 0); | 550 assert_equals(el.getAttributeNames().length, 0); |
472 | 551 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 var el = document.createElement("div"); | 604 var el = document.createElement("div"); |
526 el.setAttributeNS("", "a", ""); | 605 el.setAttributeNS("", "a", ""); |
527 el.setAttribute("b", ""); | 606 el.setAttribute("b", ""); |
528 el.setAttributeNS("foo", "a", ""); | 607 el.setAttributeNS("foo", "a", ""); |
529 assert_array_equals(getEnumerableOwnProps1(el.attributes), | 608 assert_array_equals(getEnumerableOwnProps1(el.attributes), |
530 ["0", "1", "2"]) | 609 ["0", "1", "2"]) |
531 assert_array_equals(getEnumerableOwnProps2(el.attributes), | 610 assert_array_equals(getEnumerableOwnProps2(el.attributes), |
532 ["0", "1", "2"]) | 611 ["0", "1", "2"]) |
533 assert_array_equals(Object.getOwnPropertyNames(el.attributes), | 612 assert_array_equals(Object.getOwnPropertyNames(el.attributes), |
534 ["0", "1", "2", "a", "b"]) | 613 ["0", "1", "2", "a", "b"]) |
| 614 for (var propName of Object.getOwnPropertyNames(el.attributes)) { |
| 615 assert_true(el.attributes[propName] instanceof Attr, |
| 616 "el.attributes has an Attr for property name " + propName); |
| 617 } |
535 }, "Own property correctness with non-namespaced attribute before same-name name
spaced one"); | 618 }, "Own property correctness with non-namespaced attribute before same-name name
spaced one"); |
536 | 619 |
537 test(function() { | 620 test(function() { |
538 var el = document.createElement("div"); | 621 var el = document.createElement("div"); |
539 el.setAttributeNS("foo", "a", ""); | 622 el.setAttributeNS("foo", "a", ""); |
540 el.setAttribute("b", ""); | 623 el.setAttribute("b", ""); |
541 el.setAttributeNS("", "a", ""); | 624 el.setAttributeNS("", "a", ""); |
542 assert_array_equals(getEnumerableOwnProps1(el.attributes), | 625 assert_array_equals(getEnumerableOwnProps1(el.attributes), |
543 ["0", "1", "2"]) | 626 ["0", "1", "2"]) |
544 assert_array_equals(getEnumerableOwnProps2(el.attributes), | 627 assert_array_equals(getEnumerableOwnProps2(el.attributes), |
545 ["0", "1", "2"]) | 628 ["0", "1", "2"]) |
546 assert_array_equals(Object.getOwnPropertyNames(el.attributes), | 629 assert_array_equals(Object.getOwnPropertyNames(el.attributes), |
547 ["0", "1", "2", "a", "b"]) | 630 ["0", "1", "2", "a", "b"]) |
| 631 for (var propName of Object.getOwnPropertyNames(el.attributes)) { |
| 632 assert_true(el.attributes[propName] instanceof Attr, |
| 633 "el.attributes has an Attr for property name " + propName); |
| 634 } |
548 }, "Own property correctness with namespaced attribute before same-name non-name
spaced one"); | 635 }, "Own property correctness with namespaced attribute before same-name non-name
spaced one"); |
549 | 636 |
550 test(function() { | 637 test(function() { |
551 var el = document.createElement("div"); | 638 var el = document.createElement("div"); |
552 el.setAttributeNS("foo", "a:b", ""); | 639 el.setAttributeNS("foo", "a:b", ""); |
553 el.setAttributeNS("foo", "c:d", ""); | 640 el.setAttributeNS("foo", "c:d", ""); |
554 el.setAttributeNS("bar", "a:b", ""); | 641 el.setAttributeNS("bar", "a:b", ""); |
555 assert_array_equals(getEnumerableOwnProps1(el.attributes), | 642 assert_array_equals(getEnumerableOwnProps1(el.attributes), |
556 ["0", "1", "2"]) | 643 ["0", "1", "2"]) |
557 assert_array_equals(getEnumerableOwnProps2(el.attributes), | 644 assert_array_equals(getEnumerableOwnProps2(el.attributes), |
558 ["0", "1", "2"]) | 645 ["0", "1", "2"]) |
559 assert_array_equals(Object.getOwnPropertyNames(el.attributes), | 646 assert_array_equals(Object.getOwnPropertyNames(el.attributes), |
560 ["0", "1", "2", "a:b", "c:d"]) | 647 ["0", "1", "2", "a:b", "c:d"]) |
| 648 for (var propName of Object.getOwnPropertyNames(el.attributes)) { |
| 649 assert_true(el.attributes[propName] instanceof Attr, |
| 650 "el.attributes has an Attr for property name " + propName); |
| 651 } |
561 }, "Own property correctness with two namespaced attributes with the same name-w
ith-prefix"); | 652 }, "Own property correctness with two namespaced attributes with the same name-w
ith-prefix"); |
| 653 |
| 654 test(function() { |
| 655 var el = document.createElement("div"); |
| 656 el.setAttributeNS("foo", "A:B", ""); |
| 657 el.setAttributeNS("bar", "c:D", ""); |
| 658 el.setAttributeNS("baz", "e:F", ""); |
| 659 el.setAttributeNS("qux", "g:h", ""); |
| 660 el.setAttributeNS("", "I", ""); |
| 661 el.setAttributeNS("", "j", ""); |
| 662 assert_array_equals(Object.getOwnPropertyNames(el.attributes), |
| 663 ["0", "1", "2", "3", "4", "5", "g:h", "j"]) |
| 664 for (var propName of Object.getOwnPropertyNames(el.attributes)) { |
| 665 assert_true(el.attributes[propName] instanceof Attr, |
| 666 "el.attributes has an Attr for property name " + propName); |
| 667 } |
| 668 }, "Own property names should only include all-lowercase qualified names for an
HTML element in an HTML document"); |
| 669 |
| 670 test(function() { |
| 671 var el = document.createElementNS("", "div"); |
| 672 el.setAttributeNS("foo", "A:B", ""); |
| 673 el.setAttributeNS("bar", "c:D", ""); |
| 674 el.setAttributeNS("baz", "e:F", ""); |
| 675 el.setAttributeNS("qux", "g:h", ""); |
| 676 el.setAttributeNS("", "I", ""); |
| 677 el.setAttributeNS("", "j", ""); |
| 678 assert_array_equals(Object.getOwnPropertyNames(el.attributes), |
| 679 ["0", "1", "2", "3", "4", "5", "A:B", "c:D", "e:F", "g:h",
"I", "j"]) |
| 680 for (var propName of Object.getOwnPropertyNames(el.attributes)) { |
| 681 assert_true(el.attributes[propName] instanceof Attr, |
| 682 "el.attributes has an Attr for property name " + propName); |
| 683 } |
| 684 }, "Own property names should include all qualified names for a non-HTML element
in an HTML document"); |
| 685 |
| 686 test(function() { |
| 687 var doc = document.implementation.createDocument(null, ""); |
| 688 assert_equals(doc.contentType, "application/xml"); |
| 689 var el = doc.createElementNS("http://www.w3.org/1999/xhtml", "div"); |
| 690 el.setAttributeNS("foo", "A:B", ""); |
| 691 el.setAttributeNS("bar", "c:D", ""); |
| 692 el.setAttributeNS("baz", "e:F", ""); |
| 693 el.setAttributeNS("qux", "g:h", ""); |
| 694 el.setAttributeNS("", "I", ""); |
| 695 el.setAttributeNS("", "j", ""); |
| 696 assert_array_equals(Object.getOwnPropertyNames(el.attributes), |
| 697 ["0", "1", "2", "3", "4", "5", "A:B", "c:D", "e:F", "g:h",
"I", "j"]) |
| 698 for (var propName of Object.getOwnPropertyNames(el.attributes)) { |
| 699 assert_true(el.attributes[propName] instanceof Attr, |
| 700 "el.attributes has an Attr for property name " + propName); |
| 701 } |
| 702 }, "Own property names should include all qualified names for an HTML element in
a non-HTML document"); |
562 </script> | 703 </script> |
OLD | NEW |