GTK+ build fix. Like r154620.
[WebKit-https.git] / Source / WebKit / gtk / webkit / webkitwebframe.cpp
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 "AnimationController.h"
32 #include "DOMObjectCache.h"
33 #include "DocumentFragment.h"
34 #include "DocumentLoader.h"
35 #include "DocumentLoaderGtk.h"
36 #include "Editor.h"
37 #include "FrameLoadRequest.h"
38 #include "FrameLoader.h"
39 #include "FrameLoaderClientGtk.h"
40 #include "FrameSelection.h"
41 #include "FrameTree.h"
42 #include "FrameView.h"
43 #include "GCController.h"
44 #include "GraphicsContext.h"
45 #include "GtkUtilities.h"
46 #include "GtkVersioning.h"
47 #include "HTMLFrameOwnerElement.h"
48 #include "JSDOMBinding.h"
49 #include "JSDOMWindow.h"
50 #include "JSElement.h"
51 #include "PlatformContextCairo.h"
52 #include "PrintContext.h"
53 #include "RenderListItem.h"
54 #include "RenderTreeAsText.h"
55 #include "RenderView.h"
56 #include "ScriptController.h"
57 #include "SubstituteData.h"
58 #include "TextIterator.h"
59 #include "WebKitAccessibleWrapperAtk.h"
60 #include "WebKitDOMDocumentPrivate.h"
61 #include "WebKitDOMRangePrivate.h"
62 #include "markup.h"
63 #include "webkitenumtypes.h"
64 #include "webkitglobalsprivate.h"
65 #include "webkitmarshal.h"
66 #include "webkitnetworkresponse.h"
67 #include "webkitnetworkrequestprivate.h"
68 #include "webkitnetworkresponseprivate.h"
69 #include "webkitsecurityoriginprivate.h"
70 #include "webkitwebframeprivate.h"
71 #include "webkitwebresource.h"
72 #include "webkitwebview.h"
73 #include "webkitwebviewprivate.h"
74 #include <JavaScriptCore/APICast.h>
75 #include <atk/atk.h>
76 #include <glib/gi18n-lib.h>
77 #include <wtf/text/CString.h>
78
79 #if ENABLE(SVG)
80 #include "SVGSMILElement.h"
81 #endif
82
83 /**
84  * SECTION:webkitwebframe
85  * @short_description: The content of a #WebKitWebView
86  *
87  * A #WebKitWebView contains a main #WebKitWebFrame. A #WebKitWebFrame
88  * contains the content of one URI. The URI and name of the frame can
89  * be retrieved, the load status and progress can be observed using the
90  * signals and can be controlled using the methods of the #WebKitWebFrame.
91  * A #WebKitWebFrame can have any number of children and one child can
92  * be found by using #webkit_web_frame_find_frame.
93  *
94  * <informalexample><programlisting>
95  * /<!-- -->* Get the frame from the #WebKitWebView *<!-- -->/
96  * WebKitWebFrame *frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW(my_view));
97  * g_print ("The URI of this frame is '%s'", webkit_web_frame_get_uri (frame));
98  * </programlisting></informalexample>
99  */
100
101 using namespace WebKit;
102 using namespace WebCore;
103 using namespace std;
104
105 enum {
106     CLEARED,
107     LOAD_COMMITTED,
108     LOAD_DONE,
109     TITLE_CHANGED,
110     HOVERING_OVER_LINK,
111     SCROLLBARS_POLICY_CHANGED,
112     // Resource loading signals
113     RESOURCE_REQUEST_STARTING,
114     RESOURCE_RESPONSE_RECEIVED,
115     RESOURCE_LOAD_FINISHED,
116     RESOURCE_CONTENT_LENGTH_RECEIVED,
117     RESOURCE_LOAD_FAILED,
118     INSECURE_CONTENT_RUN,
119
120     LAST_SIGNAL
121 };
122
123 enum {
124     PROP_0,
125
126     PROP_NAME,
127     PROP_TITLE,
128     PROP_URI,
129     PROP_LOAD_STATUS,
130     PROP_HORIZONTAL_SCROLLBAR_POLICY,
131     PROP_VERTICAL_SCROLLBAR_POLICY
132 };
133
134 static guint webkit_web_frame_signals[LAST_SIGNAL] = { 0, };
135
136 G_DEFINE_TYPE(WebKitWebFrame, webkit_web_frame, G_TYPE_OBJECT)
137
138 static void webkit_web_frame_get_property(GObject* object, guint propertyId, GValue* value, GParamSpec* paramSpec)
139 {
140     WebKitWebFrame* frame = WEBKIT_WEB_FRAME(object);
141
142     switch (propertyId) {
143     case PROP_NAME:
144         g_value_set_string(value, webkit_web_frame_get_name(frame));
145         break;
146     case PROP_TITLE:
147         g_value_set_string(value, webkit_web_frame_get_title(frame));
148         break;
149     case PROP_URI:
150         g_value_set_string(value, webkit_web_frame_get_uri(frame));
151         break;
152     case PROP_LOAD_STATUS:
153         g_value_set_enum(value, webkit_web_frame_get_load_status(frame));
154         break;
155     case PROP_HORIZONTAL_SCROLLBAR_POLICY:
156         g_value_set_enum(value, webkit_web_frame_get_horizontal_scrollbar_policy(frame));
157         break;
158     case PROP_VERTICAL_SCROLLBAR_POLICY:
159         g_value_set_enum(value, webkit_web_frame_get_vertical_scrollbar_policy(frame));
160         break;
161     default:
162         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyId, paramSpec);
163         break;
164     }
165 }
166
167 // Called from the FrameLoaderClient when it is destroyed. Normally
168 // the unref in the FrameLoaderClient is destroying this object as
169 // well but due reference counting a user might have added a reference...
170 void webkit_web_frame_core_frame_gone(WebKitWebFrame* frame)
171 {
172     ASSERT(WEBKIT_IS_WEB_FRAME(frame));
173     WebKitWebFramePrivate* priv = frame->priv;
174     if (priv->coreFrame)
175         DOMObjectCache::clearByFrame(priv->coreFrame);
176     priv->coreFrame = 0;
177 }
178
179 static WebKitWebDataSource* webkit_web_frame_get_data_source_from_core_loader(WebCore::DocumentLoader* loader)
180 {
181     return loader ? static_cast<WebKit::DocumentLoader*>(loader)->dataSource() : 0;
182 }
183
184 static void webkit_web_frame_finalize(GObject* object)
185 {
186     WebKitWebFrame* frame = WEBKIT_WEB_FRAME(object);
187     WebKitWebFramePrivate* priv = frame->priv;
188
189     if (priv->coreFrame) {
190         DOMObjectCache::clearByFrame(priv->coreFrame);
191         priv->coreFrame->loader().cancelAndClear();
192         priv->coreFrame = 0;
193     }
194
195     g_free(priv->name);
196     g_free(priv->title);
197     g_free(priv->uri);
198
199     G_OBJECT_CLASS(webkit_web_frame_parent_class)->finalize(object);
200 }
201
202 static void webkit_web_frame_class_init(WebKitWebFrameClass* frameClass)
203 {
204     webkitInit();
205
206     /*
207      * signals
208      */
209     webkit_web_frame_signals[CLEARED] = g_signal_new("cleared",
210         G_TYPE_FROM_CLASS(frameClass),
211         (GSignalFlags)G_SIGNAL_RUN_LAST,
212         0,
213         0,
214         0,
215         g_cclosure_marshal_VOID__VOID,
216         G_TYPE_NONE, 0);
217
218     /**
219      * WebKitWebFrame::load-committed:
220      * @web_frame: the object on which the signal is emitted
221      *
222      * Emitted when frame loading is done.
223      *
224      * Deprecated: Use the "load-status" property instead.
225      */
226     webkit_web_frame_signals[LOAD_COMMITTED] = g_signal_new("load-committed",
227         G_TYPE_FROM_CLASS(frameClass),
228         (GSignalFlags)G_SIGNAL_RUN_LAST,
229         0,
230         0,
231         0,
232         g_cclosure_marshal_VOID__VOID,
233         G_TYPE_NONE, 0);
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     /**
300      * WebKitWebFrame::resource-request-starting:
301      * @web_frame: the #WebKitWebFrame whose load dispatched this request
302      * @web_resource: an empty #WebKitWebResource object
303      * @request: the #WebKitNetworkRequest that will be dispatched
304      * @response: the #WebKitNetworkResponse representing the redirect
305      * response, if any
306      *
307      * Emitted when a request is about to be sent. You can modify the
308      * request while handling this signal. You can set the URI in the
309      * #WebKitNetworkRequest object itself, and add/remove/replace
310      * headers using the #SoupMessage object it carries, if it is
311      * present. See webkit_network_request_get_message(). Setting the
312      * request URI to "about:blank" will effectively cause the request
313      * to load nothing, and can be used to disable the loading of
314      * specific resources.
315      *
316      * Notice that information about an eventual redirect is available
317      * in @response's #SoupMessage, not in the #SoupMessage carried by
318      * the @request. If @response is %NULL, then this is not a
319      * redirected request.
320      *
321      * The #WebKitWebResource object will be the same throughout all
322      * the lifetime of the resource, but the contents may change
323      * between signal emissions.
324      *
325      * Since: 1.7.5
326      */
327     webkit_web_frame_signals[RESOURCE_REQUEST_STARTING] = g_signal_new("resource-request-starting",
328         G_TYPE_FROM_CLASS(frameClass),
329         G_SIGNAL_RUN_LAST,
330         0,
331         0, 0,
332         webkit_marshal_VOID__OBJECT_OBJECT_OBJECT,
333         G_TYPE_NONE, 3,
334         WEBKIT_TYPE_WEB_RESOURCE,
335         WEBKIT_TYPE_NETWORK_REQUEST,
336         WEBKIT_TYPE_NETWORK_RESPONSE);
337
338     /**
339      * WebKitWebFrame::resource-response-received:
340      * @web_frame: the #WebKitWebFrame the response was received for
341      * @web_resource: the #WebKitWebResource being loaded
342      * @response: the #WebKitNetworkResponse that was received.
343      *
344      * Emitted when the response is received from the server.
345      *
346      * Since: 1.7.5
347      */
348     webkit_web_frame_signals[RESOURCE_RESPONSE_RECEIVED] = g_signal_new("resource-response-received",
349         G_TYPE_FROM_CLASS(frameClass),
350         G_SIGNAL_RUN_LAST,
351         0,
352         0, 0,
353         webkit_marshal_VOID__OBJECT_OBJECT,
354         G_TYPE_NONE, 2,
355         WEBKIT_TYPE_WEB_RESOURCE,
356         WEBKIT_TYPE_NETWORK_RESPONSE);
357
358     /**
359      * WebKitWebFrame::resource-load-finished:
360      * @web_frame: the #WebKitWebFrame the response was received for
361      * @web_resource: the #WebKitWebResource being loaded
362      *
363      * Emitted when all the data for the resource was loaded.
364      *
365      * Since: 1.7.5
366      */
367     webkit_web_frame_signals[RESOURCE_LOAD_FINISHED] = g_signal_new("resource-load-finished",
368         G_TYPE_FROM_CLASS(frameClass),
369         G_SIGNAL_RUN_LAST,
370         0,
371         0, 0,
372         g_cclosure_marshal_VOID__OBJECT,
373         G_TYPE_NONE, 1,
374         WEBKIT_TYPE_WEB_RESOURCE);
375
376     /**
377      * WebKitWebFrame::resource-content-length-received:
378      * @web_frame: the #WebKitWebFrame the response was received for
379      * @web_resource: the #WebKitWebResource that was loaded
380      * @length_received: the amount of data received since the last signal emission
381      *
382      * Emitted when new resource data has been received. The
383      * @length_received variable stores the amount of bytes received
384      * since the last time this signal was emitted. This is useful to
385      * provide progress information about the resource load operation.
386      *
387      * Since: 1.7.5
388      */
389     webkit_web_frame_signals[RESOURCE_CONTENT_LENGTH_RECEIVED] = g_signal_new("resource-content-length-received",
390         G_TYPE_FROM_CLASS(frameClass),
391         G_SIGNAL_RUN_LAST,
392         0,
393         0, 0,
394         webkit_marshal_VOID__OBJECT_INT,
395         G_TYPE_NONE, 2,
396         WEBKIT_TYPE_WEB_RESOURCE,
397         G_TYPE_INT);
398
399     /**
400      * WebKitWebFrame::resource-load-failed:
401      * @web_frame: the #WebKitWebFrame the response was received for
402      * @web_resource: the #WebKitWebResource that was loaded
403      * @error: the #GError that was triggered
404      *
405      * Invoked when a resource failed to load.
406      *
407      * Since: 1.7.5
408      */
409     webkit_web_frame_signals[RESOURCE_LOAD_FAILED] = g_signal_new("resource-load-failed",
410         G_TYPE_FROM_CLASS(frameClass),
411         G_SIGNAL_RUN_LAST,
412         0,
413         0, 0,
414         webkit_marshal_VOID__OBJECT_POINTER,
415         G_TYPE_NONE, 2,
416         WEBKIT_TYPE_WEB_RESOURCE,
417         G_TYPE_POINTER);
418
419     /**
420      * WebKitWebFrame::insecure-content-run:
421      * @web_frame: the #WebKitWebFrame the response was received for.
422      * @security_origin: the #WebKitSecurityOrigin.
423      * @url: the url of the insecure content.
424      *
425      * Invoked when insecure content is run from a secure page. This happens
426      * when a page loaded via HTTPS loads a stylesheet, script, image or
427      * iframe from an unencrypted HTTP URL.
428      *
429      * Since: 1.10.0
430      */
431     webkit_web_frame_signals[INSECURE_CONTENT_RUN] = g_signal_new("insecure-content-run",
432         G_TYPE_FROM_CLASS(frameClass),
433         G_SIGNAL_RUN_LAST,
434         0,
435         0, 0,
436         webkit_marshal_VOID__OBJECT_STRING,
437         G_TYPE_NONE, 2,
438         WEBKIT_TYPE_SECURITY_ORIGIN,
439         G_TYPE_STRING);
440
441     /*
442      * implementations of virtual methods
443      */
444     GObjectClass* objectClass = G_OBJECT_CLASS(frameClass);
445     objectClass->finalize = webkit_web_frame_finalize;
446     objectClass->get_property = webkit_web_frame_get_property;
447
448     /*
449      * properties
450      */
451     g_object_class_install_property(objectClass, PROP_NAME,
452                                     g_param_spec_string("name",
453                                                         _("Name"),
454                                                         _("The name of the frame"),
455                                                         0,
456                                                         WEBKIT_PARAM_READABLE));
457
458     g_object_class_install_property(objectClass, PROP_TITLE,
459                                     g_param_spec_string("title",
460                                                         _("Title"),
461                                                         _("The document title of the frame"),
462                                                         0,
463                                                         WEBKIT_PARAM_READABLE));
464
465     g_object_class_install_property(objectClass, PROP_URI,
466                                     g_param_spec_string("uri",
467                                                         _("URI"),
468                                                         _("The current URI of the contents displayed by the frame"),
469                                                         0,
470                                                         WEBKIT_PARAM_READABLE));
471
472     /**
473     * WebKitWebFrame:load-status:
474     *
475     * Determines the current status of the load.
476     *
477     * Since: 1.1.7
478     */
479     g_object_class_install_property(objectClass, PROP_LOAD_STATUS,
480                                     g_param_spec_enum("load-status",
481                                                       "Load Status",
482                                                       "Determines the current status of the load",
483                                                       WEBKIT_TYPE_LOAD_STATUS,
484                                                       WEBKIT_LOAD_FINISHED,
485                                                       WEBKIT_PARAM_READABLE));
486
487     /**
488      * WebKitWebFrame:horizontal-scrollbar-policy:
489      *
490      * Determines the current policy for the horizontal scrollbar of
491      * the frame. For the main frame, make sure to set the same policy
492      * on the scrollable widget containing the #WebKitWebView, unless
493      * you know what you are doing.
494      *
495      * Since: 1.1.14
496      */
497     g_object_class_install_property(objectClass, PROP_HORIZONTAL_SCROLLBAR_POLICY,
498                                     g_param_spec_enum("horizontal-scrollbar-policy",
499                                                       _("Horizontal Scrollbar Policy"),
500                                                       _("Determines the current policy for the horizontal scrollbar of the frame."),
501                                                       GTK_TYPE_POLICY_TYPE,
502                                                       GTK_POLICY_AUTOMATIC,
503                                                       WEBKIT_PARAM_READABLE));
504
505     /**
506      * WebKitWebFrame:vertical-scrollbar-policy:
507      *
508      * Determines the current policy for the vertical scrollbar of
509      * the frame. For the main frame, make sure to set the same policy
510      * on the scrollable widget containing the #WebKitWebView, unless
511      * you know what you are doing.
512      *
513      * Since: 1.1.14
514      */
515     g_object_class_install_property(objectClass, PROP_VERTICAL_SCROLLBAR_POLICY,
516                                     g_param_spec_enum("vertical-scrollbar-policy",
517                                                       _("Vertical Scrollbar Policy"),
518                                                       _("Determines the current policy for the vertical scrollbar of the frame."),
519                                                       GTK_TYPE_POLICY_TYPE,
520                                                       GTK_POLICY_AUTOMATIC,
521                                                       WEBKIT_PARAM_READABLE));
522
523     g_type_class_add_private(frameClass, sizeof(WebKitWebFramePrivate));
524 }
525
526 static void webkit_web_frame_init(WebKitWebFrame* frame)
527 {
528     WebKitWebFramePrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(frame, WEBKIT_TYPE_WEB_FRAME, WebKitWebFramePrivate);
529
530     // TODO: Move constructor code here.
531     frame->priv = priv;
532 }
533
534
535 /**
536  * webkit_web_frame_new:
537  * @web_view: the controlling #WebKitWebView
538  *
539  * Creates a new #WebKitWebFrame initialized with a controlling #WebKitWebView.
540  *
541  * Returns: a new #WebKitWebFrame
542  *
543  * Deprecated: 1.0.2: #WebKitWebFrame can only be used to inspect existing
544  * frames.
545  **/
546 WebKitWebFrame* webkit_web_frame_new(WebKitWebView* webView)
547 {
548     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
549
550     WebKitWebFrame* frame = WEBKIT_WEB_FRAME(g_object_new(WEBKIT_TYPE_WEB_FRAME, NULL));
551     WebKitWebFramePrivate* priv = frame->priv;
552     WebKitWebViewPrivate* viewPriv = webView->priv;
553
554     priv->webView = webView;
555     priv->coreFrame = viewPriv->corePage->mainFrame();
556     static_cast<WebKit::FrameLoaderClient*>(&viewPriv->corePage->mainFrame()->loader().client())->setWebFrame(frame);
557     priv->coreFrame->init();
558
559     priv->origin = 0;
560
561     return frame;
562 }
563
564 /**
565  * webkit_web_frame_get_title:
566  * @frame: a #WebKitWebFrame
567  *
568  * Returns the @frame's document title
569  *
570  * Return value: the title of @frame
571  */
572 const gchar* webkit_web_frame_get_title(WebKitWebFrame* frame)
573 {
574     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
575
576     WebKitWebFramePrivate* priv = frame->priv;
577     return priv->title;
578 }
579
580 /**
581  * webkit_web_frame_get_uri:
582  * @frame: a #WebKitWebFrame
583  *
584  * Returns the current URI of the contents displayed by the @frame
585  *
586  * Return value: the URI of @frame
587  */
588 const gchar* webkit_web_frame_get_uri(WebKitWebFrame* frame)
589 {
590     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
591
592     WebKitWebFramePrivate* priv = frame->priv;
593     return priv->uri;
594 }
595
596 /**
597  * webkit_web_frame_get_web_view:
598  * @frame: a #WebKitWebFrame
599  *
600  * Returns the #WebKitWebView that manages this #WebKitWebFrame.
601  *
602  * The #WebKitWebView returned manages the entire hierarchy of #WebKitWebFrame
603  * objects that contains @frame.
604  *
605  * Return value: (transfer none): the #WebKitWebView that manages @frame
606  */
607 WebKitWebView* webkit_web_frame_get_web_view(WebKitWebFrame* frame)
608 {
609     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
610
611     WebKitWebFramePrivate* priv = frame->priv;
612     return priv->webView;
613 }
614
615 /**
616  * webkit_web_frame_get_name:
617  * @frame: a #WebKitWebFrame
618  *
619  * Returns the @frame's name
620  *
621  * Return value: the name of @frame. This method will return NULL if
622  * the #WebKitWebFrame is invalid or an empty string if it is not backed
623  * by a live WebCore frame.
624  */
625 const gchar* webkit_web_frame_get_name(WebKitWebFrame* frame)
626 {
627     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
628     Frame* coreFrame = core(frame);
629     if (!coreFrame)
630         return "";
631
632     WebKitWebFramePrivate* priv = frame->priv;
633     CString frameName = coreFrame->tree().uniqueName().string().utf8();
634     if (!g_strcmp0(frameName.data(), priv->name))
635         return priv->name;
636
637     g_free(priv->name);
638     priv->name = g_strdup(frameName.data());
639     return priv->name;
640 }
641
642 /**
643  * webkit_web_frame_get_parent:
644  * @frame: a #WebKitWebFrame
645  *
646  * Returns the @frame's parent frame, or %NULL if it has none.
647  *
648  * Return value: (transfer none): the parent #WebKitWebFrame or %NULL in case there is none
649  */
650 WebKitWebFrame* webkit_web_frame_get_parent(WebKitWebFrame* frame)
651 {
652     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
653
654     Frame* coreFrame = core(frame);
655     if (!coreFrame)
656         return 0;
657
658     return kit(coreFrame->tree().parent());
659 }
660
661 /**
662  * webkit_web_frame_load_uri:
663  * @frame: a #WebKitWebFrame
664  * @uri: an URI string
665  *
666  * Requests loading of the specified URI string.
667  *
668  * Since: 1.1.1
669  */
670 void webkit_web_frame_load_uri(WebKitWebFrame* frame, const gchar* uri)
671 {
672     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
673     g_return_if_fail(uri);
674
675     Frame* coreFrame = core(frame);
676     if (!coreFrame)
677         return;
678
679     coreFrame->loader().load(FrameLoadRequest(coreFrame, ResourceRequest(KURL(KURL(), String::fromUTF8(uri)))));
680 }
681
682 static void webkit_web_frame_load_data(WebKitWebFrame* frame, const gchar* content, const gchar* mimeType, const gchar* encoding, const gchar* baseURL, const gchar* unreachableURL)
683 {
684     Frame* coreFrame = core(frame);
685     ASSERT(coreFrame);
686
687     KURL baseKURL = baseURL ? KURL(KURL(), String::fromUTF8(baseURL)) : blankURL();
688
689     ResourceRequest request(baseKURL);
690
691     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(content, strlen(content));
692     SubstituteData substituteData(sharedBuffer.release(),
693                                   mimeType ? String::fromUTF8(mimeType) : String::fromUTF8("text/html"),
694                                   encoding ? String::fromUTF8(encoding) : String::fromUTF8("UTF-8"),
695                                   KURL(KURL(), String::fromUTF8(unreachableURL)),
696                                   KURL(KURL(), String::fromUTF8(unreachableURL)));
697
698     coreFrame->loader().load(FrameLoadRequest(coreFrame, request, substituteData));
699 }
700
701 /**
702  * webkit_web_frame_load_string:
703  * @frame: a #WebKitWebFrame
704  * @content: an URI string
705  * @mime_type: the MIME type, or %NULL
706  * @encoding: the encoding, or %NULL
707  * @base_uri: the base URI for relative locations
708  *
709  * Requests loading of the given @content with the specified @mime_type,
710  * @encoding and @base_uri.
711  *
712  * If @mime_type is %NULL, "text/html" is assumed.
713  *
714  * If @encoding is %NULL, "UTF-8" is assumed.
715  *
716  * Since: 1.1.1
717  */
718 void webkit_web_frame_load_string(WebKitWebFrame* frame, const gchar* content, const gchar* contentMimeType, const gchar* contentEncoding, const gchar* baseUri)
719 {
720     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
721     g_return_if_fail(content);
722
723     webkit_web_frame_load_data(frame, content, contentMimeType, contentEncoding, baseUri, 0);
724 }
725
726 /**
727  * webkit_web_frame_load_alternate_string:
728  * @frame: a #WebKitWebFrame
729  * @content: the alternate content to display as the main page of the @frame
730  * @base_url: the base URI for relative locations
731  * @unreachable_url: the URL for the alternate page content
732  *
733  * Request loading of an alternate content for a URL that is unreachable.
734  * Using this method will preserve the back-forward list. The URI passed in
735  * @base_url has to be an absolute URI.
736  *
737  * Since: 1.1.6
738  */
739 void webkit_web_frame_load_alternate_string(WebKitWebFrame* frame, const gchar* content, const gchar* baseURL, const gchar* unreachableURL)
740 {
741     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
742     g_return_if_fail(content);
743
744     webkit_web_frame_load_data(frame, content, 0, 0, baseURL, unreachableURL);
745 }
746
747 /**
748  * webkit_web_frame_load_request:
749  * @frame: a #WebKitWebFrame
750  * @request: a #WebKitNetworkRequest
751  *
752  * Connects to a given URI by initiating an asynchronous client request.
753  *
754  * Creates a provisional data source that will transition to a committed data
755  * source once any data has been received. Use webkit_web_frame_stop_loading() to
756  * stop the load. This function is typically invoked on the main frame.
757  */
758 void webkit_web_frame_load_request(WebKitWebFrame* frame, WebKitNetworkRequest* request)
759 {
760     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
761     g_return_if_fail(WEBKIT_IS_NETWORK_REQUEST(request));
762
763     Frame* coreFrame = core(frame);
764     if (!coreFrame)
765         return;
766
767     coreFrame->loader().load(FrameLoadRequest(coreFrame->document()->securityOrigin(), core(request)));
768 }
769
770 /**
771  * webkit_web_frame_stop_loading:
772  * @frame: a #WebKitWebFrame
773  *
774  * Stops any pending loads on @frame's data source, and those of its children.
775  */
776 void webkit_web_frame_stop_loading(WebKitWebFrame* frame)
777 {
778     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
779
780     Frame* coreFrame = core(frame);
781     if (!coreFrame)
782         return;
783
784     coreFrame->loader().stopAllLoaders();
785 }
786
787 /**
788  * webkit_web_frame_reload:
789  * @frame: a #WebKitWebFrame
790  *
791  * Reloads the initial request.
792  */
793 void webkit_web_frame_reload(WebKitWebFrame* frame)
794 {
795     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
796
797     Frame* coreFrame = core(frame);
798     if (!coreFrame)
799         return;
800
801     coreFrame->loader().reload();
802 }
803
804 /**
805  * webkit_web_frame_find_frame:
806  * @frame: a #WebKitWebFrame
807  * @name: the name of the frame to be found
808  *
809  * For pre-defined names, returns @frame if @name is "_self" or "_current",
810  * returns @frame's parent frame if @name is "_parent", and returns the main
811  * frame if @name is "_top". Also returns @frame if it is the main frame and
812  * @name is either "_parent" or "_top". For other names, this function returns
813  * the first frame that matches @name. This function searches @frame and its
814  * descendents first, then @frame's parent and its children moving up the
815  * hierarchy until a match is found. If no match is found in @frame's
816  * hierarchy, this function will search for a matching frame in other main
817  * frame hierarchies. Returns %NULL if no match is found.
818  *
819  * Return value: (transfer none): the found #WebKitWebFrame or %NULL in case none is found
820  */
821 WebKitWebFrame* webkit_web_frame_find_frame(WebKitWebFrame* frame, const gchar* name)
822 {
823     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
824     g_return_val_if_fail(name, 0);
825
826     Frame* coreFrame = core(frame);
827     if (!coreFrame)
828         return 0;
829
830     String nameString = String::fromUTF8(name);
831     return kit(coreFrame->tree().find(AtomicString(nameString)));
832 }
833
834 /**
835  * webkit_web_frame_get_global_context:
836  * @frame: a #WebKitWebFrame
837  *
838  * Gets the global JavaScript execution context. Use this function to bridge
839  * between the WebKit and JavaScriptCore APIs.
840  *
841  * Return value: (transfer none): the global JavaScript context #JSGlobalContextRef
842  */
843 JSGlobalContextRef webkit_web_frame_get_global_context(WebKitWebFrame* frame)
844 {
845     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
846
847     Frame* coreFrame = core(frame);
848     if (!coreFrame)
849         return 0;
850
851     return toGlobalRef(coreFrame->script().globalObject(mainThreadNormalWorld())->globalExec());
852 }
853
854 /**
855  * webkit_web_frame_get_data_source:
856  * @frame: a #WebKitWebFrame
857  *
858  * Returns the committed data source.
859  *
860  * Return value: (transfer none): the committed #WebKitWebDataSource.
861  *
862  * Since: 1.1.14
863  */
864 WebKitWebDataSource* webkit_web_frame_get_data_source(WebKitWebFrame* frame)
865 {
866     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
867
868     Frame* coreFrame = core(frame);
869     return webkit_web_frame_get_data_source_from_core_loader(coreFrame->loader().documentLoader());
870 }
871
872 /**
873  * webkit_web_frame_get_provisional_data_source:
874  * @frame: a #WebKitWebFrame
875  *
876  * You use the webkit_web_frame_load_request method to initiate a request that
877  * creates a provisional data source. The provisional data source will
878  * transition to a committed data source once any data has been received. Use
879  * webkit_web_frame_get_data_source to get the committed data source.
880  *
881  * Return value: (transfer none): the provisional #WebKitWebDataSource or %NULL if a load
882  * request is not in progress.
883  *
884  * Since: 1.1.14
885  */
886 WebKitWebDataSource* webkit_web_frame_get_provisional_data_source(WebKitWebFrame* frame)
887 {
888     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
889
890     Frame* coreFrame = core(frame);
891     return webkit_web_frame_get_data_source_from_core_loader(coreFrame->loader().provisionalDocumentLoader());
892 }
893
894 static void begin_print_callback(GtkPrintOperation* op, GtkPrintContext* context, gpointer user_data)
895 {
896     PrintContext* printContext = reinterpret_cast<PrintContext*>(user_data);
897
898     float width = gtk_print_context_get_width(context);
899     float height = gtk_print_context_get_height(context);
900     FloatRect printRect = FloatRect(0, 0, width, height);
901
902     printContext->begin(width);
903
904     // TODO: Margin adjustments and header/footer support
905     float headerHeight = 0;
906     float footerHeight = 0;
907     float pageHeight; // height of the page adjusted by margins
908     printContext->computePageRects(printRect, headerHeight, footerHeight, 1.0, pageHeight);
909     gtk_print_operation_set_n_pages(op, printContext->pageCount());
910 }
911
912 static void draw_page_callback(GtkPrintOperation*, GtkPrintContext* gtkPrintContext, gint pageNumber, PrintContext* corePrintContext)
913 {
914     if (pageNumber >= static_cast<gint>(corePrintContext->pageCount()))
915         return;
916
917     cairo_t* cr = gtk_print_context_get_cairo_context(gtkPrintContext);
918     float pageWidth = gtk_print_context_get_width(gtkPrintContext);
919
920     PlatformContextCairo platformContext(cr);
921     GraphicsContext graphicsContext(&platformContext);
922     corePrintContext->spoolPage(graphicsContext, pageNumber, pageWidth);
923 }
924
925 static void end_print_callback(GtkPrintOperation* op, GtkPrintContext* context, gpointer user_data)
926 {
927     PrintContext* printContext = reinterpret_cast<PrintContext*>(user_data);
928     printContext->end();
929 }
930
931 /**
932  * webkit_web_frame_print_full:
933  * @frame: a #WebKitWebFrame to be printed
934  * @operation: the #GtkPrintOperation to be carried
935  * @action: the #GtkPrintOperationAction to be performed
936  * @error: #GError for error return
937  *
938  * Prints the given #WebKitWebFrame, using the given #GtkPrintOperation
939  * and #GtkPrintOperationAction. This function wraps a call to
940  * gtk_print_operation_run() for printing the contents of the
941  * #WebKitWebFrame.
942  *
943  * Returns: The #GtkPrintOperationResult specifying the result of this operation.
944  *
945  * Since: 1.1.5
946  */
947 GtkPrintOperationResult webkit_web_frame_print_full(WebKitWebFrame* frame, GtkPrintOperation* operation, GtkPrintOperationAction action, GError** error)
948 {
949     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), GTK_PRINT_OPERATION_RESULT_ERROR);
950     g_return_val_if_fail(GTK_IS_PRINT_OPERATION(operation), GTK_PRINT_OPERATION_RESULT_ERROR);
951
952     GtkWidget* topLevel = gtk_widget_get_toplevel(GTK_WIDGET(webkit_web_frame_get_web_view(frame)));
953     if (!widgetIsOnscreenToplevelWindow(topLevel))
954         topLevel = 0;
955
956     Frame* coreFrame = core(frame);
957     if (!coreFrame)
958         return GTK_PRINT_OPERATION_RESULT_ERROR;
959
960     PrintContext printContext(coreFrame);
961
962     g_signal_connect(operation, "begin-print", G_CALLBACK(begin_print_callback), &printContext);
963     g_signal_connect(operation, "draw-page", G_CALLBACK(draw_page_callback), &printContext);
964     g_signal_connect(operation, "end-print", G_CALLBACK(end_print_callback), &printContext);
965
966     return gtk_print_operation_run(operation, action, GTK_WINDOW(topLevel), error);
967 }
968
969 /**
970  * webkit_web_frame_print:
971  * @frame: a #WebKitWebFrame
972  *
973  * Prints the given #WebKitWebFrame, by presenting a print dialog to the
974  * user. If you need more control over the printing process, see
975  * webkit_web_frame_print_full().
976  *
977  * Since: 1.1.5
978  */
979 void webkit_web_frame_print(WebKitWebFrame* frame)
980 {
981     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
982
983     WebKitWebFramePrivate* priv = frame->priv;
984     GtkPrintOperation* operation = gtk_print_operation_new();
985     GError* error = 0;
986
987     webkit_web_frame_print_full(frame, operation, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, &error);
988     g_object_unref(operation);
989
990     if (error) {
991         GtkWidget* window = gtk_widget_get_toplevel(GTK_WIDGET(priv->webView));
992         GtkWidget* dialog = gtk_message_dialog_new(widgetIsOnscreenToplevelWindow(window) ? GTK_WINDOW(window) : 0,
993                                                    GTK_DIALOG_DESTROY_WITH_PARENT,
994                                                    GTK_MESSAGE_ERROR,
995                                                    GTK_BUTTONS_CLOSE,
996                                                    "%s", error->message);
997
998         g_error_free(error);
999
1000         g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL);
1001         gtk_widget_show(dialog);
1002     }
1003 }
1004
1005 gchar* webkit_web_frame_get_response_mime_type(WebKitWebFrame* frame)
1006 {
1007     Frame* coreFrame = core(frame);
1008     WebCore::DocumentLoader* docLoader = coreFrame->loader().documentLoader();
1009     String mimeType = docLoader->responseMIMEType();
1010     return g_strdup(mimeType.utf8().data());
1011 }
1012
1013 /**
1014  * webkit_web_frame_get_load_status:
1015  * @frame: a #WebKitWebView
1016  *
1017  * Determines the current status of the load.
1018  *
1019  * Returns: The #WebKitLoadStatus specifying the status of the current load.
1020  *
1021  * Since: 1.1.7
1022  */
1023 WebKitLoadStatus webkit_web_frame_get_load_status(WebKitWebFrame* frame)
1024 {
1025     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), WEBKIT_LOAD_FINISHED);
1026
1027     WebKitWebFramePrivate* priv = frame->priv;
1028     return priv->loadStatus;
1029 }
1030
1031 GtkPolicyType webkit_web_frame_get_horizontal_scrollbar_policy(WebKitWebFrame* frame)
1032 {
1033     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), GTK_POLICY_AUTOMATIC);
1034
1035     Frame* coreFrame = core(frame);
1036     FrameView* view = coreFrame->view();
1037     if (!view)
1038         return GTK_POLICY_AUTOMATIC;
1039
1040     ScrollbarMode hMode = view->horizontalScrollbarMode();
1041
1042     if (hMode == ScrollbarAlwaysOn)
1043         return GTK_POLICY_ALWAYS;
1044
1045     if (hMode == ScrollbarAlwaysOff)
1046         return GTK_POLICY_NEVER;
1047
1048     return GTK_POLICY_AUTOMATIC;
1049 }
1050
1051 GtkPolicyType webkit_web_frame_get_vertical_scrollbar_policy(WebKitWebFrame* frame)
1052 {
1053     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), GTK_POLICY_AUTOMATIC);
1054
1055     Frame* coreFrame = core(frame);
1056     FrameView* view = coreFrame->view();
1057     if (!view)
1058         return GTK_POLICY_AUTOMATIC;
1059
1060     ScrollbarMode vMode = view->verticalScrollbarMode();
1061
1062     if (vMode == ScrollbarAlwaysOn)
1063         return GTK_POLICY_ALWAYS;
1064
1065     if (vMode == ScrollbarAlwaysOff)
1066         return GTK_POLICY_NEVER;
1067
1068     return GTK_POLICY_AUTOMATIC;
1069 }
1070
1071 /**
1072  * webkit_web_frame_get_security_origin:
1073  * @frame: a #WebKitWebFrame
1074  *
1075  * Returns the @frame's security origin.
1076  *
1077  * Return value: (transfer none): the security origin of @frame
1078  *
1079  * Since: 1.1.14
1080  */
1081 WebKitSecurityOrigin* webkit_web_frame_get_security_origin(WebKitWebFrame* frame)
1082 {
1083     WebKitWebFramePrivate* priv = frame->priv;
1084     if (!priv->coreFrame || !priv->coreFrame->document() || !priv->coreFrame->document()->securityOrigin())
1085         return 0;
1086
1087     if (priv->origin && priv->origin->priv->coreOrigin.get() == priv->coreFrame->document()->securityOrigin())
1088         return priv->origin;
1089
1090     if (priv->origin)
1091         g_object_unref(priv->origin);
1092
1093     priv->origin = kit(priv->coreFrame->document()->securityOrigin());
1094     return priv->origin;
1095 }
1096
1097 /**
1098  * webkit_web_frame_get_network_response:
1099  * @frame: a #WebKitWebFrame
1100  *
1101  * Returns a #WebKitNetworkResponse object representing the response
1102  * that was given to the request for the given frame, or NULL if the
1103  * frame was not created by a load. You must unref the object when you
1104  * are done with it.
1105  *
1106  * Return value: (transfer full): a #WebKitNetworkResponse object
1107  *
1108  * Since: 1.1.18
1109  */
1110 WebKitNetworkResponse* webkit_web_frame_get_network_response(WebKitWebFrame* frame)
1111 {
1112     Frame* coreFrame = core(frame);
1113     if (!coreFrame)
1114         return 0;
1115
1116     WebCore::DocumentLoader* loader = coreFrame->loader().activeDocumentLoader();
1117     if (!loader)
1118         return 0;
1119
1120     return kitNew(loader->response());
1121 }
1122
1123 /**
1124  * webkit_web_frame_replace_selection:
1125  * @frame: a #WebKitWeFrame
1126  * @text: the text to insert in place of the current selection
1127  *
1128  * Replaces the current selection in @frame, if any, with @text.
1129  *
1130  * Since: 1.5.1
1131  **/
1132 void webkit_web_frame_replace_selection(WebKitWebFrame* frame, const char* text)
1133 {
1134     Frame* coreFrame = core(frame);
1135     bool selectReplacement = false;
1136     bool smartReplace = true;
1137     coreFrame->editor().replaceSelectionWithText(text, selectReplacement, smartReplace);
1138 }
1139
1140 /**
1141  * webkit_web_frame_get_range_for_word_around_caret:
1142  * @frame: a #WebKitWebFrame
1143  *
1144  * Returns a #WebKitDOMRange for the word where the caret is currently
1145  * positioned.
1146  *
1147  * Returns: (transfer none): a #WebKitDOMRange spanning the word where the caret
1148  * currently is positioned. If there is no caret %NULL will be
1149  * returned.
1150  *
1151  * Since: 1.5.1.
1152  **/
1153 WebKitDOMRange* webkit_web_frame_get_range_for_word_around_caret(WebKitWebFrame* frame)
1154 {
1155     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
1156
1157     Frame* coreFrame = core(frame);
1158     FrameSelection& selection = coreFrame->selection();
1159     if (selection.isNone() || selection.isRange())
1160         return 0;
1161     VisibleSelection visibleSelection(selection.selection().visibleStart());
1162     visibleSelection.expandUsingGranularity(WordGranularity);
1163
1164     return kit(visibleSelection.firstRange().get());
1165 }
1166
1167 /**
1168  * webkit_web_frame_get_dom_document:
1169  * @frame: a #WebKitWebFrame
1170  *
1171  * Returns: (transfer none): the #WebKitDOMDocument currently loaded
1172  * in the @frame or %NULL if no document is loaded
1173  *
1174  * Since: 1.10
1175  **/
1176 WebKitDOMDocument* webkit_web_frame_get_dom_document(WebKitWebFrame* frame)
1177 {
1178     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
1179
1180     Frame* coreFrame = core(frame);
1181     if (!coreFrame)
1182         return 0;
1183
1184     Document* doc = coreFrame->document();
1185     if (!doc)
1186         return 0;
1187
1188     return kit(doc);
1189 }
1190
1191 namespace WebKit {
1192
1193 WebKitWebView* getViewFromFrame(WebKitWebFrame* frame)
1194 {
1195     WebKitWebFramePrivate* priv = frame->priv;
1196     return priv->webView;
1197 }
1198
1199 WebCore::Frame* core(WebKitWebFrame* frame)
1200 {
1201     if (!frame)
1202         return 0;
1203
1204     WebKitWebFramePrivate* priv = frame->priv;
1205     return priv ? priv->coreFrame : 0;
1206 }
1207
1208 WebKitWebFrame* kit(WebCore::Frame* coreFrame)
1209 {
1210     if (!coreFrame)
1211         return 0;
1212
1213     return static_cast<WebKit::FrameLoaderClient&>(coreFrame->loader().client()).webFrame();
1214 }
1215
1216 }