|
1 <!DOCTYPE HTML> |
|
2 <html> |
|
3 <!-- |
|
4 https://bugzilla.mozilla.org/show_bug.cgi?id=783129 |
|
5 --> |
|
6 <head> |
|
7 <title>Test for document.registerElement lifecycle callback</title> |
|
8 <script type="text/javascript" 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 // Test changing attributes in the created callback on an element |
|
20 // created after registration. |
|
21 function testChangeAttributeInCreatedCallback() { |
|
22 var createdCallbackCalled = false; |
|
23 var attributeChangedCallbackCalled = false; |
|
24 |
|
25 var p = Object.create(HTMLElement.prototype); |
|
26 p.createdCallback = function() { |
|
27 is(createdCallbackCalled, false, "Created callback should be called before attached callback."); |
|
28 createdCallbackCalled = true; |
|
29 is(attributeChangedCallbackCalled, false, "Attribute changed callback should not have been called prior to setting the attribute."); |
|
30 this.setAttribute("foo", "bar"); |
|
31 is(attributeChangedCallbackCalled, false, "While element is being created, element should not be added to the current element callback queue."); |
|
32 }; |
|
33 |
|
34 p.attributeChangedCallback = function(name, oldValue, newValue) { |
|
35 is(createdCallbackCalled, true, "attributeChanged callback should be called after the created callback because it was enqueued during created callback."); |
|
36 is(attributeChangedCallbackCalled, false, "attributeChanged callback should only be called once in this tests."); |
|
37 is(newValue, "bar", "The new value should be 'bar'"); |
|
38 attributeChangedCallbackCalled = true; |
|
39 runNextTest(); |
|
40 }; |
|
41 |
|
42 document.registerElement("x-one", { prototype: p }); |
|
43 document.createElement("x-one"); |
|
44 } |
|
45 |
|
46 function testChangeAttributeInEnteredViewCallback() { |
|
47 var p = Object.create(HTMLElement.prototype); |
|
48 var attributeChangedCallbackCalled = false; |
|
49 var attachedCallbackCalled = false; |
|
50 |
|
51 p.attachedCallback = function() { |
|
52 is(attachedCallbackCalled, false, "attached callback should be called only once in this test."); |
|
53 attachedCallbackCalled = true; |
|
54 is(attributeChangedCallbackCalled, false, "Attribute changed callback should not be called before changing attribute."); |
|
55 this.setAttribute("foo", "bar"); |
|
56 is(attributeChangedCallbackCalled, true, "Transition from user-agent implementation to script should result in attribute changed callback being called."); |
|
57 runNextTest(); |
|
58 }; |
|
59 |
|
60 p.attributeChangedCallback = function() { |
|
61 is(attachedCallbackCalled, true, "attached callback should have been called prior to attribute changed callback."); |
|
62 is(attributeChangedCallbackCalled, false, "attributeChanged callback should only be called once in this tests."); |
|
63 attributeChangedCallbackCalled = true; |
|
64 }; |
|
65 |
|
66 document.registerElement("x-two", { prototype: p }); |
|
67 var elem = document.createElement("x-two"); |
|
68 |
|
69 var container = document.getElementById("container"); |
|
70 container.appendChild(elem); |
|
71 } |
|
72 |
|
73 function testLeaveViewInEnteredViewCallback() { |
|
74 var p = Object.create(HTMLElement.prototype); |
|
75 var attachedCallbackCalled = false; |
|
76 var detachedCallbackCalled = false; |
|
77 var container = document.getElementById("container"); |
|
78 |
|
79 p.attachedCallback = function() { |
|
80 is(this.parentNode, container, "Parent node should the container in which the node was appended."); |
|
81 is(attachedCallbackCalled, false, "attached callback should be called only once in this test."); |
|
82 attachedCallbackCalled = true; |
|
83 is(detachedCallbackCalled, false, "detached callback should not be called prior to removing element from document."); |
|
84 container.removeChild(this); |
|
85 is(detachedCallbackCalled, true, "Transition from user-agent implementation to script should run left view callback."); |
|
86 runNextTest(); |
|
87 }; |
|
88 |
|
89 p.detachedCallback = function() { |
|
90 is(detachedCallbackCalled, false, "The detached callback should only be called once in this test."); |
|
91 is(attachedCallbackCalled, true, "The attached callback should be called prior to detached callback."); |
|
92 detachedCallbackCalled = true; |
|
93 }; |
|
94 |
|
95 document.registerElement("x-three", { prototype: p }); |
|
96 var elem = document.createElement("x-three"); |
|
97 |
|
98 container.appendChild(elem); |
|
99 } |
|
100 |
|
101 function testStackedAttributeChangedCallback() { |
|
102 var p = Object.create(HTMLElement.prototype); |
|
103 var attributeChangedCallbackCount = 0; |
|
104 |
|
105 var attributeSequence = ["foo", "bar", "baz"]; |
|
106 |
|
107 p.attributeChangedCallback = function(attrName, oldValue, newValue) { |
|
108 if (newValue == "baz") { |
|
109 return; |
|
110 } |
|
111 |
|
112 var nextAttribute = attributeSequence.shift(); |
|
113 ok(true, nextAttribute); |
|
114 // Setting this attribute will call this function again, when |
|
115 // control returns to the script, the last attribute in the sequence should |
|
116 // be set on the element. |
|
117 this.setAttribute("foo", nextAttribute); |
|
118 is(this.getAttribute("foo"), "baz", "The last value in the sequence should be the value of the attribute."); |
|
119 |
|
120 attributeChangedCallbackCount++; |
|
121 if (attributeChangedCallbackCount == 3) { |
|
122 runNextTest(); |
|
123 } |
|
124 }; |
|
125 |
|
126 document.registerElement("x-four", { prototype: p }); |
|
127 var elem = document.createElement("x-four"); |
|
128 elem.setAttribute("foo", "changeme"); |
|
129 } |
|
130 |
|
131 var testFunctions = [ |
|
132 testChangeAttributeInCreatedCallback, |
|
133 testChangeAttributeInEnteredViewCallback, |
|
134 testLeaveViewInEnteredViewCallback, |
|
135 testStackedAttributeChangedCallback, |
|
136 SimpleTest.finish |
|
137 ]; |
|
138 |
|
139 function runNextTest() { |
|
140 if (testFunctions.length > 0) { |
|
141 var nextTestFunction = testFunctions.shift(); |
|
142 nextTestFunction(); |
|
143 } |
|
144 } |
|
145 |
|
146 SimpleTest.waitForExplicitFinish(); |
|
147 |
|
148 runNextTest(); |
|
149 |
|
150 </script> |
|
151 </body> |
|
152 </html> |