Bug 1441136: Add a fast way to enumerate ShadowRoots in a document. r=smaug
MozReview-Commit-ID: 7QffP56jsyk
This commit is contained in:
@@ -81,12 +81,35 @@ ShadowRoot::~ShadowRoot()
|
|||||||
host->RemoveMutationObserver(this);
|
host->RemoveMutationObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsComposedDocParticipant()) {
|
||||||
|
OwnerDoc()->RemoveComposedDocShadowRoot(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(!OwnerDoc()->IsComposedDocShadowRoot(*this));
|
||||||
|
|
||||||
UnsetFlags(NODE_IS_IN_SHADOW_TREE);
|
UnsetFlags(NODE_IS_IN_SHADOW_TREE);
|
||||||
|
|
||||||
// nsINode destructor expects mSubtreeRoot == this.
|
// nsINode destructor expects mSubtreeRoot == this.
|
||||||
SetSubtreeRootPointer(this);
|
SetSubtreeRootPointer(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShadowRoot::SetIsComposedDocParticipant(bool aIsComposedDocParticipant)
|
||||||
|
{
|
||||||
|
bool changed = mIsComposedDocParticipant != aIsComposedDocParticipant;
|
||||||
|
mIsComposedDocParticipant = aIsComposedDocParticipant;
|
||||||
|
if (!changed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIDocument* doc = OwnerDoc();
|
||||||
|
if (IsComposedDocParticipant()) {
|
||||||
|
doc->AddComposedDocShadowRoot(*this);
|
||||||
|
} else {
|
||||||
|
doc->RemoveComposedDocShadowRoot(*this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
JSObject*
|
JSObject*
|
||||||
ShadowRoot::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
ShadowRoot::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -186,10 +186,7 @@ public:
|
|||||||
return mIsComposedDocParticipant;
|
return mIsComposedDocParticipant;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetIsComposedDocParticipant(bool aIsComposedDocParticipant)
|
void SetIsComposedDocParticipant(bool aIsComposedDocParticipant);
|
||||||
{
|
|
||||||
mIsComposedDocParticipant = aIsComposedDocParticipant;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
|
nsresult GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
|
||||||
|
|
||||||
|
|||||||
@@ -8638,6 +8638,7 @@ nsIDocument::DestroyElementMaps()
|
|||||||
#endif
|
#endif
|
||||||
mStyledLinks.Clear();
|
mStyledLinks.Clear();
|
||||||
mIdentifierMap.Clear();
|
mIdentifierMap.Clear();
|
||||||
|
mComposedShadowRoots.Clear();
|
||||||
mResponsiveContent.Clear();
|
mResponsiveContent.Clear();
|
||||||
IncrementExpandoGeneration(*this);
|
IncrementExpandoGeneration(*this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2967,6 +2967,33 @@ public:
|
|||||||
mResponsiveContent.RemoveEntry(aContent);
|
mResponsiveContent.RemoveEntry(aContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddComposedDocShadowRoot(mozilla::dom::ShadowRoot& aShadowRoot)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(IsShadowDOMEnabled());
|
||||||
|
mComposedShadowRoots.PutEntry(&aShadowRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
using ShadowRootSet = nsTHashtable<nsPtrHashKey<mozilla::dom::ShadowRoot>>;
|
||||||
|
|
||||||
|
void RemoveComposedDocShadowRoot(mozilla::dom::ShadowRoot& aShadowRoot)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(IsShadowDOMEnabled());
|
||||||
|
mComposedShadowRoots.RemoveEntry(&aShadowRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If you're considering using this, you probably want to use
|
||||||
|
// ShadowRoot::IsComposedDocParticipant instead. This is just for
|
||||||
|
// sanity-checking.
|
||||||
|
bool IsComposedDocShadowRoot(mozilla::dom::ShadowRoot& aShadowRoot)
|
||||||
|
{
|
||||||
|
return mComposedShadowRoots.Contains(&aShadowRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ShadowRootSet& ComposedShadowRoots() const
|
||||||
|
{
|
||||||
|
return mComposedShadowRoots;
|
||||||
|
}
|
||||||
|
|
||||||
// Notifies any responsive content added by AddResponsiveContent upon media
|
// Notifies any responsive content added by AddResponsiveContent upon media
|
||||||
// features values changing.
|
// features values changing.
|
||||||
void NotifyMediaFeatureValuesChanged();
|
void NotifyMediaFeatureValuesChanged();
|
||||||
@@ -3758,6 +3785,11 @@ protected:
|
|||||||
// Tracking for images in the document.
|
// Tracking for images in the document.
|
||||||
RefPtr<mozilla::dom::ImageTracker> mImageTracker;
|
RefPtr<mozilla::dom::ImageTracker> mImageTracker;
|
||||||
|
|
||||||
|
// A hashtable of ShadowRoots belonging to the composed doc.
|
||||||
|
//
|
||||||
|
// See ShadowRoot::SetIsComposedDocParticipant.
|
||||||
|
ShadowRootSet mComposedShadowRoots;
|
||||||
|
|
||||||
// The set of all object, embed, video/audio elements or
|
// The set of all object, embed, video/audio elements or
|
||||||
// nsIObjectLoadingContent or nsIDocumentActivity for which this is the owner
|
// nsIObjectLoadingContent or nsIDocumentActivity for which this is the owner
|
||||||
// document. (They might not be in the document.)
|
// document. (They might not be in the document.)
|
||||||
|
|||||||
@@ -168,26 +168,6 @@ ServoStyleSet::Init(nsPresContext* aPresContext)
|
|||||||
SetStylistXBLStyleSheetsDirty();
|
SetStylistXBLStyleSheetsDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Functor>
|
|
||||||
void
|
|
||||||
EnumerateShadowRootsInSubtree(const nsINode& aRoot, const Functor& aCb)
|
|
||||||
{
|
|
||||||
for (const nsINode* cur = &aRoot; cur; cur = cur->GetNextNode()) {
|
|
||||||
if (!cur->IsElement()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* shadowRoot = cur->AsElement()->GetShadowRoot();
|
|
||||||
if (!shadowRoot) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
aCb(*shadowRoot);
|
|
||||||
EnumerateShadowRootsInSubtree(*shadowRoot, aCb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME(emilio): We may want a faster way to do this.
|
|
||||||
template<typename Functor>
|
template<typename Functor>
|
||||||
void
|
void
|
||||||
EnumerateShadowRoots(const nsIDocument& aDoc, const Functor& aCb)
|
EnumerateShadowRoots(const nsIDocument& aDoc, const Functor& aCb)
|
||||||
@@ -196,7 +176,13 @@ EnumerateShadowRoots(const nsIDocument& aDoc, const Functor& aCb)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
EnumerateShadowRootsInSubtree(aDoc, aCb);
|
const nsIDocument::ShadowRootSet& shadowRoots = aDoc.ComposedShadowRoots();
|
||||||
|
for (auto iter = shadowRoots.ConstIter(); !iter.Done(); iter.Next()) {
|
||||||
|
ShadowRoot* root = iter.Get()->GetKey();
|
||||||
|
MOZ_ASSERT(root);
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(root->IsComposedDocParticipant());
|
||||||
|
aCb(*root);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
Reference in New Issue
Block a user