From 089e114bd55821cb9e1dda67ecd09e615fbd6372 Mon Sep 17 00:00:00 2001 From: Edgar Chen Date: Thu, 22 Dec 2016 11:47:19 +0800 Subject: [PATCH] Bug 1299363 - Part 1: Implement construction stack. r=wchen MozReview-Commit-ID: F59P9r9sRk --HG-- extra : rebase_source : 8195ecaba5f27cdd54572b8dab1575d2424a7d64 extra : histedit_source : 0118b2bfaecf4296e5013cc3ee312619fb32c457 --- dom/base/CustomElementRegistry.h | 6 ++++-- dom/bindings/BindingUtils.cpp | 37 ++++++++++++++++++++++---------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/dom/base/CustomElementRegistry.h b/dom/base/CustomElementRegistry.h index f39fa2dc7e19..f162ffc77307 100644 --- a/dom/base/CustomElementRegistry.h +++ b/dom/base/CustomElementRegistry.h @@ -107,6 +107,8 @@ private: virtual ~CustomElementData() {} }; +#define ALEADY_CONSTRUCTED_MARKER nullptr + // The required information for a custom element as defined in: // https://html.spec.whatwg.org/multipage/scripting.html#custom-element-definition struct CustomElementDefinition @@ -133,8 +135,8 @@ struct CustomElementDefinition // The lifecycle callbacks to call for this custom element. UniquePtr mCallbacks; - // A construction stack. - // TODO: Bug 1287348 - Implement construction stack for upgrading an element + // A construction stack. Use nullptr to represent an "already constructed marker". + nsTArray> mConstructionStack; // The document custom element order. uint32_t mDocOrder; diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp index cbe8d2b58a69..0b2adb04405f 100644 --- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -3671,20 +3671,35 @@ CreateHTMLElement(const GlobalObject& aGlobal, const JS::CallArgs& aCallArgs, // Step 6 and Step 7 are in the code output by CGClassConstructor. // Step 8. - // Construction stack will be implemented in bug 1287348. So we always run - // "construction stack is empty" case for now. - RefPtr element; - if (tag == eHTMLTag_userdefined) { - // Autonomous custom element. - element = NS_NewHTMLElement(nodeInfo.forget()); - } else { - // Customized built-in element. - element = CreateHTMLElement(tag, nodeInfo.forget(), NOT_FROM_PARSER); + nsTArray>& constructionStack = + definition->mConstructionStack; + if (constructionStack.IsEmpty()) { + RefPtr newElement; + if (tag == eHTMLTag_userdefined) { + // Autonomous custom element. + newElement = NS_NewHTMLElement(nodeInfo.forget()); + } else { + // Customized built-in element. + newElement = CreateHTMLElement(tag, nodeInfo.forget(), NOT_FROM_PARSER); + } + + newElement->SetCustomElementData( + new CustomElementData(definition->mType, CustomElementData::State::eCustom)); + + return newElement.forget(); } - element->SetCustomElementData( - new CustomElementData(definition->mType, CustomElementData::State::eCustom)); + // Step 9. + RefPtr& element = constructionStack.LastElement(); + // Step 10. + if (element == ALEADY_CONSTRUCTED_MARKER) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + + // Step 11 is in the code output by CGClassConstructor. + // Step 12 and Step 13. return element.forget(); }