1 /* 2 Copyright (C) 2008,2009 Nokia Corporation and/or its subsidiary(-ies) 3 Copyright (C) 2007 Staikos Computing Services Inc. 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Library General Public 7 License as published by the Free Software Foundation; either 8 version 2 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Library General Public License for more details. 14 15 You should have received a copy of the GNU Library General Public License 16 along with this library; see the file COPYING.LIB. If not, write to 17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 Boston, MA 02110-1301, USA. 19 */ 20 21 #include "config.h" 22 #include "qwebframe.h" 23 24 #include "Bridge.h" 25 #include "CallFrame.h" 26 #include "Document.h" 27 #include "DocumentLoader.h" 28 #include "DragData.h" 29 #include "Element.h" 30 #include "FocusController.h" 31 #include "Frame.h" 32 #include "FrameLoaderClientQt.h" 33 #include "FrameTree.h" 34 #include "FrameView.h" 35 #include "GCController.h" 36 #include "GraphicsContext.h" 37 #include "HTMLMetaElement.h" 38 #include "HitTestResult.h" 39 #include "IconDatabase.h" 40 #include "InspectorController.h" 41 #include "JSDOMBinding.h" 42 #include "JSDOMWindowBase.h" 43 #include "JSLock.h" 44 #include "JSObject.h" 45 #include "NodeList.h" 46 #include "Page.h" 47 #include "PlatformMouseEvent.h" 48 #include "PlatformWheelEvent.h" 49 #include "PrintContext.h" 50 #include "PutPropertySlot.h" 51 #include "RenderTreeAsText.h" 52 #include "RenderView.h" 53 #include "ResourceRequest.h" 54 #include "ScriptController.h" 55 #include "ScriptSourceCode.h" 56 #include "ScriptValue.h" 57 #include "Scrollbar.h" 58 #include "SelectionController.h" 59 #include "SubstituteData.h" 60 #include "SVGSMILElement.h" 61 #include "htmlediting.h" 62 #include "markup.h" 63 #include "qt_instance.h" 64 #include "qt_runtime.h" 65 #include "qwebelement.h" 66 #include "qwebframe_p.h" 67 #include "qwebpage.h" 68 #include "qwebpage_p.h" 69 #include "qwebsecurityorigin.h" 70 #include "qwebsecurityorigin_p.h" 71 #include "runtime_object.h" 72 #include "runtime_root.h" 73 #include "wtf/HashMap.h" 74 #include <QMultiMap> 75 #include <qdebug.h> 76 #include <qevent.h> 77 #include <qfileinfo.h> 78 #include <qpainter.h> 79 #include <qprinter.h> 80 #include <qregion.h> 81 #include <qnetworkrequest.h> 82 83 using namespace WebCore; 84 85 // from text/qfont.cpp 86 QT_BEGIN_NAMESPACE 87 extern Q_GUI_EXPORT int qt_defaultDpi(); 88 QT_END_NAMESPACE 89 90 bool QWEBKIT_EXPORT qt_drt_hasDocumentElement(QWebFrame* qframe) 91 { 92 return QWebFramePrivate::core(qframe)->document()->documentElement(); 93 } 94 95 void QWEBKIT_EXPORT qt_drt_setJavaScriptProfilingEnabled(QWebFrame* qframe, bool enabled) 96 { 97 #if ENABLE(JAVASCRIPT_DEBUGGER) 98 Frame* frame = QWebFramePrivate::core(qframe); 99 InspectorController* controller = frame->page()->inspectorController(); 100 if (!controller) 101 return; 102 if (enabled) 103 controller->enableProfiler(); 104 else 105 controller->disableProfiler(); 106 #endif 107 } 108 109 // Pause a given CSS animation or transition on the target node at a specific time. 110 // If the animation or transition is already paused, it will update its pause time. 111 // This method is only intended to be used for testing the CSS animation and transition system. 112 bool QWEBKIT_EXPORT qt_drt_pauseAnimation(QWebFrame *qframe, const QString &animationName, double time, const QString &elementId) 113 { 114 Frame* frame = QWebFramePrivate::core(qframe); 115 if (!frame) 116 return false; 117 118 AnimationController* controller = frame->animation(); 119 if (!controller) 120 return false; 121 122 Document* doc = frame->document(); 123 Q_ASSERT(doc); 124 125 Node* coreNode = doc->getElementById(elementId); 126 if (!coreNode || !coreNode->renderer()) 127 return false; 128 129 return controller->pauseAnimationAtTime(coreNode->renderer(), animationName, time); 130 } 131 132 bool QWEBKIT_EXPORT qt_drt_pauseTransitionOfProperty(QWebFrame *qframe, const QString &propertyName, double time, const QString &elementId) 133 { 134 Frame* frame = QWebFramePrivate::core(qframe); 135 if (!frame) 136 return false; 137 138 AnimationController* controller = frame->animation(); 139 if (!controller) 140 return false; 141 142 Document* doc = frame->document(); 143 Q_ASSERT(doc); 144 145 Node* coreNode = doc->getElementById(elementId); 146 if (!coreNode || !coreNode->renderer()) 147 return false; 148 149 return controller->pauseTransitionAtTime(coreNode->renderer(), propertyName, time); 150 } 151 152 // Pause a given SVG animation on the target node at a specific time. 153 // This method is only intended to be used for testing the SVG animation system. 154 bool QWEBKIT_EXPORT qt_drt_pauseSVGAnimation(QWebFrame *qframe, const QString &animationId, double time, const QString &elementId) 155 { 156 #if !ENABLE(SVG) 157 return false; 158 #else 159 Frame* frame = QWebFramePrivate::core(qframe); 160 if (!frame) 161 return false; 162 163 Document* doc = frame->document(); 164 Q_ASSERT(doc); 165 166 if (!doc->svgExtensions()) 167 return false; 168 169 Node* coreNode = doc->getElementById(animationId); 170 if (!coreNode || !SVGSMILElement::isSMILElement(coreNode)) 171 return false; 172 173 return doc->accessSVGExtensions()->sampleAnimationAtTime(elementId, static_cast<SVGSMILElement*>(coreNode), time); 174 #endif 175 } 176 177 // Returns the total number of currently running animations (includes both CSS transitions and CSS animations). 178 int QWEBKIT_EXPORT qt_drt_numberOfActiveAnimations(QWebFrame *qframe) 179 { 180 Frame* frame = QWebFramePrivate::core(qframe); 181 if (!frame) 182 return false; 183 184 AnimationController* controller = frame->animation(); 185 if (!controller) 186 return false; 187 188 return controller->numberOfActiveAnimations(); 189 } 190 191 void QWEBKIT_EXPORT qt_drt_clearFrameName(QWebFrame* qFrame) 192 { 193 Frame* frame = QWebFramePrivate::core(qFrame); 194 frame->tree()->clearName(); 195 } 196 197 int QWEBKIT_EXPORT qt_drt_javaScriptObjectsCount() 198 { 199 return JSDOMWindowBase::commonJSGlobalData()->heap.globalObjectCount(); 200 } 201 202 void QWEBKIT_EXPORT qt_drt_garbageCollector_collect() 203 { 204 gcController().garbageCollectNow(); 205 } 206 207 void QWEBKIT_EXPORT qt_drt_garbageCollector_collectOnAlternateThread(bool waitUntilDone) 208 { 209 gcController().garbageCollectOnAlternateThreadForDebugging(waitUntilDone); 210 } 211 212 // Returns the value of counter in the element specified by \a id. 213 QString QWEBKIT_EXPORT qt_drt_counterValueForElementById(QWebFrame* qFrame, const QString& id) 214 { 215 Frame* frame = QWebFramePrivate::core(qFrame); 216 if (Document* document = frame->document()) { 217 Element* element = document->getElementById(id); 218 return WebCore::counterValueForElement(element); 219 } 220 return QString(); 221 } 222 223 int QWEBKIT_EXPORT qt_drt_pageNumberForElementById(QWebFrame* qFrame, const QString& id, float width, float height) 224 { 225 Frame* frame = QWebFramePrivate::core(qFrame); 226 if (!frame) 227 return -1; 228 229 Element* element = frame->document()->getElementById(AtomicString(id)); 230 if (!element) 231 return -1; 232 233 return PrintContext::pageNumberForElement(element, FloatSize(width, height)); 234 } 235 236 // Suspend active DOM objects in this frame. 237 void QWEBKIT_EXPORT qt_suspendActiveDOMObjects(QWebFrame* qFrame) 238 { 239 Frame* frame = QWebFramePrivate::core(qFrame); 240 if (frame->document()) 241 frame->document()->suspendActiveDOMObjects(); 242 } 243 244 // Resume active DOM objects in this frame. 245 void QWEBKIT_EXPORT qt_resumeActiveDOMObjects(QWebFrame* qFrame) 246 { 247 Frame* frame = QWebFramePrivate::core(qFrame); 248 if (frame->document()) 249 frame->document()->resumeActiveDOMObjects(); 250 } 251 252 QWebFrameData::QWebFrameData(WebCore::Page* parentPage, WebCore::Frame* parentFrame, 253 WebCore::HTMLFrameOwnerElement* ownerFrameElement, 254 const WebCore::String& frameName) 255 : name(frameName) 256 , ownerElement(ownerFrameElement) 257 , page(parentPage) 258 , allowsScrolling(true) 259 , marginWidth(0) 260 , marginHeight(0) 261 { 262 frameLoaderClient = new FrameLoaderClientQt(); 263 frame = Frame::create(page, ownerElement, frameLoaderClient); 264 265 // FIXME: All of the below should probably be moved over into WebCore 266 frame->tree()->setName(name); 267 if (parentFrame) 268 parentFrame->tree()->appendChild(frame); 269 } 270 271 void QWebFramePrivate::init(QWebFrame *qframe, QWebFrameData *frameData) 272 { 273 q = qframe; 274 275 allowsScrolling = frameData->allowsScrolling; 276 marginWidth = frameData->marginWidth; 277 marginHeight = frameData->marginHeight; 278 frame = frameData->frame.get(); 279 frameLoaderClient = frameData->frameLoaderClient; 280 frameLoaderClient->setFrame(qframe, frame); 281 282 frame->init(); 283 } 284 285 WebCore::Scrollbar* QWebFramePrivate::horizontalScrollBar() const 286 { 287 if (!frame->view()) 288 return 0; 289 return frame->view()->horizontalScrollbar(); 290 } 291 292 WebCore::Scrollbar* QWebFramePrivate::verticalScrollBar() const 293 { 294 if (!frame->view()) 295 return 0; 296 return frame->view()->verticalScrollbar(); 297 } 298 299 void QWebFramePrivate::renderContentsLayerAbsoluteCoords(GraphicsContext* context, const QRegion& clip) 300 { 301 if (!frame->view() || !frame->contentRenderer()) 302 return; 303 304 QVector<QRect> vector = clip.rects(); 305 if (vector.isEmpty()) 306 return; 307 308 QPainter* painter = context->platformContext(); 309 310 WebCore::FrameView* view = frame->view(); 311 view->layoutIfNeededRecursive(); 312 313 for (int i = 0; i < vector.size(); ++i) { 314 const QRect& clipRect = vector.at(i); 315 316 painter->save(); 317 painter->setClipRect(clipRect, Qt::IntersectClip); 318 319 context->save(); 320 view->paintContents(context, clipRect); 321 context->restore(); 322 323 painter->restore(); 324 } 325 } 326 327 void QWebFramePrivate::renderRelativeCoords(GraphicsContext* context, QWebFrame::RenderLayer layer, const QRegion& clip) 328 { 329 if (!frame->view() || !frame->contentRenderer()) 330 return; 331 332 QVector<QRect> vector = clip.rects(); 333 if (vector.isEmpty()) 334 return; 335 336 QPainter* painter = context->platformContext(); 337 338 WebCore::FrameView* view = frame->view(); 339 view->layoutIfNeededRecursive(); 340 341 for (int i = 0; i < vector.size(); ++i) { 342 const QRect& clipRect = vector.at(i); 343 344 QRect intersectedRect = clipRect.intersected(view->frameRect()); 345 346 painter->save(); 347 painter->setClipRect(clipRect, Qt::IntersectClip); 348 349 int x = view->x(); 350 int y = view->y(); 351 352 if (layer & QWebFrame::ContentsLayer) { 353 context->save(); 354 355 int scrollX = view->scrollX(); 356 int scrollY = view->scrollY(); 357 358 QRect rect = intersectedRect; 359 context->translate(x, y); 360 rect.translate(-x, -y); 361 context->translate(-scrollX, -scrollY); 362 rect.translate(scrollX, scrollY); 363 context->clip(view->visibleContentRect()); 364 365 view->paintContents(context, rect); 366 367 context->restore(); 368 } 369 370 if (layer & QWebFrame::ScrollBarLayer 371 && !view->scrollbarsSuppressed() 372 && (view->horizontalScrollbar() || view->verticalScrollbar())) { 373 context->save(); 374 375 QRect rect = intersectedRect; 376 context->translate(x, y); 377 rect.translate(-x, -y); 378 379 view->paintScrollbars(context, rect); 380 381 context->restore(); 382 } 383 384 #if ENABLE(PAN_SCROLLING) 385 if (layer & QWebFrame::PanIconLayer) 386 view->paintPanScrollIcon(context); 387 #endif 388 389 painter->restore(); 390 } 391 } 392 393 bool QWebFramePrivate::scrollOverflow(int dx, int dy) 394 { 395 if (!frame || !frame->document() || !frame->eventHandler()) 396 return false; 397 398 Node* node = frame->document()->focusedNode(); 399 if (!node) 400 node = frame->document()->elementFromPoint(frame->eventHandler()->currentMousePosition().x(), 401 frame->eventHandler()->currentMousePosition().y()); 402 if (!node) 403 return false; 404 405 RenderObject* renderer = node->renderer(); 406 if (!renderer) 407 return false; 408 409 if (renderer->isListBox()) 410 return false; 411 412 RenderLayer* renderLayer = renderer->enclosingLayer(); 413 if (!renderLayer) 414 return false; 415 416 bool scrolledHorizontal = false; 417 bool scrolledVertical = false; 418 419 if (dx > 0) 420 scrolledHorizontal = renderLayer->scroll(ScrollRight, ScrollByPixel, dx); 421 else if (dx < 0) 422 scrolledHorizontal = renderLayer->scroll(ScrollLeft, ScrollByPixel, qAbs(dx)); 423 424 if (dy > 0) 425 scrolledVertical = renderLayer->scroll(ScrollDown, ScrollByPixel, dy); 426 else if (dy < 0) 427 scrolledVertical = renderLayer->scroll(ScrollUp, ScrollByPixel, qAbs(dy)); 428 429 return (scrolledHorizontal || scrolledVertical); 430 } 431 432 /*! 433 \class QWebFrame 434 \since 4.4 435 \brief The QWebFrame class represents a frame in a web page. 436 437 \inmodule QtWebKit 438 439 QWebFrame represents a frame inside a web page. Each QWebPage 440 object contains at least one frame, the main frame, obtained using 441 QWebPage::mainFrame(). Additional frames will be created for HTML 442 \c{<frame>} or \c{<iframe>} elements. 443 444 A frame can be loaded using load() or setUrl(). Alternatively, if you have 445 the HTML content readily available, you can use setHtml() instead. 446 447 The page() function returns a pointer to the web page object. See 448 \l{QWebView}{Elements of QWebView} for an explanation of how web 449 frames are related to a web page and web view. 450 451 The QWebFrame class also offers methods to retrieve both the URL currently 452 loaded by the frame (see url()) as well as the URL originally requested 453 to be loaded (see requestedUrl()). These methods make possible the retrieval 454 of the URL before and after a DNS resolution or a redirection occurs during 455 the load process. The requestedUrl() also matches to the URL added to the 456 frame history (\l{QWebHistory}) if load is successful. 457 458 The title of an HTML frame can be accessed with the title() property. 459 Additionally, a frame may also specify an icon, which can be accessed 460 using the icon() property. If the title or the icon changes, the 461 corresponding titleChanged() and iconChanged() signals will be emitted. 462 The zoomFactor() property can be used to change the overall size 463 of the content displayed in the frame. 464 465 QWebFrame objects are created and controlled by the web page. You 466 can connect to the web page's \l{QWebPage::}{frameCreated()} signal 467 to be notified when a new frame is created. 468 469 The hitTestContent() function can be used to programmatically examine the 470 contents of a frame. 471 472 A QWebFrame can be printed onto a QPrinter using the print() function. 473 This function is marked as a slot and can be conveniently connected to 474 \l{QPrintPreviewDialog}'s \l{QPrintPreviewDialog::}{paintRequested()} 475 signal. 476 477 \sa QWebPage 478 */ 479 480 /*! 481 \enum QWebFrame::RenderLayer 482 483 This enum describes the layers available for rendering using \l{QWebFrame::}{render()}. 484 The layers can be OR-ed together from the following list: 485 486 \value ContentsLayer The web content of the frame 487 \value ScrollBarLayer The scrollbars of the frame 488 \value PanIconLayer The icon used when panning the frame 489 490 \value AllLayers Includes all the above layers 491 */ 492 493 QWebFrame::QWebFrame(QWebPage *parent, QWebFrameData *frameData) 494 : QObject(parent) 495 , d(new QWebFramePrivate) 496 { 497 d->page = parent; 498 d->init(this, frameData); 499 500 if (!frameData->url.isEmpty()) { 501 WebCore::ResourceRequest request(frameData->url, frameData->referrer); 502 d->frame->loader()->load(request, frameData->name, false); 503 } 504 } 505 506 QWebFrame::QWebFrame(QWebFrame *parent, QWebFrameData *frameData) 507 : QObject(parent) 508 , d(new QWebFramePrivate) 509 { 510 d->page = parent->d->page; 511 d->init(this, frameData); 512 } 513 514 QWebFrame::~QWebFrame() 515 { 516 if (d->frame && d->frame->loader() && d->frame->loader()->client()) 517 static_cast<FrameLoaderClientQt*>(d->frame->loader()->client())->m_webFrame = 0; 518 519 delete d; 520 } 521 522 /*! 523 Make \a object available under \a name from within the frame's JavaScript 524 context. The \a object will be inserted as a child of the frame's window 525 object. 526 527 Qt properties will be exposed as JavaScript properties and slots as 528 JavaScript methods. 529 530 If you want to ensure that your QObjects remain accessible after loading a 531 new URL, you should add them in a slot connected to the 532 javaScriptWindowObjectCleared() signal. 533 534 If Javascript is not enabled for this page, then this method does nothing. 535 536 The \a object will never be explicitly deleted by QtWebKit. 537 */ 538 void QWebFrame::addToJavaScriptWindowObject(const QString &name, QObject *object) 539 { 540 addToJavaScriptWindowObject(name, object, QScriptEngine::QtOwnership); 541 } 542 543 /*! 544 \fn void QWebFrame::addToJavaScriptWindowObject(const QString &name, QObject *object, QScriptEngine::ValueOwnership own) 545 \overload 546 547 Make \a object available under \a name from within the frame's JavaScript 548 context. The \a object will be inserted as a child of the frame's window 549 object. 550 551 Qt properties will be exposed as JavaScript properties and slots as 552 JavaScript methods. 553 554 If you want to ensure that your QObjects remain accessible after loading a 555 new URL, you should add them in a slot connected to the 556 javaScriptWindowObjectCleared() signal. 557 558 If Javascript is not enabled for this page, then this method does nothing. 559 560 The ownership of \a object is specified using \a own. 561 */ 562 void QWebFrame::addToJavaScriptWindowObject(const QString &name, QObject *object, QScriptEngine::ValueOwnership ownership) 563 { 564 if (!page()->settings()->testAttribute(QWebSettings::JavascriptEnabled)) 565 return; 566 567 JSC::JSLock lock(JSC::SilenceAssertionsOnly); 568 JSDOMWindow* window = toJSDOMWindow(d->frame, mainThreadNormalWorld()); 569 JSC::Bindings::RootObject* root = d->frame->script()->bindingRootObject(); 570 if (!window) { 571 qDebug() << "Warning: couldn't get window object"; 572 return; 573 } 574 575 JSC::ExecState* exec = window->globalExec(); 576 577 JSC::JSObject* runtimeObject = 578 JSC::Bindings::QtInstance::getQtInstance(object, root, ownership)->createRuntimeObject(exec); 579 580 JSC::PutPropertySlot slot; 581 window->put(exec, JSC::Identifier(exec, (const UChar *) name.constData(), name.length()), runtimeObject, slot); 582 } 583 584 /*! 585 Returns the frame's content as HTML, enclosed in HTML and BODY tags. 586 587 \sa setHtml(), toPlainText() 588 */ 589 QString QWebFrame::toHtml() const 590 { 591 if (!d->frame->document()) 592 return QString(); 593 return createMarkup(d->frame->document()); 594 } 595 596 /*! 597 Returns the content of this frame converted to plain text, completely 598 stripped of all HTML formatting. 599 600 \sa toHtml() 601 */ 602 QString QWebFrame::toPlainText() const 603 { 604 if (d->frame->view() && d->frame->view()->layoutPending()) 605 d->frame->view()->layout(); 606 607 Element *documentElement = d->frame->document()->documentElement(); 608 if (documentElement) 609 return documentElement->innerText(); 610 return QString(); 611 } 612 613 /*! 614 Returns a dump of the rendering tree. This is mainly useful for debugging 615 html. 616 */ 617 QString QWebFrame::renderTreeDump() const 618 { 619 if (d->frame->view() && d->frame->view()->layoutPending()) 620 d->frame->view()->layout(); 621 622 return externalRepresentation(d->frame); 623 } 624 625 /*! 626 \property QWebFrame::title 627 \brief the title of the frame as defined by the HTML <title> element 628 629 \sa titleChanged() 630 */ 631 632 QString QWebFrame::title() const 633 { 634 if (d->frame->document()) 635 return d->frame->loader()->documentLoader()->title(); 636 return QString(); 637 } 638 639 /*! 640 \since 4.5 641 \brief Returns the meta data in this frame as a QMultiMap 642 643 The meta data consists of the name and content attributes of the 644 of the \c{<meta>} tags in the HTML document. 645 646 For example: 647 648 \code 649 <html> 650 <head> 651 <meta name="description" content="This document is a tutorial about Qt development"> 652 <meta name="keywords" content="Qt, WebKit, Programming"> 653 </head> 654 ... 655 </html> 656 \endcode 657 658 Given the above HTML code the metaData() function will return a map with two entries: 659 \table 660 \header \o Key 661 \o Value 662 \row \o "description" 663 \o "This document is a tutorial about Qt development" 664 \row \o "keywords" 665 \o "Qt, WebKit, Programming" 666 \endtable 667 668 This function returns a multi map to support multiple meta tags with the same attribute name. 669 */ 670 QMultiMap<QString, QString> QWebFrame::metaData() const 671 { 672 if (!d->frame->document()) 673 return QMap<QString, QString>(); 674 675 QMultiMap<QString, QString> map; 676 Document* doc = d->frame->document(); 677 RefPtr<NodeList> list = doc->getElementsByTagName("meta"); 678 unsigned len = list->length(); 679 for (unsigned i = 0; i < len; i++) { 680 HTMLMetaElement* meta = static_cast<HTMLMetaElement*>(list->item(i)); 681 map.insert(meta->name(), meta->content()); 682 } 683 return map; 684 } 685 686 static inline QUrl ensureAbsoluteUrl(const QUrl &url) 687 { 688 if (!url.isRelative()) 689 return url; 690 691 return QUrl::fromLocalFile(QFileInfo(url.toLocalFile()).absoluteFilePath()); 692 } 693 694 /*! 695 \property QWebFrame::url 696 \brief the url of the frame currently viewed 697 698 \sa urlChanged() 699 */ 700 701 void QWebFrame::setUrl(const QUrl &url) 702 { 703 d->frame->loader()->begin(ensureAbsoluteUrl(url)); 704 d->frame->loader()->end(); 705 load(ensureAbsoluteUrl(url)); 706 } 707 708 QUrl QWebFrame::url() const 709 { 710 return d->frame->loader()->url(); 711 } 712 713 /*! 714 \since 4.6 715 \property QWebFrame::requestedUrl 716 717 The URL requested to loaded by the frame currently viewed. The URL may differ from 718 the one returned by url() if a DNS resolution or a redirection occurs. 719 720 \sa url(), setUrl() 721 */ 722 QUrl QWebFrame::requestedUrl() const 723 { 724 // There are some possible edge cases to be handled here, 725 // apart from checking if activeDocumentLoader is valid: 726 // 727 // * Method can be called while processing an unsucessful load. 728 // In this case, frameLoaderClient will hold the current error 729 // (m_loadError), and we will make use of it to recover the 'failingURL'. 730 // * If the 'failingURL' holds a null'ed string though, we fallback 731 // to 'outgoingReferrer' (it yet is safer than originalRequest). 732 FrameLoader* loader = d->frame->loader(); 733 FrameLoaderClientQt* loaderClient = d->frameLoaderClient; 734 735 if (!loader->activeDocumentLoader() 736 || !loaderClient->m_loadError.isNull()) { 737 if (!loaderClient->m_loadError.failingURL().isNull()) 738 return QUrl(loaderClient->m_loadError.failingURL()); 739 else if (!loader->outgoingReferrer().isEmpty()) 740 return QUrl(loader->outgoingReferrer()); 741 } 742 743 return loader->originalRequest().url(); 744 } 745 /*! 746 \since 4.6 747 \property QWebFrame::baseUrl 748 \brief the base URL of the frame, can be used to resolve relative URLs 749 \since 4.6 750 */ 751 752 QUrl QWebFrame::baseUrl() const 753 { 754 return d->frame->loader()->baseURL(); 755 } 756 757 /*! 758 \property QWebFrame::icon 759 \brief the icon associated with this frame 760 761 \sa iconChanged(), QWebSettings::iconForUrl() 762 */ 763 764 QIcon QWebFrame::icon() const 765 { 766 return QWebSettings::iconForUrl(d->frame->loader()->url()); 767 } 768 769 /*! 770 The name of this frame as defined by the parent frame. 771 */ 772 QString QWebFrame::frameName() const 773 { 774 return d->frame->tree()->name(); 775 } 776 777 /*! 778 The web page that contains this frame. 779 */ 780 QWebPage *QWebFrame::page() const 781 { 782 return d->page; 783 } 784 785 /*! 786 Loads \a url into this frame. 787 788 \note The view remains the same until enough data has arrived to display the new \a url. 789 790 \sa setUrl(), setHtml(), setContent() 791 */ 792 void QWebFrame::load(const QUrl &url) 793 { 794 load(QNetworkRequest(ensureAbsoluteUrl(url))); 795 } 796 797 /*! 798 Loads a network request, \a req, into this frame, using the method specified in \a 799 operation. 800 801 \a body is optional and is only used for POST operations. 802 803 \note The view remains the same until enough data has arrived to display the new \a url. 804 805 \sa setUrl() 806 */ 807 void QWebFrame::load(const QNetworkRequest &req, 808 QNetworkAccessManager::Operation operation, 809 const QByteArray &body) 810 { 811 if (d->parentFrame()) 812 d->page->d->insideOpenCall = true; 813 814 QUrl url = ensureAbsoluteUrl(req.url()); 815 816 WebCore::ResourceRequest request(url); 817 818 switch (operation) { 819 case QNetworkAccessManager::HeadOperation: 820 request.setHTTPMethod("HEAD"); 821 break; 822 case QNetworkAccessManager::GetOperation: 823 request.setHTTPMethod("GET"); 824 break; 825 case QNetworkAccessManager::PutOperation: 826 request.setHTTPMethod("PUT"); 827 break; 828 case QNetworkAccessManager::PostOperation: 829 request.setHTTPMethod("POST"); 830 break; 831 #if QT_VERSION >= 0x040600 832 case QNetworkAccessManager::DeleteOperation: 833 request.setHTTPMethod("DELETE"); 834 break; 835 #endif 836 case QNetworkAccessManager::UnknownOperation: 837 // eh? 838 break; 839 } 840 841 QList<QByteArray> httpHeaders = req.rawHeaderList(); 842 for (int i = 0; i < httpHeaders.size(); ++i) { 843 const QByteArray &headerName = httpHeaders.at(i); 844 request.addHTTPHeaderField(QString::fromLatin1(headerName), QString::fromLatin1(req.rawHeader(headerName))); 845 } 846 847 if (!body.isEmpty()) 848 request.setHTTPBody(WebCore::FormData::create(body.constData(), body.size())); 849 850 d->frame->loader()->load(request, false); 851 852 if (d->parentFrame()) 853 d->page->d->insideOpenCall = false; 854 } 855 856 /*! 857 Sets the content of this frame to \a html. \a baseUrl is optional and used to resolve relative 858 URLs in the document, such as referenced images or stylesheets. 859 860 The \a html is loaded immediately; external objects are loaded asynchronously. 861 862 When using this method WebKit assumes that external resources such as JavaScript programs or style 863 sheets are encoded in UTF-8 unless otherwise specified. For example, the encoding of an external 864 script can be specified through the charset attribute of the HTML script tag. It is also possible 865 for the encoding to be specified by web server. 866 867 \note This method will not affect session or global history for the frame. 868 869 \sa toHtml(), setContent() 870 */ 871 void QWebFrame::setHtml(const QString &html, const QUrl &baseUrl) 872 { 873 KURL kurl(baseUrl); 874 WebCore::ResourceRequest request(kurl); 875 const QByteArray utf8 = html.toUtf8(); 876 WTF::RefPtr<WebCore::SharedBuffer> data = WebCore::SharedBuffer::create(utf8.constData(), utf8.length()); 877 WebCore::SubstituteData substituteData(data, WebCore::String("text/html"), WebCore::String("utf-8"), KURL()); 878 d->frame->loader()->load(request, substituteData, false); 879 } 880 881 /*! 882 Sets the content of this frame to the specified content \a data. If the \a mimeType argument 883 is empty it is currently assumed that the content is HTML but in future versions we may introduce 884 auto-detection. 885 886 External objects referenced in the content are located relative to \a baseUrl. 887 888 The \a data is loaded immediately; external objects are loaded asynchronously. 889 890 \note This method will not affect session or global history for the frame. 891 892 \sa toHtml(), setHtml() 893 */ 894 void QWebFrame::setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl) 895 { 896 KURL kurl(baseUrl); 897 WebCore::ResourceRequest request(kurl); 898 WTF::RefPtr<WebCore::SharedBuffer> buffer = WebCore::SharedBuffer::create(data.constData(), data.length()); 899 QString actualMimeType = mimeType; 900 if (actualMimeType.isEmpty()) 901 actualMimeType = QLatin1String("text/html"); 902 WebCore::SubstituteData substituteData(buffer, WebCore::String(actualMimeType), WebCore::String(), KURL()); 903 d->frame->loader()->load(request, substituteData, false); 904 } 905 906 /*! 907 Returns the parent frame of this frame, or 0 if the frame is the web pages 908 main frame. 909 910 This is equivalent to qobject_cast<QWebFrame*>(frame->parent()). 911 912 \sa childFrames() 913 */ 914 QWebFrame *QWebFrame::parentFrame() const 915 { 916 return d->parentFrame(); 917 } 918 919 /*! 920 Returns a list of all frames that are direct children of this frame. 921 922 \sa parentFrame() 923 */ 924 QList<QWebFrame*> QWebFrame::childFrames() const 925 { 926 QList<QWebFrame*> rc; 927 if (d->frame) { 928 FrameTree *tree = d->frame->tree(); 929 for (Frame *child = tree->firstChild(); child; child = child->tree()->nextSibling()) { 930 FrameLoader *loader = child->loader(); 931 FrameLoaderClientQt *client = static_cast<FrameLoaderClientQt*>(loader->client()); 932 if (client) 933 rc.append(client->webFrame()); 934 } 935 936 } 937 return rc; 938 } 939 940 /*! 941 Returns the scrollbar policy for the scrollbar defined by \a orientation. 942 */ 943 Qt::ScrollBarPolicy QWebFrame::scrollBarPolicy(Qt::Orientation orientation) const 944 { 945 if (orientation == Qt::Horizontal) 946 return d->horizontalScrollBarPolicy; 947 return d->verticalScrollBarPolicy; 948 } 949 950 /*! 951 Sets the scrollbar policy for the scrollbar defined by \a orientation to \a policy. 952 */ 953 void QWebFrame::setScrollBarPolicy(Qt::Orientation orientation, Qt::ScrollBarPolicy policy) 954 { 955 Q_ASSERT((int)ScrollbarAuto == (int)Qt::ScrollBarAsNeeded); 956 Q_ASSERT((int)ScrollbarAlwaysOff == (int)Qt::ScrollBarAlwaysOff); 957 Q_ASSERT((int)ScrollbarAlwaysOn == (int)Qt::ScrollBarAlwaysOn); 958 959 if (orientation == Qt::Horizontal) { 960 d->horizontalScrollBarPolicy = policy; 961 if (d->frame->view()) { 962 d->frame->view()->setHorizontalScrollbarMode((ScrollbarMode)policy); 963 d->frame->view()->updateCanHaveScrollbars(); 964 } 965 } else { 966 d->verticalScrollBarPolicy = policy; 967 if (d->frame->view()) { 968 d->frame->view()->setVerticalScrollbarMode((ScrollbarMode)policy); 969 d->frame->view()->updateCanHaveScrollbars(); 970 } 971 } 972 } 973 974 /*! 975 Sets the current \a value for the scrollbar with orientation \a orientation. 976 977 The scrollbar forces the \a value to be within the legal range: minimum <= value <= maximum. 978 979 Changing the value also updates the thumb position. 980 981 \sa scrollBarMinimum(), scrollBarMaximum() 982 */ 983 void QWebFrame::setScrollBarValue(Qt::Orientation orientation, int value) 984 { 985 Scrollbar *sb; 986 sb = (orientation == Qt::Horizontal) ? d->horizontalScrollBar() : d->verticalScrollBar(); 987 if (sb) { 988 if (value < 0) 989 value = 0; 990 else if (value > scrollBarMaximum(orientation)) 991 value = scrollBarMaximum(orientation); 992 sb->setValue(value); 993 } 994 } 995 996 /*! 997 Returns the current value for the scrollbar with orientation \a orientation, or 0 998 if no scrollbar is found for \a orientation. 999 1000 \sa scrollBarMinimum(), scrollBarMaximum() 1001 */ 1002 int QWebFrame::scrollBarValue(Qt::Orientation orientation) const 1003 { 1004 Scrollbar *sb; 1005 sb = (orientation == Qt::Horizontal) ? d->horizontalScrollBar() : d->verticalScrollBar(); 1006 if (sb) 1007 return sb->value(); 1008 return 0; 1009 } 1010 1011 /*! 1012 Returns the maximum value for the scrollbar with orientation \a orientation, or 0 1013 if no scrollbar is found for \a orientation. 1014 1015 \sa scrollBarMinimum() 1016 */ 1017 int QWebFrame::scrollBarMaximum(Qt::Orientation orientation) const 1018 { 1019 Scrollbar *sb; 1020 sb = (orientation == Qt::Horizontal) ? d->horizontalScrollBar() : d->verticalScrollBar(); 1021 if (sb) 1022 return sb->maximum(); 1023 return 0; 1024 } 1025 1026 /*! 1027 Returns the minimum value for the scrollbar with orientation \a orientation. 1028 1029 The minimum value is always 0. 1030 1031 \sa scrollBarMaximum() 1032 */ 1033 int QWebFrame::scrollBarMinimum(Qt::Orientation orientation) const 1034 { 1035 Q_UNUSED(orientation) 1036 return 0; 1037 } 1038 1039 /*! 1040 \since 4.6 1041 Returns the geometry for the scrollbar with orientation \a orientation. 1042 1043 If the scrollbar does not exist an empty rect is returned. 1044 */ 1045 QRect QWebFrame::scrollBarGeometry(Qt::Orientation orientation) const 1046 { 1047 Scrollbar *sb; 1048 sb = (orientation == Qt::Horizontal) ? d->horizontalScrollBar() : d->verticalScrollBar(); 1049 if (sb) 1050 return sb->frameRect(); 1051 return QRect(); 1052 } 1053 1054 /*! 1055 \since 4.5 1056 Scrolls the frame \a dx pixels to the right and \a dy pixels downward. Both 1057 \a dx and \a dy may be negative. 1058 1059 \sa QWebFrame::scrollPosition 1060 */ 1061 1062 void QWebFrame::scroll(int dx, int dy) 1063 { 1064 if (!d->frame->view()) 1065 return; 1066 1067 d->frame->view()->scrollBy(IntSize(dx, dy)); 1068 } 1069 1070 /*! 1071 \since 4.7 1072 Scrolls nested frames starting at this frame, \a dx pixels to the right 1073 and \a dy pixels downward. Both \a dx and \a dy may be negative. First attempts 1074 to scroll elements with CSS overflow followed by this frame. If this 1075 frame doesn't scroll, attempts to scroll the parent 1076 1077 \sa QWebFrame::scroll 1078 */ 1079 bool QWebFrame::scrollRecursively(int dx, int dy) 1080 { 1081 bool scrolledHorizontal = false; 1082 bool scrolledVertical = false; 1083 bool scrolledOverflow = d->scrollOverflow(dx, dy); 1084 1085 if (!scrolledOverflow) { 1086 Frame* frame = d->frame; 1087 if (!frame || !frame->view()) 1088 return false; 1089 1090 do { 1091 IntSize scrollOffset = frame->view()->scrollOffset(); 1092 IntPoint maxScrollOffset = frame->view()->maximumScrollPosition(); 1093 1094 if (dx > 0) // scroll right 1095 scrolledHorizontal = scrollOffset.width() < maxScrollOffset.x(); 1096 else if (dx < 0) // scroll left 1097 scrolledHorizontal = scrollOffset.width() > 0; 1098 1099 if (dy > 0) // scroll down 1100 scrolledVertical = scrollOffset.height() < maxScrollOffset.y(); 1101 else if (dy < 0) //scroll up 1102 scrolledVertical = scrollOffset.height() > 0; 1103 1104 if (scrolledHorizontal || scrolledVertical) { 1105 frame->view()->scrollBy(IntSize(dx, dy)); 1106 return true; 1107 } 1108 frame = frame->tree()->parent(); 1109 } while (frame && frame->view()); 1110 } 1111 return (scrolledHorizontal || scrolledVertical || scrolledOverflow); 1112 } 1113 1114 bool QWEBKIT_EXPORT qtwebkit_webframe_scrollRecursively(QWebFrame* qFrame, int dx, int dy) 1115 { 1116 return qFrame->scrollRecursively(dx, dy); 1117 } 1118 1119 /*! 1120 \property QWebFrame::scrollPosition 1121 \since 4.5 1122 \brief the position the frame is currently scrolled to. 1123 */ 1124 1125 QPoint QWebFrame::scrollPosition() const 1126 { 1127 if (!d->frame->view()) 1128 return QPoint(0, 0); 1129 1130 IntSize ofs = d->frame->view()->scrollOffset(); 1131 return QPoint(ofs.width(), ofs.height()); 1132 } 1133 1134 void QWebFrame::setScrollPosition(const QPoint &pos) 1135 { 1136 QPoint current = scrollPosition(); 1137 int dx = pos.x() - current.x(); 1138 int dy = pos.y() - current.y(); 1139 scroll(dx, dy); 1140 } 1141 1142 /*! 1143 \since 4.6 1144 Render the \a layer of the frame using \a painter clipping to \a clip. 1145 1146 \sa print() 1147 */ 1148 1149 void QWebFrame::render(QPainter* painter, RenderLayer layer, const QRegion& clip) 1150 { 1151 GraphicsContext context(painter); 1152 if (context.paintingDisabled() && !context.updatingControlTints()) 1153 return; 1154 1155 if (!clip.isEmpty()) 1156 d->renderRelativeCoords(&context, layer, clip); 1157 else if (d->frame->view()) 1158 d->renderRelativeCoords(&context, layer, QRegion(d->frame->view()->frameRect())); 1159 } 1160 1161 /*! 1162 Render the frame into \a painter clipping to \a clip. 1163 */ 1164 void QWebFrame::render(QPainter* painter, const QRegion& clip) 1165 { 1166 GraphicsContext context(painter); 1167 if (context.paintingDisabled() && !context.updatingControlTints()) 1168 return; 1169 1170 d->renderRelativeCoords(&context, AllLayers, clip); 1171 } 1172 1173 /*! 1174 Render the frame into \a painter. 1175 */ 1176 void QWebFrame::render(QPainter* painter) 1177 { 1178 if (!d->frame->view()) 1179 return; 1180 1181 GraphicsContext context(painter); 1182 if (context.paintingDisabled() && !context.updatingControlTints()) 1183 return; 1184 1185 d->renderRelativeCoords(&context, AllLayers, QRegion(d->frame->view()->frameRect())); 1186 } 1187 1188 /*! 1189 \property QWebFrame::textSizeMultiplier 1190 \brief the scaling factor for all text in the frame 1191 \obsolete 1192 1193 Use setZoomFactor instead, in combination with the ZoomTextOnly attribute in 1194 QWebSettings. 1195 1196 \note Setting this property also enables the ZoomTextOnly attribute in 1197 QWebSettings. 1198 */ 1199 1200 /*! 1201 Sets the value of the multiplier used to scale the text in a Web frame to 1202 the \a factor specified. 1203 */ 1204 void QWebFrame::setTextSizeMultiplier(qreal factor) 1205 { 1206 d->frame->setZoomFactor(factor, /*isTextOnly*/true); 1207 } 1208 1209 /*! 1210 Returns the value of the multiplier used to scale the text in a Web frame. 1211 */ 1212 qreal QWebFrame::textSizeMultiplier() const 1213 { 1214 return d->frame->zoomFactor(); 1215 } 1216 1217 /*! 1218 \property QWebFrame::zoomFactor 1219 \since 4.5 1220 \brief the zoom factor for the frame 1221 */ 1222 1223 void QWebFrame::setZoomFactor(qreal factor) 1224 { 1225 d->frame->setZoomFactor(factor, d->frame->isZoomFactorTextOnly()); 1226 } 1227 1228 qreal QWebFrame::zoomFactor() const 1229 { 1230 return d->frame->zoomFactor(); 1231 } 1232 1233 /*! 1234 \property QWebFrame::focus 1235 \since 4.6 1236 1237 Returns true if this frame has keyboard input focus; otherwise, returns false. 1238 */ 1239 bool QWebFrame::hasFocus() const 1240 { 1241 WebCore::Frame* ff = d->frame->page()->focusController()->focusedFrame(); 1242 return ff && QWebFramePrivate::kit(ff) == this; 1243 } 1244 1245 /*! 1246 \since 4.6 1247 1248 Gives keyboard input focus to this frame. 1249 */ 1250 void QWebFrame::setFocus() 1251 { 1252 QWebFramePrivate::core(this)->page()->focusController()->setFocusedFrame(QWebFramePrivate::core(this)); 1253 } 1254 1255 /*! 1256 Returns the position of the frame relative to it's parent frame. 1257 */ 1258 QPoint QWebFrame::pos() const 1259 { 1260 if (!d->frame->view()) 1261 return QPoint(); 1262 1263 return d->frame->view()->frameRect().topLeft(); 1264 } 1265 1266 /*! 1267 Return the geometry of the frame relative to it's parent frame. 1268 */ 1269 QRect QWebFrame::geometry() const 1270 { 1271 if (!d->frame->view()) 1272 return QRect(); 1273 return d->frame->view()->frameRect(); 1274 } 1275 1276 /*! 1277 \property QWebFrame::contentsSize 1278 \brief the size of the contents in this frame 1279 1280 \sa contentsSizeChanged() 1281 */ 1282 QSize QWebFrame::contentsSize() const 1283 { 1284 FrameView *view = d->frame->view(); 1285 if (!view) 1286 return QSize(); 1287 return QSize(view->contentsWidth(), view->contentsHeight()); 1288 } 1289 1290 /*! 1291 \since 4.6 1292 1293 Returns the document element of this frame. 1294 1295 The document element provides access to the entire structured 1296 content of the frame. 1297 */ 1298 QWebElement QWebFrame::documentElement() const 1299 { 1300 WebCore::Document *doc = d->frame->document(); 1301 if (!doc) 1302 return QWebElement(); 1303 return QWebElement(doc->documentElement()); 1304 } 1305 1306 /*! 1307 \since 4.6 1308 Returns a new list of elements matching the given CSS selector \a selectorQuery. 1309 If there are no matching elements, an empty list is returned. 1310 1311 \l{http://www.w3.org/TR/REC-CSS2/selector.html#q1}{Standard CSS2 selector} syntax is 1312 used for the query. 1313 1314 \sa QWebElement::findAll() 1315 */ 1316 QWebElementCollection QWebFrame::findAllElements(const QString &selectorQuery) const 1317 { 1318 return documentElement().findAll(selectorQuery); 1319 } 1320 1321 /*! 1322 \since 4.6 1323 Returns the first element in the frame's document that matches the 1324 given CSS selector \a selectorQuery. If there is no matching element, a 1325 null element is returned. 1326 1327 \l{http://www.w3.org/TR/REC-CSS2/selector.html#q1}{Standard CSS2 selector} syntax is 1328 used for the query. 1329 1330 \sa QWebElement::findFirst() 1331 */ 1332 QWebElement QWebFrame::findFirstElement(const QString &selectorQuery) const 1333 { 1334 return documentElement().findFirst(selectorQuery); 1335 } 1336 1337 /*! 1338 Performs a hit test on the frame contents at the given position \a pos and returns the hit test result. 1339 */ 1340 QWebHitTestResult QWebFrame::hitTestContent(const QPoint &pos) const 1341 { 1342 if (!d->frame->view() || !d->frame->contentRenderer()) 1343 return QWebHitTestResult(); 1344 1345 HitTestResult result = d->frame->eventHandler()->hitTestResultAtPoint(d->frame->view()->windowToContents(pos), /*allowShadowContent*/ false, /*ignoreClipping*/ true); 1346 1347 if (result.scrollbar()) 1348 return QWebHitTestResult(); 1349 1350 return QWebHitTestResult(new QWebHitTestResultPrivate(result)); 1351 } 1352 1353 /*! \reimp 1354 */ 1355 bool QWebFrame::event(QEvent *e) 1356 { 1357 return QObject::event(e); 1358 } 1359 1360 #ifndef QT_NO_PRINTER 1361 /*! 1362 Prints the frame to the given \a printer. 1363 1364 \sa render() 1365 */ 1366 void QWebFrame::print(QPrinter *printer) const 1367 { 1368 QPainter painter; 1369 if (!painter.begin(printer)) 1370 return; 1371 1372 const qreal zoomFactorX = printer->logicalDpiX() / qt_defaultDpi(); 1373 const qreal zoomFactorY = printer->logicalDpiY() / qt_defaultDpi(); 1374 1375 PrintContext printContext(d->frame); 1376 float pageHeight = 0; 1377 1378 QRect qprinterRect = printer->pageRect(); 1379 1380 IntRect pageRect(0, 0, 1381 int(qprinterRect.width() / zoomFactorX), 1382 int(qprinterRect.height() / zoomFactorY)); 1383 1384 printContext.begin(pageRect.width()); 1385 1386 printContext.computePageRects(pageRect, /* headerHeight */ 0, /* footerHeight */ 0, /* userScaleFactor */ 1.0, pageHeight); 1387 1388 int docCopies; 1389 int pageCopies; 1390 if (printer->collateCopies()) { 1391 docCopies = 1; 1392 pageCopies = printer->numCopies(); 1393 } else { 1394 docCopies = printer->numCopies(); 1395 pageCopies = 1; 1396 } 1397 1398 int fromPage = printer->fromPage(); 1399 int toPage = printer->toPage(); 1400 bool ascending = true; 1401 1402 if (fromPage == 0 && toPage == 0) { 1403 fromPage = 1; 1404 toPage = printContext.pageCount(); 1405 } 1406 // paranoia check 1407 fromPage = qMax(1, fromPage); 1408 toPage = qMin(printContext.pageCount(), toPage); 1409 if (toPage < fromPage) { 1410 // if the user entered a page range outside the actual number 1411 // of printable pages, just return 1412 return; 1413 } 1414 1415 if (printer->pageOrder() == QPrinter::LastPageFirst) { 1416 int tmp = fromPage; 1417 fromPage = toPage; 1418 toPage = tmp; 1419 ascending = false; 1420 } 1421 1422 painter.scale(zoomFactorX, zoomFactorY); 1423 GraphicsContext ctx(&painter); 1424 1425 for (int i = 0; i < docCopies; ++i) { 1426 int page = fromPage; 1427 while (true) { 1428 for (int j = 0; j < pageCopies; ++j) { 1429 if (printer->printerState() == QPrinter::Aborted 1430 || printer->printerState() == QPrinter::Error) { 1431 printContext.end(); 1432 return; 1433 } 1434 printContext.spoolPage(ctx, page - 1, pageRect.width()); 1435 if (j < pageCopies - 1) 1436 printer->newPage(); 1437 } 1438 1439 if (page == toPage) 1440 break; 1441 1442 if (ascending) 1443 ++page; 1444 else 1445 --page; 1446 1447 printer->newPage(); 1448 } 1449 1450 if ( i < docCopies - 1) 1451 printer->newPage(); 1452 } 1453 1454 printContext.end(); 1455 } 1456 #endif // QT_NO_PRINTER 1457 1458 /*! 1459 Evaluates the JavaScript defined by \a scriptSource using this frame as context 1460 and returns the result of the last executed statement. 1461 1462 \sa addToJavaScriptWindowObject(), javaScriptWindowObjectCleared() 1463 */ 1464 QVariant QWebFrame::evaluateJavaScript(const QString& scriptSource) 1465 { 1466 ScriptController *proxy = d->frame->script(); 1467 QVariant rc; 1468 if (proxy) { 1469 JSC::JSValue v = d->frame->script()->executeScript(ScriptSourceCode(scriptSource)).jsValue(); 1470 int distance = 0; 1471 rc = JSC::Bindings::convertValueToQVariant(proxy->globalObject(mainThreadNormalWorld())->globalExec(), v, QMetaType::Void, &distance); 1472 } 1473 return rc; 1474 } 1475 1476 /*! 1477 \since 4.5 1478 1479 Returns the frame's security origin. 1480 */ 1481 QWebSecurityOrigin QWebFrame::securityOrigin() const 1482 { 1483 QWebFrame* that = const_cast<QWebFrame*>(this); 1484 QWebSecurityOriginPrivate* priv = new QWebSecurityOriginPrivate(QWebFramePrivate::core(that)->document()->securityOrigin()); 1485 return QWebSecurityOrigin(priv); 1486 } 1487 1488 WebCore::Frame* QWebFramePrivate::core(QWebFrame* webFrame) 1489 { 1490 return webFrame->d->frame; 1491 } 1492 1493 QWebFrame* QWebFramePrivate::kit(WebCore::Frame* coreFrame) 1494 { 1495 return static_cast<FrameLoaderClientQt*>(coreFrame->loader()->client())->webFrame(); 1496 } 1497 1498 1499 /*! 1500 \fn void QWebFrame::javaScriptWindowObjectCleared() 1501 1502 This signal is emitted whenever the global window object of the JavaScript 1503 environment is cleared, e.g., before starting a new load. 1504 1505 If you intend to add QObjects to a QWebFrame using 1506 addToJavaScriptWindowObject(), you should add them in a slot connected 1507 to this signal. This ensures that your objects remain accessible when 1508 loading new URLs. 1509 */ 1510 1511 /*! 1512 \fn void QWebFrame::provisionalLoad() 1513 \internal 1514 */ 1515 1516 /*! 1517 \fn void QWebFrame::titleChanged(const QString &title) 1518 1519 This signal is emitted whenever the title of the frame changes. 1520 The \a title string specifies the new title. 1521 1522 \sa title() 1523 */ 1524 1525 /*! 1526 \fn void QWebFrame::urlChanged(const QUrl &url) 1527 1528 This signal is emitted with the URL of the frame when the frame's title is 1529 received. The new URL is specified by \a url. 1530 1531 \sa url() 1532 */ 1533 1534 /*! 1535 \fn void QWebFrame::initialLayoutCompleted() 1536 1537 This signal is emitted when the frame is laid out the first time. 1538 This is the first time you will see contents displayed on the frame. 1539 1540 \note A frame can be laid out multiple times. 1541 */ 1542 1543 /*! 1544 \fn void QWebFrame::iconChanged() 1545 1546 This signal is emitted when the icon ("favicon") associated with the frame 1547 has been loaded. 1548 1549 \sa icon() 1550 */ 1551 1552 /*! 1553 \fn void QWebFrame::contentsSizeChanged(const QSize &size) 1554 \since 4.6 1555 1556 This signal is emitted when the frame's contents size changes 1557 to \a size. 1558 1559 \sa contentsSize() 1560 */ 1561 1562 /*! 1563 \fn void QWebFrame::loadStarted() 1564 \since 4.6 1565 1566 This signal is emitted when a new load of this frame is started. 1567 1568 \sa loadFinished() 1569 */ 1570 1571 /*! 1572 \fn void QWebFrame::loadFinished(bool ok) 1573 \since 4.6 1574 1575 This signal is emitted when a load of this frame is finished. 1576 \a ok will indicate whether the load was successful or any error occurred. 1577 1578 \sa loadStarted() 1579 */ 1580 1581 /*! 1582 \class QWebHitTestResult 1583 \since 4.4 1584 \brief The QWebHitTestResult class provides information about the web 1585 page content after a hit test. 1586 1587 \inmodule QtWebKit 1588 1589 QWebHitTestResult is returned by QWebFrame::hitTestContent() to provide 1590 information about the content of the web page at the specified position. 1591 */ 1592 1593 /*! 1594 \internal 1595 */ 1596 QWebHitTestResult::QWebHitTestResult(QWebHitTestResultPrivate *priv) 1597 : d(priv) 1598 { 1599 } 1600 1601 QWebHitTestResultPrivate::QWebHitTestResultPrivate(const WebCore::HitTestResult &hitTest) 1602 : isContentEditable(false) 1603 , isContentSelected(false) 1604 , isScrollBar(false) 1605 { 1606 if (!hitTest.innerNode()) 1607 return; 1608 pos = hitTest.point(); 1609 WebCore::TextDirection dir; 1610 title = hitTest.title(dir); 1611 linkText = hitTest.textContent(); 1612 linkUrl = hitTest.absoluteLinkURL(); 1613 linkTitle = hitTest.titleDisplayString(); 1614 alternateText = hitTest.altDisplayString(); 1615 imageUrl = hitTest.absoluteImageURL(); 1616 innerNode = hitTest.innerNode(); 1617 innerNonSharedNode = hitTest.innerNonSharedNode(); 1618 boundingRect = innerNonSharedNode ? innerNonSharedNode->renderer()->absoluteBoundingBoxRect(true) : IntRect(); 1619 WebCore::Image *img = hitTest.image(); 1620 if (img) { 1621 QPixmap *pix = img->nativeImageForCurrentFrame(); 1622 if (pix) 1623 pixmap = *pix; 1624 } 1625 WebCore::Frame *wframe = hitTest.targetFrame(); 1626 if (wframe) 1627 linkTargetFrame = QWebFramePrivate::kit(wframe); 1628 linkElement = QWebElement(hitTest.URLElement()); 1629 1630 isContentEditable = hitTest.isContentEditable(); 1631 isContentSelected = hitTest.isSelected(); 1632 isScrollBar = hitTest.scrollbar(); 1633 1634 if (innerNonSharedNode && innerNonSharedNode->document() 1635 && innerNonSharedNode->document()->frame()) 1636 frame = QWebFramePrivate::kit(innerNonSharedNode->document()->frame()); 1637 1638 enclosingBlock = QWebElement(WebCore::enclosingBlock(innerNode.get())); 1639 } 1640 1641 /*! 1642 Constructs a null hit test result. 1643 */ 1644 QWebHitTestResult::QWebHitTestResult() 1645 : d(0) 1646 { 1647 } 1648 1649 /*! 1650 Constructs a hit test result from \a other. 1651 */ 1652 QWebHitTestResult::QWebHitTestResult(const QWebHitTestResult &other) 1653 : d(0) 1654 { 1655 if (other.d) 1656 d = new QWebHitTestResultPrivate(*other.d); 1657 } 1658 1659 /*! 1660 Assigns the \a other hit test result to this. 1661 */ 1662 QWebHitTestResult &QWebHitTestResult::operator=(const QWebHitTestResult &other) 1663 { 1664 if (this != &other) { 1665 if (other.d) { 1666 if (!d) 1667 d = new QWebHitTestResultPrivate; 1668 *d = *other.d; 1669 } else { 1670 delete d; 1671 d = 0; 1672 } 1673 } 1674 return *this; 1675 } 1676 1677 /*! 1678 Destructor. 1679 */ 1680 QWebHitTestResult::~QWebHitTestResult() 1681 { 1682 delete d; 1683 } 1684 1685 /*! 1686 Returns true if the hit test result is null; otherwise returns false. 1687 */ 1688 bool QWebHitTestResult::isNull() const 1689 { 1690 return !d; 1691 } 1692 1693 /*! 1694 Returns the position where the hit test occured. 1695 */ 1696 QPoint QWebHitTestResult::pos() const 1697 { 1698 if (!d) 1699 return QPoint(); 1700 return d->pos; 1701 } 1702 1703 /*! 1704 \since 4.5 1705 Returns the bounding rect of the element. 1706 */ 1707 QRect QWebHitTestResult::boundingRect() const 1708 { 1709 if (!d) 1710 return QRect(); 1711 return d->boundingRect; 1712 } 1713 1714 /*! 1715 \since 4.6 1716 Returns the block element that encloses the element hit. 1717 1718 A block element is an element that is rendered using the 1719 CSS "block" style. This includes for example text 1720 paragraphs. 1721 */ 1722 QWebElement QWebHitTestResult::enclosingBlockElement() const 1723 { 1724 if (!d) 1725 return QWebElement(); 1726 return d->enclosingBlock; 1727 } 1728 1729 /*! 1730 Returns the title of the nearest enclosing HTML element. 1731 */ 1732 QString QWebHitTestResult::title() const 1733 { 1734 if (!d) 1735 return QString(); 1736 return d->title; 1737 } 1738 1739 /*! 1740 Returns the text of the link. 1741 */ 1742 QString QWebHitTestResult::linkText() const 1743 { 1744 if (!d) 1745 return QString(); 1746 return d->linkText; 1747 } 1748 1749 /*! 1750 Returns the url to which the link points to. 1751 */ 1752 QUrl QWebHitTestResult::linkUrl() const 1753 { 1754 if (!d) 1755 return QUrl(); 1756 return d->linkUrl; 1757 } 1758 1759 /*! 1760 Returns the title of the link. 1761 */ 1762 QUrl QWebHitTestResult::linkTitle() const 1763 { 1764 if (!d) 1765 return QUrl(); 1766 return d->linkTitle; 1767 } 1768 1769 /*! 1770 \since 4.6 1771 Returns the element that represents the link. 1772 1773 \sa linkTargetFrame() 1774 */ 1775 QWebElement QWebHitTestResult::linkElement() const 1776 { 1777 if (!d) 1778 return QWebElement(); 1779 return d->linkElement; 1780 } 1781 1782 /*! 1783 Returns the frame that will load the link if it is activated. 1784 1785 \sa linkElement() 1786 */ 1787 QWebFrame *QWebHitTestResult::linkTargetFrame() const 1788 { 1789 if (!d) 1790 return 0; 1791 return d->linkTargetFrame; 1792 } 1793 1794 /*! 1795 Returns the alternate text of the element. This corresponds to the HTML alt attribute. 1796 */ 1797 QString QWebHitTestResult::alternateText() const 1798 { 1799 if (!d) 1800 return QString(); 1801 return d->alternateText; 1802 } 1803 1804 /*! 1805 Returns the url of the image. 1806 */ 1807 QUrl QWebHitTestResult::imageUrl() const 1808 { 1809 if (!d) 1810 return QUrl(); 1811 return d->imageUrl; 1812 } 1813 1814 /*! 1815 Returns a QPixmap containing the image. A null pixmap is returned if the 1816 element being tested is not an image. 1817 */ 1818 QPixmap QWebHitTestResult::pixmap() const 1819 { 1820 if (!d) 1821 return QPixmap(); 1822 return d->pixmap; 1823 } 1824 1825 /*! 1826 Returns true if the content is editable by the user; otherwise returns false. 1827 */ 1828 bool QWebHitTestResult::isContentEditable() const 1829 { 1830 if (!d) 1831 return false; 1832 return d->isContentEditable; 1833 } 1834 1835 /*! 1836 Returns true if the content tested is part of the selection; otherwise returns false. 1837 */ 1838 bool QWebHitTestResult::isContentSelected() const 1839 { 1840 if (!d) 1841 return false; 1842 return d->isContentSelected; 1843 } 1844 1845 /*! 1846 \since 4.6 1847 Returns the underlying DOM element as QWebElement. 1848 */ 1849 QWebElement QWebHitTestResult::element() const 1850 { 1851 if (!d || !d->innerNonSharedNode || !d->innerNonSharedNode->isElementNode()) 1852 return QWebElement(); 1853 1854 return QWebElement(static_cast<WebCore::Element*>(d->innerNonSharedNode.get())); 1855 } 1856 1857 /*! 1858 Returns the frame the hit test was executed in. 1859 */ 1860 QWebFrame *QWebHitTestResult::frame() const 1861 { 1862 if (!d) 1863 return 0; 1864 return d->frame; 1865 } 1866