diff options
Diffstat (limited to 'WebKit/qt/Api/qwebframe.cpp')
-rw-r--r-- | WebKit/qt/Api/qwebframe.cpp | 625 |
1 files changed, 625 insertions, 0 deletions
diff --git a/WebKit/qt/Api/qwebframe.cpp b/WebKit/qt/Api/qwebframe.cpp new file mode 100644 index 0000000..155731c --- /dev/null +++ b/WebKit/qt/Api/qwebframe.cpp @@ -0,0 +1,625 @@ +/* + Copyright (C) 2007 Trolltech ASA + 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. + + This class provides all functionality needed for loading images, style sheets and html + pages from the web. It has a memory cache for these objects. +*/ +#include "config.h" +#include "qwebframe.h" +#include "qwebpage.h" +#include "qwebpage_p.h" +#include "qwebframe_p.h" + +#include "DocumentLoader.h" +#include "FocusController.h" +#include "FrameLoaderClientQt.h" +#include "Frame.h" +#include "FrameTree.h" +#include "FrameView.h" +#include "IconDatabase.h" +#include "Page.h" +#include "ResourceRequest.h" +#include "SelectionController.h" +#include "PlatformScrollBar.h" +#include "SubstituteData.h" + +#include "markup.h" +#include "RenderTreeAsText.h" +#include "Element.h" +#include "Document.h" +#include "DragData.h" +#include "RenderObject.h" +#include "GraphicsContext.h" +#include "PlatformScrollBar.h" +#include "PlatformMouseEvent.h" +#include "PlatformWheelEvent.h" +#include "GraphicsContext.h" +#include "HitTestResult.h" + +#include "bindings/runtime.h" +#include "bindings/runtime_root.h" +#include "kjs_proxy.h" +#include "kjs_window.h" +#include "kjs_binding.h" +#include "ExecState.h" +#include "object.h" + +#include "wtf/HashMap.h" + +#include <qdebug.h> +#include <qevent.h> +#include <qpainter.h> +#if QT_VERSION >= 0x040400 +#include <qnetworkrequest.h> +#else +#include "qwebnetworkinterface.h" +#endif +#include <qregion.h> + +using namespace WebCore; + +void QWebFramePrivate::init(QWebFrame *qframe, WebCore::Page *webcorePage, QWebFrameData *frameData) +{ + q = qframe; + + frameLoaderClient = new FrameLoaderClientQt(); + frame = new Frame(webcorePage, frameData->ownerElement, frameLoaderClient); + frameLoaderClient->setFrame(qframe, frame.get()); + + frameView = new FrameView(frame.get()); + frameView->deref(); + frameView->setQWebFrame(qframe); + if (!frameData->allowsScrolling) + frameView->setScrollbarsMode(ScrollbarAlwaysOff); + if (frameData->marginWidth != -1) + frameView->setMarginWidth(frameData->marginWidth); + if (frameData->marginHeight != -1) + frameView->setMarginHeight(frameData->marginHeight); + + frame->setView(frameView.get()); + frame->init(); + + QObject::connect(q, SIGNAL(hoveringOverLink(const QString&, const QString&, const QString&)), + page, SIGNAL(hoveringOverLink(const QString&, const QString&, const QString&))); +} + +WebCore::PlatformScrollbar *QWebFramePrivate::horizontalScrollBar() const +{ + Q_ASSERT(frameView); + return frameView->horizontalScrollBar(); +} + +WebCore::PlatformScrollbar *QWebFramePrivate::verticalScrollBar() const +{ + Q_ASSERT(frameView); + return frameView->verticalScrollBar(); +} + +/*! + \class QWebFrame + \since 4.4 + \brief The QWebFrame class represents a frame in a web page. + + QWebFrame represents a frame inside a web page. Each QWebPage + object contains at least one frame, the mainFrame(). Additional + frames will be created for HTML <frame> or <iframe> + elements. + + QWebFrame objects are created and controlled by the web page. You + can connect to the web pages frameCreated() signal to find out + about creation of new frames. + + \sa QWebPage +*/ + +QWebFrame::QWebFrame(QWebPage *parent, QWebFrameData *frameData) + : QObject(parent) + , d(new QWebFramePrivate) +{ + d->page = parent; + d->init(this, parent->d->page, frameData); + + if (!frameData->url.isEmpty()) { + ResourceRequest request(frameData->url, frameData->referrer); + d->frame->loader()->load(request, frameData->name); + } +} + +QWebFrame::QWebFrame(QWebFrame *parent, QWebFrameData *frameData) + : QObject(parent) + , d(new QWebFramePrivate) +{ + d->page = parent->d->page; + d->init(this, parent->d->page->d->page, frameData); +} + +QWebFrame::~QWebFrame() +{ + Q_ASSERT(d->frame == 0); + Q_ASSERT(d->frameView == 0); + delete d; +} + +/*! + Make \a object available under \a name from within the frames + JavaScript context. The \a object will be inserted as a child of the + frames window object. + + Qt properties will be exposed as JavaScript properties and slots as + JavaScript methods. +*/ +void QWebFrame::addToJSWindowObject(const QString &name, QObject *object) +{ + KJS::JSLock lock; + KJS::Window *window = KJS::Window::retrieveWindow(d->frame.get()); + KJS::Bindings::RootObject *root = d->frame->bindingRootObject(); + if (!window) { + qDebug() << "Warning: couldn't get window object"; + return; + } + + KJS::JSObject *runtimeObject = + KJS::Bindings::Instance::createRuntimeObject(KJS::Bindings::Instance::QtLanguage, + object, root); + + window->put(window->globalExec(), KJS::Identifier((const KJS::UChar *) name.constData(), name.length()), runtimeObject); +} + +/*! + returns the markup (HTML) contained in the current frame. +*/ +QString QWebFrame::markup() const +{ + if (!d->frame->document()) + return QString(); + return createMarkup(d->frame->document()); +} + +/*! + returns the content of this frame as plain text. +*/ +QString QWebFrame::innerText() const +{ + if (d->frameView->layoutPending()) + d->frameView->layout(); + + Element *documentElement = d->frame->document()->documentElement(); + return documentElement->innerText(); +} + +/*! + returns a dump of the rendering tree. Mainly useful for debugging html. +*/ +QString QWebFrame::renderTreeDump() const +{ + if (d->frameView->layoutPending()) + d->frameView->layout(); + + return externalRepresentation(d->frame->renderer()); +} + +/*! + The title of the frame as defined by the HTML <title> + element. +*/ +QString QWebFrame::title() const +{ + if (d->frame->document()) + return d->frame->loader()->documentLoader()->title(); + else return QString(); +} + +/*! + The url of this frame. +*/ +QUrl QWebFrame::url() const +{ + return d->frame->loader()->url(); +} + +/*! + The icon associated with this frame. +*/ +QPixmap QWebFrame::icon() const +{ + String url = d->frame->loader()->url().string(); + + Image* image = 0; + if (!url.isEmpty()) { + image = iconDatabase()->iconForPageURL(url, IntSize(16, 16)); + } + + if (!image || image->isNull()) { + image = iconDatabase()->defaultIcon(IntSize(16, 16)); + } + + if (!image) { + return QPixmap(); + } + + QPixmap *icon = image->getPixmap(); + if (!icon) { + return QPixmap(); + } + return *icon; +} + +/*! + The name of this frame as defined by the parent frame. +*/ +QString QWebFrame::name() const +{ + return d->frame->tree()->name(); +} + +/*! + The web page that contains this frame. +*/ +QWebPage *QWebFrame::page() const +{ + return d->page; +} + +/*! + Load \a url into this frame. +*/ +void QWebFrame::load(const QUrl &url) +{ +#if QT_VERSION < 0x040400 + load(QWebNetworkRequest(url)); +#else + load(QNetworkRequest(url)); +#endif +} + +#if QT_VERSION < 0x040400 +/*! + Load network request \a req into this frame. +*/ +void QWebFrame::load(const QWebNetworkRequest &req) +{ + if (d->parentFrame()) + d->page->d->insideOpenCall = true; + + QUrl url = req.url(); + QHttpRequestHeader httpHeader = req.httpHeader(); + QByteArray postData = req.postData(); + + WebCore::ResourceRequest request(url); + + QString method = httpHeader.method(); + if (!method.isEmpty()) + request.setHTTPMethod(method); + + QList<QPair<QString, QString> > values = httpHeader.values(); + for (int i = 0; i < values.size(); ++i) { + const QPair<QString, QString> &val = values.at(i); + request.addHTTPHeaderField(val.first, val.second); + } + + if (!postData.isEmpty()) + request.setHTTPBody(WebCore::FormData::create(postData.constData(), postData.size())); + + d->frame->loader()->load(request); + + if (d->parentFrame()) + d->page->d->insideOpenCall = false; +} + +#else + +/*! + Load network request \a req into this frame. Use the method specified in \a + operation. \a body is optional and is only used for POST operations. +*/ +void QWebFrame::load(const QNetworkRequest &req, + QNetworkAccessManager::Operation operation, + const QByteArray &body) +{ + if (d->parentFrame()) + d->page->d->insideOpenCall = true; + + QUrl url = 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; + 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); + + if (d->parentFrame()) + d->page->d->insideOpenCall = false; +} +#endif + +/*! + Sets the content of this frame to \a html. \a baseUrl is optional and used to resolve relative + URLs in the document. +*/ +void QWebFrame::setHtml(const QString &html, const QUrl &baseUrl) +{ + KURL kurl(baseUrl); + WebCore::ResourceRequest request(kurl); + WTF::RefPtr<WebCore::SharedBuffer> data = new WebCore::SharedBuffer(reinterpret_cast<const uchar *>(html.unicode()), html.length() * 2); + WebCore::SubstituteData substituteData(data, WebCore::String("text/html"), WebCore::String("utf-16"), kurl); + d->frame->loader()->load(request, substituteData); +} + +/*! + \overload +*/ +void QWebFrame::setHtml(const QByteArray &html, const QUrl &baseUrl) +{ + setContent(html, QString(), baseUrl); +} + +/*! + Sets the content of this frame to \a data assuming \a mimeType. If + \a mimeType is not specified it defaults to 'text/html'. \a baseUrl + us optional and used to resolve relative URLs in the document. +*/ +void QWebFrame::setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl) +{ + KURL kurl(baseUrl); + WebCore::ResourceRequest request(kurl); + WTF::RefPtr<WebCore::SharedBuffer> buffer = new WebCore::SharedBuffer(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); +} + + +/*! + 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()). +*/ +QWebFrame *QWebFrame::parentFrame() const +{ + return d->parentFrame(); +} + +/*! + Returns a list of all frames that are direct children of this frame. +*/ +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; +} + +/*! + \property QWebFrame::verticalScrollBarPolicy + + This property defines the vertical scrollbar policy. + + \sa Qt::ScrollBarPolicy +*/ +Qt::ScrollBarPolicy QWebFrame::verticalScrollBarPolicy() const +{ + return (Qt::ScrollBarPolicy) d->frameView->vScrollbarMode(); +} + +void QWebFrame::setVerticalScrollBarPolicy(Qt::ScrollBarPolicy policy) +{ + Q_ASSERT((int)ScrollbarAuto == (int)Qt::ScrollBarAsNeeded); + Q_ASSERT((int)ScrollbarAlwaysOff == (int)Qt::ScrollBarAlwaysOff); + Q_ASSERT((int)ScrollbarAlwaysOn == (int)Qt::ScrollBarAlwaysOn); + d->frameView->setVScrollbarMode((ScrollbarMode)policy); +} + +/*! + \property QWebFrame::horizontalScrollBarPolicy + + This property defines the horizontal scrollbar policy. + + \sa Qt::ScrollBarPolicy +*/ +Qt::ScrollBarPolicy QWebFrame::horizontalScrollBarPolicy() const +{ + return (Qt::ScrollBarPolicy) d->frameView->hScrollbarMode(); +} + +void QWebFrame::setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy policy) +{ + d->frameView->setHScrollbarMode((ScrollbarMode)policy); +} + +/*! + Render the frame into \a painter clipping to \a clip. +*/ +void QWebFrame::render(QPainter *painter, const QRegion &clip) +{ + if (!d->frameView || !d->frame->renderer()) + return; + + layout(); + + GraphicsContext ctx(painter); + QVector<QRect> vector = clip.rects(); + for (int i = 0; i < vector.size(); ++i) + d->frameView->paint(&ctx, vector.at(i)); +} + +/*! + Ensure that the content of the frame and all subframes are correctly layouted. +*/ +void QWebFrame::layout() +{ + if (!d->frameView) + return; + + d->frameView->layoutIfNeededRecursive(); +} + +/*! + returns the position of the frame relative to it's parent frame. +*/ +QPoint QWebFrame::pos() const +{ + Q_ASSERT(d->frameView); + return d->pos(); +} + +/*! + return the geometry of the frame relative to it's parent frame. +*/ +QRect QWebFrame::geometry() const +{ + Q_ASSERT(d->frameView); + return d->frameView->frameGeometry(); +} + +/*! + Evaluate JavaScript defined by \a scriptSource using this frame as context. +*/ +QString QWebFrame::evaluateJavaScript(const QString& scriptSource) +{ + KJSProxy *proxy = d->frame->scriptProxy(); + QString rc; + if (proxy) { + KJS::JSValue *v = proxy->evaluate(String(), 0, scriptSource); + if (v) { + rc = String(v->toString(proxy->globalObject()->globalExec())); + } + } + return rc; +} + +WebCore::Frame* QWebFramePrivate::core(QWebFrame* webFrame) +{ + return webFrame->d->frame.get(); +} + +QWebFrame* QWebFramePrivate::kit(WebCore::Frame* coreFrame) +{ + return static_cast<FrameLoaderClientQt*>(coreFrame->loader()->client())->webFrame(); +} + + +/*! + \fn void QWebFrame::cleared() + + This signal is emitted whenever the content of the frame is cleared + (e.g. before starting a new load). +*/ + +/*! + \fn void QWebFrame::loadDone(bool ok) + + This signal is emitted when the frame is completely loaded. \a ok will indicate whether the load + was successful or any error occurred. +*/ + +/*! + \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 whenever the \a url of the frame changes. + + \sa url() +*/ + +/*! + \fn void QWebFrame::hoveringOverLink(const QString &link, const QString &title, const QString &textContent) + + This signal is emitted whenever the mouse cursor is hovering over a + link. It can be used to display information about the link in + e.g. the status bar. The signal arguments consist of the \a link destination, the \a title and the + link text as \a textContent . +*/ + + +/*! + \fn void QWebFrame::loadStarted() + + This signal is emitted when a new load of the frame is started. +*/ + +/*! + \fn void QWebFrame::loadFinished() + + This signal is emitted when a load of the frame is finished. +*/ + +/*! + \fn void QWebFrame::initialLayoutComplete() + + This signal is emitted when the first (initial) layout of the frame + has happened. This is the earliest time something can be shown on + the screen. +*/ + +/*! + \fn void QWebFrame::iconLoaded() + + This signal is emitted when the icon ("favicon") associated with the frame has been loaded. +*/ |