diff options
Diffstat (limited to 'dom')
-rw-r--r-- | dom/base/CustomElementRegistry.cpp | 6 | ||||
-rw-r--r-- | dom/base/nsContentCreatorFunctions.h | 4 | ||||
-rw-r--r-- | dom/html/nsHTMLContentSink.cpp | 25 | ||||
-rw-r--r-- | dom/tests/mochitest/webcomponents/mochitest.ini | 3 | ||||
-rw-r--r-- | dom/tests/mochitest/webcomponents/test_document_register_base_queue.html | 48 | ||||
-rw-r--r-- | dom/tests/mochitest/webcomponents/test_document_register_parser.html | 4 |
6 files changed, 31 insertions, 59 deletions
diff --git a/dom/base/CustomElementRegistry.cpp b/dom/base/CustomElementRegistry.cpp index 0f03b16bd..f17c2c7d9 100644 --- a/dom/base/CustomElementRegistry.cpp +++ b/dom/base/CustomElementRegistry.cpp @@ -1044,8 +1044,12 @@ CustomElementReactionsStack::PopAndInvokeElementQueue() // element, see https://github.com/w3c/webcomponents/issues/635. // We usually report the error to entry global in gecko, so just follow the // same behavior here. + // This may be null if it's called from parser, see the case of + // attributeChangedCallback in + // https://html.spec.whatwg.org/multipage/parsing.html#create-an-element-for-the-token + // In that case, the exception of callback reactions will be automatically + // reported in CallSetup. nsIGlobalObject* global = GetEntryGlobal(); - MOZ_ASSERT(global, "Should always have a entry global here!"); InvokeReactions(elementQueue, global); } diff --git a/dom/base/nsContentCreatorFunctions.h b/dom/base/nsContentCreatorFunctions.h index 9576d9ba8..a5c210500 100644 --- a/dom/base/nsContentCreatorFunctions.h +++ b/dom/base/nsContentCreatorFunctions.h @@ -24,6 +24,7 @@ namespace mozilla { namespace dom { class Element; class NodeInfo; +struct CustomElementDefinition; } // namespace dom } // namespace mozilla @@ -41,7 +42,8 @@ nsresult NS_NewHTMLElement(mozilla::dom::Element** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, mozilla::dom::FromParser aFromParser, - const nsAString* aIs = nullptr); + const nsAString* aIs = nullptr, + mozilla::dom::CustomElementDefinition* aDefinition = nullptr); // First argument should be nsHTMLTag, but that adds dependency to parser // for a bunch of files. diff --git a/dom/html/nsHTMLContentSink.cpp b/dom/html/nsHTMLContentSink.cpp index 2827f5ff6..518a3675e 100644 --- a/dom/html/nsHTMLContentSink.cpp +++ b/dom/html/nsHTMLContentSink.cpp @@ -255,7 +255,8 @@ DoCustomElementCreate(Element** aElement, nsIDocument* aDoc, nsIAtom* aLocalName nsresult NS_NewHTMLElement(Element** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, - FromParser aFromParser, const nsAString* aIs) + FromParser aFromParser, const nsAString* aIs, + mozilla::dom::CustomElementDefinition* aDefinition) { *aResult = nullptr; @@ -276,8 +277,8 @@ NS_NewHTMLElement(Element** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& // We only handle the "synchronous custom elements flag is set" now. // For the unset case (e.g. cloning a node), see bug 1319342 for that. // Step 4. - CustomElementDefinition* definition = nullptr; - if (CustomElementRegistry::IsCustomElementEnabled()) { + CustomElementDefinition* definition = aDefinition; + if (!definition && CustomElementRegistry::IsCustomElementEnabled()) { definition = nsContentUtils::LookupCustomElementDefinition(nodeInfo->GetDocument(), nodeInfo->LocalName(), @@ -302,9 +303,20 @@ NS_NewHTMLElement(Element** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& bool synchronousCustomElements = aFromParser != dom::FROM_PARSER_FRAGMENT || aFromParser == dom::NOT_FROM_PARSER; // Per discussion in https://github.com/w3c/webcomponents/issues/635, - // use entry global in those places that are called from JS APIs. - nsIGlobalObject* global = GetEntryGlobal(); - MOZ_ASSERT(global); + // use entry global in those places that are called from JS APIs and use the + // node document's global object if it is called from parser. + nsIGlobalObject* global; + if (aFromParser == dom::NOT_FROM_PARSER) { + global = GetEntryGlobal(); + } else { + global = nodeInfo->GetDocument()->GetScopeObject(); + } + if (!global) { + // In browser chrome code, one may have access to a document which doesn't + // have scope object anymore. + return NS_ERROR_FAILURE; + } + AutoEntryScript aes(global, "create custom elements"); JSContext* cx = aes.cx(); ErrorResult rv; @@ -344,6 +356,7 @@ NS_NewHTMLElement(Element** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& // Step 6.2. NS_IF_ADDREF(*aResult = NS_NewHTMLElement(nodeInfo.forget(), aFromParser)); + (*aResult)->SetCustomElementData(new CustomElementData(definition->mType)); nsContentUtils::EnqueueUpgradeReaction(*aResult, definition); return NS_OK; } diff --git a/dom/tests/mochitest/webcomponents/mochitest.ini b/dom/tests/mochitest/webcomponents/mochitest.ini index e8f632e39..b32e9999e 100644 --- a/dom/tests/mochitest/webcomponents/mochitest.ini +++ b/dom/tests/mochitest/webcomponents/mochitest.ini @@ -10,6 +10,7 @@ support-files = [test_content_element.html] [test_custom_element_adopt_callbacks.html] [test_custom_element_callback_innerhtml.html] +skip-if = true # disabled - See bug 1390396 [test_custom_element_clone_callbacks_extended.html] [test_custom_element_htmlconstructor.html] skip-if = os == 'android' # bug 1323645 @@ -20,6 +21,7 @@ support-files = [test_custom_element_in_shadow.html] skip-if = true || stylo # disabled - See bug 1390396 and 1293844 [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_nested_content_element.html] @@ -31,7 +33,6 @@ skip-if = true || stylo # disabled - See bug 1390396 and 1293844 [test_document_adoptnode.html] [test_document_importnode.html] [test_document_register.html] -[test_document_register_base_queue.html] [test_document_register_lifecycle.html] skip-if = true # disabled - See bug 1390396 [test_document_register_parser.html] diff --git a/dom/tests/mochitest/webcomponents/test_document_register_base_queue.html b/dom/tests/mochitest/webcomponents/test_document_register_base_queue.html deleted file mode 100644 index c839857b4..000000000 --- a/dom/tests/mochitest/webcomponents/test_document_register_base_queue.html +++ /dev/null @@ -1,48 +0,0 @@ -<!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" /> -<script> -var p = Object.create(HTMLElement.prototype); - -var createdCallbackCallCount = 0; - -// By the time the base element queue is processed via the microtask, -// both x-hello elements should be in the document. -p.createdCallback = function() { - var one = document.getElementById("one"); - var two = document.getElementById("two"); - isnot(one, null, "First x-hello element should be in the tree."); - isnot(two, null, "Second x-hello element should be in the tree."); - createdCallbackCallCount++; - if (createdCallbackCallCount == 2) { - SimpleTest.finish(); - } - - if (createdCallbackCallCount > 2) { - ok(false, "Created callback called too much."); - } -}; - -p.attributeChangedCallback = function(name, oldValue, newValue) { - ok(false, "Attribute changed callback should not be called because callbacks should not be queued until created callback invoked."); -}; - -document.registerElement("x-hello", { prototype: p }); - -SimpleTest.waitForExplicitFinish(); -</script> -</head> -<body> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=783129">Bug 783129</a> -<x-hello id="one"></x-hello> -<x-hello id="two"></x-hello> -<script> -</script> -</body> -</html> diff --git a/dom/tests/mochitest/webcomponents/test_document_register_parser.html b/dom/tests/mochitest/webcomponents/test_document_register_parser.html index bc4cdcbac..a4fb63139 100644 --- a/dom/tests/mochitest/webcomponents/test_document_register_parser.html +++ b/dom/tests/mochitest/webcomponents/test_document_register_parser.html @@ -11,7 +11,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=783129 var extendedButtonProto = Object.create(HTMLButtonElement.prototype); var buttonCallbackCalled = false; -extendedButtonProto.createdCallback = function() { +extendedButtonProto.connectedCallback = function() { is(buttonCallbackCalled, false, "created callback for x-button should only be called once."); is(this.tagName, "BUTTON", "Only the <button> element should be upgraded."); buttonCallbackCalled = true; @@ -21,7 +21,7 @@ document.registerElement("x-button", { prototype: extendedButtonProto, extends: var divProto = Object.create(HTMLDivElement.prototype); var divCallbackCalled = false; -divProto.createdCallback = function() { +divProto.connectedCallback = function() { is(divCallbackCalled, false, "created callback for x-div should only be called once."); is(buttonCallbackCalled, true, "crated callback should be called for x-button before x-div."); is(this.tagName, "X-DIV", "Only the <x-div> element should be upgraded."); |