• 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 
29 #include "webkitenumtypes.h"
30 #include "webkitwebframe.h"
31 #include "webkitwebview.h"
32 #include "webkitmarshal.h"
33 #include "webkitprivate.h"
34 
35 #include "AccessibilityObjectWrapperAtk.h"
36 #include "AnimationController.h"
37 #include "AXObjectCache.h"
38 #include "CString.h"
39 #include "DocumentLoader.h"
40 #include "FrameLoader.h"
41 #include "FrameLoaderClientGtk.h"
42 #include "FrameTree.h"
43 #include "FrameView.h"
44 #include <glib/gi18n-lib.h>
45 #include "GCController.h"
46 #include "GraphicsContext.h"
47 #include "HTMLFrameOwnerElement.h"
48 #include "JSDOMWindow.h"
49 #include "JSLock.h"
50 #include "PrintContext.h"
51 #include "RenderView.h"
52 #include "RenderTreeAsText.h"
53 #include "JSDOMBinding.h"
54 #include "ScriptController.h"
55 #include "SubstituteData.h"
56 
57 #include <atk/atk.h>
58 #include <JavaScriptCore/APICast.h>
59 
60 /**
61  * SECTION:webkitwebframe
62  * @short_description: The content of a #WebKitWebView
63  *
64  * A #WebKitWebView contains a main #WebKitWebFrame. A #WebKitWebFrame
65  * contains the content of one URI. The URI and name of the frame can
66  * be retrieved, the load status and progress can be observed using the
67  * signals and can be controlled using the methods of the #WebKitWebFrame.
68  * A #WebKitWebFrame can have any number of children and one child can
69  * be found by using #webkit_web_frame_find_frame.
70  *
71  * <informalexample><programlisting>
72  * /<!-- -->* Get the frame from the #WebKitWebView *<!-- -->/
73  * WebKitWebFrame *frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW(my_view));
74  * g_print("The URI of this frame is '%s'", webkit_web_frame_get_uri (frame));
75  * </programlisting></informalexample>
76  */
77 
78 using namespace WebKit;
79 using namespace WebCore;
80 using namespace std;
81 
82 enum {
83     CLEARED,
84     LOAD_COMMITTED,
85     LOAD_DONE,
86     TITLE_CHANGED,
87     HOVERING_OVER_LINK,
88     LAST_SIGNAL
89 };
90 
91 enum {
92     PROP_0,
93 
94     PROP_NAME,
95     PROP_TITLE,
96     PROP_URI,
97     PROP_LOAD_STATUS
98 };
99 
100 static guint webkit_web_frame_signals[LAST_SIGNAL] = { 0, };
101 
G_DEFINE_TYPE(WebKitWebFrame,webkit_web_frame,G_TYPE_OBJECT)102 G_DEFINE_TYPE(WebKitWebFrame, webkit_web_frame, G_TYPE_OBJECT)
103 
104 static void webkit_web_frame_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec)
105 {
106     WebKitWebFrame* frame = WEBKIT_WEB_FRAME(object);
107 
108     switch(prop_id) {
109     case PROP_NAME:
110         g_value_set_string(value, webkit_web_frame_get_name(frame));
111         break;
112     case PROP_TITLE:
113         g_value_set_string(value, webkit_web_frame_get_title(frame));
114         break;
115     case PROP_URI:
116         g_value_set_string(value, webkit_web_frame_get_uri(frame));
117         break;
118     case PROP_LOAD_STATUS:
119         g_value_set_enum(value, webkit_web_frame_get_load_status(frame));
120         break;
121     default:
122         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
123         break;
124     }
125 }
126 
127 // Called from the FrameLoaderClient when it is destroyed. Normally
128 // the unref in the FrameLoaderClient is destroying this object as
129 // well but due reference counting a user might have added a reference...
webkit_web_frame_core_frame_gone(WebKitWebFrame * frame)130 void webkit_web_frame_core_frame_gone(WebKitWebFrame* frame)
131 {
132     ASSERT(WEBKIT_IS_WEB_FRAME(frame));
133     frame->priv->coreFrame = 0;
134 }
135 
webkit_web_frame_finalize(GObject * object)136 static void webkit_web_frame_finalize(GObject* object)
137 {
138     WebKitWebFrame* frame = WEBKIT_WEB_FRAME(object);
139     WebKitWebFramePrivate* priv = frame->priv;
140 
141     if (priv->coreFrame) {
142         priv->coreFrame->loader()->cancelAndClear();
143         priv->coreFrame = 0;
144     }
145 
146     g_free(priv->name);
147     g_free(priv->title);
148     g_free(priv->uri);
149 
150     G_OBJECT_CLASS(webkit_web_frame_parent_class)->finalize(object);
151 }
152 
webkit_web_frame_class_init(WebKitWebFrameClass * frameClass)153 static void webkit_web_frame_class_init(WebKitWebFrameClass* frameClass)
154 {
155     webkit_init();
156 
157     /*
158      * signals
159      */
160     webkit_web_frame_signals[CLEARED] = g_signal_new("cleared",
161             G_TYPE_FROM_CLASS(frameClass),
162             (GSignalFlags)G_SIGNAL_RUN_LAST,
163             0,
164             NULL,
165             NULL,
166             g_cclosure_marshal_VOID__VOID,
167             G_TYPE_NONE, 0);
168 
169     webkit_web_frame_signals[LOAD_COMMITTED] = g_signal_new("load-committed",
170             G_TYPE_FROM_CLASS(frameClass),
171             (GSignalFlags)G_SIGNAL_RUN_LAST,
172             0,
173             NULL,
174             NULL,
175             g_cclosure_marshal_VOID__VOID,
176             G_TYPE_NONE, 0);
177 
178     /**
179      * WebKitWebFrame::load-done
180      * @web_frame: the object on which the signal is emitted
181      *
182      * Emitted when frame loading is done.
183      *
184      * Deprecated: Use WebKitWebView::load-finished instead, and/or
185      * WebKitWebView::load-error to be notified of load errors
186      */
187     webkit_web_frame_signals[LOAD_DONE] = g_signal_new("load-done",
188             G_TYPE_FROM_CLASS(frameClass),
189             (GSignalFlags)G_SIGNAL_RUN_LAST,
190             0,
191             NULL,
192             NULL,
193             g_cclosure_marshal_VOID__BOOLEAN,
194             G_TYPE_NONE, 1,
195             G_TYPE_BOOLEAN);
196 
197     webkit_web_frame_signals[TITLE_CHANGED] = g_signal_new("title-changed",
198             G_TYPE_FROM_CLASS(frameClass),
199             (GSignalFlags)G_SIGNAL_RUN_LAST,
200             0,
201             NULL,
202             NULL,
203             webkit_marshal_VOID__STRING,
204             G_TYPE_NONE, 1,
205             G_TYPE_STRING);
206 
207     webkit_web_frame_signals[HOVERING_OVER_LINK] = g_signal_new("hovering-over-link",
208             G_TYPE_FROM_CLASS(frameClass),
209             (GSignalFlags)G_SIGNAL_RUN_LAST,
210             0,
211             NULL,
212             NULL,
213             webkit_marshal_VOID__STRING_STRING,
214             G_TYPE_NONE, 2,
215             G_TYPE_STRING, G_TYPE_STRING);
216 
217     /*
218      * implementations of virtual methods
219      */
220     GObjectClass* objectClass = G_OBJECT_CLASS(frameClass);
221     objectClass->finalize = webkit_web_frame_finalize;
222     objectClass->get_property = webkit_web_frame_get_property;
223 
224     /*
225      * properties
226      */
227     g_object_class_install_property(objectClass, PROP_NAME,
228                                     g_param_spec_string("name",
229                                                         _("Name"),
230                                                         _("The name of the frame"),
231                                                         NULL,
232                                                         WEBKIT_PARAM_READABLE));
233 
234     g_object_class_install_property(objectClass, PROP_TITLE,
235                                     g_param_spec_string("title",
236                                                         _("Title"),
237                                                         _("The document title of the frame"),
238                                                         NULL,
239                                                         WEBKIT_PARAM_READABLE));
240 
241     g_object_class_install_property(objectClass, PROP_URI,
242                                     g_param_spec_string("uri",
243                                                         _("URI"),
244                                                         _("The current URI of the contents displayed by the frame"),
245                                                         NULL,
246                                                         WEBKIT_PARAM_READABLE));
247 
248     /**
249     * WebKitWebFrame:load-status:
250     *
251     * Determines the current status of the load.
252     *
253     * Since: 1.1.7
254     */
255     g_object_class_install_property(objectClass, PROP_LOAD_STATUS,
256                                     g_param_spec_enum("load-status",
257                                                       "Load Status",
258                                                       "Determines the current status of the load",
259                                                       WEBKIT_TYPE_LOAD_STATUS,
260                                                       WEBKIT_LOAD_FINISHED,
261                                                       WEBKIT_PARAM_READABLE));
262 
263     g_type_class_add_private(frameClass, sizeof(WebKitWebFramePrivate));
264 }
265 
webkit_web_frame_init(WebKitWebFrame * frame)266 static void webkit_web_frame_init(WebKitWebFrame* frame)
267 {
268     WebKitWebFramePrivate* priv = WEBKIT_WEB_FRAME_GET_PRIVATE(frame);
269 
270     // TODO: Move constructor code here.
271     frame->priv = priv;
272 }
273 
274 /**
275  * webkit_web_frame_new:
276  * @web_view: the controlling #WebKitWebView
277  *
278  * Creates a new #WebKitWebFrame initialized with a controlling #WebKitWebView.
279  *
280  * Returns: a new #WebKitWebFrame
281  *
282  * Deprecated: 1.0.2: #WebKitWebFrame can only be used to inspect existing
283  * frames.
284  **/
webkit_web_frame_new(WebKitWebView * webView)285 WebKitWebFrame* webkit_web_frame_new(WebKitWebView* webView)
286 {
287     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL);
288 
289     WebKitWebFrame* frame = WEBKIT_WEB_FRAME(g_object_new(WEBKIT_TYPE_WEB_FRAME, NULL));
290     WebKitWebFramePrivate* priv = frame->priv;
291     WebKitWebViewPrivate* viewPriv = WEBKIT_WEB_VIEW_GET_PRIVATE(webView);
292 
293     priv->webView = webView;
294     WebKit::FrameLoaderClient* client = new WebKit::FrameLoaderClient(frame);
295     priv->coreFrame = Frame::create(viewPriv->corePage, 0, client).get();
296     priv->coreFrame->init();
297 
298     return frame;
299 }
300 
webkit_web_frame_init_with_web_view(WebKitWebView * webView,HTMLFrameOwnerElement * element)301 PassRefPtr<Frame> webkit_web_frame_init_with_web_view(WebKitWebView* webView, HTMLFrameOwnerElement* element)
302 {
303     WebKitWebFrame* frame = WEBKIT_WEB_FRAME(g_object_new(WEBKIT_TYPE_WEB_FRAME, NULL));
304     WebKitWebFramePrivate* priv = frame->priv;
305     WebKitWebViewPrivate* viewPriv = WEBKIT_WEB_VIEW_GET_PRIVATE(webView);
306 
307     priv->webView = webView;
308     WebKit::FrameLoaderClient* client = new WebKit::FrameLoaderClient(frame);
309 
310     RefPtr<Frame> coreFrame = Frame::create(viewPriv->corePage, element, client);
311     priv->coreFrame = coreFrame.get();
312 
313     return coreFrame.release();
314 }
315 
316 /**
317  * webkit_web_frame_get_title:
318  * @frame: a #WebKitWebFrame
319  *
320  * Returns the @frame's document title
321  *
322  * Return value: the title of @frame
323  */
webkit_web_frame_get_title(WebKitWebFrame * frame)324 G_CONST_RETURN gchar* webkit_web_frame_get_title(WebKitWebFrame* frame)
325 {
326     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL);
327 
328     WebKitWebFramePrivate* priv = frame->priv;
329     return priv->title;
330 }
331 
332 /**
333  * webkit_web_frame_get_uri:
334  * @frame: a #WebKitWebFrame
335  *
336  * Returns the current URI of the contents displayed by the @frame
337  *
338  * Return value: the URI of @frame
339  */
webkit_web_frame_get_uri(WebKitWebFrame * frame)340 G_CONST_RETURN gchar* webkit_web_frame_get_uri(WebKitWebFrame* frame)
341 {
342     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL);
343 
344     WebKitWebFramePrivate* priv = frame->priv;
345     return priv->uri;
346 }
347 
348 /**
349  * webkit_web_frame_get_web_view:
350  * @frame: a #WebKitWebFrame
351  *
352  * Returns the #WebKitWebView that manages this #WebKitWebFrame.
353  *
354  * The #WebKitWebView returned manages the entire hierarchy of #WebKitWebFrame
355  * objects that contains @frame.
356  *
357  * Return value: the #WebKitWebView that manages @frame
358  */
webkit_web_frame_get_web_view(WebKitWebFrame * frame)359 WebKitWebView* webkit_web_frame_get_web_view(WebKitWebFrame* frame)
360 {
361     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL);
362 
363     WebKitWebFramePrivate* priv = frame->priv;
364     return priv->webView;
365 }
366 
367 /**
368  * webkit_web_frame_get_name:
369  * @frame: a #WebKitWebFrame
370  *
371  * Returns the @frame's name
372  *
373  * Return value: the name of @frame
374  */
webkit_web_frame_get_name(WebKitWebFrame * frame)375 G_CONST_RETURN gchar* webkit_web_frame_get_name(WebKitWebFrame* frame)
376 {
377     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL);
378 
379     WebKitWebFramePrivate* priv = frame->priv;
380 
381     if (priv->name)
382         return priv->name;
383 
384     Frame* coreFrame = core(frame);
385     if (!coreFrame)
386         return "";
387 
388     String string = coreFrame->tree()->name();
389     priv->name = g_strdup(string.utf8().data());
390     return priv->name;
391 }
392 
393 /**
394  * webkit_web_frame_get_parent:
395  * @frame: a #WebKitWebFrame
396  *
397  * Returns the @frame's parent frame, or %NULL if it has none.
398  *
399  * Return value: the parent #WebKitWebFrame or %NULL in case there is none
400  */
webkit_web_frame_get_parent(WebKitWebFrame * frame)401 WebKitWebFrame* webkit_web_frame_get_parent(WebKitWebFrame* frame)
402 {
403     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL);
404 
405     Frame* coreFrame = core(frame);
406     if (!coreFrame)
407         return NULL;
408 
409     return kit(coreFrame->tree()->parent());
410 }
411 
412 /**
413  * webkit_web_frame_load_uri:
414  * @frame: a #WebKitWebFrame
415  * @uri: an URI string
416  *
417  * Requests loading of the specified URI string.
418  *
419  * Since: 1.1.1
420  */
webkit_web_frame_load_uri(WebKitWebFrame * frame,const gchar * uri)421 void webkit_web_frame_load_uri(WebKitWebFrame* frame, const gchar* uri)
422 {
423     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
424     g_return_if_fail(uri);
425 
426     Frame* coreFrame = core(frame);
427     if (!coreFrame)
428         return;
429 
430     coreFrame->loader()->load(ResourceRequest(KURL(KURL(), String::fromUTF8(uri))), false);
431 }
432 
webkit_web_frame_load_data(WebKitWebFrame * frame,const gchar * content,const gchar * mimeType,const gchar * encoding,const gchar * baseURL,const gchar * unreachableURL)433 static void webkit_web_frame_load_data(WebKitWebFrame* frame, const gchar* content, const gchar* mimeType, const gchar* encoding, const gchar* baseURL, const gchar* unreachableURL)
434 {
435     Frame* coreFrame = core(frame);
436     ASSERT(coreFrame);
437 
438     KURL baseKURL = baseURL ? KURL(KURL(), String::fromUTF8(baseURL)) : blankURL();
439 
440     ResourceRequest request(baseKURL);
441 
442     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(content, strlen(content));
443     SubstituteData substituteData(sharedBuffer.release(),
444                                   mimeType ? String::fromUTF8(mimeType) : String::fromUTF8("text/html"),
445                                   encoding ? String::fromUTF8(encoding) : String::fromUTF8("UTF-8"),
446                                   baseKURL,
447                                   KURL(KURL(), String::fromUTF8(unreachableURL)));
448 
449     coreFrame->loader()->load(request, substituteData, false);
450 }
451 
452 /**
453  * webkit_web_frame_load_string:
454  * @frame: a #WebKitWebFrame
455  * @content: an URI string
456  * @mime_type: the MIME type, or %NULL
457  * @encoding: the encoding, or %NULL
458  * @base_uri: the base URI for relative locations
459  *
460  * Requests loading of the given @content with the specified @mime_type,
461  * @encoding and @base_uri.
462  *
463  * If @mime_type is %NULL, "text/html" is assumed.
464  *
465  * If @encoding is %NULL, "UTF-8" is assumed.
466  *
467  * Since: 1.1.1
468  */
webkit_web_frame_load_string(WebKitWebFrame * frame,const gchar * content,const gchar * contentMimeType,const gchar * contentEncoding,const gchar * baseUri)469 void webkit_web_frame_load_string(WebKitWebFrame* frame, const gchar* content, const gchar* contentMimeType, const gchar* contentEncoding, const gchar* baseUri)
470 {
471     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
472     g_return_if_fail(content);
473 
474     webkit_web_frame_load_data(frame, content, contentMimeType, contentEncoding, baseUri, NULL);
475 }
476 
477 /**
478  * webkit_web_frame_load_alternate_string:
479  * @frame: a #WebKitWebFrame
480  * @content: the alternate content to display as the main page of the @frame
481  * @base_url: the base URI for relative locations
482  * @unreachable_url: the URL for the alternate page content
483  *
484  * Request loading of an alternate content for a URL that is unreachable.
485  * Using this method will preserve the back-forward list. The URI passed in
486  * @base_url has to be an absolute URI.
487  *
488  * Since: 1.1.6
489  */
webkit_web_frame_load_alternate_string(WebKitWebFrame * frame,const gchar * content,const gchar * baseURL,const gchar * unreachableURL)490 void webkit_web_frame_load_alternate_string(WebKitWebFrame* frame, const gchar* content, const gchar* baseURL, const gchar* unreachableURL)
491 {
492     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
493     g_return_if_fail(content);
494 
495     webkit_web_frame_load_data(frame, content, NULL, NULL, baseURL, unreachableURL);
496 }
497 
498 /**
499  * webkit_web_frame_load_request:
500  * @frame: a #WebKitWebFrame
501  * @request: a #WebKitNetworkRequest
502  *
503  * Connects to a given URI by initiating an asynchronous client request.
504  *
505  * Creates a provisional data source that will transition to a committed data
506  * source once any data has been received. Use webkit_web_frame_stop_loading() to
507  * stop the load. This function is typically invoked on the main frame.
508  */
webkit_web_frame_load_request(WebKitWebFrame * frame,WebKitNetworkRequest * request)509 void webkit_web_frame_load_request(WebKitWebFrame* frame, WebKitNetworkRequest* request)
510 {
511     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
512     g_return_if_fail(WEBKIT_IS_NETWORK_REQUEST(request));
513 
514     Frame* coreFrame = core(frame);
515     if (!coreFrame)
516         return;
517 
518     coreFrame->loader()->load(core(request), false);
519 }
520 
521 /**
522  * webkit_web_frame_stop_loading:
523  * @frame: a #WebKitWebFrame
524  *
525  * Stops any pending loads on @frame's data source, and those of its children.
526  */
webkit_web_frame_stop_loading(WebKitWebFrame * frame)527 void webkit_web_frame_stop_loading(WebKitWebFrame* frame)
528 {
529     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
530 
531     Frame* coreFrame = core(frame);
532     if (!coreFrame)
533         return;
534 
535     coreFrame->loader()->stopAllLoaders();
536 }
537 
538 /**
539  * webkit_web_frame_reload:
540  * @frame: a #WebKitWebFrame
541  *
542  * Reloads the initial request.
543  */
webkit_web_frame_reload(WebKitWebFrame * frame)544 void webkit_web_frame_reload(WebKitWebFrame* frame)
545 {
546     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
547 
548     Frame* coreFrame = core(frame);
549     if (!coreFrame)
550         return;
551 
552     coreFrame->loader()->reload();
553 }
554 
555 /**
556  * webkit_web_frame_find_frame:
557  * @frame: a #WebKitWebFrame
558  * @name: the name of the frame to be found
559  *
560  * For pre-defined names, returns @frame if @name is "_self" or "_current",
561  * returns @frame's parent frame if @name is "_parent", and returns the main
562  * frame if @name is "_top". Also returns @frame if it is the main frame and
563  * @name is either "_parent" or "_top". For other names, this function returns
564  * the first frame that matches @name. This function searches @frame and its
565  * descendents first, then @frame's parent and its children moving up the
566  * hierarchy until a match is found. If no match is found in @frame's
567  * hierarchy, this function will search for a matching frame in other main
568  * frame hierarchies. Returns %NULL if no match is found.
569  *
570  * Return value: the found #WebKitWebFrame or %NULL in case none is found
571  */
webkit_web_frame_find_frame(WebKitWebFrame * frame,const gchar * name)572 WebKitWebFrame* webkit_web_frame_find_frame(WebKitWebFrame* frame, const gchar* name)
573 {
574     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL);
575     g_return_val_if_fail(name, NULL);
576 
577     Frame* coreFrame = core(frame);
578     if (!coreFrame)
579         return NULL;
580 
581     String nameString = String::fromUTF8(name);
582     return kit(coreFrame->tree()->find(AtomicString(nameString)));
583 }
584 
585 /**
586  * webkit_web_frame_get_global_context:
587  * @frame: a #WebKitWebFrame
588  *
589  * Gets the global JavaScript execution context. Use this function to bridge
590  * between the WebKit and JavaScriptCore APIs.
591  *
592  * Return value: the global JavaScript context
593  */
webkit_web_frame_get_global_context(WebKitWebFrame * frame)594 JSGlobalContextRef webkit_web_frame_get_global_context(WebKitWebFrame* frame)
595 {
596     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL);
597 
598     Frame* coreFrame = core(frame);
599     if (!coreFrame)
600         return NULL;
601 
602     return toGlobalRef(coreFrame->script()->globalObject()->globalExec());
603 }
604 
605 /**
606  * webkit_web_frame_get_children:
607  * @frame: a #WebKitWebFrame
608  *
609  * Return value: child frames of @frame
610  */
webkit_web_frame_get_children(WebKitWebFrame * frame)611 GSList* webkit_web_frame_get_children(WebKitWebFrame* frame)
612 {
613     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL);
614 
615     Frame* coreFrame = core(frame);
616     if (!coreFrame)
617         return NULL;
618 
619     GSList* children = NULL;
620     for (Frame* child = coreFrame->tree()->firstChild(); child; child = child->tree()->nextSibling()) {
621         FrameLoader* loader = child->loader();
622         WebKit::FrameLoaderClient* client = static_cast<WebKit::FrameLoaderClient*>(loader->client());
623         if (client)
624           children = g_slist_append(children, client->webFrame());
625     }
626 
627     return children;
628 }
629 
630 /**
631  * webkit_web_frame_get_inner_text:
632  * @frame: a #WebKitWebFrame
633  *
634  * Return value: inner text of @frame
635  */
webkit_web_frame_get_inner_text(WebKitWebFrame * frame)636 gchar* webkit_web_frame_get_inner_text(WebKitWebFrame* frame)
637 {
638     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL);
639 
640     Frame* coreFrame = core(frame);
641     if (!coreFrame)
642         return g_strdup("");
643 
644     FrameView* view = coreFrame->view();
645 
646     if (view && view->layoutPending())
647         view->layout();
648 
649     Element* documentElement = coreFrame->document()->documentElement();
650     String string =  documentElement->innerText();
651     return g_strdup(string.utf8().data());
652 }
653 
654 /**
655  * webkit_web_frame_dump_render_tree:
656  * @frame: a #WebKitWebFrame
657  *
658  * Return value: Non-recursive render tree dump of @frame
659  */
webkit_web_frame_dump_render_tree(WebKitWebFrame * frame)660 gchar* webkit_web_frame_dump_render_tree(WebKitWebFrame* frame)
661 {
662     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL);
663 
664     Frame* coreFrame = core(frame);
665     if (!coreFrame)
666         return g_strdup("");
667 
668     FrameView* view = coreFrame->view();
669 
670     if (view && view->layoutPending())
671         view->layout();
672 
673     String string = externalRepresentation(coreFrame->contentRenderer());
674     return g_strdup(string.utf8().data());
675 }
676 
begin_print_callback(GtkPrintOperation * op,GtkPrintContext * context,gpointer user_data)677 static void begin_print_callback(GtkPrintOperation* op, GtkPrintContext* context, gpointer user_data)
678 {
679     PrintContext* printContext = reinterpret_cast<PrintContext*>(user_data);
680 
681     float width = gtk_print_context_get_width(context);
682     float height = gtk_print_context_get_height(context);
683     FloatRect printRect = FloatRect(0, 0, width, height);
684 
685     printContext->begin(width);
686 
687     // TODO: Margin adjustments and header/footer support
688     float headerHeight = 0;
689     float footerHeight = 0;
690     float pageHeight; // height of the page adjusted by margins
691     printContext->computePageRects(printRect, headerHeight, footerHeight, 1.0, pageHeight);
692     gtk_print_operation_set_n_pages(op, printContext->pageCount());
693 }
694 
draw_page_callback(GtkPrintOperation * op,GtkPrintContext * context,gint page_nr,gpointer user_data)695 static void draw_page_callback(GtkPrintOperation* op, GtkPrintContext* context, gint page_nr, gpointer user_data)
696 {
697     PrintContext* printContext = reinterpret_cast<PrintContext*>(user_data);
698 
699     cairo_t* cr = gtk_print_context_get_cairo_context(context);
700     GraphicsContext ctx(cr);
701     float width = gtk_print_context_get_width(context);
702     printContext->spoolPage(ctx, page_nr, width);
703 }
704 
end_print_callback(GtkPrintOperation * op,GtkPrintContext * context,gpointer user_data)705 static void end_print_callback(GtkPrintOperation* op, GtkPrintContext* context, gpointer user_data)
706 {
707     PrintContext* printContext = reinterpret_cast<PrintContext*>(user_data);
708     printContext->end();
709 }
710 
711 /**
712  * webkit_web_frame_print_full:
713  * @frame: a #WebKitWebFrame to be printed
714  * @operation: the #GtkPrintOperation to be carried
715  * @action: the #GtkPrintOperationAction to be performed
716  * @error: #GError for error return
717  *
718  * Prints the given #WebKitFrame, using the given #GtkPrintOperation
719  * and #GtkPrintOperationAction. This function wraps a call to
720  * gtk_print_operation_run() for printing the contents of the
721  * #WebKitWebFrame.
722  *
723  * Since: 1.1.5
724  */
webkit_web_frame_print_full(WebKitWebFrame * frame,GtkPrintOperation * operation,GtkPrintOperationAction action,GError ** error)725 GtkPrintOperationResult webkit_web_frame_print_full(WebKitWebFrame* frame, GtkPrintOperation* operation, GtkPrintOperationAction action, GError** error)
726 {
727     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), GTK_PRINT_OPERATION_RESULT_ERROR);
728     g_return_val_if_fail(GTK_IS_PRINT_OPERATION(operation), GTK_PRINT_OPERATION_RESULT_ERROR);
729 
730     GtkWidget* topLevel = gtk_widget_get_toplevel(GTK_WIDGET(webkit_web_frame_get_web_view(frame)));
731     if (!GTK_WIDGET_TOPLEVEL(topLevel))
732         topLevel = NULL;
733 
734     Frame* coreFrame = core(frame);
735     if (!coreFrame)
736         return GTK_PRINT_OPERATION_RESULT_ERROR;
737 
738     PrintContext printContext(coreFrame);
739 
740     g_signal_connect(operation, "begin-print", G_CALLBACK(begin_print_callback), &printContext);
741     g_signal_connect(operation, "draw-page", G_CALLBACK(draw_page_callback), &printContext);
742     g_signal_connect(operation, "end-print", G_CALLBACK(end_print_callback), &printContext);
743 
744     return gtk_print_operation_run(operation, action, GTK_WINDOW(topLevel), error);
745 }
746 
747 /**
748  * webkit_web_frame_print:
749  * @frame: a #WebKitWebFrame
750  *
751  * Prints the given #WebKitFrame, by presenting a print dialog to the
752  * user. If you need more control over the printing process, see
753  * webkit_web_frame_print_full().
754  *
755  * Since: 1.1.5
756  */
webkit_web_frame_print(WebKitWebFrame * frame)757 void webkit_web_frame_print(WebKitWebFrame* frame)
758 {
759     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
760 
761     WebKitWebFramePrivate* priv = frame->priv;
762     GtkPrintOperation* operation = gtk_print_operation_new();
763     GError* error = 0;
764 
765     webkit_web_frame_print_full(frame, operation, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, &error);
766     g_object_unref(operation);
767 
768     if (error) {
769         GtkWidget* window = gtk_widget_get_toplevel(GTK_WIDGET(priv->webView));
770         GtkWidget* dialog = gtk_message_dialog_new(GTK_WIDGET_TOPLEVEL(window) ? GTK_WINDOW(window) : 0,
771                                                    GTK_DIALOG_DESTROY_WITH_PARENT,
772                                                    GTK_MESSAGE_ERROR,
773                                                    GTK_BUTTONS_CLOSE,
774                                                    "%s", error->message);
775         g_error_free(error);
776 
777         g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL);
778         gtk_widget_show(dialog);
779     }
780 }
781 
webkit_web_frame_pause_animation(WebKitWebFrame * frame,const gchar * name,double time,const gchar * element)782 bool webkit_web_frame_pause_animation(WebKitWebFrame* frame, const gchar* name, double time, const gchar* element)
783 {
784     ASSERT(core(frame));
785     Element* coreElement = core(frame)->document()->getElementById(AtomicString(element));
786     if (!coreElement || !coreElement->renderer())
787         return false;
788     return core(frame)->animation()->pauseAnimationAtTime(coreElement->renderer(), AtomicString(name), time);
789 }
790 
webkit_web_frame_pause_transition(WebKitWebFrame * frame,const gchar * name,double time,const gchar * element)791 bool webkit_web_frame_pause_transition(WebKitWebFrame* frame, const gchar* name, double time, const gchar* element)
792 {
793     ASSERT(core(frame));
794     Element* coreElement = core(frame)->document()->getElementById(AtomicString(element));
795     if (!coreElement || !coreElement->renderer())
796         return false;
797     return core(frame)->animation()->pauseTransitionAtTime(coreElement->renderer(), AtomicString(name), time);
798 }
799 
webkit_web_frame_number_of_active_animations(WebKitWebFrame * frame)800 unsigned int webkit_web_frame_number_of_active_animations(WebKitWebFrame* frame)
801 {
802     Frame* coreFrame = core(frame);
803     if (!coreFrame)
804         return 0;
805 
806     AnimationController* controller = coreFrame->animation();
807     if (!controller)
808         return 0;
809 
810     return controller->numberOfActiveAnimations();
811 }
812 
webkit_web_frame_get_response_mime_type(WebKitWebFrame * frame)813 gchar* webkit_web_frame_get_response_mime_type(WebKitWebFrame* frame)
814 {
815     Frame* coreFrame = core(frame);
816     DocumentLoader* docLoader = coreFrame->loader()->documentLoader();
817     String mimeType = docLoader->responseMIMEType();
818     return g_strdup(mimeType.utf8().data());
819 }
820 
821 /**
822  * webkit_web_frame_get_load_status:
823  * @frame: a #WebKitWebView
824  *
825  * Determines the current status of the load.
826  *
827  * Since: 1.1.7
828  */
webkit_web_frame_get_load_status(WebKitWebFrame * frame)829 WebKitLoadStatus webkit_web_frame_get_load_status(WebKitWebFrame* frame)
830 {
831     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), WEBKIT_LOAD_FINISHED);
832 
833     WebKitWebFramePrivate* priv = frame->priv;
834     return priv->loadStatus;
835 }
836 
webkit_web_frame_clear_main_frame_name(WebKitWebFrame * frame)837 void webkit_web_frame_clear_main_frame_name(WebKitWebFrame* frame)
838 {
839     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
840 
841     core(frame)->tree()->clearName();
842 }
843 
webkit_gc_collect_javascript_objects()844 void webkit_gc_collect_javascript_objects()
845 {
846     gcController().garbageCollectNow();
847 }
848 
webkit_gc_collect_javascript_objects_on_alternate_thread(gboolean waitUntilDone)849 void webkit_gc_collect_javascript_objects_on_alternate_thread(gboolean waitUntilDone)
850 {
851     gcController().garbageCollectOnAlternateThreadForDebugging(waitUntilDone);
852 }
853 
webkit_gc_count_javascript_objects()854 gsize webkit_gc_count_javascript_objects()
855 {
856     JSC::JSLock lock(JSC::SilenceAssertionsOnly);
857     return JSDOMWindow::commonJSGlobalData()->heap.objectCount();
858 
859 }
860 
webkit_web_frame_get_focused_accessible_element(WebKitWebFrame * frame)861 AtkObject* webkit_web_frame_get_focused_accessible_element(WebKitWebFrame* frame)
862 {
863     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL);
864 
865 #if HAVE(ACCESSIBILITY)
866     if (!AXObjectCache::accessibilityEnabled())
867         AXObjectCache::enableAccessibility();
868 
869     WebKitWebFramePrivate* priv = frame->priv;
870     if (!priv->coreFrame || !priv->coreFrame->document())
871         return NULL;
872 
873     RenderView* root = toRenderView(priv->coreFrame->document()->renderer());
874     if (!root)
875         return NULL;
876 
877     AtkObject* wrapper =  priv->coreFrame->document()->axObjectCache()->getOrCreate(root)->wrapper();
878     if (!wrapper)
879         return NULL;
880 
881     return webkit_accessible_get_focused_element(WEBKIT_ACCESSIBLE(wrapper));
882 #else
883     return NULL;
884 #endif
885 }
886