Bug 1299363 - Part 1: Implement construction stack.

Tag UXP Issue #1344
This commit is contained in:
Gaming4JC 2020-01-05 10:26:29 -05:00 committed by Roy Tam
commit c34486aaa0
2 changed files with 30 additions and 13 deletions

View file

@ -106,6 +106,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
@ -132,8 +134,8 @@ struct CustomElementDefinition
// The lifecycle callbacks to call for this custom element.
UniquePtr<mozilla::dom::LifecycleCallbacks> 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<RefPtr<nsGenericHTMLElement>> mConstructionStack;
// The document custom element order.
uint32_t mDocOrder;

View file

@ -3539,20 +3539,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<nsGenericHTMLElement> 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<RefPtr<nsGenericHTMLElement>>& constructionStack =
definition->mConstructionStack;
if (constructionStack.IsEmpty()) {
RefPtr<nsGenericHTMLElement> 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<nsGenericHTMLElement>& 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();
}