Skip to content

Commit

Permalink
Bug 1723521 - Part 1: Add "precustomized" custom element state; r=smaug
Browse files Browse the repository at this point in the history
  • Loading branch information
EdgarChen committed Aug 10, 2021
1 parent 9f14f15 commit 314227d
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 5 deletions.
12 changes: 11 additions & 1 deletion dom/base/CustomElementRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1143,6 +1143,10 @@ static void DoUpgrade(Element* aElement, CustomElementDefinition* aDefinition,
return;
}

RefPtr<CustomElementData> data = aElement->GetCustomElementData();
MOZ_ASSERT(data, "CustomElementData should exist");
data->mState = CustomElementData::State::ePrecustomized;

JS::Rooted<JS::Value> constructResult(RootingCx());
// Rethrow the exception since it might actually throw the exception from the
// upgrade steps back out to the caller of document.createElement.
Expand Down Expand Up @@ -1223,7 +1227,13 @@ void CustomElementRegistry::Upgrade(Element* aElement,
DoUpgrade(aElement, aDefinition, MOZ_KnownLive(aDefinition->mConstructor),
aRv);
if (aRv.Failed()) {
MOZ_ASSERT(data->mState == CustomElementData::State::eFailed);
MOZ_ASSERT(data->mState == CustomElementData::State::eFailed ||
data->mState == CustomElementData::State::ePrecustomized);
// Spec doesn't set custom element state to failed here, but without this we
// would have inconsistent state on a custom elemet that is failed to
// upgrade, see https://github.com/whatwg/html/issues/6929, and
// https://github.com/web-platform-tests/wpt/pull/29911 for the test.
data->mState = CustomElementData::State::eFailed;
aElement->SetCustomElementDefinition(nullptr);
// Empty element's custom element reaction queue.
data->mReactionQueue.Clear();
Expand Down
2 changes: 1 addition & 1 deletion dom/base/CustomElementRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ struct CustomElementData {
// CustomElementData is only created on the element which is a custom element
// or an upgrade candidate, so the state of an element without
// CustomElementData is "uncustomized".
enum class State { eUndefined, eFailed, eCustom };
enum class State { eUndefined, eFailed, eCustom, ePrecustomized };

explicit CustomElementData(nsAtom* aType);
CustomElementData(nsAtom* aType, State aState);
Expand Down
19 changes: 16 additions & 3 deletions dom/html/nsGenericHTMLElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2882,7 +2882,7 @@ void nsGenericHTMLElement::SetInnerText(const nsAString& aValue) {
mb.NodesAdded();
}

// https://html.spec.whatwg.org/commit-snapshots/b48bb2238269d90ea4f455a52cdf29505aff3df0/#dom-attachinternals
// https://html.spec.whatwg.org/commit-snapshots/53bc3803433e1c817918b83e8a84f3db900031dd/#dom-attachinternals
already_AddRefed<ElementInternals> nsGenericHTMLElement::AttachInternals(
ErrorResult& aRv) {
CustomElementData* ceData = GetCustomElementData();
Expand Down Expand Up @@ -2932,6 +2932,10 @@ already_AddRefed<ElementInternals> nsGenericHTMLElement::AttachInternals(
return nullptr;
}

// If this is not a custom element, i.e. ceData is nullptr, we are unable to
// find a definition and should return earlier above.
MOZ_ASSERT(ceData);

// 5. If element's attached internals is true, then throw an
// "NotSupportedError" DOMException.
if (ceData->HasAttachedInternals()) {
Expand All @@ -2941,10 +2945,19 @@ already_AddRefed<ElementInternals> nsGenericHTMLElement::AttachInternals(
return nullptr;
}

// 6. Set element's attached internals to true.
// 6. If element's custom element state is not "precustomized" or "custom",
// then throw a "NotSupportedError" DOMException.
if (ceData->mState != CustomElementData::State::ePrecustomized &&
ceData->mState != CustomElementData::State::eCustom) {
aRv.ThrowNotSupportedError(
R"(Custom element state is not "precustomized" or "custom".)");
return nullptr;
}

// 7. Set element's attached internals to true.
ceData->AttachedInternals();

// 7. Create a new ElementInternals instance targeting element, and return it.
// 8. Create a new ElementInternals instance targeting element, and return it.
return MakeAndAddRef<ElementInternals>(this);
}

Expand Down

0 comments on commit 314227d

Please sign in to comment.