--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -547,23 +547,21 @@ public:
/**
* Gets the custom element data used by web components custom element.
* Custom element data is created at the first attempt to enqueue a callback.
*
* @return The custom element data or null if none.
*/
inline CustomElementData* GetCustomElementData() const
{
- nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
- if (slots) {
- return slots->mCustomElementData;
- }
- return nullptr;
+ const nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
+ return slots ? slots->mCustomElementData.get() : nullptr;
}
+
/**
* Sets the custom element data, ownership of the
* callback data is taken by this element.
*
* @param aData The custom element data.
*/
void SetCustomElementData(CustomElementData* aData);
@@ -1290,19 +1288,21 @@ public:
ErrorResult& aError);
ShadowRoot* GetShadowRootByMode() const;
void SetSlot(const nsAString& aName, ErrorResult& aError);
void GetSlot(nsAString& aName);
// [deprecated] Shadow DOM v0
already_AddRefed<ShadowRoot> CreateShadowRoot(ErrorResult& aError);
- ShadowRoot *FastGetShadowRoot() const
+ // FIXME(emilio): Should just shadow GetShadowRoot(), that way we get the fast
+ // version by default everywhere we already have an Element...
+ ShadowRoot* FastGetShadowRoot() const
{
- nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
+ const nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
return slots ? slots->mShadowRoot.get() : nullptr;
}
private:
void ScrollIntoView(const ScrollIntoViewOptions &aOptions);
public:
void ScrollIntoView(const BooleanOrScrollIntoViewOptions& aObject);
MOZ_CAN_RUN_SCRIPT void Scroll(double aXScroll, double aYScroll);
@@ -1476,19 +1476,19 @@ public:
return mAttrsAndChildren.GetAttr(aAttr, aNameSpaceID);
}
/**
* Returns the attribute map, if there is one.
*
* @return existing attribute map or nullptr.
*/
- nsDOMAttributeMap *GetAttributeMap()
+ nsDOMAttributeMap* GetAttributeMap()
{
- nsDOMSlots *slots = GetExistingDOMSlots();
+ nsDOMSlots* slots = GetExistingDOMSlots();
return slots ? slots->mAttributeMap.get() : nullptr;
}
virtual void RecompileScriptEventListeners()
{
}
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -705,17 +705,17 @@ nsParentNodeChildContentList::ValidateCa
return true;
}
//----------------------------------------------------------------------
nsIHTMLCollection*
FragmentOrElement::Children()
{
- FragmentOrElement::nsDOMSlots *slots = DOMSlots();
+ nsDOMSlots* slots = DOMSlots();
if (!slots->mChildrenList) {
slots->mChildrenList = new nsContentList(this, kNameSpaceID_Wildcard,
nsGkAtoms::_asterisk, nsGkAtoms::_asterisk,
false);
}
return slots->mChildrenList;
@@ -783,114 +783,86 @@ 128;
64;
#endif
static_assert(sizeof(nsINode::nsSlots) <= MaxDOMSlotSizeAllowed,
"DOM slots cannot be grown without consideration");
static_assert(sizeof(FragmentOrElement::nsDOMSlots) <= MaxDOMSlotSizeAllowed,
"DOM slots cannot be grown without consideration");
+void
+nsIContent::nsExtendedContentSlots::Unlink()
+{
+ mXBLInsertionPoint = nullptr;
+ mContainingShadow = nullptr;
+ mAssignedSlot = nullptr;
+}
+
+void
+nsIContent::nsExtendedContentSlots::Traverse(nsCycleCollectionTraversalCallback& aCb)
+{
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mContainingShadow");
+ aCb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mContainingShadow));
+
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mAssignedSlot");
+ aCb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mAssignedSlot.get()));
+
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mXBLInsertionPoint");
+ aCb.NoteXPCOMChild(mXBLInsertionPoint.get());
+}
+
+nsIContent::nsExtendedContentSlots::nsExtendedContentSlots()
+ : mBindingParent(nullptr)
+{
+}
+
+nsIContent::nsExtendedContentSlots::~nsExtendedContentSlots() = default;
+
FragmentOrElement::nsDOMSlots::nsDOMSlots()
- : nsINode::nsSlots(),
+ : nsIContent::nsContentSlots(),
mDataset(nullptr)
{
}
FragmentOrElement::nsDOMSlots::~nsDOMSlots()
{
if (mAttributeMap) {
mAttributeMap->DropReference();
}
}
void
-FragmentOrElement::nsDOMSlots::Traverse(nsCycleCollectionTraversalCallback &cb)
+FragmentOrElement::nsDOMSlots::Traverse(nsCycleCollectionTraversalCallback& aCb)
{
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mStyle");
- cb.NoteXPCOMChild(mStyle.get());
-
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mAttributeMap");
- cb.NoteXPCOMChild(mAttributeMap.get());
-
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mChildrenList");
- cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*, mChildrenList));
+ nsIContent::nsContentSlots::Traverse(aCb);
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mClassList");
- cb.NoteXPCOMChild(mClassList.get());
-
- if (!mExtendedSlots) {
- return;
- }
-
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mSMILOverrideStyle");
- cb.NoteXPCOMChild(mExtendedSlots->mSMILOverrideStyle.get());
-
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mControllers");
- cb.NoteXPCOMChild(mExtendedSlots->mControllers);
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mSlots->mStyle");
+ aCb.NoteXPCOMChild(mStyle.get());
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mLabelsList");
- cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*,mExtendedSlots-> mLabelsList));
-
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mShadowRoot");
- cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mExtendedSlots->mShadowRoot));
-
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mContainingShadow");
- cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mExtendedSlots->mContainingShadow));
-
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mAssignedSlot");
- cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mExtendedSlots->mAssignedSlot.get()));
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mSlots->mAttributeMap");
+ aCb.NoteXPCOMChild(mAttributeMap.get());
- 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, "mExtendedSlots->mXBLInsertionPoint");
- cb.NoteXPCOMChild(mExtendedSlots->mXBLInsertionPoint.get());
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mSlots->mChildrenList");
+ aCb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*, mChildrenList));
- if (mExtendedSlots->mCustomElementData) {
- mExtendedSlots->mCustomElementData->Traverse(cb);
- }
-
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mExtendedSlots->mFrameLoaderOrOpener");
- cb.NoteXPCOMChild(mExtendedSlots->mFrameLoaderOrOpener);
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mSlots->mClassList");
+ aCb.NoteXPCOMChild(mClassList.get());
}
void
FragmentOrElement::nsDOMSlots::Unlink()
{
+ nsIContent::nsContentSlots::Unlink();
mStyle = nullptr;
if (mAttributeMap) {
mAttributeMap->DropReference();
mAttributeMap = nullptr;
}
mChildrenList = nullptr;
mClassList = nullptr;
-
- if (!mExtendedSlots) {
- return;
- }
-
- mExtendedSlots->mSMILOverrideStyle = nullptr;
- mExtendedSlots->mControllers = nullptr;
- mExtendedSlots->mLabelsList = nullptr;
- mExtendedSlots->mShadowRoot = nullptr;
- mExtendedSlots->mContainingShadow = nullptr;
- mExtendedSlots->mAssignedSlot = nullptr;
- MOZ_ASSERT(!(mExtendedSlots->mXBLBinding));
- mExtendedSlots->mXBLInsertionPoint = nullptr;
- if (mExtendedSlots->mCustomElementData) {
- mExtendedSlots->mCustomElementData->Unlink();
- mExtendedSlots->mCustomElementData = nullptr;
- }
- 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());
@@ -910,29 +882,78 @@ FragmentOrElement::nsDOMSlots::SizeOfInc
// - mChildrenList
// - mClassList
// The following members are not measured:
// - mBindingParent / mControllers: because they're non-owning
return n;
}
-FragmentOrElement::nsExtendedDOMSlots::nsExtendedDOMSlots()
- : mBindingParent(nullptr)
-{
-}
+FragmentOrElement::nsExtendedDOMSlots::nsExtendedDOMSlots() = default;
FragmentOrElement::nsExtendedDOMSlots::~nsExtendedDOMSlots()
{
nsCOMPtr<nsIFrameLoader> frameLoader = do_QueryInterface(mFrameLoaderOrOpener);
if (frameLoader) {
static_cast<nsFrameLoader*>(frameLoader.get())->Destroy();
}
}
+void
+FragmentOrElement::nsExtendedDOMSlots::Unlink()
+{
+ nsIContent::nsExtendedContentSlots::Unlink();
+
+ // Don't clear mXBLBinding, it'll be done in
+ // BindingManager::RemovedFromDocument from FragmentOrElement::Unlink.
+ mSMILOverrideStyle = nullptr;
+ mControllers = nullptr;
+ mLabelsList = nullptr;
+ mShadowRoot = nullptr;
+ if (mCustomElementData) {
+ mCustomElementData->Unlink();
+ mCustomElementData = nullptr;
+ }
+ nsCOMPtr<nsIFrameLoader> frameLoader =
+ do_QueryInterface(mFrameLoaderOrOpener);
+ if (frameLoader) {
+ static_cast<nsFrameLoader*>(frameLoader.get())->Destroy();
+ }
+ mFrameLoaderOrOpener = nullptr;
+}
+
+void
+FragmentOrElement::nsExtendedDOMSlots::Traverse(nsCycleCollectionTraversalCallback& aCb)
+{
+ nsIContent::nsExtendedContentSlots::Traverse(aCb);
+
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mSMILOverrideStyle");
+ aCb.NoteXPCOMChild(mSMILOverrideStyle.get());
+
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mControllers");
+ aCb.NoteXPCOMChild(mControllers);
+
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mLabelsList");
+ aCb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*, mLabelsList));
+
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mShadowRoot");
+ aCb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mShadowRoot));
+
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mXBLBinding");
+ aCb.NoteNativeChild(mXBLBinding,
+ NS_CYCLE_COLLECTION_PARTICIPANT(nsXBLBinding));
+
+ if (mCustomElementData) {
+ mCustomElementData->Traverse(aCb);
+ }
+
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mFrameLoaderOrOpener");
+ aCb.NoteXPCOMChild(mFrameLoaderOrOpener);
+}
+
FragmentOrElement::FragmentOrElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
: nsIContent(aNodeInfo)
{
}
FragmentOrElement::FragmentOrElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
: nsIContent(aNodeInfo)
{
@@ -1157,35 +1178,22 @@ nsIContent::IsFocusableInternal(int32_t*
bool
FragmentOrElement::IsLink(nsIURI** aURI) const
{
*aURI = nullptr;
return false;
}
-nsIContent*
-FragmentOrElement::GetBindingParent() const
-{
- nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
-
- if (slots) {
- return slots->mBindingParent;
- }
- return nullptr;
-}
-
nsXBLBinding*
FragmentOrElement::DoGetXBLBinding() const
{
MOZ_ASSERT(HasFlag(NODE_MAY_BE_IN_BINDING_MNGR));
- if (nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots()) {
- return slots->mXBLBinding;
- }
- return nullptr;
+ const nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
+ return slots ? slots->mXBLBinding.get() : nullptr;
}
void
FragmentOrElement::SetXBLBinding(nsXBLBinding* aBinding,
nsBindingManager* aOldBindingManager)
{
nsBindingManager* bindingManager;
if (aOldBindingManager) {
@@ -1219,71 +1227,40 @@ FragmentOrElement::SetXBLBinding(nsXBLBi
}
bindingManager->RemoveBoundContent(this);
if (oldBinding) {
oldBinding->SetBoundElement(nullptr);
}
}
}
-nsIContent*
-FragmentOrElement::GetXBLInsertionPoint() const
-{
- if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
- nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
- if (slots) {
- return slots->mXBLInsertionPoint;
- }
- }
-
- return nullptr;
-}
-
-ShadowRoot*
-FragmentOrElement::GetContainingShadow() const
-{
- nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
- if (slots) {
- return slots->mContainingShadow;
- }
- return nullptr;
-}
-
void
FragmentOrElement::SetShadowRoot(ShadowRoot* aShadowRoot)
{
nsExtendedDOMSlots* slots = ExtendedDOMSlots();
slots->mShadowRoot = aShadowRoot;
}
-HTMLSlotElement*
-FragmentOrElement::GetAssignedSlot() const
+void
+nsIContent::SetAssignedSlot(HTMLSlotElement* aSlot)
{
- nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
- return slots ? slots->mAssignedSlot.get() : nullptr;
+ ExtendedContentSlots()->mAssignedSlot = aSlot;
}
void
-FragmentOrElement::SetAssignedSlot(HTMLSlotElement* aSlot)
-{
- nsExtendedDOMSlots* slots = ExtendedDOMSlots();
- slots->mAssignedSlot = aSlot;
-}
-
-void
-FragmentOrElement::SetXBLInsertionPoint(nsIContent* aContent)
+nsIContent::SetXBLInsertionPoint(nsIContent* aContent)
{
nsCOMPtr<nsIContent> oldInsertionPoint = nullptr;
if (aContent) {
- nsExtendedDOMSlots* slots = ExtendedDOMSlots();
+ nsExtendedContentSlots* slots = ExtendedContentSlots();
SetFlags(NODE_MAY_BE_IN_BINDING_MNGR);
oldInsertionPoint = slots->mXBLInsertionPoint.forget();
slots->mXBLInsertionPoint = aContent;
} else {
- if (nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots()) {
+ if (nsExtendedContentSlots* slots = GetExistingExtendedContentSlots()) {
oldInsertionPoint = slots->mXBLInsertionPoint.forget();
slots->mXBLInsertionPoint = nullptr;
}
}
// We just changed the flattened tree, so any Servo style data is now invalid.
// We rely on nsXBLService::LoadBindings to re-traverse the subtree afterwards.
if (oldInsertionPoint != aContent &&
@@ -1565,25 +1542,16 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Fr
// Clear flag here because unlinking slots will clear the
// containing shadow root pointer.
tmp->UnsetFlags(NODE_IS_IN_SHADOW_TREE);
nsIDocument* doc = tmp->OwnerDoc();
doc->BindingManager()->RemovedFromDocument(tmp, doc,
nsBindingManager::eDoNotRunDtor);
-
- // Unlink any DOM slots of interest.
- {
- nsDOMSlots *slots = tmp->GetExistingDOMSlots();
- if (slots) {
- slots->Unlink();
- }
- }
-
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(FragmentOrElement)
void
FragmentOrElement::MarkUserData(void* aObject, nsAtom* aKey, void* aChild,
void* aData)
{
@@ -2143,24 +2111,16 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
}
uint32_t kids = tmp->mAttrsAndChildren.ChildCount();
for (i = 0; i < kids; i++) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mAttrsAndChildren[i]");
cb.NoteXPCOMChild(tmp->mAttrsAndChildren.GetSafeChildAt(i));
}
}
-
- // Traverse any DOM slots of interest.
- {
- nsDOMSlots *slots = tmp->GetExistingDOMSlots();
- if (slots) {
- slots->Traverse(cb);
- }
- }
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN(FragmentOrElement)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(FragmentOrElement)
NS_INTERFACE_MAP_ENTRY(Element)
NS_INTERFACE_MAP_ENTRY(nsIContent)
@@ -2496,22 +2456,16 @@ FragmentOrElement::SetInnerHTMLInternal(
nsAutoScriptBlockerSuppressNodeRemoved scriptBlocker;
static_cast<nsINode*>(target)->AppendChild(*df, aError);
mb.NodesAdded();
}
}
}
-nsINode::nsSlots*
-FragmentOrElement::CreateSlots()
-{
- return new nsDOMSlots();
-}
-
void
FragmentOrElement::FireNodeRemovedForChildren()
{
nsIDocument* doc = OwnerDoc();
// Optimize the common case
if (!nsContentUtils::
HasMutationListeners(doc, NS_EVENT_BITS_MUTATION_NODEREMOVED)) {
return;
--- a/dom/base/FragmentOrElement.h
+++ b/dom/base/FragmentOrElement.h
@@ -143,26 +143,20 @@ public:
virtual nsresult AppendText(const char16_t* aBuffer, uint32_t aLength,
bool aNotify) override;
virtual bool TextIsOnlyWhitespace() override;
virtual bool ThreadSafeTextIsOnlyWhitespace() const override;
virtual bool HasTextForTranslation() override;
virtual void AppendTextTo(nsAString& aResult) override;
MOZ_MUST_USE
virtual bool AppendTextTo(nsAString& aResult, const mozilla::fallible_t&) override;
- virtual nsIContent* GetBindingParent() const override;
virtual nsXBLBinding* DoGetXBLBinding() const override;
virtual void SetXBLBinding(nsXBLBinding* aBinding,
nsBindingManager* aOldBindingManager = nullptr) override;
- virtual ShadowRoot *GetContainingShadow() const override;
virtual void SetShadowRoot(ShadowRoot* aBinding) override;
- virtual mozilla::dom::HTMLSlotElement* GetAssignedSlot() const override;
- virtual void SetAssignedSlot(mozilla::dom::HTMLSlotElement* aSlot) override;
- virtual nsIContent *GetXBLInsertionPoint() const override;
- virtual void SetXBLInsertionPoint(nsIContent* aContent) override;
virtual bool IsLink(nsIURI** aURI) const override;
virtual void DestroyContent() override;
virtual void SaveSubtreeState() override;
nsIHTMLCollection* Children();
uint32_t ChildElementCount()
{
@@ -241,95 +235,76 @@ public:
* There are a set of DOM- and scripting-specific instance variables
* that may only be instantiated when a content object is accessed
* through the DOM. Rather than burn actual slots in the content
* objects for each of these instance variables, we put them off
* in a side structure that's only allocated when the content is
* accessed through the DOM.
*/
- class nsExtendedDOMSlots
+ class nsExtendedDOMSlots final : public nsIContent::nsExtendedContentSlots
{
public:
nsExtendedDOMSlots();
+ ~nsExtendedDOMSlots() final;
- ~nsExtendedDOMSlots();
+ void Traverse(nsCycleCollectionTraversalCallback&) final;
+ void Unlink() final;
/**
* SMIL Overridde style rules (for SMIL animation of CSS properties)
* @see Element::GetSMILOverrideStyle
*/
nsCOMPtr<nsICSSDeclaration> mSMILOverrideStyle;
/**
* Holds any SMIL override style declaration for this element.
*/
RefPtr<mozilla::DeclarationBlock> mSMILOverrideStyleDeclaration;
/**
- * The nearest enclosing content node with a binding that created us.
- * @see FragmentOrElement::GetBindingParent
- */
- nsIContent* mBindingParent; // [Weak]
-
- /**
* The controllers of the XUL Element.
*/
nsCOMPtr<nsIControllers> mControllers;
/**
* An object implementing the .labels property for this element.
*/
RefPtr<nsLabelsNodeList> mLabelsList;
/**
* ShadowRoot bound to the element.
*/
RefPtr<ShadowRoot> mShadowRoot;
/**
- * The root ShadowRoot of this element if it is in a shadow tree.
- */
- RefPtr<ShadowRoot> mContainingShadow;
-
- /**
- * The assigned slot associated with this element.
- */
- RefPtr<mozilla::dom::HTMLSlotElement> mAssignedSlot;
-
- /**
* XBL binding installed on the element.
*/
RefPtr<nsXBLBinding> mXBLBinding;
/**
- * XBL binding insertion point.
- */
- nsCOMPtr<nsIContent> mXBLInsertionPoint;
-
- /**
* Web components custom element data.
*/
RefPtr<CustomElementData> mCustomElementData;
/**
* For XUL to hold either frameloader or opener.
*/
nsCOMPtr<nsISupports> mFrameLoaderOrOpener;
};
- class nsDOMSlots : public nsINode::nsSlots
+ class nsDOMSlots final : public nsIContent::nsContentSlots
{
public:
nsDOMSlots();
- virtual ~nsDOMSlots();
+ ~nsDOMSlots() final;
- void Traverse(nsCycleCollectionTraversalCallback &cb);
- void Unlink();
+ void Traverse(nsCycleCollectionTraversalCallback&) final;
+ void Unlink() final;
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
/**
* The .style attribute (an interface that forwards to the actual
* style rules)
* @see nsGenericHTMLElement::GetStyle
*/
@@ -351,55 +326,57 @@ public:
* 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:
void GetMarkup(bool aIncludeSelf, nsAString& aMarkup);
void SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult& aError);
// Override from nsINode
- virtual nsINode::nsSlots* CreateSlots() override;
+ nsIContent::nsContentSlots* CreateSlots() override
+ {
+ return new nsDOMSlots();
+ }
- nsDOMSlots *DOMSlots()
+ nsIContent::nsExtendedContentSlots* CreateExtendedSlots() final
+ {
+ return new nsExtendedDOMSlots();
+ }
+
+ nsDOMSlots* DOMSlots()
{
return static_cast<nsDOMSlots*>(Slots());
}
nsDOMSlots *GetExistingDOMSlots() const
{
return static_cast<nsDOMSlots*>(GetExistingSlots());
}
nsExtendedDOMSlots* ExtendedDOMSlots()
{
- nsDOMSlots* slots = DOMSlots();
- if (!slots->mExtendedSlots) {
- slots->mExtendedSlots = MakeUnique<nsExtendedDOMSlots>();
- }
-
- return slots->mExtendedSlots.get();
+ return static_cast<nsExtendedDOMSlots*>(ExtendedContentSlots());
}
- nsExtendedDOMSlots* GetExistingExtendedDOMSlots() const
+ const nsExtendedDOMSlots* GetExistingExtendedDOMSlots() const
{
- nsDOMSlots* slots = GetExistingDOMSlots();
- if (slots) {
- return slots->mExtendedSlots.get();
- }
+ return static_cast<const nsExtendedDOMSlots*>(
+ GetExistingExtendedContentSlots());
+ }
- return nullptr;
+ nsExtendedDOMSlots* GetExistingExtendedDOMSlots()
+ {
+ return static_cast<nsExtendedDOMSlots*>(GetExistingExtendedContentSlots());
}
/**
* Calls SetIsElementInStyleScopeFlagOnSubtree for each shadow tree attached
* to this node, which is assumed to be an Element.
*
* @param aInStyleScope The IsElementInStyleScope flag value to set.
*/
--- a/dom/base/nsGenericDOMDataNode.cpp
+++ b/dom/base/nsGenericDOMDataNode.cpp
@@ -94,34 +94,29 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
char name[40];
SprintfLiteral(name, "nsGenericDOMDataNode (len=%d)",
tmp->mText.GetLength());
cb.DescribeRefCountedNode(tmp->mRefCnt.get(), name);
} else {
NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsGenericDOMDataNode, tmp->mRefCnt.get())
}
- if (!nsINode::Traverse(tmp, cb)) {
+ if (!nsIContent::Traverse(tmp, cb)) {
return NS_SUCCESS_INTERRUPTED_TRAVERSE;
}
-
- nsDataSlots *slots = tmp->GetExistingDataSlots();
- if (slots) {
- slots->Traverse(cb);
- }
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGenericDOMDataNode)
- nsINode::Unlink(tmp);
+ nsIContent::Unlink(tmp);
// Clear flag here because unlinking slots will clear the
// containing shadow root pointer.
tmp->UnsetFlags(NODE_IS_IN_SHADOW_TREE);
- nsDataSlots *slots = tmp->GetExistingDataSlots();
+ nsContentSlots* slots = tmp->GetExistingContentSlots();
if (slots) {
slots->Unlink();
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN(nsGenericDOMDataNode)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsGenericDOMDataNode)
@@ -503,33 +498,33 @@ nsGenericDOMDataNode::BindToTree(nsIDocu
// First set the binding parent
if (aBindingParent) {
NS_ASSERTION(IsRootOfNativeAnonymousSubtree() ||
!HasFlag(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE) ||
(aParent && aParent->IsInNativeAnonymousSubtree()),
"Trying to re-bind content from native anonymous subtree to "
"non-native anonymous parent!");
- DataSlots()->mBindingParent = aBindingParent; // Weak, so no addref happens.
+ ExtendedContentSlots()->mBindingParent = aBindingParent; // Weak, so no addref happens.
if (aParent->IsInNativeAnonymousSubtree()) {
SetFlags(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE);
}
if (aParent->HasFlag(NODE_CHROME_ONLY_ACCESS)) {
SetFlags(NODE_CHROME_ONLY_ACCESS);
}
if (HasFlag(NODE_IS_ANONYMOUS_ROOT)) {
aParent->SetMayHaveAnonymousChildren();
}
if (aParent->IsInShadowTree()) {
ClearSubtreeRootPointer();
SetFlags(NODE_IS_IN_SHADOW_TREE);
}
ShadowRoot* parentContainingShadow = aParent->GetContainingShadow();
if (parentContainingShadow) {
- DataSlots()->mContainingShadow = parentContainingShadow;
+ ExtendedContentSlots()->mContainingShadow = parentContainingShadow;
}
}
bool hadParent = !!GetParentNode();
// Set parent
if (aParent) {
if (!GetParent()) {
@@ -615,17 +610,17 @@ nsGenericDOMDataNode::UnbindFromTree(boo
// do not get uninstalled.
if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
nsContentUtils::AddScriptRunner(
new RemoveFromBindingManagerRunnable(document->BindingManager(), this,
document));
}
}
- nsDataSlots *slots = GetExistingDataSlots();
+ nsExtendedContentSlots* slots = GetExistingExtendedContentSlots();
if (slots) {
slots->mBindingParent = nullptr;
if (aNullParent || !mParent->IsInShadowTree()) {
slots->mContainingShadow = nullptr;
}
}
nsNodeUtils::ParentChainChanged(this);
@@ -663,90 +658,31 @@ nsGenericDOMDataNode::InsertChildAt(nsIC
return NS_OK;
}
void
nsGenericDOMDataNode::RemoveChildAt(uint32_t aIndex, bool aNotify)
{
}
-nsIContent *
-nsGenericDOMDataNode::GetBindingParent() const
-{
- nsDataSlots *slots = GetExistingDataSlots();
- return slots ? slots->mBindingParent : nullptr;
-}
-
-ShadowRoot *
-nsGenericDOMDataNode::GetContainingShadow() const
-{
- nsDataSlots *slots = GetExistingDataSlots();
- if (!slots) {
- return nullptr;
- }
- return slots->mContainingShadow;
-}
-
-void
-nsGenericDOMDataNode::SetShadowRoot(ShadowRoot* aShadowRoot)
-{
-}
-
-HTMLSlotElement*
-nsGenericDOMDataNode::GetAssignedSlot() const
-{
- nsDataSlots *slots = GetExistingDataSlots();
- return slots ? slots->mAssignedSlot.get() : nullptr;
-}
-
-void
-nsGenericDOMDataNode::SetAssignedSlot(HTMLSlotElement* aSlot)
-{
- nsDataSlots *slots = DataSlots();
- slots->mAssignedSlot = aSlot;
-}
-
nsXBLBinding *
nsGenericDOMDataNode::DoGetXBLBinding() const
{
return nullptr;
}
void
nsGenericDOMDataNode::SetXBLBinding(nsXBLBinding* aBinding,
nsBindingManager* aOldBindingManager)
{
}
-nsIContent *
-nsGenericDOMDataNode::GetXBLInsertionPoint() const
+void
+nsGenericDOMDataNode::SetShadowRoot(ShadowRoot* aShadowRoot)
{
- if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
- nsDataSlots *slots = GetExistingDataSlots();
- if (slots) {
- return slots->mXBLInsertionPoint;
- }
- }
-
- return nullptr;
-}
-
-void
-nsGenericDOMDataNode::SetXBLInsertionPoint(nsIContent* aContent)
-{
- if (aContent) {
- nsDataSlots *slots = DataSlots();
- SetFlags(NODE_MAY_BE_IN_BINDING_MNGR);
- slots->mXBLInsertionPoint = aContent;
- } else {
- nsDataSlots *slots = GetExistingDataSlots();
- if (slots) {
- slots->mXBLInsertionPoint = nullptr;
- }
- }
}
bool
nsGenericDOMDataNode::IsNodeOfType(uint32_t aFlags) const
{
return !(aFlags & ~eDATA_NODE);
}
@@ -770,48 +706,16 @@ nsGenericDOMDataNode::DumpContent(FILE*
bool
nsGenericDOMDataNode::IsLink(nsIURI** aURI) const
{
*aURI = nullptr;
return false;
}
-nsINode::nsSlots*
-nsGenericDOMDataNode::CreateSlots()
-{
- return new nsDataSlots();
-}
-
-nsGenericDOMDataNode::nsDataSlots::nsDataSlots()
- : nsINode::nsSlots(), mBindingParent(nullptr)
-{
-}
-
-void
-nsGenericDOMDataNode::nsDataSlots::Traverse(nsCycleCollectionTraversalCallback &cb)
-{
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mXBLInsertionPoint");
- cb.NoteXPCOMChild(mXBLInsertionPoint.get());
-
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mContainingShadow");
- cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mContainingShadow));
-
- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mAssignedSlot");
- cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mAssignedSlot.get()));
-}
-
-void
-nsGenericDOMDataNode::nsDataSlots::Unlink()
-{
- mXBLInsertionPoint = nullptr;
- mContainingShadow = nullptr;
- mAssignedSlot = nullptr;
-}
-
//----------------------------------------------------------------------
// Implementation of the nsIDOMText interface
nsresult
nsGenericDOMDataNode::SplitData(uint32_t aOffset, nsIContent** aReturn,
bool aCloneAfterOriginal)
{
--- a/dom/base/nsGenericDOMDataNode.h
+++ b/dom/base/nsGenericDOMDataNode.h
@@ -153,26 +153,20 @@ public:
const mozilla::fallible_t&) override;
virtual void SaveSubtreeState() override;
#ifdef DEBUG
virtual void List(FILE* out, int32_t aIndent) const override;
virtual void DumpContent(FILE* out, int32_t aIndent, bool aDumpAll) const override;
#endif
- virtual nsIContent* GetBindingParent() const override;
virtual nsXBLBinding* DoGetXBLBinding() const override;
virtual void SetXBLBinding(nsXBLBinding* aBinding,
nsBindingManager* aOldBindingManager = nullptr) override;
- virtual mozilla::dom::ShadowRoot *GetContainingShadow() const override;
virtual void SetShadowRoot(mozilla::dom::ShadowRoot* aShadowRoot) override;
- virtual mozilla::dom::HTMLSlotElement* GetAssignedSlot() const override;
- virtual void SetAssignedSlot(mozilla::dom::HTMLSlotElement* aSlot) override;
- virtual nsIContent *GetXBLInsertionPoint() const override;
- virtual void SetXBLInsertionPoint(nsIContent* aContent) override;
virtual bool IsNodeOfType(uint32_t aFlags) const override;
virtual bool IsLink(nsIURI** aURI) const override;
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
bool aPreallocateChildren) const override
{
nsCOMPtr<nsINode> result = CloneDataNode(aNodeInfo, true);
result.forget(aResult);
@@ -233,67 +227,16 @@ protected:
virtual mozilla::dom::Element* GetNameSpaceElement() override
{
nsINode *parent = GetParentNode();
return parent && parent->IsElement() ? parent->AsElement() : nullptr;
}
- /**
- * There are a set of DOM- and scripting-specific instance variables
- * that may only be instantiated when a content object is accessed
- * through the DOM. Rather than burn actual slots in the content
- * objects for each of these instance variables, we put them off
- * in a side structure that's only allocated when the content is
- * accessed through the DOM.
- */
- class nsDataSlots : public nsINode::nsSlots
- {
- public:
- nsDataSlots();
-
- void Traverse(nsCycleCollectionTraversalCallback &cb);
- void Unlink();
-
- /**
- * The nearest enclosing content node with a binding that created us.
- * @see nsIContent::GetBindingParent
- */
- nsIContent* mBindingParent; // [Weak]
-
- /**
- * @see nsIContent::GetXBLInsertionPoint
- */
- nsCOMPtr<nsIContent> mXBLInsertionPoint;
-
- /**
- * @see nsIContent::GetContainingShadow
- */
- RefPtr<mozilla::dom::ShadowRoot> mContainingShadow;
-
- /**
- * @see nsIContent::GetAssignedSlot
- */
- RefPtr<mozilla::dom::HTMLSlotElement> mAssignedSlot;
- };
-
- // Override from nsINode
- virtual nsINode::nsSlots* CreateSlots() override;
-
- nsDataSlots* DataSlots()
- {
- return static_cast<nsDataSlots*>(Slots());
- }
-
- nsDataSlots *GetExistingDataSlots() const
- {
- return static_cast<nsDataSlots*>(GetExistingSlots());
- }
-
nsresult SplitText(uint32_t aOffset, nsIDOMText** aReturn);
nsresult GetWholeText(nsAString& aWholeText);
static int32_t FirstLogicallyAdjacentTextNode(nsIContent* aParent,
int32_t aIndex);
static int32_t LastLogicallyAdjacentTextNode(nsIContent* aParent,
--- a/dom/base/nsIContent.h
+++ b/dom/base/nsIContent.h
@@ -502,17 +502,21 @@ public:
* frame) responsible for our construction (and existence). Used by
* anonymous content (both XBL-generated and native-anonymous).
*
* null for all explicit content (i.e., content reachable from the top
* of its GetParent() chain via child lists).
*
* @return the binding parent
*/
- virtual nsIContent* GetBindingParent() const = 0;
+ virtual nsIContent* GetBindingParent() const
+ {
+ const nsExtendedContentSlots* slots = GetExistingExtendedContentSlots();
+ return slots ? slots->mBindingParent : nullptr;
+ }
/**
* Gets the current XBL binding that is bound to this element.
*
* @return the current binding.
*/
nsXBLBinding* GetXBLBinding() const
{
@@ -541,16 +545,18 @@ public:
virtual void SetXBLBinding(nsXBLBinding* aBinding,
nsBindingManager* aOldBindingManager = nullptr) = 0;
/**
* Sets the ShadowRoot binding for this element. The contents of the
* binding is rendered in place of this node's children.
*
* @param aShadowRoot The ShadowRoot to be bound to this element.
+ *
+ * FIXME(emilio): No reason this lives in nsIContent, should move to Element.
*/
virtual void SetShadowRoot(mozilla::dom::ShadowRoot* aShadowRoot) = 0;
/**
* Gets the ShadowRoot binding for this element.
*
* @return The ShadowRoot currently bound to this element.
*/
@@ -558,31 +564,39 @@ public:
/**
* Gets the root of the node tree for this content if it is in a shadow tree.
* This method is called |GetContainingShadow| instead of |GetRootShadowRoot|
* to avoid confusion with |GetShadowRoot|.
*
* @return The ShadowRoot that is the root of the node tree.
*/
- virtual mozilla::dom::ShadowRoot *GetContainingShadow() const = 0;
+ mozilla::dom::ShadowRoot* GetContainingShadow() const
+ {
+ const nsExtendedContentSlots* slots = GetExistingExtendedContentSlots();
+ return slots ? slots->mContainingShadow.get() : nullptr;
+ }
/**
* Gets the assigned slot associated with this content.
*
* @return The assigned slot element or null.
*/
- virtual mozilla::dom::HTMLSlotElement* GetAssignedSlot() const = 0;
+ mozilla::dom::HTMLSlotElement* GetAssignedSlot() const
+ {
+ const nsExtendedContentSlots* slots = GetExistingExtendedContentSlots();
+ return slots ? slots->mAssignedSlot.get() : nullptr;
+ }
/**
* Sets the assigned slot associated with this content.
*
* @param aSlot The assigned slot.
*/
- virtual void SetAssignedSlot(mozilla::dom::HTMLSlotElement* aSlot) = 0;
+ void SetAssignedSlot(mozilla::dom::HTMLSlotElement* aSlot);
/**
* Gets the assigned slot associated with this content based on parent's
* shadow root mode. Returns null if parent's shadow root is "closed".
* https://dom.spec.whatwg.org/#dom-slotable-assignedslot
*
* @return The assigned slot element or null.
*/
@@ -595,24 +609,28 @@ public:
}
/**
* Gets the insertion parent element of the XBL binding.
* The insertion parent is our one true parent in the transformed DOM.
*
* @return the insertion parent element.
*/
- virtual nsIContent* GetXBLInsertionPoint() const = 0;
+ nsIContent* GetXBLInsertionPoint() const
+ {
+ const nsExtendedContentSlots* slots = GetExistingExtendedContentSlots();
+ return slots ? slots->mXBLInsertionPoint.get() : nullptr;
+ }
/**
* Sets the insertion parent element of the XBL binding.
*
* @param aContent The insertion parent element.
*/
- virtual void SetXBLInsertionPoint(nsIContent* aContent) = 0;
+ void SetXBLInsertionPoint(nsIContent* aContent);
/**
* Same as GetFlattenedTreeParentNode, but returns null if the parent is
* non-nsIContent.
*/
inline nsIContent *GetFlattenedTreeParent() const;
// Helper method, which we leave public so that it's accessible from nsINode.
@@ -845,16 +863,124 @@ public:
virtual already_AddRefed<nsITextControlElement> GetAsTextControlElement()
{
return nullptr;
}
protected:
/**
+ * Lazily allocated extended slots to avoid
+ * that may only be instantiated when a content object is accessed
+ * through the DOM. Rather than burn actual slots in the content
+ * objects for each of these instance variables, we put them off
+ * in a side structure that's only allocated when the content is
+ * accessed through the DOM.
+ */
+ class nsExtendedContentSlots
+ {
+ public:
+ nsExtendedContentSlots();
+ virtual ~nsExtendedContentSlots();
+
+ virtual void Traverse(nsCycleCollectionTraversalCallback&);
+ virtual void Unlink();
+
+ /**
+ * The nearest enclosing content node with a binding that created us.
+ * @see nsIContent::GetBindingParent
+ */
+ nsIContent* mBindingParent; // [Weak]
+
+ /**
+ * @see nsIContent::GetXBLInsertionPoint
+ */
+ nsCOMPtr<nsIContent> mXBLInsertionPoint;
+
+ /**
+ * @see nsIContent::GetContainingShadow
+ */
+ RefPtr<mozilla::dom::ShadowRoot> mContainingShadow;
+
+ /**
+ * @see nsIContent::GetAssignedSlot
+ */
+ RefPtr<mozilla::dom::HTMLSlotElement> mAssignedSlot;
+ };
+
+ class nsContentSlots : public nsINode::nsSlots
+ {
+ public:
+ void Traverse(nsCycleCollectionTraversalCallback& aCb) override
+ {
+ nsINode::nsSlots::Traverse(aCb);
+ if (mExtendedSlots) {
+ mExtendedSlots->Traverse(aCb);
+ }
+ }
+
+ void Unlink() override
+ {
+ nsINode::nsSlots::Unlink();
+ if (mExtendedSlots) {
+ mExtendedSlots->Unlink();
+ }
+ }
+
+ mozilla::UniquePtr<nsExtendedContentSlots> mExtendedSlots;
+ };
+
+ // Override from nsINode
+ nsContentSlots* CreateSlots() override
+ {
+ return new nsContentSlots();
+ }
+
+ nsContentSlots* ContentSlots()
+ {
+ return static_cast<nsContentSlots*>(Slots());
+ }
+
+ const nsContentSlots* GetExistingContentSlots() const
+ {
+ return static_cast<nsContentSlots*>(GetExistingSlots());
+ }
+
+ nsContentSlots* GetExistingContentSlots()
+ {
+ return static_cast<nsContentSlots*>(GetExistingSlots());
+ }
+
+ virtual nsExtendedContentSlots* CreateExtendedSlots()
+ {
+ return new nsExtendedContentSlots();
+ }
+
+ const nsExtendedContentSlots* GetExistingExtendedContentSlots() const
+ {
+ const nsContentSlots* slots = GetExistingContentSlots();
+ return slots ? slots->mExtendedSlots.get() : nullptr;
+ }
+
+ nsExtendedContentSlots* GetExistingExtendedContentSlots()
+ {
+ nsContentSlots* slots = GetExistingContentSlots();
+ return slots ? slots->mExtendedSlots.get() : nullptr;
+ }
+
+ nsExtendedContentSlots* ExtendedContentSlots()
+ {
+ nsContentSlots* slots = ContentSlots();
+ if (!slots->mExtendedSlots) {
+ slots->mExtendedSlots.reset(CreateExtendedSlots());
+ }
+ return slots->mExtendedSlots.get();
+ }
+
+ /**
* Hook for implementing GetID. This is guaranteed to only be
* called if HasID() is true.
*/
nsAtom* DoGetID() const;
/**
* Returns the assigned slot, if it exists, or the direct parent, if it's a
* fallback content of a slot.
--- a/dom/base/nsINode.h
+++ b/dom/base/nsINode.h
@@ -1107,18 +1107,18 @@ public:
{
public:
nsSlots();
// If needed we could remove the vtable pointer this dtor causes by
// putting a DestroySlots function on nsINode
virtual ~nsSlots();
- void Traverse(nsCycleCollectionTraversalCallback &cb);
- void Unlink();
+ virtual void Traverse(nsCycleCollectionTraversalCallback&);
+ virtual void Unlink();
/**
* A list of mutation observers
*/
nsAutoTObserverArray<nsIMutationObserver*, 1> mMutationObservers;
/**
* An object implementing nsIDOMNodeList for this content (childNodes)
--- a/dom/xul/nsXULElement.cpp
+++ b/dom/xul/nsXULElement.cpp
@@ -1675,22 +1675,16 @@ void
nsXULElement::DoCommand()
{
nsCOMPtr<nsIDocument> doc = GetComposedDoc(); // strong just in case
if (doc) {
nsContentUtils::DispatchXULCommand(this, true);
}
}
-nsIContent *
-nsXULElement::GetBindingParent() const
-{
- return mBindingParent;
-}
-
bool
nsXULElement::IsNodeOfType(uint32_t aFlags) const
{
return false;
}
nsresult
nsXULElement::AddPopupListener(nsAtom* aName)
--- a/dom/xul/nsXULElement.h
+++ b/dom/xul/nsXULElement.h
@@ -379,17 +379,21 @@ public:
{
}
#endif
virtual bool PerformAccesskey(bool aKeyCausesActivation,
bool aIsTrustedEvent) override;
void ClickWithInputSource(uint16_t aInputSource, bool aIsTrustedEvent);
- virtual nsIContent *GetBindingParent() const override;
+ nsIContent* GetBindingParent() const final
+ {
+ return mBindingParent;
+ }
+
virtual bool IsNodeOfType(uint32_t aFlags) const override;
virtual bool IsFocusableInternal(int32_t* aTabIndex, bool aWithMouse) override;
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) override;
virtual nsChangeHint GetAttributeChangeHint(const nsAtom* aAttribute,
int32_t aModType) const override;
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
--- a/servo/components/style/gecko/wrapper.rs
+++ b/servo/components/style/gecko/wrapper.rs
@@ -531,18 +531,19 @@ impl<'le> GeckoElement<'le> {
let slots = self.as_node().0.mSlots as *const structs::FragmentOrElement_nsDOMSlots;
unsafe { slots.as_ref() }
}
/// Returns a reference to the extended DOM slots for this Element.
fn get_extended_slots(
&self,
) -> Option<&structs::FragmentOrElement_nsExtendedDOMSlots> {
- self.get_dom_slots()
- .and_then(|s| unsafe { s.mExtendedSlots.mPtr.as_ref() })
+ self.get_dom_slots().and_then(|s| unsafe {
+ (s._base.mExtendedSlots.mPtr as *const _).as_ref()
+ })
}
#[inline]
fn may_be_in_binding_manager(&self) -> bool {
self.flags() & (structs::NODE_MAY_BE_IN_BINDING_MNGR as u32) != 0
}
#[inline]
@@ -587,17 +588,17 @@ impl<'le> GeckoElement<'le> {
});
binding_parent
}
}
fn get_non_xul_xbl_binding_parent_raw_content(&self) -> *mut nsIContent {
debug_assert!(!self.is_xul_element());
self.get_extended_slots()
- .map_or(ptr::null_mut(), |slots| slots.mBindingParent)
+ .map_or(ptr::null_mut(), |slots| slots._base.mBindingParent)
}
fn has_xbl_binding_parent(&self) -> bool {
if self.is_xul_element() {
// FIXME(heycam): Having trouble with bindgen on nsXULElement,
// where the binding parent is stored in a member variable
// rather than in slots. So just get it through FFI for now.
unsafe { bindings::Gecko_GetBindingParent(self.0).is_some() }