• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &lt;title&gt; 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