summaryrefslogtreecommitdiffstats
path: root/dom/base
diff options
context:
space:
mode:
authorGaming4JC <g4jc@hyperbola.info>2020-01-04 19:48:30 -0500
committerGaming4JC <g4jc@hyperbola.info>2020-01-26 15:50:18 -0500
commitcc533eaee5b800a534b93484598779debcdf5591 (patch)
treef4613faeda690275556065ad825c1c249e155afe /dom/base
parent59c26110c1124844b5c6820573a8cb4807f1151a (diff)
downloadUXP-cc533eaee5b800a534b93484598779debcdf5591.tar
UXP-cc533eaee5b800a534b93484598779debcdf5591.tar.gz
UXP-cc533eaee5b800a534b93484598779debcdf5591.tar.lz
UXP-cc533eaee5b800a534b93484598779debcdf5591.tar.xz
UXP-cc533eaee5b800a534b93484598779debcdf5591.zip
Bug 1377993 - Make node slots less memory hungry in common cases.
Tag UXP Issue #1344
Diffstat (limited to 'dom/base')
-rw-r--r--dom/base/Element.cpp16
-rw-r--r--dom/base/Element.h4
-rw-r--r--dom/base/FragmentOrElement.cpp145
-rw-r--r--dom/base/FragmentOrElement.h128
-rw-r--r--dom/base/ShadowRoot.cpp4
-rw-r--r--dom/base/nsNodeUtils.cpp9
6 files changed, 188 insertions, 118 deletions
diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp
index 7d926f6bb..81cc41210 100644
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -1595,7 +1595,7 @@ Element::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
#endif
{
if (aBindingParent) {
- nsDOMSlots *slots = DOMSlots();
+ nsExtendedDOMSlots* slots = ExtendedDOMSlots();
slots->mBindingParent = aBindingParent; // Weak, so no addref happens.
}
@@ -1618,7 +1618,7 @@ Element::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
}
ShadowRoot* parentContainingShadow = aParent->GetContainingShadow();
if (parentContainingShadow) {
- DOMSlots()->mContainingShadow = parentContainingShadow;
+ ExtendedDOMSlots()->mContainingShadow = parentContainingShadow;
}
}
@@ -2007,7 +2007,7 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent)
}
#endif
- nsDOMSlots* slots = GetExistingDOMSlots();
+ nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
if (slots) {
if (clearBindingParent) {
slots->mBindingParent = nullptr;
@@ -2055,7 +2055,7 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent)
nsICSSDeclaration*
Element::GetSMILOverrideStyle()
{
- Element::nsDOMSlots *slots = DOMSlots();
+ Element::nsExtendedDOMSlots* slots = ExtendedDOMSlots();
if (!slots->mSMILOverrideStyle) {
slots->mSMILOverrideStyle = new nsDOMCSSAttributeDeclaration(this, true);
@@ -2067,7 +2067,7 @@ Element::GetSMILOverrideStyle()
DeclarationBlock*
Element::GetSMILOverrideStyleDeclaration()
{
- Element::nsDOMSlots *slots = GetExistingDOMSlots();
+ Element::nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
return slots ? slots->mSMILOverrideStyleDeclaration.get() : nullptr;
}
@@ -2075,7 +2075,7 @@ nsresult
Element::SetSMILOverrideStyleDeclaration(DeclarationBlock* aDeclaration,
bool aNotify)
{
- Element::nsDOMSlots *slots = DOMSlots();
+ Element::nsExtendedDOMSlots* slots = ExtendedDOMSlots();
slots->mSMILOverrideStyleDeclaration = aDeclaration;
@@ -3988,7 +3988,7 @@ Element::ClearDataset()
nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>*
Element::RegisteredIntersectionObservers()
{
- nsDOMSlots* slots = DOMSlots();
+ nsExtendedDOMSlots* slots = ExtendedDOMSlots();
return &slots->mRegisteredIntersectionObservers;
}
@@ -4041,7 +4041,7 @@ Element::UpdateIntersectionObservation(DOMIntersectionObserver* aObserver, int32
void
Element::SetCustomElementData(CustomElementData* aData)
{
- nsDOMSlots *slots = DOMSlots();
+ nsExtendedDOMSlots *slots = ExtendedDOMSlots();
MOZ_ASSERT(!slots->mCustomElementData, "Custom element data may not be changed once set.");
slots->mCustomElementData = aData;
}
diff --git a/dom/base/Element.h b/dom/base/Element.h
index 6d8bc823e..e7218ee93 100644
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -398,7 +398,7 @@ public:
*/
inline CustomElementData* GetCustomElementData() const
{
- nsDOMSlots *slots = GetExistingDOMSlots();
+ nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
if (slots) {
return slots->mCustomElementData;
}
@@ -837,7 +837,7 @@ public:
ShadowRoot *FastGetShadowRoot() const
{
- nsDOMSlots* slots = GetExistingDOMSlots();
+ nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
return slots ? slots->mShadowRoot.get() : nullptr;
}
diff --git a/dom/base/FragmentOrElement.cpp b/dom/base/FragmentOrElement.cpp
index bf0679d9f..5755fb817 100644
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -530,8 +530,7 @@ nsNodeSupportsWeakRefTearoff::GetWeakReference(nsIWeakReference** aInstancePtr)
//----------------------------------------------------------------------
FragmentOrElement::nsDOMSlots::nsDOMSlots()
: nsINode::nsSlots(),
- mDataset(nullptr),
- mBindingParent(nullptr)
+ mDataset(nullptr)
{
}
@@ -543,84 +542,104 @@ FragmentOrElement::nsDOMSlots::~nsDOMSlots()
}
void
-FragmentOrElement::nsDOMSlots::Traverse(nsCycleCollectionTraversalCallback &cb, bool aIsXUL)
+FragmentOrElement::nsDOMSlots::Traverse(nsCycleCollectionTraversalCallback &cb)
{
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mStyle");
cb.NoteXPCOMChild(mStyle.get());
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mSMILOverrideStyle");
- cb.NoteXPCOMChild(mSMILOverrideStyle.get());
-
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mAttributeMap");
cb.NoteXPCOMChild(mAttributeMap.get());
- if (aIsXUL) {
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mControllers");
- cb.NoteXPCOMChild(mControllers);
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mChildrenList");
+ cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*, mChildrenList));
+
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mClassList");
+ cb.NoteXPCOMChild(mClassList.get());
+
+ if (!mExtendedSlots) {
+ return;
}
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mXBLBinding");
- cb.NoteNativeChild(mXBLBinding, NS_CYCLE_COLLECTION_PARTICIPANT(nsXBLBinding));
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mSMILOverrideStyle");
+ cb.NoteXPCOMChild(mExtendedSlots->mSMILOverrideStyle.get());
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mXBLInsertionParent");
- cb.NoteXPCOMChild(mXBLInsertionParent.get());
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mControllers");
+ cb.NoteXPCOMChild(mExtendedSlots->mControllers);
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mShadowRoot");
- cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mShadowRoot));
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mLabelsList");
+ cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*,mExtendedSlots-> mLabelsList));
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mContainingShadow");
- cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mContainingShadow));
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mShadowRoot");
+ cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mExtendedSlots->mShadowRoot));
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mChildrenList");
- cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*, mChildrenList));
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mContainingShadow");
+ cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mExtendedSlots->mContainingShadow));
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mLabelsList");
- cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*, mLabelsList));
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mXBLBinding");
+ cb.NoteNativeChild(mExtendedSlots->mXBLBinding,
+ NS_CYCLE_COLLECTION_PARTICIPANT(nsXBLBinding));
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mClassList");
- cb.NoteXPCOMChild(mClassList.get());
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mXBLInsertionParent");
+ cb.NoteXPCOMChild(mExtendedSlots->mXBLInsertionParent.get());
- if (mCustomElementData) {
- for (uint32_t i = 0; i < mCustomElementData->mCallbackQueue.Length(); i++) {
- mCustomElementData->mCallbackQueue[i]->Traverse(cb);
+ if (mExtendedSlots->mCustomElementData) {
+ for (uint32_t i = 0;
+ i < mExtendedSlots->mCustomElementData->mCallbackQueue.Length(); i++) {
+ mExtendedSlots->mCustomElementData->mCallbackQueue[i]->Traverse(cb);
}
}
- for (auto iter = mRegisteredIntersectionObservers.Iter(); !iter.Done(); iter.Next()) {
+ for (auto iter = mExtendedSlots->mRegisteredIntersectionObservers.Iter();
+ !iter.Done(); iter.Next()) {
DOMIntersectionObserver* observer = iter.Key();
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mRegisteredIntersectionObservers[i]");
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
+ "mExtendedSlots->mRegisteredIntersectionObservers[i]");
cb.NoteXPCOMChild(observer);
}
+
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mFrameLoaderOrOpener");
+ cb.NoteXPCOMChild(mExtendedSlots->mFrameLoaderOrOpener);
}
void
-FragmentOrElement::nsDOMSlots::Unlink(bool aIsXUL)
+FragmentOrElement::nsDOMSlots::Unlink()
{
mStyle = nullptr;
- mSMILOverrideStyle = nullptr;
if (mAttributeMap) {
mAttributeMap->DropReference();
mAttributeMap = nullptr;
}
- if (aIsXUL)
- NS_IF_RELEASE(mControllers);
-
- MOZ_ASSERT(!mXBLBinding);
-
- mXBLInsertionParent = nullptr;
- mShadowRoot = nullptr;
- mContainingShadow = nullptr;
mChildrenList = nullptr;
- mLabelsList = nullptr;
- mCustomElementData = nullptr;
mClassList = nullptr;
- mRegisteredIntersectionObservers.Clear();
+
+ if (!mExtendedSlots) {
+ return;
+ }
+
+ mExtendedSlots->mSMILOverrideStyle = nullptr;
+ mExtendedSlots->mControllers = nullptr;
+ mExtendedSlots->mLabelsList = nullptr;
+ mExtendedSlots->mShadowRoot = nullptr;
+ mExtendedSlots->mContainingShadow = nullptr;
+ MOZ_ASSERT(!(mExtendedSlots->mXBLBinding));
+ mExtendedSlots->mXBLInsertionParent = nullptr;
+ mExtendedSlots->mCustomElementData = nullptr;
+ mExtendedSlots->mRegisteredIntersectionObservers.Clear();
+ nsCOMPtr<nsIFrameLoader> frameLoader =
+ do_QueryInterface(mExtendedSlots->mFrameLoaderOrOpener);
+ if (frameLoader) {
+ static_cast<nsFrameLoader*>(frameLoader.get())->Destroy();
+ }
+ mExtendedSlots->mFrameLoaderOrOpener = nullptr;
}
size_t
FragmentOrElement::nsDOMSlots::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
size_t n = aMallocSizeOf(this);
+ if (mExtendedSlots) {
+ n += aMallocSizeOf(mExtendedSlots.get());
+ }
if (mAttributeMap) {
n += mAttributeMap->SizeOfIncludingThis(aMallocSizeOf);
@@ -641,6 +660,19 @@ FragmentOrElement::nsDOMSlots::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) c
return n;
}
+FragmentOrElement::nsExtendedDOMSlots::nsExtendedDOMSlots()
+ : mBindingParent(nullptr)
+{
+}
+
+FragmentOrElement::nsExtendedDOMSlots::~nsExtendedDOMSlots()
+{
+ nsCOMPtr<nsIFrameLoader> frameLoader = do_QueryInterface(mFrameLoaderOrOpener);
+ if (frameLoader) {
+ static_cast<nsFrameLoader*>(frameLoader.get())->Destroy();
+ }
+}
+
FragmentOrElement::FragmentOrElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
: nsIContent(aNodeInfo)
{
@@ -962,7 +994,7 @@ FragmentOrElement::IsLink(nsIURI** aURI) const
nsIContent*
FragmentOrElement::GetBindingParent() const
{
- nsDOMSlots *slots = GetExistingDOMSlots();
+ nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
if (slots) {
return slots->mBindingParent;
@@ -974,7 +1006,7 @@ nsXBLBinding*
FragmentOrElement::GetXBLBinding() const
{
if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
- nsDOMSlots *slots = GetExistingDOMSlots();
+ nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
if (slots) {
return slots->mXBLBinding;
}
@@ -1009,11 +1041,11 @@ FragmentOrElement::SetXBLBinding(nsXBLBinding* aBinding,
if (aBinding) {
SetFlags(NODE_MAY_BE_IN_BINDING_MNGR);
- nsDOMSlots *slots = DOMSlots();
+ nsExtendedDOMSlots* slots = ExtendedDOMSlots();
slots->mXBLBinding = aBinding;
bindingManager->AddBoundContent(this);
} else {
- nsDOMSlots *slots = GetExistingDOMSlots();
+ nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
if (slots) {
slots->mXBLBinding = nullptr;
}
@@ -1028,7 +1060,7 @@ nsIContent*
FragmentOrElement::GetXBLInsertionParent() const
{
if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
- nsDOMSlots *slots = GetExistingDOMSlots();
+ nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
if (slots) {
return slots->mXBLInsertionParent;
}
@@ -1040,7 +1072,7 @@ FragmentOrElement::GetXBLInsertionParent() const
ShadowRoot*
FragmentOrElement::GetContainingShadow() const
{
- nsDOMSlots *slots = GetExistingDOMSlots();
+ nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
if (slots) {
return slots->mContainingShadow;
}
@@ -1050,21 +1082,21 @@ FragmentOrElement::GetContainingShadow() const
void
FragmentOrElement::SetShadowRoot(ShadowRoot* aShadowRoot)
{
- nsDOMSlots *slots = DOMSlots();
+ nsExtendedDOMSlots* slots = ExtendedDOMSlots();
slots->mShadowRoot = aShadowRoot;
}
nsTArray<nsIContent*>&
FragmentOrElement::DestInsertionPoints()
{
- nsDOMSlots *slots = DOMSlots();
+ nsExtendedDOMSlots* slots = ExtendedDOMSlots();
return slots->mDestInsertionPoints;
}
nsTArray<nsIContent*>*
FragmentOrElement::GetExistingDestInsertionPoints() const
{
- nsDOMSlots *slots = GetExistingDOMSlots();
+ nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
if (slots) {
return &slots->mDestInsertionPoints;
}
@@ -1075,11 +1107,11 @@ void
FragmentOrElement::SetXBLInsertionParent(nsIContent* aContent)
{
if (aContent) {
- nsDOMSlots *slots = DOMSlots();
+ nsExtendedDOMSlots* slots = ExtendedDOMSlots();
SetFlags(NODE_MAY_BE_IN_BINDING_MNGR);
slots->mXBLInsertionParent = aContent;
} else {
- nsDOMSlots *slots = GetExistingDOMSlots();
+ nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
if (slots) {
slots->mXBLInsertionParent = nullptr;
}
@@ -1348,14 +1380,15 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(FragmentOrElement)
{
nsDOMSlots *slots = tmp->GetExistingDOMSlots();
if (slots) {
- if (tmp->IsElement()) {
+ if (slots->mExtendedSlots && tmp->IsElement()) {
Element* elem = tmp->AsElement();
- for (auto iter = slots->mRegisteredIntersectionObservers.Iter(); !iter.Done(); iter.Next()) {
+ for (auto iter = slots->mExtendedSlots->mRegisteredIntersectionObservers.Iter();
+ !iter.Done(); iter.Next()) {
DOMIntersectionObserver* observer = iter.Key();
observer->UnlinkTarget(*elem);
}
}
- slots->Unlink(tmp->IsXULElement());
+ slots->Unlink();
}
}
@@ -1920,7 +1953,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(FragmentOrElement)
{
nsDOMSlots *slots = tmp->GetExistingDOMSlots();
if (slots) {
- slots->Traverse(cb, tmp->IsXULElement());
+ slots->Traverse(cb);
}
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
diff --git a/dom/base/FragmentOrElement.h b/dom/base/FragmentOrElement.h
index a3a59ee43..4edd88908 100644
--- a/dom/base/FragmentOrElement.h
+++ b/dom/base/FragmentOrElement.h
@@ -15,6 +15,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/MemoryReporting.h"
+#include "mozilla/UniquePtr.h"
#include "nsAttrAndChildArray.h" // member
#include "nsCycleCollectionParticipant.h" // NS_DECL_CYCLE_*
#include "nsIContent.h" // base class
@@ -239,8 +240,6 @@ protected:
nsresult CopyInnerTo(FragmentOrElement* aDest);
public:
- // Because of a bug in MS C++ compiler nsDOMSlots must be declared public,
- // otherwise nsXULElement::nsXULSlots doesn't compile.
/**
* There are a set of DOM- and scripting-specific instance variables
* that may only be instantiated when a content object is accessed
@@ -249,29 +248,13 @@ public:
* in a side structure that's only allocated when the content is
* accessed through the DOM.
*/
- class nsDOMSlots : public nsINode::nsSlots
+
+ class nsExtendedDOMSlots
{
public:
- nsDOMSlots();
- virtual ~nsDOMSlots();
-
- void Traverse(nsCycleCollectionTraversalCallback &cb, bool aIsXUL);
- void Unlink(bool aIsXUL);
-
- size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
-
- /**
- * The .style attribute (an interface that forwards to the actual
- * style rules)
- * @see nsGenericHTMLElement::GetStyle
- */
- nsCOMPtr<nsICSSDeclaration> mStyle;
+ nsExtendedDOMSlots();
- /**
- * The .dataset attribute.
- * @see nsGenericHTMLElement::GetDataset
- */
- nsDOMStringMap* mDataset; // [Weak]
+ ~nsExtendedDOMSlots();
/**
* SMIL Overridde style rules (for SMIL animation of CSS properties)
@@ -285,35 +268,17 @@ public:
RefPtr<mozilla::DeclarationBlock> mSMILOverrideStyleDeclaration;
/**
- * An object implementing nsIDOMMozNamedAttrMap for this content (attributes)
- * @see FragmentOrElement::GetAttributes
- */
- RefPtr<nsDOMAttributeMap> mAttributeMap;
-
- union {
- /**
- * The nearest enclosing content node with a binding that created us.
- * @see FragmentOrElement::GetBindingParent
- */
- nsIContent* mBindingParent; // [Weak]
-
- /**
- * The controllers of the XUL Element.
- */
- nsIControllers* mControllers; // [OWNER]
- };
+ * The nearest enclosing content node with a binding that created us.
+ * @see FragmentOrElement::GetBindingParent
+ */
+ nsIContent* mBindingParent; // [Weak]
/**
- * An object implementing the .children property for this element.
- */
- RefPtr<nsContentList> mChildrenList;
+ * The controllers of the XUL Element.
+ */
+ nsCOMPtr<nsIControllers> mControllers;
/**
- * An object implementing the .classList property for this element.
- */
- RefPtr<nsDOMTokenList> mClassList;
-
- /*
* An object implementing the .labels property for this element.
*/
RefPtr<nsLabelsNodeList> mLabelsList;
@@ -354,6 +319,55 @@ public:
*/
nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>
mRegisteredIntersectionObservers;
+
+ /**
+ * For XUL to hold either frameloader or opener.
+ */
+ nsCOMPtr<nsISupports> mFrameLoaderOrOpener;
+
+ };
+
+ class nsDOMSlots : public nsINode::nsSlots
+ {
+ public:
+ nsDOMSlots();
+ virtual ~nsDOMSlots();
+
+ void Traverse(nsCycleCollectionTraversalCallback &cb);
+ void Unlink();
+
+ size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
+
+ /**
+ * The .style attribute (an interface that forwards to the actual
+ * style rules)
+ * @see nsGenericHTMLElement::GetStyle
+ */
+ nsCOMPtr<nsICSSDeclaration> mStyle;
+
+ /**
+ * The .dataset attribute.
+ * @see nsGenericHTMLElement::GetDataset
+ */
+ nsDOMStringMap* mDataset; // [Weak]
+
+ /**
+ * An object implementing nsIDOMMozNamedAttrMap for this content (attributes)
+ * @see FragmentOrElement::GetAttributes
+ */
+ RefPtr<nsDOMAttributeMap> mAttributeMap;
+
+ /**
+ * An object implementing the .children property for this element.
+ */
+ RefPtr<nsContentList> mChildrenList;
+
+ /**
+ * An object implementing the .classList property for this element.
+ */
+ RefPtr<nsDOMTokenList> mClassList;
+
+ mozilla::UniquePtr<nsExtendedDOMSlots> mExtendedSlots;
};
protected:
@@ -373,6 +387,26 @@ protected:
return static_cast<nsDOMSlots*>(GetExistingSlots());
}
+ nsExtendedDOMSlots* ExtendedDOMSlots()
+ {
+ nsDOMSlots* slots = DOMSlots();
+ if (!slots->mExtendedSlots) {
+ slots->mExtendedSlots = MakeUnique<nsExtendedDOMSlots>();
+ }
+
+ return slots->mExtendedSlots.get();
+ }
+
+ nsExtendedDOMSlots* GetExistingExtendedDOMSlots() const
+ {
+ nsDOMSlots* slots = GetExistingDOMSlots();
+ if (slots) {
+ return slots->mExtendedSlots.get();
+ }
+
+ return nullptr;
+ }
+
/**
* Calls SetIsElementInStyleScopeFlagOnSubtree for each shadow tree attached
* to this node, which is assumed to be an Element.
diff --git a/dom/base/ShadowRoot.cpp b/dom/base/ShadowRoot.cpp
index 9540754f7..831987a96 100644
--- a/dom/base/ShadowRoot.cpp
+++ b/dom/base/ShadowRoot.cpp
@@ -75,8 +75,8 @@ ShadowRoot::ShadowRoot(nsIContent* aContent,
SetFlags(NODE_IS_IN_SHADOW_TREE);
- DOMSlots()->mBindingParent = aContent;
- DOMSlots()->mContainingShadow = this;
+ ExtendedDOMSlots()->mBindingParent = aContent;
+ ExtendedDOMSlots()->mContainingShadow = this;
// Add the ShadowRoot as a mutation observer on the host to watch
// for mutations because the insertion points in this ShadowRoot
diff --git a/dom/base/nsNodeUtils.cpp b/dom/base/nsNodeUtils.cpp
index 75d408151..c38f08a3d 100644
--- a/dom/base/nsNodeUtils.cpp
+++ b/dom/base/nsNodeUtils.cpp
@@ -301,9 +301,12 @@ nsNodeUtils::LastRelease(nsINode* aNode)
Element* elem = aNode->AsElement();
FragmentOrElement::nsDOMSlots* domSlots =
static_cast<FragmentOrElement::nsDOMSlots*>(slots);
- for (auto iter = domSlots->mRegisteredIntersectionObservers.Iter(); !iter.Done(); iter.Next()) {
- DOMIntersectionObserver* observer = iter.Key();
- observer->UnlinkTarget(*elem);
+ if (domSlots->mExtendedSlots) {
+ for (auto iter = domSlots->mExtendedSlots->mRegisteredIntersectionObservers.Iter();
+ !iter.Done(); iter.Next()) {
+ DOMIntersectionObserver* observer = iter.Key();
+ observer->UnlinkTarget(*elem);
+ }
}
}