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