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 "WebKitFrame.h"
22
23#include "WebKitDOMNodePrivate.h"
24#include "WebKitFramePrivate.h"
25#include "WebKitScriptWorldPrivate.h"
26#include <JavaScriptCore/JSLock.h>
27#include <WebCore/Frame.h>
28#include <WebCore/JSNode.h>
29#include <WebCore/ScriptController.h>
30#include <jsc/JSCContextPrivate.h>
31#include <wtf/glib/WTFGType.h>
32#include <wtf/text/CString.h>
33
34using namespace WebKit;
35using namespace WebCore;
36
37struct _WebKitFramePrivate {
38 RefPtr<WebFrame> webFrame;
39
40 CString uri;
41};
42
43WEBKIT_DEFINE_TYPE(WebKitFrame, webkit_frame, G_TYPE_OBJECT)
44
45static void webkit_frame_class_init(WebKitFrameClass*)
46{
47}
48
49WebKitFrame* webkitFrameCreate(WebFrame* webFrame)
50{
51 WebKitFrame* frame = WEBKIT_FRAME(g_object_new(WEBKIT_TYPE_FRAME, NULL));
52 frame->priv->webFrame = webFrame;
53 return frame;
54}
55
56WebFrame* webkitFrameGetWebFrame(WebKitFrame* frame)
57{
58 return frame->priv->webFrame.get();
59}
60
61/**
62 * webkit_frame_get_id:
63 * @frame: a #WebKitFrame
64 *
65 * Gets the process-unique identifier of this #WebKitFrame. No other
66 * frame in the same web process will have the same ID; however, frames
67 * in other web processes may.
68 *
69 * Returns: the identifier of @frame
70 *
71 * Since: 2.26
72 */
73guint64 webkit_frame_get_id(WebKitFrame* frame)
74{
75 g_return_val_if_fail(WEBKIT_IS_FRAME(frame), 0);
76
77 return frame->priv->webFrame->frameID();
78}
79
80/**
81 * webkit_frame_is_main_frame:
82 * @frame: a #WebKitFrame
83 *
84 * Gets whether @frame is the main frame of a #WebKitWebPage
85 *
86 * Returns: %TRUE if @frame is a main frame or %FALSE otherwise
87 *
88 * Since: 2.2
89 */
90gboolean webkit_frame_is_main_frame(WebKitFrame* frame)
91{
92 g_return_val_if_fail(WEBKIT_IS_FRAME(frame), FALSE);
93
94 return frame->priv->webFrame->isMainFrame();
95}
96
97/**
98 * webkit_frame_get_uri:
99 * @frame: a #WebKitFrame
100 *
101 * Gets the current active URI of @frame.
102 *
103 * Returns: the current active URI of @frame or %NULL if nothing has been
104 * loaded yet.
105 *
106 * Since: 2.2
107 */
108const gchar* webkit_frame_get_uri(WebKitFrame* frame)
109{
110 g_return_val_if_fail(WEBKIT_IS_FRAME(frame), 0);
111
112 if (frame->priv->uri.isNull())
113 frame->priv->uri = frame->priv->webFrame->url().string().utf8();
114
115 return frame->priv->uri.data();
116}
117
118#if PLATFORM(GTK)
119/**
120 * webkit_frame_get_javascript_global_context: (skip)
121 * @frame: a #WebKitFrame
122 *
123 * Gets the global JavaScript execution context. Use this function to bridge
124 * between the WebKit and JavaScriptCore APIs.
125 *
126 * Returns: (transfer none): the global JavaScript context of @frame
127 *
128 * Since: 2.2
129 *
130 * Deprecated: 2.22: Use webkit_frame_get_js_context() instead.
131 */
132JSGlobalContextRef webkit_frame_get_javascript_global_context(WebKitFrame* frame)
133{
134 g_return_val_if_fail(WEBKIT_IS_FRAME(frame), 0);
135
136 return frame->priv->webFrame->jsContext();
137}
138
139/**
140 * webkit_frame_get_javascript_context_for_script_world: (skip)
141 * @frame: a #WebKitFrame
142 * @world: a #WebKitScriptWorld
143 *
144 * Gets the JavaScript execution context of @frame for the given #WebKitScriptWorld.
145 *
146 * Returns: (transfer none): the JavaScript context of @frame for @world
147 *
148 * Since: 2.2
149 *
150 * Deprecated: 2.22: Use webkit_frame_get_js_context_for_script_world() instead.
151 */
152JSGlobalContextRef webkit_frame_get_javascript_context_for_script_world(WebKitFrame* frame, WebKitScriptWorld* world)
153{
154 g_return_val_if_fail(WEBKIT_IS_FRAME(frame), 0);
155 g_return_val_if_fail(WEBKIT_IS_SCRIPT_WORLD(world), 0);
156
157 return frame->priv->webFrame->jsContextForWorld(webkitScriptWorldGetInjectedBundleScriptWorld(world));
158}
159#endif
160
161/**
162 * webkit_frame_get_js_context:
163 * @frame: a #WebKitFrame
164 *
165 * Get the JavaScript execution context of @frame. Use this function to bridge
166 * between the WebKit and JavaScriptCore APIs.
167 *
168 * Returns: (transfer full): the #JSCContext for the JavaScript execution context of @frame.
169 *
170 * Since: 2.22
171 */
172JSCContext* webkit_frame_get_js_context(WebKitFrame* frame)
173{
174 g_return_val_if_fail(WEBKIT_IS_FRAME(frame), nullptr);
175
176 return jscContextGetOrCreate(frame->priv->webFrame->jsContext()).leakRef();
177}
178
179/**
180 * webkit_frame_get_js_context_for_script_world:
181 * @frame: a #WebKitFrame
182 * @world: a #WebKitScriptWorld
183 *
184 * Get the JavaScript execution context of @frame for the given #WebKitScriptWorld.
185 *
186 * Returns: (transfer full): the #JSCContext for the JavaScript execution context of @frame for @world.
187 *
188 * Since: 2.22
189 */
190JSCContext* webkit_frame_get_js_context_for_script_world(WebKitFrame* frame, WebKitScriptWorld* world)
191{
192 g_return_val_if_fail(WEBKIT_IS_FRAME(frame), nullptr);
193 g_return_val_if_fail(WEBKIT_IS_SCRIPT_WORLD(world), nullptr);
194
195 return jscContextGetOrCreate(frame->priv->webFrame->jsContextForWorld(webkitScriptWorldGetInjectedBundleScriptWorld(world))).leakRef();
196}
197
198/**
199 * webkit_frame_get_js_value_for_dom_object:
200 * @frame: a #WebKitFrame
201 * @dom_object: a #WebKitDOMObject
202 *
203 * Get a #JSCValue referencing the given DOM object. The value is created in the JavaScript execution
204 * context of @frame.
205 *
206 * Returns: (transfer full): the #JSCValue referencing @dom_object.
207 *
208 * Since: 2.22
209 */
210JSCValue* webkit_frame_get_js_value_for_dom_object(WebKitFrame* frame, WebKitDOMObject* domObject)
211{
212 return webkit_frame_get_js_value_for_dom_object_in_script_world(frame, domObject, webkit_script_world_get_default());
213}
214
215/**
216 * webkit_frame_get_js_value_for_dom_object_in_script_world:
217 * @frame: a #WebKitFrame
218 * @dom_object: a #WebKitDOMObject
219 * @world: a #WebKitScriptWorld
220 *
221 * Get a #JSCValue referencing the given DOM object. The value is created in the JavaScript execution
222 * context of @frame for the given #WebKitScriptWorld.
223 *
224 * Returns: (transfer full): the #JSCValue referencing @dom_object
225 *
226 * Since: 2.22
227 */
228JSCValue* webkit_frame_get_js_value_for_dom_object_in_script_world(WebKitFrame* frame, WebKitDOMObject* domObject, WebKitScriptWorld* world)
229{
230 g_return_val_if_fail(WEBKIT_IS_FRAME(frame), nullptr);
231 g_return_val_if_fail(WEBKIT_DOM_IS_OBJECT(domObject), nullptr);
232 g_return_val_if_fail(WEBKIT_IS_SCRIPT_WORLD(world), nullptr);
233
234 auto* wkWorld = webkitScriptWorldGetInjectedBundleScriptWorld(world);
235 auto jsContext = jscContextGetOrCreate(frame->priv->webFrame->jsContextForWorld(wkWorld));
236 JSDOMWindow* globalObject = frame->priv->webFrame->coreFrame()->script().globalObject(wkWorld->coreWorld());
237 JSC::ExecState* exec = globalObject->globalExec();
238 JSValueRef jsValue = nullptr;
239 {
240 JSC::JSLockHolder lock(exec);
241 if (WEBKIT_DOM_IS_NODE(domObject))
242 jsValue = toRef(exec, toJS(exec, globalObject, WebKit::core(WEBKIT_DOM_NODE(domObject))));
243 }
244
245 return jsValue ? jscContextGetOrCreateValue(jsContext.get(), jsValue).leakRef() : nullptr;
246}
247