From 6bbb9f062b63c5a920b1d240ba0d8575150dd01a Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sun, 5 Jan 2020 16:09:19 -0500 Subject: Bug 1334044: Replace detached callback (v0) with disconnected callback (v1). Tag UXP Issue #1344 --- dom/base/CustomElementRegistry.cpp | 28 ++++++++++++++++------------ dom/base/CustomElementRegistry.h | 5 +++-- dom/base/Element.cpp | 11 ++++++----- dom/base/nsIDocument.h | 2 +- 4 files changed, 26 insertions(+), 20 deletions(-) (limited to 'dom/base') diff --git a/dom/base/CustomElementRegistry.cpp b/dom/base/CustomElementRegistry.cpp index 67498a59b..069611f65 100644 --- a/dom/base/CustomElementRegistry.cpp +++ b/dom/base/CustomElementRegistry.cpp @@ -57,8 +57,8 @@ CustomElementCallback::Call() case nsIDocument::eConnected: static_cast(mCallback.get())->Call(mThisObject, rv); break; - case nsIDocument::eDetached: - static_cast(mCallback.get())->Call(mThisObject, rv); + case nsIDocument::eDisconnected: + static_cast(mCallback.get())->Call(mThisObject, rv); break; case nsIDocument::eAttributeChanged: static_cast(mCallback.get())->Call(mThisObject, @@ -354,9 +354,9 @@ CustomElementRegistry::CreateCustomElementCallback( } break; - case nsIDocument::eDetached: - if (aDefinition->mCallbacks->mDetachedCallback.WasPassed()) { - func = aDefinition->mCallbacks->mDetachedCallback.Value(); + case nsIDocument::eDisconnected: + if (aDefinition->mCallbacks->mDisconnectedCallback.WasPassed()) { + func = aDefinition->mCallbacks->mDisconnectedCallback.Value(); } break; @@ -1025,14 +1025,14 @@ CustomElementReactionsStack::Enqueue(Element* aElement, // Add element to the current element queue. if (!mReactionsStack.IsEmpty()) { - mReactionsStack.LastElement()->AppendElement(do_GetWeakReference(aElement)); + mReactionsStack.LastElement()->AppendElement(aElement); elementData->mReactionQueue.AppendElement(aReaction); return; } // If the custom element reactions stack is empty, then: // Add element to the backup element queue. - mBackupQueue.AppendElement(do_GetWeakReference(aElement)); + mBackupQueue.AppendElement(aElement); elementData->mReactionQueue.AppendElement(aReaction); if (mIsBackupQueueProcessing) { @@ -1070,14 +1070,18 @@ CustomElementReactionsStack::InvokeReactions(ElementQueue* aElementQueue, // Note: It's possible to re-enter this method. for (uint32_t i = 0; i < aElementQueue->Length(); ++i) { - nsCOMPtr element = do_QueryReferent(aElementQueue->ElementAt(i)); + Element* element = aElementQueue->ElementAt(i); if (!element) { continue; } RefPtr elementData = element->GetCustomElementData(); - MOZ_ASSERT(elementData, "CustomElementData should exist"); + if (!elementData) { + // This happens when the document is destroyed and the element is already + // unlinked, no need to fire the callbacks in this case. + return; + } auto& reactions = elementData->mReactionQueue; for (uint32_t j = 0; j < reactions.Length(); ++j) { @@ -1132,9 +1136,9 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CustomElementDefinition) cb.NoteXPCOMChild(callbacks->mConnectedCallback.Value()); } - if (callbacks->mDetachedCallback.WasPassed()) { - NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCallbacks->mDetachedCallback"); - cb.NoteXPCOMChild(callbacks->mDetachedCallback.Value()); + if (callbacks->mDisconnectedCallback.WasPassed()) { + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCallbacks->mDisconnectedCallback"); + cb.NoteXPCOMChild(callbacks->mDisconnectedCallback.Value()); } NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mConstructor"); diff --git a/dom/base/CustomElementRegistry.h b/dom/base/CustomElementRegistry.h index f73a8707e..30e2c00ab 100644 --- a/dom/base/CustomElementRegistry.h +++ b/dom/base/CustomElementRegistry.h @@ -256,11 +256,12 @@ public: { } - // nsWeakPtr is a weak pointer of Element + // Hold a strong reference of Element so that it does not get cycle collected + // before the reactions in its reaction queue are invoked. // The element reaction queues are stored in CustomElementData. // We need to lookup ElementReactionQueueMap again to get relevant reaction queue. // The choice of 1 for the auto size here is based on gut feeling. - typedef AutoTArray ElementQueue; + typedef AutoTArray, 1> ElementQueue; /** * Enqueue a custom element upgrade reaction diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index bfa0869c3..bc1e27ba7 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -1983,11 +1983,12 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent) document->ClearBoxObjectFor(this); - // Detached must be enqueued whenever custom element is removed from - // the document and this document has a browsing context. - if (GetCustomElementData() && document->GetDocShell()) { - // Enqueue a detached callback for the custom element. - nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eDetached, this); + // Disconnected must be enqueued whenever a connected custom element becomes + // disconnected. + if (CustomElementRegistry::IsCustomElementEnabled() && + GetCustomElementData()) { + nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eDisconnected, + this); } } diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index 0f05bbfcb..c620d1d09 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -2581,7 +2581,7 @@ public: enum ElementCallbackType { eCreated, eConnected, - eDetached, + eDisconnected, eAttributeChanged }; -- cgit v1.2.3