1 /*
2 * Copyright (C) 2007, 2008 Holger Hans Peter Freyther
3 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
4 * Copyright (C) 2007 Apple Inc.
5 * Copyright (C) 2008 Christian Dywan <christian@imendio.com>
6 * Copyright (C) 2008 Collabora Ltd.
7 * Copyright (C) 2008 Nuanti Ltd.
8 * Copyright (C) 2009 Jan Alonzo <jmalonzo@gmail.com>
9 * Copyright (C) 2009 Gustavo Noronha Silva <gns@gnome.org>
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Library General Public
13 * License as published by the Free Software Foundation; either
14 * version 2 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Library General Public License for more details.
20 *
21 * You should have received a copy of the GNU Library General Public License
22 * along with this library; see the file COPYING.LIB. If not, write to
23 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 * Boston, MA 02110-1301, USA.
25 */
26
27 #include "config.h"
28 #include "webkitwebframe.h"
29
30 #include "AXObjectCache.h"
31 #include "AccessibilityObjectWrapperAtk.h"
32 #include "AnimationController.h"
33 #include "DOMObjectCache.h"
34 #include "DocumentLoader.h"
35 #include "DocumentLoaderGtk.h"
36 #include "FrameLoader.h"
37 #include "FrameLoaderClientGtk.h"
38 #include "FrameTree.h"
39 #include "FrameView.h"
40 #include "GCController.h"
41 #include "GraphicsContext.h"
42 #include "GtkVersioning.h"
43 #include "HTMLFrameOwnerElement.h"
44 #include "JSDOMBinding.h"
45 #include "JSDOMWindow.h"
46 #include "JSElement.h"
47 #include "PlatformContextCairo.h"
48 #include "PrintContext.h"
49 #include "RenderListItem.h"
50 #include "RenderTreeAsText.h"
51 #include "RenderView.h"
52 #include "ScriptController.h"
53 #include "SubstituteData.h"
54 #include "webkitenumtypes.h"
55 #include "webkitglobalsprivate.h"
56 #include "webkitmarshal.h"
57 #include "webkitnetworkrequestprivate.h"
58 #include "webkitnetworkresponseprivate.h"
59 #include "webkitsecurityoriginprivate.h"
60 #include "webkitwebframeprivate.h"
61 #include "webkitwebview.h"
62 #include "webkitwebviewprivate.h"
63 #include <JavaScriptCore/APICast.h>
64 #include <atk/atk.h>
65 #include <glib/gi18n-lib.h>
66 #include <wtf/text/CString.h>
67
68 #if ENABLE(SVG)
69 #include "SVGSMILElement.h"
70 #endif
71
72 /**
73 * SECTION:webkitwebframe
74 * @short_description: The content of a #WebKitWebView
75 *
76 * A #WebKitWebView contains a main #WebKitWebFrame. A #WebKitWebFrame
77 * contains the content of one URI. The URI and name of the frame can
78 * be retrieved, the load status and progress can be observed using the
79 * signals and can be controlled using the methods of the #WebKitWebFrame.
80 * A #WebKitWebFrame can have any number of children and one child can
81 * be found by using #webkit_web_frame_find_frame.
82 *
83 * <informalexample><programlisting>
84 * /<!-- -->* Get the frame from the #WebKitWebView *<!-- -->/
85 * WebKitWebFrame *frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW(my_view));
86 * g_print("The URI of this frame is '%s'", webkit_web_frame_get_uri (frame));
87 * </programlisting></informalexample>
88 */
89
90 using namespace WebKit;
91 using namespace WebCore;
92 using namespace std;
93
94 enum {
95 CLEARED,
96 LOAD_COMMITTED,
97 LOAD_DONE,
98 TITLE_CHANGED,
99 HOVERING_OVER_LINK,
100 SCROLLBARS_POLICY_CHANGED,
101 LAST_SIGNAL
102 };
103
104 enum {
105 PROP_0,
106
107 PROP_NAME,
108 PROP_TITLE,
109 PROP_URI,
110 PROP_LOAD_STATUS,
111 PROP_HORIZONTAL_SCROLLBAR_POLICY,
112 PROP_VERTICAL_SCROLLBAR_POLICY
113 };
114
115 static guint webkit_web_frame_signals[LAST_SIGNAL] = { 0, };
116
G_DEFINE_TYPE(WebKitWebFrame,webkit_web_frame,G_TYPE_OBJECT)117 G_DEFINE_TYPE(WebKitWebFrame, webkit_web_frame, G_TYPE_OBJECT)
118
119 static void webkit_web_frame_get_property(GObject* object, guint propertyId, GValue* value, GParamSpec* paramSpec)
120 {
121 WebKitWebFrame* frame = WEBKIT_WEB_FRAME(object);
122
123 switch (propertyId) {
124 case PROP_NAME:
125 g_value_set_string(value, webkit_web_frame_get_name(frame));
126 break;
127 case PROP_TITLE:
128 g_value_set_string(value, webkit_web_frame_get_title(frame));
129 break;
130 case PROP_URI:
131 g_value_set_string(value, webkit_web_frame_get_uri(frame));
132 break;
133 case PROP_LOAD_STATUS:
134 g_value_set_enum(value, webkit_web_frame_get_load_status(frame));
135 break;
136 case PROP_HORIZONTAL_SCROLLBAR_POLICY:
137 g_value_set_enum(value, webkit_web_frame_get_horizontal_scrollbar_policy(frame));
138 break;
139 case PROP_VERTICAL_SCROLLBAR_POLICY:
140 g_value_set_enum(value, webkit_web_frame_get_vertical_scrollbar_policy(frame));
141 break;
142 default:
143 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyId, paramSpec);
144 break;
145 }
146 }
147
148 // Called from the FrameLoaderClient when it is destroyed. Normally
149 // the unref in the FrameLoaderClient is destroying this object as
150 // well but due reference counting a user might have added a reference...
webkit_web_frame_core_frame_gone(WebKitWebFrame * frame)151 void webkit_web_frame_core_frame_gone(WebKitWebFrame* frame)
152 {
153 ASSERT(WEBKIT_IS_WEB_FRAME(frame));
154 WebKitWebFramePrivate* priv = frame->priv;
155 if (priv->coreFrame)
156 DOMObjectCache::clearByFrame(priv->coreFrame);
157 priv->coreFrame = 0;
158 }
159
webkit_web_frame_get_data_source_from_core_loader(WebCore::DocumentLoader * loader)160 static WebKitWebDataSource* webkit_web_frame_get_data_source_from_core_loader(WebCore::DocumentLoader* loader)
161 {
162 return loader ? static_cast<WebKit::DocumentLoader*>(loader)->dataSource() : 0;
163 }
164
webkit_web_frame_finalize(GObject * object)165 static void webkit_web_frame_finalize(GObject* object)
166 {
167 WebKitWebFrame* frame = WEBKIT_WEB_FRAME(object);
168 WebKitWebFramePrivate* priv = frame->priv;
169
170 if (priv->coreFrame) {
171 DOMObjectCache::clearByFrame(priv->coreFrame);
172 priv->coreFrame->loader()->cancelAndClear();
173 priv->coreFrame = 0;
174 }
175
176 g_free(priv->name);
177 g_free(priv->title);
178 g_free(priv->uri);
179
180 G_OBJECT_CLASS(webkit_web_frame_parent_class)->finalize(object);
181 }
182
webkit_web_frame_class_init(WebKitWebFrameClass * frameClass)183 static void webkit_web_frame_class_init(WebKitWebFrameClass* frameClass)
184 {
185 webkitInit();
186
187 /*
188 * signals
189 */
190 webkit_web_frame_signals[CLEARED] = g_signal_new("cleared",
191 G_TYPE_FROM_CLASS(frameClass),
192 (GSignalFlags)G_SIGNAL_RUN_LAST,
193 0,
194 0,
195 0,
196 g_cclosure_marshal_VOID__VOID,
197 G_TYPE_NONE, 0);
198
199 /**
200 * WebKitWebFrame::load-done
201 * @web_frame: the object on which the signal is emitted
202 *
203 * Emitted when frame loading is done.
204 *
205 * Deprecated: Use the "load-status" property instead.
206 */
207 webkit_web_frame_signals[LOAD_COMMITTED] = g_signal_new("load-committed",
208 G_TYPE_FROM_CLASS(frameClass),
209 (GSignalFlags)G_SIGNAL_RUN_LAST,
210 0,
211 0,
212 0,
213 g_cclosure_marshal_VOID__VOID,
214 G_TYPE_NONE, 0);
215
216 /**
217 * WebKitWebFrame::load-done
218 * @web_frame: the object on which the signal is emitted
219 *
220 * Emitted when frame loading is done.
221 *
222 * Deprecated: Use the "load-status" property instead, and/or
223 * WebKitWebView::load-error to be notified of load errors
224 */
225 webkit_web_frame_signals[LOAD_DONE] = g_signal_new("load-done",
226 G_TYPE_FROM_CLASS(frameClass),
227 (GSignalFlags)G_SIGNAL_RUN_LAST,
228 0,
229 0,
230 0,
231 g_cclosure_marshal_VOID__BOOLEAN,
232 G_TYPE_NONE, 1,
233 G_TYPE_BOOLEAN);
234
235 /**
236 * WebKitWebFrame::title-changed:
237 * @frame: the object on which the signal is emitted
238 * @title: the new title
239 *
240 * When a #WebKitWebFrame changes the document title this signal is emitted.
241 *
242 * Deprecated: 1.1.18: Use "notify::title" instead.
243 */
244 webkit_web_frame_signals[TITLE_CHANGED] = g_signal_new("title-changed",
245 G_TYPE_FROM_CLASS(frameClass),
246 (GSignalFlags)G_SIGNAL_RUN_LAST,
247 0,
248 0,
249 0,
250 webkit_marshal_VOID__STRING,
251 G_TYPE_NONE, 1,
252 G_TYPE_STRING);
253
254 webkit_web_frame_signals[HOVERING_OVER_LINK] = g_signal_new("hovering-over-link",
255 G_TYPE_FROM_CLASS(frameClass),
256 (GSignalFlags)G_SIGNAL_RUN_LAST,
257 0,
258 0,
259 0,
260 webkit_marshal_VOID__STRING_STRING,
261 G_TYPE_NONE, 2,
262 G_TYPE_STRING, G_TYPE_STRING);
263
264 /**
265 * WebKitWebFrame::scrollbars-policy-changed:
266 * @web_view: the object which received the signal
267 *
268 * Signal emitted when policy for one or both of the scrollbars of
269 * the view has changed. The default handler will apply the new
270 * policy to the container that holds the #WebKitWebFrame if it is
271 * a #GtkScrolledWindow and the frame is the main frame. If you do
272 * not want this to be handled automatically, you need to handle
273 * this signal.
274 *
275 * The exception to this rule is that policies to disable the
276 * scrollbars are applied as %GTK_POLICY_AUTOMATIC instead, since
277 * the size request of the widget would force browser windows to
278 * not be resizable.
279 *
280 * You can obtain the new policies from the
281 * WebKitWebFrame:horizontal-scrollbar-policy and
282 * WebKitWebFrame:vertical-scrollbar-policy properties.
283 *
284 * Return value: %TRUE to stop other handlers from being invoked for the
285 * event. %FALSE to propagate the event further.
286 *
287 * Since: 1.1.14
288 */
289 webkit_web_frame_signals[SCROLLBARS_POLICY_CHANGED] = g_signal_new("scrollbars-policy-changed",
290 G_TYPE_FROM_CLASS(frameClass),
291 (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
292 0,
293 g_signal_accumulator_true_handled,
294 0,
295 webkit_marshal_BOOLEAN__VOID,
296 G_TYPE_BOOLEAN, 0);
297
298 /*
299 * implementations of virtual methods
300 */
301 GObjectClass* objectClass = G_OBJECT_CLASS(frameClass);
302 objectClass->finalize = webkit_web_frame_finalize;
303 objectClass->get_property = webkit_web_frame_get_property;
304
305 /*
306 * properties
307 */
308 g_object_class_install_property(objectClass, PROP_NAME,
309 g_param_spec_string("name",
310 _("Name"),
311 _("The name of the frame"),
312 0,
313 WEBKIT_PARAM_READABLE));
314
315 g_object_class_install_property(objectClass, PROP_TITLE,
316 g_param_spec_string("title",
317 _("Title"),
318 _("The document title of the frame"),
319 0,
320 WEBKIT_PARAM_READABLE));
321
322 g_object_class_install_property(objectClass, PROP_URI,
323 g_param_spec_string("uri",
324 _("URI"),
325 _("The current URI of the contents displayed by the frame"),
326 0,
327 WEBKIT_PARAM_READABLE));
328
329 /**
330 * WebKitWebFrame:load-status:
331 *
332 * Determines the current status of the load.
333 *
334 * Since: 1.1.7
335 */
336 g_object_class_install_property(objectClass, PROP_LOAD_STATUS,
337 g_param_spec_enum("load-status",
338 "Load Status",
339 "Determines the current status of the load",
340 WEBKIT_TYPE_LOAD_STATUS,
341 WEBKIT_LOAD_FINISHED,
342 WEBKIT_PARAM_READABLE));
343
344 /**
345 * WebKitWebFrame:horizontal-scrollbar-policy:
346 *
347 * Determines the current policy for the horizontal scrollbar of
348 * the frame. For the main frame, make sure to set the same policy
349 * on the scrollable widget containing the #WebKitWebView, unless
350 * you know what you are doing.
351 *
352 * Since: 1.1.14
353 */
354 g_object_class_install_property(objectClass, PROP_HORIZONTAL_SCROLLBAR_POLICY,
355 g_param_spec_enum("horizontal-scrollbar-policy",
356 _("Horizontal Scrollbar Policy"),
357 _("Determines the current policy for the horizontal scrollbar of the frame."),
358 GTK_TYPE_POLICY_TYPE,
359 GTK_POLICY_AUTOMATIC,
360 WEBKIT_PARAM_READABLE));
361
362 /**
363 * WebKitWebFrame:vertical-scrollbar-policy:
364 *
365 * Determines the current policy for the vertical scrollbar of
366 * the frame. For the main frame, make sure to set the same policy
367 * on the scrollable widget containing the #WebKitWebView, unless
368 * you know what you are doing.
369 *
370 * Since: 1.1.14
371 */
372 g_object_class_install_property(objectClass, PROP_VERTICAL_SCROLLBAR_POLICY,
373 g_param_spec_enum("vertical-scrollbar-policy",
374 _("Vertical Scrollbar Policy"),
375 _("Determines the current policy for the vertical scrollbar of the frame."),
376 GTK_TYPE_POLICY_TYPE,
377 GTK_POLICY_AUTOMATIC,
378 WEBKIT_PARAM_READABLE));
379
380 g_type_class_add_private(frameClass, sizeof(WebKitWebFramePrivate));
381 }
382
webkit_web_frame_init(WebKitWebFrame * frame)383 static void webkit_web_frame_init(WebKitWebFrame* frame)
384 {
385 WebKitWebFramePrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(frame, WEBKIT_TYPE_WEB_FRAME, WebKitWebFramePrivate);
386
387 // TODO: Move constructor code here.
388 frame->priv = priv;
389 }
390
391
392 /**
393 * webkit_web_frame_new:
394 * @web_view: the controlling #WebKitWebView
395 *
396 * Creates a new #WebKitWebFrame initialized with a controlling #WebKitWebView.
397 *
398 * Returns: a new #WebKitWebFrame
399 *
400 * Deprecated: 1.0.2: #WebKitWebFrame can only be used to inspect existing
401 * frames.
402 **/
webkit_web_frame_new(WebKitWebView * webView)403 WebKitWebFrame* webkit_web_frame_new(WebKitWebView* webView)
404 {
405 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
406
407 WebKitWebFrame* frame = WEBKIT_WEB_FRAME(g_object_new(WEBKIT_TYPE_WEB_FRAME, NULL));
408 WebKitWebFramePrivate* priv = frame->priv;
409 WebKitWebViewPrivate* viewPriv = webView->priv;
410
411 priv->webView = webView;
412 WebKit::FrameLoaderClient* client = new WebKit::FrameLoaderClient(frame);
413 priv->coreFrame = Frame::create(viewPriv->corePage, 0, client).get();
414 priv->coreFrame->init();
415
416 priv->origin = 0;
417
418 return frame;
419 }
420
421 /**
422 * webkit_web_frame_get_title:
423 * @frame: a #WebKitWebFrame
424 *
425 * Returns the @frame's document title
426 *
427 * Return value: the title of @frame
428 */
webkit_web_frame_get_title(WebKitWebFrame * frame)429 G_CONST_RETURN gchar* webkit_web_frame_get_title(WebKitWebFrame* frame)
430 {
431 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
432
433 WebKitWebFramePrivate* priv = frame->priv;
434 return priv->title;
435 }
436
437 /**
438 * webkit_web_frame_get_uri:
439 * @frame: a #WebKitWebFrame
440 *
441 * Returns the current URI of the contents displayed by the @frame
442 *
443 * Return value: the URI of @frame
444 */
webkit_web_frame_get_uri(WebKitWebFrame * frame)445 G_CONST_RETURN gchar* webkit_web_frame_get_uri(WebKitWebFrame* frame)
446 {
447 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
448
449 WebKitWebFramePrivate* priv = frame->priv;
450 return priv->uri;
451 }
452
453 /**
454 * webkit_web_frame_get_web_view:
455 * @frame: a #WebKitWebFrame
456 *
457 * Returns the #WebKitWebView that manages this #WebKitWebFrame.
458 *
459 * The #WebKitWebView returned manages the entire hierarchy of #WebKitWebFrame
460 * objects that contains @frame.
461 *
462 * Return value: (transfer none): the #WebKitWebView that manages @frame
463 */
webkit_web_frame_get_web_view(WebKitWebFrame * frame)464 WebKitWebView* webkit_web_frame_get_web_view(WebKitWebFrame* frame)
465 {
466 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
467
468 WebKitWebFramePrivate* priv = frame->priv;
469 return priv->webView;
470 }
471
472 /**
473 * webkit_web_frame_get_name:
474 * @frame: a #WebKitWebFrame
475 *
476 * Returns the @frame's name
477 *
478 * Return value: the name of @frame. This method will return NULL if
479 * the #WebKitWebFrame is invalid or an empty string if it is not backed
480 * by a live WebCore frame.
481 */
webkit_web_frame_get_name(WebKitWebFrame * frame)482 G_CONST_RETURN gchar* webkit_web_frame_get_name(WebKitWebFrame* frame)
483 {
484 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
485 Frame* coreFrame = core(frame);
486 if (!coreFrame)
487 return "";
488
489 WebKitWebFramePrivate* priv = frame->priv;
490 CString frameName = coreFrame->tree()->uniqueName().string().utf8();
491 if (!g_strcmp0(frameName.data(), priv->name))
492 return priv->name;
493
494 g_free(priv->name);
495 priv->name = g_strdup(frameName.data());
496 return priv->name;
497 }
498
499 /**
500 * webkit_web_frame_get_parent:
501 * @frame: a #WebKitWebFrame
502 *
503 * Returns the @frame's parent frame, or %NULL if it has none.
504 *
505 * Return value: (transfer none): the parent #WebKitWebFrame or %NULL in case there is none
506 */
webkit_web_frame_get_parent(WebKitWebFrame * frame)507 WebKitWebFrame* webkit_web_frame_get_parent(WebKitWebFrame* frame)
508 {
509 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
510
511 Frame* coreFrame = core(frame);
512 if (!coreFrame)
513 return 0;
514
515 return kit(coreFrame->tree()->parent());
516 }
517
518 /**
519 * webkit_web_frame_load_uri:
520 * @frame: a #WebKitWebFrame
521 * @uri: an URI string
522 *
523 * Requests loading of the specified URI string.
524 *
525 * Since: 1.1.1
526 */
webkit_web_frame_load_uri(WebKitWebFrame * frame,const gchar * uri)527 void webkit_web_frame_load_uri(WebKitWebFrame* frame, const gchar* uri)
528 {
529 g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
530 g_return_if_fail(uri);
531
532 Frame* coreFrame = core(frame);
533 if (!coreFrame)
534 return;
535
536 coreFrame->loader()->load(ResourceRequest(KURL(KURL(), String::fromUTF8(uri))), false);
537 }
538
webkit_web_frame_load_data(WebKitWebFrame * frame,const gchar * content,const gchar * mimeType,const gchar * encoding,const gchar * baseURL,const gchar * unreachableURL)539 static void webkit_web_frame_load_data(WebKitWebFrame* frame, const gchar* content, const gchar* mimeType, const gchar* encoding, const gchar* baseURL, const gchar* unreachableURL)
540 {
541 Frame* coreFrame = core(frame);
542 ASSERT(coreFrame);
543
544 KURL baseKURL = baseURL ? KURL(KURL(), String::fromUTF8(baseURL)) : blankURL();
545
546 ResourceRequest request(baseKURL);
547
548 RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(content, strlen(content));
549 SubstituteData substituteData(sharedBuffer.release(),
550 mimeType ? String::fromUTF8(mimeType) : String::fromUTF8("text/html"),
551 encoding ? String::fromUTF8(encoding) : String::fromUTF8("UTF-8"),
552 KURL(KURL(), String::fromUTF8(unreachableURL)),
553 KURL(KURL(), String::fromUTF8(unreachableURL)));
554
555 coreFrame->loader()->load(request, substituteData, false);
556 }
557
558 /**
559 * webkit_web_frame_load_string:
560 * @frame: a #WebKitWebFrame
561 * @content: an URI string
562 * @mime_type: the MIME type, or %NULL
563 * @encoding: the encoding, or %NULL
564 * @base_uri: the base URI for relative locations
565 *
566 * Requests loading of the given @content with the specified @mime_type,
567 * @encoding and @base_uri.
568 *
569 * If @mime_type is %NULL, "text/html" is assumed.
570 *
571 * If @encoding is %NULL, "UTF-8" is assumed.
572 *
573 * Since: 1.1.1
574 */
webkit_web_frame_load_string(WebKitWebFrame * frame,const gchar * content,const gchar * contentMimeType,const gchar * contentEncoding,const gchar * baseUri)575 void webkit_web_frame_load_string(WebKitWebFrame* frame, const gchar* content, const gchar* contentMimeType, const gchar* contentEncoding, const gchar* baseUri)
576 {
577 g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
578 g_return_if_fail(content);
579
580 webkit_web_frame_load_data(frame, content, contentMimeType, contentEncoding, baseUri, 0);
581 }
582
583 /**
584 * webkit_web_frame_load_alternate_string:
585 * @frame: a #WebKitWebFrame
586 * @content: the alternate content to display as the main page of the @frame
587 * @base_url: the base URI for relative locations
588 * @unreachable_url: the URL for the alternate page content
589 *
590 * Request loading of an alternate content for a URL that is unreachable.
591 * Using this method will preserve the back-forward list. The URI passed in
592 * @base_url has to be an absolute URI.
593 *
594 * Since: 1.1.6
595 */
webkit_web_frame_load_alternate_string(WebKitWebFrame * frame,const gchar * content,const gchar * baseURL,const gchar * unreachableURL)596 void webkit_web_frame_load_alternate_string(WebKitWebFrame* frame, const gchar* content, const gchar* baseURL, const gchar* unreachableURL)
597 {
598 g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
599 g_return_if_fail(content);
600
601 webkit_web_frame_load_data(frame, content, 0, 0, baseURL, unreachableURL);
602 }
603
604 /**
605 * webkit_web_frame_load_request:
606 * @frame: a #WebKitWebFrame
607 * @request: a #WebKitNetworkRequest
608 *
609 * Connects to a given URI by initiating an asynchronous client request.
610 *
611 * Creates a provisional data source that will transition to a committed data
612 * source once any data has been received. Use webkit_web_frame_stop_loading() to
613 * stop the load. This function is typically invoked on the main frame.
614 */
webkit_web_frame_load_request(WebKitWebFrame * frame,WebKitNetworkRequest * request)615 void webkit_web_frame_load_request(WebKitWebFrame* frame, WebKitNetworkRequest* request)
616 {
617 g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
618 g_return_if_fail(WEBKIT_IS_NETWORK_REQUEST(request));
619
620 Frame* coreFrame = core(frame);
621 if (!coreFrame)
622 return;
623
624 coreFrame->loader()->load(core(request), false);
625 }
626
627 /**
628 * webkit_web_frame_stop_loading:
629 * @frame: a #WebKitWebFrame
630 *
631 * Stops any pending loads on @frame's data source, and those of its children.
632 */
webkit_web_frame_stop_loading(WebKitWebFrame * frame)633 void webkit_web_frame_stop_loading(WebKitWebFrame* frame)
634 {
635 g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
636
637 Frame* coreFrame = core(frame);
638 if (!coreFrame)
639 return;
640
641 coreFrame->loader()->stopAllLoaders();
642 }
643
644 /**
645 * webkit_web_frame_reload:
646 * @frame: a #WebKitWebFrame
647 *
648 * Reloads the initial request.
649 */
webkit_web_frame_reload(WebKitWebFrame * frame)650 void webkit_web_frame_reload(WebKitWebFrame* frame)
651 {
652 g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
653
654 Frame* coreFrame = core(frame);
655 if (!coreFrame)
656 return;
657
658 coreFrame->loader()->reload();
659 }
660
661 /**
662 * webkit_web_frame_find_frame:
663 * @frame: a #WebKitWebFrame
664 * @name: the name of the frame to be found
665 *
666 * For pre-defined names, returns @frame if @name is "_self" or "_current",
667 * returns @frame's parent frame if @name is "_parent", and returns the main
668 * frame if @name is "_top". Also returns @frame if it is the main frame and
669 * @name is either "_parent" or "_top". For other names, this function returns
670 * the first frame that matches @name. This function searches @frame and its
671 * descendents first, then @frame's parent and its children moving up the
672 * hierarchy until a match is found. If no match is found in @frame's
673 * hierarchy, this function will search for a matching frame in other main
674 * frame hierarchies. Returns %NULL if no match is found.
675 *
676 * Return value: (transfer none): the found #WebKitWebFrame or %NULL in case none is found
677 */
webkit_web_frame_find_frame(WebKitWebFrame * frame,const gchar * name)678 WebKitWebFrame* webkit_web_frame_find_frame(WebKitWebFrame* frame, const gchar* name)
679 {
680 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
681 g_return_val_if_fail(name, 0);
682
683 Frame* coreFrame = core(frame);
684 if (!coreFrame)
685 return 0;
686
687 String nameString = String::fromUTF8(name);
688 return kit(coreFrame->tree()->find(AtomicString(nameString)));
689 }
690
691 /**
692 * webkit_web_frame_get_global_context:
693 * @frame: a #WebKitWebFrame
694 *
695 * Gets the global JavaScript execution context. Use this function to bridge
696 * between the WebKit and JavaScriptCore APIs.
697 *
698 * Return value: (transfer none): the global JavaScript context
699 */
webkit_web_frame_get_global_context(WebKitWebFrame * frame)700 JSGlobalContextRef webkit_web_frame_get_global_context(WebKitWebFrame* frame)
701 {
702 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
703
704 Frame* coreFrame = core(frame);
705 if (!coreFrame)
706 return 0;
707
708 return toGlobalRef(coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec());
709 }
710
711 /**
712 * webkit_web_frame_get_data_source:
713 * @frame: a #WebKitWebFrame
714 *
715 * Returns the committed data source.
716 *
717 * Return value: (transfer none): the committed #WebKitWebDataSource.
718 *
719 * Since: 1.1.14
720 */
webkit_web_frame_get_data_source(WebKitWebFrame * frame)721 WebKitWebDataSource* webkit_web_frame_get_data_source(WebKitWebFrame* frame)
722 {
723 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
724
725 Frame* coreFrame = core(frame);
726 return webkit_web_frame_get_data_source_from_core_loader(coreFrame->loader()->documentLoader());
727 }
728
729 /**
730 * webkit_web_frame_get_provisional_data_source:
731 * @frame: a #WebKitWebFrame
732 *
733 * You use the webkit_web_frame_load_request method to initiate a request that
734 * creates a provisional data source. The provisional data source will
735 * transition to a committed data source once any data has been received. Use
736 * webkit_web_frame_get_data_source to get the committed data source.
737 *
738 * Return value: (transfer none): the provisional #WebKitWebDataSource or %NULL if a load
739 * request is not in progress.
740 *
741 * Since: 1.1.14
742 */
webkit_web_frame_get_provisional_data_source(WebKitWebFrame * frame)743 WebKitWebDataSource* webkit_web_frame_get_provisional_data_source(WebKitWebFrame* frame)
744 {
745 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
746
747 Frame* coreFrame = core(frame);
748 return webkit_web_frame_get_data_source_from_core_loader(coreFrame->loader()->provisionalDocumentLoader());
749 }
750
begin_print_callback(GtkPrintOperation * op,GtkPrintContext * context,gpointer user_data)751 static void begin_print_callback(GtkPrintOperation* op, GtkPrintContext* context, gpointer user_data)
752 {
753 PrintContext* printContext = reinterpret_cast<PrintContext*>(user_data);
754
755 float width = gtk_print_context_get_width(context);
756 float height = gtk_print_context_get_height(context);
757 FloatRect printRect = FloatRect(0, 0, width, height);
758
759 printContext->begin(width);
760
761 // TODO: Margin adjustments and header/footer support
762 float headerHeight = 0;
763 float footerHeight = 0;
764 float pageHeight; // height of the page adjusted by margins
765 printContext->computePageRects(printRect, headerHeight, footerHeight, 1.0, pageHeight);
766 gtk_print_operation_set_n_pages(op, printContext->pageCount());
767 }
768
draw_page_callback(GtkPrintOperation *,GtkPrintContext * gtkPrintContext,gint pageNumber,PrintContext * corePrintContext)769 static void draw_page_callback(GtkPrintOperation*, GtkPrintContext* gtkPrintContext, gint pageNumber, PrintContext* corePrintContext)
770 {
771 if (pageNumber >= static_cast<gint>(corePrintContext->pageCount()))
772 return;
773
774 cairo_t* cr = gtk_print_context_get_cairo_context(gtkPrintContext);
775 float pageWidth = gtk_print_context_get_width(gtkPrintContext);
776
777 PlatformContextCairo platformContext(cr);
778 GraphicsContext graphicsContext(&platformContext);
779 corePrintContext->spoolPage(graphicsContext, pageNumber, pageWidth);
780 }
781
end_print_callback(GtkPrintOperation * op,GtkPrintContext * context,gpointer user_data)782 static void end_print_callback(GtkPrintOperation* op, GtkPrintContext* context, gpointer user_data)
783 {
784 PrintContext* printContext = reinterpret_cast<PrintContext*>(user_data);
785 printContext->end();
786 }
787
788 /**
789 * webkit_web_frame_print_full:
790 * @frame: a #WebKitWebFrame to be printed
791 * @operation: the #GtkPrintOperation to be carried
792 * @action: the #GtkPrintOperationAction to be performed
793 * @error: #GError for error return
794 *
795 * Prints the given #WebKitWebFrame, using the given #GtkPrintOperation
796 * and #GtkPrintOperationAction. This function wraps a call to
797 * gtk_print_operation_run() for printing the contents of the
798 * #WebKitWebFrame.
799 *
800 * Since: 1.1.5
801 */
webkit_web_frame_print_full(WebKitWebFrame * frame,GtkPrintOperation * operation,GtkPrintOperationAction action,GError ** error)802 GtkPrintOperationResult webkit_web_frame_print_full(WebKitWebFrame* frame, GtkPrintOperation* operation, GtkPrintOperationAction action, GError** error)
803 {
804 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), GTK_PRINT_OPERATION_RESULT_ERROR);
805 g_return_val_if_fail(GTK_IS_PRINT_OPERATION(operation), GTK_PRINT_OPERATION_RESULT_ERROR);
806
807 GtkWidget* topLevel = gtk_widget_get_toplevel(GTK_WIDGET(webkit_web_frame_get_web_view(frame)));
808
809 if (!gtk_widget_is_toplevel(topLevel))
810 topLevel = 0;
811
812 Frame* coreFrame = core(frame);
813 if (!coreFrame)
814 return GTK_PRINT_OPERATION_RESULT_ERROR;
815
816 PrintContext printContext(coreFrame);
817
818 g_signal_connect(operation, "begin-print", G_CALLBACK(begin_print_callback), &printContext);
819 g_signal_connect(operation, "draw-page", G_CALLBACK(draw_page_callback), &printContext);
820 g_signal_connect(operation, "end-print", G_CALLBACK(end_print_callback), &printContext);
821
822 return gtk_print_operation_run(operation, action, GTK_WINDOW(topLevel), error);
823 }
824
825 /**
826 * webkit_web_frame_print:
827 * @frame: a #WebKitWebFrame
828 *
829 * Prints the given #WebKitWebFrame, by presenting a print dialog to the
830 * user. If you need more control over the printing process, see
831 * webkit_web_frame_print_full().
832 *
833 * Since: 1.1.5
834 */
webkit_web_frame_print(WebKitWebFrame * frame)835 void webkit_web_frame_print(WebKitWebFrame* frame)
836 {
837 g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
838
839 WebKitWebFramePrivate* priv = frame->priv;
840 GtkPrintOperation* operation = gtk_print_operation_new();
841 GError* error = 0;
842
843 webkit_web_frame_print_full(frame, operation, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, &error);
844 g_object_unref(operation);
845
846 if (error) {
847 GtkWidget* window = gtk_widget_get_toplevel(GTK_WIDGET(priv->webView));
848 GtkWidget* dialog = gtk_message_dialog_new(gtk_widget_is_toplevel(window) ? GTK_WINDOW(window) : 0,
849 GTK_DIALOG_DESTROY_WITH_PARENT,
850 GTK_MESSAGE_ERROR,
851 GTK_BUTTONS_CLOSE,
852 "%s", error->message);
853
854 g_error_free(error);
855
856 g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL);
857 gtk_widget_show(dialog);
858 }
859 }
860
webkit_web_frame_get_response_mime_type(WebKitWebFrame * frame)861 gchar* webkit_web_frame_get_response_mime_type(WebKitWebFrame* frame)
862 {
863 Frame* coreFrame = core(frame);
864 WebCore::DocumentLoader* docLoader = coreFrame->loader()->documentLoader();
865 String mimeType = docLoader->responseMIMEType();
866 return g_strdup(mimeType.utf8().data());
867 }
868
869 /**
870 * webkit_web_frame_get_load_status:
871 * @frame: a #WebKitWebView
872 *
873 * Determines the current status of the load.
874 *
875 * Since: 1.1.7
876 */
webkit_web_frame_get_load_status(WebKitWebFrame * frame)877 WebKitLoadStatus webkit_web_frame_get_load_status(WebKitWebFrame* frame)
878 {
879 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), WEBKIT_LOAD_FINISHED);
880
881 WebKitWebFramePrivate* priv = frame->priv;
882 return priv->loadStatus;
883 }
884
webkit_web_frame_get_horizontal_scrollbar_policy(WebKitWebFrame * frame)885 GtkPolicyType webkit_web_frame_get_horizontal_scrollbar_policy(WebKitWebFrame* frame)
886 {
887 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), GTK_POLICY_AUTOMATIC);
888
889 Frame* coreFrame = core(frame);
890 FrameView* view = coreFrame->view();
891 if (!view)
892 return GTK_POLICY_AUTOMATIC;
893
894 ScrollbarMode hMode = view->horizontalScrollbarMode();
895
896 if (hMode == ScrollbarAlwaysOn)
897 return GTK_POLICY_ALWAYS;
898
899 if (hMode == ScrollbarAlwaysOff)
900 return GTK_POLICY_NEVER;
901
902 return GTK_POLICY_AUTOMATIC;
903 }
904
webkit_web_frame_get_vertical_scrollbar_policy(WebKitWebFrame * frame)905 GtkPolicyType webkit_web_frame_get_vertical_scrollbar_policy(WebKitWebFrame* frame)
906 {
907 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), GTK_POLICY_AUTOMATIC);
908
909 Frame* coreFrame = core(frame);
910 FrameView* view = coreFrame->view();
911 if (!view)
912 return GTK_POLICY_AUTOMATIC;
913
914 ScrollbarMode vMode = view->verticalScrollbarMode();
915
916 if (vMode == ScrollbarAlwaysOn)
917 return GTK_POLICY_ALWAYS;
918
919 if (vMode == ScrollbarAlwaysOff)
920 return GTK_POLICY_NEVER;
921
922 return GTK_POLICY_AUTOMATIC;
923 }
924
925 /**
926 * webkit_web_frame_get_security_origin:
927 * @frame: a #WebKitWebFrame
928 *
929 * Returns the @frame's security origin.
930 *
931 * Return value: (transfer none): the security origin of @frame
932 *
933 * Since: 1.1.14
934 */
webkit_web_frame_get_security_origin(WebKitWebFrame * frame)935 WebKitSecurityOrigin* webkit_web_frame_get_security_origin(WebKitWebFrame* frame)
936 {
937 WebKitWebFramePrivate* priv = frame->priv;
938 if (!priv->coreFrame || !priv->coreFrame->document() || !priv->coreFrame->document()->securityOrigin())
939 return 0;
940
941 if (priv->origin && priv->origin->priv->coreOrigin.get() == priv->coreFrame->document()->securityOrigin())
942 return priv->origin;
943
944 if (priv->origin)
945 g_object_unref(priv->origin);
946
947 priv->origin = kit(priv->coreFrame->document()->securityOrigin());
948 return priv->origin;
949 }
950
951 /**
952 * webkit_web_frame_get_network_response:
953 * @frame: a #WebKitWebFrame
954 *
955 * Returns a #WebKitNetworkResponse object representing the response
956 * that was given to the request for the given frame, or NULL if the
957 * frame was not created by a load. You must unref the object when you
958 * are done with it.
959 *
960 * Return value: (transfer full): a #WebKitNetworkResponse object
961 *
962 * Since: 1.1.18
963 */
webkit_web_frame_get_network_response(WebKitWebFrame * frame)964 WebKitNetworkResponse* webkit_web_frame_get_network_response(WebKitWebFrame* frame)
965 {
966 Frame* coreFrame = core(frame);
967 if (!coreFrame)
968 return 0;
969
970 WebCore::DocumentLoader* loader = coreFrame->loader()->activeDocumentLoader();
971 if (!loader)
972 return 0;
973
974 return kitNew(loader->response());
975 }
976
977 namespace WebKit {
978
getViewFromFrame(WebKitWebFrame * frame)979 WebKitWebView* getViewFromFrame(WebKitWebFrame* frame)
980 {
981 WebKitWebFramePrivate* priv = frame->priv;
982 return priv->webView;
983 }
984
core(WebKitWebFrame * frame)985 WebCore::Frame* core(WebKitWebFrame* frame)
986 {
987 if (!frame)
988 return 0;
989
990 WebKitWebFramePrivate* priv = frame->priv;
991 return priv ? priv->coreFrame : 0;
992 }
993
kit(WebCore::Frame * coreFrame)994 WebKitWebFrame* kit(WebCore::Frame* coreFrame)
995 {
996 if (!coreFrame)
997 return 0;
998
999 ASSERT(coreFrame->loader());
1000 WebKit::FrameLoaderClient* client = static_cast<WebKit::FrameLoaderClient*>(coreFrame->loader()->client());
1001 return client ? client->webFrame() : 0;
1002 }
1003
1004 }
1005