1/* 2 * Copyright (C) 2013 Igalia S.L. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2,1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public License 15 * along with this library; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 */ 19 20#include "config.h" 21#include "WebKitScriptWorld.h" 22 23#include "WebKitMarshal.h" 24#include "WebKitPrivate.h" 25#include "WebKitScriptWorldPrivate.h" 26#include <wtf/HashMap.h> 27#include <wtf/NeverDestroyed.h> 28 29using namespace WebKit; 30using namespace WebCore; 31 32enum { 33 WINDOW_OBJECT_CLEARED, 34 35 LAST_SIGNAL 36}; 37 38typedef HashMap<InjectedBundleScriptWorld*, WebKitScriptWorld*> ScriptWorldMap; 39 40static ScriptWorldMap& scriptWorlds() 41{ 42 static NeverDestroyed<ScriptWorldMap> map; 43 return map; 44} 45 46struct _WebKitScriptWorldPrivate { 47 ~_WebKitScriptWorldPrivate() 48 { 49 ASSERT(scriptWorlds().contains(scriptWorld.get())); 50 scriptWorlds().remove(scriptWorld.get()); 51 } 52 53 RefPtr<InjectedBundleScriptWorld> scriptWorld; 54}; 55 56static guint signals[LAST_SIGNAL] = { 0, }; 57 58WEBKIT_DEFINE_TYPE(WebKitScriptWorld, webkit_script_world, G_TYPE_OBJECT) 59 60static void webkit_script_world_class_init(WebKitScriptWorldClass* klass) 61{ 62 /** 63 * WebKitScriptWorld::window-object-cleared: 64 * @world: the #WebKitScriptWorld on which the signal is emitted 65 * @page: a #WebKitWebPage 66 * @frame: the #WebKitFrame to which @world belongs 67 * 68 * Emitted when the JavaScript window object in a #WebKitScriptWorld has been 69 * cleared. This is the preferred place to set custom properties on the window 70 * object using the JavaScriptCore API. You can get the window object of @frame 71 * from the JavaScript execution context of @world that is returned by 72 * webkit_frame_get_javascript_context_for_script_world(). 73 * 74 * Since: 2.2 75 */ 76 signals[WINDOW_OBJECT_CLEARED] = g_signal_new( 77 "window-object-cleared", 78 G_TYPE_FROM_CLASS(klass), 79 G_SIGNAL_RUN_LAST, 80 0, 0, 0, 81 webkit_marshal_VOID__OBJECT_OBJECT, 82 G_TYPE_NONE, 2, 83 WEBKIT_TYPE_WEB_PAGE, 84 WEBKIT_TYPE_FRAME); 85} 86 87WebKitScriptWorld* webkitScriptWorldGet(InjectedBundleScriptWorld* scriptWorld) 88{ 89 return scriptWorlds().get(scriptWorld); 90} 91 92InjectedBundleScriptWorld* webkitScriptWorldGetInjectedBundleScriptWorld(WebKitScriptWorld* world) 93{ 94 return world->priv->scriptWorld.get(); 95} 96 97void webkitScriptWorldWindowObjectCleared(WebKitScriptWorld* world, WebKitWebPage* page, WebKitFrame* frame) 98{ 99 g_signal_emit(world, signals[WINDOW_OBJECT_CLEARED], 0, page, frame); 100} 101 102static WebKitScriptWorld* webkitScriptWorldCreate(PassRefPtr<InjectedBundleScriptWorld> scriptWorld) 103{ 104 WebKitScriptWorld* world = WEBKIT_SCRIPT_WORLD(g_object_new(WEBKIT_TYPE_SCRIPT_WORLD, NULL)); 105 world->priv->scriptWorld = scriptWorld; 106 107 ASSERT(!scriptWorlds().contains(world->priv->scriptWorld.get())); 108 scriptWorlds().add(world->priv->scriptWorld.get(), world); 109 110 return world; 111} 112 113static gpointer createDefaultScriptWorld(gpointer) 114{ 115 return webkitScriptWorldCreate(InjectedBundleScriptWorld::normalWorld()); 116} 117 118/** 119 * webkit_script_world_get_default: 120 * 121 * Get the default #WebKitScriptWorld. This is the normal script world 122 * where all scripts are executed by default. 123 * You can get the JavaScript execution context of a #WebKitScriptWorld 124 * for a given #WebKitFrame with webkit_frame_get_javascript_context_for_script_world(). 125 * 126 * Returns: (transfer none): the default #WebKitScriptWorld 127 * 128 * Since: 2.2 129 */ 130WebKitScriptWorld* webkit_script_world_get_default(void) 131{ 132 static GOnce onceInit = G_ONCE_INIT; 133 return WEBKIT_SCRIPT_WORLD(g_once(&onceInit, createDefaultScriptWorld, 0)); 134} 135 136/** 137 * webkit_script_world_new: 138 * 139 * Creates a new isolated #WebKitScriptWorld. Scripts executed in 140 * isolated worlds have access to the DOM but not to other variable 141 * or functions created by the page. 142 * You can get the JavaScript execution context of a #WebKitScriptWorld 143 * for a given #WebKitFrame with webkit_frame_get_javascript_context_for_script_world(). 144 * 145 * Returns: (transfer full): a new isolated #WebKitScriptWorld 146 * 147 * Since: 2.2 148 */ 149WebKitScriptWorld* webkit_script_world_new(void) 150{ 151 return webkitScriptWorldCreate(InjectedBundleScriptWorld::create()); 152} 153