Bug 1333580 - Properly unregister last unobserved target. r?mrbkap
MozReview-Commit-ID: FfPJFSXeT98
--- a/dom/base/DOMIntersectionObserver.cpp
+++ b/dom/base/DOMIntersectionObserver.cpp
@@ -154,34 +154,36 @@ DOMIntersectionObserver::Observe(Element
aTarget.RegisterIntersectionObserver(this);
mObservationTargets.PutEntry(&aTarget);
Connect();
}
void
DOMIntersectionObserver::Unobserve(Element& aTarget)
{
- if (UnlinkTarget(aTarget)) {
- aTarget.UnregisterIntersectionObserver(this);
+ if (mObservationTargets.Count() == 1) {
+ Disconnect();
+ return;
}
+
+ mObservationTargets.RemoveEntry(&aTarget);
+ aTarget.UnregisterIntersectionObserver(this);
}
-bool
+void
DOMIntersectionObserver::UnlinkTarget(Element& aTarget)
{
if (!mObservationTargets.Contains(&aTarget)) {
- return false;
+ return;
}
mObservationTargets.RemoveEntry(&aTarget);
if (mObservationTargets.Count() == 0) {
Disconnect();
- return false;
}
- return true;
}
void
DOMIntersectionObserver::Connect()
{
if (mConnected) {
return;
}
--- a/dom/base/DOMIntersectionObserver.h
+++ b/dom/base/DOMIntersectionObserver.h
@@ -96,17 +96,19 @@ protected:
#define NS_DOM_INTERSECTION_OBSERVER_IID \
{ 0x8570a575, 0xe303, 0x4d18, \
{ 0xb6, 0xb1, 0x4d, 0x2b, 0x49, 0xd8, 0xef, 0x94 } }
class DOMIntersectionObserver final : public nsISupports,
public nsWrapperCache
{
- virtual ~DOMIntersectionObserver() { }
+ virtual ~DOMIntersectionObserver() {
+ Disconnect();
+ }
public:
DOMIntersectionObserver(already_AddRefed<nsPIDOMWindowInner>&& aOwner,
mozilla::dom::IntersectionCallback& aCb)
: mOwner(aOwner), mCallback(&aCb), mConnected(false)
{
}
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@@ -137,17 +139,17 @@ public:
return mRoot;
}
void GetRootMargin(mozilla::dom::DOMString& aRetVal);
void GetThresholds(nsTArray<double>& aRetVal);
void Observe(Element& aTarget);
void Unobserve(Element& aTarget);
- bool UnlinkTarget(Element& aTarget);
+ void UnlinkTarget(Element& aTarget);
void Disconnect();
void TakeRecords(nsTArray<RefPtr<DOMIntersectionObserverEntry>>& aRetVal);
mozilla::dom::IntersectionCallback* IntersectionCallback() { return mCallback; }
bool SetRootMargin(const nsAString& aString);
new file mode 100644
--- /dev/null
+++ b/dom/base/crashtests/1332939.html
@@ -0,0 +1,16 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<script type="application/javascript">
+
+var target = document.createElement("div");
+target.foo = 'bar';
+var observer = new IntersectionObserver(function () { });
+observer.observe(target);
+observer.unobserve(target);
+observer = null;
+target = null;
+
+</script>
+</head>
+</html>
--- a/dom/base/crashtests/crashtests.list
+++ b/dom/base/crashtests/crashtests.list
@@ -206,8 +206,9 @@ HTTP(..) load xhr_abortinprogress.html
load xhr_empty_datauri.html
load xhr_html_nullresponse.html
load 1230422.html
load 1251361.html
load 1304437.html
pref(dom.IntersectionObserver.enabled,true) load 1324209.html
pref(dom.IntersectionObserver.enabled,true) load 1326194-1.html
pref(dom.IntersectionObserver.enabled,true) load 1326194-2.html
+pref(dom.IntersectionObserver.enabled,true) load 1332939.html