Bug 1334044: Replace detached callback (v0) with disconnected callback (v1).

Tag UXP Issue #1344
This commit is contained in:
Gaming4JC 2020-01-05 16:09:19 -05:00 • committed by Roy Tam
commit 659204631b
9 changed files with 28 additions and 84 deletions

View file

@ -57,8 +57,8 @@ CustomElementCallback::Call()
case nsIDocument::eConnected: case nsIDocument::eConnected:
static_cast<LifecycleConnectedCallback *>(mCallback.get())->Call(mThisObject, rv); static_cast<LifecycleConnectedCallback *>(mCallback.get())->Call(mThisObject, rv);
break; break;
case nsIDocument::eDetached: case nsIDocument::eDisconnected:
static_cast<LifecycleDetachedCallback *>(mCallback.get())->Call(mThisObject, rv); static_cast<LifecycleDisconnectedCallback *>(mCallback.get())->Call(mThisObject, rv);
break; break;
case nsIDocument::eAttributeChanged: case nsIDocument::eAttributeChanged:
static_cast<LifecycleAttributeChangedCallback *>(mCallback.get())->Call(mThisObject, static_cast<LifecycleAttributeChangedCallback *>(mCallback.get())->Call(mThisObject,
@ -354,9 +354,9 @@ CustomElementRegistry::CreateCustomElementCallback(
} }
break; break;
case nsIDocument::eDetached: case nsIDocument::eDisconnected:
if (aDefinition->mCallbacks->mDetachedCallback.WasPassed()) { if (aDefinition->mCallbacks->mDisconnectedCallback.WasPassed()) {
func = aDefinition->mCallbacks->mDetachedCallback.Value(); func = aDefinition->mCallbacks->mDisconnectedCallback.Value();
} }
break; break;
@ -1025,14 +1025,14 @@ CustomElementReactionsStack::Enqueue(Element* aElement,
// Add element to the current element queue. // Add element to the current element queue.
if (!mReactionsStack.IsEmpty()) { if (!mReactionsStack.IsEmpty()) {
mReactionsStack.LastElement()->AppendElement(do_GetWeakReference(aElement)); mReactionsStack.LastElement()->AppendElement(aElement);
elementData->mReactionQueue.AppendElement(aReaction); elementData->mReactionQueue.AppendElement(aReaction);
return; return;
} }
// If the custom element reactions stack is empty, then: // If the custom element reactions stack is empty, then:
// Add element to the backup element queue. // Add element to the backup element queue.
mBackupQueue.AppendElement(do_GetWeakReference(aElement)); mBackupQueue.AppendElement(aElement);
elementData->mReactionQueue.AppendElement(aReaction); elementData->mReactionQueue.AppendElement(aReaction);
if (mIsBackupQueueProcessing) { if (mIsBackupQueueProcessing) {
@ -1070,14 +1070,18 @@ CustomElementReactionsStack::InvokeReactions(ElementQueue* aElementQueue,
// Note: It's possible to re-enter this method. // Note: It's possible to re-enter this method.
for (uint32_t i = 0; i < aElementQueue->Length(); ++i) { for (uint32_t i = 0; i < aElementQueue->Length(); ++i) {
nsCOMPtr<Element> element = do_QueryReferent(aElementQueue->ElementAt(i)); Element* element = aElementQueue->ElementAt(i);
if (!element) { if (!element) {
continue; continue;
} }
RefPtr<CustomElementData> elementData = element->GetCustomElementData(); RefPtr<CustomElementData> 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; auto& reactions = elementData->mReactionQueue;
for (uint32_t j = 0; j < reactions.Length(); ++j) { 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()); cb.NoteXPCOMChild(callbacks->mConnectedCallback.Value());
} }
if (callbacks->mDetachedCallback.WasPassed()) { if (callbacks->mDisconnectedCallback.WasPassed()) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCallbacks->mDetachedCallback"); NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCallbacks->mDisconnectedCallback");
cb.NoteXPCOMChild(callbacks->mDetachedCallback.Value()); cb.NoteXPCOMChild(callbacks->mDisconnectedCallback.Value());
} }
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mConstructor"); NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mConstructor");

View file

@ -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. // The element reaction queues are stored in CustomElementData.
// We need to lookup ElementReactionQueueMap again to get relevant reaction queue. // 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. // The choice of 1 for the auto size here is based on gut feeling.
typedef AutoTArray<nsWeakPtr, 1> ElementQueue; typedef AutoTArray<RefPtr<Element>, 1> ElementQueue;
/** /**
* Enqueue a custom element upgrade reaction * Enqueue a custom element upgrade reaction

View file

@ -1983,11 +1983,12 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent)
document->ClearBoxObjectFor(this); document->ClearBoxObjectFor(this);
// Detached must be enqueued whenever custom element is removed from // Disconnected must be enqueued whenever a connected custom element becomes
// the document and this document has a browsing context. // disconnected.
if (GetCustomElementData() && document->GetDocShell()) { if (CustomElementRegistry::IsCustomElementEnabled() &&
// Enqueue a detached callback for the custom element. GetCustomElementData()) {
nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eDetached, this); nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eDisconnected,
this);
} }
} }

View file

@ -2581,7 +2581,7 @@ public:
enum ElementCallbackType { enum ElementCallbackType {
eCreated, eCreated,
eConnected, eConnected,
eDetached, eDisconnected,
eAttributeChanged eAttributeChanged
}; };

View file

@ -12,7 +12,7 @@
callback LifecycleCreatedCallback = void(); callback LifecycleCreatedCallback = void();
callback LifecycleConnectedCallback = void(); callback LifecycleConnectedCallback = void();
callback LifecycleDetachedCallback = void(); callback LifecycleDisconnectedCallback = void();
callback LifecycleAttributeChangedCallback = void(DOMString attrName, callback LifecycleAttributeChangedCallback = void(DOMString attrName,
DOMString? oldValue, DOMString? oldValue,
DOMString? newValue, DOMString? newValue,
@ -21,7 +21,7 @@ callback LifecycleAttributeChangedCallback = void(DOMString attrName,
dictionary LifecycleCallbacks { dictionary LifecycleCallbacks {
LifecycleCreatedCallback? createdCallback; LifecycleCreatedCallback? createdCallback;
LifecycleConnectedCallback? connectedCallback; LifecycleConnectedCallback? connectedCallback;
LifecycleDetachedCallback? detachedCallback; LifecycleDisconnectedCallback? disconnectedCallback;
LifecycleAttributeChangedCallback? attributeChangedCallback; LifecycleAttributeChangedCallback? attributeChangedCallback;
}; };

View file

@ -1,11 +1,5 @@
[disconnected-callbacks.html] [disconnected-callbacks.html]
type: testharness type: testharness
[Removing a custom element from the document must enqueue and invoke disconnectedCallback]
expected: FAIL
[Removing an ancestor of custom element from the document must enqueue and invoke disconnectedCallback]
expected: FAIL
[Removing a custom element from a shadow tree in the document must enqueue and invoke disconnectedCallback] [Removing a custom element from a shadow tree in the document must enqueue and invoke disconnectedCallback]
expected: FAIL expected: FAIL
@ -15,12 +9,6 @@
[Removing a custom element from a detached shadow tree that belongs to the document must not enqueue and invoke disconnectedCallback] [Removing a custom element from a detached shadow tree that belongs to the document must not enqueue and invoke disconnectedCallback]
expected: FAIL expected: FAIL
[Removing a custom element from the document of the template elements must enqueue and invoke disconnectedCallback]
expected: FAIL
[Removing an ancestor of custom element from the document of the template elements must enqueue and invoke disconnectedCallback]
expected: FAIL
[Removing a custom element from a shadow tree in the document of the template elements must enqueue and invoke disconnectedCallback] [Removing a custom element from a shadow tree in the document of the template elements must enqueue and invoke disconnectedCallback]
expected: FAIL expected: FAIL
@ -30,12 +18,6 @@
[Removing a custom element from a detached shadow tree that belongs to the document of the template elements must not enqueue and invoke disconnectedCallback] [Removing a custom element from a detached shadow tree that belongs to the document of the template elements must not enqueue and invoke disconnectedCallback]
expected: FAIL expected: FAIL
[Removing a custom element from a new document must enqueue and invoke disconnectedCallback]
expected: FAIL
[Removing an ancestor of custom element from a new document must enqueue and invoke disconnectedCallback]
expected: FAIL
[Removing a custom element from a shadow tree in a new document must enqueue and invoke disconnectedCallback] [Removing a custom element from a shadow tree in a new document must enqueue and invoke disconnectedCallback]
expected: FAIL expected: FAIL
@ -45,12 +27,6 @@
[Removing a custom element from a detached shadow tree that belongs to a new document must not enqueue and invoke disconnectedCallback] [Removing a custom element from a detached shadow tree that belongs to a new document must not enqueue and invoke disconnectedCallback]
expected: FAIL expected: FAIL
[Removing a custom element from a cloned document must enqueue and invoke disconnectedCallback]
expected: FAIL
[Removing an ancestor of custom element from a cloned document must enqueue and invoke disconnectedCallback]
expected: FAIL
[Removing a custom element from a shadow tree in a cloned document must enqueue and invoke disconnectedCallback] [Removing a custom element from a shadow tree in a cloned document must enqueue and invoke disconnectedCallback]
expected: FAIL expected: FAIL
@ -60,12 +36,6 @@
[Removing a custom element from a detached shadow tree that belongs to a cloned document must not enqueue and invoke disconnectedCallback] [Removing a custom element from a detached shadow tree that belongs to a cloned document must not enqueue and invoke disconnectedCallback]
expected: FAIL expected: FAIL
[Removing a custom element from a document created by createHTMLDocument must enqueue and invoke disconnectedCallback]
expected: FAIL
[Removing an ancestor of custom element from a document created by createHTMLDocument must enqueue and invoke disconnectedCallback]
expected: FAIL
[Removing a custom element from a shadow tree in a document created by createHTMLDocument must enqueue and invoke disconnectedCallback] [Removing a custom element from a shadow tree in a document created by createHTMLDocument must enqueue and invoke disconnectedCallback]
expected: FAIL expected: FAIL
@ -75,12 +45,6 @@
[Removing a custom element from a detached shadow tree that belongs to a document created by createHTMLDocument must not enqueue and invoke disconnectedCallback] [Removing a custom element from a detached shadow tree that belongs to a document created by createHTMLDocument must not enqueue and invoke disconnectedCallback]
expected: FAIL expected: FAIL
[Removing a custom element from an HTML document created by createDocument must enqueue and invoke disconnectedCallback]
expected: FAIL
[Removing an ancestor of custom element from an HTML document created by createDocument must enqueue and invoke disconnectedCallback]
expected: FAIL
[Removing a custom element from a shadow tree in an HTML document created by createDocument must enqueue and invoke disconnectedCallback] [Removing a custom element from a shadow tree in an HTML document created by createDocument must enqueue and invoke disconnectedCallback]
expected: FAIL expected: FAIL
@ -90,12 +54,6 @@
[Removing a custom element from a detached shadow tree that belongs to an HTML document created by createDocument must not enqueue and invoke disconnectedCallback] [Removing a custom element from a detached shadow tree that belongs to an HTML document created by createDocument must not enqueue and invoke disconnectedCallback]
expected: FAIL expected: FAIL
[Removing a custom element from the document of an iframe must enqueue and invoke disconnectedCallback]
expected: FAIL
[Removing an ancestor of custom element from the document of an iframe must enqueue and invoke disconnectedCallback]
expected: FAIL
[Removing a custom element from a shadow tree in the document of an iframe must enqueue and invoke disconnectedCallback] [Removing a custom element from a shadow tree in the document of an iframe must enqueue and invoke disconnectedCallback]
expected: FAIL expected: FAIL
@ -105,12 +63,6 @@
[Removing a custom element from a detached shadow tree that belongs to the document of an iframe must not enqueue and invoke disconnectedCallback] [Removing a custom element from a detached shadow tree that belongs to the document of an iframe must not enqueue and invoke disconnectedCallback]
expected: FAIL expected: FAIL
[Removing a custom element from an HTML document fetched by XHR must enqueue and invoke disconnectedCallback]
expected: FAIL
[Removing an ancestor of custom element from an HTML document fetched by XHR must enqueue and invoke disconnectedCallback]
expected: FAIL
[Removing a custom element from a shadow tree in an HTML document fetched by XHR must enqueue and invoke disconnectedCallback] [Removing a custom element from a shadow tree in an HTML document fetched by XHR must enqueue and invoke disconnectedCallback]
expected: FAIL expected: FAIL

View file

@ -8,7 +8,3 @@
[replaceWith on ChildNode must enqueue a disconnected reaction, an adopted reaction, and a connected reaction when the custom element was in another document] [replaceWith on ChildNode must enqueue a disconnected reaction, an adopted reaction, and a connected reaction when the custom element was in another document]
expected: FAIL expected: FAIL
[replaceWith on ChildNode must enqueue a disconnected reaction]
expected: FAIL

View file

@ -29,7 +29,3 @@
[replaceChild on ChildNode must enqueue a disconnected reaction, an adopted reaction, and a connected reaction when the custom element was in another document] [replaceChild on ChildNode must enqueue a disconnected reaction, an adopted reaction, and a connected reaction when the custom element was in another document]
expected: FAIL expected: FAIL
[removeChild on ChildNode must enqueue a disconnected reaction]
expected: FAIL

View file

@ -1,11 +1,5 @@
[Range.html] [Range.html]
type: testharness type: testharness
[deleteContents on Range must enqueue a disconnected reaction]
expected: FAIL
[extractContents on Range must enqueue a disconnected reaction]
expected: FAIL
[cloneContents on Range must enqueue an attributeChanged reaction when cloning an element with an observed attribute] [cloneContents on Range must enqueue an attributeChanged reaction when cloning an element with an observed attribute]
expected: FAIL expected: FAIL