author | Edgar Chen <echen@mozilla.com> |
Tue, 03 Oct 2017 17:22:58 +0800 | |
changeset 393050 | b4a1ab50128ef069d2a1853c9f6ad462a1f7161d |
parent 393049 | 18f77ef35a2231f8fa2d4ba37e3e5c7d3cbee469 |
child 393051 | af8727e2028e660aa0f7525c0e1c784d8edafff7 |
push id | 32953 |
push user | shindli@mozilla.com |
push date | Wed, 22 Nov 2017 21:28:42 +0000 |
treeherder | mozilla-central@f5dafe8991b3 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | smaug |
bugs | 1390396 |
milestone | 59.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/tests/mochitest/webcomponents/mochitest.ini +++ b/dom/tests/mochitest/webcomponents/mochitest.ini @@ -5,45 +5,41 @@ support-files = [test_bug900724.html] [test_bug1017896.html] [test_bug1176757.html] [test_bug1276240.html] [test_content_element.html] skip-if = true # Triggers assertions about flattened tree inconsistencies and it's going away in bug 1418002. [test_custom_element_callback_innerhtml.html] -skip-if = true # disabled - See bug 1390396 [test_custom_element_htmlconstructor.html] skip-if = os == 'android' # bug 1323645 support-files = htmlconstructor_autonomous_tests.js htmlconstructor_builtin_tests.js [test_custom_element_in_shadow.html] -skip-if = true # disabled - See bug 1390396 [test_custom_element_register_invalid_callbacks.html] [test_custom_element_throw_on_dynamic_markup_insertion.html] [test_custom_element_get.html] [test_custom_element_when_defined.html] [test_custom_element_upgrade.html] support-files = test_upgrade_page.html upgrade_tests.js +[test_custom_element_lifecycle.html] +[test_custom_element_stack.html] [test_nested_content_element.html] [test_dest_insertion_points.html] [test_fallback_dest_insertion_points.html] [test_detached_style.html] [test_dynamic_content_element_matching.html] [test_document_adoptnode.html] [test_document_importnode.html] [test_document_register.html] -[test_document_register_lifecycle.html] -skip-if = true # disabled - See bug 1390396 [test_document_register_parser.html] -[test_document_register_stack.html] -skip-if = true # disabled - See bug 1390396 [test_document_shared_registry.html] [test_event_retarget.html] [test_event_stopping.html] [test_template.html] [test_template_xhtml.html] [test_template_custom_elements.html] [test_shadowroot.html] [test_shadowroot_inert_element.html]
--- a/dom/tests/mochitest/webcomponents/test_custom_element_callback_innerhtml.html +++ b/dom/tests/mochitest/webcomponents/test_custom_element_callback_innerhtml.html @@ -1,34 +1,30 @@ <!DOCTYPE HTML> <html> <!-- https://bugzilla.mozilla.org/show_bug.cgi?id=1102502 --> <head> - <title>Test for attached callback for element created in the document by the parser</title> + <title>Test for connected callback for element created in the document by the parser</title> <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> </head> <body> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1102502">Bug 1102502</a> <div id="container"></div> <script> SimpleTest.waitForExplicitFinish(); var connectedCallbackCount = 0; var p = Object.create(HTMLElement.prototype); -p.createdCallback = function() { - ok(true, "createdCallback called."); -}; - p.connectedCallback = function() { ok(true, "connectedCallback should be called when the parser creates an element in the document."); connectedCallbackCount++; // connectedCallback should be called twice, once for the element created for innerHTML and // once for the element created in this document. if (connectedCallbackCount == 2) { SimpleTest.finish(); }
--- a/dom/tests/mochitest/webcomponents/test_custom_element_in_shadow.html +++ b/dom/tests/mochitest/webcomponents/test_custom_element_in_shadow.html @@ -11,122 +11,110 @@ https://bugzilla.mozilla.org/show_bug.cg <body> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1087460">Bug 1087460</a> <div id="container"></div> <script> // Test callback for custom element when used after registration. -var createdCallbackCount = 0; -var attachedCallbackCount = 0; -var detachedCallbackCount = 0; +var connectedCallbackCount = 0; +var disconnectedCallbackCount = 0; var attributeChangedCallbackCount = 0; -var p1 = Object.create(HTMLElement.prototype); +class Foo extends HTMLElement +{ + connectedCallback() { + connectedCallbackCount++; + } -p1.createdCallback = function() { - createdCallbackCount++; -}; - -p1.attachedCallback = function() { - attachedCallbackCount++; -}; + disconnectedCallback() { + disconnectedCallbackCount++; + } -p1.detachedCallback = function() { - detachedCallbackCount++; -}; + attributeChangedCallback(aName, aOldValue, aNewValue) { + attributeChangedCallbackCount++; + } -p1.attributeChangedCallback = function(name, oldValue, newValue) { - attributeChangedCallbackCount++; -}; + static get observedAttributes() { + return ["data-foo"]; + } +} -document.registerElement("x-foo", { prototype: p1 }); +customElements.define("x-foo", Foo); var container = document.getElementById("container"); var shadow = container.createShadowRoot(); - -is(createdCallbackCount, 0, "createdCallback should not be called more than once in this test."); var customElem = document.createElement("x-foo"); -is(createdCallbackCount, 1, "createdCallback should be called after creating custom element."); is(attributeChangedCallbackCount, 0, "attributeChangedCallback should not be called after just creating an element."); customElem.setAttribute("data-foo", "bar"); is(attributeChangedCallbackCount, 1, "attributeChangedCallback should be called after setting an attribute."); -is(attachedCallbackCount, 0, "attachedCallback should not be called on an element that is not in a document/composed document."); +is(connectedCallbackCount, 0, "connectedCallback should not be called on an element that is not in a document/composed document."); shadow.appendChild(customElem); -is(attachedCallbackCount, 1, "attachedCallback should be called after attaching custom element to the composed document."); +is(connectedCallbackCount, 1, "connectedCallback should be called after attaching custom element to the composed document."); -is(detachedCallbackCount, 0, "detachedCallback should not be called without detaching custom element."); +is(disconnectedCallbackCount, 0, "disconnectedCallback should not be called without detaching custom element."); shadow.removeChild(customElem); -is(detachedCallbackCount, 1, "detachedCallback should be called after detaching custom element from the composed document."); +is(disconnectedCallbackCount, 1, "disconnectedCallback should be called after detaching custom element from the composed document."); // Test callback for custom element already in the composed doc when created. -createdCallbackCount = 0; -attachedCallbackCount = 0; -detachedCallbackCount = 0; +connectedCallbackCount = 0; +disconnectedCallbackCount = 0; attributeChangedCallbackCount = 0; shadow.innerHTML = "<x-foo></x-foo>"; -is(createdCallbackCount, 1, "createdCallback should be called after creating a custom element."); -is(attachedCallbackCount, 1, "attachedCallback should be called after creating an element in the composed document."); +is(connectedCallbackCount, 1, "connectedCallback should be called after creating an element in the composed document."); shadow.innerHTML = ""; -is(detachedCallbackCount, 1, "detachedCallback should be called after detaching custom element from the composed document."); +is(disconnectedCallbackCount, 1, "disconnectedCallback should be called after detaching custom element from the composed document."); // Test callback for custom element in shadow DOM when host attached/detached to/from document. -createdCallbackCount = 0; -attachedCallbackCount = 0; -detachedCallbackCount = 0; +connectedCallbackCount = 0; +disconnectedCallbackCount = 0; attributeChangedCallbackCount = 0; var host = document.createElement("div"); shadow = host.createShadowRoot(); customElem = document.createElement("x-foo"); -is(attachedCallbackCount, 0, "attachedCallback should not be called on newly created element."); +is(connectedCallbackCount, 0, "connectedCallback should not be called on newly created element."); shadow.appendChild(customElem); -is(attachedCallbackCount, 0, "attachedCallback should not be called on attaching to a tree that is not in the composed document."); +is(connectedCallbackCount, 0, "connectedCallback should not be called on attaching to a tree that is not in the composed document."); -is(attachedCallbackCount, 0, "detachedCallback should not be called."); +is(disconnectedCallbackCount, 0, "disconnectedCallback should not be called."); shadow.removeChild(customElem); -is(detachedCallbackCount, 0, "detachedCallback should not be called when detaching from a tree that is not in the composed document."); +is(disconnectedCallbackCount, 0, "disconnectedCallback should not be called when detaching from a tree that is not in the composed document."); shadow.appendChild(customElem); -is(attachedCallbackCount, 0, "attachedCallback should still not be called after reattaching to a shadow tree that is not in the composed document."); +is(connectedCallbackCount, 0, "connectedCallback should still not be called after reattaching to a shadow tree that is not in the composed document."); container.appendChild(host); -is(attachedCallbackCount, 1, "attachedCallback should be called after host is inserted into document."); +is(connectedCallbackCount, 1, "connectedCallback should be called after host is inserted into document."); container.removeChild(host); -is(detachedCallbackCount, 1, "detachedCallback should be called after host is removed from document."); +is(disconnectedCallbackCount, 1, "disconnectedCallback should be called after host is removed from document."); // Test callback for custom element for upgraded element. -createdCallbackCount = 0; -attachedCallbackCount = 0; -detachedCallbackCount = 0; +connectedCallbackCount = 0; +disconnectedCallbackCount = 0; attributeChangedCallbackCount = 0; shadow = container.shadowRoot; shadow.innerHTML = "<x-bar></x-bar>"; var p2 = Object.create(HTMLElement.prototype); -p2.createdCallback = function() { - createdCallbackCount++; -}; - -p2.attachedCallback = function() { - attachedCallbackCount++; +p2.connectedCallback = function() { + connectedCallbackCount++; }; document.registerElement("x-bar", { prototype: p2 }); -is(createdCallbackCount, 1, "createdCallback should be called after registering element."); -is(attachedCallbackCount, 1, "attachedCallback should be called after upgrading element in composed document."); +is(connectedCallbackCount, 1, "connectedCallback should be called after upgrading element in composed document."); </script> </body> </html>
rename from dom/tests/mochitest/webcomponents/test_document_register_lifecycle.html rename to dom/tests/mochitest/webcomponents/test_custom_element_lifecycle.html --- a/dom/tests/mochitest/webcomponents/test_document_register_lifecycle.html +++ b/dom/tests/mochitest/webcomponents/test_custom_element_lifecycle.html @@ -18,295 +18,273 @@ https://bugzilla.mozilla.org/show_bug.cg var container = document.getElementById("container"); // Tests callbacks after registering element type that is already in the document. // create element in document -> register -> remove from document function testRegisterUnresolved() { var helloElem = document.getElementById("hello"); - var createdCallbackCalled = false; - var attachedCallbackCalled = false; - var detachedCallbackCalled = false; + var connectedCallbackCalled = false; + var disconnectedCallbackCalled = false; var p = Object.create(HTMLElement.prototype); - p.createdCallback = function() { - is(helloElem.__proto__, p, "Prototype should be adjusted just prior to invoking the created callback."); - is(createdCallbackCalled, false, "Created callback should only be called once in this tests."); + p.connectedCallback = function() { + is(connectedCallbackCalled, false, "Connected callback should only be called once in this test."); is(this, helloElem, "The 'this' value should be the custom element."); - createdCallbackCalled = true; + connectedCallbackCalled = true; }; - p.attachedCallback = function() { - is(createdCallbackCalled, true, "Created callback should be called before attached"); - is(attachedCallbackCalled, false, "attached callback should only be called once in this test."); - is(this, helloElem, "The 'this' value should be the custom element."); - attachedCallbackCalled = true; - }; - - p.detachedCallback = function() { - is(attachedCallbackCalled, true, "attached callback should be called before detached"); - is(detachedCallbackCalled, false, "detached callback should only be called once in this test."); - detachedCallbackCalled = true; + p.disconnectedCallback = function() { + is(connectedCallbackCalled, true, "Connected callback should be called before detached"); + is(disconnectedCallbackCalled, false, "Disconnected callback should only be called once in this test."); + disconnectedCallbackCalled = true; is(this, helloElem, "The 'this' value should be the custom element."); runNextTest(); }; p.attributeChangedCallback = function(name, oldValue, newValue) { ok(false, "attributeChanged callback should never be called in this test."); }; document.registerElement("x-hello", { prototype: p }); - is(createdCallbackCalled, true, "created callback should be called when control returns to script from user agent code"); - // Remove element from document to trigger detached callback. + // Remove element from document to trigger disconnected callback. container.removeChild(helloElem); } // Tests callbacks after registering an extended element type that is already in the document. // create element in document -> register -> remove from document function testRegisterUnresolvedExtended() { var buttonElem = document.getElementById("extbutton"); - var createdCallbackCalled = false; - var attachedCallbackCalled = false; - var detachedCallbackCalled = false; + var connectedCallbackCalled = false; + var disconnectedCallbackCalled = false; var p = Object.create(HTMLButtonElement.prototype); - p.createdCallback = function() { - is(buttonElem.__proto__, p, "Prototype should be adjusted just prior to invoking the created callback."); - is(createdCallbackCalled, false, "Created callback should only be called once in this tests."); + p.connectedCallback = function() { + is(connectedCallbackCalled, false, "Connected callback should only be called once in this test."); is(this, buttonElem, "The 'this' value should be the custom element."); - createdCallbackCalled = true; + connectedCallbackCalled = true; }; - p.attachedCallback = function() { - is(createdCallbackCalled, true, "Created callback should be called before attached"); - is(attachedCallbackCalled, false, "attached callback should only be called once in this test."); - is(this, buttonElem, "The 'this' value should be the custom element."); - attachedCallbackCalled = true; - }; - - p.detachedCallback = function() { - is(attachedCallbackCalled, true, "attached callback should be called before detached"); - is(detachedCallbackCalled, false, "detached callback should only be called once in this test."); - detachedCallbackCalled = true; + p.disconnectedCallback = function() { + is(connectedCallbackCalled, true, "Connected callback should be called before detached"); + is(disconnectedCallbackCalled, false, "Disconnected callback should only be called once in this test."); + disconnectedCallbackCalled = true; is(this, buttonElem, "The 'this' value should be the custom element."); runNextTest(); }; p.attributeChangedCallback = function(name, oldValue, newValue) { ok(false, "attributeChanged callback should never be called in this test."); }; document.registerElement("x-button", { prototype: p, extends: "button" }); - is(createdCallbackCalled, true, "created callback should be called when control returns to script from user agent code"); - // Remove element from document to trigger detached callback. + // Remove element from document to trigger disconnected callback. container.removeChild(buttonElem); } function testInnerHTML() { - var createdCallbackCalled = false; + var connectedCallbackCalled = false; var p = Object.create(HTMLElement.prototype); - p.createdCallback = function() { - is(createdCallbackCalled, false, "created callback should only be called once in this test."); - createdCallbackCalled = true; + p.connectedCallback = function() { + is(connectedCallbackCalled, false, "Connected callback should only be called once in this test."); + connectedCallbackCalled = true; }; document.registerElement("x-inner-html", { prototype: p }); var div = document.createElement(div); + document.documentElement.appendChild(div); div.innerHTML = '<x-inner-html></x-inner-html>'; - is(createdCallbackCalled, true, "created callback should be called after setting innerHTML."); + is(connectedCallbackCalled, true, "Connected callback should be called after setting innerHTML."); runNextTest(); } function testInnerHTMLExtended() { - var createdCallbackCalled = false; + var connectedCallbackCalled = false; var p = Object.create(HTMLButtonElement.prototype); - p.createdCallback = function() { - is(createdCallbackCalled, false, "created callback should only be called once in this test."); - createdCallbackCalled = true; + p.connectedCallback = function() { + is(connectedCallbackCalled, false, "Connected callback should only be called once in this test."); + connectedCallbackCalled = true; }; document.registerElement("x-inner-html-extended", { prototype: p, extends: "button" }); var div = document.createElement(div); + document.documentElement.appendChild(div); div.innerHTML = '<button is="x-inner-html-extended"></button>'; - is(createdCallbackCalled, true, "created callback should be called after setting innerHTML."); + is(connectedCallbackCalled, true, "Connected callback should be called after setting innerHTML."); runNextTest(); } function testInnerHTMLUpgrade() { - var createdCallbackCalled = false; + var connectedCallbackCalled = false; var div = document.createElement(div); + document.documentElement.appendChild(div); div.innerHTML = '<x-inner-html-upgrade></x-inner-html-upgrade>'; var p = Object.create(HTMLElement.prototype); - p.createdCallback = function() { - is(createdCallbackCalled, false, "created callback should only be called once in this test."); - createdCallbackCalled = true; + p.connectedCallback = function() { + is(connectedCallbackCalled, false, "Connected callback should only be called once in this test."); + connectedCallbackCalled = true; }; document.registerElement("x-inner-html-upgrade", { prototype: p }); - is(createdCallbackCalled, true, "created callback should be called after registering."); + is(connectedCallbackCalled, true, "Connected callback should be called after registering."); runNextTest(); } function testInnerHTMLExtendedUpgrade() { - var createdCallbackCalled = false; + var connectedCallbackCalled = false; var div = document.createElement(div); + document.documentElement.appendChild(div); div.innerHTML = '<button is="x-inner-html-extended-upgrade"></button>'; var p = Object.create(HTMLButtonElement.prototype); - p.createdCallback = function() { - is(createdCallbackCalled, false, "created callback should only be called once in this test."); - createdCallbackCalled = true; + p.connectedCallback = function() { + is(connectedCallbackCalled, false, "Connected callback should only be called once in this test."); + connectedCallbackCalled = true; }; document.registerElement("x-inner-html-extended-upgrade", { prototype: p, extends: "button" }); - is(createdCallbackCalled, true, "created callback should be called after registering."); + is(connectedCallbackCalled, true, "Connected callback should be called after registering."); runNextTest(); } // Test callback when creating element after registering an element type. // register -> create element -> insert into document -> remove from document function testRegisterResolved() { - var createdCallbackCalled = false; - var attachedCallbackCalled = false; - var detachedCallbackCalled = false; - - var createdCallbackThis; + var connectedCallbackCalled = false; + var disconnectedCallbackCalled = false; var p = Object.create(HTMLElement.prototype); - p.createdCallback = function() { - is(createdCallbackCalled, false, "Created callback should only be called once in this test."); - createdCallbackThis = this; - createdCallbackCalled = true; + p.connectedCallback = function() { + is(connectedCallbackCalled, false, "Connected callback should only be called on in this test."); + is(this, createdElement, "The 'this' value should be the custom element."); + connectedCallbackCalled = true; }; - p.attachedCallback = function() { - is(createdCallbackCalled, true, "created callback should be called before attached callback."); - is(attachedCallbackCalled, false, "attached callback should only be called on in this test."); + p.disconnectedCallback = function() { + is(connectedCallbackCalled, true, "Connected callback should be called before detached"); + is(disconnectedCallbackCalled, false, "Disconnected callback should only be called once in this test."); is(this, createdElement, "The 'this' value should be the custom element."); - attachedCallbackCalled = true; - }; - - p.detachedCallback = function() { - is(attachedCallbackCalled, true, "attached callback should be called before detached"); - is(detachedCallbackCalled, false, "detached callback should only be called once in this test."); - is(this, createdElement, "The 'this' value should be the custom element."); - detachedCallbackCalled = true; + disconnectedCallbackCalled = true; runNextTest(); }; p.attributeChangedCallback = function() { ok(false, "attributeChanged callback should never be called in this test."); }; document.registerElement("x-resolved", { prototype: p }); - is(createdCallbackCalled, false, "Created callback should not be called when custom element instance has not been created."); var createdElement = document.createElement("x-resolved"); - is(createdCallbackThis, createdElement, "The 'this' value in the created callback should be the custom element."); is(createdElement.__proto__, p, "Prototype of custom element should be the registered prototype."); // Insert element into document to trigger attached callback. container.appendChild(createdElement); // Remove element from document to trigger detached callback. container.removeChild(createdElement); } // Callbacks should always be the same ones when registered. function testChangingCallback() { - var p = Object.create(HTMLElement.prototype); var callbackCalled = false; - p.attributeChangedCallback = function(name, oldValue, newValue) { - is(callbackCalled, false, "Callback should only be called once in this test."); - callbackCalled = true; - runNextTest(); - }; + + class TestCallback extends HTMLElement + { + attributeChangedCallback(aName, aOldValue, aNewValue) { + is(callbackCalled, false, "Callback should only be called once in this test."); + callbackCalled = true; + runNextTest(); + } - document.registerElement("x-test-callback", { prototype: p }); + static get observedAttributes() { + return ["data-foo"]; + } + } - p.attributeChangedCallback = function(name, oldValue, newValue) { + customElements.define("x-test-callback", TestCallback); + + TestCallback.prototype.attributeChangedCallback = function(name, oldValue, newValue) { ok(false, "Only callbacks at registration should be called."); }; var elem = document.createElement("x-test-callback"); - elem.setAttribute("foo", "bar"); + elem.setAttribute("data-foo", "bar"); } function testAttributeChanged() { - var createdCallbackCalled = false; - var createdElement; - var createdCallbackThis; - - var p = Object.create(HTMLElement.prototype); - p.createdCallback = function() { - is(createdCallbackCalled, false, "Created callback should only be called once in this test."); - createdCallbackThis = this; - createdCallbackCalled = true; - }; - // Sequence of callback arguments that we expect from attribute changed callback // after changing attributes values in a specific order. var expectedCallbackArguments = [ // [oldValue, newValue] [null, "newvalue"], // Setting the attribute value to "newvalue" ["newvalue", "nextvalue"], // Changing the attribute value from "newvalue" to "nextvalue" ["nextvalue", ""], // Changing the attribute value from "nextvalue" to empty string ["", null], // Removing the attribute. ]; - p.attributeChangedCallback = function(name, oldValue, newValue) { - is(createdCallbackCalled, true, "created callback should be called before attribute changed."); - is(this, createdElement, "The 'this' value should be the custom element."); - ok(expectedCallbackArguments.length > 0, "Attribute changed callback should not be called more than expected."); + class AttrChange extends HTMLElement + { + attributeChangedCallback(name, oldValue, newValue) { + is(this, createdElement, "The 'this' value should be the custom element."); + ok(expectedCallbackArguments.length > 0, "Attribute changed callback should not be called more than expected."); - is(name, "changeme", "name arugment in attribute changed callback should be the name of the changed attribute."); + is(name, "changeme", "name arugment in attribute changed callback should be the name of the changed attribute."); - var expectedArgs = expectedCallbackArguments.shift(); - is(oldValue, expectedArgs[0], "The old value argument should match the expected value."); - is(newValue, expectedArgs[1], "The new value argument should match the expected value."); + var expectedArgs = expectedCallbackArguments.shift(); + is(oldValue, expectedArgs[0], "The old value argument should match the expected value."); + is(newValue, expectedArgs[1], "The new value argument should match the expected value."); - if (expectedCallbackArguments.length === 0) { - // Done with the attribute changed callback test. - runNextTest(); + if (expectedCallbackArguments.length === 0) { + // Done with the attribute changed callback test. + runNextTest(); + } } - }; - document.registerElement("x-attrchange", { prototype: p }); + static get observedAttributes() { + return ["changeme"]; + } + } - var createdElement = document.createElement("x-attrchange"); - is(createdCallbackThis, createdElement, "The 'this' value in the created callback should be the custom element."); + customElements.define("x-attrchange", AttrChange); + + createdElement = document.createElement("x-attrchange"); createdElement.setAttribute("changeme", "newvalue"); createdElement.setAttribute("changeme", "nextvalue"); createdElement.setAttribute("changeme", ""); createdElement.removeAttribute("changeme"); } function testAttributeChangedExtended() { - var p = Object.create(HTMLButtonElement.prototype); - var callbackCalled = 0; - p.attributeChangedCallback = function(name, oldValue, newValue) { - callbackCalled++; - if (callbackCalled > 2) { - is(false, "Got unexpected attribute changed callback."); - } else if (callbackCalled === 2) { + var callbackCalled = false; + + class ExtnededAttributeChange extends HTMLButtonElement + { + attributeChangedCallback(name, oldValue, newValue) { + is(callbackCalled, false, "Callback should only be called once in this test."); + callbackCalled = true; runNextTest(); } - }; - document.registerElement("x-extended-attribute-change", { prototype: p, extends: "button" }); + static get observedAttributes() { + return ["foo"]; + } + } + + customElements.define("x-extended-attribute-change", ExtnededAttributeChange, + { extends: "button" }); var elem = document.createElement("button", {is: "x-extended-attribute-change"}); elem.setAttribute("foo", "bar"); } // Creates a custom element that is an upgrade candidate (no registration) // and mutate the element in ways that would call callbacks for registered // elements. @@ -341,37 +319,37 @@ function testNotInDocEnterLeave() { var divNotInDoc = document.createElement("div"); divNotInDoc.appendChild(createdElement); divNotInDoc.removeChild(createdElement); runNextTest(); } function testEnterLeaveView() { - var attachedCallbackCalled = false; - var detachedCallbackCalled = false; + var connectedCallbackCalled = false; + var disconnectedCallbackCalled = false; var p = Object.create(HTMLElement.prototype); - p.attachedCallback = function() { - is(attachedCallbackCalled, false, "attached callback should only be called on in this test."); - attachedCallbackCalled = true; + p.connectedCallback = function() { + is(connectedCallbackCalled, false, "Connected callback should only be called on in this test."); + connectedCallbackCalled = true; }; - p.detachedCallback = function() { - is(attachedCallbackCalled, true, "attached callback should be called before detached"); - is(detachedCallbackCalled, false, "detached callback should only be called once in this test."); - detachedCallbackCalled = true; + p.disconnectedCallback = function() { + is(connectedCallbackCalled, true, "Connected callback should be called before detached"); + is(disconnectedCallbackCalled, false, "Disconnected callback should only be called once in this test."); + disconnectedCallbackCalled = true; runNextTest(); }; var div = document.createElement("div"); document.registerElement("x-element-in-div", { prototype: p }); var customElement = document.createElement("x-element-in-div"); div.appendChild(customElement); - is(attachedCallbackCalled, false, "Appending a custom element to a node that is not in the document should not call the attached callback."); + is(connectedCallbackCalled, false, "Appending a custom element to a node that is not in the document should not call the connected callback."); container.appendChild(div); container.removeChild(div); } var testFunctions = [ testRegisterUnresolved, testRegisterUnresolvedExtended, @@ -387,16 +365,17 @@ var testFunctions = [ testNotInDocEnterLeave, testEnterLeaveView, SimpleTest.finish ]; function runNextTest() { if (testFunctions.length > 0) { var nextTestFunction = testFunctions.shift(); + info(`Start ${nextTestFunction.name} ...`); nextTestFunction(); } } SimpleTest.waitForExplicitFinish(); runNextTest();
rename from dom/tests/mochitest/webcomponents/test_document_register_stack.html rename to dom/tests/mochitest/webcomponents/test_custom_element_stack.html --- a/dom/tests/mochitest/webcomponents/test_document_register_stack.html +++ b/dom/tests/mochitest/webcomponents/test_custom_element_stack.html @@ -11,139 +11,124 @@ https://bugzilla.mozilla.org/show_bug.cg <body> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=783129">Bug 783129</a> <div id="container"> </div> <script> var container = document.getElementById("container"); -// Test changing attributes in the created callback on an element -// created after registration. -function testChangeAttributeInCreatedCallback() { - var createdCallbackCalled = false; +function testChangeAttributeInEnteredViewCallback() { var attributeChangedCallbackCalled = false; - - var p = Object.create(HTMLElement.prototype); - p.createdCallback = function() { - is(createdCallbackCalled, false, "Created callback should be called before attached callback."); - createdCallbackCalled = true; - is(attributeChangedCallbackCalled, false, "Attribute changed callback should not have been called prior to setting the attribute."); - this.setAttribute("foo", "bar"); - is(attributeChangedCallbackCalled, true, "While element is being created, element should be added to the current element callback queue."); - runNextTest(); - }; - - p.attributeChangedCallback = function(name, oldValue, newValue) { - is(createdCallbackCalled, true, "attributeChanged callback should be called after the created callback because it was enqueued during created callback."); - is(attributeChangedCallbackCalled, false, "attributeChanged callback should only be called once in this tests."); - is(newValue, "bar", "The new value should be 'bar'"); - attributeChangedCallbackCalled = true; - }; + var connectedCallbackCalled = false; - document.registerElement("x-one", { prototype: p }); - document.createElement("x-one"); -} - -function testChangeAttributeInEnteredViewCallback() { - var p = Object.create(HTMLElement.prototype); - var attributeChangedCallbackCalled = false; - var attachedCallbackCalled = false; + class Two extends HTMLElement + { + connectedCallback() { + is(connectedCallbackCalled, false, "Connected callback should be called only once in this test."); + connectedCallbackCalled = true; + is(attributeChangedCallbackCalled, false, "Attribute changed callback should not be called before changing attribute."); + this.setAttribute("foo", "bar"); + is(attributeChangedCallbackCalled, true, "Transition from user-agent implementation to script should result in attribute changed callback being called."); + runNextTest(); + } - p.attachedCallback = function() { - is(attachedCallbackCalled, false, "attached callback should be called only once in this test."); - attachedCallbackCalled = true; - is(attributeChangedCallbackCalled, false, "Attribute changed callback should not be called before changing attribute."); - this.setAttribute("foo", "bar"); - is(attributeChangedCallbackCalled, true, "Transition from user-agent implementation to script should result in attribute changed callback being called."); - runNextTest(); - }; + attributeChangedCallback() { + is(connectedCallbackCalled, true, "Connected callback should have been called prior to attribute changed callback."); + is(attributeChangedCallbackCalled, false, "Attribute changed callback should only be called once in this tests."); + attributeChangedCallbackCalled = true; + } - p.attributeChangedCallback = function() { - is(attachedCallbackCalled, true, "attached callback should have been called prior to attribute changed callback."); - is(attributeChangedCallbackCalled, false, "attributeChanged callback should only be called once in this tests."); - attributeChangedCallbackCalled = true; - }; + static get observedAttributes() { + return ["foo"]; + } + } - document.registerElement("x-two", { prototype: p }); + customElements.define("x-two", Two); var elem = document.createElement("x-two"); var container = document.getElementById("container"); container.appendChild(elem); } function testLeaveViewInEnteredViewCallback() { var p = Object.create(HTMLElement.prototype); - var attachedCallbackCalled = false; - var detachedCallbackCalled = false; + var connectedCallbackCalled = false; + var disconnectedCallbackCalled = false; var container = document.getElementById("container"); - p.attachedCallback = function() { + p.connectedCallback = function() { is(this.parentNode, container, "Parent node should the container in which the node was appended."); - is(attachedCallbackCalled, false, "attached callback should be called only once in this test."); - attachedCallbackCalled = true; - is(detachedCallbackCalled, false, "detached callback should not be called prior to removing element from document."); + is(connectedCallbackCalled, false, "Connected callback should be called only once in this test."); + connectedCallbackCalled = true; + is(disconnectedCallbackCalled, false, "Disconnected callback should not be called prior to removing element from document."); container.removeChild(this); - is(detachedCallbackCalled, true, "Transition from user-agent implementation to script should run left view callback."); + is(disconnectedCallbackCalled, true, "Transition from user-agent implementation to script should run left view callback."); runNextTest(); }; - p.detachedCallback = function() { - is(detachedCallbackCalled, false, "The detached callback should only be called once in this test."); - is(attachedCallbackCalled, true, "The attached callback should be called prior to detached callback."); - detachedCallbackCalled = true; + p.disconnectedCallback = function() { + is(disconnectedCallbackCalled, false, "The disconnected callback should only be called once in this test."); + is(connectedCallbackCalled, true, "The connected callback should be called prior to disconnected callback."); + disconnectedCallbackCalled = true; }; document.registerElement("x-three", { prototype: p }); var elem = document.createElement("x-three"); container.appendChild(elem); } function testStackedAttributeChangedCallback() { - var p = Object.create(HTMLElement.prototype); var attributeChangedCallbackCount = 0; var attributeSequence = ["foo", "bar", "baz"]; - p.attributeChangedCallback = function(attrName, oldValue, newValue) { - if (newValue == "baz") { - return; + class Four extends HTMLElement + { + attributeChangedCallback(attrName, oldValue, newValue) { + if (newValue == "baz") { + return; + } + + var nextAttribute = attributeSequence.shift(); + ok(true, nextAttribute); + // Setting this attribute will call this function again, when + // control returns to the script, the last attribute in the sequence should + // be set on the element. + this.setAttribute("foo", nextAttribute); + is(this.getAttribute("foo"), "baz", "The last value in the sequence should be the value of the attribute."); + + attributeChangedCallbackCount++; + if (attributeChangedCallbackCount == 3) { + runNextTest(); + } } - var nextAttribute = attributeSequence.shift(); - ok(true, nextAttribute); - // Setting this attribute will call this function again, when - // control returns to the script, the last attribute in the sequence should - // be set on the element. - this.setAttribute("foo", nextAttribute); - is(this.getAttribute("foo"), "baz", "The last value in the sequence should be the value of the attribute."); + static get observedAttributes() { + return ["foo"]; + } + } - attributeChangedCallbackCount++; - if (attributeChangedCallbackCount == 3) { - runNextTest(); - } - }; - - document.registerElement("x-four", { prototype: p }); + customElements.define("x-four", Four); var elem = document.createElement("x-four"); elem.setAttribute("foo", "changeme"); } var testFunctions = [ - testChangeAttributeInCreatedCallback, testChangeAttributeInEnteredViewCallback, testLeaveViewInEnteredViewCallback, testStackedAttributeChangedCallback, SimpleTest.finish ]; function runNextTest() { if (testFunctions.length > 0) { var nextTestFunction = testFunctions.shift(); + info(`Start ${nextTestFunction.name} ...`); nextTestFunction(); } } SimpleTest.waitForExplicitFinish(); runNextTest();