Bug 1334043 - Part 1: Replace attached callback (v0) with connected callback (v1). r=smaug
MozReview-Commit-ID: 3qQh4viyvBX
--- a/dom/base/CustomElementRegistry.cpp
+++ b/dom/base/CustomElementRegistry.cpp
@@ -23,46 +23,45 @@ CustomElementCallback::Call()
switch (mType) {
case nsIDocument::eCreated:
{
// For the duration of this callback invocation, the element is being created
// flag must be set to true.
mOwnerData->mElementIsBeingCreated = true;
// The callback hasn't actually been invoked yet, but we need to flip
- // this now in order to enqueue the attached callback. This is a spec
+ // this now in order to enqueue the connected callback. This is a spec
// bug (w3c bug 27437).
mOwnerData->mCreatedCallbackInvoked = true;
- // If ELEMENT is in a document and this document has a browsing context,
- // enqueue attached callback for ELEMENT.
+ // If ELEMENT is connected, enqueue connected callback for ELEMENT.
nsIDocument* document = mThisObject->GetComposedDoc();
- if (document && document->GetDocShell()) {
+ if (document) {
NodeInfo* ni = mThisObject->NodeInfo();
nsDependentAtomString extType(mOwnerData->mType);
// We need to do this because at this point, CustomElementDefinition is
// not set to CustomElementData yet, so EnqueueLifecycleCallback will
// fail to find the CE definition for this custom element.
// This will go away eventually since there is no created callback in v1.
CustomElementDefinition* definition =
nsContentUtils::LookupCustomElementDefinition(document,
ni->LocalName(), ni->NamespaceID(),
extType.IsEmpty() ? nullptr : &extType);
nsContentUtils::EnqueueLifecycleCallback(
- document, nsIDocument::eAttached, mThisObject, nullptr, definition);
+ document, nsIDocument::eConnected, mThisObject, nullptr, definition);
}
static_cast<LifecycleCreatedCallback *>(mCallback.get())->Call(mThisObject, rv);
mOwnerData->mElementIsBeingCreated = false;
break;
}
- case nsIDocument::eAttached:
- static_cast<LifecycleAttachedCallback *>(mCallback.get())->Call(mThisObject, rv);
+ case nsIDocument::eConnected:
+ static_cast<LifecycleConnectedCallback *>(mCallback.get())->Call(mThisObject, rv);
break;
case nsIDocument::eDetached:
static_cast<LifecycleDetachedCallback *>(mCallback.get())->Call(mThisObject, rv);
break;
case nsIDocument::eAttributeChanged:
static_cast<LifecycleAttributeChangedCallback *>(mCallback.get())->Call(mThisObject,
mArgs.name, mArgs.oldValue, mArgs.newValue, mArgs.namespaceURI, rv);
break;
@@ -335,19 +334,19 @@ CustomElementRegistry::CreateCustomEleme
CallbackFunction* func = nullptr;
switch (aType) {
case nsIDocument::eCreated:
if (aDefinition->mCallbacks->mCreatedCallback.WasPassed()) {
func = aDefinition->mCallbacks->mCreatedCallback.Value();
}
break;
- case nsIDocument::eAttached:
- if (aDefinition->mCallbacks->mAttachedCallback.WasPassed()) {
- func = aDefinition->mCallbacks->mAttachedCallback.Value();
+ case nsIDocument::eConnected:
+ if (aDefinition->mCallbacks->mConnectedCallback.WasPassed()) {
+ func = aDefinition->mCallbacks->mConnectedCallback.Value();
}
break;
case nsIDocument::eDetached:
if (aDefinition->mCallbacks->mDetachedCallback.WasPassed()) {
func = aDefinition->mCallbacks->mDetachedCallback.Value();
}
break;
@@ -938,17 +937,21 @@ CustomElementRegistry::Upgrade(Element*
nsIDocument::eAttributeChanged,
aElement,
&args, aDefinition);
}
}
}
// Step 4.
- // TODO: Bug 1334043 - Implement connected lifecycle callbacks for custom elements
+ if (aElement->IsInComposedDoc()) {
+ nsContentUtils::EnqueueLifecycleCallback(aElement->OwnerDoc(),
+ nsIDocument::eConnected, aElement,
+ nullptr, aDefinition);
+ }
// Step 5.
AutoConstructionStackEntry acs(aDefinition->mConstructionStack,
nsGenericHTMLElement::FromContent(aElement));
// Step 6 and step 7.
DoUpgrade(aElement, aDefinition->mConstructor, aRv);
if (aRv.Failed()) {
@@ -1133,19 +1136,19 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
cb.NoteXPCOMChild(callbacks->mAttributeChangedCallback.Value());
}
if (callbacks->mCreatedCallback.WasPassed()) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCallbacks->mCreatedCallback");
cb.NoteXPCOMChild(callbacks->mCreatedCallback.Value());
}
- if (callbacks->mAttachedCallback.WasPassed()) {
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCallbacks->mAttachedCallback");
- cb.NoteXPCOMChild(callbacks->mAttachedCallback.Value());
+ if (callbacks->mConnectedCallback.WasPassed()) {
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCallbacks->mConnectedCallback");
+ cb.NoteXPCOMChild(callbacks->mConnectedCallback.Value());
}
if (callbacks->mDetachedCallback.WasPassed()) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCallbacks->mDetachedCallback");
cb.NoteXPCOMChild(callbacks->mDetachedCallback.Value());
}
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mConstructor");
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -1616,23 +1616,22 @@ Element::BindToTree(nsIDocument* aDocume
NODE_DESCENDANTS_NEED_FRAMES | ELEMENT_ALL_RESTYLE_FLAGS);
} else {
// If we're not in the doc and not in a shadow tree,
// update our subtree pointer.
SetSubtreeRootPointer(aParent->SubtreeRoot());
}
nsIDocument* composedDoc = GetComposedDoc();
- if (composedDoc) {
- // Attached callback must be enqueued whenever custom element is inserted into a
- // document and this document has a browsing context.
- if (GetCustomElementData() && composedDoc->GetDocShell()) {
- // Enqueue an attached callback for the custom element.
+ if (CustomElementRegistry::IsCustomElementEnabled() && composedDoc) {
+ // Connected callback must be enqueued whenever a custom element becomes
+ // connected.
+ if (GetCustomElementData()) {
nsContentUtils::EnqueueLifecycleCallback(
- composedDoc, nsIDocument::eAttached, this);
+ composedDoc, nsIDocument::eConnected, this);
}
}
// Propagate scoped style sheet tracking bit.
if (mParent->IsContent()) {
nsIContent* parent;
ShadowRoot* shadowRootParent = ShadowRoot::FromNode(mParent);
if (shadowRootParent) {
@@ -2620,17 +2619,17 @@ Element::SetAttrAndNotify(int32_t aNames
if (aComposedDocument || HasFlag(NODE_FORCE_XBL_BINDINGS)) {
RefPtr<nsXBLBinding> binding = GetXBLBinding();
if (binding) {
binding->AttributeChanged(aName, aNamespaceID, false, aNotify);
}
}
- if (nsContentUtils::IsWebComponentsEnabled()) {
+ if (CustomElementRegistry::IsCustomElementEnabled()) {
if (CustomElementData* data = GetCustomElementData()) {
if (CustomElementDefinition* definition =
nsContentUtils::GetElementDefinitionIfObservingAttr(this,
data->mType,
aName)) {
nsCOMPtr<nsIAtom> oldValueAtom;
if (oldValue) {
oldValueAtom = oldValue->GetAsAtom();
@@ -2924,17 +2923,17 @@ Element::UnsetAttr(int32_t aNameSpaceID,
if (document || HasFlag(NODE_FORCE_XBL_BINDINGS)) {
RefPtr<nsXBLBinding> binding = GetXBLBinding();
if (binding) {
binding->AttributeChanged(aName, aNameSpaceID, true, aNotify);
}
}
- if (nsContentUtils::IsWebComponentsEnabled()) {
+ if (CustomElementRegistry::IsCustomElementEnabled()) {
if (CustomElementData* data = GetCustomElementData()) {
if (CustomElementDefinition* definition =
nsContentUtils::GetElementDefinitionIfObservingAttr(this,
data->mType,
aName)) {
nsAutoString ns;
nsContentUtils::NameSpaceManager()->GetNameSpaceURI(aNameSpaceID, ns);
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -2737,17 +2737,17 @@ public:
// GetDoctype defined above
Element* GetDocumentElement() const
{
return GetRootElement();
}
enum ElementCallbackType {
eCreated,
- eAttached,
+ eConnected,
eDetached,
eAttributeChanged
};
nsIDocument* GetTopLevelContentDocument();
virtual void
RegisterElement(JSContext* aCx, const nsAString& aName,
--- a/dom/webidl/WebComponents.webidl
+++ b/dom/webidl/WebComponents.webidl
@@ -6,26 +6,26 @@
* The origin of this IDL file is
* http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
callback LifecycleCreatedCallback = void();
-callback LifecycleAttachedCallback = void();
+callback LifecycleConnectedCallback = void();
callback LifecycleDetachedCallback = void();
callback LifecycleAttributeChangedCallback = void(DOMString attrName,
DOMString? oldValue,
DOMString? newValue,
DOMString? namespaceURI);
dictionary LifecycleCallbacks {
LifecycleCreatedCallback? createdCallback;
- LifecycleAttachedCallback? attachedCallback;
+ LifecycleConnectedCallback? connectedCallback;
LifecycleDetachedCallback? detachedCallback;
LifecycleAttributeChangedCallback? attributeChangedCallback;
};
dictionary ElementRegistrationOptions {
object? prototype = null;
DOMString? extends = null;
};