test_custom_element_stack.html (4506B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=783129 5 --> 6 <head> 7 <title>Test for custom elements lifecycle callback</title> 8 <script src="/tests/SimpleTest/SimpleTest.js"></script> 9 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 10 </head> 11 <body> 12 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=783129">Bug 783129</a> 13 <div id="container"> 14 </div> 15 <script> 16 17 var container = document.getElementById("container"); 18 19 function testChangeAttributeInEnteredViewCallback() { 20 var attributeChangedCallbackCalled = false; 21 var connectedCallbackCalled = false; 22 23 class Two extends HTMLElement 24 { 25 connectedCallback() { 26 is(connectedCallbackCalled, false, "Connected callback should be called only once in this test."); 27 connectedCallbackCalled = true; 28 is(attributeChangedCallbackCalled, false, "Attribute changed callback should not be called before changing attribute."); 29 this.setAttribute("foo", "bar"); 30 is(attributeChangedCallbackCalled, true, "Transition from user-agent implementation to script should result in attribute changed callback being called."); 31 runNextTest(); 32 } 33 34 attributeChangedCallback() { 35 is(connectedCallbackCalled, true, "Connected callback should have been called prior to attribute changed callback."); 36 is(attributeChangedCallbackCalled, false, "Attribute changed callback should only be called once in this tests."); 37 attributeChangedCallbackCalled = true; 38 } 39 40 static get observedAttributes() { 41 return ["foo"]; 42 } 43 } 44 45 customElements.define("x-two", Two); 46 var elem = document.createElement("x-two"); 47 48 var container = document.getElementById("container"); 49 container.appendChild(elem); 50 } 51 52 function testLeaveViewInEnteredViewCallback() { 53 var connectedCallbackCalled = false; 54 var disconnectedCallbackCalled = false; 55 var container = document.getElementById("container"); 56 57 class Three extends HTMLElement { 58 connectedCallback() { 59 is(this.parentNode, container, "Parent node should the container in which the node was appended."); 60 is(connectedCallbackCalled, false, "Connected callback should be called only once in this test."); 61 connectedCallbackCalled = true; 62 is(disconnectedCallbackCalled, false, "Disconnected callback should not be called prior to removing element from document."); 63 container.removeChild(this); 64 is(disconnectedCallbackCalled, true, "Transition from user-agent implementation to script should run left view callback."); 65 runNextTest(); 66 } 67 68 disconnectedCallback() { 69 is(disconnectedCallbackCalled, false, "The disconnected callback should only be called once in this test."); 70 is(connectedCallbackCalled, true, "The connected callback should be called prior to disconnected callback."); 71 disconnectedCallbackCalled = true; 72 } 73 }; 74 75 customElements.define("x-three", Three); 76 var elem = document.createElement("x-three"); 77 78 container.appendChild(elem); 79 } 80 81 function testStackedAttributeChangedCallback() { 82 var attributeChangedCallbackCount = 0; 83 84 var attributeSequence = ["foo", "bar", "baz"]; 85 86 class Four extends HTMLElement 87 { 88 attributeChangedCallback(attrName, oldValue, newValue) { 89 if (newValue == "baz") { 90 return; 91 } 92 93 var nextAttribute = attributeSequence.shift(); 94 ok(true, nextAttribute); 95 // Setting this attribute will call this function again, when 96 // control returns to the script, the last attribute in the sequence should 97 // be set on the element. 98 this.setAttribute("foo", nextAttribute); 99 is(this.getAttribute("foo"), "baz", "The last value in the sequence should be the value of the attribute."); 100 101 attributeChangedCallbackCount++; 102 if (attributeChangedCallbackCount == 3) { 103 runNextTest(); 104 } 105 } 106 107 static get observedAttributes() { 108 return ["foo"]; 109 } 110 } 111 112 customElements.define("x-four", Four); 113 var elem = document.createElement("x-four"); 114 elem.setAttribute("foo", "changeme"); 115 } 116 117 var testFunctions = [ 118 testChangeAttributeInEnteredViewCallback, 119 testLeaveViewInEnteredViewCallback, 120 testStackedAttributeChangedCallback, 121 SimpleTest.finish 122 ]; 123 124 function runNextTest() { 125 if (testFunctions.length) { 126 var nextTestFunction = testFunctions.shift(); 127 info(`Start ${nextTestFunction.name} ...`); 128 nextTestFunction(); 129 } 130 } 131 132 SimpleTest.waitForExplicitFinish(); 133 134 runNextTest(); 135 136 </script> 137 </body> 138 </html>