Title: [110570] trunk
Revision
110570
Author
[email protected]
Date
2012-03-13 08:57:37 -0700 (Tue, 13 Mar 2012)

Log Message

<rdar://problem/7908830> and https://bugs.webkit.org/show_bug.cgi?id=34679 Location and other objects are dysfunctional after a document gets restored from page cache

Reviewed by Adam Barth.

Source/WebCore:

Test: fast/loader/window-properties-restored-from-page-cache.html

Give DOMWindowProperties the ability to reconnect to their Frame:
* page/DOMWindowProperty.cpp:
(WebCore::DOMWindowProperty::reconnectFrame):
* page/DOMWindowProperty.h:
(DOMWindowProperty):

Let ApplicationCache do some extra work when reconnecting:
* loader/appcache/DOMApplicationCache.cpp:
(WebCore::DOMApplicationCache::reconnectFrame):
(WebCore):
* loader/appcache/DOMApplicationCache.h:
(DOMApplicationCache):

Let IndexDB do some extra work when reconnecting:
* Modules/indexeddb/DOMWindowIndexedDatabase.cpp:
(WebCore::DOMWindowIndexedDatabase::disconnectFrame):
(WebCore::DOMWindowIndexedDatabase::reconnectFrame):
(WebCore::DOMWindowIndexedDatabase::webkitIndexedDB):
* Modules/indexeddb/DOMWindowIndexedDatabase.h:
(DOMWindowIndexedDatabase):

Tell the DOMWindow to suspend to the page cache:
* history/CachedFrame.cpp:
(WebCore::CachedFrame::CachedFrame):

Tell the DOMWindow to resume from the page cache:
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::open):

* page/DOMWindow.cpp:
(WebCore::DOMWindow::DOMWindow):
(WebCore::DOMWindow::~DOMWindow): Call clearDOMWindowProperties directly instead of clear()
(WebCore::DOMWindow::frameDestroyed): Ditto.
(WebCore::DOMWindow::clear): Only clear if the DOMWindow is not suspended for the page cache.
(WebCore::DOMWindow::suspendForPageCache): Disconnect properties and set the page cache flag.
(WebCore::DOMWindow::resumeFromPageCache): Reconnect properties and revert the page cache flag.
(WebCore::DOMWindow::disconnectDOMWindowProperties): Only disconnect the registered properties.
(WebCore::DOMWindow::reconnectDOMWindowProperties):
(WebCore::DOMWindow::clearDOMWindowProperties): Disconnect the registered properties then clear them out.

For all of the following, if the DOMWindow is not displayed in a frame (i.e., it is suspended), do nothing:
(WebCore::DOMWindow::screen):
(WebCore::DOMWindow::history):
(WebCore::DOMWindow::crypto):
(WebCore::DOMWindow::locationbar):
(WebCore::DOMWindow::menubar):
(WebCore::DOMWindow::personalbar):
(WebCore::DOMWindow::scrollbars):
(WebCore::DOMWindow::statusbar):
(WebCore::DOMWindow::toolbar):
(WebCore::DOMWindow::console):
(WebCore::DOMWindow::applicationCache):
(WebCore::DOMWindow::navigator):
(WebCore::DOMWindow::performance):
(WebCore::DOMWindow::location):
(WebCore::DOMWindow::sessionStorage):
(WebCore::DOMWindow::localStorage):
(WebCore::DOMWindow::webkitNotifications):
(WebCore::DOMWindow::postMessageTimerFired):
(WebCore::DOMWindow::getSelection):
(WebCore::DOMWindow::styleMedia):
(WebCore::DOMWindow::webkitStorageInfo):
* page/DOMWindow.h:

LayoutTests:

* fast/loader/window-properties-restored-from-page-cache-expected.txt: Added.
* fast/loader/window-properties-restored-from-page-cache.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (110569 => 110570)


--- trunk/LayoutTests/ChangeLog	2012-03-13 15:43:45 UTC (rev 110569)
+++ trunk/LayoutTests/ChangeLog	2012-03-13 15:57:37 UTC (rev 110570)
@@ -1,3 +1,13 @@
+2012-03-12  Brady Eidson  <[email protected]>
+
+        <rdar://problem/7908830> and https://bugs.webkit.org/show_bug.cgi?id=34679
+        Location and other objects are dysfunctional after a document gets restored from page cache
+
+        Reviewed by Adam Barth.
+
+        * fast/loader/window-properties-restored-from-page-cache-expected.txt: Added.
+        * fast/loader/window-properties-restored-from-page-cache.html: Added.
+
 2012-03-13  ChangSeok Oh  <[email protected]>
 
         [EFL] [DRT] Implement scheduleAsynchronousKeyDown.

Added: trunk/LayoutTests/fast/loader/window-properties-restored-from-page-cache-expected.txt (0 => 110570)


--- trunk/LayoutTests/fast/loader/window-properties-restored-from-page-cache-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/loader/window-properties-restored-from-page-cache-expected.txt	2012-03-13 15:57:37 UTC (rev 110570)
@@ -0,0 +1,20 @@
+This test makes sure that various properties on the window object are correctly reconnected after restoring a page from the page cache.
+[object DOMApplicationCache] 
+[object Console] 
+[object Crypto] 
+[object History] 
+[object Storage] 
+true 
+[object BarInfo] 
+[object StyleMedia] 
+[object BarInfo] 
+[object Navigator] 
+[object BarInfo] 
+[object Screen] 
+[object BarInfo] 
+true 
+[object Storage] 
+[object BarInfo] 
+[object BarInfo] 
+
+All tests passed.

Added: trunk/LayoutTests/fast/loader/window-properties-restored-from-page-cache.html (0 => 110570)


--- trunk/LayoutTests/fast/loader/window-properties-restored-from-page-cache.html	                        (rev 0)
+++ trunk/LayoutTests/fast/loader/window-properties-restored-from-page-cache.html	2012-03-13 15:57:37 UTC (rev 110570)
@@ -0,0 +1,110 @@
+<script>
+if (window.layoutTestController) {
+	layoutTestController.dumpAsText();
+	layoutTestController.waitUntilDone();
+	layoutTestController.overridePreference("WebKitUsesPageCachePreferenceKey", 1);
+}
+
+var cachedApplicationCache = window.applicationCache;
+var cachedConsole = window.console;
+var cachedCrypto = window.crypto;
+var cachedHistory = window.history;
+var cachedLocalStorage = window.localStorage;
+var cachedLocation = window.location;
+var cachedLocationbar = window.locationbar;
+var cachedMedia = window.styleMedia;
+var cachedMenubar = window.menubar;
+var cachedNavigator = window.navigator;
+var cachedPersonalbar = window.personalbar;
+var cachedScreen = window.screen;
+var cachedScrollbars = window.scrollbars;
+var cachedSelection = window.getSelection();
+var cachedSessionStorage = window.sessionStorage;
+var cachedStatusbar = window.statusbar;
+var cachedToolbar = window.toolbar;
+
+function logMessage(msg)
+{
+	document.getElementById("outputDiv").innerText += msg + " \n";
+}
+
+function logErrorMessage(msg)
+{
+	document.getElementById("errorDiv").innerText += msg + " \n";
+}
+
+window._onpageshow_ = function(evt) {
+	if (!evt.persisted) {
+		window.setTimeout("window.location.href = ''", 0);
+		return;
+	}
+	
+	// First alert all of the objects to make sure we get a valid toString()-ification
+	// instead of "undefined", "null", or "Object"
+	logMessage(window.applicationCache);
+	logMessage(window.console);
+	logMessage(window.crypto);
+	logMessage(window.history);
+	logMessage(window.localStorage);
+	logMessage(window.location != null && window.location != undefined);
+	logMessage(window.locationbar);
+	logMessage(window.styleMedia);
+	logMessage(window.menubar);
+	logMessage(window.navigator);
+	logMessage(window.personalbar);
+	logMessage(window.screen);
+	logMessage(window.scrollbars);
+	logMessage(window.getSelection() != null && window.getSelection() != undefined);
+	logMessage(window.sessionStorage);
+	logMessage(window.statusbar);
+	logMessage(window.toolbar);
+	
+	// Then make sure the window properties match the cached references from the initial page load
+	if (cachedApplicationCache != window.applicationCache)
+		logErrorMessage("applicationCache");
+	if (cachedConsole != window.console)
+		logErrorMessage("console");
+	if (cachedCrypto != window.crypto)
+		logErrorMessage("crypto");
+	if (cachedHistory != window.history)
+		logErrorMessage("history");
+	if (cachedLocalStorage != window.localStorage)
+		logErrorMessage("localStorage");
+	if (cachedLocation != window.location)
+		logErrorMessage("location");
+	if (cachedLocationbar != window.locationbar)
+		logErrorMessage("locationbar");
+	if (cachedMedia != window.styleMedia)
+		logErrorMessage("styleMedia");
+	if (cachedMenubar != window.menubar)
+		logErrorMessage("menubar");
+	if (cachedNavigator != window.navigator)
+		logErrorMessage("navigator");
+	if (cachedPersonalbar != window.personalbar)
+		logErrorMessage("personalbar");
+	if (cachedScreen != window.screen)
+		logErrorMessage("screen");
+	if (cachedScrollbars != window.scrollbars)
+		logErrorMessage("scrollbars");
+	if (cachedSelection != window.getSelection())
+		logErrorMessage("getSelection");
+	if (cachedSessionStorage != window.sessionStorage)
+		logErrorMessage("sessionStorage");
+	if (cachedStatusbar != window.statusbar)
+		logErrorMessage("statusbar");
+	if (cachedToolbar != window.toolbar)
+		logErrorMessage("toolbar");
+
+	if (document.getElementById("errorDiv").innerText == "")
+		document.getElementById("errorDiv").innerText = "All tests passed.";
+
+	if (window.layoutTestController)
+		layoutTestController.notifyDone();
+}
+
+</script>
+<body>
+This test makes sure that various properties on the window object are correctly reconnected after restoring a page from the page cache.<br>
+<div id="outputDiv"></div><br>
+<div id="errorDiv"></div>
+</body>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (110569 => 110570)


--- trunk/Source/WebCore/ChangeLog	2012-03-13 15:43:45 UTC (rev 110569)
+++ trunk/Source/WebCore/ChangeLog	2012-03-13 15:57:37 UTC (rev 110570)
@@ -1,3 +1,78 @@
+2012-03-12  Brady Eidson  <[email protected]>
+
+        <rdar://problem/7908830> and https://bugs.webkit.org/show_bug.cgi?id=34679
+        Location and other objects are dysfunctional after a document gets restored from page cache
+
+        Reviewed by Adam Barth.
+
+        Test: fast/loader/window-properties-restored-from-page-cache.html
+
+        Give DOMWindowProperties the ability to reconnect to their Frame:
+        * page/DOMWindowProperty.cpp:
+        (WebCore::DOMWindowProperty::reconnectFrame):
+        * page/DOMWindowProperty.h:
+        (DOMWindowProperty):
+
+        Let ApplicationCache do some extra work when reconnecting:
+        * loader/appcache/DOMApplicationCache.cpp:
+        (WebCore::DOMApplicationCache::reconnectFrame):
+        (WebCore):
+        * loader/appcache/DOMApplicationCache.h:
+        (DOMApplicationCache):
+
+        Let IndexDB do some extra work when reconnecting:
+        * Modules/indexeddb/DOMWindowIndexedDatabase.cpp:
+        (WebCore::DOMWindowIndexedDatabase::disconnectFrame):
+        (WebCore::DOMWindowIndexedDatabase::reconnectFrame):
+        (WebCore::DOMWindowIndexedDatabase::webkitIndexedDB):
+        * Modules/indexeddb/DOMWindowIndexedDatabase.h:
+        (DOMWindowIndexedDatabase):
+
+        Tell the DOMWindow to suspend to the page cache:
+        * history/CachedFrame.cpp:
+        (WebCore::CachedFrame::CachedFrame):
+
+        Tell the DOMWindow to resume from the page cache:
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::open):
+
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::DOMWindow):
+        (WebCore::DOMWindow::~DOMWindow): Call clearDOMWindowProperties directly instead of clear()
+        (WebCore::DOMWindow::frameDestroyed): Ditto.
+        (WebCore::DOMWindow::clear): Only clear if the DOMWindow is not suspended for the page cache.
+        (WebCore::DOMWindow::suspendForPageCache): Disconnect properties and set the page cache flag.
+        (WebCore::DOMWindow::resumeFromPageCache): Reconnect properties and revert the page cache flag.
+        (WebCore::DOMWindow::disconnectDOMWindowProperties): Only disconnect the registered properties.
+        (WebCore::DOMWindow::reconnectDOMWindowProperties):
+        (WebCore::DOMWindow::clearDOMWindowProperties): Disconnect the registered properties then clear them out.
+
+        For all of the following, if the DOMWindow is not displayed in a frame (i.e., it is suspended), do nothing:
+        (WebCore::DOMWindow::screen):
+        (WebCore::DOMWindow::history):
+        (WebCore::DOMWindow::crypto):
+        (WebCore::DOMWindow::locationbar):
+        (WebCore::DOMWindow::menubar):
+        (WebCore::DOMWindow::personalbar):
+        (WebCore::DOMWindow::scrollbars):
+        (WebCore::DOMWindow::statusbar):
+        (WebCore::DOMWindow::toolbar):
+        (WebCore::DOMWindow::console):
+        (WebCore::DOMWindow::applicationCache):
+        (WebCore::DOMWindow::navigator):
+        (WebCore::DOMWindow::performance):
+        (WebCore::DOMWindow::location):
+        (WebCore::DOMWindow::sessionStorage):
+        (WebCore::DOMWindow::localStorage):
+        (WebCore::DOMWindow::webkitNotifications):
+        (WebCore::DOMWindow::postMessageTimerFired):
+        (WebCore::DOMWindow::getSelection):
+        (WebCore::DOMWindow::styleMedia):
+        (WebCore::DOMWindow::webkitStorageInfo):
+        * page/DOMWindow.h:
+
+
+
 2012-03-13  Dana Jansens  <[email protected]>
 
         [chromium] Use projectQuad to apply inverse mapRect

Modified: trunk/Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.cpp (110569 => 110570)


--- trunk/Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.cpp	2012-03-13 15:43:45 UTC (rev 110569)
+++ trunk/Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.cpp	2012-03-13 15:57:37 UTC (rev 110570)
@@ -60,10 +60,16 @@
 
 void DOMWindowIndexedDatabase::disconnectFrame()
 {
-    m_idbFactory = 0;
+    m_suspendedIDBFactory = m_idbFactory.release();
     DOMWindowProperty::disconnectFrame();
 }
 
+void DOMWindowIndexedDatabase::reconnectFrame(Frame* frame)
+{
+    DOMWindowProperty::reconnectFrame(frame);
+    m_idbFactory = m_suspendedIDBFactory.release();
+}
+
 IDBFactory* DOMWindowIndexedDatabase::webkitIndexedDB(DOMWindow* window)
 {
     return from(window)->webkitIndexedDB();
@@ -82,7 +88,10 @@
     if (!document->securityOrigin()->canAccessDatabase())
         return 0;
 
-    if (!m_idbFactory && m_window->isCurrentlyDisplayedInFrame())
+    if (!m_window->isCurrentlyDisplayedInFrame())
+        return 0;
+
+    if (!m_idbFactory)
         m_idbFactory = IDBFactory::create(PageGroupIndexedDatabase::from(page->group())->factoryBackend());
     return m_idbFactory.get();
 }

Modified: trunk/Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.h (110569 => 110570)


--- trunk/Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.h	2012-03-13 15:43:45 UTC (rev 110569)
+++ trunk/Source/WebCore/Modules/indexeddb/DOMWindowIndexedDatabase.h	2012-03-13 15:57:37 UTC (rev 110570)
@@ -44,6 +44,7 @@
     static IDBFactory* webkitIndexedDB(DOMWindow*);
 
     virtual void disconnectFrame() OVERRIDE;
+    virtual void reconnectFrame(Frame*) OVERRIDE;
 
 private:
     explicit DOMWindowIndexedDatabase(DOMWindow*);
@@ -52,6 +53,7 @@
 
     DOMWindow* m_window;
     RefPtr<IDBFactory> m_idbFactory;
+    RefPtr<IDBFactory> m_suspendedIDBFactory;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/history/CachedFrame.cpp (110569 => 110570)


--- trunk/Source/WebCore/history/CachedFrame.cpp	2012-03-13 15:43:45 UTC (rev 110569)
+++ trunk/Source/WebCore/history/CachedFrame.cpp	2012-03-13 15:57:37 UTC (rev 110570)
@@ -172,6 +172,9 @@
     m_document->suspendScriptedAnimationControllerCallbacks();
     m_document->suspendActiveDOMObjects(ActiveDOMObject::DocumentWillBecomeInactive);
     m_cachedFrameScriptData = adoptPtr(new ScriptCachedFrameData(frame));
+    
+    if (DOMWindow* domWindow = m_cachedFrameScriptData->domWindow())
+        domWindow->suspendForPageCache();
 
     frame->loader()->client()->savePlatformDataToCachedFrame(this);
 

Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (110569 => 110570)


--- trunk/Source/WebCore/loader/FrameLoader.cpp	2012-03-13 15:43:45 UTC (rev 110569)
+++ trunk/Source/WebCore/loader/FrameLoader.cpp	2012-03-13 15:57:37 UTC (rev 110570)
@@ -2056,6 +2056,7 @@
     
     m_frame->setDocument(document);
     m_frame->setDOMWindow(cachedFrame.domWindow());
+    m_frame->domWindow()->resumeFromPageCache();
     m_frame->domWindow()->setURL(document->url());
     m_frame->domWindow()->setSecurityOrigin(document->securityOrigin());
 

Modified: trunk/Source/WebCore/loader/appcache/DOMApplicationCache.cpp (110569 => 110570)


--- trunk/Source/WebCore/loader/appcache/DOMApplicationCache.cpp	2012-03-13 15:43:45 UTC (rev 110569)
+++ trunk/Source/WebCore/loader/appcache/DOMApplicationCache.cpp	2012-03-13 15:57:37 UTC (rev 110570)
@@ -55,6 +55,14 @@
     DOMWindowProperty::disconnectFrame();
 }
 
+void DOMApplicationCache::reconnectFrame(Frame* frame)
+{
+    DOMWindowProperty::reconnectFrame(frame);
+    ApplicationCacheHost* cacheHost = applicationCacheHost();
+    if (cacheHost)
+        cacheHost->setDOMApplicationCache(this);
+}
+
 ApplicationCacheHost* DOMApplicationCache::applicationCacheHost() const
 {
     if (!m_frame || !m_frame->loader()->documentLoader())

Modified: trunk/Source/WebCore/loader/appcache/DOMApplicationCache.h (110569 => 110570)


--- trunk/Source/WebCore/loader/appcache/DOMApplicationCache.h	2012-03-13 15:43:45 UTC (rev 110569)
+++ trunk/Source/WebCore/loader/appcache/DOMApplicationCache.h	2012-03-13 15:57:37 UTC (rev 110570)
@@ -48,6 +48,7 @@
     ~DOMApplicationCache() { ASSERT(!m_frame); }
 
     virtual void disconnectFrame() OVERRIDE;
+    virtual void reconnectFrame(Frame*) OVERRIDE;
 
     unsigned short status() const;
     void update(ExceptionCode&);

Modified: trunk/Source/WebCore/page/DOMWindow.cpp (110569 => 110570)


--- trunk/Source/WebCore/page/DOMWindow.cpp	2012-03-13 15:43:45 UTC (rev 110569)
+++ trunk/Source/WebCore/page/DOMWindow.cpp	2012-03-13 15:57:37 UTC (rev 110570)
@@ -390,44 +390,49 @@
 DOMWindow::DOMWindow(Frame* frame)
     : FrameDestructionObserver(frame)
     , m_shouldPrintWhenFinishedLoading(false)
+    , m_suspendedForPageCache(false)
 {
 }
 
 DOMWindow::~DOMWindow()
 {
-    ASSERT(!m_screen);
-    ASSERT(!m_selection);
-    ASSERT(!m_history);
-    ASSERT(!m_crypto);
-    ASSERT(!m_locationbar);
-    ASSERT(!m_menubar);
-    ASSERT(!m_personalbar);
-    ASSERT(!m_scrollbars);
-    ASSERT(!m_statusbar);
-    ASSERT(!m_toolbar);
-    ASSERT(!m_console);
-    ASSERT(!m_navigator);
+#ifndef NDEBUG
+    if (!m_suspendedForPageCache) {
+        ASSERT(!m_screen);
+        ASSERT(!m_selection);
+        ASSERT(!m_history);
+        ASSERT(!m_crypto);
+        ASSERT(!m_locationbar);
+        ASSERT(!m_menubar);
+        ASSERT(!m_personalbar);
+        ASSERT(!m_scrollbars);
+        ASSERT(!m_statusbar);
+        ASSERT(!m_toolbar);
+        ASSERT(!m_console);
+        ASSERT(!m_navigator);
 #if ENABLE(WEB_TIMING)
-    ASSERT(!m_performance);
+        ASSERT(!m_performance);
 #endif
-    ASSERT(!m_location);
-    ASSERT(!m_media);
-    ASSERT(!m_sessionStorage);
-    ASSERT(!m_localStorage);
-    ASSERT(!m_applicationCache);
+        ASSERT(!m_location);
+        ASSERT(!m_media);
+        ASSERT(!m_sessionStorage);
+        ASSERT(!m_localStorage);
+        ASSERT(!m_applicationCache);
 #if ENABLE(NOTIFICATIONS)
-    ASSERT(!m_notifications);
+        ASSERT(!m_notifications);
 #endif
 #if ENABLE(BLOB)
-    ASSERT(!m_domURL);
+        ASSERT(!m_domURL);
 #endif
 #if ENABLE(QUOTA)
-    ASSERT(!m_storageInfo);
+        ASSERT(!m_storageInfo);
 #endif
+    }
+#endif
 
-    // This clear should be unnessary given the ASSERTs above, but we don't
-    // want any of these objects to hang around after we've been destroyed.
-    clear();
+    // As the ASSERTs above indicate, this clear should only be necesary if this DOMWindow is suspended for the page cache.
+    // But we don't want to risk any of these objects hanging around after we've been destroyed.
+    clearDOMWindowProperties();
 
     removeAllUnloadEventListeners(this);
     removeAllBeforeUnloadEventListeners(this);
@@ -466,7 +471,7 @@
 void DOMWindow::frameDestroyed()
 {
     FrameDestructionObserver::frameDestroyed();
-    clear();
+    clearDOMWindowProperties();
 }
 
 void DOMWindow::willDetachPage()
@@ -496,9 +501,54 @@
 
 void DOMWindow::clear()
 {
+    // The main frame will always try to clear its DOMWindow when a new load is committed, even if that
+    // DOMWindow is suspended in the page cache.
+    // In those cases we need to make sure we don't actually clear it.
+    if (m_suspendedForPageCache)
+        return;
+    
+    clearDOMWindowProperties();
+}
+
+void DOMWindow::suspendForPageCache()
+{
+    disconnectDOMWindowProperties();
+    m_suspendedForPageCache = true;
+}
+
+void DOMWindow::resumeFromPageCache()
+{
+    reconnectDOMWindowProperties();
+    m_suspendedForPageCache = false;
+}
+
+void DOMWindow::disconnectDOMWindowProperties()
+{
     HashSet<DOMWindowProperty*>::iterator stop = m_properties.end();
     for (HashSet<DOMWindowProperty*>::iterator it = m_properties.begin(); it != stop; ++it)
         (*it)->disconnectFrame();
+
+#if ENABLE(NOTIFICATIONS)
+    // FIXME: Notifications shouldn't have different disconnection logic than
+    // the rest of the DOMWindowProperties.
+    // There is currently no way to reconnect them in resumeFromPageCache() so
+    // they will be broken after returning to a cached page.
+    // This should be fixed as part of https://bugs.webkit.org/show_bug.cgi?id=79636
+    resetNotifications();
+#endif
+}
+
+void DOMWindow::reconnectDOMWindowProperties()
+{
+    ASSERT(m_suspendedForPageCache);
+    HashSet<DOMWindowProperty*>::iterator stop = m_properties.end();
+    for (HashSet<DOMWindowProperty*>::iterator it = m_properties.begin(); it != stop; ++it)
+        (*it)->reconnectFrame(m_frame);
+}
+
+void DOMWindow::clearDOMWindowProperties()
+{
+    disconnectDOMWindowProperties();
     m_properties.clear();
 
     m_screen = 0;
@@ -551,84 +601,108 @@
 
 Screen* DOMWindow::screen() const
 {
-    if (!m_screen && isCurrentlyDisplayedInFrame())
+    if (!isCurrentlyDisplayedInFrame())
+        return 0;
+    if (!m_screen)
         m_screen = Screen::create(m_frame);
     return m_screen.get();
 }
 
 History* DOMWindow::history() const
 {
-    if (!m_history && isCurrentlyDisplayedInFrame())
+    if (!isCurrentlyDisplayedInFrame())
+        return 0;
+    if (!m_history)
         m_history = History::create(m_frame);
     return m_history.get();
 }
 
 Crypto* DOMWindow::crypto() const
 {
-    if (!m_crypto && isCurrentlyDisplayedInFrame())
+    if (!isCurrentlyDisplayedInFrame())
+        return 0;
+    if (!m_crypto)
         m_crypto = Crypto::create();
     return m_crypto.get();
 }
 
 BarInfo* DOMWindow::locationbar() const
 {
-    if (!m_locationbar && isCurrentlyDisplayedInFrame())
+    if (!isCurrentlyDisplayedInFrame())
+        return 0;
+    if (!m_locationbar)
         m_locationbar = BarInfo::create(m_frame, BarInfo::Locationbar);
     return m_locationbar.get();
 }
 
 BarInfo* DOMWindow::menubar() const
 {
-    if (!m_menubar && isCurrentlyDisplayedInFrame())
+    if (!isCurrentlyDisplayedInFrame())
+        return 0;
+    if (!m_menubar)
         m_menubar = BarInfo::create(m_frame, BarInfo::Menubar);
     return m_menubar.get();
 }
 
 BarInfo* DOMWindow::personalbar() const
 {
-    if (!m_personalbar && isCurrentlyDisplayedInFrame())
+    if (!isCurrentlyDisplayedInFrame())
+        return 0;
+    if (!m_personalbar)
         m_personalbar = BarInfo::create(m_frame, BarInfo::Personalbar);
     return m_personalbar.get();
 }
 
 BarInfo* DOMWindow::scrollbars() const
 {
-    if (!m_scrollbars && isCurrentlyDisplayedInFrame())
+    if (!isCurrentlyDisplayedInFrame())
+        return 0;
+    if (!m_scrollbars)
         m_scrollbars = BarInfo::create(m_frame, BarInfo::Scrollbars);
     return m_scrollbars.get();
 }
 
 BarInfo* DOMWindow::statusbar() const
 {
-    if (!m_statusbar && isCurrentlyDisplayedInFrame())
+    if (!isCurrentlyDisplayedInFrame())
+        return 0;
+    if (!m_statusbar)
         m_statusbar = BarInfo::create(m_frame, BarInfo::Statusbar);
     return m_statusbar.get();
 }
 
 BarInfo* DOMWindow::toolbar() const
 {
-    if (!m_toolbar && isCurrentlyDisplayedInFrame())
+    if (!isCurrentlyDisplayedInFrame())
+        return 0;
+    if (!m_toolbar)
         m_toolbar = BarInfo::create(m_frame, BarInfo::Toolbar);
     return m_toolbar.get();
 }
 
 Console* DOMWindow::console() const
 {
-    if (!m_console && isCurrentlyDisplayedInFrame())
+    if (!isCurrentlyDisplayedInFrame())
+        return 0;
+    if (!m_console)
         m_console = Console::create(m_frame);
     return m_console.get();
 }
 
 DOMApplicationCache* DOMWindow::applicationCache() const
 {
-    if (!m_applicationCache && isCurrentlyDisplayedInFrame())
+    if (!isCurrentlyDisplayedInFrame())
+        return 0;
+    if (!m_applicationCache)
         m_applicationCache = DOMApplicationCache::create(m_frame);
     return m_applicationCache.get();
 }
 
 Navigator* DOMWindow::navigator() const
 {
-    if (!m_navigator && isCurrentlyDisplayedInFrame())
+    if (!isCurrentlyDisplayedInFrame())
+        return 0;
+    if (!m_navigator)
         m_navigator = Navigator::create(m_frame);
     return m_navigator.get();
 }
@@ -636,7 +710,9 @@
 #if ENABLE(WEB_TIMING)
 Performance* DOMWindow::performance() const
 {
-    if (!m_performance && isCurrentlyDisplayedInFrame())
+    if (!isCurrentlyDisplayedInFrame())
+        return 0;
+    if (!m_performance)
         m_performance = Performance::create(m_frame);
     return m_performance.get();
 }
@@ -644,14 +720,18 @@
 
 Location* DOMWindow::location() const
 {
-    if (!m_location && isCurrentlyDisplayedInFrame())
+    if (!isCurrentlyDisplayedInFrame())
+        return 0;
+    if (!m_location)
         m_location = Location::create(m_frame);
     return m_location.get();
 }
 
 Storage* DOMWindow::sessionStorage(ExceptionCode& ec) const
 {
-    if (m_sessionStorage || !isCurrentlyDisplayedInFrame())
+    if (!isCurrentlyDisplayedInFrame())
+        return 0;
+    if (m_sessionStorage)
         return m_sessionStorage.get();
 
     Document* document = this->document();
@@ -676,7 +756,9 @@
 
 Storage* DOMWindow::localStorage(ExceptionCode& ec) const
 {
-    if (m_localStorage || !isCurrentlyDisplayedInFrame())
+    if (!isCurrentlyDisplayedInFrame())
+        return 0;
+    if (m_localStorage)
         return m_localStorage.get();
 
     Document* document = this->document();
@@ -705,7 +787,9 @@
 #if ENABLE(NOTIFICATIONS)
 NotificationCenter* DOMWindow::webkitNotifications() const
 {
-    if (m_notifications || !isCurrentlyDisplayedInFrame())
+    if (!isCurrentlyDisplayedInFrame())
+        return 0;
+    if (m_notifications)
         return m_notifications.get();
 
     Document* document = this->document();
@@ -788,7 +872,7 @@
 {
     OwnPtr<PostMessageTimer> timer(t);
 
-    if (!document())
+    if (!document() || !isCurrentlyDisplayedInFrame())
         return;
 
     RefPtr<MessageEvent> event = timer->event(document());
@@ -796,7 +880,7 @@
     // Give the embedder a chance to intercept this postMessage because this
     // DOMWindow might be a proxy for another in browsers that support
     // postMessage calls across WebKit instances.
-    if (isCurrentlyDisplayedInFrame() && m_frame->loader()->client()->willCheckAndDispatchMessageEvent(timer->targetOrigin(), event.get()))
+    if (m_frame->loader()->client()->willCheckAndDispatchMessageEvent(timer->targetOrigin(), event.get()))
         return;
 
     if (timer->targetOrigin()) {
@@ -814,7 +898,9 @@
 
 DOMSelection* DOMWindow::getSelection()
 {
-    if (!m_selection && isCurrentlyDisplayedInFrame())
+    if (!isCurrentlyDisplayedInFrame())
+        return 0;
+    if (!m_selection)
         m_selection = DOMSelection::create(m_frame);
     return m_selection.get();
 }
@@ -1233,7 +1319,9 @@
 
 PassRefPtr<StyleMedia> DOMWindow::styleMedia() const
 {
-    if (!m_media && isCurrentlyDisplayedInFrame())
+    if (!isCurrentlyDisplayedInFrame())
+        return 0;
+    if (!m_media)
         m_media = StyleMedia::create(m_frame);
     return m_media.get();
 }
@@ -1832,7 +1920,9 @@
 #if ENABLE(QUOTA)
 StorageInfo* DOMWindow::webkitStorageInfo() const
 {
-    if (!m_storageInfo && isCurrentlyDisplayedInFrame())
+    if (!isCurrentlyDisplayedInFrame())
+        return 0;
+    if (!m_storageInfo)
         m_storageInfo = StorageInfo::create();
     return m_storageInfo.get();
 }

Modified: trunk/Source/WebCore/page/DOMWindow.h (110569 => 110570)


--- trunk/Source/WebCore/page/DOMWindow.h	2012-03-13 15:43:45 UTC (rev 110569)
+++ trunk/Source/WebCore/page/DOMWindow.h	2012-03-13 15:57:37 UTC (rev 110570)
@@ -95,6 +95,8 @@
         void unregisterProperty(DOMWindowProperty*);
 
         void clear();
+        void suspendForPageCache();
+        void resumeFromPageCache();
 
         PassRefPtr<MediaQueryList> matchMedia(const String&);
 
@@ -412,10 +414,15 @@
             PrepareDialogFunction = 0, void* functionContext = 0);
         bool isInsecureScriptAccess(DOMWindow* activeWindow, const String& urlString);
 
+        void clearDOMWindowProperties();
+        void disconnectDOMWindowProperties();
+        void reconnectDOMWindowProperties();
+
         RefPtr<SecurityOrigin> m_securityOrigin;
         KURL m_url;
 
         bool m_shouldPrintWhenFinishedLoading;
+        bool m_suspendedForPageCache;
 
         HashSet<DOMWindowProperty*> m_properties;
 

Modified: trunk/Source/WebCore/page/DOMWindowProperty.cpp (110569 => 110570)


--- trunk/Source/WebCore/page/DOMWindowProperty.cpp	2012-03-13 15:43:45 UTC (rev 110569)
+++ trunk/Source/WebCore/page/DOMWindowProperty.cpp	2012-03-13 15:57:37 UTC (rev 110570)
@@ -49,6 +49,13 @@
     m_frame = 0;
 }
 
+void DOMWindowProperty::reconnectFrame(Frame* frame)
+{
+    ASSERT(frame);
+    ASSERT(!m_frame);
+    m_frame = frame;
+}
+
 void DOMWindowProperty::willDetachPage()
 {
     // Subclasses should override this function to handle this notification.

Modified: trunk/Source/WebCore/page/DOMWindowProperty.h (110569 => 110570)


--- trunk/Source/WebCore/page/DOMWindowProperty.h	2012-03-13 15:43:45 UTC (rev 110569)
+++ trunk/Source/WebCore/page/DOMWindowProperty.h	2012-03-13 15:57:37 UTC (rev 110570)
@@ -35,6 +35,7 @@
     explicit DOMWindowProperty(Frame*);
 
     virtual void disconnectFrame();
+    virtual void reconnectFrame(Frame*);
     virtual void willDetachPage();
 
     Frame* frame() const { return m_frame; }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to