Bug 1406325 - Part 4: Use mType for LookupCustomElementDefinition and also removing parts of v0.

Tag UXP Issue #1344
This commit is contained in:
Gaming4JC 2020-01-19 22:59:16 -05:00 • committed by Roy Tam
commit db3b6b5884
8 changed files with 34 additions and 112 deletions

View file

@ -36,7 +36,6 @@ CustomElementCallback::Call()
nsIDocument* document = mThisObject->GetComposedDoc(); nsIDocument* document = mThisObject->GetComposedDoc();
if (document) { if (document) {
NodeInfo* ni = mThisObject->NodeInfo(); NodeInfo* ni = mThisObject->NodeInfo();
nsDependentAtomString extType(mOwnerData->mType);
// We need to do this because at this point, CustomElementDefinition is // We need to do this because at this point, CustomElementDefinition is
// not set to CustomElementData yet, so EnqueueLifecycleCallback will // not set to CustomElementData yet, so EnqueueLifecycleCallback will
@ -45,7 +44,8 @@ CustomElementCallback::Call()
CustomElementDefinition* definition = CustomElementDefinition* definition =
nsContentUtils::LookupCustomElementDefinition(document, nsContentUtils::LookupCustomElementDefinition(document,
ni->LocalName(), ni->NamespaceID(), ni->LocalName(), ni->NamespaceID(),
extType.IsEmpty() ? nullptr : &extType); mOwnerData->GetCustomElementType());
nsContentUtils::EnqueueLifecycleCallback( nsContentUtils::EnqueueLifecycleCallback(
nsIDocument::eConnected, mThisObject, nullptr, nullptr, definition); nsIDocument::eConnected, mThisObject, nullptr, nullptr, definition);
} }
@ -131,10 +131,10 @@ CustomElementData::CustomElementData(nsIAtom* aType)
} }
CustomElementData::CustomElementData(nsIAtom* aType, State aState) CustomElementData::CustomElementData(nsIAtom* aType, State aState)
: mType(aType) : mElementIsBeingCreated(false)
, mElementIsBeingCreated(false)
, mCreatedCallbackInvoked(true) , mCreatedCallbackInvoked(true)
, mState(aState) , mState(aState)
, mType(aType)
{ {
} }
@ -157,6 +157,12 @@ CustomElementData::GetCustomElementDefinition()
return mCustomElementDefinition; return mCustomElementDefinition;
} }
nsIAtom*
CustomElementData::GetCustomElementType()
{
return mType;
}
void void
CustomElementData::Traverse(nsCycleCollectionTraversalCallback& aCb) const CustomElementData::Traverse(nsCycleCollectionTraversalCallback& aCb) const
{ {
@ -274,12 +280,10 @@ CustomElementRegistry::~CustomElementRegistry()
CustomElementDefinition* CustomElementDefinition*
CustomElementRegistry::LookupCustomElementDefinition(const nsAString& aLocalName, CustomElementRegistry::LookupCustomElementDefinition(const nsAString& aLocalName,
const nsAString* aIs) const nsIAtom* aTypeAtom) const
{ {
nsCOMPtr<nsIAtom> localNameAtom = NS_Atomize(aLocalName); nsCOMPtr<nsIAtom> localNameAtom = NS_Atomize(aLocalName);
nsCOMPtr<nsIAtom> typeAtom = aIs ? NS_Atomize(*aIs) : localNameAtom; CustomElementDefinition* data = mCustomDefinitions.GetWeak(aTypeAtom);
CustomElementDefinition* data = mCustomDefinitions.GetWeak(typeAtom);
if (data && data->mLocalName == localNameAtom) { if (data && data->mLocalName == localNameAtom) {
return data; return data;
} }
@ -329,50 +333,6 @@ CustomElementRegistry::RegisterUnresolvedElement(Element* aElement, nsIAtom* aTy
return; return;
} }
void
CustomElementRegistry::SetupCustomElement(Element* aElement,
const nsAString* aTypeExtension)
{
nsCOMPtr<nsIAtom> tagAtom = aElement->NodeInfo()->NameAtom();
nsCOMPtr<nsIAtom> typeAtom = aTypeExtension ?
NS_Atomize(*aTypeExtension) : tagAtom;
if (aTypeExtension && !aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::is)) {
// Custom element setup in the parser happens after the "is"
// attribute is added.
aElement->SetAttr(kNameSpaceID_None, nsGkAtoms::is, *aTypeExtension, true);
}
// SetupCustomElement() should be called with an element that don't have
// CustomElementData setup, if not we will hit the assertion in
// SetCustomElementData().
aElement->SetCustomElementData(new CustomElementData(typeAtom));
CustomElementDefinition* definition = LookupCustomElementDefinition(
aElement->NodeInfo()->LocalName(), aTypeExtension);
if (!definition) {
// The type extension doesn't exist in the registry,
// thus we don't need to enqueue callback or adjust
// the "is" attribute, but it is possibly an upgrade candidate.
RegisterUnresolvedElement(aElement, typeAtom);
return;
}
if (definition->mLocalName != tagAtom) {
// The element doesn't match the local name for the
// definition, thus the element isn't a custom element
// and we don't need to do anything more.
return;
}
// Enqueuing the created callback will set the CustomElementData on the
// element, causing prototype swizzling to occur in Element::WrapObject.
// We make it synchronously for createElement/createElementNS in order to
// pass tests. It'll be removed when we deprecate custom elements v0.
// SyncInvokeReactions(nsIDocument::eCreated, aElement, definition);
}
/* static */ UniquePtr<CustomElementCallback> /* static */ UniquePtr<CustomElementCallback>
CustomElementRegistry::CreateCustomElementCallback( CustomElementRegistry::CreateCustomElementCallback(
nsIDocument::ElementCallbackType aType, Element* aCustomElement, nsIDocument::ElementCallbackType aType, Element* aCustomElement,

View file

@ -112,9 +112,7 @@ struct CustomElementData
explicit CustomElementData(nsIAtom* aType); explicit CustomElementData(nsIAtom* aType);
CustomElementData(nsIAtom* aType, State aState); CustomElementData(nsIAtom* aType, State aState);
// Custom element type, for <button is="x-button"> or <x-button>
// this would be x-button.
nsCOMPtr<nsIAtom> mType;
// Element is being created flag as described in the custom elements spec. // Element is being created flag as described in the custom elements spec.
bool mElementIsBeingCreated; bool mElementIsBeingCreated;
// Flag to determine if the created callback has been invoked, thus it // Flag to determine if the created callback has been invoked, thus it
@ -132,6 +130,7 @@ struct CustomElementData
void SetCustomElementDefinition(CustomElementDefinition* aDefinition); void SetCustomElementDefinition(CustomElementDefinition* aDefinition);
CustomElementDefinition* GetCustomElementDefinition(); CustomElementDefinition* GetCustomElementDefinition();
nsIAtom* GetCustomElementType();
void Traverse(nsCycleCollectionTraversalCallback& aCb) const; void Traverse(nsCycleCollectionTraversalCallback& aCb) const;
void Unlink(); void Unlink();
@ -139,6 +138,9 @@ struct CustomElementData
private: private:
virtual ~CustomElementData() {} virtual ~CustomElementData() {}
// Custom element type, for <button is="x-button"> or <x-button>
// this would be x-button.
RefPtr<nsIAtom> mType;
RefPtr<CustomElementDefinition> mCustomElementDefinition; RefPtr<CustomElementDefinition> mCustomElementDefinition;
}; };
@ -361,18 +363,11 @@ public:
* https://html.spec.whatwg.org/#look-up-a-custom-element-definition * https://html.spec.whatwg.org/#look-up-a-custom-element-definition
*/ */
CustomElementDefinition* LookupCustomElementDefinition( CustomElementDefinition* LookupCustomElementDefinition(
const nsAString& aLocalName, const nsAString* aIs = nullptr) const; const nsAString& aLocalName, nsIAtom* aTypeAtom) const;
CustomElementDefinition* LookupCustomElementDefinition( CustomElementDefinition* LookupCustomElementDefinition(
JSContext* aCx, JSObject *aConstructor) const; JSContext* aCx, JSObject *aConstructor) const;
/**
* Enqueue created callback or register upgrade candidate for
* newly created custom elements, possibly extending an existing type.
* ex. <x-button>, <button is="x-button> (type extension)
*/
void SetupCustomElement(Element* aElement, const nsAString* aTypeExtension);
static void EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType, static void EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
Element* aCustomElement, Element* aCustomElement,
LifecycleCallbackArgs* aArgs, LifecycleCallbackArgs* aArgs,

View file

@ -479,7 +479,7 @@ Element::WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
if (data) { if (data) {
// If this is a registered custom element then fix the prototype. // If this is a registered custom element then fix the prototype.
nsContentUtils::GetCustomPrototype(OwnerDoc(), NodeInfo()->NamespaceID(), nsContentUtils::GetCustomPrototype(OwnerDoc(), NodeInfo()->NamespaceID(),
data->mType, &customProto); data->GetCustomElementType(), &customProto);
if (customProto && if (customProto &&
NodePrincipal()->SubsumesConsideringDomain(nsContentUtils::ObjectPrincipal(customProto))) { NodePrincipal()->SubsumesConsideringDomain(nsContentUtils::ObjectPrincipal(customProto))) {
// Just go ahead and create with the right proto up front. Set // Just go ahead and create with the right proto up front. Set
@ -2590,7 +2590,7 @@ Element::SetAttrAndNotify(int32_t aNamespaceID,
if (CustomElementData* data = GetCustomElementData()) { if (CustomElementData* data = GetCustomElementData()) {
if (CustomElementDefinition* definition = if (CustomElementDefinition* definition =
nsContentUtils::GetElementDefinitionIfObservingAttr(this, nsContentUtils::GetElementDefinitionIfObservingAttr(this,
data->mType, data->GetCustomElementType(),
aName)) { aName)) {
MOZ_ASSERT(data->mState == CustomElementData::State::eCustom, MOZ_ASSERT(data->mState == CustomElementData::State::eCustom,
"AttributeChanged callback should fire only if " "AttributeChanged callback should fire only if "
@ -2860,7 +2860,7 @@ Element::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName,
if (CustomElementData* data = GetCustomElementData()) { if (CustomElementData* data = GetCustomElementData()) {
if (CustomElementDefinition* definition = if (CustomElementDefinition* definition =
nsContentUtils::GetElementDefinitionIfObservingAttr(this, nsContentUtils::GetElementDefinitionIfObservingAttr(this,
data->mType, data->GetCustomElementType(),
aName)) { aName)) {
MOZ_ASSERT(data->mState == CustomElementData::State::eCustom, MOZ_ASSERT(data->mState == CustomElementData::State::eCustom,
"AttributeChanged callback should fire only if " "AttributeChanged callback should fire only if "

View file

@ -9579,7 +9579,7 @@ nsContentUtils::HttpsStateIsModern(nsIDocument* aDocument)
nsContentUtils::LookupCustomElementDefinition(nsIDocument* aDoc, nsContentUtils::LookupCustomElementDefinition(nsIDocument* aDoc,
const nsAString& aLocalName, const nsAString& aLocalName,
uint32_t aNameSpaceID, uint32_t aNameSpaceID,
const nsAString* aIs) nsIAtom* aTypeAtom)
{ {
MOZ_ASSERT(aDoc); MOZ_ASSERT(aDoc);
@ -9601,40 +9601,7 @@ nsContentUtils::LookupCustomElementDefinition(nsIDocument* aDoc,
return nullptr; return nullptr;
} }
return registry->LookupCustomElementDefinition(aLocalName, aIs); return registry->LookupCustomElementDefinition(aLocalName, aTypeAtom);
}
/* static */ void
nsContentUtils::SetupCustomElement(Element* aElement,
const nsAString* aTypeExtension)
{
MOZ_ASSERT(aElement);
nsCOMPtr<nsIDocument> doc = aElement->OwnerDoc();
if (!doc) {
return;
}
// To support imported document.
doc = doc->MasterDocument();
if (aElement->GetNameSpaceID() != kNameSpaceID_XHTML ||
!doc->GetDocShell()) {
return;
}
nsCOMPtr<nsPIDOMWindowInner> window(doc->GetInnerWindow());
if (!window) {
return;
}
RefPtr<CustomElementRegistry> registry(window->CustomElements());
if (!registry) {
return;
}
return registry->SetupCustomElement(aElement, aTypeExtension);
} }
/* static */ CustomElementDefinition* /* static */ CustomElementDefinition*

View file

@ -2719,10 +2719,7 @@ public:
LookupCustomElementDefinition(nsIDocument* aDoc, LookupCustomElementDefinition(nsIDocument* aDoc,
const nsAString& aLocalName, const nsAString& aLocalName,
uint32_t aNameSpaceID, uint32_t aNameSpaceID,
const nsAString* aIs = nullptr); nsIAtom* aTypeAtom);
static void SetupCustomElement(Element* aElement,
const nsAString* aTypeExtension = nullptr);
static mozilla::dom::CustomElementDefinition* static mozilla::dom::CustomElementDefinition*
GetElementDefinitionIfObservingAttr(Element* aCustomElement, GetElementDefinitionIfObservingAttr(Element* aCustomElement,

View file

@ -501,7 +501,7 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
nsContentUtils::LookupCustomElementDefinition(nodeInfo->GetDocument(), nsContentUtils::LookupCustomElementDefinition(nodeInfo->GetDocument(),
nodeInfo->LocalName(), nodeInfo->LocalName(),
nodeInfo->NamespaceID(), nodeInfo->NamespaceID(),
extension.IsEmpty() ? nullptr : &extension); typeAtom);
if (definition) { if (definition) {
nsContentUtils::EnqueueUpgradeReaction(cloneElem, definition); nsContentUtils::EnqueueUpgradeReaction(cloneElem, definition);
} }

View file

@ -267,6 +267,8 @@ NS_NewHTMLElement(Element** aResult, already_AddRefed<mozilla::dom::NodeInfo>&&
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
nsIAtom *name = nodeInfo->NameAtom(); nsIAtom *name = nodeInfo->NameAtom();
RefPtr<nsIAtom> tagAtom = nodeInfo->NameAtom();
RefPtr<nsIAtom> typeAtom = aIs ? NS_Atomize(*aIs) : tagAtom;
NS_ASSERTION(nodeInfo->NamespaceEquals(kNameSpaceID_XHTML), NS_ASSERTION(nodeInfo->NamespaceEquals(kNameSpaceID_XHTML),
"Trying to HTML elements that don't have the XHTML namespace"); "Trying to HTML elements that don't have the XHTML namespace");
@ -283,7 +285,7 @@ NS_NewHTMLElement(Element** aResult, already_AddRefed<mozilla::dom::NodeInfo>&&
nsContentUtils::LookupCustomElementDefinition(nodeInfo->GetDocument(), nsContentUtils::LookupCustomElementDefinition(nodeInfo->GetDocument(),
nodeInfo->LocalName(), nodeInfo->LocalName(),
nodeInfo->NamespaceID(), nodeInfo->NamespaceID(),
aIs); typeAtom);
} }
// It might be a problem that parser synchronously calls constructor, so filed // It might be a problem that parser synchronously calls constructor, so filed
@ -326,8 +328,6 @@ NS_NewHTMLElement(Element** aResult, already_AddRefed<mozilla::dom::NodeInfo>&&
// SetupCustomElement() should be called with an element that don't have // SetupCustomElement() should be called with an element that don't have
// CustomElementData setup, if not we will hit the assertion in // CustomElementData setup, if not we will hit the assertion in
// SetCustomElementData(). // SetCustomElementData().
nsCOMPtr<nsIAtom> tagAtom = nodeInfo->NameAtom();
nsCOMPtr<nsIAtom> typeAtom = aIs ? NS_Atomize(*aIs) : tagAtom;
// Built-in element // Built-in element
*aResult = CreateHTMLElement(tag, nodeInfo.forget(), aFromParser).take(); *aResult = CreateHTMLElement(tag, nodeInfo.forget(), aFromParser).take();
(*aResult)->SetCustomElementData(new CustomElementData(typeAtom)); (*aResult)->SetCustomElementData(new CustomElementData(typeAtom));
@ -377,7 +377,7 @@ NS_NewHTMLElement(Element** aResult, already_AddRefed<mozilla::dom::NodeInfo>&&
if (CustomElementRegistry::IsCustomElementEnabled() && if (CustomElementRegistry::IsCustomElementEnabled() &&
(isCustomElementName || aIs)) { (isCustomElementName || aIs)) {
nsContentUtils::SetupCustomElement(*aResult, aIs); (*aResult)->SetCustomElementData(new CustomElementData(typeAtom));
} }
return NS_OK; return NS_OK;

View file

@ -429,9 +429,12 @@ nsHtml5TreeOperation::CreateHTMLElement(
isCustomElement = (aCreator == NS_NewCustomElement || !isValue.IsEmpty()); isCustomElement = (aCreator == NS_NewCustomElement || !isValue.IsEmpty());
if (isCustomElement && aFromParser != dom::FROM_PARSER_FRAGMENT) { if (isCustomElement && aFromParser != dom::FROM_PARSER_FRAGMENT) {
RefPtr<nsIAtom> tagAtom = nodeInfo->NameAtom();
RefPtr<nsIAtom> typeAtom =
isValue.IsEmpty() ? tagAtom : NS_Atomize(isValue);
definition = nsContentUtils::LookupCustomElementDefinition(document, definition = nsContentUtils::LookupCustomElementDefinition(document,
nodeInfo->LocalName(), nodeInfo->NamespaceID(), nodeInfo->LocalName(), nodeInfo->NamespaceID(), typeAtom);
(isValue.IsEmpty() ? nullptr : &isValue));
if (definition) { if (definition) {
willExecuteScript = true; willExecuteScript = true;