1/* 2 * Copyright (C) 2014 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "WebUserContentController.h" 28 29#include "DataReference.h" 30#include "WebFrame.h" 31#include "WebPage.h" 32#include "WebProcess.h" 33#include "WebUserContentControllerMessages.h" 34#include "WebUserContentControllerProxyMessages.h" 35#include <WebCore/DOMWrapperWorld.h> 36#include <WebCore/ScriptController.h> 37#include <WebCore/SerializedScriptValue.h> 38#include <WebCore/UserStyleSheet.h> 39#include <wtf/NeverDestroyed.h> 40 41#if ENABLE(USER_MESSAGE_HANDLERS) 42#include <WebCore/UserMessageHandler.h> 43#include <WebCore/UserMessageHandlerDescriptor.h> 44#endif 45 46using namespace WebCore; 47 48namespace WebKit { 49 50static HashMap<uint64_t, WebUserContentController*>& userContentControllers() 51{ 52 static NeverDestroyed<HashMap<uint64_t, WebUserContentController*>> userContentControllers; 53 54 return userContentControllers; 55} 56 57PassRefPtr<WebUserContentController> WebUserContentController::getOrCreate(uint64_t identifier) 58{ 59 auto& userContentControllerPtr = userContentControllers().add(identifier, nullptr).iterator->value; 60 if (userContentControllerPtr) 61 return userContentControllerPtr; 62 63 RefPtr<WebUserContentController> userContentController = adoptRef(new WebUserContentController(identifier)); 64 userContentControllerPtr = userContentController.get(); 65 66 return userContentController.release(); 67} 68 69WebUserContentController::WebUserContentController(uint64_t identifier) 70 : m_identifier(identifier) 71 , m_userContentController(*UserContentController::create()) 72{ 73 WebProcess::shared().addMessageReceiver(Messages::WebUserContentController::messageReceiverName(), m_identifier, *this); 74} 75 76WebUserContentController::~WebUserContentController() 77{ 78 ASSERT(userContentControllers().contains(m_identifier)); 79 80 WebProcess::shared().removeMessageReceiver(Messages::WebUserContentController::messageReceiverName(), m_identifier); 81 82 userContentControllers().remove(m_identifier); 83} 84 85void WebUserContentController::addUserScripts(const Vector<WebCore::UserScript>& userScripts) 86{ 87 for (const auto& userScript : userScripts) 88 m_userContentController->addUserScript(mainThreadNormalWorld(), std::make_unique<WebCore::UserScript>(userScript)); 89} 90 91void WebUserContentController::removeAllUserScripts() 92{ 93 m_userContentController->removeUserScripts(mainThreadNormalWorld()); 94} 95 96void WebUserContentController::addUserStyleSheets(const Vector<WebCore::UserStyleSheet>& userStyleSheets) 97{ 98 for (const auto& userStyleSheet : userStyleSheets) { 99 m_userContentController->addUserStyleSheet(mainThreadNormalWorld(), 100 std::make_unique<WebCore::UserStyleSheet>(userStyleSheet), InjectInExistingDocuments); 101 } 102} 103 104void WebUserContentController::removeAllUserStyleSheets() 105{ 106 m_userContentController->removeUserStyleSheets(mainThreadNormalWorld()); 107} 108 109#if ENABLE(USER_MESSAGE_HANDLERS) 110class WebUserMessageHandlerDescriptorProxy : public RefCounted<WebUserMessageHandlerDescriptorProxy>, public WebCore::UserMessageHandlerDescriptor::Client { 111public: 112 static PassRefPtr<WebUserMessageHandlerDescriptorProxy> create(WebUserContentController* controller, const String& name, uint64_t identifier) 113 { 114 return adoptRef(new WebUserMessageHandlerDescriptorProxy(controller, name, identifier)); 115 } 116 117 virtual ~WebUserMessageHandlerDescriptorProxy() 118 { 119 } 120 121 // WebCore::UserMessageHandlerDescriptor::Client 122 virtual void didPostMessage(WebCore::UserMessageHandler& handler, WebCore::SerializedScriptValue* value) 123 { 124 WebCore::Frame* frame = handler.frame(); 125 if (!frame) 126 return; 127 128 WebFrame* webFrame = WebFrame::fromCoreFrame(*frame); 129 if (!webFrame) 130 return; 131 132 WebPage* webPage = webFrame->page(); 133 if (!webPage) 134 return; 135 136 WebProcess::shared().parentProcessConnection()->send(Messages::WebUserContentControllerProxy::DidPostMessage(webPage->pageID(), webFrame->frameID(), m_identifier, IPC::DataReference(value->data())), m_controller->identifier()); 137 } 138 139 WebCore::UserMessageHandlerDescriptor& descriptor() { return *m_descriptor; } 140 uint64_t identifier() { return m_identifier; } 141 142private: 143 WebUserMessageHandlerDescriptorProxy(WebUserContentController* controller, const String& name, uint64_t identifier) 144 : m_controller(controller) 145 , m_descriptor(UserMessageHandlerDescriptor::create(name, mainThreadNormalWorld(), *this)) 146 , m_identifier(identifier) 147 { 148 } 149 150 RefPtr<WebUserContentController> m_controller; 151 RefPtr<WebCore::UserMessageHandlerDescriptor> m_descriptor; 152 uint64_t m_identifier; 153}; 154#endif 155 156void WebUserContentController::addUserScriptMessageHandlers(const Vector<WebScriptMessageHandlerHandle>& scriptMessageHandlers) 157{ 158#if ENABLE(USER_MESSAGE_HANDLERS) 159 for (auto& handle : scriptMessageHandlers) { 160 RefPtr<WebUserMessageHandlerDescriptorProxy> descriptor = WebUserMessageHandlerDescriptorProxy::create(this, handle.name, handle.identifier); 161 162 m_userMessageHandlerDescriptors.add(descriptor->identifier(), descriptor); 163 m_userContentController->addUserMessageHandlerDescriptor(descriptor->descriptor()); 164 } 165#else 166 UNUSED_PARAM(scriptMessageHandlers); 167#endif 168} 169 170void WebUserContentController::removeUserScriptMessageHandler(uint64_t identifier) 171{ 172#if ENABLE(USER_MESSAGE_HANDLERS) 173 auto it = m_userMessageHandlerDescriptors.find(identifier); 174 ASSERT(it != m_userMessageHandlerDescriptors.end()); 175 176 m_userContentController->removeUserMessageHandlerDescriptor(it->value->descriptor()); 177 m_userMessageHandlerDescriptors.remove(it); 178#else 179 UNUSED_PARAM(identifier); 180#endif 181} 182 183} // namespace WebKit 184