Changeset 199020 in webkit


Ignore:
Timestamp:
Apr 4, 2016 2:03:28 PM (8 years ago)
Author:
weinig@apple.com
Message:

Add SPI to allow install script message handlers in isolated worlds
https://bugs.webkit.org/show_bug.cgi?id=156153

Reviewed by Anders Carlsson.

Source/WebCore:

Added API Test: WKUserContentController.ScriptMessageHandlerBasicPostIsolatedWorld

  • Changes the signature of the method in UserContentProvider to get UserMessageHandlerDescriptors to match that of UserScripts and UserStyleSheets.
  • Removes the need for UserMessageHandlerDescriptor::Client by making UserMessageHandlerDescriptor directly subclassable.
  • Changes invalidation model of UserMessageHandlersNamespace to be more direct by allowing it to register for invalidation notifications, rather than always checking if handler has been removed on each invocation.
  • loader/EmptyClients.cpp:

Update for new signature.

  • page/DOMWindow.cpp:

(WebCore::DOMWindow::shouldHaveWebKitNamespaceForWorld):
Switch to using forEachUserMessageHandler.

(WebCore::DOMWindow::webkitNamespace):
Pass the UserContentProvider to the namespace on creation, so the UserMessageHandlersNamespace
can use it to register to listen for UserMessageHandler changes.

  • page/UserContentController.h:
  • page/UserContentController.cpp:

(WebCore::UserContentController::forEachUserStyleSheet):
(WebCore::UserContentController::forEachUserMessageHandler):
(WebCore::UserContentController::addUserScript):
(WebCore::UserContentController::removeUserStyleSheets):
(WebCore::UserContentController::removeAllUserContent):
(WebCore::UserContentController::addUserMessageHandlerDescriptor): Deleted.
(WebCore::UserContentController::removeUserMessageHandlerDescriptor): Deleted.
(WebCore::UserContentController::addUserContentExtension): Deleted.
(WebCore::UserContentController::removeUserContentExtension): Deleted.
(WebCore::UserContentController::removeAllUserContentExtensions): Deleted.
Removed unused functions, all the UserMessageHandler and UserContentExtension ones. UserContentController
is only used for Legacy WebKit where those features are not exposed.

  • page/UserContentProvider.h:
  • page/UserContentProvider.cpp:

(WebCore::UserContentProvider::registerForUserMessageHandlerInvalidation):
(WebCore::UserContentProvider::unregisterForUserMessageHandlerInvalidation):
(WebCore::UserContentProvider::invalidateAllRegisteredUserMessageHandlerInvalidationClients):
(WebCore::UserContentProviderInvalidationClient::~UserContentProviderInvalidationClient):
Update signature for UserMessageHandlerDescriptor access to match UserScript and UserStyleSheet.
Adds explicit invalidation for UserMessageHandlers.

  • page/UserMessageHandler.cpp:

(WebCore::UserMessageHandler::UserMessageHandler):
(WebCore::UserMessageHandler::postMessage):
(WebCore::UserMessageHandler::name): Deleted.
(WebCore::UserMessageHandler::world): Deleted.

  • page/UserMessageHandler.h:

(WebCore::UserMessageHandler::descriptor):
(WebCore::UserMessageHandler::invalidateDescriptor):

  • page/UserMessageHandlerDescriptor.cpp:

(WebCore::UserMessageHandlerDescriptor::UserMessageHandlerDescriptor):
(WebCore::UserMessageHandlerDescriptor::~UserMessageHandlerDescriptor):
(WebCore::UserMessageHandlerDescriptor::name):
(WebCore::UserMessageHandlerDescriptor::world):

  • page/UserMessageHandlerDescriptor.h:

(WebCore::UserMessageHandlerDescriptor::Client::~Client): Deleted.
(WebCore::UserMessageHandlerDescriptor::create): Deleted.
(WebCore::UserMessageHandlerDescriptor::client): Deleted.
(WebCore::UserMessageHandlerDescriptor::invalidateClient): Deleted.
Simplify by removing the Client. Now, when the UserMessageHandlerDescriptor is no longer
active, it gets nulled out in the UserMessageHandler.

  • page/UserMessageHandlersNamespace.cpp:

(WebCore::UserMessageHandlersNamespace::UserMessageHandlersNamespace):
(WebCore::UserMessageHandlersNamespace::~UserMessageHandlersNamespace):
(WebCore::UserMessageHandlersNamespace::didInvalidate):
(WebCore::UserMessageHandlersNamespace::handler):

  • page/UserMessageHandlersNamespace.h:

Change the logic to listen for invalidations of the UserMessageHandlerDescriptor map. When it
is invalidated, re-build the map of cached UserMessageHandlers from the UserContentProvider,
and invalidate any remaining UserMessageHandlers that no longer exist in the UserContentProvider.

  • page/WebKitNamespace.cpp:

(WebCore::WebKitNamespace::WebKitNamespace):

  • page/WebKitNamespace.h:

(WebCore::WebKitNamespace::create):
Pass through the UserContentProvider.

Source/WebKit2:

  • Scripts/webkit/messages.py:

(headers_for_type):

  • Shared/WebUserContentControllerDataTypes.cpp:

(WebKit::WebScriptMessageHandlerData::encode):
(WebKit::WebScriptMessageHandlerData::decode):

  • Shared/WebUserContentControllerDataTypes.h:

Add WebKit::WebScriptMessageHandlerData, matching WebKit::WebUserScriptData and
WebKit::WebUserStyleSheetData.

  • UIProcess/API/Cocoa/WKUserContentController.mm:

(-[WKUserContentController addScriptMessageHandler:name:]):
(-[WKUserContentController removeScriptMessageHandlerForName:]):
(-[WKUserContentController _removeAllUserStyleSheetsAssociatedWithUserContentWorld:]):
(-[WKUserContentController _addScriptMessageHandler:name:userContentWorld:]):
(-[WKUserContentController _removeScriptMessageHandlerForName:userContentWorld:]):
(-[WKUserContentController _removeAllScriptMessageHandlersAssociatedWithUserContentWorld:]):

  • UIProcess/API/Cocoa/WKUserContentControllerPrivate.h:

Add SPI for adding and removing ScriptMessageHandlers associated with a world.

  • UIProcess/UserContent/WebScriptMessageHandler.cpp:

(WebKit::WebScriptMessageHandler::create):
(WebKit::WebScriptMessageHandler::WebScriptMessageHandler):
(WebKit::WebScriptMessageHandlerHandle::encode): Deleted.
(WebKit::WebScriptMessageHandlerHandle::decode): Deleted.

  • UIProcess/UserContent/WebScriptMessageHandler.h:

(WebKit::WebScriptMessageHandler::identifier):
(WebKit::WebScriptMessageHandler::name):
(WebKit::WebScriptMessageHandler::userContentWorld):
(WebKit::WebScriptMessageHandler::client):
(WebKit::WebScriptMessageHandler::handle): Deleted.
Add the world and move the data object to WebUserContentControllerDataTypes.h

  • UIProcess/UserContent/WebUserContentControllerProxy.cpp:

(WebKit::WebUserContentControllerProxy::addProcess):
(WebKit::WebUserContentControllerProxy::addUserScriptMessageHandler):
(WebKit::WebUserContentControllerProxy::removeUserMessageHandlerForName):
(WebKit::WebUserContentControllerProxy::removeAllUserMessageHandlers):

  • UIProcess/UserContent/WebUserContentControllerProxy.h:

Update for worlds, matching UserScript/UserStyleSheet model.

  • WebProcess/UserContent/WebUserContentController.h:
  • WebProcess/UserContent/WebUserContentController.cpp:

(WebKit::WebUserMessageHandlerDescriptorProxy::WebUserMessageHandlerDescriptorProxy):
Change to inherit directly from WebCore::UserMessageHandlerDescriptor.

(WebKit::WebUserContentController::addUserScriptMessageHandlers):
(WebKit::WebUserContentController::removeUserScriptMessageHandler):
(WebKit::WebUserContentController::removeAllUserScriptMessageHandlers):
(WebKit::WebUserContentController::addUserScriptMessageHandlerInternal):
(WebKit::WebUserContentController::removeUserScriptMessageHandlerInternal):
Add support for worlds, matching UserScript/UserStyleSheet model.

(WebKit::WebUserContentController::addUserStyleSheets):
Add missing call to invalidateInjectedStyleSheetCacheInAllFramesInAllPages()

(WebKit::WebUserContentController::removeAllUserStyleSheets):
Switch to only calling invalidateInjectedStyleSheetCacheInAllFramesInAllPages() once
after the loop and only if any stylesheets were removed.

(WebKit::WebUserContentController::addUserStyleSheetInternal):
Remove call to invalidateInjectedStyleSheetCacheInAllFramesInAllPages(), make
callers call it. This allows us to avoid calling it repeatedly in removeAllUserStyleSheets().

(WebKit::WebUserContentController::addUserStyleSheet):
Call invalidateInjectedStyleSheetCacheInAllFramesInAllPages() explicitly since it
is no longer called in addUserStyleSheetInternal().

(WebKit::WebUserContentController::forEachUserMessageHandler):
Implement by iterating the m_userMessageHandlers map.

  • WebProcess/UserContent/WebUserContentController.messages.in:

Update for worlds, matching UserScript/UserStyleSheet model.

Tools:

  • TestWebKitAPI/Tests/WebKit2Cocoa/UserContentController.mm:

Add new test, WKUserContentController.ScriptMessageHandlerBasicPostIsolatedWorld

Location:
trunk
Files:
30 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r199017 r199020  
     12016-04-03  Sam Weinig  <sam@webkit.org>
     2
     3        Add SPI to allow install script message handlers in isolated worlds
     4        https://bugs.webkit.org/show_bug.cgi?id=156153
     5
     6        Reviewed by Anders Carlsson.
     7
     8        Added API Test: WKUserContentController.ScriptMessageHandlerBasicPostIsolatedWorld
     9
     10        - Changes the signature of the method in UserContentProvider to get UserMessageHandlerDescriptors
     11          to match that of UserScripts and UserStyleSheets.
     12        - Removes the need for UserMessageHandlerDescriptor::Client by making UserMessageHandlerDescriptor
     13          directly subclassable.
     14        - Changes invalidation model of UserMessageHandlersNamespace to be more direct by allowing it to
     15          register for invalidation notifications, rather than always checking if handler has been removed
     16          on each invocation.
     17
     18        * loader/EmptyClients.cpp:
     19        Update for new signature.
     20
     21        * page/DOMWindow.cpp:
     22        (WebCore::DOMWindow::shouldHaveWebKitNamespaceForWorld):
     23        Switch to using forEachUserMessageHandler.
     24
     25        (WebCore::DOMWindow::webkitNamespace):
     26        Pass the UserContentProvider to the namespace on creation, so the UserMessageHandlersNamespace
     27        can use it to register to listen for UserMessageHandler changes.
     28
     29        * page/UserContentController.h:
     30        * page/UserContentController.cpp:
     31        (WebCore::UserContentController::forEachUserStyleSheet):
     32        (WebCore::UserContentController::forEachUserMessageHandler):
     33        (WebCore::UserContentController::addUserScript):
     34        (WebCore::UserContentController::removeUserStyleSheets):
     35        (WebCore::UserContentController::removeAllUserContent):
     36        (WebCore::UserContentController::addUserMessageHandlerDescriptor): Deleted.
     37        (WebCore::UserContentController::removeUserMessageHandlerDescriptor): Deleted.
     38        (WebCore::UserContentController::addUserContentExtension): Deleted.
     39        (WebCore::UserContentController::removeUserContentExtension): Deleted.
     40        (WebCore::UserContentController::removeAllUserContentExtensions): Deleted.
     41        Removed unused functions, all the UserMessageHandler and UserContentExtension ones. UserContentController
     42        is only used for Legacy WebKit where those features are not exposed.
     43
     44        * page/UserContentProvider.h:
     45        * page/UserContentProvider.cpp:
     46        (WebCore::UserContentProvider::registerForUserMessageHandlerInvalidation):
     47        (WebCore::UserContentProvider::unregisterForUserMessageHandlerInvalidation):
     48        (WebCore::UserContentProvider::invalidateAllRegisteredUserMessageHandlerInvalidationClients):
     49        (WebCore::UserContentProviderInvalidationClient::~UserContentProviderInvalidationClient):
     50        Update signature for UserMessageHandlerDescriptor access to match UserScript and UserStyleSheet.
     51        Adds explicit invalidation for UserMessageHandlers.
     52
     53        * page/UserMessageHandler.cpp:
     54        (WebCore::UserMessageHandler::UserMessageHandler):
     55        (WebCore::UserMessageHandler::postMessage):
     56        (WebCore::UserMessageHandler::name): Deleted.
     57        (WebCore::UserMessageHandler::world): Deleted.
     58        * page/UserMessageHandler.h:
     59        (WebCore::UserMessageHandler::descriptor):
     60        (WebCore::UserMessageHandler::invalidateDescriptor):
     61        * page/UserMessageHandlerDescriptor.cpp:
     62        (WebCore::UserMessageHandlerDescriptor::UserMessageHandlerDescriptor):
     63        (WebCore::UserMessageHandlerDescriptor::~UserMessageHandlerDescriptor):
     64        (WebCore::UserMessageHandlerDescriptor::name):
     65        (WebCore::UserMessageHandlerDescriptor::world):
     66        * page/UserMessageHandlerDescriptor.h:
     67        (WebCore::UserMessageHandlerDescriptor::Client::~Client): Deleted.
     68        (WebCore::UserMessageHandlerDescriptor::create): Deleted.
     69        (WebCore::UserMessageHandlerDescriptor::client): Deleted.
     70        (WebCore::UserMessageHandlerDescriptor::invalidateClient): Deleted.
     71        Simplify by removing the Client. Now, when the UserMessageHandlerDescriptor is no longer
     72        active, it gets nulled out in the UserMessageHandler.
     73
     74        * page/UserMessageHandlersNamespace.cpp:
     75        (WebCore::UserMessageHandlersNamespace::UserMessageHandlersNamespace):
     76        (WebCore::UserMessageHandlersNamespace::~UserMessageHandlersNamespace):
     77        (WebCore::UserMessageHandlersNamespace::didInvalidate):
     78        (WebCore::UserMessageHandlersNamespace::handler):
     79        * page/UserMessageHandlersNamespace.h:
     80        Change the logic to listen for invalidations of the UserMessageHandlerDescriptor map. When it
     81        is invalidated, re-build the map of cached UserMessageHandlers from the UserContentProvider,
     82        and invalidate any remaining UserMessageHandlers that no longer exist in the UserContentProvider.
     83
     84        * page/WebKitNamespace.cpp:
     85        (WebCore::WebKitNamespace::WebKitNamespace):
     86        * page/WebKitNamespace.h:
     87        (WebCore::WebKitNamespace::create):
     88        Pass through the UserContentProvider.
     89
    1902016-04-04  Chris Dumez  <cdumez@apple.com>
    291
  • trunk/Source/WebCore/loader/EmptyClients.cpp

    r198389 r199020  
    102102    void forEachUserStyleSheet(const std::function<void(const UserStyleSheet&)>&) const override { }
    103103#if ENABLE(USER_MESSAGE_HANDLERS)
    104     const UserMessageHandlerDescriptorMap& userMessageHandlerDescriptors() const override { static NeverDestroyed<UserMessageHandlerDescriptorMap> map; return map.get(); }
     104    void forEachUserMessageHandler(const std::function<void(const UserMessageHandlerDescriptor&)>&) const override { }
    105105#endif
    106106#if ENABLE(CONTENT_EXTENSIONS)
  • trunk/Source/WebCore/page/DOMWindow.cpp

    r198180 r199020  
    762762        return false;
    763763
    764     for (auto& descriptor : page->userContentProvider().userMessageHandlerDescriptors().values()) {
    765         if (&descriptor->world() == &world)
    766             return true;
    767     }
    768 
    769     return false;
     764    bool hasUserMessageHandler = false;
     765    page->userContentProvider().forEachUserMessageHandler([&](const UserMessageHandlerDescriptor& descriptor) {
     766        if (&descriptor.world() == &world) {
     767            hasUserMessageHandler = true;
     768            return;
     769        }
     770    });
     771
     772    return hasUserMessageHandler;
    770773}
    771774
     
    773776{
    774777    if (!isCurrentlyDisplayedInFrame())
     778        return nullptr;
     779    auto* page = m_frame->page();
     780    if (!page)
    775781        return nullptr;
    776782    if (!m_webkitNamespace)
    777         m_webkitNamespace = WebKitNamespace::create(*m_frame);
     783        m_webkitNamespace = WebKitNamespace::create(*m_frame, page->userContentProvider());
    778784    return m_webkitNamespace.get();
    779785}
  • trunk/Source/WebCore/page/UserContentController.cpp

    r198183 r199020  
    3232#include <runtime/JSCellInlines.h>
    3333#include <runtime/StructureInlines.h>
    34 
    35 #if ENABLE(USER_MESSAGE_HANDLERS)
    36 #include "UserMessageHandlerDescriptor.h"
    37 #endif
    3834
    3935#if ENABLE(CONTENT_EXTENSIONS)
     
    7268    }
    7369}
     70
     71#if ENABLE(USER_MESSAGE_HANDLERS)
     72void UserContentController::forEachUserMessageHandler(const std::function<void(const UserMessageHandlerDescriptor&)>&) const
     73{
     74}
     75#endif
    7476
    7577void UserContentController::addUserScript(DOMWrapperWorld& world, std::unique_ptr<UserScript> userScript)
     
    142144}
    143145
    144 #if ENABLE(USER_MESSAGE_HANDLERS)
    145 void UserContentController::addUserMessageHandlerDescriptor(UserMessageHandlerDescriptor& descriptor)
    146 {
    147     m_userMessageHandlerDescriptors.add(std::make_pair(descriptor.name(), &descriptor.world()), &descriptor);
    148 }
    149 
    150 void UserContentController::removeUserMessageHandlerDescriptor(UserMessageHandlerDescriptor& descriptor)
    151 {
    152     m_userMessageHandlerDescriptors.remove(std::make_pair(descriptor.name(), &descriptor.world()));
    153 }
    154 #endif
    155 
    156 #if ENABLE(CONTENT_EXTENSIONS)
    157 void UserContentController::addUserContentExtension(const String& name, RefPtr<ContentExtensions::CompiledContentExtension> contentExtension)
    158 {
    159     m_contentExtensionBackend.addContentExtension(name, contentExtension);
    160 }
    161 
    162 void UserContentController::removeUserContentExtension(const String& name)
    163 {
    164     m_contentExtensionBackend.removeContentExtension(name);
    165 }
    166 
    167 void UserContentController::removeAllUserContentExtensions()
    168 {
    169     m_contentExtensionBackend.removeAllContentExtensions();
    170 }
    171 #endif
    172 
    173146void UserContentController::removeAllUserContent()
    174147{
  • trunk/Source/WebCore/page/UserContentController.h

    r198180 r199020  
    4646    WEBCORE_EXPORT void removeAllUserContent();
    4747
    48 #if ENABLE(USER_MESSAGE_HANDLERS)
    49     WEBCORE_EXPORT void addUserMessageHandlerDescriptor(UserMessageHandlerDescriptor&);
    50     WEBCORE_EXPORT void removeUserMessageHandlerDescriptor(UserMessageHandlerDescriptor&);
    51 #endif
    52 
    53 #if ENABLE(CONTENT_EXTENSIONS)
    54     WEBCORE_EXPORT void addUserContentExtension(const String& name, RefPtr<ContentExtensions::CompiledContentExtension>);
    55     WEBCORE_EXPORT void removeUserContentExtension(const String& name);
    56     WEBCORE_EXPORT void removeAllUserContentExtensions();
    57 #endif
    58 
    5948private:
    6049    UserContentController();
     
    6453    void forEachUserStyleSheet(const std::function<void(const UserStyleSheet&)>&) const override;
    6554#if ENABLE(USER_MESSAGE_HANDLERS)
    66     const UserMessageHandlerDescriptorMap& userMessageHandlerDescriptors() const override { return m_userMessageHandlerDescriptors; }
     55    void forEachUserMessageHandler(const std::function<void(const UserMessageHandlerDescriptor&)>&) const override;
    6756#endif
    6857#if ENABLE(CONTENT_EXTENSIONS)
     
    7261    UserScriptMap m_userScripts;
    7362    UserStyleSheetMap m_userStyleSheets;
    74 #if ENABLE(USER_MESSAGE_HANDLERS)
    75     UserMessageHandlerDescriptorMap m_userMessageHandlerDescriptors;
    76 #endif
    7763#if ENABLE(CONTENT_EXTENSIONS)
    7864    ContentExtensions::ContentExtensionsBackend m_contentExtensionBackend;
  • trunk/Source/WebCore/page/UserContentProvider.cpp

    r198180 r199020  
    6262}
    6363
     64void UserContentProvider::registerForUserMessageHandlerInvalidation(UserContentProviderInvalidationClient& invalidationClient)
     65{
     66    ASSERT(!m_userMessageHandlerInvalidationClients.contains(&invalidationClient));
     67
     68    m_userMessageHandlerInvalidationClients.add(&invalidationClient);
     69}
     70
     71void UserContentProvider::unregisterForUserMessageHandlerInvalidation(UserContentProviderInvalidationClient& invalidationClient)
     72{
     73    ASSERT(m_userMessageHandlerInvalidationClients.contains(&invalidationClient));
     74
     75    m_userMessageHandlerInvalidationClients.remove(&invalidationClient);
     76}
     77
     78void UserContentProvider::invalidateAllRegisteredUserMessageHandlerInvalidationClients()
     79{
     80    for (auto& client : m_userMessageHandlerInvalidationClients)
     81        client->didInvalidate(*this);
     82}
     83
    6484void UserContentProvider::invalidateInjectedStyleSheetCacheInAllFramesInAllPages()
    6585{
  • trunk/Source/WebCore/page/UserContentProvider.h

    r198180 r199020  
    5959}
    6060
     61class UserContentProvider;
     62
     63class UserContentProviderInvalidationClient {
     64public:
     65    virtual ~UserContentProviderInvalidationClient()
     66    {
     67    }
     68   
     69    virtual void didInvalidate(UserContentProvider&) = 0;
     70};
     71
    6172class UserContentProvider : public RefCounted<UserContentProvider> {
    6273public:
     
    6677    virtual void forEachUserScript(const std::function<void(DOMWrapperWorld&, const UserScript&)>&) const = 0;
    6778    virtual void forEachUserStyleSheet(const std::function<void(const UserStyleSheet&)>&) const = 0;
    68 
    6979#if ENABLE(USER_MESSAGE_HANDLERS)
    70     virtual const UserMessageHandlerDescriptorMap& userMessageHandlerDescriptors() const = 0;
     80    virtual void forEachUserMessageHandler(const std::function<void(const UserMessageHandlerDescriptor&)>&) const = 0;
    7181#endif
    72 
    7382#if ENABLE(CONTENT_EXTENSIONS)
    7483    virtual ContentExtensions::ContentExtensionsBackend& userContentExtensionBackend() = 0;
    7584#endif
    7685
     86    void registerForUserMessageHandlerInvalidation(UserContentProviderInvalidationClient&);
     87    void unregisterForUserMessageHandlerInvalidation(UserContentProviderInvalidationClient&);
     88
    7789    void addPage(Page&);
    7890    void removePage(Page&);
    79 
    8091
    8192#if ENABLE(CONTENT_EXTENSIONS)
     
    8798
    8899protected:
     100    WEBCORE_EXPORT void invalidateAllRegisteredUserMessageHandlerInvalidationClients();
    89101    WEBCORE_EXPORT void invalidateInjectedStyleSheetCacheInAllFramesInAllPages();
    90102
    91103private:
    92104    HashSet<Page*> m_pages;
     105    HashSet<UserContentProviderInvalidationClient*> m_userMessageHandlerInvalidationClients;
    93106};
    94107
  • trunk/Source/WebCore/page/UserMessageHandler.cpp

    r184846 r199020  
    3737UserMessageHandler::UserMessageHandler(Frame& frame, UserMessageHandlerDescriptor& descriptor)
    3838    : FrameDestructionObserver(&frame)
    39     , m_descriptor(descriptor)
     39    , m_descriptor(&descriptor)
    4040{
    4141}
     
    4949    // Check to see if the descriptor has been removed. This can happen if the host application has
    5050    // removed the named message handler at the WebKit2 API level.
    51     if (!m_descriptor->client()) {
     51    if (!m_descriptor) {
    5252        ec = INVALID_ACCESS_ERR;
    5353        return;
    5454    }
    5555
    56     m_descriptor->client()->didPostMessage(*this, value.get());
    57 }
    58 
    59 const AtomicString& UserMessageHandler::name()
    60 {
    61     return m_descriptor->name();
    62 }
    63 
    64 DOMWrapperWorld& UserMessageHandler::world()
    65 {
    66     return m_descriptor->world();
     56    m_descriptor->didPostMessage(*this, value.get());
    6757}
    6858
  • trunk/Source/WebCore/page/UserMessageHandler.h

    r197868 r199020  
    3131#include "FrameDestructionObserver.h"
    3232#include "UserMessageHandlerDescriptor.h"
    33 #include <bindings/ScriptValue.h>
    3433
    3534namespace WebCore {
     
    4746    void postMessage(PassRefPtr<SerializedScriptValue>, ExceptionCode&);
    4847
    49     const AtomicString& name();
    50     DOMWrapperWorld& world();
    51     const UserMessageHandlerDescriptor& descriptor() const { return m_descriptor.get(); }
     48    UserMessageHandlerDescriptor* descriptor() { return m_descriptor.get(); }
     49    void invalidateDescriptor() { m_descriptor = nullptr; }
    5250
    5351private:
    5452    UserMessageHandler(Frame&, UserMessageHandlerDescriptor&);
    5553   
    56     Ref<UserMessageHandlerDescriptor> m_descriptor;
     54    RefPtr<UserMessageHandlerDescriptor> m_descriptor;
    5755};
    5856
  • trunk/Source/WebCore/page/UserMessageHandlerDescriptor.cpp

    r184846 r199020  
    3333namespace WebCore {
    3434
    35 UserMessageHandlerDescriptor::UserMessageHandlerDescriptor(const AtomicString& name, DOMWrapperWorld& world, Client& client)
     35UserMessageHandlerDescriptor::UserMessageHandlerDescriptor(const AtomicString& name, DOMWrapperWorld& world)
    3636    : m_name(name)
    3737    , m_world(world)
    38     , m_client(&client)
    3938{
    4039}
     
    4443}
    4544
    46 const AtomicString& UserMessageHandlerDescriptor::name()
     45const AtomicString& UserMessageHandlerDescriptor::name() const
    4746{
    4847    return m_name;
     
    5453}
    5554
     55const DOMWrapperWorld& UserMessageHandlerDescriptor::world() const
     56{
     57    return m_world.get();
     58}
     59
    5660} // namespace WebCore
    5761
  • trunk/Source/WebCore/page/UserMessageHandlerDescriptor.h

    r198180 r199020  
    2929#if ENABLE(USER_MESSAGE_HANDLERS)
    3030
    31 #include <wtf/PassRefPtr.h>
     31#include <wtf/Ref.h>
    3232#include <wtf/RefCounted.h>
    33 #include <wtf/RefPtr.h>
    3433#include <wtf/text/AtomicString.h>
    3534
    3635namespace WebCore {
    3736
    38 class Frame;
    3937class DOMWrapperWorld;
     38class SerializedScriptValue;
    4039class UserMessageHandler;
    41 class SerializedScriptValue;
    4240
    4341class UserMessageHandlerDescriptor : public RefCounted<UserMessageHandlerDescriptor> {
    4442public:
    45     class Client {
    46     public:
    47         virtual ~Client() { }
    48         virtual void didPostMessage(UserMessageHandler&, SerializedScriptValue*) = 0;
    49     };
     43    WEBCORE_EXPORT explicit UserMessageHandlerDescriptor(const AtomicString&, DOMWrapperWorld&);
     44    WEBCORE_EXPORT virtual ~UserMessageHandlerDescriptor();
    5045
    51     static Ref<UserMessageHandlerDescriptor> create(const AtomicString& name, DOMWrapperWorld& world, Client& client)
    52     {
    53         return adoptRef(*new UserMessageHandlerDescriptor(name, world, client));
    54     }
    55     WEBCORE_EXPORT ~UserMessageHandlerDescriptor();
     46    WEBCORE_EXPORT const AtomicString& name() const;
     47    WEBCORE_EXPORT DOMWrapperWorld& world();
     48    WEBCORE_EXPORT const DOMWrapperWorld& world() const;
    5649
    57     WEBCORE_EXPORT const AtomicString& name();
    58     WEBCORE_EXPORT DOMWrapperWorld& world();
    59 
    60     Client* client() const { return m_client; }
    61     void invalidateClient() { m_client = nullptr; }
     50    virtual void didPostMessage(UserMessageHandler&, SerializedScriptValue*) = 0;
    6251
    6352private:
    64     WEBCORE_EXPORT explicit UserMessageHandlerDescriptor(const AtomicString&, DOMWrapperWorld&, Client&);
    65 
    6653    AtomicString m_name;
    6754    Ref<DOMWrapperWorld> m_world;
    68     Client* m_client;
    6955};
    7056
  • trunk/Source/WebCore/page/UserMessageHandlersNamespace.cpp

    r198180 r199020  
    3333#include "Page.h"
    3434#include "UserContentController.h"
     35#include "UserMessageHandler.h"
    3536
    3637namespace WebCore {
    3738
    38 UserMessageHandlersNamespace::UserMessageHandlersNamespace(Frame& frame)
     39UserMessageHandlersNamespace::UserMessageHandlersNamespace(Frame& frame, UserContentProvider& userContentProvider)
    3940    : FrameDestructionObserver(&frame)
     41    , m_userContentProvider(userContentProvider)
    4042{
     43    m_userContentProvider->registerForUserMessageHandlerInvalidation(*this);
    4144}
    4245
    4346UserMessageHandlersNamespace::~UserMessageHandlersNamespace()
    4447{
     48    m_userContentProvider->unregisterForUserMessageHandlerInvalidation(*this);
     49}
     50
     51void UserMessageHandlersNamespace::didInvalidate(UserContentProvider& provider)
     52{
     53    auto oldMap = WTFMove(m_messageHandlers);
     54
     55    provider.forEachUserMessageHandler([&](const UserMessageHandlerDescriptor& descriptor) {
     56        auto userMessageHandler = oldMap.take(std::make_pair(descriptor.name(), const_cast<DOMWrapperWorld*>(&descriptor.world())));
     57        if (userMessageHandler) {
     58            m_messageHandlers.add(std::make_pair(descriptor.name(), const_cast<DOMWrapperWorld*>(&descriptor.world())), userMessageHandler);
     59            return;
     60        }
     61    });
     62
     63    for (auto& userMessageHandler : oldMap.values())
     64        userMessageHandler->invalidateDescriptor();
    4565}
    4666
    4767UserMessageHandler* UserMessageHandlersNamespace::handler(const AtomicString& name, DOMWrapperWorld& world)
    4868{
    49     if (!frame())
     69    Frame* frame = this->frame();
     70    if (!frame)
    5071        return nullptr;
    5172
    52     Page* page = frame()->page();
     73    Page* page = frame->page();
    5374    if (!page)
    5475        return nullptr;
    55    
    56     auto& descriptors = page->userContentProvider().userMessageHandlerDescriptors();
    57    
    58     RefPtr<UserMessageHandlerDescriptor> descriptor = descriptors.get(std::make_pair(name, &world));
    59     if (!descriptor)
    60         return nullptr;
    6176
    62     for (auto& handler : m_messageHandlers) {
    63         if (&handler->descriptor() == descriptor.get())
    64             return &handler.get();
    65     }
     77    UserMessageHandler* handler = m_messageHandlers.get(std::pair<AtomicString, RefPtr<DOMWrapperWorld>>(name, &world));
     78    if (handler)
     79        return handler;
    6680
    67     auto liveHandlers = descriptors.values();
    68     m_messageHandlers.removeAllMatching([liveHandlers](const Ref<UserMessageHandler>& handler) {
    69         for (const auto& liveHandler : liveHandlers) {
    70             if (liveHandler.get() == &handler->descriptor())
    71                 return true;
    72         }
    73         return false;
     81    page->userContentProvider().forEachUserMessageHandler([&](const UserMessageHandlerDescriptor& descriptor) {
     82        if (descriptor.name() != name || &descriptor.world() != &world)
     83            return;
     84       
     85        ASSERT(!handler);
     86
     87        auto addResult = m_messageHandlers.add(std::make_pair(descriptor.name(), const_cast<DOMWrapperWorld*>(&descriptor.world())), UserMessageHandler::create(*frame, const_cast<UserMessageHandlerDescriptor&>(descriptor)));
     88        handler = addResult.iterator->value.get();
    7489    });
    7590
    76     m_messageHandlers.append(UserMessageHandler::create(*frame(), *descriptor));
    77     return &m_messageHandlers.last().get();
     91    return handler;
    7892}
    7993
  • trunk/Source/WebCore/page/UserMessageHandlersNamespace.h

    r184066 r199020  
    3030
    3131#include "FrameDestructionObserver.h"
     32#include "UserContentProvider.h"
    3233#include "UserMessageHandler.h"
     34#include <wtf/HashMap.h>
    3335#include <wtf/RefCounted.h>
    3436#include <wtf/RefPtr.h>
    35 #include <wtf/Vector.h>
    3637#include <wtf/text/AtomicString.h>
     38#include <wtf/text/AtomicStringHash.h>
    3739
    3840namespace WebCore {
     
    4244class DOMWrapperWorld;
    4345
    44 class UserMessageHandlersNamespace : public RefCounted<UserMessageHandlersNamespace>, public FrameDestructionObserver {
     46class UserMessageHandlersNamespace : public RefCounted<UserMessageHandlersNamespace>, public FrameDestructionObserver, public UserContentProviderInvalidationClient {
    4547public:
    46     static Ref<UserMessageHandlersNamespace> create(Frame& frame)
     48    static Ref<UserMessageHandlersNamespace> create(Frame& frame, UserContentProvider& userContentProvider)
    4749    {
    48         return adoptRef(*new UserMessageHandlersNamespace(frame));
     50        return adoptRef(*new UserMessageHandlersNamespace(frame, userContentProvider));
    4951    }
    5052
     
    5456
    5557private:
    56     explicit UserMessageHandlersNamespace(Frame&);
     58    explicit UserMessageHandlersNamespace(Frame&, UserContentProvider&);
    5759
    58     Vector<Ref<UserMessageHandler>> m_messageHandlers;
     60    // UserContentProviderInvalidationClient
     61    void didInvalidate(UserContentProvider&) override;
     62
     63    Ref<UserContentProvider> m_userContentProvider;
     64    HashMap<std::pair<AtomicString, RefPtr<DOMWrapperWorld>>, RefPtr<UserMessageHandler>> m_messageHandlers;
    5965};
    6066
  • trunk/Source/WebCore/page/WebKitNamespace.cpp

    r169023 r199020  
    3434namespace WebCore {
    3535
    36 WebKitNamespace::WebKitNamespace(Frame& frame)
     36WebKitNamespace::WebKitNamespace(Frame& frame, UserContentProvider& userContentProvider)
    3737    : DOMWindowProperty(&frame)
    38     , m_messageHandlerNamespace(UserMessageHandlersNamespace::create(frame))
     38    , m_messageHandlerNamespace(UserMessageHandlersNamespace::create(frame, userContentProvider))
    3939{
    4040}
  • trunk/Source/WebCore/page/WebKitNamespace.h

    r184066 r199020  
    3636
    3737class Frame;
     38class UserContentProvider;
    3839class UserMessageHandlersNamespace;
    3940
    4041class WebKitNamespace : public DOMWindowProperty, public RefCounted<WebKitNamespace> {
    4142public:
    42     static Ref<WebKitNamespace> create(Frame& frame)
     43    static Ref<WebKitNamespace> create(Frame& frame, UserContentProvider& userContentProvider)
    4344    {
    44         return adoptRef(*new WebKitNamespace(frame));
     45        return adoptRef(*new WebKitNamespace(frame, userContentProvider));
    4546    }
    4647
     
    5051
    5152private:
    52     explicit WebKitNamespace(Frame&);
     53    explicit WebKitNamespace(Frame&, UserContentProvider&);
    5354
    5455    Ref<UserMessageHandlersNamespace> m_messageHandlerNamespace;
  • trunk/Source/WebKit2/ChangeLog

    r199011 r199020  
     12016-04-03  Sam Weinig  <sam@webkit.org>
     2
     3        Add SPI to allow install script message handlers in isolated worlds
     4        https://bugs.webkit.org/show_bug.cgi?id=156153
     5
     6        Reviewed by Anders Carlsson.
     7
     8        * Scripts/webkit/messages.py:
     9        (headers_for_type):
     10        * Shared/WebUserContentControllerDataTypes.cpp:
     11        (WebKit::WebScriptMessageHandlerData::encode):
     12        (WebKit::WebScriptMessageHandlerData::decode):
     13        * Shared/WebUserContentControllerDataTypes.h:
     14        Add WebKit::WebScriptMessageHandlerData, matching WebKit::WebUserScriptData and
     15        WebKit::WebUserStyleSheetData.
     16
     17        * UIProcess/API/Cocoa/WKUserContentController.mm:
     18        (-[WKUserContentController addScriptMessageHandler:name:]):
     19        (-[WKUserContentController removeScriptMessageHandlerForName:]):
     20        (-[WKUserContentController _removeAllUserStyleSheetsAssociatedWithUserContentWorld:]):
     21        (-[WKUserContentController _addScriptMessageHandler:name:userContentWorld:]):
     22        (-[WKUserContentController _removeScriptMessageHandlerForName:userContentWorld:]):
     23        (-[WKUserContentController _removeAllScriptMessageHandlersAssociatedWithUserContentWorld:]):
     24        * UIProcess/API/Cocoa/WKUserContentControllerPrivate.h:
     25        Add SPI for adding and removing ScriptMessageHandlers associated with a world.
     26
     27        * UIProcess/UserContent/WebScriptMessageHandler.cpp:
     28        (WebKit::WebScriptMessageHandler::create):
     29        (WebKit::WebScriptMessageHandler::WebScriptMessageHandler):
     30        (WebKit::WebScriptMessageHandlerHandle::encode): Deleted.
     31        (WebKit::WebScriptMessageHandlerHandle::decode): Deleted.
     32        * UIProcess/UserContent/WebScriptMessageHandler.h:
     33        (WebKit::WebScriptMessageHandler::identifier):
     34        (WebKit::WebScriptMessageHandler::name):
     35        (WebKit::WebScriptMessageHandler::userContentWorld):
     36        (WebKit::WebScriptMessageHandler::client):
     37        (WebKit::WebScriptMessageHandler::handle): Deleted.
     38        Add the world and move the data object to WebUserContentControllerDataTypes.h
     39
     40        * UIProcess/UserContent/WebUserContentControllerProxy.cpp:
     41        (WebKit::WebUserContentControllerProxy::addProcess):
     42        (WebKit::WebUserContentControllerProxy::addUserScriptMessageHandler):
     43        (WebKit::WebUserContentControllerProxy::removeUserMessageHandlerForName):
     44        (WebKit::WebUserContentControllerProxy::removeAllUserMessageHandlers):
     45        * UIProcess/UserContent/WebUserContentControllerProxy.h:
     46        Update for worlds, matching UserScript/UserStyleSheet model.
     47
     48        * WebProcess/UserContent/WebUserContentController.h:
     49        * WebProcess/UserContent/WebUserContentController.cpp:
     50        (WebKit::WebUserMessageHandlerDescriptorProxy::WebUserMessageHandlerDescriptorProxy):
     51        Change to inherit directly from WebCore::UserMessageHandlerDescriptor.
     52
     53        (WebKit::WebUserContentController::addUserScriptMessageHandlers):
     54        (WebKit::WebUserContentController::removeUserScriptMessageHandler):
     55        (WebKit::WebUserContentController::removeAllUserScriptMessageHandlers):
     56        (WebKit::WebUserContentController::addUserScriptMessageHandlerInternal):
     57        (WebKit::WebUserContentController::removeUserScriptMessageHandlerInternal):
     58        Add support for worlds, matching UserScript/UserStyleSheet model.
     59
     60        (WebKit::WebUserContentController::addUserStyleSheets):
     61        Add missing call to invalidateInjectedStyleSheetCacheInAllFramesInAllPages()
     62
     63        (WebKit::WebUserContentController::removeAllUserStyleSheets):
     64        Switch to only calling invalidateInjectedStyleSheetCacheInAllFramesInAllPages() once
     65        after the loop and only if any stylesheets were removed.
     66       
     67        (WebKit::WebUserContentController::addUserStyleSheetInternal):
     68        Remove call to invalidateInjectedStyleSheetCacheInAllFramesInAllPages(), make
     69        callers call it. This allows us to avoid calling it repeatedly in removeAllUserStyleSheets().
     70
     71        (WebKit::WebUserContentController::addUserStyleSheet):
     72        Call invalidateInjectedStyleSheetCacheInAllFramesInAllPages() explicitly since it
     73        is no longer called in addUserStyleSheetInternal().
     74
     75        (WebKit::WebUserContentController::forEachUserMessageHandler):
     76        Implement by iterating the m_userMessageHandlers map.
     77
     78        * WebProcess/UserContent/WebUserContentController.messages.in:
     79        Update for worlds, matching UserScript/UserStyleSheet model.
     80
    1812016-04-04  Joonghun Park  <jh718.park@samsung.com>
    282
  • trunk/Source/WebKit2/Scripts/webkit/messages.py

    r198180 r199020  
    378378        'WebKit::WebTouchEvent': ['"WebEvent.h"'],
    379379        'WebKit::WebWheelEvent': ['"WebEvent.h"'],
    380         'WebKit::WebScriptMessageHandlerHandle': ['"WebScriptMessageHandler.h"'],
    381380        'struct WebKit::WebUserScriptData': ['"WebUserContentControllerDataTypes.h"'],
    382381        'struct WebKit::WebUserStyleSheetData': ['"WebUserContentControllerDataTypes.h"'],
     382        'struct WebKit::WebScriptMessageHandlerData': ['"WebUserContentControllerDataTypes.h"'],
    383383        'std::chrono::system_clock::time_point': ['<chrono>'],
    384384    }
  • trunk/Source/WebKit2/Shared/WebUserContentControllerDataTypes.cpp

    r198180 r199020  
    6767}
    6868
     69
     70void WebScriptMessageHandlerData::encode(IPC::ArgumentEncoder& encoder) const
     71{
     72    encoder << identifier;
     73    encoder << worldIdentifier;
     74    encoder << name;
     75}
     76
     77bool WebScriptMessageHandlerData::decode(IPC::ArgumentDecoder& decoder, WebScriptMessageHandlerData& data)
     78{
     79    if (!decoder.decode(data.identifier))
     80        return false;
     81    if (!decoder.decode(data.worldIdentifier))
     82        return false;
     83    if (!decoder.decode(data.name))
     84        return false;
     85
     86    return true;
     87}
     88
    6989} // namespace WebKit
  • trunk/Source/WebKit2/Shared/WebUserContentControllerDataTypes.h

    r198180 r199020  
    5555};
    5656
     57struct WebScriptMessageHandlerData {
     58    void encode(IPC::ArgumentEncoder&) const;
     59    static bool decode(IPC::ArgumentDecoder&, WebScriptMessageHandlerData&);
     60
     61    uint64_t identifier;
     62    uint64_t worldIdentifier;
     63    String name;
     64};
     65
    5766} // namespace WebKit
    5867
  • trunk/Source/WebKit2/UIProcess/API/Cocoa/WKUserContentController.mm

    r197302 r199020  
    3030
    3131#import "APISerializedScriptValue.h"
     32#import "APIUserContentWorld.h"
    3233#import "WKFrameInfoInternal.h"
    3334#import "WKNSArray.h"
     
    119120- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name
    120121{
    121     RefPtr<WebKit::WebScriptMessageHandler> handler = WebKit::WebScriptMessageHandler::create(std::make_unique<ScriptMessageHandlerDelegate>(self, scriptMessageHandler, name), name);
     122    auto handler = WebKit::WebScriptMessageHandler::create(std::make_unique<ScriptMessageHandlerDelegate>(self, scriptMessageHandler, name), name, API::UserContentWorld::normalWorld());
    122123    if (!_userContentControllerProxy->addUserScriptMessageHandler(handler.get()))
    123124        [NSException raise:NSInvalidArgumentException format:@"Attempt to add script message handler with name '%@' when one already exists.", name];
     
    126127- (void)removeScriptMessageHandlerForName:(NSString *)name
    127128{
    128     _userContentControllerProxy->removeUserMessageHandlerForName(name);
     129    _userContentControllerProxy->removeUserMessageHandlerForName(name, API::UserContentWorld::normalWorld());
    129130}
    130131
     
    196197}
    197198
     199- (void)_addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name userContentWorld:(_WKUserContentWorld *)userContentWorld
     200{
     201    auto handler = WebKit::WebScriptMessageHandler::create(std::make_unique<ScriptMessageHandlerDelegate>(self, scriptMessageHandler, name), name, *userContentWorld->_userContentWorld);
     202    if (!_userContentControllerProxy->addUserScriptMessageHandler(handler.get()))
     203        [NSException raise:NSInvalidArgumentException format:@"Attempt to add script message handler with name '%@' when one already exists.", name];
     204}
     205
     206- (void)_removeScriptMessageHandlerForName:(NSString *)name userContentWorld:(_WKUserContentWorld *)userContentWorld
     207{
     208    _userContentControllerProxy->removeUserMessageHandlerForName(name, *userContentWorld->_userContentWorld);
     209}
     210
     211- (void)_removeAllScriptMessageHandlersAssociatedWithUserContentWorld:(_WKUserContentWorld *)userContentWorld
     212{
     213    _userContentControllerProxy->removeAllUserMessageHandlers(*userContentWorld->_userContentWorld);
     214}
     215
    198216@end
    199217
  • trunk/Source/WebKit2/UIProcess/API/Cocoa/WKUserContentControllerPrivate.h

    r197302 r199020  
    4848- (void)_removeAllUserStyleSheetsAssociatedWithUserContentWorld:(_WKUserContentWorld *)userContentWorld WK_AVAILABLE(WK_MAC_TBA, WK_IOS_TBA);
    4949
     50- (void)_addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name userContentWorld:(_WKUserContentWorld *)userContentWorld;
     51- (void)_removeScriptMessageHandlerForName:(NSString *)name userContentWorld:(_WKUserContentWorld *)userContentWorld;
     52- (void)_removeAllScriptMessageHandlersAssociatedWithUserContentWorld:(_WKUserContentWorld *)userContentWorld;
     53
    5054@end
    5155
  • trunk/Source/WebKit2/UIProcess/UserContent/WebScriptMessageHandler.cpp

    r194496 r199020  
    2727#include "WebScriptMessageHandler.h"
    2828
    29 #include "ArgumentCoders.h"
     29#include "APIUserContentWorld.h"
    3030
    3131namespace WebKit {
    32 
    33 void WebScriptMessageHandlerHandle::encode(IPC::ArgumentEncoder& encoder) const
    34 {
    35     encoder << identifier;
    36     encoder << name;
    37 }
    38 
    39 bool WebScriptMessageHandlerHandle::decode(IPC::ArgumentDecoder& decoder, WebScriptMessageHandlerHandle& handle)
    40 {
    41     if (!decoder.decode(handle.identifier))
    42         return false;
    43 
    44     if (!decoder.decode(handle.name))
    45         return false;
    46 
    47     return true;
    48 }
    4932
    5033static uint64_t generateIdentifier()
     
    5538}
    5639
    57 PassRefPtr<WebScriptMessageHandler> WebScriptMessageHandler::create(std::unique_ptr<Client> client, const String& name)
     40Ref<WebScriptMessageHandler> WebScriptMessageHandler::create(std::unique_ptr<Client> client, const String& name, API::UserContentWorld& world)
    5841{
    59     return adoptRef(new WebScriptMessageHandler(WTFMove(client), name));
     42    return adoptRef(*new WebScriptMessageHandler(WTFMove(client), name, world));
    6043}
    6144
    62 WebScriptMessageHandler::WebScriptMessageHandler(std::unique_ptr<Client> client, const String& name)
     45WebScriptMessageHandler::WebScriptMessageHandler(std::unique_ptr<Client> client, const String& name, API::UserContentWorld& world)
    6346    : m_identifier(generateIdentifier())
    6447    , m_client(WTFMove(client))
    6548    , m_name(name)
     49    , m_world(world)
    6650{
    6751}
  • trunk/Source/WebKit2/UIProcess/UserContent/WebScriptMessageHandler.h

    r189313 r199020  
    2727#define WebScriptMessageHandler_h
    2828
    29 #include <wtf/PassRefPtr.h>
     29#include "WebUserContentControllerDataTypes.h"
     30#include <wtf/Ref.h>
    3031#include <wtf/RefCounted.h>
    3132#include <wtf/text/WTFString.h>
    32 
    33 namespace IPC {
    34 class ArgumentDecoder;
    35 class ArgumentEncoder;
    36 }
    3733
    3834namespace WebCore {
     
    4137}
    4238
     39namespace API {
     40class UserContentWorld;
     41}
     42
    4343namespace WebKit {
    4444
    4545class WebPageProxy;
    4646class WebFrameProxy;
    47 
    48 struct WebScriptMessageHandlerHandle {
    49     void encode(IPC::ArgumentEncoder&) const;
    50     static bool decode(IPC::ArgumentDecoder&, WebScriptMessageHandlerHandle&);
    51 
    52     uint64_t identifier;
    53     String name;
    54 };
    5547
    5648class WebScriptMessageHandler : public RefCounted<WebScriptMessageHandler> {
     
    6254    };
    6355
    64     static PassRefPtr<WebScriptMessageHandler> create(std::unique_ptr<Client>, const String& name);   
     56    static Ref<WebScriptMessageHandler> create(std::unique_ptr<Client>, const String& name, API::UserContentWorld&);
    6557    virtual ~WebScriptMessageHandler();
    66 
    67     WebScriptMessageHandlerHandle handle() { return { m_identifier, m_name }; }
    6858
    6959    uint64_t identifier() const { return m_identifier; }
    7060    String name() const { return m_name; }
    7161
     62    const API::UserContentWorld& userContentWorld() const { return m_world; }
     63    API::UserContentWorld& userContentWorld() { return m_world; }
     64
    7265    Client& client() const { return *m_client; }
    7366
    7467private:
    75     WebScriptMessageHandler(std::unique_ptr<Client>, const String&);
     68    WebScriptMessageHandler(std::unique_ptr<Client>, const String&, API::UserContentWorld&);
    7669   
    7770    uint64_t m_identifier;
     
    7972    std::unique_ptr<Client> m_client;
    8073    String m_name;
     74    Ref<API::UserContentWorld> m_world;
    8175};
    8276
  • trunk/Source/WebKit2/UIProcess/UserContent/WebUserContentControllerProxy.cpp

    r198180 r199020  
    9292    webProcessProxy.connection()->send(Messages::WebUserContentController::AddUserStyleSheets(userStyleSheets), m_identifier);
    9393
    94     Vector<WebScriptMessageHandlerHandle> messageHandlerHandles;
     94    Vector<WebScriptMessageHandlerData> messageHandlers;
    9595    for (auto& handler : m_scriptMessageHandlers.values())
    96         messageHandlerHandles.append(handler->handle());
    97     webProcessProxy.connection()->send(Messages::WebUserContentController::AddUserScriptMessageHandlers(messageHandlerHandles), m_identifier);
     96        messageHandlers.append({ handler->identifier(), handler->userContentWorld().identifier(), handler->name() });
     97    webProcessProxy.connection()->send(Messages::WebUserContentController::AddUserScriptMessageHandlers(messageHandlers), m_identifier);
    9898
    9999#if ENABLE(CONTENT_EXTENSIONS)
     
    271271}
    272272
    273 bool WebUserContentControllerProxy::addUserScriptMessageHandler(WebScriptMessageHandler* handler)
    274 {
     273bool WebUserContentControllerProxy::addUserScriptMessageHandler(WebScriptMessageHandler& handler)
     274{
     275    Ref<API::UserContentWorld> world = handler.userContentWorld();
     276
    275277    for (auto& existingHandler : m_scriptMessageHandlers.values()) {
    276         if (existingHandler->name() == handler->name())
     278        if (existingHandler->name() == handler.name() && &existingHandler->userContentWorld() == world.ptr())
    277279            return false;
    278280    }
    279281
    280     m_scriptMessageHandlers.add(handler->identifier(), handler);
    281 
    282     for (WebProcessProxy* process : m_processes)
    283         process->connection()->send(Messages::WebUserContentController::AddUserScriptMessageHandlers({ handler->handle() }), m_identifier);
     282    addUserContentWorldUse(world.get());
     283
     284    m_scriptMessageHandlers.add(handler.identifier(), &handler);
     285
     286    for (WebProcessProxy* process : m_processes)
     287        process->connection()->send(Messages::WebUserContentController::AddUserScriptMessageHandlers({ { handler.identifier(), world->identifier(), handler.name() } }), m_identifier);
    284288   
    285289    return true;
    286290}
    287291
    288 void WebUserContentControllerProxy::removeUserMessageHandlerForName(const String& name)
     292void WebUserContentControllerProxy::removeUserMessageHandlerForName(const String& name, API::UserContentWorld& world)
    289293{
    290294    for (auto it = m_scriptMessageHandlers.begin(), end = m_scriptMessageHandlers.end(); it != end; ++it) {
    291         if (it->value->name() == name) {
     295        if (it->value->name() == name && &it->value->userContentWorld() == &world) {
    292296            for (WebProcessProxy* process : m_processes)
    293                 process->connection()->send(Messages::WebUserContentController::RemoveUserScriptMessageHandler(it->value->identifier()), m_identifier);
     297                process->connection()->send(Messages::WebUserContentController::RemoveUserScriptMessageHandler(world.identifier(), it->value->identifier()), m_identifier);
     298
    294299            m_scriptMessageHandlers.remove(it);
     300
     301            removeUserContentWorldUses(world, 1);
    295302            return;
    296303        }
    297304    }
     305}
     306
     307void WebUserContentControllerProxy::removeAllUserMessageHandlers(API::UserContentWorld& world)
     308{
     309    for (WebProcessProxy* process : m_processes)
     310        process->connection()->send(Messages::WebUserContentController::RemoveAllUserScriptMessageHandlers({ world.identifier() }), m_identifier);
     311
     312    unsigned numberRemoved = 0;
     313    m_scriptMessageHandlers.removeIf([&](HashMap<uint64_t, RefPtr<WebScriptMessageHandler>>::KeyValuePairType& entry) {
     314        if (&entry.value->userContentWorld() == &world) {
     315            ++numberRemoved;
     316            return true;
     317        }
     318        return false;
     319    });
     320
     321    removeUserContentWorldUses(world, numberRemoved);
    298322}
    299323
     
    316340        return;
    317341
    318     handler->client().didPostMessage(*page, *frame, securityOrigin,
    319         WebCore::SerializedScriptValue::adopt(dataReference.vector()));
     342    handler->client().didPostMessage(*page, *frame, securityOrigin, WebCore::SerializedScriptValue::adopt(dataReference.vector()));
    320343}
    321344
  • trunk/Source/WebKit2/UIProcess/UserContent/WebUserContentControllerProxy.h

    r197563 r199020  
    8989
    9090    // Returns false if there was a name conflict.
    91     bool addUserScriptMessageHandler(WebScriptMessageHandler*);
    92     void removeUserMessageHandlerForName(const String&);
     91    bool addUserScriptMessageHandler(WebScriptMessageHandler&);
     92    void removeUserMessageHandlerForName(const String&, API::UserContentWorld&);
     93    void removeAllUserMessageHandlers(API::UserContentWorld&);
    9394
    9495#if ENABLE(CONTENT_EXTENSIONS)
  • trunk/Source/WebKit2/WebProcess/UserContent/WebUserContentController.cpp

    r198180 r199020  
    172172        addUserStyleSheetInternal(*it->value.first, userStyleSheetData.identifier, WTFMove(sheet));
    173173    }
     174
     175    invalidateInjectedStyleSheetCacheInAllFramesInAllPages();
    174176}
    175177
     
    187189void WebUserContentController::removeAllUserStyleSheets(const Vector<uint64_t>& worldIdentifiers)
    188190{
     191    bool sheetsChanged = false;
    189192    for (auto& worldIdentifier : worldIdentifiers) {
    190193        auto it = worldMap().find(worldIdentifier);
     
    194197        }
    195198
    196         removeUserStyleSheets(*it->value.first);
    197     }
    198 }
    199 
    200 #if ENABLE(USER_MESSAGE_HANDLERS)
    201 class WebUserMessageHandlerDescriptorProxy : public RefCounted<WebUserMessageHandlerDescriptorProxy>, public WebCore::UserMessageHandlerDescriptor::Client {
     199        if (m_userStyleSheets.remove(it->value.first.get()))
     200            sheetsChanged = true;
     201    }
     202
     203    if (sheetsChanged)
     204        invalidateInjectedStyleSheetCacheInAllFramesInAllPages();
     205}
     206
     207#if ENABLE(USER_MESSAGE_HANDLERS)
     208class WebUserMessageHandlerDescriptorProxy : public WebCore::UserMessageHandlerDescriptor {
    202209public:
    203     static PassRefPtr<WebUserMessageHandlerDescriptorProxy> create(WebUserContentController* controller, const String& name, uint64_t identifier)
     210    static PassRefPtr<WebUserMessageHandlerDescriptorProxy> create(WebUserContentController* controller, const String& name, InjectedBundleScriptWorld& world, uint64_t identifier)
    204211    {
    205         return adoptRef(new WebUserMessageHandlerDescriptorProxy(controller, name, identifier));
     212        return adoptRef(new WebUserMessageHandlerDescriptorProxy(controller, name, world, identifier));
    206213    }
    207214
    208215    virtual ~WebUserMessageHandlerDescriptorProxy()
    209216    {
    210         m_descriptor->invalidateClient();
    211     }
    212 
    213     // WebCore::UserMessageHandlerDescriptor::Client
    214     virtual void didPostMessage(WebCore::UserMessageHandler& handler, WebCore::SerializedScriptValue* value)
     217    }
     218
     219    uint64_t identifier() { return m_identifier; }
     220
     221private:
     222    WebUserMessageHandlerDescriptorProxy(WebUserContentController* controller, const String& name, InjectedBundleScriptWorld& world, uint64_t identifier)
     223        : WebCore::UserMessageHandlerDescriptor(name, world.coreWorld())
     224        , m_controller(controller)
     225        , m_identifier(identifier)
     226    {
     227    }
     228
     229    // WebCore::UserMessageHandlerDescriptor
     230    void didPostMessage(WebCore::UserMessageHandler& handler, WebCore::SerializedScriptValue* value) override
    215231    {
    216232        WebCore::Frame* frame = handler.frame();
     
    229245    }
    230246
    231     WebCore::UserMessageHandlerDescriptor& descriptor() { return *m_descriptor; }
    232     uint64_t identifier() { return m_identifier; }
    233 
    234 private:
    235     WebUserMessageHandlerDescriptorProxy(WebUserContentController* controller, const String& name, uint64_t identifier)
    236         : m_controller(controller)
    237         , m_descriptor(UserMessageHandlerDescriptor::create(name, mainThreadNormalWorld(), *this))
    238         , m_identifier(identifier)
    239     {
    240     }
    241 
    242247    RefPtr<WebUserContentController> m_controller;
    243     RefPtr<WebCore::UserMessageHandlerDescriptor> m_descriptor;
    244248    uint64_t m_identifier;
    245249};
    246250#endif
    247251
    248 void WebUserContentController::addUserScriptMessageHandlers(const Vector<WebScriptMessageHandlerHandle>& scriptMessageHandlers)
    249 {
    250 #if ENABLE(USER_MESSAGE_HANDLERS)
    251     for (auto& handle : scriptMessageHandlers) {
    252         RefPtr<WebUserMessageHandlerDescriptorProxy> descriptor = WebUserMessageHandlerDescriptorProxy::create(this, handle.name, handle.identifier);
    253 
    254         m_userMessageHandlerDescriptors.add(descriptor->identifier(), descriptor);
    255 
    256         auto& coreDescriptor = descriptor->descriptor();
    257         m_userMessageHandlerDescriptorsMap.add(std::make_pair(coreDescriptor.name(), &coreDescriptor.world()), &coreDescriptor);
     252void WebUserContentController::addUserScriptMessageHandlers(const Vector<WebScriptMessageHandlerData>& scriptMessageHandlers)
     253{
     254#if ENABLE(USER_MESSAGE_HANDLERS)
     255    for (auto& handler : scriptMessageHandlers) {
     256        auto it = worldMap().find(handler.worldIdentifier);
     257        if (it == worldMap().end()) {
     258            WTFLogAlways("Trying to add a UserScriptMessageHandler to a UserContentWorld (id=%" PRIu64 ") that does not exist.", handler.worldIdentifier);
     259            continue;
     260        }
     261
     262        addUserScriptMessageHandlerInternal(*it->value.first, handler.identifier, handler.name);
    258263    }
    259264#else
     
    262267}
    263268
    264 void WebUserContentController::removeUserScriptMessageHandler(uint64_t identifier)
    265 {
    266 #if ENABLE(USER_MESSAGE_HANDLERS)
    267     auto it = m_userMessageHandlerDescriptors.find(identifier);
    268     ASSERT(it != m_userMessageHandlerDescriptors.end());
    269 
    270     auto& coreDescriptor = it->value->descriptor();
    271     m_userMessageHandlerDescriptorsMap.remove(std::make_pair(coreDescriptor.name(), &coreDescriptor.world()));
    272 
    273     m_userMessageHandlerDescriptors.remove(it);
     269void WebUserContentController::removeUserScriptMessageHandler(uint64_t worldIdentifier, uint64_t userScriptMessageHandlerIdentifier)
     270{
     271#if ENABLE(USER_MESSAGE_HANDLERS)
     272    auto it = worldMap().find(worldIdentifier);
     273    if (it == worldMap().end()) {
     274        WTFLogAlways("Trying to remove a UserScriptMessageHandler from a UserContentWorld (id=%" PRIu64 ") that does not exist.", worldIdentifier);
     275        return;
     276    }
     277
     278    removeUserScriptMessageHandlerInternal(*it->value.first, userScriptMessageHandlerIdentifier);
    274279#else
    275     UNUSED_PARAM(identifier);
    276 #endif
    277 }
     280    UNUSED_PARAM(worldIdentifier);
     281    UNUSED_PARAM(userScriptMessageHandlerIdentifier);
     282#endif
     283}
     284
     285void WebUserContentController::removeAllUserScriptMessageHandlers(const Vector<uint64_t>& worldIdentifiers)
     286{
     287#if ENABLE(USER_MESSAGE_HANDLERS)
     288    bool userMessageHandlersChanged = false;
     289    for (auto& worldIdentifier : worldIdentifiers) {
     290        auto it = worldMap().find(worldIdentifier);
     291        if (it == worldMap().end()) {
     292            WTFLogAlways("Trying to remove all UserScriptMessageHandler from a UserContentWorld (id=%" PRIu64 ") that does not exist.", worldIdentifier);
     293            return;
     294        }
     295
     296        if (m_userMessageHandlers.remove(it->value.first.get()))
     297            userMessageHandlersChanged = true;
     298    }
     299
     300    if (userMessageHandlersChanged)
     301        invalidateAllRegisteredUserMessageHandlerInvalidationClients();
     302#else
     303    UNUSED_PARAM(worldIdentifiers);
     304#endif
     305}
     306
     307#if ENABLE(USER_MESSAGE_HANDLERS)
     308void WebUserContentController::addUserScriptMessageHandlerInternal(InjectedBundleScriptWorld& world, uint64_t userScriptMessageHandlerIdentifier, const String& name)
     309{
     310    auto& messageHandlersInWorld = m_userMessageHandlers.ensure(&world, [] { return Vector<RefPtr<WebUserMessageHandlerDescriptorProxy>>(); }).iterator->value;
     311    messageHandlersInWorld.append(WebUserMessageHandlerDescriptorProxy::create(this, name, world, userScriptMessageHandlerIdentifier));
     312}
     313
     314void WebUserContentController::removeUserScriptMessageHandlerInternal(InjectedBundleScriptWorld& world, uint64_t userScriptMessageHandlerIdentifier)
     315{
     316    auto it = m_userMessageHandlers.find(&world);
     317    if (it == m_userMessageHandlers.end())
     318        return;
     319
     320    auto& userMessageHandlers = it->value;
     321
     322    bool userMessageHandlersChanged = false;
     323    for (int i = userMessageHandlers.size() - 1; i >= 0; --i) {
     324        if (userMessageHandlers[i]->identifier() == userScriptMessageHandlerIdentifier) {
     325            userMessageHandlers.remove(i);
     326            userMessageHandlersChanged = true;
     327        }
     328    }
     329
     330    if (!userMessageHandlersChanged)
     331        return;
     332
     333    if (userMessageHandlers.isEmpty())
     334        m_userMessageHandlers.remove(it);
     335
     336    invalidateAllRegisteredUserMessageHandlerInvalidationClients();
     337}
     338#endif
    278339
    279340#if ENABLE(CONTENT_EXTENSIONS)
     
    298359}
    299360#endif
    300 
    301 
    302361
    303362void WebUserContentController::addUserScriptInternal(InjectedBundleScriptWorld& world, uint64_t userScriptIdentifier, UserScript&& userScript)
     
    353412    auto& styleSheetsInWorld = m_userStyleSheets.ensure(&world, [] { return Vector<std::pair<uint64_t, WebCore::UserStyleSheet>>(); }).iterator->value;
    354413    styleSheetsInWorld.append(std::make_pair(userStyleSheetIdentifier, WTFMove(userStyleSheet)));
    355 
     414}
     415
     416void WebUserContentController::addUserStyleSheet(InjectedBundleScriptWorld& world, UserStyleSheet&& userStyleSheet)
     417{
     418    addUserStyleSheetInternal(world, 0, WTFMove(userStyleSheet));
    356419    invalidateInjectedStyleSheetCacheInAllFramesInAllPages();
    357 }
    358 
    359 void WebUserContentController::addUserStyleSheet(InjectedBundleScriptWorld& world, UserStyleSheet&& userStyleSheet)
    360 {
    361     addUserStyleSheetInternal(world, 0, WTFMove(userStyleSheet));
    362420}
    363421
     
    447505}
    448506
     507#if ENABLE(USER_MESSAGE_HANDLERS)
     508void WebUserContentController::forEachUserMessageHandler(const std::function<void(const WebCore::UserMessageHandlerDescriptor&)>& functor) const
     509{
     510    for (const auto& userMessageHandlerVector : m_userMessageHandlers.values()) {
     511        for (const auto& userMessageHandler : userMessageHandlerVector)
     512            functor(*userMessageHandler.get());
     513    }
     514}
     515#endif
     516
    449517} // namespace WebKit
  • trunk/Source/WebKit2/WebProcess/UserContent/WebUserContentController.h

    r198208 r199020  
    4747class InjectedBundleScriptWorld;
    4848class WebCompiledContentExtensionData;
    49 
    50 #if ENABLE(USER_MESSAGE_HANDLERS)
    5149class WebUserMessageHandlerDescriptorProxy;
    52 #endif
    5350
    5451class WebUserContentController final : public WebCore::UserContentProvider, private IPC::MessageReceiver {
     
    7471    void forEachUserStyleSheet(const std::function<void(const WebCore::UserStyleSheet&)>&) const override;
    7572#if ENABLE(USER_MESSAGE_HANDLERS)
    76     const WebCore::UserMessageHandlerDescriptorMap& userMessageHandlerDescriptors() const override { return m_userMessageHandlerDescriptorsMap; }
     73    void forEachUserMessageHandler(const std::function<void(const WebCore::UserMessageHandlerDescriptor&)>&) const override;
    7774#endif
    7875#if ENABLE(CONTENT_EXTENSIONS)
     
    9491    void removeAllUserStyleSheets(const Vector<uint64_t>&);
    9592
    96     void addUserScriptMessageHandlers(const Vector<WebScriptMessageHandlerHandle>&);
    97     void removeUserScriptMessageHandler(uint64_t);
     93    void addUserScriptMessageHandlers(const Vector<WebScriptMessageHandlerData>&);
     94    void removeUserScriptMessageHandler(uint64_t worldIdentifier, uint64_t userScriptIdentifier);
     95    void removeAllUserScriptMessageHandlers(const Vector<uint64_t>&);
    9896
    9997#if ENABLE(CONTENT_EXTENSIONS)
     
    103101#endif
    104102
    105 
    106103    void addUserScriptInternal(InjectedBundleScriptWorld&, uint64_t userScriptIdentifier, WebCore::UserScript&&);
    107104    void removeUserScriptInternal(InjectedBundleScriptWorld&, uint64_t userScriptIdentifier);
    108105    void addUserStyleSheetInternal(InjectedBundleScriptWorld&, uint64_t userStyleSheetIdentifier, WebCore::UserStyleSheet&&);
    109106    void removeUserStyleSheetInternal(InjectedBundleScriptWorld&, uint64_t userStyleSheetIdentifier);
    110 
     107#if ENABLE(USER_MESSAGE_HANDLERS)
     108    void addUserScriptMessageHandlerInternal(InjectedBundleScriptWorld&, uint64_t userScriptMessageHandlerIdentifier, const String& name);
     109    void removeUserScriptMessageHandlerInternal(InjectedBundleScriptWorld&, uint64_t userScriptMessageHandlerIdentifier);
     110#endif
    111111
    112112    uint64_t m_identifier;
     
    119119
    120120#if ENABLE(USER_MESSAGE_HANDLERS)
    121     HashMap<uint64_t, RefPtr<WebUserMessageHandlerDescriptorProxy>> m_userMessageHandlerDescriptors;
    122     WebCore::UserMessageHandlerDescriptorMap m_userMessageHandlerDescriptorsMap;
     121    typedef HashMap<RefPtr<InjectedBundleScriptWorld>, Vector<RefPtr<WebUserMessageHandlerDescriptorProxy>>> WorldToUserMessageHandlerVectorMap;
     122    WorldToUserMessageHandlerVectorMap m_userMessageHandlers;
    123123#endif
    124124#if ENABLE(CONTENT_EXTENSIONS)
  • trunk/Source/WebKit2/WebProcess/UserContent/WebUserContentController.messages.in

    r198180 r199020  
    3636    RemoveAllUserStyleSheets(Vector<uint64_t> worldIdentifiers);
    3737
    38     AddUserScriptMessageHandlers(Vector<WebKit::WebScriptMessageHandlerHandle> scriptMessageHandlers);
    39     RemoveUserScriptMessageHandler(uint64_t identifier);
     38    AddUserScriptMessageHandlers(Vector<struct WebKit::WebScriptMessageHandlerData> scriptMessageHandlers);
     39    RemoveUserScriptMessageHandler(uint64_t worldIdentifier, uint64_t identifier);
     40    RemoveAllUserScriptMessageHandlers(Vector<uint64_t> worldIdentifiers);
    4041
    4142#if ENABLE(CONTENT_EXTENSIONS)
  • trunk/Tools/ChangeLog

    r199018 r199020  
     12016-04-03  Sam Weinig  <sam@webkit.org>
     2
     3        Add SPI to allow install script message handlers in isolated worlds
     4        https://bugs.webkit.org/show_bug.cgi?id=156153
     5
     6        Reviewed by Anders Carlsson.
     7
     8        * TestWebKitAPI/Tests/WebKit2Cocoa/UserContentController.mm:
     9        Add new test, WKUserContentController.ScriptMessageHandlerBasicPostIsolatedWorld
     10
    1112016-04-04  Jiewen Tan  <jiewen_tan@apple.com>
    212
  • trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/UserContentController.mm

    r197868 r199020  
    9696}
    9797
     98TEST(WKUserContentController, ScriptMessageHandlerBasicPostIsolatedWorld)
     99{
     100    RetainPtr<_WKUserContentWorld> world = adoptNS([_WKUserContentWorld worldWithName:@"TestWorld"]);
     101
     102    RetainPtr<ScriptMessageHandler> handler = adoptNS([[ScriptMessageHandler alloc] init]);
     103    RetainPtr<WKUserScript> userScript = adoptNS([[WKUserScript alloc] _initWithSource:@"window.webkit.messageHandlers.testHandler.postMessage('Hello')" injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO legacyWhitelist:@[] legacyBlacklist:@[] userContentWorld:world.get()]);
     104
     105    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     106    [[configuration userContentController] _addScriptMessageHandler:handler.get() name:@"testHandler" userContentWorld:world.get()];
     107    [[configuration userContentController] addUserScript:userScript.get()];
     108
     109    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
     110
     111    RetainPtr<SimpleNavigationDelegate> delegate = adoptNS([[SimpleNavigationDelegate alloc] init]);
     112    [webView setNavigationDelegate:delegate.get()];
     113
     114    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
     115
     116    isDoneWithNavigation = false;
     117    [webView loadRequest:request];
     118
     119    TestWebKitAPI::Util::run(&receivedScriptMessage);
     120    receivedScriptMessage = false;
     121
     122    EXPECT_WK_STREQ(@"Hello", (NSString *)[lastScriptMessage body]);
     123
     124    if (!isDoneWithNavigation)
     125        TestWebKitAPI::Util::run(&isDoneWithNavigation);
     126
     127    __block bool isDoneEvaluatingScript = false;
     128    __block NSString *resultValue = @"";
     129    [webView evaluateJavaScript:
     130        @"var result;"
     131         "if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.testHandler) {"
     132         "    result = { 'result': 'FAIL' };"
     133         "} else {"
     134         "    result = { 'result': 'PASS' };"
     135         "} "
     136         "result;"
     137         completionHandler:^(id value, NSError *error) {
     138            resultValue = [((NSDictionary *)value)[@"result"] copy];
     139            isDoneEvaluatingScript = true;
     140        }];
     141
     142    TestWebKitAPI::Util::run(&isDoneEvaluatingScript);
     143
     144    EXPECT_WK_STREQ(@"PASS", resultValue);
     145}
     146
    98147TEST(WKUserContentController, ScriptMessageHandlerBasicRemove)
    99148{
Note: See TracChangeset for help on using the changeset viewer.