Diff
Modified: trunk/Source/WebCore/ChangeLog (199019 => 199020)
--- trunk/Source/WebCore/ChangeLog 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebCore/ChangeLog 2016-04-04 21:03:28 UTC (rev 199020)
@@ -1,3 +1,92 @@
+2016-04-03 Sam Weinig <[email protected]>
+
+ Add SPI to allow install script message handlers in isolated worlds
+ https://bugs.webkit.org/show_bug.cgi?id=156153
+
+ Reviewed by Anders Carlsson.
+
+ 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.
+
2016-04-04 Chris Dumez <[email protected]>
Regression(r196145): Crash in getOwnPropertyDescriptor on http://www.history.com/shows/vikings
Modified: trunk/Source/WebCore/loader/EmptyClients.cpp (199019 => 199020)
--- trunk/Source/WebCore/loader/EmptyClients.cpp 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebCore/loader/EmptyClients.cpp 2016-04-04 21:03:28 UTC (rev 199020)
@@ -101,7 +101,7 @@
void forEachUserScript(const std::function<void(DOMWrapperWorld&, const UserScript&)>&) const override { }
void forEachUserStyleSheet(const std::function<void(const UserStyleSheet&)>&) const override { }
#if ENABLE(USER_MESSAGE_HANDLERS)
- const UserMessageHandlerDescriptorMap& userMessageHandlerDescriptors() const override { static NeverDestroyed<UserMessageHandlerDescriptorMap> map; return map.get(); }
+ void forEachUserMessageHandler(const std::function<void(const UserMessageHandlerDescriptor&)>&) const override { }
#endif
#if ENABLE(CONTENT_EXTENSIONS)
ContentExtensions::ContentExtensionsBackend& userContentExtensionBackend() override { static NeverDestroyed<ContentExtensions::ContentExtensionsBackend> backend; return backend.get(); };
Modified: trunk/Source/WebCore/page/DOMWindow.cpp (199019 => 199020)
--- trunk/Source/WebCore/page/DOMWindow.cpp 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebCore/page/DOMWindow.cpp 2016-04-04 21:03:28 UTC (rev 199020)
@@ -761,20 +761,26 @@
if (!page)
return false;
- for (auto& descriptor : page->userContentProvider().userMessageHandlerDescriptors().values()) {
- if (&descriptor->world() == &world)
- return true;
- }
+ bool hasUserMessageHandler = false;
+ page->userContentProvider().forEachUserMessageHandler([&](const UserMessageHandlerDescriptor& descriptor) {
+ if (&descriptor.world() == &world) {
+ hasUserMessageHandler = true;
+ return;
+ }
+ });
- return false;
+ return hasUserMessageHandler;
}
WebKitNamespace* DOMWindow::webkitNamespace() const
{
if (!isCurrentlyDisplayedInFrame())
return nullptr;
+ auto* page = m_frame->page();
+ if (!page)
+ return nullptr;
if (!m_webkitNamespace)
- m_webkitNamespace = WebKitNamespace::create(*m_frame);
+ m_webkitNamespace = WebKitNamespace::create(*m_frame, page->userContentProvider());
return m_webkitNamespace.get();
}
#endif
Modified: trunk/Source/WebCore/page/UserContentController.cpp (199019 => 199020)
--- trunk/Source/WebCore/page/UserContentController.cpp 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebCore/page/UserContentController.cpp 2016-04-04 21:03:28 UTC (rev 199020)
@@ -32,10 +32,6 @@
#include <runtime/JSCellInlines.h>
#include <runtime/StructureInlines.h>
-#if ENABLE(USER_MESSAGE_HANDLERS)
-#include "UserMessageHandlerDescriptor.h"
-#endif
-
#if ENABLE(CONTENT_EXTENSIONS)
#include "CompiledContentExtension.h"
#endif
@@ -72,6 +68,12 @@
}
}
+#if ENABLE(USER_MESSAGE_HANDLERS)
+void UserContentController::forEachUserMessageHandler(const std::function<void(const UserMessageHandlerDescriptor&)>&) const
+{
+}
+#endif
+
void UserContentController::addUserScript(DOMWrapperWorld& world, std::unique_ptr<UserScript> userScript)
{
auto& scriptsInWorld = m_userScripts.ensure(&world, [&] { return std::make_unique<UserScriptVector>(); }).iterator->value;
@@ -141,35 +143,6 @@
invalidateInjectedStyleSheetCacheInAllFramesInAllPages();
}
-#if ENABLE(USER_MESSAGE_HANDLERS)
-void UserContentController::addUserMessageHandlerDescriptor(UserMessageHandlerDescriptor& descriptor)
-{
- m_userMessageHandlerDescriptors.add(std::make_pair(descriptor.name(), &descriptor.world()), &descriptor);
-}
-
-void UserContentController::removeUserMessageHandlerDescriptor(UserMessageHandlerDescriptor& descriptor)
-{
- m_userMessageHandlerDescriptors.remove(std::make_pair(descriptor.name(), &descriptor.world()));
-}
-#endif
-
-#if ENABLE(CONTENT_EXTENSIONS)
-void UserContentController::addUserContentExtension(const String& name, RefPtr<ContentExtensions::CompiledContentExtension> contentExtension)
-{
- m_contentExtensionBackend.addContentExtension(name, contentExtension);
-}
-
-void UserContentController::removeUserContentExtension(const String& name)
-{
- m_contentExtensionBackend.removeContentExtension(name);
-}
-
-void UserContentController::removeAllUserContentExtensions()
-{
- m_contentExtensionBackend.removeAllContentExtensions();
-}
-#endif
-
void UserContentController::removeAllUserContent()
{
m_userScripts.clear();
Modified: trunk/Source/WebCore/page/UserContentController.h (199019 => 199020)
--- trunk/Source/WebCore/page/UserContentController.h 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebCore/page/UserContentController.h 2016-04-04 21:03:28 UTC (rev 199020)
@@ -45,17 +45,6 @@
WEBCORE_EXPORT void removeAllUserContent();
-#if ENABLE(USER_MESSAGE_HANDLERS)
- WEBCORE_EXPORT void addUserMessageHandlerDescriptor(UserMessageHandlerDescriptor&);
- WEBCORE_EXPORT void removeUserMessageHandlerDescriptor(UserMessageHandlerDescriptor&);
-#endif
-
-#if ENABLE(CONTENT_EXTENSIONS)
- WEBCORE_EXPORT void addUserContentExtension(const String& name, RefPtr<ContentExtensions::CompiledContentExtension>);
- WEBCORE_EXPORT void removeUserContentExtension(const String& name);
- WEBCORE_EXPORT void removeAllUserContentExtensions();
-#endif
-
private:
UserContentController();
@@ -63,7 +52,7 @@
void forEachUserScript(const std::function<void(DOMWrapperWorld&, const UserScript&)>&) const override;
void forEachUserStyleSheet(const std::function<void(const UserStyleSheet&)>&) const override;
#if ENABLE(USER_MESSAGE_HANDLERS)
- const UserMessageHandlerDescriptorMap& userMessageHandlerDescriptors() const override { return m_userMessageHandlerDescriptors; }
+ void forEachUserMessageHandler(const std::function<void(const UserMessageHandlerDescriptor&)>&) const override;
#endif
#if ENABLE(CONTENT_EXTENSIONS)
ContentExtensions::ContentExtensionsBackend& userContentExtensionBackend() override { return m_contentExtensionBackend; }
@@ -71,9 +60,6 @@
UserScriptMap m_userScripts;
UserStyleSheetMap m_userStyleSheets;
-#if ENABLE(USER_MESSAGE_HANDLERS)
- UserMessageHandlerDescriptorMap m_userMessageHandlerDescriptors;
-#endif
#if ENABLE(CONTENT_EXTENSIONS)
ContentExtensions::ContentExtensionsBackend m_contentExtensionBackend;
#endif
Modified: trunk/Source/WebCore/page/UserContentProvider.cpp (199019 => 199020)
--- trunk/Source/WebCore/page/UserContentProvider.cpp 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebCore/page/UserContentProvider.cpp 2016-04-04 21:03:28 UTC (rev 199020)
@@ -61,6 +61,26 @@
m_pages.remove(&page);
}
+void UserContentProvider::registerForUserMessageHandlerInvalidation(UserContentProviderInvalidationClient& invalidationClient)
+{
+ ASSERT(!m_userMessageHandlerInvalidationClients.contains(&invalidationClient));
+
+ m_userMessageHandlerInvalidationClients.add(&invalidationClient);
+}
+
+void UserContentProvider::unregisterForUserMessageHandlerInvalidation(UserContentProviderInvalidationClient& invalidationClient)
+{
+ ASSERT(m_userMessageHandlerInvalidationClients.contains(&invalidationClient));
+
+ m_userMessageHandlerInvalidationClients.remove(&invalidationClient);
+}
+
+void UserContentProvider::invalidateAllRegisteredUserMessageHandlerInvalidationClients()
+{
+ for (auto& client : m_userMessageHandlerInvalidationClients)
+ client->didInvalidate(*this);
+}
+
void UserContentProvider::invalidateInjectedStyleSheetCacheInAllFramesInAllPages()
{
for (auto& page : m_pages)
Modified: trunk/Source/WebCore/page/UserContentProvider.h (199019 => 199020)
--- trunk/Source/WebCore/page/UserContentProvider.h 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebCore/page/UserContentProvider.h 2016-04-04 21:03:28 UTC (rev 199020)
@@ -58,6 +58,17 @@
struct Action;
}
+class UserContentProvider;
+
+class UserContentProviderInvalidationClient {
+public:
+ virtual ~UserContentProviderInvalidationClient()
+ {
+ }
+
+ virtual void didInvalidate(UserContentProvider&) = 0;
+};
+
class UserContentProvider : public RefCounted<UserContentProvider> {
public:
WEBCORE_EXPORT UserContentProvider();
@@ -65,19 +76,19 @@
virtual void forEachUserScript(const std::function<void(DOMWrapperWorld&, const UserScript&)>&) const = 0;
virtual void forEachUserStyleSheet(const std::function<void(const UserStyleSheet&)>&) const = 0;
-
#if ENABLE(USER_MESSAGE_HANDLERS)
- virtual const UserMessageHandlerDescriptorMap& userMessageHandlerDescriptors() const = 0;
+ virtual void forEachUserMessageHandler(const std::function<void(const UserMessageHandlerDescriptor&)>&) const = 0;
#endif
-
#if ENABLE(CONTENT_EXTENSIONS)
virtual ContentExtensions::ContentExtensionsBackend& userContentExtensionBackend() = 0;
#endif
+ void registerForUserMessageHandlerInvalidation(UserContentProviderInvalidationClient&);
+ void unregisterForUserMessageHandlerInvalidation(UserContentProviderInvalidationClient&);
+
void addPage(Page&);
void removePage(Page&);
-
#if ENABLE(CONTENT_EXTENSIONS)
// FIXME: These don't really belong here. They should probably bundled up in the ContentExtensionsBackend
// which should always exist.
@@ -86,10 +97,12 @@
#endif
protected:
+ WEBCORE_EXPORT void invalidateAllRegisteredUserMessageHandlerInvalidationClients();
WEBCORE_EXPORT void invalidateInjectedStyleSheetCacheInAllFramesInAllPages();
private:
HashSet<Page*> m_pages;
+ HashSet<UserContentProviderInvalidationClient*> m_userMessageHandlerInvalidationClients;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/page/UserMessageHandler.cpp (199019 => 199020)
--- trunk/Source/WebCore/page/UserMessageHandler.cpp 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebCore/page/UserMessageHandler.cpp 2016-04-04 21:03:28 UTC (rev 199020)
@@ -36,7 +36,7 @@
UserMessageHandler::UserMessageHandler(Frame& frame, UserMessageHandlerDescriptor& descriptor)
: FrameDestructionObserver(&frame)
- , m_descriptor(descriptor)
+ , m_descriptor(&descriptor)
{
}
@@ -48,24 +48,14 @@
{
// Check to see if the descriptor has been removed. This can happen if the host application has
// removed the named message handler at the WebKit2 API level.
- if (!m_descriptor->client()) {
+ if (!m_descriptor) {
ec = INVALID_ACCESS_ERR;
return;
}
- m_descriptor->client()->didPostMessage(*this, value.get());
+ m_descriptor->didPostMessage(*this, value.get());
}
-const AtomicString& UserMessageHandler::name()
-{
- return m_descriptor->name();
-}
-
-DOMWrapperWorld& UserMessageHandler::world()
-{
- return m_descriptor->world();
-}
-
} // namespace WebCore
#endif // ENABLE(USER_MESSAGE_HANDLERS)
Modified: trunk/Source/WebCore/page/UserMessageHandler.h (199019 => 199020)
--- trunk/Source/WebCore/page/UserMessageHandler.h 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebCore/page/UserMessageHandler.h 2016-04-04 21:03:28 UTC (rev 199020)
@@ -30,7 +30,6 @@
#include "FrameDestructionObserver.h"
#include "UserMessageHandlerDescriptor.h"
-#include <bindings/ScriptValue.h>
namespace WebCore {
@@ -46,14 +45,13 @@
void postMessage(PassRefPtr<SerializedScriptValue>, ExceptionCode&);
- const AtomicString& name();
- DOMWrapperWorld& world();
- const UserMessageHandlerDescriptor& descriptor() const { return m_descriptor.get(); }
+ UserMessageHandlerDescriptor* descriptor() { return m_descriptor.get(); }
+ void invalidateDescriptor() { m_descriptor = nullptr; }
private:
UserMessageHandler(Frame&, UserMessageHandlerDescriptor&);
- Ref<UserMessageHandlerDescriptor> m_descriptor;
+ RefPtr<UserMessageHandlerDescriptor> m_descriptor;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/page/UserMessageHandlerDescriptor.cpp (199019 => 199020)
--- trunk/Source/WebCore/page/UserMessageHandlerDescriptor.cpp 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebCore/page/UserMessageHandlerDescriptor.cpp 2016-04-04 21:03:28 UTC (rev 199020)
@@ -32,10 +32,9 @@
namespace WebCore {
-UserMessageHandlerDescriptor::UserMessageHandlerDescriptor(const AtomicString& name, DOMWrapperWorld& world, Client& client)
+UserMessageHandlerDescriptor::UserMessageHandlerDescriptor(const AtomicString& name, DOMWrapperWorld& world)
: m_name(name)
, m_world(world)
- , m_client(&client)
{
}
@@ -43,7 +42,7 @@
{
}
-const AtomicString& UserMessageHandlerDescriptor::name()
+const AtomicString& UserMessageHandlerDescriptor::name() const
{
return m_name;
}
@@ -53,6 +52,11 @@
return m_world.get();
}
+const DOMWrapperWorld& UserMessageHandlerDescriptor::world() const
+{
+ return m_world.get();
+}
+
} // namespace WebCore
#endif // ENABLE(USER_MESSAGE_HANDLERS)
Modified: trunk/Source/WebCore/page/UserMessageHandlerDescriptor.h (199019 => 199020)
--- trunk/Source/WebCore/page/UserMessageHandlerDescriptor.h 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebCore/page/UserMessageHandlerDescriptor.h 2016-04-04 21:03:28 UTC (rev 199020)
@@ -28,44 +28,30 @@
#if ENABLE(USER_MESSAGE_HANDLERS)
-#include <wtf/PassRefPtr.h>
+#include <wtf/Ref.h>
#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
#include <wtf/text/AtomicString.h>
namespace WebCore {
-class Frame;
class DOMWrapperWorld;
-class UserMessageHandler;
class SerializedScriptValue;
+class UserMessageHandler;
class UserMessageHandlerDescriptor : public RefCounted<UserMessageHandlerDescriptor> {
public:
- class Client {
- public:
- virtual ~Client() { }
- virtual void didPostMessage(UserMessageHandler&, SerializedScriptValue*) = 0;
- };
+ WEBCORE_EXPORT explicit UserMessageHandlerDescriptor(const AtomicString&, DOMWrapperWorld&);
+ WEBCORE_EXPORT virtual ~UserMessageHandlerDescriptor();
- static Ref<UserMessageHandlerDescriptor> create(const AtomicString& name, DOMWrapperWorld& world, Client& client)
- {
- return adoptRef(*new UserMessageHandlerDescriptor(name, world, client));
- }
- WEBCORE_EXPORT ~UserMessageHandlerDescriptor();
-
- WEBCORE_EXPORT const AtomicString& name();
+ WEBCORE_EXPORT const AtomicString& name() const;
WEBCORE_EXPORT DOMWrapperWorld& world();
+ WEBCORE_EXPORT const DOMWrapperWorld& world() const;
- Client* client() const { return m_client; }
- void invalidateClient() { m_client = nullptr; }
+ virtual void didPostMessage(UserMessageHandler&, SerializedScriptValue*) = 0;
private:
- WEBCORE_EXPORT explicit UserMessageHandlerDescriptor(const AtomicString&, DOMWrapperWorld&, Client&);
-
AtomicString m_name;
Ref<DOMWrapperWorld> m_world;
- Client* m_client;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/page/UserMessageHandlersNamespace.cpp (199019 => 199020)
--- trunk/Source/WebCore/page/UserMessageHandlersNamespace.cpp 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebCore/page/UserMessageHandlersNamespace.cpp 2016-04-04 21:03:28 UTC (rev 199020)
@@ -32,49 +32,63 @@
#include "Frame.h"
#include "Page.h"
#include "UserContentController.h"
+#include "UserMessageHandler.h"
namespace WebCore {
-UserMessageHandlersNamespace::UserMessageHandlersNamespace(Frame& frame)
+UserMessageHandlersNamespace::UserMessageHandlersNamespace(Frame& frame, UserContentProvider& userContentProvider)
: FrameDestructionObserver(&frame)
+ , m_userContentProvider(userContentProvider)
{
+ m_userContentProvider->registerForUserMessageHandlerInvalidation(*this);
}
UserMessageHandlersNamespace::~UserMessageHandlersNamespace()
{
+ m_userContentProvider->unregisterForUserMessageHandlerInvalidation(*this);
}
+void UserMessageHandlersNamespace::didInvalidate(UserContentProvider& provider)
+{
+ auto oldMap = WTFMove(m_messageHandlers);
+
+ provider.forEachUserMessageHandler([&](const UserMessageHandlerDescriptor& descriptor) {
+ auto userMessageHandler = oldMap.take(std::make_pair(descriptor.name(), const_cast<DOMWrapperWorld*>(&descriptor.world())));
+ if (userMessageHandler) {
+ m_messageHandlers.add(std::make_pair(descriptor.name(), const_cast<DOMWrapperWorld*>(&descriptor.world())), userMessageHandler);
+ return;
+ }
+ });
+
+ for (auto& userMessageHandler : oldMap.values())
+ userMessageHandler->invalidateDescriptor();
+}
+
UserMessageHandler* UserMessageHandlersNamespace::handler(const AtomicString& name, DOMWrapperWorld& world)
{
- if (!frame())
+ Frame* frame = this->frame();
+ if (!frame)
return nullptr;
- Page* page = frame()->page();
+ Page* page = frame->page();
if (!page)
return nullptr;
-
- auto& descriptors = page->userContentProvider().userMessageHandlerDescriptors();
-
- RefPtr<UserMessageHandlerDescriptor> descriptor = descriptors.get(std::make_pair(name, &world));
- if (!descriptor)
- return nullptr;
- for (auto& handler : m_messageHandlers) {
- if (&handler->descriptor() == descriptor.get())
- return &handler.get();
- }
+ UserMessageHandler* handler = m_messageHandlers.get(std::pair<AtomicString, RefPtr<DOMWrapperWorld>>(name, &world));
+ if (handler)
+ return handler;
- auto liveHandlers = descriptors.values();
- m_messageHandlers.removeAllMatching([liveHandlers](const Ref<UserMessageHandler>& handler) {
- for (const auto& liveHandler : liveHandlers) {
- if (liveHandler.get() == &handler->descriptor())
- return true;
- }
- return false;
+ page->userContentProvider().forEachUserMessageHandler([&](const UserMessageHandlerDescriptor& descriptor) {
+ if (descriptor.name() != name || &descriptor.world() != &world)
+ return;
+
+ ASSERT(!handler);
+
+ auto addResult = m_messageHandlers.add(std::make_pair(descriptor.name(), const_cast<DOMWrapperWorld*>(&descriptor.world())), UserMessageHandler::create(*frame, const_cast<UserMessageHandlerDescriptor&>(descriptor)));
+ handler = addResult.iterator->value.get();
});
- m_messageHandlers.append(UserMessageHandler::create(*frame(), *descriptor));
- return &m_messageHandlers.last().get();
+ return handler;
}
} // namespace WebCore
Modified: trunk/Source/WebCore/page/UserMessageHandlersNamespace.h (199019 => 199020)
--- trunk/Source/WebCore/page/UserMessageHandlersNamespace.h 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebCore/page/UserMessageHandlersNamespace.h 2016-04-04 21:03:28 UTC (rev 199020)
@@ -29,11 +29,13 @@
#if ENABLE(USER_MESSAGE_HANDLERS)
#include "FrameDestructionObserver.h"
+#include "UserContentProvider.h"
#include "UserMessageHandler.h"
+#include <wtf/HashMap.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
-#include <wtf/Vector.h>
#include <wtf/text/AtomicString.h>
+#include <wtf/text/AtomicStringHash.h>
namespace WebCore {
@@ -41,11 +43,11 @@
class UserMessageHandler;
class DOMWrapperWorld;
-class UserMessageHandlersNamespace : public RefCounted<UserMessageHandlersNamespace>, public FrameDestructionObserver {
+class UserMessageHandlersNamespace : public RefCounted<UserMessageHandlersNamespace>, public FrameDestructionObserver, public UserContentProviderInvalidationClient {
public:
- static Ref<UserMessageHandlersNamespace> create(Frame& frame)
+ static Ref<UserMessageHandlersNamespace> create(Frame& frame, UserContentProvider& userContentProvider)
{
- return adoptRef(*new UserMessageHandlersNamespace(frame));
+ return adoptRef(*new UserMessageHandlersNamespace(frame, userContentProvider));
}
virtual ~UserMessageHandlersNamespace();
@@ -53,9 +55,13 @@
UserMessageHandler* handler(const AtomicString&, DOMWrapperWorld&);
private:
- explicit UserMessageHandlersNamespace(Frame&);
+ explicit UserMessageHandlersNamespace(Frame&, UserContentProvider&);
- Vector<Ref<UserMessageHandler>> m_messageHandlers;
+ // UserContentProviderInvalidationClient
+ void didInvalidate(UserContentProvider&) override;
+
+ Ref<UserContentProvider> m_userContentProvider;
+ HashMap<std::pair<AtomicString, RefPtr<DOMWrapperWorld>>, RefPtr<UserMessageHandler>> m_messageHandlers;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/page/WebKitNamespace.cpp (199019 => 199020)
--- trunk/Source/WebCore/page/WebKitNamespace.cpp 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebCore/page/WebKitNamespace.cpp 2016-04-04 21:03:28 UTC (rev 199020)
@@ -33,9 +33,9 @@
namespace WebCore {
-WebKitNamespace::WebKitNamespace(Frame& frame)
+WebKitNamespace::WebKitNamespace(Frame& frame, UserContentProvider& userContentProvider)
: DOMWindowProperty(&frame)
- , m_messageHandlerNamespace(UserMessageHandlersNamespace::create(frame))
+ , m_messageHandlerNamespace(UserMessageHandlersNamespace::create(frame, userContentProvider))
{
}
Modified: trunk/Source/WebCore/page/WebKitNamespace.h (199019 => 199020)
--- trunk/Source/WebCore/page/WebKitNamespace.h 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebCore/page/WebKitNamespace.h 2016-04-04 21:03:28 UTC (rev 199020)
@@ -35,13 +35,14 @@
namespace WebCore {
class Frame;
+class UserContentProvider;
class UserMessageHandlersNamespace;
class WebKitNamespace : public DOMWindowProperty, public RefCounted<WebKitNamespace> {
public:
- static Ref<WebKitNamespace> create(Frame& frame)
+ static Ref<WebKitNamespace> create(Frame& frame, UserContentProvider& userContentProvider)
{
- return adoptRef(*new WebKitNamespace(frame));
+ return adoptRef(*new WebKitNamespace(frame, userContentProvider));
}
virtual ~WebKitNamespace();
@@ -49,7 +50,7 @@
UserMessageHandlersNamespace* messageHandlers();
private:
- explicit WebKitNamespace(Frame&);
+ explicit WebKitNamespace(Frame&, UserContentProvider&);
Ref<UserMessageHandlersNamespace> m_messageHandlerNamespace;
};
Modified: trunk/Source/WebKit2/ChangeLog (199019 => 199020)
--- trunk/Source/WebKit2/ChangeLog 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebKit2/ChangeLog 2016-04-04 21:03:28 UTC (rev 199020)
@@ -1,3 +1,83 @@
+2016-04-03 Sam Weinig <[email protected]>
+
+ Add SPI to allow install script message handlers in isolated worlds
+ https://bugs.webkit.org/show_bug.cgi?id=156153
+
+ Reviewed by Anders Carlsson.
+
+ * 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.
+
2016-04-04 Joonghun Park <[email protected]>
[EFL] Fix build break since r198800
Modified: trunk/Source/WebKit2/Scripts/webkit/messages.py (199019 => 199020)
--- trunk/Source/WebKit2/Scripts/webkit/messages.py 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebKit2/Scripts/webkit/messages.py 2016-04-04 21:03:28 UTC (rev 199020)
@@ -377,9 +377,9 @@
'WebKit::WebMouseEvent': ['"WebEvent.h"'],
'WebKit::WebTouchEvent': ['"WebEvent.h"'],
'WebKit::WebWheelEvent': ['"WebEvent.h"'],
- 'WebKit::WebScriptMessageHandlerHandle': ['"WebScriptMessageHandler.h"'],
'struct WebKit::WebUserScriptData': ['"WebUserContentControllerDataTypes.h"'],
'struct WebKit::WebUserStyleSheetData': ['"WebUserContentControllerDataTypes.h"'],
+ 'struct WebKit::WebScriptMessageHandlerData': ['"WebUserContentControllerDataTypes.h"'],
'std::chrono::system_clock::time_point': ['<chrono>'],
}
Modified: trunk/Source/WebKit2/Shared/WebUserContentControllerDataTypes.cpp (199019 => 199020)
--- trunk/Source/WebKit2/Shared/WebUserContentControllerDataTypes.cpp 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebKit2/Shared/WebUserContentControllerDataTypes.cpp 2016-04-04 21:03:28 UTC (rev 199020)
@@ -66,4 +66,24 @@
return true;
}
+
+void WebScriptMessageHandlerData::encode(IPC::ArgumentEncoder& encoder) const
+{
+ encoder << identifier;
+ encoder << worldIdentifier;
+ encoder << name;
+}
+
+bool WebScriptMessageHandlerData::decode(IPC::ArgumentDecoder& decoder, WebScriptMessageHandlerData& data)
+{
+ if (!decoder.decode(data.identifier))
+ return false;
+ if (!decoder.decode(data.worldIdentifier))
+ return false;
+ if (!decoder.decode(data.name))
+ return false;
+
+ return true;
+}
+
} // namespace WebKit
Modified: trunk/Source/WebKit2/Shared/WebUserContentControllerDataTypes.h (199019 => 199020)
--- trunk/Source/WebKit2/Shared/WebUserContentControllerDataTypes.h 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebKit2/Shared/WebUserContentControllerDataTypes.h 2016-04-04 21:03:28 UTC (rev 199020)
@@ -54,6 +54,15 @@
WebCore::UserStyleSheet userStyleSheet;
};
+struct WebScriptMessageHandlerData {
+ void encode(IPC::ArgumentEncoder&) const;
+ static bool decode(IPC::ArgumentDecoder&, WebScriptMessageHandlerData&);
+
+ uint64_t identifier;
+ uint64_t worldIdentifier;
+ String name;
+};
+
} // namespace WebKit
#endif // WebUserContentControllerDataTypes_h
Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKUserContentController.mm (199019 => 199020)
--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKUserContentController.mm 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKUserContentController.mm 2016-04-04 21:03:28 UTC (rev 199020)
@@ -29,6 +29,7 @@
#if WK_API_ENABLED
#import "APISerializedScriptValue.h"
+#import "APIUserContentWorld.h"
#import "WKFrameInfoInternal.h"
#import "WKNSArray.h"
#import "WKScriptMessageHandler.h"
@@ -118,14 +119,14 @@
- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name
{
- RefPtr<WebKit::WebScriptMessageHandler> handler = WebKit::WebScriptMessageHandler::create(std::make_unique<ScriptMessageHandlerDelegate>(self, scriptMessageHandler, name), name);
+ auto handler = WebKit::WebScriptMessageHandler::create(std::make_unique<ScriptMessageHandlerDelegate>(self, scriptMessageHandler, name), name, API::UserContentWorld::normalWorld());
if (!_userContentControllerProxy->addUserScriptMessageHandler(handler.get()))
[NSException raise:NSInvalidArgumentException format:@"Attempt to add script message handler with name '%@' when one already exists.", name];
}
- (void)removeScriptMessageHandlerForName:(NSString *)name
{
- _userContentControllerProxy->removeUserMessageHandlerForName(name);
+ _userContentControllerProxy->removeUserMessageHandlerForName(name, API::UserContentWorld::normalWorld());
}
#pragma mark WKObject protocol implementation
@@ -195,6 +196,23 @@
_userContentControllerProxy->removeAllUserStyleSheets(*userContentWorld->_userContentWorld);
}
+- (void)_addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name userContentWorld:(_WKUserContentWorld *)userContentWorld
+{
+ auto handler = WebKit::WebScriptMessageHandler::create(std::make_unique<ScriptMessageHandlerDelegate>(self, scriptMessageHandler, name), name, *userContentWorld->_userContentWorld);
+ if (!_userContentControllerProxy->addUserScriptMessageHandler(handler.get()))
+ [NSException raise:NSInvalidArgumentException format:@"Attempt to add script message handler with name '%@' when one already exists.", name];
+}
+
+- (void)_removeScriptMessageHandlerForName:(NSString *)name userContentWorld:(_WKUserContentWorld *)userContentWorld
+{
+ _userContentControllerProxy->removeUserMessageHandlerForName(name, *userContentWorld->_userContentWorld);
+}
+
+- (void)_removeAllScriptMessageHandlersAssociatedWithUserContentWorld:(_WKUserContentWorld *)userContentWorld
+{
+ _userContentControllerProxy->removeAllUserMessageHandlers(*userContentWorld->_userContentWorld);
+}
+
@end
#endif
Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKUserContentControllerPrivate.h (199019 => 199020)
--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKUserContentControllerPrivate.h 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKUserContentControllerPrivate.h 2016-04-04 21:03:28 UTC (rev 199020)
@@ -47,6 +47,10 @@
- (void)_removeAllUserStyleSheets WK_AVAILABLE(WK_MAC_TBA, WK_IOS_TBA);
- (void)_removeAllUserStyleSheetsAssociatedWithUserContentWorld:(_WKUserContentWorld *)userContentWorld WK_AVAILABLE(WK_MAC_TBA, WK_IOS_TBA);
+- (void)_addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name userContentWorld:(_WKUserContentWorld *)userContentWorld;
+- (void)_removeScriptMessageHandlerForName:(NSString *)name userContentWorld:(_WKUserContentWorld *)userContentWorld;
+- (void)_removeAllScriptMessageHandlersAssociatedWithUserContentWorld:(_WKUserContentWorld *)userContentWorld;
+
@end
#endif
Modified: trunk/Source/WebKit2/UIProcess/UserContent/WebScriptMessageHandler.cpp (199019 => 199020)
--- trunk/Source/WebKit2/UIProcess/UserContent/WebScriptMessageHandler.cpp 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebKit2/UIProcess/UserContent/WebScriptMessageHandler.cpp 2016-04-04 21:03:28 UTC (rev 199020)
@@ -26,27 +26,10 @@
#include "config.h"
#include "WebScriptMessageHandler.h"
-#include "ArgumentCoders.h"
+#include "APIUserContentWorld.h"
namespace WebKit {
-void WebScriptMessageHandlerHandle::encode(IPC::ArgumentEncoder& encoder) const
-{
- encoder << identifier;
- encoder << name;
-}
-
-bool WebScriptMessageHandlerHandle::decode(IPC::ArgumentDecoder& decoder, WebScriptMessageHandlerHandle& handle)
-{
- if (!decoder.decode(handle.identifier))
- return false;
-
- if (!decoder.decode(handle.name))
- return false;
-
- return true;
-}
-
static uint64_t generateIdentifier()
{
static uint64_t identifier;
@@ -54,15 +37,16 @@
return ++identifier;
}
-PassRefPtr<WebScriptMessageHandler> WebScriptMessageHandler::create(std::unique_ptr<Client> client, const String& name)
+Ref<WebScriptMessageHandler> WebScriptMessageHandler::create(std::unique_ptr<Client> client, const String& name, API::UserContentWorld& world)
{
- return adoptRef(new WebScriptMessageHandler(WTFMove(client), name));
+ return adoptRef(*new WebScriptMessageHandler(WTFMove(client), name, world));
}
-WebScriptMessageHandler::WebScriptMessageHandler(std::unique_ptr<Client> client, const String& name)
+WebScriptMessageHandler::WebScriptMessageHandler(std::unique_ptr<Client> client, const String& name, API::UserContentWorld& world)
: m_identifier(generateIdentifier())
, m_client(WTFMove(client))
, m_name(name)
+ , m_world(world)
{
}
Modified: trunk/Source/WebKit2/UIProcess/UserContent/WebScriptMessageHandler.h (199019 => 199020)
--- trunk/Source/WebKit2/UIProcess/UserContent/WebScriptMessageHandler.h 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebKit2/UIProcess/UserContent/WebScriptMessageHandler.h 2016-04-04 21:03:28 UTC (rev 199020)
@@ -26,33 +26,25 @@
#ifndef WebScriptMessageHandler_h
#define WebScriptMessageHandler_h
-#include <wtf/PassRefPtr.h>
+#include "WebUserContentControllerDataTypes.h"
+#include <wtf/Ref.h>
#include <wtf/RefCounted.h>
#include <wtf/text/WTFString.h>
-namespace IPC {
-class ArgumentDecoder;
-class ArgumentEncoder;
-}
-
namespace WebCore {
struct SecurityOriginData;
class SerializedScriptValue;
}
+namespace API {
+class UserContentWorld;
+}
+
namespace WebKit {
class WebPageProxy;
class WebFrameProxy;
-struct WebScriptMessageHandlerHandle {
- void encode(IPC::ArgumentEncoder&) const;
- static bool decode(IPC::ArgumentDecoder&, WebScriptMessageHandlerHandle&);
-
- uint64_t identifier;
- String name;
-};
-
class WebScriptMessageHandler : public RefCounted<WebScriptMessageHandler> {
public:
class Client {
@@ -61,23 +53,25 @@
virtual void didPostMessage(WebPageProxy&, WebFrameProxy&, const WebCore::SecurityOriginData&, WebCore::SerializedScriptValue&) = 0;
};
- static PassRefPtr<WebScriptMessageHandler> create(std::unique_ptr<Client>, const String& name);
+ static Ref<WebScriptMessageHandler> create(std::unique_ptr<Client>, const String& name, API::UserContentWorld&);
virtual ~WebScriptMessageHandler();
- WebScriptMessageHandlerHandle handle() { return { m_identifier, m_name }; }
-
uint64_t identifier() const { return m_identifier; }
String name() const { return m_name; }
+ const API::UserContentWorld& userContentWorld() const { return m_world; }
+ API::UserContentWorld& userContentWorld() { return m_world; }
+
Client& client() const { return *m_client; }
private:
- WebScriptMessageHandler(std::unique_ptr<Client>, const String&);
+ WebScriptMessageHandler(std::unique_ptr<Client>, const String&, API::UserContentWorld&);
uint64_t m_identifier;
std::unique_ptr<Client> m_client;
String m_name;
+ Ref<API::UserContentWorld> m_world;
};
} // namespace API
Modified: trunk/Source/WebKit2/UIProcess/UserContent/WebUserContentControllerProxy.cpp (199019 => 199020)
--- trunk/Source/WebKit2/UIProcess/UserContent/WebUserContentControllerProxy.cpp 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebKit2/UIProcess/UserContent/WebUserContentControllerProxy.cpp 2016-04-04 21:03:28 UTC (rev 199020)
@@ -91,10 +91,10 @@
userStyleSheets.append({ userStyleSheet->identifier(), userStyleSheet->userContentWorld().identifier(), userStyleSheet->userStyleSheet() });
webProcessProxy.connection()->send(Messages::WebUserContentController::AddUserStyleSheets(userStyleSheets), m_identifier);
- Vector<WebScriptMessageHandlerHandle> messageHandlerHandles;
+ Vector<WebScriptMessageHandlerData> messageHandlers;
for (auto& handler : m_scriptMessageHandlers.values())
- messageHandlerHandles.append(handler->handle());
- webProcessProxy.connection()->send(Messages::WebUserContentController::AddUserScriptMessageHandlers(messageHandlerHandles), m_identifier);
+ messageHandlers.append({ handler->identifier(), handler->userContentWorld().identifier(), handler->name() });
+ webProcessProxy.connection()->send(Messages::WebUserContentController::AddUserScriptMessageHandlers(messageHandlers), m_identifier);
#if ENABLE(CONTENT_EXTENSIONS)
Vector<std::pair<String, WebCompiledContentExtensionData>> userContentExtensions;
@@ -270,33 +270,57 @@
removeUserContentWorldUses(worlds);
}
-bool WebUserContentControllerProxy::addUserScriptMessageHandler(WebScriptMessageHandler* handler)
+bool WebUserContentControllerProxy::addUserScriptMessageHandler(WebScriptMessageHandler& handler)
{
+ Ref<API::UserContentWorld> world = handler.userContentWorld();
+
for (auto& existingHandler : m_scriptMessageHandlers.values()) {
- if (existingHandler->name() == handler->name())
+ if (existingHandler->name() == handler.name() && &existingHandler->userContentWorld() == world.ptr())
return false;
}
- m_scriptMessageHandlers.add(handler->identifier(), handler);
+ addUserContentWorldUse(world.get());
+ m_scriptMessageHandlers.add(handler.identifier(), &handler);
+
for (WebProcessProxy* process : m_processes)
- process->connection()->send(Messages::WebUserContentController::AddUserScriptMessageHandlers({ handler->handle() }), m_identifier);
+ process->connection()->send(Messages::WebUserContentController::AddUserScriptMessageHandlers({ { handler.identifier(), world->identifier(), handler.name() } }), m_identifier);
return true;
}
-void WebUserContentControllerProxy::removeUserMessageHandlerForName(const String& name)
+void WebUserContentControllerProxy::removeUserMessageHandlerForName(const String& name, API::UserContentWorld& world)
{
for (auto it = m_scriptMessageHandlers.begin(), end = m_scriptMessageHandlers.end(); it != end; ++it) {
- if (it->value->name() == name) {
+ if (it->value->name() == name && &it->value->userContentWorld() == &world) {
for (WebProcessProxy* process : m_processes)
- process->connection()->send(Messages::WebUserContentController::RemoveUserScriptMessageHandler(it->value->identifier()), m_identifier);
+ process->connection()->send(Messages::WebUserContentController::RemoveUserScriptMessageHandler(world.identifier(), it->value->identifier()), m_identifier);
+
m_scriptMessageHandlers.remove(it);
+
+ removeUserContentWorldUses(world, 1);
return;
}
}
}
+void WebUserContentControllerProxy::removeAllUserMessageHandlers(API::UserContentWorld& world)
+{
+ for (WebProcessProxy* process : m_processes)
+ process->connection()->send(Messages::WebUserContentController::RemoveAllUserScriptMessageHandlers({ world.identifier() }), m_identifier);
+
+ unsigned numberRemoved = 0;
+ m_scriptMessageHandlers.removeIf([&](HashMap<uint64_t, RefPtr<WebScriptMessageHandler>>::KeyValuePairType& entry) {
+ if (&entry.value->userContentWorld() == &world) {
+ ++numberRemoved;
+ return true;
+ }
+ return false;
+ });
+
+ removeUserContentWorldUses(world, numberRemoved);
+}
+
void WebUserContentControllerProxy::didPostMessage(IPC::Connection& connection, uint64_t pageID, uint64_t frameID, const WebCore::SecurityOriginData& securityOrigin, uint64_t messageHandlerID, const IPC::DataReference& dataReference)
{
WebPageProxy* page = WebProcessProxy::webPage(pageID);
@@ -315,8 +339,7 @@
if (!handler)
return;
- handler->client().didPostMessage(*page, *frame, securityOrigin,
- WebCore::SerializedScriptValue::adopt(dataReference.vector()));
+ handler->client().didPostMessage(*page, *frame, securityOrigin, WebCore::SerializedScriptValue::adopt(dataReference.vector()));
}
#if ENABLE(CONTENT_EXTENSIONS)
Modified: trunk/Source/WebKit2/UIProcess/UserContent/WebUserContentControllerProxy.h (199019 => 199020)
--- trunk/Source/WebKit2/UIProcess/UserContent/WebUserContentControllerProxy.h 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebKit2/UIProcess/UserContent/WebUserContentControllerProxy.h 2016-04-04 21:03:28 UTC (rev 199020)
@@ -88,8 +88,9 @@
void removeAllUserContent(API::UserContentWorld&);
// Returns false if there was a name conflict.
- bool addUserScriptMessageHandler(WebScriptMessageHandler*);
- void removeUserMessageHandlerForName(const String&);
+ bool addUserScriptMessageHandler(WebScriptMessageHandler&);
+ void removeUserMessageHandlerForName(const String&, API::UserContentWorld&);
+ void removeAllUserMessageHandlers(API::UserContentWorld&);
#if ENABLE(CONTENT_EXTENSIONS)
void addUserContentExtension(API::UserContentExtension&);
Modified: trunk/Source/WebKit2/WebProcess/UserContent/WebUserContentController.cpp (199019 => 199020)
--- trunk/Source/WebKit2/WebProcess/UserContent/WebUserContentController.cpp 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebKit2/WebProcess/UserContent/WebUserContentController.cpp 2016-04-04 21:03:28 UTC (rev 199020)
@@ -171,6 +171,8 @@
UserStyleSheet sheet = userStyleSheetData.userStyleSheet;
addUserStyleSheetInternal(*it->value.first, userStyleSheetData.identifier, WTFMove(sheet));
}
+
+ invalidateInjectedStyleSheetCacheInAllFramesInAllPages();
}
void WebUserContentController::removeUserStyleSheet(uint64_t worldIdentifier, uint64_t userStyleSheetIdentifier)
@@ -186,6 +188,7 @@
void WebUserContentController::removeAllUserStyleSheets(const Vector<uint64_t>& worldIdentifiers)
{
+ bool sheetsChanged = false;
for (auto& worldIdentifier : worldIdentifiers) {
auto it = worldMap().find(worldIdentifier);
if (it == worldMap().end()) {
@@ -193,26 +196,39 @@
return;
}
- removeUserStyleSheets(*it->value.first);
+ if (m_userStyleSheets.remove(it->value.first.get()))
+ sheetsChanged = true;
}
+
+ if (sheetsChanged)
+ invalidateInjectedStyleSheetCacheInAllFramesInAllPages();
}
#if ENABLE(USER_MESSAGE_HANDLERS)
-class WebUserMessageHandlerDescriptorProxy : public RefCounted<WebUserMessageHandlerDescriptorProxy>, public WebCore::UserMessageHandlerDescriptor::Client {
+class WebUserMessageHandlerDescriptorProxy : public WebCore::UserMessageHandlerDescriptor {
public:
- static PassRefPtr<WebUserMessageHandlerDescriptorProxy> create(WebUserContentController* controller, const String& name, uint64_t identifier)
+ static PassRefPtr<WebUserMessageHandlerDescriptorProxy> create(WebUserContentController* controller, const String& name, InjectedBundleScriptWorld& world, uint64_t identifier)
{
- return adoptRef(new WebUserMessageHandlerDescriptorProxy(controller, name, identifier));
+ return adoptRef(new WebUserMessageHandlerDescriptorProxy(controller, name, world, identifier));
}
virtual ~WebUserMessageHandlerDescriptorProxy()
{
- m_descriptor->invalidateClient();
}
- // WebCore::UserMessageHandlerDescriptor::Client
- virtual void didPostMessage(WebCore::UserMessageHandler& handler, WebCore::SerializedScriptValue* value)
+ uint64_t identifier() { return m_identifier; }
+
+private:
+ WebUserMessageHandlerDescriptorProxy(WebUserContentController* controller, const String& name, InjectedBundleScriptWorld& world, uint64_t identifier)
+ : WebCore::UserMessageHandlerDescriptor(name, world.coreWorld())
+ , m_controller(controller)
+ , m_identifier(identifier)
{
+ }
+
+ // WebCore::UserMessageHandlerDescriptor
+ void didPostMessage(WebCore::UserMessageHandler& handler, WebCore::SerializedScriptValue* value) override
+ {
WebCore::Frame* frame = handler.frame();
if (!frame)
return;
@@ -228,54 +244,99 @@
WebProcess::singleton().parentProcessConnection()->send(Messages::WebUserContentControllerProxy::DidPostMessage(webPage->pageID(), webFrame->frameID(), SecurityOriginData::fromFrame(frame), m_identifier, IPC::DataReference(value->data())), m_controller->identifier());
}
- WebCore::UserMessageHandlerDescriptor& descriptor() { return *m_descriptor; }
- uint64_t identifier() { return m_identifier; }
-
-private:
- WebUserMessageHandlerDescriptorProxy(WebUserContentController* controller, const String& name, uint64_t identifier)
- : m_controller(controller)
- , m_descriptor(UserMessageHandlerDescriptor::create(name, mainThreadNormalWorld(), *this))
- , m_identifier(identifier)
- {
- }
-
RefPtr<WebUserContentController> m_controller;
- RefPtr<WebCore::UserMessageHandlerDescriptor> m_descriptor;
uint64_t m_identifier;
};
#endif
-void WebUserContentController::addUserScriptMessageHandlers(const Vector<WebScriptMessageHandlerHandle>& scriptMessageHandlers)
+void WebUserContentController::addUserScriptMessageHandlers(const Vector<WebScriptMessageHandlerData>& scriptMessageHandlers)
{
#if ENABLE(USER_MESSAGE_HANDLERS)
- for (auto& handle : scriptMessageHandlers) {
- RefPtr<WebUserMessageHandlerDescriptorProxy> descriptor = WebUserMessageHandlerDescriptorProxy::create(this, handle.name, handle.identifier);
+ for (auto& handler : scriptMessageHandlers) {
+ auto it = worldMap().find(handler.worldIdentifier);
+ if (it == worldMap().end()) {
+ WTFLogAlways("Trying to add a UserScriptMessageHandler to a UserContentWorld (id=%" PRIu64 ") that does not exist.", handler.worldIdentifier);
+ continue;
+ }
- m_userMessageHandlerDescriptors.add(descriptor->identifier(), descriptor);
-
- auto& coreDescriptor = descriptor->descriptor();
- m_userMessageHandlerDescriptorsMap.add(std::make_pair(coreDescriptor.name(), &coreDescriptor.world()), &coreDescriptor);
+ addUserScriptMessageHandlerInternal(*it->value.first, handler.identifier, handler.name);
}
#else
UNUSED_PARAM(scriptMessageHandlers);
#endif
}
-void WebUserContentController::removeUserScriptMessageHandler(uint64_t identifier)
+void WebUserContentController::removeUserScriptMessageHandler(uint64_t worldIdentifier, uint64_t userScriptMessageHandlerIdentifier)
{
#if ENABLE(USER_MESSAGE_HANDLERS)
- auto it = m_userMessageHandlerDescriptors.find(identifier);
- ASSERT(it != m_userMessageHandlerDescriptors.end());
+ auto it = worldMap().find(worldIdentifier);
+ if (it == worldMap().end()) {
+ WTFLogAlways("Trying to remove a UserScriptMessageHandler from a UserContentWorld (id=%" PRIu64 ") that does not exist.", worldIdentifier);
+ return;
+ }
- auto& coreDescriptor = it->value->descriptor();
- m_userMessageHandlerDescriptorsMap.remove(std::make_pair(coreDescriptor.name(), &coreDescriptor.world()));
+ removeUserScriptMessageHandlerInternal(*it->value.first, userScriptMessageHandlerIdentifier);
+#else
+ UNUSED_PARAM(worldIdentifier);
+ UNUSED_PARAM(userScriptMessageHandlerIdentifier);
+#endif
+}
- m_userMessageHandlerDescriptors.remove(it);
+void WebUserContentController::removeAllUserScriptMessageHandlers(const Vector<uint64_t>& worldIdentifiers)
+{
+#if ENABLE(USER_MESSAGE_HANDLERS)
+ bool userMessageHandlersChanged = false;
+ for (auto& worldIdentifier : worldIdentifiers) {
+ auto it = worldMap().find(worldIdentifier);
+ if (it == worldMap().end()) {
+ WTFLogAlways("Trying to remove all UserScriptMessageHandler from a UserContentWorld (id=%" PRIu64 ") that does not exist.", worldIdentifier);
+ return;
+ }
+
+ if (m_userMessageHandlers.remove(it->value.first.get()))
+ userMessageHandlersChanged = true;
+ }
+
+ if (userMessageHandlersChanged)
+ invalidateAllRegisteredUserMessageHandlerInvalidationClients();
#else
- UNUSED_PARAM(identifier);
+ UNUSED_PARAM(worldIdentifiers);
#endif
}
+#if ENABLE(USER_MESSAGE_HANDLERS)
+void WebUserContentController::addUserScriptMessageHandlerInternal(InjectedBundleScriptWorld& world, uint64_t userScriptMessageHandlerIdentifier, const String& name)
+{
+ auto& messageHandlersInWorld = m_userMessageHandlers.ensure(&world, [] { return Vector<RefPtr<WebUserMessageHandlerDescriptorProxy>>(); }).iterator->value;
+ messageHandlersInWorld.append(WebUserMessageHandlerDescriptorProxy::create(this, name, world, userScriptMessageHandlerIdentifier));
+}
+
+void WebUserContentController::removeUserScriptMessageHandlerInternal(InjectedBundleScriptWorld& world, uint64_t userScriptMessageHandlerIdentifier)
+{
+ auto it = m_userMessageHandlers.find(&world);
+ if (it == m_userMessageHandlers.end())
+ return;
+
+ auto& userMessageHandlers = it->value;
+
+ bool userMessageHandlersChanged = false;
+ for (int i = userMessageHandlers.size() - 1; i >= 0; --i) {
+ if (userMessageHandlers[i]->identifier() == userScriptMessageHandlerIdentifier) {
+ userMessageHandlers.remove(i);
+ userMessageHandlersChanged = true;
+ }
+ }
+
+ if (!userMessageHandlersChanged)
+ return;
+
+ if (userMessageHandlers.isEmpty())
+ m_userMessageHandlers.remove(it);
+
+ invalidateAllRegisteredUserMessageHandlerInvalidationClients();
+}
+#endif
+
#if ENABLE(CONTENT_EXTENSIONS)
void WebUserContentController::addUserContentExtensions(const Vector<std::pair<String, WebCompiledContentExtensionData>>& userContentExtensions)
{
@@ -298,8 +359,6 @@
}
#endif
-
-
void WebUserContentController::addUserScriptInternal(InjectedBundleScriptWorld& world, uint64_t userScriptIdentifier, UserScript&& userScript)
{
auto& scriptsInWorld = m_userScripts.ensure(&world, [] { return Vector<std::pair<uint64_t, WebCore::UserScript>>(); }).iterator->value;
@@ -352,13 +411,12 @@
{
auto& styleSheetsInWorld = m_userStyleSheets.ensure(&world, [] { return Vector<std::pair<uint64_t, WebCore::UserStyleSheet>>(); }).iterator->value;
styleSheetsInWorld.append(std::make_pair(userStyleSheetIdentifier, WTFMove(userStyleSheet)));
-
- invalidateInjectedStyleSheetCacheInAllFramesInAllPages();
}
void WebUserContentController::addUserStyleSheet(InjectedBundleScriptWorld& world, UserStyleSheet&& userStyleSheet)
{
addUserStyleSheetInternal(world, 0, WTFMove(userStyleSheet));
+ invalidateInjectedStyleSheetCacheInAllFramesInAllPages();
}
void WebUserContentController::removeUserStyleSheetWithURL(InjectedBundleScriptWorld& world, const URL& url)
@@ -446,4 +504,14 @@
}
}
+#if ENABLE(USER_MESSAGE_HANDLERS)
+void WebUserContentController::forEachUserMessageHandler(const std::function<void(const WebCore::UserMessageHandlerDescriptor&)>& functor) const
+{
+ for (const auto& userMessageHandlerVector : m_userMessageHandlers.values()) {
+ for (const auto& userMessageHandler : userMessageHandlerVector)
+ functor(*userMessageHandler.get());
+ }
+}
+#endif
+
} // namespace WebKit
Modified: trunk/Source/WebKit2/WebProcess/UserContent/WebUserContentController.h (199019 => 199020)
--- trunk/Source/WebKit2/WebProcess/UserContent/WebUserContentController.h 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebKit2/WebProcess/UserContent/WebUserContentController.h 2016-04-04 21:03:28 UTC (rev 199020)
@@ -46,10 +46,7 @@
class InjectedBundleScriptWorld;
class WebCompiledContentExtensionData;
-
-#if ENABLE(USER_MESSAGE_HANDLERS)
class WebUserMessageHandlerDescriptorProxy;
-#endif
class WebUserContentController final : public WebCore::UserContentProvider, private IPC::MessageReceiver {
public:
@@ -73,7 +70,7 @@
void forEachUserScript(const std::function<void(WebCore::DOMWrapperWorld&, const WebCore::UserScript&)>&) const override;
void forEachUserStyleSheet(const std::function<void(const WebCore::UserStyleSheet&)>&) const override;
#if ENABLE(USER_MESSAGE_HANDLERS)
- const WebCore::UserMessageHandlerDescriptorMap& userMessageHandlerDescriptors() const override { return m_userMessageHandlerDescriptorsMap; }
+ void forEachUserMessageHandler(const std::function<void(const WebCore::UserMessageHandlerDescriptor&)>&) const override;
#endif
#if ENABLE(CONTENT_EXTENSIONS)
WebCore::ContentExtensions::ContentExtensionsBackend& userContentExtensionBackend() override { return m_contentExtensionBackend; }
@@ -93,8 +90,9 @@
void removeUserStyleSheet(uint64_t worldIdentifier, uint64_t userScriptIdentifier);
void removeAllUserStyleSheets(const Vector<uint64_t>&);
- void addUserScriptMessageHandlers(const Vector<WebScriptMessageHandlerHandle>&);
- void removeUserScriptMessageHandler(uint64_t);
+ void addUserScriptMessageHandlers(const Vector<WebScriptMessageHandlerData>&);
+ void removeUserScriptMessageHandler(uint64_t worldIdentifier, uint64_t userScriptIdentifier);
+ void removeAllUserScriptMessageHandlers(const Vector<uint64_t>&);
#if ENABLE(CONTENT_EXTENSIONS)
void addUserContentExtensions(const Vector<std::pair<String, WebCompiledContentExtensionData>>&);
@@ -102,13 +100,15 @@
void removeAllUserContentExtensions();
#endif
-
void addUserScriptInternal(InjectedBundleScriptWorld&, uint64_t userScriptIdentifier, WebCore::UserScript&&);
void removeUserScriptInternal(InjectedBundleScriptWorld&, uint64_t userScriptIdentifier);
void addUserStyleSheetInternal(InjectedBundleScriptWorld&, uint64_t userStyleSheetIdentifier, WebCore::UserStyleSheet&&);
void removeUserStyleSheetInternal(InjectedBundleScriptWorld&, uint64_t userStyleSheetIdentifier);
+#if ENABLE(USER_MESSAGE_HANDLERS)
+ void addUserScriptMessageHandlerInternal(InjectedBundleScriptWorld&, uint64_t userScriptMessageHandlerIdentifier, const String& name);
+ void removeUserScriptMessageHandlerInternal(InjectedBundleScriptWorld&, uint64_t userScriptMessageHandlerIdentifier);
+#endif
-
uint64_t m_identifier;
typedef HashMap<RefPtr<InjectedBundleScriptWorld>, Vector<std::pair<uint64_t, WebCore::UserScript>>> WorldToUserScriptMap;
@@ -118,8 +118,8 @@
WorldToUserStyleSheetMap m_userStyleSheets;
#if ENABLE(USER_MESSAGE_HANDLERS)
- HashMap<uint64_t, RefPtr<WebUserMessageHandlerDescriptorProxy>> m_userMessageHandlerDescriptors;
- WebCore::UserMessageHandlerDescriptorMap m_userMessageHandlerDescriptorsMap;
+ typedef HashMap<RefPtr<InjectedBundleScriptWorld>, Vector<RefPtr<WebUserMessageHandlerDescriptorProxy>>> WorldToUserMessageHandlerVectorMap;
+ WorldToUserMessageHandlerVectorMap m_userMessageHandlers;
#endif
#if ENABLE(CONTENT_EXTENSIONS)
WebCore::ContentExtensions::ContentExtensionsBackend m_contentExtensionBackend;
Modified: trunk/Source/WebKit2/WebProcess/UserContent/WebUserContentController.messages.in (199019 => 199020)
--- trunk/Source/WebKit2/WebProcess/UserContent/WebUserContentController.messages.in 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Source/WebKit2/WebProcess/UserContent/WebUserContentController.messages.in 2016-04-04 21:03:28 UTC (rev 199020)
@@ -35,8 +35,9 @@
RemoveUserStyleSheet(uint64_t worldIdentifier, uint64_t identifier);
RemoveAllUserStyleSheets(Vector<uint64_t> worldIdentifiers);
- AddUserScriptMessageHandlers(Vector<WebKit::WebScriptMessageHandlerHandle> scriptMessageHandlers);
- RemoveUserScriptMessageHandler(uint64_t identifier);
+ AddUserScriptMessageHandlers(Vector<struct WebKit::WebScriptMessageHandlerData> scriptMessageHandlers);
+ RemoveUserScriptMessageHandler(uint64_t worldIdentifier, uint64_t identifier);
+ RemoveAllUserScriptMessageHandlers(Vector<uint64_t> worldIdentifiers);
#if ENABLE(CONTENT_EXTENSIONS)
AddUserContentExtensions(Vector<std::pair<String, WebKit::WebCompiledContentExtensionData>> userContentFilters);
Modified: trunk/Tools/ChangeLog (199019 => 199020)
--- trunk/Tools/ChangeLog 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Tools/ChangeLog 2016-04-04 21:03:28 UTC (rev 199020)
@@ -1,3 +1,13 @@
+2016-04-03 Sam Weinig <[email protected]>
+
+ Add SPI to allow install script message handlers in isolated worlds
+ https://bugs.webkit.org/show_bug.cgi?id=156153
+
+ Reviewed by Anders Carlsson.
+
+ * TestWebKitAPI/Tests/WebKit2Cocoa/UserContentController.mm:
+ Add new test, WKUserContentController.ScriptMessageHandlerBasicPostIsolatedWorld
+
2016-04-04 Jiewen Tan <[email protected]>
Build fix for r198956.
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/UserContentController.mm (199019 => 199020)
--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/UserContentController.mm 2016-04-04 20:45:01 UTC (rev 199019)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/UserContentController.mm 2016-04-04 21:03:28 UTC (rev 199020)
@@ -95,6 +95,55 @@
EXPECT_WK_STREQ(@"Hello", (NSString *)[lastScriptMessage body]);
}
+TEST(WKUserContentController, ScriptMessageHandlerBasicPostIsolatedWorld)
+{
+ RetainPtr<_WKUserContentWorld> world = adoptNS([_WKUserContentWorld worldWithName:@"TestWorld"]);
+
+ RetainPtr<ScriptMessageHandler> handler = adoptNS([[ScriptMessageHandler alloc] init]);
+ RetainPtr<WKUserScript> userScript = adoptNS([[WKUserScript alloc] _initWithSource:@"window.webkit.messageHandlers.testHandler.postMessage('Hello')" injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO legacyWhitelist:@[] legacyBlacklist:@[] userContentWorld:world.get()]);
+
+ RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ [[configuration userContentController] _addScriptMessageHandler:handler.get() name:@"testHandler" userContentWorld:world.get()];
+ [[configuration userContentController] addUserScript:userScript.get()];
+
+ RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+
+ RetainPtr<SimpleNavigationDelegate> delegate = adoptNS([[SimpleNavigationDelegate alloc] init]);
+ [webView setNavigationDelegate:delegate.get()];
+
+ NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+
+ isDoneWithNavigation = false;
+ [webView loadRequest:request];
+
+ TestWebKitAPI::Util::run(&receivedScriptMessage);
+ receivedScriptMessage = false;
+
+ EXPECT_WK_STREQ(@"Hello", (NSString *)[lastScriptMessage body]);
+
+ if (!isDoneWithNavigation)
+ TestWebKitAPI::Util::run(&isDoneWithNavigation);
+
+ __block bool isDoneEvaluatingScript = false;
+ __block NSString *resultValue = @"";
+ [webView evaluateJavaScript:
+ @"var result;"
+ "if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.testHandler) {"
+ " result = { 'result': 'FAIL' };"
+ "} else {"
+ " result = { 'result': 'PASS' };"
+ "} "
+ "result;"
+ completionHandler:^(id value, NSError *error) {
+ resultValue = [((NSDictionary *)value)[@"result"] copy];
+ isDoneEvaluatingScript = true;
+ }];
+
+ TestWebKitAPI::Util::run(&isDoneEvaluatingScript);
+
+ EXPECT_WK_STREQ(@"PASS", resultValue);
+}
+
TEST(WKUserContentController, ScriptMessageHandlerBasicRemove)
{
RetainPtr<ScriptMessageHandler> handler = adoptNS([[ScriptMessageHandler alloc] init]);