test_custom_element_in_shadow.html (4849B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=1087460 5 --> 6 <head> 7 <title>Test for custom element callbacks in shadow DOM.</title> 8 <script type="text/javascript" src="head.js"></script> 9 <script src="/tests/SimpleTest/SimpleTest.js"></script> 10 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 11 </head> 12 <body> 13 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1087460">Bug 1087460</a> 14 15 <script> 16 17 SimpleTest.waitForExplicitFinish(); 18 19 var content = '<div id="container"></div>'; 20 createIframe(content) 21 .then((aDocument) => { 22 23 // Test callback for custom element when used after registration. 24 25 var iframeWin = aDocument.defaultView; 26 var connectedCallbackCount = 0; 27 var disconnectedCallbackCount = 0; 28 var attributeChangedCallbackCount = 0; 29 30 class Foo extends iframeWin.HTMLElement 31 { 32 connectedCallback() { 33 connectedCallbackCount++; 34 } 35 36 disconnectedCallback() { 37 disconnectedCallbackCount++; 38 } 39 40 attributeChangedCallback(aName, aOldValue, aNewValue) { 41 attributeChangedCallbackCount++; 42 } 43 44 static get observedAttributes() { 45 return ["data-foo"]; 46 } 47 } 48 49 iframeWin.customElements.define("x-foo", Foo); 50 51 var container = aDocument.getElementById("container"); 52 var shadow = container.attachShadow({mode: "open"}); 53 var customElem = aDocument.createElement("x-foo"); 54 55 is(attributeChangedCallbackCount, 0, "attributeChangedCallback should not be called after just creating an element."); 56 customElem.setAttribute("data-foo", "bar"); 57 is(attributeChangedCallbackCount, 1, "attributeChangedCallback should be called after setting an attribute."); 58 59 is(connectedCallbackCount, 0, "connectedCallback should not be called on an element that is not in a document/composed document."); 60 shadow.appendChild(customElem); 61 is(connectedCallbackCount, 1, "connectedCallback should be called after attaching custom element to the composed document."); 62 63 is(disconnectedCallbackCount, 0, "disconnectedCallback should not be called without detaching custom element."); 64 shadow.removeChild(customElem); 65 is(disconnectedCallbackCount, 1, "disconnectedCallback should be called after detaching custom element from the composed document."); 66 67 // Test callback for custom element already in the composed doc when created. 68 69 connectedCallbackCount = 0; 70 disconnectedCallbackCount = 0; 71 attributeChangedCallbackCount = 0; 72 73 shadow.innerHTML = "<x-foo></x-foo>"; 74 is(connectedCallbackCount, 1, "connectedCallback should be called after creating an element in the composed document."); 75 76 shadow.innerHTML = ""; 77 is(disconnectedCallbackCount, 1, "disconnectedCallback should be called after detaching custom element from the composed document."); 78 79 // Test callback for custom element in shadow DOM when host attached/detached to/from document. 80 81 connectedCallbackCount = 0; 82 disconnectedCallbackCount = 0; 83 attributeChangedCallbackCount = 0; 84 85 var host = aDocument.createElement("div"); 86 shadow = host.attachShadow({mode: "open"}); 87 customElem = aDocument.createElement("x-foo"); 88 89 is(connectedCallbackCount, 0, "connectedCallback should not be called on newly created element."); 90 shadow.appendChild(customElem); 91 is(connectedCallbackCount, 0, "connectedCallback should not be called on attaching to a tree that is not in the composed document."); 92 93 is(disconnectedCallbackCount, 0, "disconnectedCallback should not be called."); 94 shadow.removeChild(customElem); 95 is(disconnectedCallbackCount, 0, "disconnectedCallback should not be called when detaching from a tree that is not in the composed document."); 96 97 shadow.appendChild(customElem); 98 is(connectedCallbackCount, 0, "connectedCallback should still not be called after reattaching to a shadow tree that is not in the composed document."); 99 100 container.appendChild(host); 101 is(connectedCallbackCount, 1, "connectedCallback should be called after host is inserted into document."); 102 103 container.removeChild(host); 104 is(disconnectedCallbackCount, 1, "disconnectedCallback should be called after host is removed from document."); 105 106 // Test callback for custom element for upgraded element. 107 108 connectedCallbackCount = 0; 109 disconnectedCallbackCount = 0; 110 attributeChangedCallbackCount = 0; 111 112 shadow = container.shadowRoot; 113 shadow.innerHTML = "<x-bar></x-bar>"; 114 115 class Bar extends iframeWin.HTMLElement { 116 connectedCallback() { 117 connectedCallbackCount++; 118 } 119 }; 120 121 iframeWin.customElements.define("x-bar", Bar); 122 is(connectedCallbackCount, 1, "connectedCallback should be called after upgrading element in composed document."); 123 124 SimpleTest.finish(); 125 }); 126 </script> 127 128 </body> 129 </html>