• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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