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