Simplify DOMWindowProperty code / handling
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 10 Mar 2019 02:25:42 +0000 (02:25 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 10 Mar 2019 02:25:42 +0000 (02:25 +0000)
https://bugs.webkit.org/show_bug.cgi?id=195495

Reviewed by Ryosuke Niwa.

DOMWindowProperty code was unnecessarily complex because DOMWindowExtension inherited
from it and DOMWindowExtension needs a lot of information about the global object's
lifetime to communicate to the injected bbundle client. This subclassing is also
very confusing because a DOMWindowExtension is not a *property* on the Window object.

This patch updates DOMWindowExtension to stop subclassing DOMWindowProperty and
moves all the complexity from DOMWindowProperty to DOMWindowExtension.
DOMWindowProperty is now a very simple base class which merely has a WeakPtr to
the window and getters for the window and the frame.

* Modules/indexeddb/DOMWindowIndexedDatabase.cpp:
(WebCore::DOMWindowIndexedDatabase::DOMWindowIndexedDatabase):
(WebCore::DOMWindowIndexedDatabase::indexedDB):
* Modules/indexeddb/DOMWindowIndexedDatabase.h:
There is no reason for DOMWindowIndexedDatabase to move its IDBFactory to a
separate data member which in PageCache. Script do not run while in PageCache.
Also, frames are nulled out while in the PageCache so the indexedDB() getter
would return null anyway while in PageCache.

* css/StyleMedia.idl:
* loader/appcache/ApplicationCacheHost.cpp:
(WebCore::ApplicationCacheHost::setDOMApplicationCache):
Store a WeakPtr to the DOMApplicationCache for safety.

(WebCore::ApplicationCacheHost::dispatchDOMEvent):
Do not fire events on the DOMApplicationCache if it is frameless to maintain
previous behavior. Previously, the DOMApplicationCache would have been nulled
out when detached from its frame so we would not have fired events.

* loader/appcache/ApplicationCacheHost.h:
* loader/appcache/DOMApplicationCache.cpp:
* loader/appcache/DOMApplicationCache.h:
Remove some unnecessary complexity. The ApplicationCacheHost is owned by the
DocumentLoader, which changes on navigation. There is therefore no reason to
null out the DOMApplicationCache on the ApplicationCacheHost when its gets
detached from its frame or enters PageCache.

* page/BarProp.idl:
* page/DOMSelection.idl:
* page/DOMWindow.cpp:
(WebCore::DOMWindow::willDestroyCachedFrame):
(WebCore::DOMWindow::willDestroyDocumentInFrame):
(WebCore::DOMWindow::willDetachDocumentFromFrame):
(WebCore::DOMWindow::registerExtension):
(WebCore::DOMWindow::unregisterExtension):

(WebCore::DOMWindow::resetDOMWindowProperties): Removed.
Stop clearing some of the DOMWindow's properties when the document gets destroyed or when
the Window for the initial empty document gets reused on navigation. I think we used to
need this because DOMWindowProperty used to hold pointers to their frame. However, this
is no longer the case nowadays as DOMWindowProperty objects get their frame from their
Window.

(WebCore::DOMWindow::resetUnlessSuspendedForDocumentSuspension):
(WebCore::DOMWindow::suspendForPageCache):
(WebCore::DOMWindow::resumeFromPageCache):
* page/DOMWindow.h:
* page/DOMWindowExtension.cpp:
(WebCore::DOMWindowExtension::DOMWindowExtension):
(WebCore::DOMWindowExtension::~DOMWindowExtension):
(WebCore::DOMWindowExtension::frame const):
(WebCore::DOMWindowExtension::suspendForPageCache):
(WebCore::DOMWindowExtension::resumeFromPageCache):
(WebCore::DOMWindowExtension::willDestroyGlobalObjectInCachedFrame):
(WebCore::DOMWindowExtension::willDestroyGlobalObjectInFrame):
(WebCore::DOMWindowExtension::willDetachGlobalObjectFromFrame):
* page/DOMWindowExtension.h:
* page/DOMWindowProperty.cpp:
(WebCore::DOMWindowProperty::DOMWindowProperty):
* page/DOMWindowProperty.h:
(WebCore::DOMWindowProperty::window const):
* page/History.idl:
* page/Location.idl:
* page/Navigator.cpp:
(WebCore::Navigator::plugins):
(WebCore::Navigator::mimeTypes):
* page/PerformanceNavigation.idl:
* page/PerformanceTiming.idl:
* page/Screen.idl:
* page/VisualViewport.cpp:
(WebCore::VisualViewport::scriptExecutionContext const):
* plugins/DOMMimeTypeArray.idl:
* plugins/DOMPluginArray.idl:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242676 268f45cc-cd09-0410-ab3c-d52691b4dbfc

26 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.cpp
Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.h
Source/WebCore/css/StyleMedia.idl
Source/WebCore/loader/appcache/ApplicationCacheHost.cpp
Source/WebCore/loader/appcache/ApplicationCacheHost.h
Source/WebCore/loader/appcache/DOMApplicationCache.cpp
Source/WebCore/loader/appcache/DOMApplicationCache.h
Source/WebCore/page/BarProp.idl
Source/WebCore/page/DOMSelection.idl
Source/WebCore/page/DOMWindow.cpp
Source/WebCore/page/DOMWindow.h
Source/WebCore/page/DOMWindowExtension.cpp
Source/WebCore/page/DOMWindowExtension.h
Source/WebCore/page/DOMWindowProperty.cpp
Source/WebCore/page/DOMWindowProperty.h
Source/WebCore/page/History.idl
Source/WebCore/page/Location.idl
Source/WebCore/page/Navigator.cpp
Source/WebCore/page/PerformanceNavigation.idl
Source/WebCore/page/PerformanceTiming.idl
Source/WebCore/page/Screen.idl
Source/WebCore/page/VisualViewport.cpp
Source/WebCore/plugins/DOMMimeTypeArray.idl
Source/WebCore/plugins/DOMPluginArray.idl
Source/WebKit/WebProcess/InjectedBundle/API/glib/DOM/DOMObjectCache.cpp

index 5eb1d8d..a07f96e 100644 (file)
@@ -1,3 +1,94 @@
+2019-03-09  Chris Dumez  <cdumez@apple.com>
+
+        Simplify DOMWindowProperty code / handling
+        https://bugs.webkit.org/show_bug.cgi?id=195495
+
+        Reviewed by Ryosuke Niwa.
+
+        DOMWindowProperty code was unnecessarily complex because DOMWindowExtension inherited
+        from it and DOMWindowExtension needs a lot of information about the global object's
+        lifetime to communicate to the injected bbundle client. This subclassing is also
+        very confusing because a DOMWindowExtension is not a *property* on the Window object.
+
+        This patch updates DOMWindowExtension to stop subclassing DOMWindowProperty and
+        moves all the complexity from DOMWindowProperty to DOMWindowExtension.
+        DOMWindowProperty is now a very simple base class which merely has a WeakPtr to
+        the window and getters for the window and the frame.
+
+        * Modules/indexeddb/DOMWindowIndexedDatabase.cpp:
+        (WebCore::DOMWindowIndexedDatabase::DOMWindowIndexedDatabase):
+        (WebCore::DOMWindowIndexedDatabase::indexedDB):
+        * Modules/indexeddb/DOMWindowIndexedDatabase.h:
+        There is no reason for DOMWindowIndexedDatabase to move its IDBFactory to a
+        separate data member which in PageCache. Script do not run while in PageCache.
+        Also, frames are nulled out while in the PageCache so the indexedDB() getter
+        would return null anyway while in PageCache.
+
+        * css/StyleMedia.idl:
+        * loader/appcache/ApplicationCacheHost.cpp:
+        (WebCore::ApplicationCacheHost::setDOMApplicationCache):
+        Store a WeakPtr to the DOMApplicationCache for safety.
+
+        (WebCore::ApplicationCacheHost::dispatchDOMEvent):
+        Do not fire events on the DOMApplicationCache if it is frameless to maintain
+        previous behavior. Previously, the DOMApplicationCache would have been nulled
+        out when detached from its frame so we would not have fired events.
+
+        * loader/appcache/ApplicationCacheHost.h:
+        * loader/appcache/DOMApplicationCache.cpp:
+        * loader/appcache/DOMApplicationCache.h:
+        Remove some unnecessary complexity. The ApplicationCacheHost is owned by the
+        DocumentLoader, which changes on navigation. There is therefore no reason to
+        null out the DOMApplicationCache on the ApplicationCacheHost when its gets
+        detached from its frame or enters PageCache.
+
+        * page/BarProp.idl:
+        * page/DOMSelection.idl:
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::willDestroyCachedFrame):
+        (WebCore::DOMWindow::willDestroyDocumentInFrame):
+        (WebCore::DOMWindow::willDetachDocumentFromFrame):
+        (WebCore::DOMWindow::registerExtension):
+        (WebCore::DOMWindow::unregisterExtension):
+
+        (WebCore::DOMWindow::resetDOMWindowProperties): Removed.
+        Stop clearing some of the DOMWindow's properties when the document gets destroyed or when
+        the Window for the initial empty document gets reused on navigation. I think we used to
+        need this because DOMWindowProperty used to hold pointers to their frame. However, this
+        is no longer the case nowadays as DOMWindowProperty objects get their frame from their
+        Window.
+
+        (WebCore::DOMWindow::resetUnlessSuspendedForDocumentSuspension):
+        (WebCore::DOMWindow::suspendForPageCache):
+        (WebCore::DOMWindow::resumeFromPageCache):
+        * page/DOMWindow.h:
+        * page/DOMWindowExtension.cpp:
+        (WebCore::DOMWindowExtension::DOMWindowExtension):
+        (WebCore::DOMWindowExtension::~DOMWindowExtension):
+        (WebCore::DOMWindowExtension::frame const):
+        (WebCore::DOMWindowExtension::suspendForPageCache):
+        (WebCore::DOMWindowExtension::resumeFromPageCache):
+        (WebCore::DOMWindowExtension::willDestroyGlobalObjectInCachedFrame):
+        (WebCore::DOMWindowExtension::willDestroyGlobalObjectInFrame):
+        (WebCore::DOMWindowExtension::willDetachGlobalObjectFromFrame):
+        * page/DOMWindowExtension.h:
+        * page/DOMWindowProperty.cpp:
+        (WebCore::DOMWindowProperty::DOMWindowProperty):
+        * page/DOMWindowProperty.h:
+        (WebCore::DOMWindowProperty::window const):
+        * page/History.idl:
+        * page/Location.idl:
+        * page/Navigator.cpp:
+        (WebCore::Navigator::plugins):
+        (WebCore::Navigator::mimeTypes):
+        * page/PerformanceNavigation.idl:
+        * page/PerformanceTiming.idl:
+        * page/Screen.idl:
+        * page/VisualViewport.cpp:
+        (WebCore::VisualViewport::scriptExecutionContext const):
+        * plugins/DOMMimeTypeArray.idl:
+        * plugins/DOMPluginArray.idl:
+
 2019-03-09  Zalan Bujtas  <zalan@apple.com>
 
         [ContentChangeObserver] Start observing for content change between touchEnd and mouseMoved start
index 5a61b16..c7203a9 100644 (file)
@@ -38,7 +38,6 @@ namespace WebCore {
 
 DOMWindowIndexedDatabase::DOMWindowIndexedDatabase(DOMWindow* window)
     : DOMWindowProperty(window)
-    , m_window(window)
 {
 }
 
@@ -60,36 +59,6 @@ DOMWindowIndexedDatabase* DOMWindowIndexedDatabase::from(DOMWindow* window)
     return supplement;
 }
 
-void DOMWindowIndexedDatabase::suspendForPageCache()
-{
-    m_suspendedIDBFactory = WTFMove(m_idbFactory);
-    DOMWindowProperty::suspendForPageCache();
-}
-
-void DOMWindowIndexedDatabase::resumeFromPageCache()
-{
-    DOMWindowProperty::resumeFromPageCache();
-    m_idbFactory = WTFMove(m_suspendedIDBFactory);
-}
-
-void DOMWindowIndexedDatabase::willDestroyGlobalObjectInCachedFrame()
-{
-    m_suspendedIDBFactory = nullptr;
-    DOMWindowProperty::willDestroyGlobalObjectInCachedFrame();
-}
-
-void DOMWindowIndexedDatabase::willDestroyGlobalObjectInFrame()
-{
-    m_idbFactory = nullptr;
-    DOMWindowProperty::willDestroyGlobalObjectInFrame();
-}
-
-void DOMWindowIndexedDatabase::willDetachGlobalObjectFromFrame()
-{
-    m_idbFactory = nullptr;
-    DOMWindowProperty::willDetachGlobalObjectFromFrame();
-}
-
 IDBFactory* DOMWindowIndexedDatabase::indexedDB(DOMWindow& window)
 {
     return from(&window)->indexedDB();
@@ -97,15 +66,19 @@ IDBFactory* DOMWindowIndexedDatabase::indexedDB(DOMWindow& window)
 
 IDBFactory* DOMWindowIndexedDatabase::indexedDB()
 {
-    Document* document = m_window->document();
+    auto* window = this->window();
+    if (!window)
+        return nullptr;
+
+    auto* document = window->document();
     if (!document)
         return nullptr;
 
-    Page* page = document->page();
+    auto* page = document->page();
     if (!page)
         return nullptr;
 
-    if (!m_window->isCurrentlyDisplayedInFrame())
+    if (!window->isCurrentlyDisplayedInFrame())
         return nullptr;
 
     if (!m_idbFactory) {
index 3cee89f..dc2b4e9 100644 (file)
@@ -45,19 +45,11 @@ public:
 
     WEBCORE_EXPORT static IDBFactory* indexedDB(DOMWindow&);
 
-    void suspendForPageCache() override;
-    void resumeFromPageCache() override;
-    void willDestroyGlobalObjectInCachedFrame() override;
-    void willDestroyGlobalObjectInFrame() override;
-    void willDetachGlobalObjectFromFrame() override;
-
 private:
     IDBFactory* indexedDB();
     static const char* supplementName();
 
-    DOMWindow* m_window;
     RefPtr<IDBFactory> m_idbFactory;
-    RefPtr<IDBFactory> m_suspendedIDBFactory;
 };
 
 } // namespace WebCore
index d7ad549..1e871f2 100644 (file)
@@ -27,6 +27,7 @@
 [
     NoInterfaceObject,
     GenerateIsReachable=ImplFrame,
+    ImplementationLacksVTable,
 ] interface StyleMedia {
     readonly attribute DOMString type;
 
index 8a33e88..d8a5ec6 100644 (file)
@@ -296,7 +296,7 @@ bool ApplicationCacheHost::canCacheInPageCache()
 void ApplicationCacheHost::setDOMApplicationCache(DOMApplicationCache* domApplicationCache)
 {
     ASSERT(!m_domApplicationCache || !domApplicationCache);
-    m_domApplicationCache = domApplicationCache;
+    m_domApplicationCache = makeWeakPtr(domApplicationCache);
 }
 
 void ApplicationCacheHost::notifyDOMApplicationCache(const AtomicString& eventType, int total, int done)
@@ -379,8 +379,9 @@ static Ref<Event> createApplicationCacheEvent(const AtomicString& eventType, int
 
 void ApplicationCacheHost::dispatchDOMEvent(const AtomicString& eventType, int total, int done)
 {
-    if (!m_domApplicationCache)
+    if (!m_domApplicationCache || !m_domApplicationCache->frame())
         return;
+
     m_domApplicationCache->dispatchEvent(createApplicationCacheEvent(eventType, total, done));
 }
 
index 0d130a4..01f2735 100644 (file)
@@ -34,6 +34,7 @@
 #include <wtf/Deque.h>
 #include <wtf/URL.h>
 #include <wtf/Vector.h>
+#include <wtf/WeakPtr.h>
 
 namespace WebCore {
 
@@ -146,7 +147,7 @@ private:
     ApplicationCache* mainResourceApplicationCache() const { return m_mainResourceApplicationCache.get(); }
     bool maybeLoadFallbackForMainError(const ResourceRequest&, const ResourceError&);
 
-    DOMApplicationCache* m_domApplicationCache { nullptr };
+    WeakPtr<DOMApplicationCache> m_domApplicationCache;
     DocumentLoader& m_documentLoader;
 
     bool m_defersEvents { true }; // Events are deferred until after document onload.
index 764a2f0..93dc13f 100644 (file)
@@ -41,27 +41,6 @@ DOMApplicationCache::DOMApplicationCache(DOMWindow& window)
         host->setDOMApplicationCache(this);
 }
 
-void DOMApplicationCache::suspendForPageCache()
-{
-    if (auto* host = applicationCacheHost())
-        host->setDOMApplicationCache(nullptr);
-    DOMWindowProperty::suspendForPageCache();
-}
-
-void DOMApplicationCache::resumeFromPageCache()
-{
-    DOMWindowProperty::resumeFromPageCache();
-    if (auto* host = applicationCacheHost())
-        host->setDOMApplicationCache(this);
-}
-
-void DOMApplicationCache::willDestroyGlobalObjectInFrame()
-{
-    if (auto* host = applicationCacheHost())
-        host->setDOMApplicationCache(nullptr);
-    DOMWindowProperty::willDestroyGlobalObjectInFrame();
-}
-
 ApplicationCacheHost* DOMApplicationCache::applicationCacheHost() const
 {
     auto* frame = this->frame();
index fc582b8..38a7650 100644 (file)
 
 #include "DOMWindowProperty.h"
 #include "EventTarget.h"
+#include <wtf/WeakPtr.h>
 
 namespace WebCore {
 
 class ApplicationCacheHost;
 class Frame;
 
-class DOMApplicationCache final : public RefCounted<DOMApplicationCache>, public EventTargetWithInlineData, public DOMWindowProperty {
+class DOMApplicationCache final : public RefCounted<DOMApplicationCache>, public EventTargetWithInlineData, public DOMWindowProperty, public CanMakeWeakPtr<DOMApplicationCache> {
 public:
     static Ref<DOMApplicationCache> create(DOMWindow& window) { return adoptRef(*new DOMApplicationCache(window)); }
     virtual ~DOMApplicationCache() { ASSERT(!frame()); }
@@ -55,10 +56,6 @@ private:
     EventTargetInterface eventTargetInterface() const final { return DOMApplicationCacheEventTargetInterfaceType; }
     ScriptExecutionContext* scriptExecutionContext() const final;
 
-    void suspendForPageCache() final;
-    void resumeFromPageCache() final;
-    void willDestroyGlobalObjectInFrame() final;
-
     ApplicationCacheHost* applicationCacheHost() const;
 };
 
index d7ae239..f6fbae6 100644 (file)
@@ -28,6 +28,7 @@
 
 [
     GenerateIsReachable=ImplFrame,
+    ImplementationLacksVTable,
 ] interface BarProp {
     readonly attribute boolean visible;
 };
index 92eb2bf..979530a 100644 (file)
@@ -30,6 +30,7 @@
 // https://www.w3.org/TR/selection-api/#idl-def-Selection
 [
     GenerateIsReachable=ImplFrame,
+    ImplementationLacksVTable,
     InterfaceName=Selection,
 ] interface DOMSelection {
     readonly attribute Node? anchorNode;
index 59891d2..ed47c2f 100644 (file)
@@ -45,7 +45,6 @@
 #include "DOMTimer.h"
 #include "DOMTokenList.h"
 #include "DOMURL.h"
-#include "DOMWindowExtension.h"
 #include "DeviceMotionController.h"
 #include "DeviceMotionData.h"
 #include "DeviceMotionEvent.h"
@@ -451,21 +450,21 @@ void DOMWindow::frameDestroyed()
 
 void DOMWindow::willDestroyCachedFrame()
 {
-    // It is necessary to copy m_properties to a separate vector because the DOMWindowProperties may
+    // It is necessary to copy m_observers to a separate vector because the Observer may
     // unregister themselves from the DOMWindow as a result of the call to willDestroyGlobalObjectInCachedFrame.
-    for (auto* property : copyToVector(m_properties)) {
-        if (m_properties.contains(property))
-            property->willDestroyGlobalObjectInCachedFrame();
+    for (auto* observer : copyToVector(m_observers)) {
+        if (m_observers.contains(observer))
+            observer->willDestroyGlobalObjectInCachedFrame();
     }
 }
 
 void DOMWindow::willDestroyDocumentInFrame()
 {
-    // It is necessary to copy m_properties to a separate vector because the DOMWindowProperties may
+    // It is necessary to copy m_observers to a separate vector because the Observer may
     // unregister themselves from the DOMWindow as a result of the call to willDestroyGlobalObjectInFrame.
-    for (auto* property : copyToVector(m_properties)) {
-        if (m_properties.contains(property))
-            property->willDestroyGlobalObjectInFrame();
+    for (auto* observer : copyToVector(m_observers)) {
+        if (m_observers.contains(observer))
+            observer->willDestroyGlobalObjectInFrame();
     }
 }
 
@@ -474,11 +473,11 @@ void DOMWindow::willDetachDocumentFromFrame()
     if (!frame())
         return;
 
-    // It is necessary to copy m_properties to a separate vector because the DOMWindowProperties may
+    // It is necessary to copy m_observers to a separate vector because the Observer may
     // unregister themselves from the DOMWindow as a result of the call to willDetachGlobalObjectFromFrame.
-    for (auto& property : copyToVector(m_properties)) {
-        if (m_properties.contains(property))
-            property->willDetachGlobalObjectFromFrame();
+    for (auto& observer : copyToVector(m_observers)) {
+        if (m_observers.contains(observer))
+            observer->willDetachGlobalObjectFromFrame();
     }
 
     if (m_performance)
@@ -503,14 +502,14 @@ void DOMWindow::decrementGamepadEventListenerCount()
 
 #endif
 
-void DOMWindow::registerProperty(DOMWindowProperty& property)
+void DOMWindow::registerObserver(Observer& observer)
 {
-    m_properties.add(&property);
+    m_observers.add(&observer);
 }
 
-void DOMWindow::unregisterProperty(DOMWindowProperty& property)
+void DOMWindow::unregisterObserver(Observer& observer)
 {
-    m_properties.remove(&property);
+    m_observers.remove(&observer);
 }
 
 void DOMWindow::resetUnlessSuspendedForDocumentSuspension()
@@ -518,14 +517,13 @@ void DOMWindow::resetUnlessSuspendedForDocumentSuspension()
     if (m_suspendedForDocumentSuspension)
         return;
     willDestroyDocumentInFrame();
-    resetDOMWindowProperties();
 }
 
 void DOMWindow::suspendForPageCache()
 {
-    for (auto* property : copyToVector(m_properties)) {
-        if (m_properties.contains(property))
-            property->suspendForPageCache();
+    for (auto* observer : copyToVector(m_observers)) {
+        if (m_observers.contains(observer))
+            observer->suspendForPageCache();
     }
 
     m_suspendedForDocumentSuspension = true;
@@ -533,38 +531,14 @@ void DOMWindow::suspendForPageCache()
 
 void DOMWindow::resumeFromPageCache()
 {
-    for (auto* property : copyToVector(m_properties)) {
-        if (m_properties.contains(property))
-            property->resumeFromPageCache();
+    for (auto* observer : copyToVector(m_observers)) {
+        if (m_observers.contains(observer))
+            observer->resumeFromPageCache();
     }
 
     m_suspendedForDocumentSuspension = false;
 }
 
-void DOMWindow::resetDOMWindowProperties()
-{
-    m_properties.clear();
-
-    m_applicationCache = nullptr;
-    m_crypto = nullptr;
-    m_history = nullptr;
-    m_localStorage = nullptr;
-    m_location = nullptr;
-    m_locationbar = nullptr;
-    m_media = nullptr;
-    m_menubar = nullptr;
-    m_navigator = nullptr;
-    m_personalbar = nullptr;
-    m_screen = nullptr;
-    m_scrollbars = nullptr;
-    m_selection = nullptr;
-    m_sessionStorage = nullptr;
-    m_statusbar = nullptr;
-    m_toolbar = nullptr;
-    m_performance = nullptr;
-    m_visualViewport = nullptr;
-}
-
 bool DOMWindow::isCurrentlyDisplayedInFrame() const
 {
     auto* frame = this->frame();
index 1d8a642..5e788c4 100644 (file)
@@ -113,8 +113,19 @@ public:
     // the network load. See also SecurityContext::isSecureTransitionTo.
     void didSecureTransitionTo(Document&);
 
-    void registerProperty(DOMWindowProperty&);
-    void unregisterProperty(DOMWindowProperty&);
+    class Observer {
+    public:
+        virtual ~Observer() { }
+
+        virtual void suspendForPageCache() { }
+        virtual void resumeFromPageCache() { }
+        virtual void willDestroyGlobalObjectInCachedFrame() { }
+        virtual void willDestroyGlobalObjectInFrame() { }
+        virtual void willDetachGlobalObjectFromFrame() { }
+    };
+
+    void registerObserver(Observer&);
+    void unregisterObserver(Observer&);
 
     void resetUnlessSuspendedForDocumentSuspension();
     void suspendForPageCache();
@@ -369,8 +380,6 @@ private:
     static ExceptionOr<RefPtr<Frame>> createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures&, DOMWindow& activeWindow, Frame& firstFrame, Frame& openerFrame, const WTF::Function<void(DOMWindow&)>& prepareDialogFunction = nullptr);
     bool isInsecureScriptAccess(DOMWindow& activeWindow, const String& urlString);
 
-    void resetDOMWindowProperties();
-
 #if ENABLE(DEVICE_ORIENTATION)
     void failedToRegisterDeviceMotionEventListener();
 #endif
@@ -386,7 +395,7 @@ private:
     bool m_suspendedForDocumentSuspension { false };
     Optional<bool> m_canShowModalDialogOverride;
 
-    HashSet<DOMWindowProperty*> m_properties;
+    HashSet<Observer*> m_observers;
 
     mutable RefPtr<Crypto> m_crypto;
     mutable RefPtr<History> m_history;
index c4aaaad..2bc6741 100644 (file)
 namespace WebCore {
 
 DOMWindowExtension::DOMWindowExtension(DOMWindow* window, DOMWrapperWorld& world)
-    : DOMWindowProperty(window)
+    : m_window(makeWeakPtr(window))
     , m_world(world)
     , m_wasDetached(false)
 {
     ASSERT(this->frame());
+    if (m_window)
+        m_window->registerObserver(*this);
+}
+
+DOMWindowExtension::~DOMWindowExtension()
+{
+    if (m_window)
+        m_window->unregisterObserver(*this);
+}
+
+Frame* DOMWindowExtension::frame() const
+{
+    return m_window ? m_window->frame() : nullptr;
 }
 
 void DOMWindowExtension::suspendForPageCache()
@@ -53,15 +66,14 @@ void DOMWindowExtension::suspendForPageCache()
     frame->loader().client().dispatchWillDisconnectDOMWindowExtensionFromGlobalObject(this);
 
     m_disconnectedFrame = WTFMove(frame);
-
-    DOMWindowProperty::suspendForPageCache();
 }
 
 void DOMWindowExtension::resumeFromPageCache()
 {
+    ASSERT(frame());
     ASSERT(m_disconnectedFrame == frame());
-    
-    DOMWindowProperty::resumeFromPageCache();
+    ASSERT(frame()->document()->domWindow() == m_window);
+
     m_disconnectedFrame = nullptr;
 
     frame()->loader().client().dispatchDidReconnectDOMWindowExtensionToGlobalObject(this);
@@ -78,7 +90,12 @@ void DOMWindowExtension::willDestroyGlobalObjectInCachedFrame()
     m_disconnectedFrame->loader().client().dispatchWillDestroyGlobalObjectForDOMWindowExtension(this);
     m_disconnectedFrame = nullptr;
 
-    DOMWindowProperty::willDestroyGlobalObjectInCachedFrame();
+    // DOMWindowExtension lifetime isn't tied directly to the DOMWindow itself so it is important that it unregister
+    // itself from any DOMWindow it is associated with if that DOMWindow is going away.
+    ASSERT(m_window);
+    if (m_window)
+        m_window->unregisterObserver(*this);
+    m_window = nullptr;
 }
 
 void DOMWindowExtension::willDestroyGlobalObjectInFrame()
@@ -95,7 +112,12 @@ void DOMWindowExtension::willDestroyGlobalObjectInFrame()
         frame->loader().client().dispatchWillDestroyGlobalObjectForDOMWindowExtension(this);
     }
 
-    DOMWindowProperty::willDestroyGlobalObjectInFrame();
+    // DOMWindowExtension lifetime isn't tied directly to the DOMWindow itself so it is important that it unregister
+    // itself from any DOMWindow it is associated with if that DOMWindow is going away.
+    ASSERT(m_window);
+    if (m_window)
+        m_window->unregisterObserver(*this);
+    m_window = nullptr;
 }
 
 void DOMWindowExtension::willDetachGlobalObjectFromFrame()
@@ -112,7 +134,6 @@ void DOMWindowExtension::willDetachGlobalObjectFromFrame()
     frame->loader().client().dispatchWillDestroyGlobalObjectForDOMWindowExtension(this);
 
     m_wasDetached = true;
-    DOMWindowProperty::willDetachGlobalObjectFromFrame();
 }
 
 } // namespace WebCore
index 0f61f1e..480d98e 100644 (file)
 
 #pragma once
 
-#include "DOMWindowProperty.h"
+#include "DOMWindow.h"
 #include <wtf/RefCounted.h>
 #include <wtf/RefPtr.h>
+#include <wtf/WeakPtr.h>
 
 namespace WebCore {
 
-class DOMWindowExtension;
 class DOMWrapperWorld;
 class Frame;
 
-class DOMWindowExtension : public RefCounted<DOMWindowExtension>, public DOMWindowProperty {
+class DOMWindowExtension final : public RefCounted<DOMWindowExtension>, public DOMWindow::Observer {
 public:
     static Ref<DOMWindowExtension> create(DOMWindow* window, DOMWrapperWorld& world)
     {
         return adoptRef(*new DOMWindowExtension(window, world));
     }
 
-    void suspendForPageCache() override;
-    void resumeFromPageCache() override;
-    void willDestroyGlobalObjectInCachedFrame() override;
-    void willDestroyGlobalObjectInFrame() override;
-    void willDetachGlobalObjectFromFrame() override;
+    WEBCORE_EXPORT ~DOMWindowExtension();
 
+    void suspendForPageCache() final;
+    void resumeFromPageCache() final;
+    void willDestroyGlobalObjectInCachedFrame() final;
+    void willDestroyGlobalObjectInFrame() final;
+    void willDetachGlobalObjectFromFrame() final;
+
+    WEBCORE_EXPORT Frame* frame() const;
     DOMWrapperWorld& world() const { return m_world; }
 
 private:
     WEBCORE_EXPORT DOMWindowExtension(DOMWindow*, DOMWrapperWorld&);
 
+    WeakPtr<DOMWindow> m_window;
     Ref<DOMWrapperWorld> m_world;
     RefPtr<Frame> m_disconnectedFrame;
     bool m_wasDetached;
index 9b84ad0..b87f2e5 100644 (file)
 #include "DOMWindowProperty.h"
 
 #include "DOMWindow.h"
-#include "Document.h"
 #include "Frame.h"
 
 namespace WebCore {
 
 DOMWindowProperty::DOMWindowProperty(DOMWindow* window)
-    : m_window(window)
-{
-    if (m_window)
-        m_window->registerProperty(*this);
-}
-
-DOMWindowProperty::~DOMWindowProperty()
-{
-    if (m_window)
-        m_window->unregisterProperty(*this);
-
-    m_window = nullptr;
-}
-
-void DOMWindowProperty::suspendForPageCache()
-{
-    ASSERT(m_window);
-}
-
-void DOMWindowProperty::resumeFromPageCache()
-{
-    // If this property is being reconnected to its Frame to enter the PageCache, it must have
-    // been disconnected from its Frame in the first place and it should still have an associated DOMWindow.
-    ASSERT(frame());
-    ASSERT(frame()->document()->domWindow() == m_window);
-}
-
-void DOMWindowProperty::willDestroyGlobalObjectInCachedFrame()
-{
-    // If the property has been disconnected from its Frame for the page cache, then it must have originally had a Frame
-    // and therefore should still have an associated DOMWindow.
-    ASSERT(m_window);
-
-    // DOMWindowProperty lifetime isn't tied directly to the DOMWindow itself so it is important that it unregister
-    // itself from any DOMWindow it is associated with if that DOMWindow is going away.
-    if (m_window)
-        m_window->unregisterProperty(*this);
-    m_window = nullptr;
-}
-
-void DOMWindowProperty::willDestroyGlobalObjectInFrame()
-{
-    ASSERT(m_window);
-
-    // DOMWindowProperty lifetime isn't tied directly to the DOMWindow itself so it is important that it unregister
-    // itself from any DOMWindow it is associated with if that DOMWindow is going away.
-    if (m_window)
-        m_window->unregisterProperty(*this);
-    m_window = nullptr;
-}
-
-void DOMWindowProperty::willDetachGlobalObjectFromFrame()
+    : m_window(makeWeakPtr(window))
 {
 }
 
index db9b6aa..fb77175 100644 (file)
@@ -25,6 +25,8 @@
 
 #pragma once
 
+#include <wtf/WeakPtr.h>
+
 namespace WebCore {
 
 class DOMWindow;
@@ -32,21 +34,15 @@ class Frame;
 
 class DOMWindowProperty {
 public:
-    explicit DOMWindowProperty(DOMWindow*);
-
-    virtual void suspendForPageCache();
-    virtual void resumeFromPageCache();
-    virtual void willDestroyGlobalObjectInCachedFrame();
-    virtual void willDestroyGlobalObjectInFrame();
-    virtual void willDetachGlobalObjectFromFrame();
-
-    WEBCORE_EXPORT Frame* frame() const;
-    DOMWindow* window() const { return m_window; }
+    Frame* frame() const;
+    DOMWindow* window() const { return m_window.get(); }
 
 protected:
-    virtual ~DOMWindowProperty();
+    explicit DOMWindowProperty(DOMWindow*);
+    ~DOMWindowProperty() = default;
 
-    DOMWindow* m_window;
+private:
+    WeakPtr<DOMWindow> m_window;
 };
 
 } // namespace WebCore
index 33a80fb..0b958ee 100644 (file)
@@ -26,6 +26,7 @@
 [
     GenerateIsReachable=ImplFrame,
     JSCustomMarkFunction,
+    ImplementationLacksVTable,
 ] interface History {
     readonly attribute unsigned long length;
     attribute ScrollRestoration scrollRestoration;
index 0c1ae05..9dcd723 100644 (file)
@@ -40,6 +40,7 @@
     CustomToStringName,
     GenerateIsReachable=ImplFrame,
     IsImmutablePrototypeExoticObject,
+    ImplementationLacksVTable,
     Unforgeable
 ] interface Location {
     [SetterCallWith=ActiveWindow&FirstWindow, DoNotCheckSecurityOnSetter] stringifier attribute USVString href;
index 6e2faec..a591ae9 100644 (file)
@@ -167,7 +167,7 @@ DOMPluginArray& Navigator::plugins()
             ResourceLoadObserver::shared().logNavigatorAPIAccessed(*frame->document(), ResourceLoadStatistics::NavigatorAPI::Plugins);
     }
     if (!m_plugins)
-        m_plugins = DOMPluginArray::create(m_window);
+        m_plugins = DOMPluginArray::create(window());
     return *m_plugins;
 }
 
@@ -178,7 +178,7 @@ DOMMimeTypeArray& Navigator::mimeTypes()
             ResourceLoadObserver::shared().logNavigatorAPIAccessed(*frame->document(), ResourceLoadStatistics::NavigatorAPI::MimeTypes);
     }
     if (!m_mimeTypes)
-        m_mimeTypes = DOMMimeTypeArray::create(m_window);
+        m_mimeTypes = DOMMimeTypeArray::create(window());
     return *m_mimeTypes;
 }
 
index cde7a72..0d24d02 100644 (file)
@@ -29,7 +29,9 @@
  */
 
 // See: http://www.w3.org/TR/navigation-timing/
-interface PerformanceNavigation {
+[
+    ImplementationLacksVTable,
+] interface PerformanceNavigation {
     const unsigned short TYPE_NAVIGATE = 0;
     const unsigned short TYPE_RELOAD = 1;
     const unsigned short TYPE_BACK_FORWARD = 2;
index e3f2e0a..2999aff 100644 (file)
@@ -29,7 +29,9 @@
  */
 
 // See: https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/NavigationTiming/Overview.html
-interface PerformanceTiming {
+[
+    ImplementationLacksVTable,
+] interface PerformanceTiming {
     readonly attribute unsigned long long navigationStart;
     readonly attribute unsigned long long unloadEventStart;
     readonly attribute unsigned long long unloadEventEnd;
index 0007343..662d08c 100644 (file)
@@ -29,6 +29,7 @@
 
 [
     GenerateIsReachable=ImplFrame,
+    ImplementationLacksVTable,
 ] interface Screen {
     readonly attribute unsigned long height;
     readonly attribute unsigned long width;
index c91994e..789a318 100644 (file)
@@ -50,9 +50,10 @@ EventTargetInterface VisualViewport::eventTargetInterface() const
 
 ScriptExecutionContext* VisualViewport::scriptExecutionContext() const
 {
-    if (!m_window)
+    auto window = this->window();
+    if (!window)
         return nullptr;
-    return static_cast<ContextDestructionObserver*>(m_window)->scriptExecutionContext();
+    return static_cast<ContextDestructionObserver*>(window)->scriptExecutionContext();
 }
 
 bool VisualViewport::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, const AddEventListenerOptions& options)
index e5efc56..67f9132 100644 (file)
@@ -21,6 +21,7 @@
 [
     GenerateIsReachable=ImplFrame,
     LegacyUnenumerableNamedProperties,
+    ImplementationLacksVTable,
     InterfaceName=MimeTypeArray,
 ] interface DOMMimeTypeArray {
     readonly attribute unsigned long length;
index 6946ff5..14868ae 100644 (file)
@@ -21,6 +21,7 @@
 [
     GenerateIsReachable=ImplFrame,
     LegacyUnenumerableNamedProperties,
+    ImplementationLacksVTable,
     InterfaceName=PluginArray,
 ] interface DOMPluginArray {
     readonly attribute unsigned long length;
index d76fc32..42101f8 100644 (file)
@@ -19,7 +19,7 @@
 #include "config.h"
 #include "DOMObjectCache.h"
 
-#include <WebCore/DOMWindowProperty.h>
+#include <WebCore/DOMWindow.h>
 #include <WebCore/Document.h>
 #include <WebCore/Frame.h>
 #include <WebCore/FrameDestructionObserver.h>
@@ -113,27 +113,31 @@ public:
     }
 
 private:
-    class DOMWindowObserver final: public WebCore::DOMWindowProperty {
+    class DOMWindowObserver final : public WebCore::DOMWindow::Observer {
         WTF_MAKE_FAST_ALLOCATED;
     public:
         DOMWindowObserver(WebCore::DOMWindow& window, DOMObjectCacheFrameObserver& frameObserver)
-            : DOMWindowProperty(&window)
+            : m_window(makeWeakPtr(window))
             , m_frameObserver(frameObserver)
         {
+            window.registerObserver(*this);
         }
 
-        virtual ~DOMWindowObserver()
+        ~DOMWindowObserver()
         {
+            if (m_window)
+                m_window->unregisterObserver(*this);
         }
 
+        WebCore::DOMWindow* window() const { return m_window.get(); }
+
     private:
         void willDetachGlobalObjectFromFrame() override
         {
-            // Clear the DOMWindowProperty first, and then notify the Frame observer.
-            DOMWindowProperty::willDetachGlobalObjectFromFrame();
             m_frameObserver.willDetachGlobalObjectFromFrame();
         }
 
+        WeakPtr<WebCore::DOMWindow> m_window;
         DOMObjectCacheFrameObserver& m_frameObserver;
     };