OSDN Git Service

Fixes a WebKit bug where ongoing Geolocation requests are not stopped when the page...
authorSteve Block <steveblock@google.com>
Tue, 6 Oct 2009 09:57:53 +0000 (10:57 +0100)
committerSteve Block <steveblock@google.com>
Tue, 6 Oct 2009 09:57:53 +0000 (10:57 +0100)
This fixes bug http://b/issue?id=2164673

Change-Id: I68a615c0b82bcee2a4a61dc0433a4f9321780ad1

WebCore/page/Geolocation.cpp
WebCore/page/Geolocation.h

index d7e0cc3..38411ce 100644 (file)
@@ -30,6 +30,7 @@
 #include "Chrome.h"
 #include "CurrentTime.h"
 #include "Document.h"
+#include "EventNames.h"
 #include "Frame.h"
 #include "Page.h"
 #include "SQLiteDatabase.h"
@@ -249,6 +250,15 @@ Geolocation::Geolocation(Frame* frame)
         return;
     ASSERT(m_frame->document());
     m_frame->document()->setUsingGeolocation(true);
+
+    if (m_frame->domWindow())
+        m_frame->domWindow()->addEventListener(eventNames().unloadEvent, this, false);
+}
+
+Geolocation::~Geolocation()
+{
+    if (m_frame && m_frame->domWindow())
+        m_frame->domWindow()->removeEventListener(eventNames().unloadEvent, this, false);
 }
 
 void Geolocation::disconnectFrame()
@@ -552,6 +562,16 @@ void Geolocation::geolocationServiceErrorOccurred(GeolocationService* service)
     handleError(service->lastError());
 }
 
+void Geolocation::handleEvent(Event* event, bool)
+{
+  ASSERT_UNUSED(event, event->type() == eventTypes().unloadEvent);
+  // Cancel any ongoing requests on page unload. This is required to release
+  // references to JS callbacks in the page, to allow the frame to be cleaned up
+  // by WebKit.
+  m_oneShots.clear();
+  m_watchers.clear();
+}
+
 void Geolocation::setDatabasePath(String databasePath)
 {
     CachedPositionManager::setDatabasePath(databasePath);
index c97c3e6..9b3b43f 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef Geolocation_h
 #define Geolocation_h
 
+#include "EventListener.h"
 #include "GeolocationService.h"
 #include "Geoposition.h"
 #include "PositionCallback.h"
@@ -48,11 +49,11 @@ class Frame;
 class CachedPositionManager;
 
 
-class Geolocation : public RefCounted<Geolocation>, public GeolocationServiceClient {
+class Geolocation : public GeolocationServiceClient, public EventListener {
 public:
     static PassRefPtr<Geolocation> create(Frame* frame) { return adoptRef(new Geolocation(frame)); }
 
-    virtual ~Geolocation() {}
+    virtual ~Geolocation();
 
     void disconnectFrame();
     
@@ -118,6 +119,9 @@ private:
     virtual void geolocationServicePositionChanged(GeolocationService*);
     virtual void geolocationServiceErrorOccurred(GeolocationService*);
 
+    // EventListener
+    virtual void handleEvent(Event*, bool isWindowEvent);
+
     void fatalErrorOccurred(GeoNotifier* notifier);
     void requestTimedOut(GeoNotifier* notifier);
     void requestReturnedCachedPosition(GeoNotifier* notifier);