1 /* 2 * Copyright (C) 2007, 2008 Holger Hans Peter Freyther 3 * Copyright (C) 2007 Alp Toker <alp (at) atoker.com> 4 * Copyright (C) 2007 Apple Inc. 5 * Copyright (C) 2008 Christian Dywan <christian (at) imendio.com> 6 * Copyright (C) 2008 Collabora Ltd. 7 * Copyright (C) 2008 Nuanti Ltd. 8 * Copyright (C) 2009 Jan Alonzo <jmalonzo (at) gmail.com> 9 * Copyright (C) 2009 Gustavo Noronha Silva <gns (at) 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 "DocumentLoaderGtk.h" 41 #include "FrameLoader.h" 42 #include "FrameLoaderClientGtk.h" 43 #include "FrameTree.h" 44 #include "FrameView.h" 45 #include <glib/gi18n-lib.h> 46 #include "GCController.h" 47 #include "GraphicsContext.h" 48 #include "HTMLFrameOwnerElement.h" 49 #include "JSDOMWindow.h" 50 #include "JSLock.h" 51 #include "PrintContext.h" 52 #include "RenderView.h" 53 #include "RenderTreeAsText.h" 54 #include "JSDOMBinding.h" 55 #include "ScriptController.h" 56 #include "SubstituteData.h" 57 #if ENABLE(SVG) 58 #include "SVGSMILElement.h" 59 #endif 60 61 #include <atk/atk.h> 62 #include <JavaScriptCore/APICast.h> 63 64 /** 65 * SECTION:webkitwebframe 66 * @short_description: The content of a #WebKitWebView 67 * 68 * A #WebKitWebView contains a main #WebKitWebFrame. A #WebKitWebFrame 69 * contains the content of one URI. The URI and name of the frame can 70 * be retrieved, the load status and progress can be observed using the 71 * signals and can be controlled using the methods of the #WebKitWebFrame. 72 * A #WebKitWebFrame can have any number of children and one child can 73 * be found by using #webkit_web_frame_find_frame. 74 * 75 * <informalexample><programlisting> 76 * /<!-- -->* Get the frame from the #WebKitWebView *<!-- -->/ 77 * WebKitWebFrame *frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW(my_view)); 78 * g_print("The URI of this frame is '%s'", webkit_web_frame_get_uri (frame)); 79 * </programlisting></informalexample> 80 */ 81 82 using namespace WebKit; 83 using namespace WebCore; 84 using namespace std; 85 86 enum { 87 CLEARED, 88 LOAD_COMMITTED, 89 LOAD_DONE, 90 TITLE_CHANGED, 91 HOVERING_OVER_LINK, 92 SCROLLBARS_POLICY_CHANGED, 93 LAST_SIGNAL 94 }; 95 96 enum { 97 PROP_0, 98 99 PROP_NAME, 100 PROP_TITLE, 101 PROP_URI, 102 PROP_LOAD_STATUS, 103 PROP_HORIZONTAL_SCROLLBAR_POLICY, 104 PROP_VERTICAL_SCROLLBAR_POLICY 105 }; 106 107 static guint webkit_web_frame_signals[LAST_SIGNAL] = { 0, }; 108 109 G_DEFINE_TYPE(WebKitWebFrame, webkit_web_frame, G_TYPE_OBJECT) 110 111 static void webkit_web_frame_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec) 112 { 113 WebKitWebFrame* frame = WEBKIT_WEB_FRAME(object); 114 115 switch(prop_id) { 116 case PROP_NAME: 117 g_value_set_string(value, webkit_web_frame_get_name(frame)); 118 break; 119 case PROP_TITLE: 120 g_value_set_string(value, webkit_web_frame_get_title(frame)); 121 break; 122 case PROP_URI: 123 g_value_set_string(value, webkit_web_frame_get_uri(frame)); 124 break; 125 case PROP_LOAD_STATUS: 126 g_value_set_enum(value, webkit_web_frame_get_load_status(frame)); 127 break; 128 case PROP_HORIZONTAL_SCROLLBAR_POLICY: 129 g_value_set_enum(value, webkit_web_frame_get_horizontal_scrollbar_policy(frame)); 130 break; 131 case PROP_VERTICAL_SCROLLBAR_POLICY: 132 g_value_set_enum(value, webkit_web_frame_get_vertical_scrollbar_policy(frame)); 133 break; 134 default: 135 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); 136 break; 137 } 138 } 139 140 // Called from the FrameLoaderClient when it is destroyed. Normally 141 // the unref in the FrameLoaderClient is destroying this object as 142 // well but due reference counting a user might have added a reference... 143 void webkit_web_frame_core_frame_gone(WebKitWebFrame* frame) 144 { 145 ASSERT(WEBKIT_IS_WEB_FRAME(frame)); 146 frame->priv->coreFrame = 0; 147 } 148 149 static WebKitWebDataSource* webkit_web_frame_get_data_source_from_core_loader(WebCore::DocumentLoader* loader) 150 { 151 return loader ? static_cast<WebKit::DocumentLoader*>(loader)->dataSource() : NULL; 152 } 153 154 static void webkit_web_frame_finalize(GObject* object) 155 { 156 WebKitWebFrame* frame = WEBKIT_WEB_FRAME(object); 157 WebKitWebFramePrivate* priv = frame->priv; 158 159 if (priv->coreFrame) { 160 priv->coreFrame->loader()->cancelAndClear(); 161 priv->coreFrame = 0; 162 } 163 164 g_free(priv->name); 165 g_free(priv->title); 166 g_free(priv->uri); 167 168 G_OBJECT_CLASS(webkit_web_frame_parent_class)->finalize(object); 169 } 170 171 static void webkit_web_frame_class_init(WebKitWebFrameClass* frameClass) 172 { 173 webkit_init(); 174 175 /* 176 * signals 177 */ 178 webkit_web_frame_signals[CLEARED] = g_signal_new("cleared", 179 G_TYPE_FROM_CLASS(frameClass), 180 (GSignalFlags)G_SIGNAL_RUN_LAST, 181 0, 182 NULL, 183 NULL, 184 g_cclosure_marshal_VOID__VOID, 185 G_TYPE_NONE, 0); 186 187 /** 188 * WebKitWebFrame::load-done 189 * @web_frame: the object on which the signal is emitted 190 * 191 * Emitted when frame loading is done. 192 * 193 * Deprecated: Use the "load-status" property instead. 194 */ 195 webkit_web_frame_signals[LOAD_COMMITTED] = g_signal_new("load-committed", 196 G_TYPE_FROM_CLASS(frameClass), 197 (GSignalFlags)G_SIGNAL_RUN_LAST, 198 0, 199 NULL, 200 NULL, 201 g_cclosure_marshal_VOID__VOID, 202 G_TYPE_NONE, 0); 203 204 /** 205 * WebKitWebFrame::load-done 206 * @web_frame: the object on which the signal is emitted 207 * 208 * Emitted when frame loading is done. 209 * 210 * Deprecated: Use the "load-status" property instead, and/or 211 * WebKitWebView::load-error to be notified of load errors 212 */ 213 webkit_web_frame_signals[LOAD_DONE] = g_signal_new("load-done", 214 G_TYPE_FROM_CLASS(frameClass), 215 (GSignalFlags)G_SIGNAL_RUN_LAST, 216 0, 217 NULL, 218 NULL, 219 g_cclosure_marshal_VOID__BOOLEAN, 220 G_TYPE_NONE, 1, 221 G_TYPE_BOOLEAN); 222 223 /** 224 * WebKitWebFrame::title-changed: 225 * @frame: the object on which the signal is emitted 226 * @title: the new title 227 * 228 * When a #WebKitWebFrame changes the document title this signal is emitted. 229 * 230 * Deprecated: 1.1.18: Use "notify::title" instead. 231 */ 232 webkit_web_frame_signals[TITLE_CHANGED] = g_signal_new("title-changed", 233 G_TYPE_FROM_CLASS(frameClass), 234 (GSignalFlags)G_SIGNAL_RUN_LAST, 235 0, 236 NULL, 237 NULL, 238 webkit_marshal_VOID__STRING, 239 G_TYPE_NONE, 1, 240 G_TYPE_STRING); 241 242 webkit_web_frame_signals[HOVERING_OVER_LINK] = g_signal_new("hovering-over-link", 243 G_TYPE_FROM_CLASS(frameClass), 244 (GSignalFlags)G_SIGNAL_RUN_LAST, 245 0, 246 NULL, 247 NULL, 248 webkit_marshal_VOID__STRING_STRING, 249 G_TYPE_NONE, 2, 250 G_TYPE_STRING, G_TYPE_STRING); 251 252 /** 253 * WebKitWebFrame::scrollbars-policy-changed: 254 * @web_view: the object which received the signal 255 * 256 * Signal emitted when policy for one or both of the scrollbars of 257 * the view has changed. The default handler will apply the new 258 * policy to the container that holds the #WebKitWebFrame if it is 259 * a #GtkScrolledWindow and the frame is the main frame. If you do 260 * not want this to be handled automatically, you need to handle 261 * this signal. 262 * 263 * The exception to this rule is that policies to disable the 264 * scrollbars are applied as %GTK_POLICY_AUTOMATIC instead, since 265 * the size request of the widget would force browser windows to 266 * not be resizable. 267 * 268 * You can obtain the new policies from the 269 * WebKitWebFrame:horizontal-scrollbar-policy and 270 * WebKitWebFrame:vertical-scrollbar-policy properties. 271 * 272 * Return value: %TRUE to stop other handlers from being invoked for the 273 * event. %FALSE to propagate the event further. 274 * 275 * Since: 1.1.14 276 */ 277 webkit_web_frame_signals[SCROLLBARS_POLICY_CHANGED] = g_signal_new("scrollbars-policy-changed", 278 G_TYPE_FROM_CLASS(frameClass), 279 (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), 280 0, 281 g_signal_accumulator_true_handled, 282 NULL, 283 webkit_marshal_BOOLEAN__VOID, 284 G_TYPE_BOOLEAN, 0); 285 286 /* 287 * implementations of virtual methods 288 */ 289 GObjectClass* objectClass = G_OBJECT_CLASS(frameClass); 290 objectClass->finalize = webkit_web_frame_finalize; 291 objectClass->get_property = webkit_web_frame_get_property; 292 293 /* 294 * properties 295 */ 296 g_object_class_install_property(objectClass, PROP_NAME, 297 g_param_spec_string("name", 298 _("Name"), 299 _("The name of the frame"), 300 NULL, 301 WEBKIT_PARAM_READABLE)); 302 303 g_object_class_install_property(objectClass, PROP_TITLE, 304 g_param_spec_string("title", 305 _("Title"), 306 _("The document title of the frame"), 307 NULL, 308 WEBKIT_PARAM_READABLE)); 309 310 g_object_class_install_property(objectClass, PROP_URI, 311 g_param_spec_string("uri", 312 _("URI"), 313 _("The current URI of the contents displayed by the frame"), 314 NULL, 315 WEBKIT_PARAM_READABLE)); 316 317 /** 318 * WebKitWebFrame:load-status: 319 * 320 * Determines the current status of the load. 321 * 322 * Since: 1.1.7 323 */ 324 g_object_class_install_property(objectClass, PROP_LOAD_STATUS, 325 g_param_spec_enum("load-status", 326 "Load Status", 327 "Determines the current status of the load", 328 WEBKIT_TYPE_LOAD_STATUS, 329 WEBKIT_LOAD_FINISHED, 330 WEBKIT_PARAM_READABLE)); 331 332 /** 333 * WebKitWebFrame:horizontal-scrollbar-policy: 334 * 335 * Determines the current policy for the horizontal scrollbar of 336 * the frame. For the main frame, make sure to set the same policy 337 * on the scrollable widget containing the #WebKitWebView, unless 338 * you know what you are doing. 339 * 340 * Since: 1.1.14 341 */ 342 g_object_class_install_property(objectClass, PROP_HORIZONTAL_SCROLLBAR_POLICY, 343 g_param_spec_enum("horizontal-scrollbar-policy", 344 _("Horizontal Scrollbar Policy"), 345 _("Determines the current policy for the horizontal scrollbar of the frame."), 346 GTK_TYPE_POLICY_TYPE, 347 GTK_POLICY_AUTOMATIC, 348 WEBKIT_PARAM_READABLE)); 349 350 /** 351 * WebKitWebFrame:vertical-scrollbar-policy: 352 * 353 * Determines the current policy for the vertical scrollbar of 354 * the frame. For the main frame, make sure to set the same policy 355 * on the scrollable widget containing the #WebKitWebView, unless 356 * you know what you are doing. 357 * 358 * Since: 1.1.14 359 */ 360 g_object_class_install_property(objectClass, PROP_VERTICAL_SCROLLBAR_POLICY, 361 g_param_spec_enum("vertical-scrollbar-policy", 362 _("Vertical Scrollbar Policy"), 363 _("Determines the current policy for the vertical scrollbar of the frame."), 364 GTK_TYPE_POLICY_TYPE, 365 GTK_POLICY_AUTOMATIC, 366 WEBKIT_PARAM_READABLE)); 367 368 g_type_class_add_private(frameClass, sizeof(WebKitWebFramePrivate)); 369 } 370 371 static void webkit_web_frame_init(WebKitWebFrame* frame) 372 { 373 WebKitWebFramePrivate* priv = WEBKIT_WEB_FRAME_GET_PRIVATE(frame); 374 375 // TODO: Move constructor code here. 376 frame->priv = priv; 377 } 378 379 /** 380 * webkit_web_frame_new: 381 * @web_view: the controlling #WebKitWebView 382 * 383 * Creates a new #WebKitWebFrame initialized with a controlling #WebKitWebView. 384 * 385 * Returns: a new #WebKitWebFrame 386 * 387 * Deprecated: 1.0.2: #WebKitWebFrame can only be used to inspect existing 388 * frames. 389 **/ 390 WebKitWebFrame* webkit_web_frame_new(WebKitWebView* webView) 391 { 392 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL); 393 394 WebKitWebFrame* frame = WEBKIT_WEB_FRAME(g_object_new(WEBKIT_TYPE_WEB_FRAME, NULL)); 395 WebKitWebFramePrivate* priv = frame->priv; 396 WebKitWebViewPrivate* viewPriv = WEBKIT_WEB_VIEW_GET_PRIVATE(webView); 397 398 priv->webView = webView; 399 WebKit::FrameLoaderClient* client = new WebKit::FrameLoaderClient(frame); 400 priv->coreFrame = Frame::create(viewPriv->corePage, 0, client).get(); 401 priv->coreFrame->init(); 402 403 priv->origin = NULL; 404 405 return frame; 406 } 407 408 PassRefPtr<Frame> webkit_web_frame_init_with_web_view(WebKitWebView* webView, HTMLFrameOwnerElement* element) 409 { 410 WebKitWebFrame* frame = WEBKIT_WEB_FRAME(g_object_new(WEBKIT_TYPE_WEB_FRAME, NULL)); 411 WebKitWebFramePrivate* priv = frame->priv; 412 WebKitWebViewPrivate* viewPriv = WEBKIT_WEB_VIEW_GET_PRIVATE(webView); 413 414 priv->webView = webView; 415 WebKit::FrameLoaderClient* client = new WebKit::FrameLoaderClient(frame); 416 417 RefPtr<Frame> coreFrame = Frame::create(viewPriv->corePage, element, client); 418 priv->coreFrame = coreFrame.get(); 419 420 return coreFrame.release(); 421 } 422 423 /** 424 * webkit_web_frame_get_title: 425 * @frame: a #WebKitWebFrame 426 * 427 * Returns the @frame's document title 428 * 429 * Return value: the title of @frame 430 */ 431 G_CONST_RETURN gchar* webkit_web_frame_get_title(WebKitWebFrame* frame) 432 { 433 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL); 434 435 WebKitWebFramePrivate* priv = frame->priv; 436 return priv->title; 437 } 438 439 /** 440 * webkit_web_frame_get_uri: 441 * @frame: a #WebKitWebFrame 442 * 443 * Returns the current URI of the contents displayed by the @frame 444 * 445 * Return value: the URI of @frame 446 */ 447 G_CONST_RETURN gchar* webkit_web_frame_get_uri(WebKitWebFrame* frame) 448 { 449 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL); 450 451 WebKitWebFramePrivate* priv = frame->priv; 452 return priv->uri; 453 } 454 455 /** 456 * webkit_web_frame_get_web_view: 457 * @frame: a #WebKitWebFrame 458 * 459 * Returns the #WebKitWebView that manages this #WebKitWebFrame. 460 * 461 * The #WebKitWebView returned manages the entire hierarchy of #WebKitWebFrame 462 * objects that contains @frame. 463 * 464 * Return value: the #WebKitWebView that manages @frame 465 */ 466 WebKitWebView* webkit_web_frame_get_web_view(WebKitWebFrame* frame) 467 { 468 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL); 469 470 WebKitWebFramePrivate* priv = frame->priv; 471 return priv->webView; 472 } 473 474 /** 475 * webkit_web_frame_get_name: 476 * @frame: a #WebKitWebFrame 477 * 478 * Returns the @frame's name 479 * 480 * Return value: the name of @frame 481 */ 482 G_CONST_RETURN gchar* webkit_web_frame_get_name(WebKitWebFrame* frame) 483 { 484 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL); 485 486 WebKitWebFramePrivate* priv = frame->priv; 487 488 if (priv->name) 489 return priv->name; 490 491 Frame* coreFrame = core(frame); 492 if (!coreFrame) 493 return ""; 494 495 String string = coreFrame->tree()->name(); 496 priv->name = g_strdup(string.utf8().data()); 497 return priv->name; 498 } 499 500 /** 501 * webkit_web_frame_get_parent: 502 * @frame: a #WebKitWebFrame 503 * 504 * Returns the @frame's parent frame, or %NULL if it has none. 505 * 506 * Return value: the parent #WebKitWebFrame or %NULL in case there is none 507 */ 508 WebKitWebFrame* webkit_web_frame_get_parent(WebKitWebFrame* frame) 509 { 510 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL); 511 512 Frame* coreFrame = core(frame); 513 if (!coreFrame) 514 return NULL; 515 516 return kit(coreFrame->tree()->parent()); 517 } 518 519 /** 520 * webkit_web_frame_load_uri: 521 * @frame: a #WebKitWebFrame 522 * @uri: an URI string 523 * 524 * Requests loading of the specified URI string. 525 * 526 * Since: 1.1.1 527 */ 528 void webkit_web_frame_load_uri(WebKitWebFrame* frame, const gchar* uri) 529 { 530 g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame)); 531 g_return_if_fail(uri); 532 533 Frame* coreFrame = core(frame); 534 if (!coreFrame) 535 return; 536 537 coreFrame->loader()->load(ResourceRequest(KURL(KURL(), String::fromUTF8(uri))), false); 538 } 539 540 static void webkit_web_frame_load_data(WebKitWebFrame* frame, const gchar* content, const gchar* mimeType, const gchar* encoding, const gchar* baseURL, const gchar* unreachableURL) 541 { 542 Frame* coreFrame = core(frame); 543 ASSERT(coreFrame); 544 545 KURL baseKURL = baseURL ? KURL(KURL(), String::fromUTF8(baseURL)) : blankURL(); 546 547 ResourceRequest request(baseKURL); 548 549 RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(content, strlen(content)); 550 SubstituteData substituteData(sharedBuffer.release(), 551 mimeType ? String::fromUTF8(mimeType) : String::fromUTF8("text/html"), 552 encoding ? String::fromUTF8(encoding) : String::fromUTF8("UTF-8"), 553 KURL(KURL(), String::fromUTF8(unreachableURL)), 554 KURL(KURL(), String::fromUTF8(unreachableURL))); 555 556 coreFrame->loader()->load(request, substituteData, false); 557 } 558 559 /** 560 * webkit_web_frame_load_string: 561 * @frame: a #WebKitWebFrame 562 * @content: an URI string 563 * @mime_type: the MIME type, or %NULL 564 * @encoding: the encoding, or %NULL 565 * @base_uri: the base URI for relative locations 566 * 567 * Requests loading of the given @content with the specified @mime_type, 568 * @encoding and @base_uri. 569 * 570 * If @mime_type is %NULL, "text/html" is assumed. 571 * 572 * If @encoding is %NULL, "UTF-8" is assumed. 573 * 574 * Since: 1.1.1 575 */ 576 void webkit_web_frame_load_string(WebKitWebFrame* frame, const gchar* content, const gchar* contentMimeType, const gchar* contentEncoding, const gchar* baseUri) 577 { 578 g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame)); 579 g_return_if_fail(content); 580 581 webkit_web_frame_load_data(frame, content, contentMimeType, contentEncoding, baseUri, NULL); 582 } 583 584 /** 585 * webkit_web_frame_load_alternate_string: 586 * @frame: a #WebKitWebFrame 587 * @content: the alternate content to display as the main page of the @frame 588 * @base_url: the base URI for relative locations 589 * @unreachable_url: the URL for the alternate page content 590 * 591 * Request loading of an alternate content for a URL that is unreachable. 592 * Using this method will preserve the back-forward list. The URI passed in 593 * @base_url has to be an absolute URI. 594 * 595 * Since: 1.1.6 596 */ 597 void webkit_web_frame_load_alternate_string(WebKitWebFrame* frame, const gchar* content, const gchar* baseURL, const gchar* unreachableURL) 598 { 599 g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame)); 600 g_return_if_fail(content); 601 602 webkit_web_frame_load_data(frame, content, NULL, NULL, baseURL, unreachableURL); 603 } 604 605 /** 606 * webkit_web_frame_load_request: 607 * @frame: a #WebKitWebFrame 608 * @request: a #WebKitNetworkRequest 609 * 610 * Connects to a given URI by initiating an asynchronous client request. 611 * 612 * Creates a provisional data source that will transition to a committed data 613 * source once any data has been received. Use webkit_web_frame_stop_loading() to 614 * stop the load. This function is typically invoked on the main frame. 615 */ 616 void webkit_web_frame_load_request(WebKitWebFrame* frame, WebKitNetworkRequest* request) 617 { 618 g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame)); 619 g_return_if_fail(WEBKIT_IS_NETWORK_REQUEST(request)); 620 621 Frame* coreFrame = core(frame); 622 if (!coreFrame) 623 return; 624 625 coreFrame->loader()->load(core(request), false); 626 } 627 628 /** 629 * webkit_web_frame_stop_loading: 630 * @frame: a #WebKitWebFrame 631 * 632 * Stops any pending loads on @frame's data source, and those of its children. 633 */ 634 void webkit_web_frame_stop_loading(WebKitWebFrame* frame) 635 { 636 g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame)); 637 638 Frame* coreFrame = core(frame); 639 if (!coreFrame) 640 return; 641 642 coreFrame->loader()->stopAllLoaders(); 643 } 644 645 /** 646 * webkit_web_frame_reload: 647 * @frame: a #WebKitWebFrame 648 * 649 * Reloads the initial request. 650 */ 651 void webkit_web_frame_reload(WebKitWebFrame* frame) 652 { 653 g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame)); 654 655 Frame* coreFrame = core(frame); 656 if (!coreFrame) 657 return; 658 659 coreFrame->loader()->reload(); 660 } 661 662 /** 663 * webkit_web_frame_find_frame: 664 * @frame: a #WebKitWebFrame 665 * @name: the name of the frame to be found 666 * 667 * For pre-defined names, returns @frame if @name is "_self" or "_current", 668 * returns @frame's parent frame if @name is "_parent", and returns the main 669 * frame if @name is "_top". Also returns @frame if it is the main frame and 670 * @name is either "_parent" or "_top". For other names, this function returns 671 * the first frame that matches @name. This function searches @frame and its 672 * descendents first, then @frame's parent and its children moving up the 673 * hierarchy until a match is found. If no match is found in @frame's 674 * hierarchy, this function will search for a matching frame in other main 675 * frame hierarchies. Returns %NULL if no match is found. 676 * 677 * Return value: the found #WebKitWebFrame or %NULL in case none is found 678 */ 679 WebKitWebFrame* webkit_web_frame_find_frame(WebKitWebFrame* frame, const gchar* name) 680 { 681 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL); 682 g_return_val_if_fail(name, NULL); 683 684 Frame* coreFrame = core(frame); 685 if (!coreFrame) 686 return NULL; 687 688 String nameString = String::fromUTF8(name); 689 return kit(coreFrame->tree()->find(AtomicString(nameString))); 690 } 691 692 /** 693 * webkit_web_frame_get_global_context: 694 * @frame: a #WebKitWebFrame 695 * 696 * Gets the global JavaScript execution context. Use this function to bridge 697 * between the WebKit and JavaScriptCore APIs. 698 * 699 * Return value: the global JavaScript context 700 */ 701 JSGlobalContextRef webkit_web_frame_get_global_context(WebKitWebFrame* frame) 702 { 703 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL); 704 705 Frame* coreFrame = core(frame); 706 if (!coreFrame) 707 return NULL; 708 709 return toGlobalRef(coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec()); 710 } 711 712 /** 713 * webkit_web_frame_get_data_source: 714 * @frame: a #WebKitWebFrame 715 * 716 * Returns the committed data source. 717 * 718 * Return value: the committed #WebKitWebDataSource. 719 * 720 * Since: 1.1.14 721 */ 722 WebKitWebDataSource* webkit_web_frame_get_data_source(WebKitWebFrame* frame) 723 { 724 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL); 725 726 Frame* coreFrame = core(frame); 727 return webkit_web_frame_get_data_source_from_core_loader(coreFrame->loader()->documentLoader()); 728 } 729 730 /** 731 * webkit_web_frame_get_provisional_data_source: 732 * @frame: a #WebKitWebFrame 733 * 734 * You use the webkit_web_frame_load_request method to initiate a request that 735 * creates a provisional data source. The provisional data source will 736 * transition to a committed data source once any data has been received. Use 737 * webkit_web_frame_get_data_source to get the committed data source. 738 * 739 * Return value: the provisional #WebKitWebDataSource or %NULL if a load 740 * request is not in progress. 741 * 742 * Since: 1.1.14 743 */ 744 WebKitWebDataSource* webkit_web_frame_get_provisional_data_source(WebKitWebFrame* frame) 745 { 746 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL); 747 748 Frame* coreFrame = core(frame); 749 return webkit_web_frame_get_data_source_from_core_loader(coreFrame->loader()->provisionalDocumentLoader()); 750 } 751 752 /** 753 * webkit_web_frame_get_children: 754 * @frame: a #WebKitWebFrame 755 * 756 * Return value: child frames of @frame 757 */ 758 GSList* webkit_web_frame_get_children(WebKitWebFrame* frame) 759 { 760 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL); 761 762 Frame* coreFrame = core(frame); 763 if (!coreFrame) 764 return NULL; 765 766 GSList* children = NULL; 767 for (Frame* child = coreFrame->tree()->firstChild(); child; child = child->tree()->nextSibling()) { 768 FrameLoader* loader = child->loader(); 769 WebKit::FrameLoaderClient* client = static_cast<WebKit::FrameLoaderClient*>(loader->client()); 770 if (client) 771 children = g_slist_append(children, client->webFrame()); 772 } 773 774 return children; 775 } 776 777 /** 778 * webkit_web_frame_get_inner_text: 779 * @frame: a #WebKitWebFrame 780 * 781 * Return value: inner text of @frame 782 */ 783 gchar* webkit_web_frame_get_inner_text(WebKitWebFrame* frame) 784 { 785 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL); 786 787 Frame* coreFrame = core(frame); 788 if (!coreFrame) 789 return g_strdup(""); 790 791 FrameView* view = coreFrame->view(); 792 793 if (view && view->layoutPending()) 794 view->layout(); 795 796 Element* documentElement = coreFrame->document()->documentElement(); 797 String string = documentElement->innerText(); 798 return g_strdup(string.utf8().data()); 799 } 800 801 /** 802 * webkit_web_frame_dump_render_tree: 803 * @frame: a #WebKitWebFrame 804 * 805 * Return value: Non-recursive render tree dump of @frame 806 */ 807 gchar* webkit_web_frame_dump_render_tree(WebKitWebFrame* frame) 808 { 809 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL); 810 811 Frame* coreFrame = core(frame); 812 if (!coreFrame) 813 return g_strdup(""); 814 815 FrameView* view = coreFrame->view(); 816 817 if (view && view->layoutPending()) 818 view->layout(); 819 820 String string = externalRepresentation(coreFrame); 821 return g_strdup(string.utf8().data()); 822 } 823 824 /** 825 * webkit_web_frame_counter_value_for_element_by_id: 826 * @frame: a #WebKitWebFrame 827 * @id: an element ID string 828 * 829 * Return value: The counter value of element @id in @frame 830 */ 831 gchar* webkit_web_frame_counter_value_for_element_by_id(WebKitWebFrame* frame, const gchar* id) 832 { 833 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL); 834 835 Frame* coreFrame = core(frame); 836 if (!coreFrame) 837 return 0; 838 839 Element* coreElement = coreFrame->document()->getElementById(AtomicString(id)); 840 if (!coreElement) 841 return 0; 842 String counterValue = counterValueForElement(coreElement); 843 return g_strdup(counterValue.utf8().data()); 844 } 845 846 /** 847 * webkit_web_frame_page_number_for_element_by_id 848 * @frame: a #WebKitWebFrame 849 * @id: an element ID string 850 * @pageWidth: width of a page 851 * @pageHeight: height of a page 852 * 853 * Return value: The number of page where the specified element will be put 854 */ 855 int webkit_web_frame_page_number_for_element_by_id(WebKitWebFrame* frame, const gchar* id, float pageWidth, float pageHeight) 856 { 857 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL); 858 859 Frame* coreFrame = core(frame); 860 if (!coreFrame) 861 return -1; 862 863 Element* coreElement = coreFrame->document()->getElementById(AtomicString(id)); 864 if (!coreElement) 865 return -1; 866 return PrintContext::pageNumberForElement(coreElement, FloatSize(pageWidth, pageHeight)); 867 } 868 869 /** 870 * webkit_web_frame_get_pending_unload_event_count: 871 * @frame: a #WebKitWebFrame 872 * 873 * Return value: number of pending unload events 874 */ 875 guint webkit_web_frame_get_pending_unload_event_count(WebKitWebFrame* frame) 876 { 877 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0); 878 879 return core(frame)->domWindow()->pendingUnloadEventListeners(); 880 } 881 882 static void begin_print_callback(GtkPrintOperation* op, GtkPrintContext* context, gpointer user_data) 883 { 884 PrintContext* printContext = reinterpret_cast<PrintContext*>(user_data); 885 886 float width = gtk_print_context_get_width(context); 887 float height = gtk_print_context_get_height(context); 888 FloatRect printRect = FloatRect(0, 0, width, height); 889 890 printContext->begin(width); 891 892 // TODO: Margin adjustments and header/footer support 893 float headerHeight = 0; 894 float footerHeight = 0; 895 float pageHeight; // height of the page adjusted by margins 896 printContext->computePageRects(printRect, headerHeight, footerHeight, 1.0, pageHeight); 897 gtk_print_operation_set_n_pages(op, printContext->pageCount()); 898 } 899 900 static void draw_page_callback(GtkPrintOperation* op, GtkPrintContext* context, gint page_nr, gpointer user_data) 901 { 902 PrintContext* printContext = reinterpret_cast<PrintContext*>(user_data); 903 904 if (page_nr >= printContext->pageCount()) 905 return; 906 907 cairo_t* cr = gtk_print_context_get_cairo_context(context); 908 GraphicsContext ctx(cr); 909 float width = gtk_print_context_get_width(context); 910 printContext->spoolPage(ctx, page_nr, width); 911 } 912 913 static void end_print_callback(GtkPrintOperation* op, GtkPrintContext* context, gpointer user_data) 914 { 915 PrintContext* printContext = reinterpret_cast<PrintContext*>(user_data); 916 printContext->end(); 917 } 918 919 /** 920 * webkit_web_frame_print_full: 921 * @frame: a #WebKitWebFrame to be printed 922 * @operation: the #GtkPrintOperation to be carried 923 * @action: the #GtkPrintOperationAction to be performed 924 * @error: #GError for error return 925 * 926 * Prints the given #WebKitFrame, using the given #GtkPrintOperation 927 * and #GtkPrintOperationAction. This function wraps a call to 928 * gtk_print_operation_run() for printing the contents of the 929 * #WebKitWebFrame. 930 * 931 * Since: 1.1.5 932 */ 933 GtkPrintOperationResult webkit_web_frame_print_full(WebKitWebFrame* frame, GtkPrintOperation* operation, GtkPrintOperationAction action, GError** error) 934 { 935 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), GTK_PRINT_OPERATION_RESULT_ERROR); 936 g_return_val_if_fail(GTK_IS_PRINT_OPERATION(operation), GTK_PRINT_OPERATION_RESULT_ERROR); 937 938 GtkWidget* topLevel = gtk_widget_get_toplevel(GTK_WIDGET(webkit_web_frame_get_web_view(frame))); 939 940 #if GTK_CHECK_VERSION(2, 18, 0) 941 if (!gtk_widget_is_toplevel(topLevel)) 942 #else 943 if (!GTK_WIDGET_TOPLEVEL(topLevel)) 944 #endif 945 topLevel = NULL; 946 947 Frame* coreFrame = core(frame); 948 if (!coreFrame) 949 return GTK_PRINT_OPERATION_RESULT_ERROR; 950 951 PrintContext printContext(coreFrame); 952 953 g_signal_connect(operation, "begin-print", G_CALLBACK(begin_print_callback), &printContext); 954 g_signal_connect(operation, "draw-page", G_CALLBACK(draw_page_callback), &printContext); 955 g_signal_connect(operation, "end-print", G_CALLBACK(end_print_callback), &printContext); 956 957 return gtk_print_operation_run(operation, action, GTK_WINDOW(topLevel), error); 958 } 959 960 /** 961 * webkit_web_frame_print: 962 * @frame: a #WebKitWebFrame 963 * 964 * Prints the given #WebKitFrame, by presenting a print dialog to the 965 * user. If you need more control over the printing process, see 966 * webkit_web_frame_print_full(). 967 * 968 * Since: 1.1.5 969 */ 970 void webkit_web_frame_print(WebKitWebFrame* frame) 971 { 972 g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame)); 973 974 WebKitWebFramePrivate* priv = frame->priv; 975 GtkPrintOperation* operation = gtk_print_operation_new(); 976 GError* error = 0; 977 978 webkit_web_frame_print_full(frame, operation, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, &error); 979 g_object_unref(operation); 980 981 if (error) { 982 GtkWidget* window = gtk_widget_get_toplevel(GTK_WIDGET(priv->webView)); 983 #if GTK_CHECK_VERSION(2, 18, 0) 984 GtkWidget* dialog = gtk_message_dialog_new(gtk_widget_is_toplevel(window) ? GTK_WINDOW(window) : 0, 985 GTK_DIALOG_DESTROY_WITH_PARENT, 986 GTK_MESSAGE_ERROR, 987 GTK_BUTTONS_CLOSE, 988 "%s", error->message); 989 #else 990 GtkWidget* dialog = gtk_message_dialog_new(GTK_WIDGET_TOPLEVEL(window) ? GTK_WINDOW(window) : 0, 991 GTK_DIALOG_DESTROY_WITH_PARENT, 992 GTK_MESSAGE_ERROR, 993 GTK_BUTTONS_CLOSE, 994 "%s", error->message); 995 #endif 996 997 g_error_free(error); 998 999 g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL); 1000 gtk_widget_show(dialog); 1001 } 1002 } 1003 1004 bool webkit_web_frame_pause_animation(WebKitWebFrame* frame, const gchar* name, double time, const gchar* element) 1005 { 1006 ASSERT(core(frame)); 1007 Element* coreElement = core(frame)->document()->getElementById(AtomicString(element)); 1008 if (!coreElement || !coreElement->renderer()) 1009 return false; 1010 return core(frame)->animation()->pauseAnimationAtTime(coreElement->renderer(), AtomicString(name), time); 1011 } 1012 1013 bool webkit_web_frame_pause_transition(WebKitWebFrame* frame, const gchar* name, double time, const gchar* element) 1014 { 1015 ASSERT(core(frame)); 1016 Element* coreElement = core(frame)->document()->getElementById(AtomicString(element)); 1017 if (!coreElement || !coreElement->renderer()) 1018 return false; 1019 return core(frame)->animation()->pauseTransitionAtTime(coreElement->renderer(), AtomicString(name), time); 1020 } 1021 1022 bool webkit_web_frame_pause_svg_animation(WebKitWebFrame* frame, const gchar* animationId, double time, const gchar* elementId) 1023 { 1024 ASSERT(core(frame)); 1025 #if ENABLE(SVG) 1026 Document* document = core(frame)->document(); 1027 if (!document || !document->svgExtensions()) 1028 return false; 1029 Element* coreElement = document->getElementById(AtomicString(animationId)); 1030 if (!coreElement || !SVGSMILElement::isSMILElement(coreElement)) 1031 return false; 1032 return document->accessSVGExtensions()->sampleAnimationAtTime(elementId, static_cast<SVGSMILElement*>(coreElement), time); 1033 #else 1034 return false; 1035 #endif 1036 } 1037 1038 unsigned int webkit_web_frame_number_of_active_animations(WebKitWebFrame* frame) 1039 { 1040 Frame* coreFrame = core(frame); 1041 if (!coreFrame) 1042 return 0; 1043 1044 AnimationController* controller = coreFrame->animation(); 1045 if (!controller) 1046 return 0; 1047 1048 return controller->numberOfActiveAnimations(); 1049 } 1050 1051 gchar* webkit_web_frame_get_response_mime_type(WebKitWebFrame* frame) 1052 { 1053 Frame* coreFrame = core(frame); 1054 WebCore::DocumentLoader* docLoader = coreFrame->loader()->documentLoader(); 1055 String mimeType = docLoader->responseMIMEType(); 1056 return g_strdup(mimeType.utf8().data()); 1057 } 1058 1059 /** 1060 * webkit_web_frame_get_load_status: 1061 * @frame: a #WebKitWebView 1062 * 1063 * Determines the current status of the load. 1064 * 1065 * Since: 1.1.7 1066 */ 1067 WebKitLoadStatus webkit_web_frame_get_load_status(WebKitWebFrame* frame) 1068 { 1069 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), WEBKIT_LOAD_FINISHED); 1070 1071 WebKitWebFramePrivate* priv = frame->priv; 1072 return priv->loadStatus; 1073 } 1074 1075 void webkit_web_frame_clear_main_frame_name(WebKitWebFrame* frame) 1076 { 1077 g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame)); 1078 1079 core(frame)->tree()->clearName(); 1080 } 1081 1082 void webkit_gc_collect_javascript_objects() 1083 { 1084 gcController().garbageCollectNow(); 1085 } 1086 1087 void webkit_gc_collect_javascript_objects_on_alternate_thread(gboolean waitUntilDone) 1088 { 1089 gcController().garbageCollectOnAlternateThreadForDebugging(waitUntilDone); 1090 } 1091 1092 gsize webkit_gc_count_javascript_objects() 1093 { 1094 JSC::JSLock lock(JSC::SilenceAssertionsOnly); 1095 return JSDOMWindow::commonJSGlobalData()->heap.objectCount(); 1096 1097 } 1098 1099 AtkObject* webkit_web_frame_get_focused_accessible_element(WebKitWebFrame* frame) 1100 { 1101 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), NULL); 1102 1103 #if HAVE(ACCESSIBILITY) 1104 if (!AXObjectCache::accessibilityEnabled()) 1105 AXObjectCache::enableAccessibility(); 1106 1107 WebKitWebFramePrivate* priv = frame->priv; 1108 if (!priv->coreFrame || !priv->coreFrame->document()) 1109 return NULL; 1110 1111 RenderView* root = toRenderView(priv->coreFrame->document()->renderer()); 1112 if (!root) 1113 return NULL; 1114 1115 AtkObject* wrapper = priv->coreFrame->document()->axObjectCache()->getOrCreate(root)->wrapper(); 1116 if (!wrapper) 1117 return NULL; 1118 1119 return webkit_accessible_get_focused_element(WEBKIT_ACCESSIBLE(wrapper)); 1120 #else 1121 return NULL; 1122 #endif 1123 } 1124 1125 GtkPolicyType webkit_web_frame_get_horizontal_scrollbar_policy(WebKitWebFrame* frame) 1126 { 1127 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), GTK_POLICY_AUTOMATIC); 1128 1129 Frame* coreFrame = core(frame); 1130 FrameView* view = coreFrame->view(); 1131 if (!view) 1132 return GTK_POLICY_AUTOMATIC; 1133 1134 ScrollbarMode hMode = view->horizontalScrollbarMode(); 1135 1136 if (hMode == ScrollbarAlwaysOn) 1137 return GTK_POLICY_ALWAYS; 1138 1139 if (hMode == ScrollbarAlwaysOff) 1140 return GTK_POLICY_NEVER; 1141 1142 return GTK_POLICY_AUTOMATIC; 1143 } 1144 1145 GtkPolicyType webkit_web_frame_get_vertical_scrollbar_policy(WebKitWebFrame* frame) 1146 { 1147 g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), GTK_POLICY_AUTOMATIC); 1148 1149 Frame* coreFrame = core(frame); 1150 FrameView* view = coreFrame->view(); 1151 if (!view) 1152 return GTK_POLICY_AUTOMATIC; 1153 1154 ScrollbarMode vMode = view->verticalScrollbarMode(); 1155 1156 if (vMode == ScrollbarAlwaysOn) 1157 return GTK_POLICY_ALWAYS; 1158 1159 if (vMode == ScrollbarAlwaysOff) 1160 return GTK_POLICY_NEVER; 1161 1162 return GTK_POLICY_AUTOMATIC; 1163 } 1164 1165 /** 1166 * webkit_web_frame_get_security_origin: 1167 * @frame: a #WebKitWebFrame 1168 * 1169 * Returns the @frame's security origin. 1170 * 1171 * Return value: the security origin of @frame 1172 * 1173 * Since: 1.1.14 1174 */ 1175 WebKitSecurityOrigin* webkit_web_frame_get_security_origin(WebKitWebFrame* frame) 1176 { 1177 WebKitWebFramePrivate* priv = frame->priv; 1178 if (!priv->coreFrame || !priv->coreFrame->document() || !priv->coreFrame->document()->securityOrigin()) 1179 return NULL; 1180 1181 if (priv->origin && priv->origin->priv->coreOrigin.get() == priv->coreFrame->document()->securityOrigin()) 1182 return priv->origin; 1183 1184 if (priv->origin) 1185 g_object_unref(priv->origin); 1186 1187 priv->origin = kit(priv->coreFrame->document()->securityOrigin()); 1188 return priv->origin; 1189 } 1190 1191 void webkit_web_frame_layout(WebKitWebFrame* frame) 1192 { 1193 Frame* coreFrame = core(frame); 1194 if (!coreFrame) 1195 return; 1196 1197 FrameView* view = coreFrame->view(); 1198 if (!view) 1199 return; 1200 1201 view->layout(); 1202 } 1203 1204 /** 1205 * webkit_web_frame_get_network_response: 1206 * @frame: a #WebKitWebFrame 1207 * 1208 * Returns a #WebKitNetworkResponse object representing the response 1209 * that was given to the request for the given frame, or NULL if the 1210 * frame was not created by a load. You must unref the object when you 1211 * are done with it. 1212 * 1213 * Return value: a #WebKitNetworkResponse object 1214 * 1215 * Since: 1.1.18 1216 */ 1217 WebKitNetworkResponse* webkit_web_frame_get_network_response(WebKitWebFrame* frame) 1218 { 1219 Frame* coreFrame = core(frame); 1220 if (!coreFrame) 1221 return NULL; 1222 1223 WebCore::DocumentLoader* loader = coreFrame->loader()->activeDocumentLoader(); 1224 if (!loader) 1225 return NULL; 1226 1227 return webkit_network_response_new_with_core_response(loader->response()); 1228 } 1229