3ef76350131ae6dfcc2463c39bfc6def891e4ca7
[WebKit-https.git] / WebKit / gtk / WebView / webkitwebframe.cpp
1 /*
2  * Copyright (C) 2007 Holger Hans Peter Freyther
3  * Copyright (C) 2007 Alp Toker <alp@atoker.com>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer. 
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution. 
14  * 3.  Neither the name of Apple, Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission. 
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31 #include "webkitwebframe.h"
32 #include "webkitwebview.h"
33 #include "webkitprivate.h"
34
35 #include "CString.h"
36 #include "FrameLoader.h"
37 #include "FrameLoaderClientGtk.h"
38 #include "FrameTree.h"
39 #include "FrameView.h"
40 #include "HTMLFrameOwnerElement.h"
41 #include "kjs_binding.h"
42 #include "kjs_proxy.h"
43 #include "kjs_window.h"
44
45 #include <JavaScriptCore/APICast.h>
46
47 using namespace WebKit;
48 using namespace WebCore;
49
50 extern "C" {
51
52 extern void webkit_marshal_VOID__STRING_STRING (GClosure*     closure,
53                                                 GValue*       return_value,
54                                                 guint         n_param_values,
55                                                 const GValue* param_values,
56                                                 gpointer      invocation_hint,
57                                                 gpointer      marshal_data);
58
59 enum {
60     CLEARED,
61     LOAD_DONE,
62     TITLE_CHANGED,
63     HOVERING_OVER_LINK,
64     LAST_SIGNAL
65 };
66
67 static guint webkit_web_frame_signals[LAST_SIGNAL] = { 0, };
68
69 static void webkit_web_frame_real_title_changed(WebKitWebFrame* frame, gchar* title, gchar* location);
70
71 G_DEFINE_TYPE(WebKitWebFrame, webkit_web_frame, G_TYPE_OBJECT)
72
73 static void webkit_web_frame_finalize(GObject* object)
74 {
75     WebKitWebFramePrivate* privateData = WEBKIT_WEB_FRAME_GET_PRIVATE(WEBKIT_WEB_FRAME(object));
76     privateData->frame->loader()->cancelAndClear();
77     g_free(privateData->name);
78     g_free(privateData->title);
79     g_free(privateData->location);
80     delete privateData->frame;
81
82     G_OBJECT_CLASS(webkit_web_frame_parent_class)->finalize(object);
83 }
84
85 static void webkit_web_frame_class_init(WebKitWebFrameClass* frameClass)
86 {
87     g_type_class_add_private(frameClass, sizeof(WebKitWebFramePrivate));
88
89     /*
90      * signals
91      */
92     webkit_web_frame_signals[CLEARED] = g_signal_new("cleared",
93             G_TYPE_FROM_CLASS(frameClass),
94             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
95             0,
96             NULL,
97             NULL,
98             g_cclosure_marshal_VOID__VOID,
99             G_TYPE_NONE, 0);
100
101     webkit_web_frame_signals[LOAD_DONE] = g_signal_new("load_done",
102             G_TYPE_FROM_CLASS(frameClass),
103             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
104             0,
105             NULL,
106             NULL,
107             g_cclosure_marshal_VOID__BOOLEAN,
108             G_TYPE_NONE, 1,
109             G_TYPE_BOOLEAN);
110
111     webkit_web_frame_signals[TITLE_CHANGED] = g_signal_new("title_changed",
112             G_TYPE_FROM_CLASS(frameClass),
113             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
114             G_STRUCT_OFFSET(WebKitWebFrameClass, title_changed),
115             NULL,
116             NULL,
117             webkit_marshal_VOID__STRING_STRING,
118             G_TYPE_NONE, 2,
119             G_TYPE_STRING, G_TYPE_STRING);
120
121     webkit_web_frame_signals[HOVERING_OVER_LINK] = g_signal_new("hovering_over_link",
122             G_TYPE_FROM_CLASS(frameClass),
123             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
124             0,
125             NULL,
126             NULL,
127             webkit_marshal_VOID__STRING_STRING,
128             G_TYPE_NONE, 2,
129             G_TYPE_STRING, G_TYPE_STRING);
130
131     frameClass->title_changed = webkit_web_frame_real_title_changed;
132
133     /*
134      * implementations of virtual methods
135      */
136     G_OBJECT_CLASS(frameClass)->finalize = webkit_web_frame_finalize;
137 }
138
139 static void webkit_web_frame_real_title_changed(WebKitWebFrame* frame, gchar* title, gchar* location)
140 {
141     WebKitWebFramePrivate* frameData = WEBKIT_WEB_FRAME_GET_PRIVATE(frame);
142     g_free(frameData->title);
143     g_free(frameData->location);
144     frameData->title = g_strdup(title);
145     frameData->location = g_strdup(location);
146 }
147
148 static void webkit_web_frame_init(WebKitWebFrame* frame)
149 {
150     // TODO: Move constructor code here.
151 }
152
153 /**
154  * webkit_web_frame_new:
155  * @web_view: the controlling #WebKitWebView
156  *
157  * Creates a new #WebKitWebFrame initialized with a controlling #WebKitWebView.
158  *
159  * Returns: a new #WebKitWebFrame
160  **/
161 WebKitWebFrame* webkit_web_frame_new(WebKitWebView* webView)
162 {
163     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL);
164
165     WebKitWebFrame* frame = WEBKIT_WEB_FRAME(g_object_new(WEBKIT_TYPE_WEB_FRAME, NULL));
166     WebKitWebFramePrivate* frameData = WEBKIT_WEB_FRAME_GET_PRIVATE(frame);
167     WebKitWebViewPrivate* webViewData = WEBKIT_WEB_VIEW_GET_PRIVATE(webView);
168
169     frameData->client = new WebKit::FrameLoaderClient(frame);
170     frameData->frame = new Frame(webViewData->corePage, 0, frameData->client);
171
172     FrameView* frameView = new FrameView(frameData->frame);
173     frameView->setContainingWindow(GTK_CONTAINER(webView));
174     frameView->setGtkAdjustments(GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)),
175                                  GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)));
176     frameData->frame->setView(frameView);
177     frameData->frame->init();
178     frameData->webView = webView;
179     frameData->name = 0;
180     frameData->title = 0;
181     frameData->location = 0;
182
183     return frame;
184 }
185
186 WebKitWebFrame* webkit_web_frame_init_with_web_view(WebKitWebView* webView, HTMLFrameOwnerElement* element)
187 {
188     WebKitWebFrame* frame = WEBKIT_WEB_FRAME(g_object_new(WEBKIT_TYPE_WEB_FRAME, NULL));
189     WebKitWebFramePrivate* frameData = WEBKIT_WEB_FRAME_GET_PRIVATE(frame);
190     WebKitWebViewPrivate* webViewData = WEBKIT_WEB_VIEW_GET_PRIVATE(webView);
191
192     frameData->client = new WebKit::FrameLoaderClient(frame);
193     frameData->frame = new Frame(webViewData->corePage, element, frameData->client);
194
195     FrameView* frameView = new FrameView(frameData->frame);
196     frameView->setContainingWindow(GTK_CONTAINER(webView));
197     frameData->frame->setView(frameView);
198     frameView->deref();
199     frameData->frame->init();
200     frameData->webView = webView;
201
202     return frame;
203 }
204
205 const gchar* webkit_web_frame_get_title(WebKitWebFrame* frame)
206 {
207     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL);
208
209     WebKitWebFramePrivate* frameData = WEBKIT_WEB_FRAME_GET_PRIVATE(frame);
210     return frameData->title;
211 }
212
213 const gchar* webkit_web_frame_get_location(WebKitWebFrame* frame)
214 {
215     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL);
216
217     WebKitWebFramePrivate* frameData = WEBKIT_WEB_FRAME_GET_PRIVATE(frame);
218     return frameData->location;
219 }
220
221 /**
222  * webkit_web_frame_get_web_view:
223  * @frame: a #WebKitWebFrame
224  *
225  * Returns the #WebKitWebView that manages this #WebKitWebFrame.
226  *
227  * The #WebKitWebView returned manages the entire hierarchy of #WebKitWebFrame
228  * objects that contains @frame.
229  *
230  * Return value: the #WebKitWebView that manages @frame
231  */
232 WebKitWebView* webkit_web_frame_get_web_view(WebKitWebFrame* frame)
233 {
234     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL);
235
236     WebKitWebFramePrivate* frameData = WEBKIT_WEB_FRAME_GET_PRIVATE(frame);
237     return frameData->webView;
238 }
239
240 /**
241  * webkit_web_frame_get_name:
242  * @frame: a #WebKitWebFrame
243  *
244  * Returns the @frame's name
245  *
246  * Return value: the name of @frame
247  */
248 const gchar* webkit_web_frame_get_name(WebKitWebFrame* frame)
249 {
250     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL);
251
252     WebKitWebFramePrivate* frameData = WEBKIT_WEB_FRAME_GET_PRIVATE(frame);
253
254     if (frameData->name)
255         return frameData->name;
256
257     Frame* coreFrame = core(frame);
258     g_return_val_if_fail(coreFrame, NULL);
259
260     String string = coreFrame->tree()->name();
261     frameData->name = g_strdup(string.utf8().data());
262
263     return frameData->name;
264 }
265
266 /**
267  * webkit_web_frame_get_parent:
268  * @frame: a #WebKitWebFrame
269  *
270  * Returns the @frame's parent frame, or %NULL if it has none.
271  *
272  * Return value: the parent #WebKitWebFrame or %NULL in case there is none
273  */
274 WebKitWebFrame* webkit_web_frame_get_parent(WebKitWebFrame* frame)
275 {
276     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL);
277
278     Frame* coreFrame = core(frame);
279     g_return_val_if_fail(coreFrame, NULL);
280
281     return kit(coreFrame->tree()->parent());
282 }
283
284 /**
285  * webkit_web_frame_load_request:
286  * @frame: a #WebKitWebFrame
287  * @request: a #WebKitNetworkRequest
288  *
289  * Connects to a given URI by initiating an asynchronous client request.
290  *
291  * Creates a provisional data source that will transition to a committed data
292  * source once any data has been received. Use webkit_web_frame_stop_loading() to
293  * stop the load. This function is typically invoked on the main frame.
294  */
295 void webkit_web_frame_load_request(WebKitWebFrame* frame, WebKitNetworkRequest* request)
296 {
297     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
298     g_return_if_fail(WEBKIT_IS_NETWORK_REQUEST(request));
299
300     Frame* coreFrame = core(frame);
301     g_return_if_fail(coreFrame);
302
303     // TODO: Use the ResourceRequest carried by WebKitNetworkRequest when it gets implemented.
304     DeprecatedString string = DeprecatedString::fromUtf8(webkit_network_request_get_uri(request));
305     coreFrame->loader()->load(ResourceRequest(KURL(string)));
306 }
307
308 /**
309  * webkit_web_frame_stop_loading:
310  * @frame: a #WebKitWebFrame
311  *
312  * Stops any pending loads on @frame's data source, and those of its children.
313  */
314 void webkit_web_frame_stop_loading(WebKitWebFrame* frame)
315 {
316     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
317
318     Frame* coreFrame = core(frame);
319     g_return_if_fail(coreFrame);
320
321     coreFrame->loader()->stopAllLoaders();
322 }
323
324 /**
325  * webkit_web_frame_reload:
326  * @frame: a #WebKitWebFrame
327  *
328  * Reloads the initial request.
329  */
330 void webkit_web_frame_reload(WebKitWebFrame* frame)
331 {
332     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
333
334     Frame* coreFrame = core(frame);
335     g_return_if_fail(coreFrame);
336
337     coreFrame->loader()->reload();
338 }
339
340 /**
341  * webkit_web_frame_find_frame:
342  * @frame: a #WebKitWebFrame
343  * @name: the name of the frame to be found
344  *
345  * For pre-defined names, returns @frame if @name is "_self" or "_current",
346  * returns @frame's parent frame if @name is "_parent", and returns the main
347  * frame if @name is "_top". Also returns @frame if it is the main frame and
348  * @name is either "_parent" or "_top". For other names, this function returns
349  * the first frame that matches @name. This function searches @frame and its
350  * descendents first, then @frame's parent and its children moving up the
351  * hierarchy until a match is found. If no match is found in @frame's
352  * hierarchy, this function will search for a matching frame in other main
353  * frame hierarchies. Returns %NULL if no match is found.
354  *
355  * Return value: the found #WebKitWebFrame or %NULL in case none is found
356  */
357 WebKitWebFrame* webkit_web_frame_find_frame(WebKitWebFrame* frame, const gchar* name)
358 {
359     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL);
360     g_return_val_if_fail(name, NULL);
361
362     Frame* coreFrame = core(frame);
363     g_return_val_if_fail(coreFrame, NULL);
364
365     String nameString = String::fromUTF8(name);
366     return kit(coreFrame->tree()->find(AtomicString(nameString)));
367 }
368
369 /**
370  * webkit_web_frame_get_global_context:
371  * @frame: a #WebKitWebFrame
372  *
373  * Gets the global JavaScript execution context. Use this function to bridge
374  * between the WebKit and JavaScriptCore APIs.
375  *
376  * Return value: the global JavaScript context
377  */
378 JSGlobalContextRef webkit_web_frame_get_global_context(WebKitWebFrame* frame)
379 {
380     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL);
381
382     Frame* coreFrame = core(frame);
383     g_return_val_if_fail(coreFrame, NULL);
384
385     return toGlobalRef(coreFrame->scriptProxy()->globalObject()->globalExec());
386 }
387
388 }