diff options
Diffstat (limited to 'dom/tests/mochitest/webcomponents/test_document_register_stack.html')
-rw-r--r-- | dom/tests/mochitest/webcomponents/test_document_register_stack.html | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/dom/tests/mochitest/webcomponents/test_document_register_stack.html b/dom/tests/mochitest/webcomponents/test_document_register_stack.html new file mode 100644 index 000000000..34f108654 --- /dev/null +++ b/dom/tests/mochitest/webcomponents/test_document_register_stack.html @@ -0,0 +1,152 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=783129 +--> +<head> + <title>Test for document.registerElement lifecycle callback</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=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; + 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, false, "While element is being created, element should not be added to the current element callback queue."); + }; + + 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; + runNextTest(); + }; + + document.registerElement("x-one", { prototype: p }); + document.createElement("x-one"); +} + +function testChangeAttributeInEnteredViewCallback() { + var p = Object.create(HTMLElement.prototype); + var attributeChangedCallbackCalled = false; + var attachedCallbackCalled = false; + + 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(); + }; + + 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; + }; + + document.registerElement("x-two", { prototype: p }); + 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 container = document.getElementById("container"); + + p.attachedCallback = 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."); + container.removeChild(this); + is(detachedCallbackCalled, 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; + }; + + 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; + } + + 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(); + } + }; + + document.registerElement("x-four", { prototype: p }); + 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(); + nextTestFunction(); + } +} + +SimpleTest.waitForExplicitFinish(); + +runNextTest(); + +</script> +</body> +</html> |