-
jberlin@webkit.org authored
https://bugs.webkit.org/show_bug.cgi?id=85888 Reviewed by Brady Eidson. Source/WebCore: WKBundlePageWillDestroyGlobalObjectForDOMWindowExtensionCallback was only being invoked when the WKPage was destroyed, and then only for the child frames. In addition, the DOMWindowExtension was holding onto a destroyed DOMWindow and attempting to unregister from when the WK2 wrapper object was attempting to destroy the DOMWindowExtension. The underlying issue here was that the DOMWindowProperties were getting disconnectFrame and willDetachPage called on them at the wrong times. Rename DOMWindowProperty::disconnectFrame and reconnectFrame to disconnectFrameForPageCache and reconnectFrameFromPageCache for clarity. Only invoke DOMWindowProperty::disconnectFrameForPageCache when the frame is going into the page cache. In the cases where the DOMWindow is getting destroyed, the frame is being destroyed, or the DOMWindow is getting cleared because the frame is being navigated, invoke DOMWindowProperty::willDestroyGlobalObjectInFrame instead of disconnectFrame. Invoke DOMWindowProperty::willDetachGlobalObjectFromFrame when a document is being detached because the frame has been detached (e.g. fast/storage/storage-detached-iframe.html) and won't be immediately destroyed. Invoke DOMWindowProperty::willDestroyGlobalObjectInCachedFrame when a cached frame is being destroyed. New WK2 API Test: DOMWindowExtensionNoCache. * Modules/indexeddb/DOMWindowIndexedDatabase.cpp: (WebCore::DOMWindowIndexedDatabase::disconnectFrameForPageCache): Updated for disconnectFrame rename. (WebCore::DOMWindowIndexedDatabase::reconnectFrameFromPageCache): Updated for reconnectFrame rename. (WebCore::DOMWindowIndexedDatabase::willDestroyGlobalObjectInCachedFrame): Get rid of the suspended IDBFactory. (WebCore::DOMWindowIndexedDatabase::willDestroyGlobalObjectInFrame): Get rid of the IDBFactory. (WebCore::DOMWindowIndexedDatabase::willDetachGlobalObjectFromFrame): Ditto. * Modules/indexeddb/DOMWindowIndexedDatabase.h: * dom/Document.cpp: (WebCore::Document::prepareForDestruction): Tell the DOMWindow before detaching the Document. * dom/Document.h: * history/CachedFrame.cpp: (WebCore::CachedFrame::destroy): Tell the DOMWindow. * loader/FrameLoader.cpp: (WebCore::FrameLoader::clear): Use Document::prepareForDestruction so that the DOMWindow is told about the main frame navigation before detaching the Document. * loader/appcache/DOMApplicationCache.cpp: (WebCore::DOMApplicationCache::disconnectFrameForPageCache): Updated for the disconnectFrame rename. (WebCore::DOMApplicationCache::reconnectFrameFromPageCache): Updated for the reconnectFrame rename. (WebCore::DOMApplicationCache::willDestroyGlobalObjectInFrame): Cover the cases formerly covered by disconnectFrame (which was sometimes being called when called when the frame was destroyed). * loader/appcache/DOMApplicationCache.h: * notifications/DOMWindowNotifications.cpp: (WebCore::DOMWindowNotifications::disconnectFrameForPageCache): Updated for the disconnectFrame rename. (WebCore::DOMWindowNotifications::reconnectFrameFromPageCache): Updated for the reconnectFrame rename. (WebCore::DOMWindowNotifications::willDestroyGlobalObjectInCachedFrame): Get rid of the suspended notification center. (WebCore::DOMWindowNotifications::willDestroyGlobalObjectInFrame): Get rid of the notification center. (WebCore::DOMWindowNotifications::willDetachGlobalObjectFromFrame): Do not allow use of the notification center by detached frames. * notifications/DOMWindowNotifications.h: * page/DOMWindow.cpp: (WebCore::DOMWindow::clearDOMWindowProperties): Do not call disconnectDOMWindowProperties. It is now the responsibility of the callers to tell the DOMWindowProperties the correct cause of being cleared. (WebCore::DOMWindow::~DOMWindow): Make sure the DOMWindowProperties still know that the DOMWindow is going away. (WebCore::DOMWindow::frameDestroyed): Invoke willDestroyGlobalObjectInFrame on the DOMWindowProperties. (WebCore::DOMWindow::willDetachPage): It is no longer necessary to tell the DOMWindowProperties anything here. (WebCore::DOMWindow::willDestroyCachedFrame): Tell the DOMWindowProperties. (WebCore::DOMWindow::willDestroyDocumentInFrame): Ditto. (WebCore::DOMWindow::willDetachDocumentFromFrame): Ditto. (WebCore::DOMWindow::clear): Ditto. (WebCore::DOMWindow::disconnectDOMWindowProperties): Updated for the disconnectFrame rename. (WebCore::DOMWindow::reconnectDOMWindowProperties): Ditto. * page/DOMWindow.h: * page/DOMWindowExtension.cpp: (WebCore::DOMWindowExtension::DOMWindowExtension): Move the responsibility for tracking the disconnected DOMWindow to DOMWindowProperty, since DOMWindowProperty will need it to unregister the property when a cached frame is destroyed. (WebCore::DOMWindowExtension::disconnectFrameForPageCache): Remove the code to check for disconnectFrame being called twice - it is now only called when a frame goes into the page cache. Let the DOMWindowProperty keep track of the disconnected DOMWindow. (WebCore::DOMWindowExtension::reconnectFrameFromPageCache): Let the DOMWindowProperty keep track of the disconnected DOMWindow. (WebCore::DOMWindowExtension::willDestroyGlobalObjectInCachedFrame): Dispatch the willDestroyGlobalObjectForDOMWindowExtension callback. (WebCore::DOMWindowExtension::willDestroyGlobalObjectInFrame): Ditto, but only if the callback hasn't already been sent because the frame has been detached. (WebCore::DOMWindowExtension::willDetachGlobalObjectFromFrame): Send the callback because nothing interesting can be done in the frame once it has been detached. * page/DOMWindowExtension.h: * page/DOMWindowProperty.cpp: (WebCore::DOMWindowProperty::DOMWindowProperty): Keep track of the disconnected DOMWindow so it can be used to unregister the property when a cached frame is destroyed. (WebCore::DOMWindowProperty::~DOMWindowProperty): Also unregister the property when a DOMWindowProperty for a cached frame is destroyed. (WebCore::DOMWindowProperty::disconnectFrameForPageCache): Keep track of the disconnected DOMWindow. (WebCore::DOMWindowProperty::reconnectFrameFromPageCache): Ditto. (WebCore::DOMWindowProperty::willDestroyGlobalObjectInCachedFrame): Unregister the property from the disconnected DOMWindow. (WebCore::DOMWindowProperty::willDestroyGlobalObjectInFrame): Unregister the property from the DOMWindow and stop keeping track of the frame. (WebCore::DOMWindowProperty::willDetachGlobalObjectFromFrame): Do not set m_frame to 0 because detached frames still have access to the DOMWindow, even if they can't do anything meaningful with it. * page/DOMWindowProperty.h: * page/Frame.cpp: (WebCore::Frame::setView): Tell the DOMWindow that the Document is being detached so it can tell the DOMWindowProperties. * page/PointerLock.cpp: (WebCore::PointerLock::disconnectFrameForPageCache): Updated for disconnectFrame rename. (WebCore::PointerLock::willDestroyGlobalObjectInFrame): Cover the cases formerly covered by disconnectFrame (which was sometimes being called when called when the frame was destroyed). * page/PointerLock.h: Tools: Cached frames can live slightly longer than the page, but most clients unregister themselves and do other cleanup in the willDestroyPage callback, making them miss the willDestroyGlobalObjectForDOMWindowExtension callbacks. The calls to willDestroyGlobalObjectForDOMWindowExtension in the DOMWindowExtensionBasic test were all being invoked underneath WebPage::close. This is unrealistic. Update that test to destroy the BundleDOMWindowExtensions in response to the willDestroyPage callback. Add a test to verify that willDestroyGlobalObjectForDOMWindowExtension is being called for pages that don't go into the page cache. * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: Add DOMWindowExtensionNoCache.cpp, DOMWindowExtensionNoCache_Bundle.cpp, simple-unload.html and simple-iframe-unload.html * TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionBasic.cpp: (TestWebKitAPI): Remove the expected messages for willDestroyGlobalObjectForDOMWindowExtension. (TestWebKitAPI::didReceiveMessageFromInjectedBundle): Do not bother to keep track of the live extension count - all of them are expected to be live until the test completes. (TestWebKitAPI::TEST): Fix the calls to EXPECT to pass the expected value first, and use EXPECT_WK_STREQ so that message failures will be clearer. * TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionBasic_Bundle.cpp: (TestWebKitAPI::DOMWindowExtensionBasic::willDestroyPage): Clean up the BundleDOMWindowExtensions. (TestWebKitAPI::DOMWindowExtensionBasic::willDestroyGlobalObjectForDOMWindowExtension): Add an ASSERT_NOT_REACHED. * TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionNoCache.cpp: Added. (TestWebKitAPI::didReceiveMessageFromInjectedBundle): Keep track of the messages received so they can be checked at the end of the test. (TestWebKitAPI::TEST): Navigate to uncacheable pages and back. * TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionNoCache_Bundle.cpp: Copied from Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionBasic_Bundle.cpp. (DOMWindowExtensionNoCache): (TestWebKitAPI::DOMWindowExtensionNoCache::DOMWindowExtensionNoCache): Set up all the states for each BundleDOMWindowExtension. (TestWebKitAPI::DOMWindowExtensionNoCache::frameLoadFinished): Tell the UI Process about the states of the BundleDOMWindowExtensions. (TestWebKitAPI::DOMWindowExtensionNoCache::sendExtensionStateMessage): (TestWebKitAPI::DOMWindowExtensionNoCache::initialize): (TestWebKitAPI::DOMWindowExtensionNoCache::didCreatePage): (TestWebKitAPI::DOMWindowExtensionNoCache::willDestroyPage): Remvoe the remaining BundleDOMWindowExtensions, send the updated state, and finish the test. (TestWebKitAPI::DOMWindowExtensionNoCache::updateExtensionStateRecord): (TestWebKitAPI::DOMWindowExtensionNoCache::sendBundleMessage): (TestWebKitAPI::DOMWindowExtensionNoCache::globalObjectIsAvailableForFrame): (TestWebKitAPI::DOMWindowExtensionNoCache::willDisconnectDOMWindowExtensionFromGlobalObject): ASSERT that these pages not going into the page cache are not getting disconnected to go into the page cache. (TestWebKitAPI::DOMWindowExtensionNoCache::didReconnectDOMWindowExtensionToGlobalObject): Ditto about getting reconnected when coming out of the page cache. (TestWebKitAPI::DOMWindowExtensionNoCache::willDestroyGlobalObjectForDOMWindowExtension): Tell the UI Process, update the state, and get rid of the BundleDOMWindowExtension. (TestWebKitAPI::didFinishLoadForFrameCallback): (TestWebKitAPI::globalObjectIsAvailableForFrameCallback): (TestWebKitAPI::willDisconnectDOMWindowExtensionFromGlobalObjectCallback): (TestWebKitAPI::didReconnectDOMWindowExtensionToGlobalObjectCallback): (TestWebKitAPI::willDestroyGlobalObjectForDOMWindowExtensionCallback): * TestWebKitAPI/Tests/WebKit2/simple-iframe-unload.html: Added. * TestWebKitAPI/Tests/WebKit2/simple-unload.html: Added. git-svn-id: http://svn.webkit.org/repository/webkit/trunk@116595 268f45cc-cd09-0410-ab3c-d52691b4dbfc
a4facf2c