diff options
author | Gaming4JC <g4jc@hyperbola.info> | 2020-01-05 18:15:57 -0500 |
---|---|---|
committer | Gaming4JC <g4jc@hyperbola.info> | 2020-01-26 15:50:30 -0500 |
commit | 8e6ce5fae721e5a4caf38b0b72e1c4a0324ae55e (patch) | |
tree | 1c398b6e727da3fd13829209835ede7a427eac97 /dom/base | |
parent | 6bbb9f062b63c5a920b1d240ba0d8575150dd01a (diff) | |
download | UXP-8e6ce5fae721e5a4caf38b0b72e1c4a0324ae55e.tar UXP-8e6ce5fae721e5a4caf38b0b72e1c4a0324ae55e.tar.gz UXP-8e6ce5fae721e5a4caf38b0b72e1c4a0324ae55e.tar.lz UXP-8e6ce5fae721e5a4caf38b0b72e1c4a0324ae55e.tar.xz UXP-8e6ce5fae721e5a4caf38b0b72e1c4a0324ae55e.zip |
Bug 1121994 - Implement adopted callback for custom elements.
Tag UXP Issue #1344
Diffstat (limited to 'dom/base')
-rw-r--r-- | dom/base/CustomElementRegistry.cpp | 35 | ||||
-rw-r--r-- | dom/base/CustomElementRegistry.h | 19 | ||||
-rw-r--r-- | dom/base/Element.cpp | 8 | ||||
-rw-r--r-- | dom/base/nsContentUtils.cpp | 2 | ||||
-rw-r--r-- | dom/base/nsContentUtils.h | 2 | ||||
-rw-r--r-- | dom/base/nsIDocument.h | 1 | ||||
-rw-r--r-- | dom/base/nsNodeUtils.cpp | 17 |
7 files changed, 73 insertions, 11 deletions
diff --git a/dom/base/CustomElementRegistry.cpp b/dom/base/CustomElementRegistry.cpp index 069611f65..bad100cf5 100644 --- a/dom/base/CustomElementRegistry.cpp +++ b/dom/base/CustomElementRegistry.cpp @@ -47,7 +47,7 @@ CustomElementCallback::Call() ni->LocalName(), ni->NamespaceID(), extType.IsEmpty() ? nullptr : &extType); nsContentUtils::EnqueueLifecycleCallback( - nsIDocument::eConnected, mThisObject, nullptr, definition); + nsIDocument::eConnected, mThisObject, nullptr, nullptr, definition); } static_cast<LifecycleCreatedCallback *>(mCallback.get())->Call(mThisObject, rv); @@ -60,6 +60,10 @@ CustomElementCallback::Call() case nsIDocument::eDisconnected: static_cast<LifecycleDisconnectedCallback *>(mCallback.get())->Call(mThisObject, rv); break; + case nsIDocument::eAdopted: + static_cast<LifecycleAdoptedCallback *>(mCallback.get())->Call(mThisObject, + mAdoptedCallbackArgs.mOldDocument, mAdoptedCallbackArgs.mNewDocument, rv); + break; case nsIDocument::eAttributeChanged: static_cast<LifecycleAttributeChangedCallback *>(mCallback.get())->Call(mThisObject, mArgs.name, mArgs.oldValue, mArgs.newValue, mArgs.namespaceURI, rv); @@ -332,7 +336,9 @@ CustomElementRegistry::SetupCustomElement(Element* aElement, /* static */ UniquePtr<CustomElementCallback> CustomElementRegistry::CreateCustomElementCallback( nsIDocument::ElementCallbackType aType, Element* aCustomElement, - LifecycleCallbackArgs* aArgs, CustomElementDefinition* aDefinition) + LifecycleCallbackArgs* aArgs, + LifecycleAdoptedCallbackArgs* aAdoptedCallbackArgs, + CustomElementDefinition* aDefinition) { MOZ_ASSERT(aDefinition, "CustomElementDefinition should not be null"); @@ -360,6 +366,12 @@ CustomElementRegistry::CreateCustomElementCallback( } break; + case nsIDocument::eAdopted: + if (aDefinition->mCallbacks->mAdoptedCallback.WasPassed()) { + func = aDefinition->mCallbacks->mAdoptedCallback.Value(); + } + break; + case nsIDocument::eAttributeChanged: if (aDefinition->mCallbacks->mAttributeChangedCallback.WasPassed()) { func = aDefinition->mCallbacks->mAttributeChangedCallback.Value(); @@ -388,6 +400,9 @@ CustomElementRegistry::CreateCustomElementCallback( callback->SetArgs(*aArgs); } + if (aAdoptedCallbackArgs) { + callback->SetAdoptedCallbackArgs(*aAdoptedCallbackArgs); + } return Move(callback); } @@ -395,6 +410,7 @@ CustomElementRegistry::CreateCustomElementCallback( CustomElementRegistry::EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType, Element* aCustomElement, LifecycleCallbackArgs* aArgs, + LifecycleAdoptedCallbackArgs* aAdoptedCallbackArgs, CustomElementDefinition* aDefinition) { CustomElementDefinition* definition = aDefinition; @@ -407,7 +423,8 @@ CustomElementRegistry::EnqueueLifecycleCallback(nsIDocument::ElementCallbackType } auto callback = - CreateCustomElementCallback(aType, aCustomElement, aArgs, definition); + CreateCustomElementCallback(aType, aCustomElement, aArgs, + aAdoptedCallbackArgs, definition); if (!callback) { return; } @@ -926,7 +943,7 @@ CustomElementRegistry::Upgrade(Element* aElement, }; nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eAttributeChanged, aElement, - &args, aDefinition); + &args, nullptr, aDefinition); } } } @@ -934,7 +951,7 @@ CustomElementRegistry::Upgrade(Element* aElement, // Step 4. if (aElement->IsInComposedDoc()) { nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eConnected, aElement, - nullptr, aDefinition); + nullptr, nullptr, aDefinition); } // Step 5. @@ -958,7 +975,8 @@ CustomElementRegistry::Upgrade(Element* aElement, // This is for old spec. nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eCreated, - aElement, nullptr, aDefinition); + aElement, nullptr, + nullptr, aDefinition); } //----------------------------------------------------- @@ -1141,6 +1159,11 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CustomElementDefinition) cb.NoteXPCOMChild(callbacks->mDisconnectedCallback.Value()); } + if (callbacks->mAdoptedCallback.WasPassed()) { + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCallbacks->mAdoptedCallback"); + cb.NoteXPCOMChild(callbacks->mAdoptedCallback.Value()); + } + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mConstructor"); cb.NoteXPCOMChild(tmp->mConstructor); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END diff --git a/dom/base/CustomElementRegistry.h b/dom/base/CustomElementRegistry.h index 30e2c00ab..e9b2bee56 100644 --- a/dom/base/CustomElementRegistry.h +++ b/dom/base/CustomElementRegistry.h @@ -38,6 +38,12 @@ struct LifecycleCallbackArgs nsString namespaceURI; }; +struct LifecycleAdoptedCallbackArgs +{ + nsCOMPtr<nsIDocument> mOldDocument; + nsCOMPtr<nsIDocument> mNewDocument; +}; + class CustomElementCallback { public: @@ -54,6 +60,13 @@ public: mArgs = aArgs; } + void SetAdoptedCallbackArgs(LifecycleAdoptedCallbackArgs& aAdoptedCallbackArgs) + { + MOZ_ASSERT(mType == nsIDocument::eAdopted, + "Arguments are only used by adopted callback."); + mAdoptedCallbackArgs = aAdoptedCallbackArgs; + } + private: // The this value to use for invocation of the callback. RefPtr<Element> mThisObject; @@ -63,6 +76,7 @@ private: // Arguments to be passed to the callback, // used by the attribute changed callback. LifecycleCallbackArgs mArgs; + LifecycleAdoptedCallbackArgs mAdoptedCallbackArgs; // CustomElementData that contains this callback in the // callback queue. CustomElementData* mOwnerData; @@ -365,6 +379,7 @@ public: static void EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType, Element* aCustomElement, LifecycleCallbackArgs* aArgs, + LifecycleAdoptedCallbackArgs* aAdoptedCallbackArgs, CustomElementDefinition* aDefinition); void GetCustomPrototype(nsIAtom* aAtom, @@ -381,7 +396,9 @@ private: static UniquePtr<CustomElementCallback> CreateCustomElementCallback( nsIDocument::ElementCallbackType aType, Element* aCustomElement, - LifecycleCallbackArgs* aArgs, CustomElementDefinition* aDefinition); + LifecycleCallbackArgs* aArgs, + LifecycleAdoptedCallbackArgs* aAdoptedCallbackArgs, + CustomElementDefinition* aDefinition); /** * Registers an unresolved custom element that is a candidate for diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index bc1e27ba7..9efa01439 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -2602,8 +2602,8 @@ Element::SetAttrAndNotify(int32_t aNamespaceID, (ns.IsEmpty() ? NullString() : ns) }; - nsContentUtils::EnqueueLifecycleCallback( - nsIDocument::eAttributeChanged, this, &args, definition); + nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eAttributeChanged, + this, &args, nullptr, definition); } } } @@ -2867,8 +2867,8 @@ Element::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName, (ns.IsEmpty() ? NullString() : ns) }; - nsContentUtils::EnqueueLifecycleCallback( - nsIDocument::eAttributeChanged, this, &args, definition); + nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eAttributeChanged, + this, &args, nullptr, definition); } } } diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 76171dda0..864319b17 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -9676,6 +9676,7 @@ nsContentUtils::EnqueueUpgradeReaction(Element* aElement, nsContentUtils::EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType, Element* aCustomElement, LifecycleCallbackArgs* aArgs, + LifecycleAdoptedCallbackArgs* aAdoptedCallbackArgs, CustomElementDefinition* aDefinition) { // No DocGroup means no custom element reactions stack. @@ -9684,6 +9685,7 @@ nsContentUtils::EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType, } CustomElementRegistry::EnqueueLifecycleCallback(aType, aCustomElement, aArgs, + aAdoptedCallbackArgs, aDefinition); } diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 5075bcb6d..ae9b4c8c8 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -126,6 +126,7 @@ class EventTarget; class IPCDataTransfer; class IPCDataTransferItem; struct LifecycleCallbackArgs; +struct LifecycleAdoptedCallbackArgs; class NodeInfo; class nsIContentChild; class nsIContentParent; @@ -2734,6 +2735,7 @@ public: static void EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType, Element* aCustomElement, mozilla::dom::LifecycleCallbackArgs* aArgs = nullptr, + mozilla::dom::LifecycleAdoptedCallbackArgs* aAdoptedCallbackArgs = nullptr, mozilla::dom::CustomElementDefinition* aDefinition = nullptr); static void GetCustomPrototype(nsIDocument* aDoc, diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index c620d1d09..66f30a6bc 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -2582,6 +2582,7 @@ public: eCreated, eConnected, eDisconnected, + eAdopted, eAttributeChanged }; diff --git a/dom/base/nsNodeUtils.cpp b/dom/base/nsNodeUtils.cpp index c38f08a3d..ce023ccfa 100644 --- a/dom/base/nsNodeUtils.cpp +++ b/dom/base/nsNodeUtils.cpp @@ -526,6 +526,23 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep, nsIDocument* newDoc = aNode->OwnerDoc(); if (newDoc) { + if (CustomElementRegistry::IsCustomElementEnabled()) { + // Adopted callback must be enqueued whenever a node’s + // shadow-including inclusive descendants that is custom. + Element* element = aNode->IsElement() ? aNode->AsElement() : nullptr; + if (element) { + RefPtr<CustomElementData> data = element->GetCustomElementData(); + if (data && data->mState == CustomElementData::State::eCustom) { + LifecycleAdoptedCallbackArgs args = { + oldDoc, + newDoc + }; + nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eAdopted, + element, nullptr, &args); + } + } + } + // XXX what if oldDoc is null, we don't know if this should be // registered or not! Can that really happen? if (wasRegistered) { |