/* * Copyright (C) 2012 Igalia S.L. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2,1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "config.h" #include "WebKitWebExtension.h" #include "ImmutableDictionary.h" #include "WKBundleAPICast.h" #include "WKBundlePage.h" #include "WebKitPrivate.h" #include "WebKitWebExtensionPrivate.h" #include "WebKitWebPagePrivate.h" #include #include #include using namespace WebKit; enum { PAGE_CREATED, LAST_SIGNAL }; typedef HashMap > WebPageMap; struct _WebKitWebExtensionPrivate { WebPageMap pages; }; static guint signals[LAST_SIGNAL] = { 0, }; WEBKIT_DEFINE_TYPE(WebKitWebExtension, webkit_web_extension, G_TYPE_OBJECT) static void webkit_web_extension_class_init(WebKitWebExtensionClass* klass) { /** * WebKitWebExtension::page-created: * @extension: the #WebKitWebExtension on which the signal is emitted * @web_page: the #WebKitWebPage created * * This signal is emitted when a new #WebKitWebPage is created in * the Web Process. */ signals[PAGE_CREATED] = g_signal_new( "page-created", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, 0, 0, 0, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, WEBKIT_TYPE_WEB_PAGE); } static void webkitWebExtensionPageCreated(WebKitWebExtension* extension, WebPage* page) { GRefPtr webPage = adoptGRef(webkitWebPageCreate(page)); extension->priv->pages.add(page, webPage); g_signal_emit(extension, signals[PAGE_CREATED], 0, webPage.get()); } static void webkitWebExtensionPageDestroy(WebKitWebExtension* extension, WebPage* page) { extension->priv->pages.remove(page); } static void webkitWebExtensionDidReceiveMessage(WebKitWebExtension* extension, const String& messageName, ImmutableDictionary& message) { if (messageName == String::fromUTF8("PrefetchDNS")) { WebString* hostname = static_cast(message.get(String::fromUTF8("Hostname"))); WebCore::prefetchDNS(hostname->string()); } else ASSERT_NOT_REACHED(); } static void didCreatePage(WKBundleRef bundle, WKBundlePageRef page, const void* clientInfo) { webkitWebExtensionPageCreated(WEBKIT_WEB_EXTENSION(clientInfo), toImpl(page)); } static void willDestroyPage(WKBundleRef bundle, WKBundlePageRef page, const void* clientInfo) { webkitWebExtensionPageDestroy(WEBKIT_WEB_EXTENSION(clientInfo), toImpl(page)); } static void didReceiveMessage(WKBundleRef bundle, WKStringRef name, WKTypeRef messageBody, const void* clientInfo) { ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); webkitWebExtensionDidReceiveMessage(WEBKIT_WEB_EXTENSION(clientInfo), toImpl(name)->string(), *toImpl(static_cast(messageBody))); } static void didReceiveMessageToPage(WKBundleRef bundle, WKBundlePageRef page, WKStringRef name, WKTypeRef messageBody, const void* clientInfo) { ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); if (WebKitWebPage* webPage = WEBKIT_WEB_EXTENSION(clientInfo)->priv->pages.get(toImpl(page)).get()) webkitWebPageDidReceiveMessage(webPage, toImpl(name)->string(), *toImpl(static_cast(messageBody))); } WebKitWebExtension* webkitWebExtensionCreate(InjectedBundle* bundle) { WebKitWebExtension* extension = WEBKIT_WEB_EXTENSION(g_object_new(WEBKIT_TYPE_WEB_EXTENSION, NULL)); WKBundleClient wkBundleClient = { kWKBundleClientCurrentVersion, extension, // clientInfo didCreatePage, willDestroyPage, 0, // didInitializePageGroup didReceiveMessage, didReceiveMessageToPage }; WKBundleSetClient(toAPI(bundle), &wkBundleClient); return extension; } /** * webkit_web_extension_get_page: * @extension: a #WebKitWebExtension * @page_id: the identifier of the #WebKitWebPage to get * * Get the web page of the given @page_id. * * Returns: (transfer none): the #WebKitWebPage for the given @page_id, or %NULL if the * identifier doesn't correspond to an exsiting web page. */ WebKitWebPage* webkit_web_extension_get_page(WebKitWebExtension* extension, guint64 pageID) { g_return_val_if_fail(WEBKIT_IS_WEB_EXTENSION(extension), 0); WebKitWebExtensionPrivate* priv = extension->priv; WebPageMap::const_iterator end = priv->pages.end(); for (WebPageMap::const_iterator it = priv->pages.begin(); it != end; ++it) if (it->key->pageID() == pageID) return it->value.get(); return 0; }