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