WebKit/qt/Api/qwebframe.cpp
changeset 0 4f2f89ce4247
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebKit/qt/Api/qwebframe.cpp	Fri Sep 17 09:02:29 2010 +0300
@@ -0,0 +1,1790 @@
+/*
+    Copyright (C) 2008,2009 Nokia Corporation and/or its subsidiary(-ies)
+    Copyright (C) 2007 Staikos Computing Services Inc.
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "qwebframe.h"
+
+#include "Bridge.h"
+#include "CallFrame.h"
+#include "Document.h"
+#include "DocumentLoader.h"
+#include "DragData.h"
+#include "Element.h"
+#include "FocusController.h"
+#include "Frame.h"
+#include "FrameLoaderClientQt.h"
+#include "FrameTree.h"
+#include "FrameView.h"
+#include "GCController.h"
+#include "GraphicsContext.h"
+#include "HTMLMetaElement.h"
+#include "HitTestResult.h"
+#include "IconDatabase.h"
+#include "InspectorController.h"
+#include "JSDOMBinding.h"
+#include "JSDOMWindowBase.h"
+#include "JSLock.h"
+#include "JSObject.h"
+#include "NodeList.h"
+#include "Page.h"
+#include "PlatformMouseEvent.h"
+#include "PlatformWheelEvent.h"
+#include "PrintContext.h"
+#include "PutPropertySlot.h"
+#include "RenderLayer.h"
+#include "RenderTreeAsText.h"
+#include "RenderView.h"
+#include "ResourceRequest.h"
+#include "ScriptController.h"
+#include "ScriptSourceCode.h"
+#include "ScriptValue.h"
+#include "Scrollbar.h"
+#include "Settings.h"
+#include "SelectionController.h"
+#include "SubstituteData.h"
+#include "SVGSMILElement.h"
+#include "TiledBackingStore.h"
+#include "htmlediting.h"
+#include "markup.h"
+#include "qt_instance.h"
+#include "qt_runtime.h"
+#include "qwebelement.h"
+#include "qwebframe_p.h"
+#include "qwebpage.h"
+#include "qwebpage_p.h"
+#include "qwebsecurityorigin.h"
+#include "qwebsecurityorigin_p.h"
+#include "qwebscriptworld.h"
+#include "qwebscriptworld_p.h"
+#include "runtime_object.h"
+#include "runtime_root.h"
+#include "wtf/HashMap.h"
+#include <QMultiMap>
+#include <qdebug.h>
+#include <qevent.h>
+#include <qfileinfo.h>
+#include <qpainter.h>
+#include <qprinter.h>
+#include <qregion.h>
+#include <qnetworkrequest.h>
+
+using namespace WebCore;
+
+// from text/qfont.cpp
+QT_BEGIN_NAMESPACE
+extern Q_GUI_EXPORT int qt_defaultDpi();
+QT_END_NAMESPACE
+
+bool QWEBKIT_EXPORT qtwebkit_webframe_scrollOverflow(QWebFrame* qFrame, int dx, int dy, const QPoint& pos)
+{
+    WebCore::Frame* frame = QWebFramePrivate::core(qFrame);
+    if (!frame || !frame->document() || !frame->view() || !frame->eventHandler())
+        return false;
+
+    QPoint contentsPos = frame->view()->windowToContents(pos);
+    Node* node = frame->document()->elementFromPoint(contentsPos.x(), contentsPos.y());
+    if (!node)
+        return false;
+
+    RenderObject* renderer = node->renderer();
+    if (!renderer)
+        return false;
+
+    if (renderer->isListBox())
+        return false;
+
+    RenderLayer* renderLayer = renderer->enclosingLayer();
+    if (!renderLayer)
+        return false;
+
+    bool scrolledHorizontal = false;
+    bool scrolledVertical = false;
+
+    do {
+        if (dx > 0)
+            scrolledHorizontal = renderLayer->scroll(ScrollRight, ScrollByPixel, dx);
+        else if (dx < 0)
+            scrolledHorizontal = renderLayer->scroll(ScrollLeft, ScrollByPixel, qAbs(dx));
+
+        if (dy > 0)
+            scrolledVertical = renderLayer->scroll(ScrollDown, ScrollByPixel, dy);
+        else if (dy < 0)
+            scrolledVertical = renderLayer->scroll(ScrollUp, ScrollByPixel, qAbs(dy));
+
+        if (scrolledHorizontal || scrolledVertical)
+            return true;
+
+        renderLayer = renderLayer->parent();
+    } while (renderLayer);
+
+    return false;
+}
+
+
+/*!
+  \internal
+  Scrolls nested frames starting at this frame, \a dx pixels to the right 
+  and \a dy pixels downward. Both \a dx and \a dy may be negative. First attempts
+  to scroll elements with CSS overflow at position pos, followed by this frame. If this 
+  frame doesn't scroll, attempts to scroll the parent
+*/
+void QWEBKIT_EXPORT qtwebkit_webframe_scrollRecursively(QWebFrame* qFrame, int dx, int dy, const QPoint& pos)
+{
+    if (!qFrame)
+        return;
+
+    if (qtwebkit_webframe_scrollOverflow(qFrame, dx, dy, pos))
+        return;
+
+    bool scrollHorizontal = false;
+    bool scrollVertical = false;
+
+    do {
+        if (dx > 0)  // scroll right
+            scrollHorizontal = qFrame->scrollBarValue(Qt::Horizontal) < qFrame->scrollBarMaximum(Qt::Horizontal);
+        else if (dx < 0)  // scroll left
+            scrollHorizontal = qFrame->scrollBarValue(Qt::Horizontal) > qFrame->scrollBarMinimum(Qt::Horizontal);
+
+        if (dy > 0)  // scroll down
+            scrollVertical = qFrame->scrollBarValue(Qt::Vertical) < qFrame->scrollBarMaximum(Qt::Vertical);
+        else if (dy < 0) //scroll up
+            scrollVertical = qFrame->scrollBarValue(Qt::Vertical) > qFrame->scrollBarMinimum(Qt::Vertical);
+
+        if (scrollHorizontal || scrollVertical) {
+            qFrame->scroll(dx, dy);
+            return;
+        }
+
+        qFrame = qFrame->parentFrame();
+    } while (qFrame);
+}
+
+QWebFrameData::QWebFrameData(WebCore::Page* parentPage, WebCore::Frame* parentFrame,
+                             WebCore::HTMLFrameOwnerElement* ownerFrameElement,
+                             const WebCore::String& frameName)
+    : name(frameName)
+    , ownerElement(ownerFrameElement)
+    , page(parentPage)
+    , allowsScrolling(true)
+    , marginWidth(0)
+    , marginHeight(0)
+{
+    frameLoaderClient = new FrameLoaderClientQt();
+    frame = Frame::create(page, ownerElement, frameLoaderClient);
+
+    // FIXME: All of the below should probably be moved over into WebCore
+    frame->tree()->setName(name);
+    if (parentFrame)
+        parentFrame->tree()->appendChild(frame);
+}
+
+void QWebFramePrivate::init(QWebFrame *qframe, QWebFrameData *frameData)
+{
+    q = qframe;
+
+    allowsScrolling = frameData->allowsScrolling;
+    marginWidth = frameData->marginWidth;
+    marginHeight = frameData->marginHeight;
+    frame = frameData->frame.get();
+    frameLoaderClient = frameData->frameLoaderClient;
+    frameLoaderClient->setFrame(qframe, frame);
+
+    frame->init();
+}
+
+void QWebFramePrivate::setPage(QWebPage* newPage)
+{
+    if (page == newPage)
+        return;
+
+    // The QWebFrame is created as a child of QWebPage or a parent QWebFrame.
+    // That adds it to QObject's internal children list and ensures it will be
+    // deleted when parent QWebPage is deleted. Reparent if needed.
+    if (q->parent() == qobject_cast<QObject*>(page))
+        q->setParent(newPage);
+
+    page = newPage;
+    emit q->pageChanged();
+}
+
+WebCore::Scrollbar* QWebFramePrivate::horizontalScrollBar() const
+{
+    if (!frame->view())
+        return 0;
+    return frame->view()->horizontalScrollbar();
+}
+
+WebCore::Scrollbar* QWebFramePrivate::verticalScrollBar() const
+{
+    if (!frame->view())
+        return 0;
+    return frame->view()->verticalScrollbar();
+}
+
+#if ENABLE(TILED_BACKING_STORE)
+void QWebFramePrivate::renderFromTiledBackingStore(GraphicsContext* context, const QRegion& clip)
+{
+    ASSERT(frame->tiledBackingStore());
+
+    if (!frame->view() || !frame->contentRenderer())
+        return;
+
+    QVector<QRect> vector = clip.rects();
+    if (vector.isEmpty())
+        return;
+
+    QPainter* painter = context->platformContext();
+
+    WebCore::FrameView* view = frame->view();
+    
+    int scrollX = view->scrollX();
+    int scrollY = view->scrollY();
+    context->translate(-scrollX, -scrollY);
+
+    for (int i = 0; i < vector.size(); ++i) {
+        const QRect& clipRect = vector.at(i);
+
+        painter->save();
+        
+        QRect rect = clipRect.translated(scrollX, scrollY);
+        painter->setClipRect(rect, Qt::IntersectClip);
+
+        frame->tiledBackingStore()->paint(context, rect);
+
+        painter->restore();
+    }
+}
+#endif
+
+void QWebFramePrivate::renderRelativeCoords(GraphicsContext* context, QWebFrame::RenderLayer layer, const QRegion& clip)
+{
+    if (!frame->view() || !frame->contentRenderer())
+        return;
+
+    QVector<QRect> vector = clip.rects();
+    if (vector.isEmpty())
+        return;
+
+    QPainter* painter = context->platformContext();
+
+    WebCore::FrameView* view = frame->view();
+    view->layoutIfNeededRecursive();
+
+    for (int i = 0; i < vector.size(); ++i) {
+        const QRect& clipRect = vector.at(i);
+
+        QRect intersectedRect = clipRect.intersected(view->frameRect());
+
+        painter->save();
+        painter->setClipRect(clipRect, Qt::IntersectClip);
+
+        int x = view->x();
+        int y = view->y();
+
+        if (layer & QWebFrame::ContentsLayer) {
+            context->save();
+
+            int scrollX = view->scrollX();
+            int scrollY = view->scrollY();
+
+            QRect rect = intersectedRect;
+            context->translate(x, y);
+            rect.translate(-x, -y);
+            context->translate(-scrollX, -scrollY);
+            rect.translate(scrollX, scrollY);
+            context->clip(view->visibleContentRect());
+
+            view->paintContents(context, rect);
+
+            context->restore();
+        }
+
+        if (layer & QWebFrame::ScrollBarLayer
+            && !view->scrollbarsSuppressed()
+            && (view->horizontalScrollbar() || view->verticalScrollbar())) {
+            context->save();
+
+            QRect rect = intersectedRect;
+            context->translate(x, y);
+            rect.translate(-x, -y);
+
+            view->paintScrollbars(context, rect);
+
+            context->restore();
+        }
+
+#if ENABLE(PAN_SCROLLING)
+        if (layer & QWebFrame::PanIconLayer)
+            view->paintPanScrollIcon(context);
+#endif
+
+        painter->restore();
+    }
+}
+
+/*!
+    \class QWebFrame
+    \since 4.4
+    \brief The QWebFrame class represents a frame in a web page.
+
+    \inmodule QtWebKit
+
+    QWebFrame represents a frame inside a web page. Each QWebPage
+    object contains at least one frame, the main frame, obtained using
+    QWebPage::mainFrame(). Additional frames will be created for HTML
+    \c{<frame>} or \c{<iframe>} elements.
+
+    A frame can be loaded using load() or setUrl(). Alternatively, if you have
+    the HTML content readily available, you can use setHtml() instead.
+
+    The page() function returns a pointer to the web page object. See
+    \l{QWebView}{Elements of QWebView} for an explanation of how web
+    frames are related to a web page and web view.
+
+    The QWebFrame class also offers methods to retrieve both the URL currently
+    loaded by the frame (see url()) as well as the URL originally requested
+    to be loaded (see requestedUrl()). These methods make possible the retrieval
+    of the URL before and after a DNS resolution or a redirection occurs during
+    the load process. The requestedUrl() also matches to the URL added to the
+    frame history (\l{QWebHistory}) if load is successful.
+
+    The title of an HTML frame can be accessed with the title() property.
+    Additionally, a frame may also specify an icon, which can be accessed
+    using the icon() property. If the title or the icon changes, the
+    corresponding titleChanged() and iconChanged() signals will be emitted.
+    The zoomFactor() property can be used to change the overall size
+    of the content displayed in the frame.
+
+    QWebFrame objects are created and controlled by the web page. You
+    can connect to the web page's \l{QWebPage::}{frameCreated()} signal
+    to be notified when a new frame is created.
+
+    There are multiple ways to programmatically examine the contents of a frame.
+    The hitTestContent() function can be used to find elements by coordinate.
+    For access to the underlying DOM tree, there is documentElement(),
+    findAllElements() and findFirstElement().
+
+    A QWebFrame can be printed onto a QPrinter using the print() function.
+    This function is marked as a slot and can be conveniently connected to
+    \l{QPrintPreviewDialog}'s \l{QPrintPreviewDialog::}{paintRequested()}
+    signal.
+
+    \sa QWebPage
+*/
+
+/*!
+    \enum QWebFrame::RenderLayer
+
+    This enum describes the layers available for rendering using \l{QWebFrame::}{render()}.
+    The layers can be OR-ed together from the following list:
+
+    \value ContentsLayer The web content of the frame
+    \value ScrollBarLayer The scrollbars of the frame
+    \value PanIconLayer The icon used when panning the frame
+
+    \value AllLayers Includes all the above layers
+*/
+
+QWebFrame::QWebFrame(QWebPage *parent, QWebFrameData *frameData)
+    : QObject(parent)
+    , d(new QWebFramePrivate)
+{
+    d->page = parent;
+    d->init(this, frameData);
+
+    if (!frameData->url.isEmpty()) {
+        WebCore::ResourceRequest request(frameData->url, frameData->referrer);
+        d->frame->loader()->load(request, frameData->name, false);
+    }
+}
+
+QWebFrame::QWebFrame(QWebFrame *parent, QWebFrameData *frameData)
+    : QObject(parent)
+    , d(new QWebFramePrivate)
+{
+    d->page = parent->d->page;
+    d->init(this, frameData);
+}
+
+QWebFrame::~QWebFrame()
+{
+    if (d->frame && d->frame->loader() && d->frame->loader()->client())
+        static_cast<FrameLoaderClientQt*>(d->frame->loader()->client())->m_webFrame = 0;
+
+    delete d;
+}
+
+/*!
+    Make \a object available under \a name from within the frame's JavaScript
+    context. The \a object will be inserted as a child of the frame's window
+    object.
+
+    Qt properties will be exposed as JavaScript properties and slots as
+    JavaScript methods.
+
+    If you want to ensure that your QObjects remain accessible after loading a
+    new URL, you should add them in a slot connected to the
+    javaScriptWindowObjectCleared() signal.
+
+    If Javascript is not enabled for this page, then this method does nothing.
+
+    The \a object will never be explicitly deleted by QtWebKit.
+*/
+void QWebFrame::addToJavaScriptWindowObject(const QString &name, QObject *object)
+{
+    addToJavaScriptWindowObject(name, object, QScriptEngine::QtOwnership);
+}
+
+/*!
+    \fn void QWebFrame::addToJavaScriptWindowObject(const QString &name, QObject *object, QScriptEngine::ValueOwnership own)
+    \overload
+
+    Make \a object available under \a name from within the frame's JavaScript
+    context. The \a object will be inserted as a child of the frame's window
+    object.
+
+    Qt properties will be exposed as JavaScript properties and slots as
+    JavaScript methods.
+
+    If you want to ensure that your QObjects remain accessible after loading a
+    new URL, you should add them in a slot connected to the
+    javaScriptWindowObjectCleared() signal.
+
+    If Javascript is not enabled for this page, then this method does nothing.
+
+    The ownership of \a object is specified using \a own.
+*/
+void QWebFrame::addToJavaScriptWindowObject(const QString &name, QObject *object, QScriptEngine::ValueOwnership ownership)
+{
+    if (!page()->settings()->testAttribute(QWebSettings::JavascriptEnabled))
+        return;
+
+    JSC::JSLock lock(JSC::SilenceAssertionsOnly);
+    JSDOMWindow* window = toJSDOMWindow(d->frame, mainThreadNormalWorld());
+    JSC::Bindings::RootObject* root;
+    if (ownership == QScriptEngine::QtOwnership)
+        root = d->frame->script()->cacheableBindingRootObject();
+    else
+        root = d->frame->script()->bindingRootObject();
+
+    if (!window) {
+        qDebug() << "Warning: couldn't get window object";
+        return;
+    }
+
+    JSC::ExecState* exec = window->globalExec();
+
+    JSC::JSObject* runtimeObject =
+            JSC::Bindings::QtInstance::getQtInstance(object, root, ownership)->createRuntimeObject(exec);
+
+    JSC::PutPropertySlot slot;
+    window->put(exec, JSC::Identifier(exec, (const UChar *) name.constData(), name.length()), runtimeObject, slot);
+}
+
+/*!
+    Returns the frame's content as HTML, enclosed in HTML and BODY tags.
+
+    \sa setHtml(), toPlainText()
+*/
+QString QWebFrame::toHtml() const
+{
+    if (!d->frame->document())
+        return QString();
+    return createMarkup(d->frame->document());
+}
+
+/*!
+    Returns the content of this frame converted to plain text, completely
+    stripped of all HTML formatting.
+
+    \sa toHtml()
+*/
+QString QWebFrame::toPlainText() const
+{
+    if (d->frame->view() && d->frame->view()->layoutPending())
+        d->frame->view()->layout();
+
+    Element *documentElement = d->frame->document()->documentElement();
+    if (documentElement)
+        return documentElement->innerText();
+    return QString();
+}
+
+/*!
+    Returns a dump of the rendering tree. This is mainly useful for debugging
+    html.
+*/
+QString QWebFrame::renderTreeDump() const
+{
+    if (d->frame->view() && d->frame->view()->layoutPending())
+        d->frame->view()->layout();
+
+    return externalRepresentation(d->frame);
+}
+
+/*!
+    \property QWebFrame::title
+    \brief the title of the frame as defined by the HTML &lt;title&gt; element
+
+    \sa titleChanged()
+*/
+
+QString QWebFrame::title() const
+{
+    if (d->frame->document())
+        return d->frame->loader()->documentLoader()->title();
+    return QString();
+}
+
+/*!
+    \since 4.5
+    \brief Returns the meta data in this frame as a QMultiMap
+
+    The meta data consists of the name and content attributes of the
+    of the \c{<meta>} tags in the HTML document.
+
+    For example:
+
+    \code
+    <html>
+        <head>
+            <meta name="description" content="This document is a tutorial about Qt development">
+            <meta name="keywords" content="Qt, WebKit, Programming">
+        </head>
+        ...
+    </html>
+    \endcode
+
+    Given the above HTML code the metaData() function will return a map with two entries:
+    \table
+    \header \o Key
+            \o Value
+    \row    \o "description"
+            \o "This document is a tutorial about Qt development"
+    \row    \o "keywords"
+            \o "Qt, WebKit, Programming"
+    \endtable
+
+    This function returns a multi map to support multiple meta tags with the same attribute name.
+*/
+QMultiMap<QString, QString> QWebFrame::metaData() const
+{
+    if (!d->frame->document())
+       return QMap<QString, QString>();
+
+    QMultiMap<QString, QString> map;
+    Document* doc = d->frame->document();
+    RefPtr<NodeList> list = doc->getElementsByTagName("meta");
+    unsigned len = list->length();
+    for (unsigned i = 0; i < len; i++) {
+        HTMLMetaElement* meta = static_cast<HTMLMetaElement*>(list->item(i));
+        map.insert(meta->name(), meta->content());
+    }
+    return map;
+}
+
+static inline QUrl ensureAbsoluteUrl(const QUrl &url)
+{
+    if (!url.isRelative())
+        return url;
+
+    return QUrl::fromLocalFile(QFileInfo(url.toLocalFile()).absoluteFilePath());
+}
+
+/*!
+    \property QWebFrame::url
+    \brief the url of the frame currently viewed
+
+    Setting this property clears the view and loads the URL.
+
+    By default, this property contains an empty, invalid URL.
+
+    \sa urlChanged()
+*/
+
+void QWebFrame::setUrl(const QUrl &url)
+{
+    const QUrl absolute = ensureAbsoluteUrl(url);
+    d->frame->loader()->writer()->begin(absolute);
+    d->frame->loader()->writer()->end();
+    load(absolute);
+}
+
+QUrl QWebFrame::url() const
+{
+    return d->frame->loader()->url();
+}
+
+/*!
+    \since 4.6
+    \property QWebFrame::requestedUrl
+
+    The URL requested to loaded by the frame currently viewed. The URL may differ from
+    the one returned by url() if a DNS resolution or a redirection occurs.
+
+    \sa url(), setUrl()
+*/
+QUrl QWebFrame::requestedUrl() const
+{
+    // There are some possible edge cases to be handled here,
+    // apart from checking if activeDocumentLoader is valid:
+    //
+    // * Method can be called while processing an unsucessful load.
+    //   In this case, frameLoaderClient will hold the current error
+    //   (m_loadError), and we will make use of it to recover the 'failingURL'.
+    // * If the 'failingURL' holds a null'ed string though, we fallback
+    //   to 'outgoingReferrer' (it yet is safer than originalRequest).
+    FrameLoader* loader = d->frame->loader();
+    FrameLoaderClientQt* loaderClient = d->frameLoaderClient;
+
+    if (!loader->activeDocumentLoader()
+        || !loaderClient->m_loadError.isNull()) {
+        if (!loaderClient->m_loadError.failingURL().isNull())
+            return QUrl(loaderClient->m_loadError.failingURL());
+        else if (!loader->outgoingReferrer().isEmpty())
+            return QUrl(loader->outgoingReferrer());
+    }
+
+    return loader->originalRequest().url();
+}
+/*!
+    \since 4.6
+    \property QWebFrame::baseUrl
+    \brief the base URL of the frame, can be used to resolve relative URLs
+    \since 4.6
+*/
+
+QUrl QWebFrame::baseUrl() const
+{
+    return d->frame->loader()->baseURL();
+}
+
+/*!
+    \property QWebFrame::icon
+    \brief the icon associated with this frame
+
+    \sa iconChanged(), QWebSettings::iconForUrl()
+*/
+
+QIcon QWebFrame::icon() const
+{
+    return QWebSettings::iconForUrl(d->frame->loader()->url());
+}
+
+/*!
+  The name of this frame as defined by the parent frame.
+*/
+QString QWebFrame::frameName() const
+{
+    return d->frame->tree()->name();
+}
+
+/*!
+  The web page that contains this frame.
+
+  \sa pageChanged()
+*/
+QWebPage *QWebFrame::page() const
+{
+    return d->page;
+}
+
+/*!
+  Loads \a url into this frame.
+
+  \note The view remains the same until enough data has arrived to display the new \a url.
+
+  \sa setUrl(), setHtml(), setContent()
+*/
+void QWebFrame::load(const QUrl &url)
+{
+    // The load() overload ensures that the url is absolute.
+    load(QNetworkRequest(url));
+}
+
+/*!
+  Loads a network request, \a req, into this frame, using the method specified in \a
+  operation.
+
+  \a body is optional and is only used for POST operations.
+
+  \note The view remains the same until enough data has arrived to display the new content.
+
+  \sa setUrl()
+*/
+void QWebFrame::load(const QNetworkRequest &req,
+                     QNetworkAccessManager::Operation operation,
+                     const QByteArray &body)
+{
+    if (d->parentFrame())
+        d->page->d->insideOpenCall = true;
+
+    QUrl url = ensureAbsoluteUrl(req.url());
+
+    WebCore::ResourceRequest request(url);
+
+    switch (operation) {
+        case QNetworkAccessManager::HeadOperation:
+            request.setHTTPMethod("HEAD");
+            break;
+        case QNetworkAccessManager::GetOperation:
+            request.setHTTPMethod("GET");
+            break;
+        case QNetworkAccessManager::PutOperation:
+            request.setHTTPMethod("PUT");
+            break;
+        case QNetworkAccessManager::PostOperation:
+            request.setHTTPMethod("POST");
+            break;
+#if QT_VERSION >= 0x040600
+        case QNetworkAccessManager::DeleteOperation:
+            request.setHTTPMethod("DELETE");
+            break;
+#endif
+        case QNetworkAccessManager::UnknownOperation:
+            // eh?
+            break;
+    }
+
+    QList<QByteArray> httpHeaders = req.rawHeaderList();
+    for (int i = 0; i < httpHeaders.size(); ++i) {
+        const QByteArray &headerName = httpHeaders.at(i);
+        request.addHTTPHeaderField(QString::fromLatin1(headerName), QString::fromLatin1(req.rawHeader(headerName)));
+    }
+
+    if (!body.isEmpty())
+        request.setHTTPBody(WebCore::FormData::create(body.constData(), body.size()));
+
+    d->frame->loader()->load(request, false);
+
+    if (d->parentFrame())
+        d->page->d->insideOpenCall = false;
+}
+
+/*!
+  Sets the content of this frame to \a html. \a baseUrl is optional and used to resolve relative
+  URLs in the document, such as referenced images or stylesheets.
+
+  The \a html is loaded immediately; external objects are loaded asynchronously.
+
+  If a script in the \a html runs longer than the default script timeout (currently 10 seconds),
+  for example due to being blocked by a modal JavaScript alert dialog, this method will return
+  as soon as possible after the timeout and any subsequent \a html will be loaded asynchronously.
+
+  When using this method WebKit assumes that external resources such as JavaScript programs or style
+  sheets are encoded in UTF-8 unless otherwise specified. For example, the encoding of an external
+  script can be specified through the charset attribute of the HTML script tag. It is also possible
+  for the encoding to be specified by web server.
+
+  This is a convenience function equivalent to setContent(html, "text/html", baseUrl).
+
+  \note This method will not affect session or global history for the frame.
+
+  \warning This function works only for HTML, for other mime types (i.e. XHTML, SVG)
+  setContent() should be used instead.
+
+  \sa toHtml(), setContent(), load()
+*/
+void QWebFrame::setHtml(const QString &html, const QUrl &baseUrl)
+{
+    KURL kurl(baseUrl);
+    WebCore::ResourceRequest request(kurl);
+    const QByteArray utf8 = html.toUtf8();
+    WTF::RefPtr<WebCore::SharedBuffer> data = WebCore::SharedBuffer::create(utf8.constData(), utf8.length());
+    WebCore::SubstituteData substituteData(data, WebCore::String("text/html"), WebCore::String("utf-8"), KURL());
+    d->frame->loader()->load(request, substituteData, false);
+}
+
+/*!
+  Sets the content of this frame to the specified content \a data. If the \a mimeType argument
+  is empty it is currently assumed that the content is HTML but in future versions we may introduce
+  auto-detection.
+
+  External objects referenced in the content are located relative to \a baseUrl.
+
+  The \a data is loaded immediately; external objects are loaded asynchronously.
+
+  \note This method will not affect session or global history for the frame.
+
+  \sa toHtml(), setHtml()
+*/
+void QWebFrame::setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl)
+{
+    KURL kurl(baseUrl);
+    WebCore::ResourceRequest request(kurl);
+    WTF::RefPtr<WebCore::SharedBuffer> buffer = WebCore::SharedBuffer::create(data.constData(), data.length());
+    QString actualMimeType = mimeType;
+    if (actualMimeType.isEmpty())
+        actualMimeType = QLatin1String("text/html");
+    WebCore::SubstituteData substituteData(buffer, WebCore::String(actualMimeType), WebCore::String(), KURL());
+    d->frame->loader()->load(request, substituteData, false);
+}
+
+/*!
+  Returns the parent frame of this frame, or 0 if the frame is the web pages
+  main frame.
+
+  This is equivalent to qobject_cast<QWebFrame*>(frame->parent()).
+
+  \sa childFrames()
+*/
+QWebFrame *QWebFrame::parentFrame() const
+{
+    return d->parentFrame();
+}
+
+/*!
+  Returns a list of all frames that are direct children of this frame.
+
+  \sa parentFrame()
+*/
+QList<QWebFrame*> QWebFrame::childFrames() const
+{
+    QList<QWebFrame*> rc;
+    if (d->frame) {
+        FrameTree *tree = d->frame->tree();
+        for (Frame *child = tree->firstChild(); child; child = child->tree()->nextSibling()) {
+            FrameLoader *loader = child->loader();
+            FrameLoaderClientQt *client = static_cast<FrameLoaderClientQt*>(loader->client());
+            if (client)
+                rc.append(client->webFrame());
+        }
+
+    }
+    return rc;
+}
+
+/*!
+    Returns the scrollbar policy for the scrollbar defined by \a orientation.
+*/
+Qt::ScrollBarPolicy QWebFrame::scrollBarPolicy(Qt::Orientation orientation) const
+{
+    if (orientation == Qt::Horizontal)
+        return d->horizontalScrollBarPolicy;
+    return d->verticalScrollBarPolicy;
+}
+
+/*!
+    Sets the scrollbar policy for the scrollbar defined by \a orientation to \a policy.
+*/
+void QWebFrame::setScrollBarPolicy(Qt::Orientation orientation, Qt::ScrollBarPolicy policy)
+{
+    Q_ASSERT((int)ScrollbarAuto == (int)Qt::ScrollBarAsNeeded);
+    Q_ASSERT((int)ScrollbarAlwaysOff == (int)Qt::ScrollBarAlwaysOff);
+    Q_ASSERT((int)ScrollbarAlwaysOn == (int)Qt::ScrollBarAlwaysOn);
+
+    if (orientation == Qt::Horizontal) {
+        d->horizontalScrollBarPolicy = policy;
+        if (d->frame->view()) {
+            d->frame->view()->setHorizontalScrollbarMode((ScrollbarMode)policy, policy != Qt::ScrollBarAsNeeded /* lock */);
+            d->frame->view()->updateCanHaveScrollbars();
+        }
+    } else {
+        d->verticalScrollBarPolicy = policy;
+        if (d->frame->view()) {
+            d->frame->view()->setVerticalScrollbarMode((ScrollbarMode)policy, policy != Qt::ScrollBarAsNeeded /* lock */);
+            d->frame->view()->updateCanHaveScrollbars();
+        }
+    }
+}
+
+/*!
+  Sets the current \a value for the scrollbar with orientation \a orientation.
+
+  The scrollbar forces the \a value to be within the legal range: minimum <= value <= maximum.
+
+  Changing the value also updates the thumb position.
+
+  \sa scrollBarMinimum(), scrollBarMaximum()
+*/
+void QWebFrame::setScrollBarValue(Qt::Orientation orientation, int value)
+{
+    Scrollbar *sb;
+    sb = (orientation == Qt::Horizontal) ? d->horizontalScrollBar() : d->verticalScrollBar();
+    if (sb) {
+        if (value < 0)
+            value = 0;
+        else if (value > scrollBarMaximum(orientation))
+            value = scrollBarMaximum(orientation);
+        sb->setValue(value);
+    }
+}
+
+/*!
+  Returns the current value for the scrollbar with orientation \a orientation, or 0
+  if no scrollbar is found for \a orientation.
+
+  \sa scrollBarMinimum(), scrollBarMaximum()
+*/
+int QWebFrame::scrollBarValue(Qt::Orientation orientation) const
+{
+    Scrollbar *sb;
+    sb = (orientation == Qt::Horizontal) ? d->horizontalScrollBar() : d->verticalScrollBar();
+    if (sb)
+        return sb->value();
+    return 0;
+}
+
+/*!
+  Returns the maximum value for the scrollbar with orientation \a orientation, or 0
+  if no scrollbar is found for \a orientation.
+
+  \sa scrollBarMinimum()
+*/
+int QWebFrame::scrollBarMaximum(Qt::Orientation orientation) const
+{
+    Scrollbar *sb;
+    sb = (orientation == Qt::Horizontal) ? d->horizontalScrollBar() : d->verticalScrollBar();
+    if (sb)
+        return sb->maximum();
+    return 0;
+}
+
+/*!
+  Returns the minimum value for the scrollbar with orientation \a orientation.
+
+  The minimum value is always 0.
+
+  \sa scrollBarMaximum()
+*/
+int QWebFrame::scrollBarMinimum(Qt::Orientation orientation) const
+{
+    Q_UNUSED(orientation)
+    return 0;
+}
+
+/*!
+  \since 4.6
+  Returns the geometry for the scrollbar with orientation \a orientation.
+
+  If the scrollbar does not exist an empty rect is returned.
+*/
+QRect QWebFrame::scrollBarGeometry(Qt::Orientation orientation) const
+{
+    Scrollbar *sb;
+    sb = (orientation == Qt::Horizontal) ? d->horizontalScrollBar() : d->verticalScrollBar();
+    if (sb)
+        return sb->frameRect();
+    return QRect();
+}
+
+/*!
+  \since 4.5
+  Scrolls the frame \a dx pixels to the right and \a dy pixels downward. Both
+  \a dx and \a dy may be negative.
+
+  \sa QWebFrame::scrollPosition
+*/
+
+void QWebFrame::scroll(int dx, int dy)
+{
+    if (!d->frame->view())
+        return;
+
+    d->frame->view()->scrollBy(IntSize(dx, dy));
+}
+
+/*!
+  \property QWebFrame::scrollPosition
+  \since 4.5
+  \brief the position the frame is currently scrolled to.
+*/
+
+QPoint QWebFrame::scrollPosition() const
+{
+    if (!d->frame->view())
+        return QPoint(0, 0);
+
+    IntSize ofs = d->frame->view()->scrollOffset();
+    return QPoint(ofs.width(), ofs.height());
+}
+
+void QWebFrame::setScrollPosition(const QPoint &pos)
+{
+    QPoint current = scrollPosition();
+    int dx = pos.x() - current.x();
+    int dy = pos.y() - current.y();
+    scroll(dx, dy);
+}
+
+/*!
+  \since 4.7
+  Scrolls the frame to the given \a anchor name.
+*/
+void QWebFrame::scrollToAnchor(const QString& anchor)
+{
+    FrameView *view = d->frame->view();
+    if (view)
+        view->scrollToAnchor(anchor);
+}
+
+/*!
+  \since 4.6
+  Render the \a layer of the frame using \a painter clipping to \a clip.
+
+  \sa print()
+*/
+
+void QWebFrame::render(QPainter* painter, RenderLayer layer, const QRegion& clip)
+{
+    GraphicsContext context(painter);
+    if (context.paintingDisabled() && !context.updatingControlTints())
+        return;
+
+    if (!clip.isEmpty())
+        d->renderRelativeCoords(&context, layer, clip);
+    else if (d->frame->view())
+        d->renderRelativeCoords(&context, layer, QRegion(d->frame->view()->frameRect()));
+}
+
+/*!
+  Render the frame into \a painter clipping to \a clip.
+*/
+void QWebFrame::render(QPainter* painter, const QRegion& clip)
+{
+    GraphicsContext context(painter);
+    if (context.paintingDisabled() && !context.updatingControlTints())
+        return;
+
+    d->renderRelativeCoords(&context, AllLayers, clip);
+}
+
+/*!
+  Render the frame into \a painter.
+*/
+void QWebFrame::render(QPainter* painter)
+{
+    if (!d->frame->view())
+        return;
+
+    GraphicsContext context(painter);
+    if (context.paintingDisabled() && !context.updatingControlTints())
+        return;
+
+    d->renderRelativeCoords(&context, AllLayers, QRegion(d->frame->view()->frameRect()));
+}
+
+/*!
+    \property QWebFrame::textSizeMultiplier
+    \brief the scaling factor for all text in the frame
+    \obsolete
+
+    Use setZoomFactor instead, in combination with the ZoomTextOnly attribute in
+    QWebSettings.
+
+    \note Setting this property also enables the ZoomTextOnly attribute in
+    QWebSettings.
+*/
+
+/*!
+    Sets the value of the multiplier used to scale the text in a Web frame to
+    the \a factor specified.
+*/
+void QWebFrame::setTextSizeMultiplier(qreal factor)
+{
+    FrameView* view = d->frame->view();
+    if (!view)
+        return;
+
+    view->setZoomFactor(factor, ZoomTextOnly);
+}
+
+/*!
+    Returns the value of the multiplier used to scale the text in a Web frame.
+*/
+qreal QWebFrame::textSizeMultiplier() const
+{
+    FrameView* view = d->frame->view();
+    if (!view)
+        return 1;
+
+    return view->zoomFactor();
+}
+
+/*!
+    \property QWebFrame::zoomFactor
+    \since 4.5
+    \brief the zoom factor for the frame
+*/
+
+void QWebFrame::setZoomFactor(qreal factor)
+{
+    Page* page = d->frame->page();
+    if (!page)
+        return;
+
+    FrameView* view = d->frame->view();
+    if (!view)
+        return;
+
+    view->setZoomFactor(factor, page->settings()->zoomMode());
+}
+
+qreal QWebFrame::zoomFactor() const
+{
+    FrameView* view = d->frame->view();
+    if (!view)
+        return 1;
+
+    return view->zoomFactor();
+}
+
+/*!
+    \property QWebFrame::focus
+    \since 4.6
+
+    Returns true if this frame has keyboard input focus; otherwise, returns false.
+*/
+bool QWebFrame::hasFocus() const
+{
+    WebCore::Frame* ff = d->frame->page()->focusController()->focusedFrame();
+    return ff && QWebFramePrivate::kit(ff) == this;
+}
+
+/*!
+    \since 4.6
+
+    Gives keyboard input focus to this frame.
+*/
+void QWebFrame::setFocus()
+{
+    QWebFramePrivate::core(this)->page()->focusController()->setFocusedFrame(QWebFramePrivate::core(this));
+}
+
+/*!
+    Returns the position of the frame relative to it's parent frame.
+*/
+QPoint QWebFrame::pos() const
+{
+    if (!d->frame->view())
+        return QPoint();
+
+    return d->frame->view()->frameRect().topLeft();
+}
+
+/*!
+    Return the geometry of the frame relative to it's parent frame.
+*/
+QRect QWebFrame::geometry() const
+{
+    if (!d->frame->view())
+        return QRect();
+    return d->frame->view()->frameRect();
+}
+
+/*!
+    \property QWebFrame::contentsSize
+    \brief the size of the contents in this frame
+
+    \sa contentsSizeChanged()
+*/
+QSize QWebFrame::contentsSize() const
+{
+    FrameView *view = d->frame->view();
+    if (!view)
+        return QSize();
+    return QSize(view->contentsWidth(), view->contentsHeight());
+}
+
+/*!
+    \since 4.6
+
+    Returns the document element of this frame.
+
+    The document element provides access to the entire structured
+    content of the frame.
+*/
+QWebElement QWebFrame::documentElement() const
+{
+    WebCore::Document *doc = d->frame->document();
+    if (!doc)
+        return QWebElement();
+    return QWebElement(doc->documentElement());
+}
+
+/*!
+    \since 4.6
+    Returns a new list of elements matching the given CSS selector \a selectorQuery.
+    If there are no matching elements, an empty list is returned.
+
+    \l{http://www.w3.org/TR/REC-CSS2/selector.html#q1}{Standard CSS2 selector} syntax is
+    used for the query.
+
+    \sa QWebElement::findAll()
+*/
+QWebElementCollection QWebFrame::findAllElements(const QString &selectorQuery) const
+{
+    return documentElement().findAll(selectorQuery);
+}
+
+/*!
+    \since 4.6
+    Returns the first element in the frame's document that matches the
+    given CSS selector \a selectorQuery. If there is no matching element, a
+    null element is returned.
+
+    \l{http://www.w3.org/TR/REC-CSS2/selector.html#q1}{Standard CSS2 selector} syntax is
+    used for the query.
+
+    \sa QWebElement::findFirst()
+*/
+QWebElement QWebFrame::findFirstElement(const QString &selectorQuery) const
+{
+    return documentElement().findFirst(selectorQuery);
+}
+
+/*!
+    Performs a hit test on the frame contents at the given position \a pos and returns the hit test result.
+*/
+QWebHitTestResult QWebFrame::hitTestContent(const QPoint &pos) const
+{
+    if (!d->frame->view() || !d->frame->contentRenderer())
+        return QWebHitTestResult();
+
+    HitTestResult result = d->frame->eventHandler()->hitTestResultAtPoint(d->frame->view()->windowToContents(pos), /*allowShadowContent*/ false, /*ignoreClipping*/ true);
+
+    if (result.scrollbar())
+        return QWebHitTestResult();
+
+    return QWebHitTestResult(new QWebHitTestResultPrivate(result));
+}
+
+/*! \reimp
+*/
+bool QWebFrame::event(QEvent *e)
+{
+    return QObject::event(e);
+}
+
+#ifndef QT_NO_PRINTER
+/*!
+    Prints the frame to the given \a printer.
+
+    \sa render()
+*/
+void QWebFrame::print(QPrinter *printer) const
+{
+    QPainter painter;
+    if (!painter.begin(printer))
+        return;
+
+    const qreal zoomFactorX = (qreal)printer->logicalDpiX() / qt_defaultDpi();
+    const qreal zoomFactorY = (qreal)printer->logicalDpiY() / qt_defaultDpi();
+
+    PrintContext printContext(d->frame);
+    float pageHeight = 0;
+
+    QRect qprinterRect = printer->pageRect();
+
+    IntRect pageRect(0, 0,
+                     int(qprinterRect.width() / zoomFactorX),
+                     int(qprinterRect.height() / zoomFactorY));
+
+    printContext.begin(pageRect.width());
+
+    printContext.computePageRects(pageRect, /* headerHeight */ 0, /* footerHeight */ 0, /* userScaleFactor */ 1.0, pageHeight);
+
+    int docCopies;
+    int pageCopies;
+    if (printer->collateCopies()) {
+        docCopies = 1;
+        pageCopies = printer->numCopies();
+    } else {
+        docCopies = printer->numCopies();
+        pageCopies = 1;
+    }
+
+    int fromPage = printer->fromPage();
+    int toPage = printer->toPage();
+    bool ascending = true;
+
+    if (fromPage == 0 && toPage == 0) {
+        fromPage = 1;
+        toPage = printContext.pageCount();
+    }
+    // paranoia check
+    fromPage = qMax(1, fromPage);
+    toPage = qMin(printContext.pageCount(), toPage);
+    if (toPage < fromPage) {
+        // if the user entered a page range outside the actual number
+        // of printable pages, just return
+        return;
+    }
+
+    if (printer->pageOrder() == QPrinter::LastPageFirst) {
+        int tmp = fromPage;
+        fromPage = toPage;
+        toPage = tmp;
+        ascending = false;
+    }
+
+    painter.scale(zoomFactorX, zoomFactorY);
+    GraphicsContext ctx(&painter);
+
+    for (int i = 0; i < docCopies; ++i) {
+        int page = fromPage;
+        while (true) {
+            for (int j = 0; j < pageCopies; ++j) {
+                if (printer->printerState() == QPrinter::Aborted
+                    || printer->printerState() == QPrinter::Error) {
+                    printContext.end();
+                    return;
+                }
+                printContext.spoolPage(ctx, page - 1, pageRect.width());
+                if (j < pageCopies - 1)
+                    printer->newPage();
+            }
+
+            if (page == toPage)
+                break;
+
+            if (ascending)
+                ++page;
+            else
+                --page;
+
+            printer->newPage();
+        }
+
+        if ( i < docCopies - 1)
+            printer->newPage();
+    }
+
+    printContext.end();
+}
+#endif // QT_NO_PRINTER
+
+/*!
+    Evaluates the JavaScript defined by \a scriptSource using this frame as context
+    and returns the result of the last executed statement.
+
+    \sa addToJavaScriptWindowObject(), javaScriptWindowObjectCleared()
+*/
+QVariant QWebFrame::evaluateJavaScript(const QString& scriptSource)
+{
+    ScriptController *proxy = d->frame->script();
+    QVariant rc;
+    if (proxy) {
+        JSC::JSValue v = d->frame->script()->executeScript(ScriptSourceCode(scriptSource)).jsValue();
+        int distance = 0;
+        rc = JSC::Bindings::convertValueToQVariant(proxy->globalObject(mainThreadNormalWorld())->globalExec(), v, QMetaType::Void, &distance);
+    }
+    return rc;
+}
+
+/*!
+    \since 4.5
+
+    Returns the frame's security origin.
+*/
+QWebSecurityOrigin QWebFrame::securityOrigin() const
+{
+    QWebFrame* that = const_cast<QWebFrame*>(this);
+    QWebSecurityOriginPrivate* priv = new QWebSecurityOriginPrivate(QWebFramePrivate::core(that)->document()->securityOrigin());
+    return QWebSecurityOrigin(priv);
+}
+
+WebCore::Frame* QWebFramePrivate::core(QWebFrame* webFrame)
+{
+    return webFrame->d->frame;
+}
+
+QWebFrame* QWebFramePrivate::kit(WebCore::Frame* coreFrame)
+{
+    return static_cast<FrameLoaderClientQt*>(coreFrame->loader()->client())->webFrame();
+}
+
+
+/*!
+    \fn void QWebFrame::javaScriptWindowObjectCleared()
+
+    This signal is emitted whenever the global window object of the JavaScript
+    environment is cleared, e.g., before starting a new load.
+
+    If you intend to add QObjects to a QWebFrame using
+    addToJavaScriptWindowObject(), you should add them in a slot connected
+    to this signal. This ensures that your objects remain accessible when
+    loading new URLs.
+*/
+
+/*!
+    \fn void QWebFrame::provisionalLoad()
+    \internal
+*/
+
+/*!
+    \fn void QWebFrame::titleChanged(const QString &title)
+
+    This signal is emitted whenever the title of the frame changes.
+    The \a title string specifies the new title.
+
+    \sa title()
+*/
+
+/*!
+    \fn void QWebFrame::urlChanged(const QUrl &url)
+
+    This signal is emitted with the URL of the frame when the frame's title is
+    received. The new URL is specified by \a url.
+
+    \sa url()
+*/
+
+/*!
+    \fn void QWebFrame::initialLayoutCompleted()
+
+    This signal is emitted when the frame is laid out the first time.
+    This is the first time you will see contents displayed on the frame.
+
+    \note A frame can be laid out multiple times.
+*/
+
+/*!
+  \fn void QWebFrame::iconChanged()
+
+  This signal is emitted when the icon ("favicon") associated with the frame
+  has been loaded.
+
+  \sa icon()
+*/
+
+/*!
+  \fn void QWebFrame::contentsSizeChanged(const QSize &size)
+  \since 4.6
+
+  This signal is emitted when the frame's contents size changes
+  to \a size.
+
+  \sa contentsSize()
+*/
+
+/*!
+    \fn void QWebFrame::loadStarted()
+    \since 4.6
+
+    This signal is emitted when a new load of this frame is started.
+
+    \sa loadFinished()
+*/
+
+/*!
+    \fn void QWebFrame::loadFinished(bool ok)
+    \since 4.6
+
+    This signal is emitted when a load of this frame is finished.
+    \a ok will indicate whether the load was successful or any error occurred.
+
+    \sa loadStarted()
+*/
+
+/*!
+    \fn void QWebFrame::pageChanged()
+    \since 4.7
+
+    This signal is emitted when this frame has been moved to a different QWebPage.
+
+    \sa page()
+*/
+
+/*!
+    \class QWebHitTestResult
+    \since 4.4
+    \brief The QWebHitTestResult class provides information about the web
+    page content after a hit test.
+
+    \inmodule QtWebKit
+
+    QWebHitTestResult is returned by QWebFrame::hitTestContent() to provide
+    information about the content of the web page at the specified position.
+*/
+
+/*!
+    \internal
+*/
+QWebHitTestResult::QWebHitTestResult(QWebHitTestResultPrivate *priv)
+    : d(priv)
+{
+}
+
+QWebHitTestResultPrivate::QWebHitTestResultPrivate(const WebCore::HitTestResult &hitTest)
+    : isContentEditable(false)
+    , isContentSelected(false)
+    , isScrollBar(false)
+{
+    if (!hitTest.innerNode())
+        return;
+    pos = hitTest.point();
+    WebCore::TextDirection dir;
+    title = hitTest.title(dir);
+    linkText = hitTest.textContent();
+    linkUrl = hitTest.absoluteLinkURL();
+    linkTitle = hitTest.titleDisplayString();
+    alternateText = hitTest.altDisplayString();
+    imageUrl = hitTest.absoluteImageURL();
+    innerNode = hitTest.innerNode();
+    innerNonSharedNode = hitTest.innerNonSharedNode();
+    boundingRect = innerNonSharedNode ? innerNonSharedNode->renderer()->absoluteBoundingBoxRect(true) : IntRect();
+    WebCore::Image *img = hitTest.image();
+    if (img) {
+        QPixmap *pix = img->nativeImageForCurrentFrame();
+        if (pix)
+            pixmap = *pix;
+    }
+    WebCore::Frame *wframe = hitTest.targetFrame();
+    if (wframe)
+        linkTargetFrame = QWebFramePrivate::kit(wframe);
+    linkElement = QWebElement(hitTest.URLElement());
+
+    isContentEditable = hitTest.isContentEditable();
+    isContentSelected = hitTest.isSelected();
+    isScrollBar = hitTest.scrollbar();
+
+    if (innerNonSharedNode && innerNonSharedNode->document()
+        && innerNonSharedNode->document()->frame())
+        frame = QWebFramePrivate::kit(innerNonSharedNode->document()->frame());
+
+    enclosingBlock = QWebElement(WebCore::enclosingBlock(innerNode.get()));
+}
+
+/*!
+    Constructs a null hit test result.
+*/
+QWebHitTestResult::QWebHitTestResult()
+    : d(0)
+{
+}
+
+/*!
+    Constructs a hit test result from \a other.
+*/
+QWebHitTestResult::QWebHitTestResult(const QWebHitTestResult &other)
+    : d(0)
+{
+    if (other.d)
+        d = new QWebHitTestResultPrivate(*other.d);
+}
+
+/*!
+    Assigns the \a other hit test result to this.
+*/
+QWebHitTestResult &QWebHitTestResult::operator=(const QWebHitTestResult &other)
+{
+    if (this != &other) {
+        if (other.d) {
+            if (!d)
+                d = new QWebHitTestResultPrivate;
+            *d = *other.d;
+        } else {
+            delete d;
+            d = 0;
+        }
+    }
+    return *this;
+}
+
+/*!
+    Destructor.
+*/
+QWebHitTestResult::~QWebHitTestResult()
+{
+    delete d;
+}
+
+/*!
+    Returns true if the hit test result is null; otherwise returns false.
+*/
+bool QWebHitTestResult::isNull() const
+{
+    return !d;
+}
+
+/*!
+    Returns the position where the hit test occured.
+*/
+QPoint QWebHitTestResult::pos() const
+{
+    if (!d)
+        return QPoint();
+    return d->pos;
+}
+
+/*!
+    \since 4.5
+    Returns the bounding rect of the element.
+*/
+QRect QWebHitTestResult::boundingRect() const
+{
+    if (!d)
+        return QRect();
+    return d->boundingRect;
+}
+
+/*!
+    \since 4.6
+    Returns the block element that encloses the element hit.
+
+    A block element is an element that is rendered using the
+    CSS "block" style. This includes for example text
+    paragraphs.
+*/
+QWebElement QWebHitTestResult::enclosingBlockElement() const
+{
+    if (!d)
+        return QWebElement();
+    return d->enclosingBlock;
+}
+
+/*!
+    Returns the title of the nearest enclosing HTML element.
+*/
+QString QWebHitTestResult::title() const
+{
+    if (!d)
+        return QString();
+    return d->title;
+}
+
+/*!
+    Returns the text of the link.
+*/
+QString QWebHitTestResult::linkText() const
+{
+    if (!d)
+        return QString();
+    return d->linkText;
+}
+
+/*!
+    Returns the url to which the link points to.
+*/
+QUrl QWebHitTestResult::linkUrl() const
+{
+    if (!d)
+        return QUrl();
+    return d->linkUrl;
+}
+
+/*!
+    Returns the title of the link.
+*/
+QUrl QWebHitTestResult::linkTitle() const
+{
+    if (!d)
+        return QUrl();
+    return d->linkTitle;
+}
+
+/*!
+  \since 4.6
+  Returns the element that represents the link.
+
+  \sa linkTargetFrame()
+*/
+QWebElement QWebHitTestResult::linkElement() const
+{
+    if (!d)
+        return QWebElement();
+    return d->linkElement;
+}
+
+/*!
+    Returns the frame that will load the link if it is activated.
+
+    \sa linkElement()
+*/
+QWebFrame *QWebHitTestResult::linkTargetFrame() const
+{
+    if (!d)
+        return 0;
+    return d->linkTargetFrame;
+}
+
+/*!
+    Returns the alternate text of the element. This corresponds to the HTML alt attribute.
+*/
+QString QWebHitTestResult::alternateText() const
+{
+    if (!d)
+        return QString();
+    return d->alternateText;
+}
+
+/*!
+    Returns the url of the image.
+*/
+QUrl QWebHitTestResult::imageUrl() const
+{
+    if (!d)
+        return QUrl();
+    return d->imageUrl;
+}
+
+/*!
+    Returns a QPixmap containing the image. A null pixmap is returned if the
+    element being tested is not an image.
+*/
+QPixmap QWebHitTestResult::pixmap() const
+{
+    if (!d)
+        return QPixmap();
+    return d->pixmap;
+}
+
+/*!
+    Returns true if the content is editable by the user; otherwise returns false.
+*/
+bool QWebHitTestResult::isContentEditable() const
+{
+    if (!d)
+        return false;
+    return d->isContentEditable;
+}
+
+/*!
+    Returns true if the content tested is part of the selection; otherwise returns false.
+*/
+bool QWebHitTestResult::isContentSelected() const
+{
+    if (!d)
+        return false;
+    return d->isContentSelected;
+}
+
+/*!
+    \since 4.6
+    Returns the underlying DOM element as QWebElement.
+*/
+QWebElement QWebHitTestResult::element() const
+{
+    if (!d || !d->innerNonSharedNode || !d->innerNonSharedNode->isElementNode())
+        return QWebElement();
+
+    return QWebElement(static_cast<WebCore::Element*>(d->innerNonSharedNode.get()));
+}
+
+/*!
+    Returns the frame the hit test was executed in.
+*/
+QWebFrame *QWebHitTestResult::frame() const
+{
+    if (!d)
+        return 0;
+    return d->frame;
+}