mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-07 21:43:24 +00:00
Bug 1316277 - Move intersection observer list from DOMSlots to a property. r=mrbkap
--HG-- extra : rebase_source : fcaa7d31e0a99ad666e0091c56cd9858e3afcc4b
This commit is contained in:
parent
4e3feba463
commit
7c9837e0e8
@ -4194,13 +4194,6 @@ Element::ClearDataset()
|
||||
slots->mDataset = nullptr;
|
||||
}
|
||||
|
||||
nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>*
|
||||
Element::RegisteredIntersectionObservers()
|
||||
{
|
||||
nsExtendedDOMSlots* slots = ExtendedDOMSlots();
|
||||
return &slots->mRegisteredIntersectionObservers;
|
||||
}
|
||||
|
||||
enum nsPreviousIntersectionThreshold {
|
||||
eUninitialized = -2,
|
||||
eNonIntersecting = -1
|
||||
@ -4209,7 +4202,20 @@ enum nsPreviousIntersectionThreshold {
|
||||
void
|
||||
Element::RegisterIntersectionObserver(DOMIntersectionObserver* aObserver)
|
||||
{
|
||||
RegisteredIntersectionObservers()->LookupForAdd(aObserver).OrInsert([]() {
|
||||
IntersectionObserverList* observers =
|
||||
static_cast<IntersectionObserverList*>(
|
||||
GetProperty(nsGkAtoms::intersectionobserverlist)
|
||||
);
|
||||
|
||||
if (!observers) {
|
||||
observers = new IntersectionObserverList();
|
||||
observers->Put(aObserver, eUninitialized);
|
||||
SetProperty(nsGkAtoms::intersectionobserverlist, observers,
|
||||
nsINode::DeleteProperty<IntersectionObserverList>);
|
||||
return;
|
||||
}
|
||||
|
||||
observers->LookupForAdd(aObserver).OrInsert([]() {
|
||||
// Value can be:
|
||||
// -2: Makes sure next calculated threshold always differs, leading to a
|
||||
// notification task being scheduled.
|
||||
@ -4222,14 +4228,44 @@ Element::RegisterIntersectionObserver(DOMIntersectionObserver* aObserver)
|
||||
void
|
||||
Element::UnregisterIntersectionObserver(DOMIntersectionObserver* aObserver)
|
||||
{
|
||||
RegisteredIntersectionObservers()->Remove(aObserver);
|
||||
IntersectionObserverList* observers =
|
||||
static_cast<IntersectionObserverList*>(
|
||||
GetProperty(nsGkAtoms::intersectionobserverlist)
|
||||
);
|
||||
if (observers) {
|
||||
observers->Remove(aObserver);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Element::UnlinkIntersectionObservers()
|
||||
{
|
||||
IntersectionObserverList* observers =
|
||||
static_cast<IntersectionObserverList*>(
|
||||
GetProperty(nsGkAtoms::intersectionobserverlist)
|
||||
);
|
||||
if (!observers) {
|
||||
return;
|
||||
}
|
||||
for (auto iter = observers->Iter(); !iter.Done(); iter.Next()) {
|
||||
DOMIntersectionObserver* observer = iter.Key();
|
||||
observer->UnlinkTarget(*this);
|
||||
}
|
||||
observers->Clear();
|
||||
}
|
||||
|
||||
bool
|
||||
Element::UpdateIntersectionObservation(DOMIntersectionObserver* aObserver, int32_t aThreshold)
|
||||
{
|
||||
IntersectionObserverList* observers =
|
||||
static_cast<IntersectionObserverList*>(
|
||||
GetProperty(nsGkAtoms::intersectionobserverlist)
|
||||
);
|
||||
if (!observers) {
|
||||
return false;
|
||||
}
|
||||
bool updated = false;
|
||||
if (auto entry = RegisteredIntersectionObservers()->Lookup(aObserver)) {
|
||||
if (auto entry = observers->Lookup(aObserver)) {
|
||||
updated = entry.Data() != aThreshold;
|
||||
entry.Data() = aThreshold;
|
||||
}
|
||||
|
@ -73,6 +73,8 @@ namespace dom {
|
||||
class ElementOrCSSPseudoElement;
|
||||
class UnrestrictedDoubleOrKeyframeAnimationOptions;
|
||||
enum class CallerType : uint32_t;
|
||||
typedef nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>
|
||||
IntersectionObserverList;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@ -1436,6 +1438,7 @@ public:
|
||||
|
||||
void RegisterIntersectionObserver(DOMIntersectionObserver* aObserver);
|
||||
void UnregisterIntersectionObserver(DOMIntersectionObserver* aObserver);
|
||||
void UnlinkIntersectionObservers();
|
||||
bool UpdateIntersectionObservation(DOMIntersectionObserver* aObserver, int32_t threshold);
|
||||
|
||||
protected:
|
||||
@ -1721,9 +1724,6 @@ protected:
|
||||
nsDOMTokenList* GetTokenList(nsIAtom* aAtom,
|
||||
const DOMTokenListSupportedTokenArray aSupportedTokens = nullptr);
|
||||
|
||||
nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>*
|
||||
RegisteredIntersectionObservers();
|
||||
|
||||
private:
|
||||
/**
|
||||
* Hook for implementing GetClasses. This is guaranteed to only be
|
||||
|
@ -816,14 +816,6 @@ FragmentOrElement::nsDOMSlots::Traverse(nsCycleCollectionTraversalCallback &cb)
|
||||
}
|
||||
}
|
||||
|
||||
for (auto iter = mExtendedSlots->mRegisteredIntersectionObservers.Iter();
|
||||
!iter.Done(); iter.Next()) {
|
||||
DOMIntersectionObserver* observer = iter.Key();
|
||||
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);
|
||||
}
|
||||
@ -856,7 +848,6 @@ FragmentOrElement::nsDOMSlots::Unlink()
|
||||
}
|
||||
mExtendedSlots->mCustomElementData = nullptr;
|
||||
}
|
||||
mExtendedSlots->mRegisteredIntersectionObservers.Clear();
|
||||
nsCOMPtr<nsIFrameLoader> frameLoader =
|
||||
do_QueryInterface(mExtendedSlots->mFrameLoaderOrOpener);
|
||||
if (frameLoader) {
|
||||
@ -1563,6 +1554,11 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(FragmentOrElement)
|
||||
// which is dispatched in UnbindFromTree.
|
||||
|
||||
if (tmp->HasProperties()) {
|
||||
if (tmp->IsElement()) {
|
||||
Element* elem = tmp->AsElement();
|
||||
elem->UnlinkIntersectionObservers();
|
||||
}
|
||||
|
||||
if (tmp->IsHTMLElement() || tmp->IsSVGElement()) {
|
||||
nsIAtom*** props = Element::HTMLSVGPropertiesToTraverseAndUnlink();
|
||||
for (uint32_t i = 0; props[i]; ++i) {
|
||||
@ -1617,14 +1613,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(FragmentOrElement)
|
||||
{
|
||||
nsDOMSlots *slots = tmp->GetExistingDOMSlots();
|
||||
if (slots) {
|
||||
if (slots->mExtendedSlots && tmp->IsElement()) {
|
||||
Element* elem = tmp->AsElement();
|
||||
for (auto iter = slots->mExtendedSlots->mRegisteredIntersectionObservers.Iter();
|
||||
!iter.Done(); iter.Next()) {
|
||||
DOMIntersectionObserver* observer = iter.Key();
|
||||
observer->UnlinkTarget(*elem);
|
||||
}
|
||||
}
|
||||
slots->Unlink();
|
||||
}
|
||||
}
|
||||
@ -2145,6 +2133,19 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(FragmentOrElement)
|
||||
#endif
|
||||
|
||||
if (tmp->HasProperties()) {
|
||||
if (tmp->IsElement()) {
|
||||
Element* elem = tmp->AsElement();
|
||||
IntersectionObserverList* observers =
|
||||
static_cast<IntersectionObserverList*>(
|
||||
elem->GetProperty(nsGkAtoms::intersectionobserverlist)
|
||||
);
|
||||
if (observers) {
|
||||
for (auto iter = observers->Iter(); !iter.Done(); iter.Next()) {
|
||||
DOMIntersectionObserver* observer = iter.Key();
|
||||
cb.NoteXPCOMChild(observer);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tmp->IsHTMLElement() || tmp->IsSVGElement()) {
|
||||
nsIAtom*** props = Element::HTMLSVGPropertiesToTraverseAndUnlink();
|
||||
for (uint32_t i = 0; props[i]; ++i) {
|
||||
|
@ -40,7 +40,6 @@ namespace mozilla {
|
||||
class DeclarationBlock;
|
||||
namespace dom {
|
||||
struct CustomElementData;
|
||||
class DOMIntersectionObserver;
|
||||
class Element;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
@ -313,12 +312,6 @@ public:
|
||||
*/
|
||||
RefPtr<CustomElementData> mCustomElementData;
|
||||
|
||||
/**
|
||||
* Registered Intersection Observers on the element.
|
||||
*/
|
||||
nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>
|
||||
mRegisteredIntersectionObservers;
|
||||
|
||||
/**
|
||||
* For XUL to hold either frameloader or opener.
|
||||
*/
|
||||
|
@ -582,6 +582,7 @@ GK_ATOM(int64, "int64")
|
||||
GK_ATOM(integer, "integer")
|
||||
GK_ATOM(integrity, "integrity")
|
||||
GK_ATOM(intersection, "intersection")
|
||||
GK_ATOM(intersectionobserverlist, "intersectionobserverlist")
|
||||
GK_ATOM(is, "is")
|
||||
GK_ATOM(iscontainer, "iscontainer")
|
||||
GK_ATOM(isempty, "isempty")
|
||||
|
@ -293,19 +293,6 @@ nsNodeUtils::LastRelease(nsINode* aNode)
|
||||
NodeWillBeDestroyed, (aNode));
|
||||
}
|
||||
|
||||
if (aNode->IsElement()) {
|
||||
Element* elem = aNode->AsElement();
|
||||
FragmentOrElement::nsDOMSlots* domSlots =
|
||||
static_cast<FragmentOrElement::nsDOMSlots*>(slots);
|
||||
if (domSlots->mExtendedSlots) {
|
||||
for (auto iter = domSlots->mExtendedSlots->mRegisteredIntersectionObservers.Iter();
|
||||
!iter.Done(); iter.Next()) {
|
||||
DOMIntersectionObserver* observer = iter.Key();
|
||||
observer->UnlinkTarget(*elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete slots;
|
||||
aNode->mSlots = nullptr;
|
||||
}
|
||||
@ -320,6 +307,12 @@ nsNodeUtils::LastRelease(nsINode* aNode)
|
||||
}
|
||||
else {
|
||||
if (aNode->HasProperties()) {
|
||||
if (aNode->IsElement()) {
|
||||
Element* elem = aNode->AsElement();
|
||||
elem->UnlinkIntersectionObservers();
|
||||
elem->DeleteProperty(nsGkAtoms::intersectionobserverlist);
|
||||
}
|
||||
|
||||
// Strong reference to the document so that deleting properties can't
|
||||
// delete the document.
|
||||
nsCOMPtr<nsIDocument> document = aNode->OwnerDoc();
|
||||
|
Loading…
Reference in New Issue
Block a user