WebUserContentController.cpp [plain text]
#include "config.h"
#include "WebUserContentController.h"
#include "DataReference.h"
#include "SecurityOriginData.h"
#include "WebCompiledContentExtension.h"
#include "WebFrame.h"
#include "WebPage.h"
#include "WebProcess.h"
#include "WebUserContentControllerMessages.h"
#include "WebUserContentControllerProxyMessages.h"
#include <WebCore/DOMWrapperWorld.h>
#include <WebCore/ScriptController.h>
#include <WebCore/SerializedScriptValue.h>
#include <WebCore/UserStyleSheet.h>
#include <wtf/NeverDestroyed.h>
#if ENABLE(USER_MESSAGE_HANDLERS)
#include <WebCore/UserMessageHandler.h>
#include <WebCore/UserMessageHandlerDescriptor.h>
#endif
using namespace WebCore;
namespace WebKit {
static HashMap<uint64_t, WebUserContentController*>& userContentControllers()
{
static NeverDestroyed<HashMap<uint64_t, WebUserContentController*>> userContentControllers;
return userContentControllers;
}
PassRefPtr<WebUserContentController> WebUserContentController::getOrCreate(uint64_t identifier)
{
auto& userContentControllerPtr = userContentControllers().add(identifier, nullptr).iterator->value;
if (userContentControllerPtr)
return userContentControllerPtr;
RefPtr<WebUserContentController> userContentController = adoptRef(new WebUserContentController(identifier));
userContentControllerPtr = userContentController.get();
return userContentController.release();
}
WebUserContentController::WebUserContentController(uint64_t identifier)
: m_identifier(identifier)
, m_userContentController(UserContentController::create())
{
WebProcess::singleton().addMessageReceiver(Messages::WebUserContentController::messageReceiverName(), m_identifier, *this);
}
WebUserContentController::~WebUserContentController()
{
ASSERT(userContentControllers().contains(m_identifier));
WebProcess::singleton().removeMessageReceiver(Messages::WebUserContentController::messageReceiverName(), m_identifier);
userContentControllers().remove(m_identifier);
}
void WebUserContentController::addUserScripts(const Vector<WebCore::UserScript>& userScripts)
{
for (const auto& userScript : userScripts)
m_userContentController->addUserScript(mainThreadNormalWorld(), std::make_unique<WebCore::UserScript>(userScript));
}
void WebUserContentController::removeAllUserScripts()
{
m_userContentController->removeUserScripts(mainThreadNormalWorld());
}
void WebUserContentController::addUserStyleSheets(const Vector<WebCore::UserStyleSheet>& userStyleSheets)
{
for (const auto& userStyleSheet : userStyleSheets) {
m_userContentController->addUserStyleSheet(mainThreadNormalWorld(),
std::make_unique<WebCore::UserStyleSheet>(userStyleSheet), InjectInExistingDocuments);
}
}
void WebUserContentController::removeAllUserStyleSheets()
{
m_userContentController->removeUserStyleSheets(mainThreadNormalWorld());
}
#if ENABLE(USER_MESSAGE_HANDLERS)
class WebUserMessageHandlerDescriptorProxy : public RefCounted<WebUserMessageHandlerDescriptorProxy>, public WebCore::UserMessageHandlerDescriptor::Client {
public:
static PassRefPtr<WebUserMessageHandlerDescriptorProxy> create(WebUserContentController* controller, const String& name, uint64_t identifier)
{
return adoptRef(new WebUserMessageHandlerDescriptorProxy(controller, name, identifier));
}
virtual ~WebUserMessageHandlerDescriptorProxy()
{
m_descriptor->invalidateClient();
}
virtual void didPostMessage(WebCore::UserMessageHandler& handler, WebCore::SerializedScriptValue* value)
{
WebCore::Frame* frame = handler.frame();
if (!frame)
return;
WebFrame* webFrame = WebFrame::fromCoreFrame(*frame);
if (!webFrame)
return;
WebPage* webPage = webFrame->page();
if (!webPage)
return;
WebProcess::singleton().parentProcessConnection()->send(Messages::WebUserContentControllerProxy::DidPostMessage(webPage->pageID(), webFrame->frameID(), SecurityOriginData::fromFrame(webFrame), 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)
{
#if ENABLE(USER_MESSAGE_HANDLERS)
for (auto& handle : scriptMessageHandlers) {
RefPtr<WebUserMessageHandlerDescriptorProxy> descriptor = WebUserMessageHandlerDescriptorProxy::create(this, handle.name, handle.identifier);
m_userMessageHandlerDescriptors.add(descriptor->identifier(), descriptor);
m_userContentController->addUserMessageHandlerDescriptor(descriptor->descriptor());
}
#else
UNUSED_PARAM(scriptMessageHandlers);
#endif
}
void WebUserContentController::removeUserScriptMessageHandler(uint64_t identifier)
{
#if ENABLE(USER_MESSAGE_HANDLERS)
auto it = m_userMessageHandlerDescriptors.find(identifier);
ASSERT(it != m_userMessageHandlerDescriptors.end());
m_userContentController->removeUserMessageHandlerDescriptor(it->value->descriptor());
m_userMessageHandlerDescriptors.remove(it);
#else
UNUSED_PARAM(identifier);
#endif
}
#if ENABLE(CONTENT_EXTENSIONS)
void WebUserContentController::addUserContentExtensions(const Vector<std::pair<String, WebCompiledContentExtensionData>>& userContentExtensions)
{
for (const auto& userContentExtension : userContentExtensions) {
WebCompiledContentExtensionData contentExtensionData = userContentExtension.second;
RefPtr<WebCompiledContentExtension> compiledContentExtension = WebCompiledContentExtension::create(WTF::move(contentExtensionData));
m_userContentController->addUserContentExtension(userContentExtension.first, compiledContentExtension);
}
}
void WebUserContentController::removeUserContentExtension(const String& name)
{
m_userContentController->removeUserContentExtension(name);
}
void WebUserContentController::removeAllUserContentExtensions()
{
m_userContentController->removeAllUserContentExtensions();
}
#endif
}