• beidson@apple.com's avatar
    <rdar://problem/10120155> and https://bugs.webkit.org/show_bug.cgi?id=82664 ... · 2a75a96b
    beidson@apple.com authored
    <rdar://problem/10120155> and https://bugs.webkit.org/show_bug.cgi?id=82664  Need DOMWindow mechanism to supplement UserScripts for page cache notifications
    
    Source/WebCore:
    
    This patch creates a new object type "DOMWindowExtension" which extends DOMWindowProperty.
    A DOMWindowExtension is tied to a particular DOMWindow and represents extensibility in that
    DOMWindow within a particular DOMWrapperWorld.
    
    It is a token object meant designed to notify clients of the various events in the lifetime
    of a DOMWindow property such as creation, disconnecting for the page cache, reconnecting
    when restoring from the page cache, and DOMWindow destruction.
    
    Reviewed by Sam Weinig.
    
    New WebKit API test DOMWindowExtensionBasic added.
    
    Add hooks for 4 new client calls regarding DOMWindowExtensions and global object lifetime:
    * loader/FrameLoaderClient.h:
    (WebCore::FrameLoaderClient::dispatchCanCreateGlobalObject):
    (WebCore::FrameLoaderClient::dispatchWillDisconnectDOMWindowExtensionFromGlobalObject):
    (WebCore::FrameLoaderClient::dispatchDidReconnectDOMWindowExtensionToGlobalObject):
    (WebCore::FrameLoaderClient::dispatchWillDestroyGlobalObjectForDOMWindowExtension):
    
    At the same time "DidClearWindowObject" is called, also notify clients that the global object is available:
    * loader/FrameLoader.cpp:
    (WebCore::FrameLoader::receivedFirstData):
    (WebCore::FrameLoader::dispatchGlobalObjectAvailableInAllWorlds):
    * loader/FrameLoader.h:
    
     DOMWindowProperties might want to unregister themselves during these notifications, so copy
     the set to a Vector. While this technique is arguably fragile, its certainly less fragile than
     mutating a set while iterating it:
    * page/DOMWindow.cpp:
    (WebCore::DOMWindow::willDetachPage):
    (WebCore::DOMWindow::disconnectDOMWindowProperties):
    (WebCore::DOMWindow::reconnectDOMWindowProperties):
    
     Implement the DOMWindowExtension object. It acts like a DOMWindowProperty with the added capability
     of remembering what Frame it used to be connected to so it can *always* notify clients on willDetachPage:
    * page/DOMWindowExtension.cpp: Added.
    (WebCore::DOMWindowExtension::DOMWindowExtension):
    (WebCore::DOMWindowExtension::~DOMWindowExtension):
    (WebCore::DOMWindowExtension::disconnectFrame):
    (WebCore::DOMWindowExtension::reconnectFrame):
    (WebCore::DOMWindowExtension::willDetachPage):
    * page/DOMWindowExtension.h: Added.
    (WebCore::DOMWindowExtension::create):
    (WebCore::DOMWindowExtension::world):
    
     Project files:
    * CMakeLists.txt:
    * GNUmakefile.list.am:
    * Target.pri:
    * WebCore.exp.in:
    * WebCore.gypi:
    * WebCore.vcproj/WebCore.vcproj:
    * WebCore.xcodeproj/project.pbxproj:
    
    Source/WebKit2:
    
    Reviewed by Sam Weinig.
    
    - Adds a new API object WKBundleDOMWindowExtension
    - Exposes callbacks about the lifetime of DOMWindowExtensions through BundlePageLoaderClient
    
    Add new API casts:
    * Shared/API/c/WKBase.h:
    * Shared/APIClientTraits.cpp:
    * Shared/APIObject.h:
    * WebProcess/InjectedBundle/API/c/WKBundleAPICast.h:
    
    Add API for the new DOMWindowExtension object:
    * WebProcess/InjectedBundle/API/c/WKBundleDOMWindowExtension.cpp: Added.
    (WKBundleDOMWindowExtensionGetTypeID):
    (WKBundleDOMWindowExtensionCreate):
    (WKBundleDOMWindowExtensionGetFrame):
    (WKBundleDOMWindowExtensionGetScriptWorld):
    * WebProcess/InjectedBundle/API/c/WKBundleDOMWindowExtension.h: Added.
    
    Add implementation for that API which wraps the WebCore::DOMWindowExtension:
    * WebProcess/InjectedBundle/InjectedBundleDOMWindowExtension.cpp: Added.
    (WebKit::allExtensions):
    (WebKit::InjectedBundleDOMWindowExtension::create):
    (WebKit::InjectedBundleDOMWindowExtension::get):
    (WebKit::InjectedBundleDOMWindowExtension::InjectedBundleDOMWindowExtension):
    (WebKit::InjectedBundleDOMWindowExtension::~InjectedBundleDOMWindowExtension):
    (WebKit::InjectedBundleDOMWindowExtension::frame):
    (WebKit::InjectedBundleDOMWindowExtension::world):
    * WebProcess/InjectedBundle/InjectedBundleDOMWindowExtension.h: Added.
    (InjectedBundleDOMWindowExtension):
    (WebKit::InjectedBundleDOMWindowExtension::type):
    
    Add new BundlePageLoaderClient methods:
    * WebProcess/InjectedBundle/API/c/WKBundlePage.h:
    * WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.cpp:
    (WebKit::InjectedBundlePageLoaderClient::didCreateGlobalObjectForFrame):
    (WebKit::InjectedBundlePageLoaderClient::willDisconnectDOMWindowExtensionFromGlobalObject):
    (WebKit::InjectedBundlePageLoaderClient::didReconnectDOMWindowExtensionToGlobalObject):
    (WebKit::InjectedBundlePageLoaderClient::willDestroyGlobalObjectForDOMWindowExtension):
    * WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.h:
    (InjectedBundlePageLoaderClient):
    
    Implement the 4 new callbacks from WebCore which notify the BundlePageLoaderClient:
    * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
    (WebKit::WebFrameLoaderClient::dispatchGlobalObjectAvailable):
    (WebKit::WebFrameLoaderClient::dispatchWillDisconnectDOMWindowExtensionFromGlobalObject):
    (WebKit::WebFrameLoaderClient::dispatchDidReconnectDOMWindowExtensionToGlobalObject):
    (WebKit::WebFrameLoaderClient::dispatchWillDestroyGlobalObjectForDOMWindowExtension):
    * WebProcess/WebCoreSupport/WebFrameLoaderClient.h:
    
    Project Files:
    * CMakeLists.txt:
    * GNUmakefile.am:
    * Target.pri:
    * WebKit2.xcodeproj/project.pbxproj:
    * win/WebKit2.vcproj:
    
    Tools:
    
    Reviewed by Sam Weinig.
    
    Add a new bundle test that stresses the basics of the WKBundleDOMWindowExtension API.
    
    It makes sure new extensions can be added at the right times, and that all of the expected
    callbacks are made.
    
    * TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionBasic.cpp: Added.
    (TestWebKitAPI::didReceiveMessageFromInjectedBundle): Record all messages sent from the bundle.
    (TestWebKitAPI::TEST): Run a page through some basic exercises, then compared messages sent from the
       bundle to a set of known expected messages.
    
    Listen to all the new client callbacks, create some extensions, and monitor their lifetimes:
    * TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionBasic_Bundle.cpp: Added.
    (TestWebKitAPI::DOMWindowExtensionBasic::DOMWindowExtensionBasic):
    (TestWebKitAPI::DOMWindowExtensionBasic::frameLoadFinished):
    (TestWebKitAPI::DOMWindowExtensionBasic::sendExtensionStateMessage):
    (TestWebKitAPI::DOMWindowExtensionBasic::initialize):
    (TestWebKitAPI::DOMWindowExtensionBasic::didCreatePage):
    (TestWebKitAPI::DOMWindowExtensionBasic::updateExtensionStateRecord):
    (TestWebKitAPI::DOMWindowExtensionBasic::sendBundleMessage):
    (TestWebKitAPI::DOMWindowExtensionBasic::didCreateGlobalObjectForFrame):
    (TestWebKitAPI::DOMWindowExtensionBasic::willDisconnectDOMWindowExtensionFromGlobalObject):
    (TestWebKitAPI::DOMWindowExtensionBasic::didReconnectDOMWindowExtensionToGlobalObject):
    (TestWebKitAPI::DOMWindowExtensionBasic::willDestroyGlobalObjectForDOMWindowExtension):
    (TestWebKitAPI::didFinishLoadForFrameCallback):
    (TestWebKitAPI::didCreateGlobalObjectForFrameCallback):
    (TestWebKitAPI::willDisconnectDOMWindowExtensionFromGlobalObjectCallback):
    (TestWebKitAPI::didReconnectDOMWindowExtensionToGlobalObjectCallback):
    (TestWebKitAPI::willDestroyGlobalObjectForDOMWindowExtensionCallback):
    
    * TestWebKitAPI/Tests/WebKit2/InjectedBundleBasic.cpp:
    (TestWebKitAPI::didReceiveMessageFromInjectedBundle): Make this method static, as it always should have been.
    
    * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@115083 268f45cc-cd09-0410-ab3c-d52691b4dbfc
    2a75a96b
DOMWindowExtension.cpp 4.42 KB