diff options
Diffstat (limited to 'WebKit/qt')
86 files changed, 10508 insertions, 4383 deletions
diff --git a/WebKit/qt/Api/headers.pri b/WebKit/qt/Api/headers.pri index 92a120d..1a42597 100644 --- a/WebKit/qt/Api/headers.pri +++ b/WebKit/qt/Api/headers.pri @@ -1,4 +1,5 @@ WEBKIT_API_HEADERS = $$PWD/qwebframe.h \ + $$PWD/qgraphicswebview.h \ $$PWD/qwebkitglobal.h \ $$PWD/qwebpage.h \ $$PWD/qwebview.h \ @@ -7,7 +8,7 @@ WEBKIT_API_HEADERS = $$PWD/qwebframe.h \ $$PWD/qwebdatabase.h \ $$PWD/qwebsecurityorigin.h \ $$PWD/qwebelement.h \ - $$PWD/qwebplugindatabase.h \ $$PWD/qwebpluginfactory.h \ $$PWD/qwebhistory.h \ + $$PWD/qwebinspector.h \ $$PWD/qwebkitversion.h diff --git a/WebKit/qt/Api/qcookiejar.cpp b/WebKit/qt/Api/qcookiejar.cpp deleted file mode 100644 index a02fe78..0000000 --- a/WebKit/qt/Api/qcookiejar.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - 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 "qcookiejar.h" -#include <QCoreApplication> -uint qHash(const QUrl&); -#include <QHash> -#include <QPointer> - -class QCookieJarPrivate { - public: - QCookieJarPrivate() - { - enabled = true; - } - bool enabled; - QHash<QUrl, QString> jar; -}; - - -uint qHash(const QUrl& url) -{ - return qHash(url.toString()); -} - - -QCookieJar::QCookieJar() -: QObject(), d(new QCookieJarPrivate) -{ -} - - -QCookieJar::~QCookieJar() -{ - delete d; -} - - -void QCookieJar::setCookies(const QUrl& url, const QUrl& policyUrl, const QString& value) -{ - Q_UNUSED(policyUrl) - d->jar.insert(url, value); -} - - -QString QCookieJar::cookies(const QUrl& url) -{ - return d->jar.value(url); -} - - -bool QCookieJar::isEnabled() const -{ - return d->enabled; -} - - -void QCookieJar::setEnabled(bool enabled) -{ - d->enabled = enabled; -} - - -static QPointer<QCookieJar> gJar; -static bool gRoutineAdded = false; - -static void gCleanupJar() -{ - delete gJar; -} - - -void QCookieJar::setCookieJar(QCookieJar* jar) -{ - if (!gRoutineAdded) { - qAddPostRoutine(gCleanupJar); - gRoutineAdded = true; - } - delete gJar; - gJar = jar; -} - - -QCookieJar* QCookieJar::cookieJar() -{ - if (!gJar) - setCookieJar(new QCookieJar); - - return gJar; -} diff --git a/WebKit/qt/Api/qgraphicswebview.cpp b/WebKit/qt/Api/qgraphicswebview.cpp new file mode 100644 index 0000000..b25b53b --- /dev/null +++ b/WebKit/qt/Api/qgraphicswebview.cpp @@ -0,0 +1,1007 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in> + + 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 "qgraphicswebview.h" + +#include "qwebframe.h" +#include "qwebpage.h" +#include "qwebpage_p.h" +#include "QWebPageClient.h" +#include <QtGui/QGraphicsScene> +#include <QtGui/QGraphicsView> +#include <QtGui/qapplication.h> +#include <QtGui/qgraphicssceneevent.h> +#include <QtGui/qstyleoption.h> +#if defined(Q_WS_X11) +#include <QX11Info> +#endif + +class QGraphicsWebViewPrivate : public QWebPageClient { +public: + QGraphicsWebViewPrivate(QGraphicsWebView* parent) + : q(parent) + , page(0) + {} + + virtual ~QGraphicsWebViewPrivate(); + virtual void scroll(int dx, int dy, const QRect&); + virtual void update(const QRect& dirtyRect); + virtual void setInputMethodEnabled(bool enable); + virtual bool inputMethodEnabled() const; +#if QT_VERSION >= 0x040600 + virtual void setInputMethodHint(Qt::InputMethodHint hint, bool enable); +#endif + +#ifndef QT_NO_CURSOR + virtual QCursor cursor() const; + virtual void updateCursor(const QCursor& cursor); +#endif + + virtual QPalette palette() const; + virtual int screenNumber() const; + virtual QWidget* ownerWidget() const; + + virtual QObject* pluginParent() const; + + void _q_doLoadFinished(bool success); + + QGraphicsWebView* q; + QWebPage* page; +}; + +QGraphicsWebViewPrivate::~QGraphicsWebViewPrivate() +{ +} + +void QGraphicsWebViewPrivate::_q_doLoadFinished(bool success) +{ + // If the page had no title, still make sure it gets the signal + if (q->title().isEmpty()) + emit q->urlChanged(q->url()); + + emit q->loadFinished(success); +} + +void QGraphicsWebViewPrivate::scroll(int dx, int dy, const QRect& rectToScroll) +{ + q->scroll(qreal(dx), qreal(dy), QRectF(rectToScroll)); +} + +void QGraphicsWebViewPrivate::update(const QRect & dirtyRect) +{ + q->update(QRectF(dirtyRect)); +} + + +void QGraphicsWebViewPrivate::setInputMethodEnabled(bool enable) +{ +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + q->setFlag(QGraphicsItem::ItemAcceptsInputMethod, enable); +#endif +} + +bool QGraphicsWebViewPrivate::inputMethodEnabled() const +{ +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + return q->flags() & QGraphicsItem::ItemAcceptsInputMethod; +#else + return false; +#endif +} + +#if QT_VERSION >= 0x040600 +void QGraphicsWebViewPrivate::setInputMethodHint(Qt::InputMethodHint hint, bool enable) +{ + if (enable) + q->setInputMethodHints(q->inputMethodHints() | hint); + else + q->setInputMethodHints(q->inputMethodHints() & ~hint); +} +#endif +#ifndef QT_NO_CURSOR +QCursor QGraphicsWebViewPrivate::cursor() const +{ + return q->cursor(); +} + +void QGraphicsWebViewPrivate::updateCursor(const QCursor& cursor) +{ + q->setCursor(cursor); +} +#endif + +QPalette QGraphicsWebViewPrivate::palette() const +{ + return q->palette(); +} + +int QGraphicsWebViewPrivate::screenNumber() const +{ +#if defined(Q_WS_X11) + const QList<QGraphicsView*> views = q->scene()->views(); + + if (!views.isEmpty()) + return views.at(0)->x11Info().screen(); +#endif + + return 0; +} + +QWidget* QGraphicsWebViewPrivate::ownerWidget() const +{ + const QList<QGraphicsView*> views = q->scene()->views(); + return views.value(0); +} + +QObject* QGraphicsWebViewPrivate::pluginParent() const +{ + return q; +} + +/*! + \class QGraphicsWebView + \brief The QGraphicsWebView class allows Web content to be added to a GraphicsView. + \since 4.6 + + An instance of this class renders Web content from a URL or supplied as data, using + features of the QtWebKit module. + + If the width and height of the item are not set, they will default to 800 and 600, + respectively. If the Web page contents is larger than that, scrollbars will be shown + if not disabled explicitly. + + \section1 Browser Features + + Many of the functions, signals and properties provided by QWebView are also available + for this item, making it simple to adapt existing code to use QGraphicsWebView instead + of QWebView. + + The item uses a QWebPage object to perform the rendering of Web content, and this can + be obtained with the page() function, enabling the document itself to be accessed and + modified. + + As with QWebView, the item records the browsing history using a QWebHistory object, + accessible using the history() function. The QWebSettings object that defines the + configuration of the browser can be obtained with the settings() function, enabling + features like plugin support to be customized for each item. + + \sa QWebView, QGraphicsTextItem +*/ + +/*! + \fn void QGraphicsWebView::titleChanged(const QString &title) + + This signal is emitted whenever the \a title of the main frame changes. + + \sa title() +*/ + +/*! + \fn void QGraphicsWebView::urlChanged(const QUrl &url) + + This signal is emitted when the \a url of the view changes. + + \sa url(), load() +*/ + +/*! + \fn void QGraphicsWebView::iconChanged() + + This signal is emitted whenever the icon of the page is loaded or changes. + + In order for icons to be loaded, you will need to set an icon database path + using QWebSettings::setIconDatabasePath(). + + \sa icon(), QWebSettings::setIconDatabasePath() +*/ + +/*! + \fn void QGraphicsWebView::loadStarted() + + This signal is emitted when a new load of the page is started. + + \sa loadProgress(), loadFinished() +*/ + +/*! + \fn void QGraphicsWebView::loadFinished(bool ok) + + This signal is emitted when a load of the page is finished. + \a ok will indicate whether the load was successful or any error occurred. + + \sa loadStarted() +*/ + +/*! + Constructs an empty QGraphicsWebView with parent \a parent. + + \sa load() +*/ +QGraphicsWebView::QGraphicsWebView(QGraphicsItem* parent) + : QGraphicsWidget(parent) + , d(new QGraphicsWebViewPrivate(this)) +{ +#if QT_VERSION >= 0x040600 + setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, true); +#endif + setAcceptDrops(true); + setAcceptHoverEvents(true); + setFocusPolicy(Qt::StrongFocus); +} + +/*! + Destroys the item. +*/ +QGraphicsWebView::~QGraphicsWebView() +{ + if (d->page) { +#if QT_VERSION >= 0x040600 + d->page->d->view.clear(); +#else + d->page->d->view = 0; +#endif + d->page->d->client = 0; // unset the page client + } + + if (d->page && d->page->parent() == this) + delete d->page; + + delete d; +} + +/*! + Returns a pointer to the underlying web page. + + \sa setPage() +*/ +QWebPage* QGraphicsWebView::page() const +{ + if (!d->page) { + QGraphicsWebView* that = const_cast<QGraphicsWebView*>(this); + QWebPage* page = new QWebPage(that); + + // Default to not having a background, in the case + // the page doesn't provide one. + QPalette palette = QApplication::palette(); + palette.setBrush(QPalette::Base, QColor::fromRgbF(0, 0, 0, 0)); + page->setPalette(palette); + + that->setPage(page); + } + + return d->page; +} + +/*! \reimp +*/ +void QGraphicsWebView::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget*) +{ + page()->mainFrame()->render(painter, option->exposedRect.toRect()); +} + +/*! \reimp +*/ +bool QGraphicsWebView::sceneEvent(QEvent* event) +{ + // Re-implemented in order to allows fixing event-related bugs in patch releases. + return QGraphicsWidget::sceneEvent(event); +} + +/*! \reimp +*/ +QVariant QGraphicsWebView::itemChange(GraphicsItemChange change, const QVariant& value) +{ + switch (change) { + // Differently from QWebView, it is interesting to QGraphicsWebView to handle + // post mouse cursor change notifications. Reason: 'ItemCursorChange' is sent + // as the first action in QGraphicsItem::setCursor implementation, and at that + // item widget's cursor has not been effectively changed yet. + // After cursor is properly set (at 'ItemCursorHasChanged' emission time), we + // fire 'CursorChange'. + case ItemCursorChange: + return value; + case ItemCursorHasChanged: + QEvent event(QEvent::CursorChange); + QApplication::sendEvent(this, &event); + return value; + } + + return QGraphicsWidget::itemChange(change, value); +} + +/*! \reimp +*/ +QSizeF QGraphicsWebView::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const +{ + if (which == Qt::PreferredSize) + return QSizeF(800, 600); // ### + return QGraphicsWidget::sizeHint(which, constraint); +} + +/*! \reimp +*/ +QVariant QGraphicsWebView::inputMethodQuery(Qt::InputMethodQuery query) const +{ + if (d->page) + return d->page->inputMethodQuery(query); + return QVariant(); +} + +/*! \reimp +*/ +bool QGraphicsWebView::event(QEvent* event) +{ + // Re-implemented in order to allows fixing event-related bugs in patch releases. + + if (d->page) { +#ifndef QT_NO_CONTEXTMENU + if (event->type() == QEvent::GraphicsSceneContextMenu) { + if (!isEnabled()) + return false; + + QGraphicsSceneContextMenuEvent* ev = static_cast<QGraphicsSceneContextMenuEvent*>(event); + QContextMenuEvent fakeEvent(QContextMenuEvent::Reason(ev->reason()), ev->pos().toPoint()); + if (d->page->swallowContextMenuEvent(&fakeEvent)) { + event->accept(); + return true; + } + d->page->updatePositionDependentActions(fakeEvent.pos()); + } else +#endif // QT_NO_CONTEXTMENU + { +#ifndef QT_NO_CURSOR + if (event->type() == QEvent::CursorChange) { + // An unsetCursor will set the cursor to Qt::ArrowCursor. + // Thus this cursor change might be a QWidget::unsetCursor() + // If this is not the case and it came from WebCore, the + // QWebPageClient already has set its cursor internally + // to Qt::ArrowCursor, so updating the cursor is always + // right, as it falls back to the last cursor set by + // WebCore. + // FIXME: Add a QEvent::CursorUnset or similar to Qt. + if (cursor().shape() == Qt::ArrowCursor) + d->resetCursor(); + } +#endif + } + } + return QGraphicsWidget::event(event); +} + +/*! + Makes \a page the new web page of the web graphicsitem. + + The parent QObject of the provided page remains the owner + of the object. If the current document is a child of the web + view, it will be deleted. + + \sa page() +*/ +void QGraphicsWebView::setPage(QWebPage* page) +{ + if (d->page == page) + return; + + if (d->page) { + d->page->d->client = 0; // unset the page client + if (d->page->parent() == this) + delete d->page; + else + d->page->disconnect(this); + } + + d->page = page; + if (!d->page) + return; + d->page->d->client = d; // set the page client + + QSize size = geometry().size().toSize(); + page->setViewportSize(size); + + QWebFrame* mainFrame = d->page->mainFrame(); + + connect(mainFrame, SIGNAL(titleChanged(QString)), + this, SIGNAL(titleChanged(QString))); + connect(mainFrame, SIGNAL(iconChanged()), + this, SIGNAL(iconChanged())); + connect(mainFrame, SIGNAL(urlChanged(QUrl)), + this, SIGNAL(urlChanged(QUrl))); + connect(d->page, SIGNAL(loadStarted()), + this, SIGNAL(loadStarted())); + connect(d->page, SIGNAL(loadProgress(int)), + this, SIGNAL(loadProgress(int))); + connect(d->page, SIGNAL(loadFinished(bool)), + this, SLOT(_q_doLoadFinished(bool))); + connect(d->page, SIGNAL(statusBarMessage(QString)), + this, SIGNAL(statusBarMessage(QString))); + connect(d->page, SIGNAL(linkClicked(QUrl)), + this, SIGNAL(linkClicked(QUrl))); +} + +/*! + \property QGraphicsWebView::url + \brief the url of the web page currently viewed + + Setting this property clears the view and loads the URL. + + By default, this property contains an empty, invalid URL. + + \sa load(), urlChanged() +*/ + +void QGraphicsWebView::setUrl(const QUrl &url) +{ + page()->mainFrame()->setUrl(url); +} + +QUrl QGraphicsWebView::url() const +{ + if (d->page) + return d->page->mainFrame()->url(); + + return QUrl(); +} + +/*! + \property QGraphicsWebView::title + \brief the title of the web page currently viewed + + By default, this property contains an empty string. + + \sa titleChanged() +*/ +QString QGraphicsWebView::title() const +{ + if (d->page) + return d->page->mainFrame()->title(); + + return QString(); +} + +/*! + \property QGraphicsWebView::icon + \brief the icon associated with the web page currently viewed + + By default, this property contains a null icon. + + \sa iconChanged(), QWebSettings::iconForUrl() +*/ +QIcon QGraphicsWebView::icon() const +{ + if (d->page) + return d->page->mainFrame()->icon(); + + return QIcon(); +} + +/*! + \property QGraphicsWebView::zoomFactor + \since 4.5 + \brief the zoom factor for the view +*/ + +void QGraphicsWebView::setZoomFactor(qreal factor) +{ + if (factor == page()->mainFrame()->zoomFactor()) + return; + + page()->mainFrame()->setZoomFactor(factor); +} + +qreal QGraphicsWebView::zoomFactor() const +{ + return page()->mainFrame()->zoomFactor(); +} + +/*! \reimp +*/ +void QGraphicsWebView::updateGeometry() +{ + QGraphicsWidget::updateGeometry(); + + if (!d->page) + return; + + QSize size = geometry().size().toSize(); + d->page->setViewportSize(size); +} + +/*! \reimp +*/ +void QGraphicsWebView::setGeometry(const QRectF& rect) +{ + QGraphicsWidget::setGeometry(rect); + + if (!d->page) + return; + + // NOTE: call geometry() as setGeometry ensures that + // the geometry is within legal bounds (minimumSize, maximumSize) + QSize size = geometry().size().toSize(); + d->page->setViewportSize(size); +} + +/*! + Convenience slot that stops loading the document. + + \sa reload(), loadFinished() +*/ +void QGraphicsWebView::stop() +{ + if (d->page) + d->page->triggerAction(QWebPage::Stop); +} + +/*! + Convenience slot that loads the previous document in the list of documents + built by navigating links. Does nothing if there is no previous document. + + \sa forward() +*/ +void QGraphicsWebView::back() +{ + if (d->page) + d->page->triggerAction(QWebPage::Back); +} + +/*! + Convenience slot that loads the next document in the list of documents + built by navigating links. Does nothing if there is no next document. + + \sa back() +*/ +void QGraphicsWebView::forward() +{ + if (d->page) + d->page->triggerAction(QWebPage::Forward); +} + +/*! + Reloads the current document. + + \sa stop(), loadStarted() +*/ +void QGraphicsWebView::reload() +{ + if (d->page) + d->page->triggerAction(QWebPage::Reload); +} + +/*! + Loads the specified \a url and displays it. + + \note The view remains the same until enough data has arrived to display the new \a url. + + \sa setUrl(), url(), urlChanged() +*/ +void QGraphicsWebView::load(const QUrl& url) +{ + page()->mainFrame()->load(url); +} + +/*! + \fn void QGraphicsWebView::load(const QNetworkRequest &request, QNetworkAccessManager::Operation operation, const QByteArray &body) + + Loads a network request, \a request, 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 url. + + \sa url(), urlChanged() +*/ + +void QGraphicsWebView::load(const QNetworkRequest& request, + QNetworkAccessManager::Operation operation, + const QByteArray& body) +{ + page()->mainFrame()->load(request, operation, body); +} + +/*! + Sets the content of the web view to the specified \a html. + + External objects such as stylesheets or images referenced in the HTML + document are located relative to \a baseUrl. + + The \a html is loaded immediately; external objects are 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. Alternatively, the + encoding can also be specified by the web server. + + \sa load(), setContent(), QWebFrame::toHtml() +*/ +void QGraphicsWebView::setHtml(const QString& html, const QUrl& baseUrl) +{ + page()->mainFrame()->setHtml(html, baseUrl); +} + +/*! + Sets the content of the web graphicsitem 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. + + \sa load(), setHtml(), QWebFrame::toHtml() +*/ +void QGraphicsWebView::setContent(const QByteArray& data, const QString& mimeType, const QUrl& baseUrl) +{ + page()->mainFrame()->setContent(data, mimeType, baseUrl); +} + +/*! + Returns a pointer to the view's history of navigated web pages. + + It is equivalent to + + \snippet webkitsnippets/qtwebkit_qwebview_snippet.cpp 0 +*/ +QWebHistory* QGraphicsWebView::history() const +{ + return page()->history(); +} + +/*! + \property QGraphicsWebView::modified + \brief whether the document was modified by the user + + Parts of HTML documents can be editable for example through the + \c{contenteditable} attribute on HTML elements. + + By default, this property is false. +*/ +bool QGraphicsWebView::isModified() const +{ + if (d->page) + return d->page->isModified(); + return false; +} + +/*! + Returns a pointer to the view/page specific settings object. + + It is equivalent to + + \snippet webkitsnippets/qtwebkit_qwebview_snippet.cpp 1 + + \sa QWebSettings::globalSettings() +*/ +QWebSettings* QGraphicsWebView::settings() const +{ + return page()->settings(); +} + +/*! + Returns a pointer to a QAction that encapsulates the specified web action \a action. +*/ +QAction *QGraphicsWebView::pageAction(QWebPage::WebAction action) const +{ + return page()->action(action); +} + +/*! + Triggers the specified \a action. If it is a checkable action the specified + \a checked state is assumed. + + \sa pageAction() +*/ +void QGraphicsWebView::triggerPageAction(QWebPage::WebAction action, bool checked) +{ + page()->triggerAction(action, checked); +} + +/*! + Finds the specified string, \a subString, in the page, using the given \a options. + + If the HighlightAllOccurrences flag is passed, the function will highlight all occurrences + that exist in the page. All subsequent calls will extend the highlight, rather than + replace it, with occurrences of the new string. + + If the HighlightAllOccurrences flag is not passed, the function will select an occurrence + and all subsequent calls will replace the current occurrence with the next one. + + To clear the selection, just pass an empty string. + + Returns true if \a subString was found; otherwise returns false. + + \sa QWebPage::selectedText(), QWebPage::selectionChanged() +*/ +bool QGraphicsWebView::findText(const QString &subString, QWebPage::FindFlags options) +{ + if (d->page) + return d->page->findText(subString, options); + return false; +} + +/*! \reimp +*/ +void QGraphicsWebView::hoverMoveEvent(QGraphicsSceneHoverEvent* ev) +{ + if (d->page) { + const bool accepted = ev->isAccepted(); + QMouseEvent me = QMouseEvent(QEvent::MouseMove, + ev->pos().toPoint(), Qt::NoButton, + Qt::NoButton, Qt::NoModifier); + d->page->event(&me); + ev->setAccepted(accepted); + } + + if (!ev->isAccepted()) + QGraphicsItem::hoverMoveEvent(ev); +} + +/*! \reimp +*/ +void QGraphicsWebView::hoverLeaveEvent(QGraphicsSceneHoverEvent* ev) +{ + Q_UNUSED(ev); +} + +/*! \reimp +*/ +void QGraphicsWebView::mouseMoveEvent(QGraphicsSceneMouseEvent* ev) +{ + if (d->page) { + const bool accepted = ev->isAccepted(); + d->page->event(ev); + ev->setAccepted(accepted); + } + + if (!ev->isAccepted()) + QGraphicsItem::mouseMoveEvent(ev); +} + +/*! \reimp +*/ +void QGraphicsWebView::mousePressEvent(QGraphicsSceneMouseEvent* ev) +{ + if (d->page) { + const bool accepted = ev->isAccepted(); + d->page->event(ev); + ev->setAccepted(accepted); + } + + if (!ev->isAccepted()) + QGraphicsItem::mousePressEvent(ev); +} + +/*! \reimp +*/ +void QGraphicsWebView::mouseReleaseEvent(QGraphicsSceneMouseEvent* ev) +{ + if (d->page) { + const bool accepted = ev->isAccepted(); + d->page->event(ev); + ev->setAccepted(accepted); + } + + if (!ev->isAccepted()) + QGraphicsItem::mouseReleaseEvent(ev); +} + +/*! \reimp +*/ +void QGraphicsWebView::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* ev) +{ + if (d->page) { + const bool accepted = ev->isAccepted(); + d->page->event(ev); + ev->setAccepted(accepted); + } + + if (!ev->isAccepted()) + QGraphicsItem::mouseDoubleClickEvent(ev); +} + +/*! \reimp +*/ +void QGraphicsWebView::keyPressEvent(QKeyEvent* ev) +{ + if (d->page) + d->page->event(ev); + + if (!ev->isAccepted()) + QGraphicsItem::keyPressEvent(ev); +} + +/*! \reimp +*/ +void QGraphicsWebView::keyReleaseEvent(QKeyEvent* ev) +{ + if (d->page) + d->page->event(ev); + + if (!ev->isAccepted()) + QGraphicsItem::keyReleaseEvent(ev); +} + +/*! \reimp +*/ +void QGraphicsWebView::focusInEvent(QFocusEvent* ev) +{ + if (d->page) + d->page->event(ev); + else + QGraphicsItem::focusInEvent(ev); +} + +/*! \reimp +*/ +void QGraphicsWebView::focusOutEvent(QFocusEvent* ev) +{ + if (d->page) + d->page->event(ev); + else + QGraphicsItem::focusOutEvent(ev); +} + +/*! \reimp +*/ +bool QGraphicsWebView::focusNextPrevChild(bool next) +{ + if (d->page) + return d->page->focusNextPrevChild(next); + + return QGraphicsWidget::focusNextPrevChild(next); +} + +/*! \reimp +*/ +void QGraphicsWebView::dragEnterEvent(QGraphicsSceneDragDropEvent* ev) +{ +#ifndef QT_NO_DRAGANDDROP + if (d->page) + d->page->event(ev); +#else + Q_UNUSED(ev); +#endif +} + +/*! \reimp +*/ +void QGraphicsWebView::dragLeaveEvent(QGraphicsSceneDragDropEvent* ev) +{ +#ifndef QT_NO_DRAGANDDROP + if (d->page) { + const bool accepted = ev->isAccepted(); + d->page->event(ev); + ev->setAccepted(accepted); + } + + if (!ev->isAccepted()) + QGraphicsWidget::dragLeaveEvent(ev); +#else + Q_UNUSED(ev); +#endif +} + +/*! \reimp +*/ +void QGraphicsWebView::dragMoveEvent(QGraphicsSceneDragDropEvent* ev) +{ +#ifndef QT_NO_DRAGANDDROP + if (d->page) { + const bool accepted = ev->isAccepted(); + d->page->event(ev); + ev->setAccepted(accepted); + } + + if (!ev->isAccepted()) + QGraphicsWidget::dragMoveEvent(ev); +#else + Q_UNUSED(ev); +#endif +} + +/*! \reimp +*/ +void QGraphicsWebView::dropEvent(QGraphicsSceneDragDropEvent* ev) +{ +#ifndef QT_NO_DRAGANDDROP + if (d->page) { + const bool accepted = ev->isAccepted(); + d->page->event(ev); + ev->setAccepted(accepted); + } + + if (!ev->isAccepted()) + QGraphicsWidget::dropEvent(ev); +#else + Q_UNUSED(ev); +#endif +} + +#ifndef QT_NO_CONTEXTMENU +/*! \reimp +*/ +void QGraphicsWebView::contextMenuEvent(QGraphicsSceneContextMenuEvent* ev) +{ + if (d->page) { + const bool accepted = ev->isAccepted(); + d->page->event(ev); + ev->setAccepted(accepted); + } +} +#endif // QT_NO_CONTEXTMENU + +#ifndef QT_NO_WHEELEVENT +/*! \reimp +*/ +void QGraphicsWebView::wheelEvent(QGraphicsSceneWheelEvent* ev) +{ + if (d->page) { + const bool accepted = ev->isAccepted(); + d->page->event(ev); + ev->setAccepted(accepted); + } + + if (!ev->isAccepted()) + QGraphicsItem::wheelEvent(ev); +} +#endif // QT_NO_WHEELEVENT + +/*! \reimp +*/ +void QGraphicsWebView::inputMethodEvent(QInputMethodEvent* ev) +{ + if (d->page) + d->page->event(ev); + + if (!ev->isAccepted()) + QGraphicsItem::inputMethodEvent(ev); +} + +/*! + \fn void QGraphicsWebView::statusBarMessage(const QString& text) + + This signal is emitted when the statusbar \a text is changed by the page. +*/ + +/*! + \fn void QGraphicsWebView::loadProgress(int progress) + + This signal is emitted every time an element in the web page + completes loading and the overall loading progress advances. + + This signal tracks the progress of all child frames. + + The current value is provided by \a progress and scales from 0 to 100, + which is the default range of QProgressBar. + + \sa loadStarted(), loadFinished() +*/ + +/*! + \fn void QGraphicsWebView::linkClicked(const QUrl &url) + + This signal is emitted whenever the user clicks on a link and the page's linkDelegationPolicy + property is set to delegate the link handling for the specified \a url. + + \sa QWebPage::linkDelegationPolicy() +*/ + +#include "moc_qgraphicswebview.cpp" diff --git a/WebKit/qt/Api/qgraphicswebview.h b/WebKit/qt/Api/qgraphicswebview.h new file mode 100644 index 0000000..f3afb4c --- /dev/null +++ b/WebKit/qt/Api/qgraphicswebview.h @@ -0,0 +1,142 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + 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. +*/ + +#ifndef QGraphicsWebView_h +#define QGraphicsWebView_h + +#include "qwebkitglobal.h" +#include "qwebpage.h" +#include <QtCore/qurl.h> +#include <QtGui/qevent.h> +#include <QtGui/qgraphicswidget.h> +#include <QtGui/qicon.h> +#include <QtGui/qpainter.h> +#include <QtNetwork/qnetworkaccessmanager.h> + +class QWebPage; +class QWebHistory; +class QWebSettings; + +class QGraphicsWebViewPrivate; + +class QWEBKIT_EXPORT QGraphicsWebView : public QGraphicsWidget { + Q_OBJECT + + Q_PROPERTY(QString title READ title NOTIFY titleChanged) + Q_PROPERTY(QIcon icon READ icon NOTIFY iconChanged) + Q_PROPERTY(qreal zoomFactor READ zoomFactor WRITE setZoomFactor) + + Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged) + + Q_PROPERTY(bool modified READ isModified) + +public: + explicit QGraphicsWebView(QGraphicsItem* parent = 0); + ~QGraphicsWebView(); + + QWebPage* page() const; + void setPage(QWebPage*); + + QUrl url() const; + void setUrl(const QUrl&); + + QString title() const; + QIcon icon() const; + + qreal zoomFactor() const; + void setZoomFactor(qreal); + + bool isModified() const; + + void load(const QUrl &url); + void load(const QNetworkRequest& request, QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation, const QByteArray& body = QByteArray()); + + void setHtml(const QString& html, const QUrl& baseUrl = QUrl()); + // FIXME: Consider rename to setHtml? + void setContent(const QByteArray& data, const QString& mimeType = QString(), const QUrl& baseUrl = QUrl()); + + QWebHistory* history() const; + QWebSettings* settings() const; + + QAction* pageAction(QWebPage::WebAction action) const; + void triggerPageAction(QWebPage::WebAction action, bool checked = false); + + bool findText(const QString& subString, QWebPage::FindFlags options = 0); + + virtual void setGeometry(const QRectF& rect); + virtual void updateGeometry(); + virtual void paint(QPainter*, const QStyleOptionGraphicsItem* options, QWidget* widget = 0); + virtual QVariant itemChange(GraphicsItemChange change, const QVariant& value); + virtual bool event(QEvent*); + + virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const; + + virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const; + +public Q_SLOTS: + void stop(); + void back(); + void forward(); + void reload(); + +Q_SIGNALS: + void loadStarted(); + void loadFinished(bool); + + void loadProgress(int progress); + void urlChanged(const QUrl&); + void titleChanged(const QString&); + void iconChanged(); + void statusBarMessage(const QString& message); + void linkClicked(const QUrl&); + +protected: + virtual void mousePressEvent(QGraphicsSceneMouseEvent*); + virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent*); + virtual void hoverMoveEvent(QGraphicsSceneHoverEvent*); + virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent*); +#ifndef QT_NO_WHEELEVENT + virtual void wheelEvent(QGraphicsSceneWheelEvent*); +#endif + virtual void keyPressEvent(QKeyEvent*); + virtual void keyReleaseEvent(QKeyEvent*); +#ifndef QT_NO_CONTEXTMENU + virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent*); +#endif + virtual void dragEnterEvent(QGraphicsSceneDragDropEvent*); + virtual void dragLeaveEvent(QGraphicsSceneDragDropEvent*); + virtual void dragMoveEvent(QGraphicsSceneDragDropEvent*); + virtual void dropEvent(QGraphicsSceneDragDropEvent*); + virtual void focusInEvent(QFocusEvent*); + virtual void focusOutEvent(QFocusEvent*); + virtual void inputMethodEvent(QInputMethodEvent*); + virtual bool focusNextPrevChild(bool next); + + virtual bool sceneEvent(QEvent*); + +private: + Q_PRIVATE_SLOT(d, void _q_doLoadFinished(bool success)) + + QGraphicsWebViewPrivate* const d; + friend class QGraphicsWebViewPrivate; +}; + +#endif // QGraphicsWebView_h diff --git a/WebKit/qt/Api/qwebdatabase.cpp b/WebKit/qt/Api/qwebdatabase.cpp index d51e4e6..4e8fd30 100644 --- a/WebKit/qt/Api/qwebdatabase.cpp +++ b/WebKit/qt/Api/qwebdatabase.cpp @@ -33,6 +33,8 @@ using namespace WebCore; \since 4.5 \brief The QWebDatabase class provides access to HTML 5 databases created with JavaScript. + \inmodule QtWebKit + The upcoming HTML 5 standard includes support for SQL databases that web sites can create and access on a local computer through JavaScript. QWebDatabase is the C++ interface to these databases. diff --git a/WebKit/qt/Api/qwebelement.cpp b/WebKit/qt/Api/qwebelement.cpp index 14b2811..441bec7 100644 --- a/WebKit/qt/Api/qwebelement.cpp +++ b/WebKit/qt/Api/qwebelement.cpp @@ -23,27 +23,32 @@ #include "CSSComputedStyleDeclaration.h" #include "CSSMutableStyleDeclaration.h" #include "CSSParser.h" -#include "CSSRuleList.h" #include "CSSRule.h" +#include "CSSRuleList.h" #include "CSSStyleRule.h" #include "CString.h" #include "Document.h" #include "DocumentFragment.h" #include "FrameView.h" +#include "GraphicsContext.h" #include "HTMLElement.h" #include "JSGlobalObject.h" #include "JSHTMLElement.h" #include "JSObject.h" #include "NodeList.h" #include "PropertyNameArray.h" +#include "RenderImage.h" #include "ScriptFunctionCall.h" #include "StaticNodeList.h" #include "qt_runtime.h" #include "qwebframe.h" #include "qwebframe_p.h" #include "runtime_root.h" +#include <parser/SourceCode.h> #include <wtf/Vector.h> +#include <QPainter> + using namespace WebCore; class QWebElementPrivate { @@ -53,45 +58,55 @@ public: /*! \class QWebElement \since 4.6 - \brief The QWebElement class provides convenient access to DOM elements in a QWebFrame. + \brief The QWebElement class provides convenient access to DOM elements in + a QWebFrame. + \inmodule QtWebKit - QWebElement is the main class to easily access to the document model. - The document model is represented by a tree-like structure of DOM elements. - The root of the tree is called the document element and can be accessed using QWebFrame::documentElement(). + A QWebElement object allows easy access to the document model, represented + by a tree-like structure of DOM elements. The root of the tree is called + the document element and can be accessed using + QWebFrame::documentElement(). - You can reach specific elements using findAll() and findFirst(); the elements - are identified through CSS selectors. + Specific elements can be accessed using findAll() and findFirst(). These + elements are identified using CSS selectors. The code snippet below + demonstrates the use of findAll(). \snippet webkitsnippets/webelement/main.cpp FindAll - The first list contains all \c span elements in the document. The second list contains - \c span elements that are children of \c p, classified with \c intro. + The first list contains all \c span elements in the document. The second + list contains \c span elements that are children of \c p, classified with + \c intro. - Using findFirst() is more efficient than calling findAll() and extracting the first element - only in the returned list. + Using findFirst() is more efficient than calling findAll(), and extracting + the first element only in the list returned. - Alternatively you can manually traverse the document using firstChild() and nextSibling(): + Alternatively you can traverse the document manually using firstChild() and + nextSibling(): \snippet webkitsnippets/webelement/main.cpp Traversing with QWebElement - The underlying content of QWebElement is explicitly shared. Creating a copy of a QWebElement - does not create a copy of the content. Instead, both instances point to the same element. + The underlying content of QWebElement is explicitly shared. Creating a copy + of a QWebElement does not create a copy of the content. Instead, both + instances point to the same element. - The element's attributes can be read using attribute() and modified with setAttribute(). + The element's attributes can be read using attribute() and modified with + setAttribute(). - The contents of child elements can be converted to plain text with toPlainText() and to - XHTML using toInnerXml(). To also include the element's tag in the output, use toOuterXml(). + The contents of child elements can be converted to plain text with + toPlainText(); to XHTML using toInnerXml(). To include the element's tag in + the output, use toOuterXml(). - It is possible to replace the contents using setPlainText() and setInnerXml(). To replace - the element itself and its contents, use setOuterXml(). + It is possible to replace the contents of child elements using + setPlainText() and setInnerXml(). To replace the element itself and its + contents, use setOuterXml(). - In the JavaScript DOM interfaces, elements can have additional functions depending on their - type. For example an HTML form element can be triggered to submit the entire form to the - web server using the submit() function. A list of these special functions can be obtained - in QWebElement using functions(); they can be invoked using callFunction(). + \section1 Examples - Similarly element specific properties can be obtained using scriptableProperties() and - read/written using scriptableProperty()/setScriptableProperty(). + The \l{DOM Traversal Example} shows one way to traverse documents in a running + example. + + The \l{Simple Selector Example} can be used to experiment with the searching + features of this class and provides sample code you can start working with. */ /*! @@ -156,7 +171,7 @@ QWebElement &QWebElement::operator=(const QWebElement &other) } /*! - Destroys the element. The underlying DOM element is not destroyed. + Destroys the element. However, the underlying DOM element is not destroyed. */ QWebElement::~QWebElement() { @@ -176,7 +191,7 @@ bool QWebElement::operator!=(const QWebElement& o) const } /*! - Returns true if the element is a null element; false otherwise. + Returns true if the element is a null element; otherwise returns false. */ bool QWebElement::isNull() const { @@ -184,40 +199,30 @@ bool QWebElement::isNull() const } /*! - Returns a new list of child elements matching the given CSS selector \a selectorQuery. - If there are no matching elements, an empty list is returned. + Returns a new list of child 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. + \l{Standard CSS2 selector} syntax is used for the query. \note This search is performed recursively. + + \sa findFirst() */ -QList<QWebElement> QWebElement::findAll(const QString &selectorQuery) const +QWebElementCollection QWebElement::findAll(const QString &selectorQuery) const { - QList<QWebElement> elements; - if (!m_element) - return elements; - - ExceptionCode exception = 0; // ### - RefPtr<NodeList> nodes = m_element->querySelectorAll(selectorQuery, exception); - if (!nodes) - return elements; - - for (int i = 0; i < nodes->length(); ++i) { - WebCore::Node* n = nodes->item(i); - elements.append(QWebElement(static_cast<Element*>(n))); - } - - return elements; + return QWebElementCollection(*this, selectorQuery); } /*! - Returns the first child element that matches the given CSS selector \a selectorQuery. + Returns the first child element that matches the given CSS selector + \a selectorQuery. - \l{http://www.w3.org/TR/REC-CSS2/selector.html#q1}{Standard CSS2 selector} syntax is - used for the query. + \l{Standard CSS2 selector} syntax is used for the query. \note This search is performed recursively. + + \sa findAll() */ QWebElement QWebElement::findFirst(const QString &selectorQuery) const { @@ -231,6 +236,8 @@ QWebElement QWebElement::findFirst(const QString &selectorQuery) const Replaces the existing content of this element with \a text. This is equivalent to setting the HTML innerText property. + + \sa toPlainText() */ void QWebElement::setPlainText(const QString &text) { @@ -245,6 +252,8 @@ void QWebElement::setPlainText(const QString &text) element. This is equivalent to reading the HTML innerText property. + + \sa setPlainText() */ QString QWebElement::toPlainText() const { @@ -254,11 +263,13 @@ QString QWebElement::toPlainText() const } /*! - Replaces the contents of this element as well as its own tag with \a markup. - The string may contain HTML or XML tags, which is parsed and formatted - before insertion into the document. + Replaces the contents of this element as well as its own tag with + \a markup. The string may contain HTML or XML tags, which is parsed and + formatted before insertion into the document. \note This is currently only implemented for (X)HTML elements. + + \sa toOuterXml(), toInnerXml(), setInnerXml() */ void QWebElement::setOuterXml(const QString &markup) { @@ -272,9 +283,11 @@ void QWebElement::setOuterXml(const QString &markup) /*! Returns this element converted to XML, including the start and the end - tag of this element and its attributes. + tags as well as its attributes. - \note This is currently only implemented for (X)HTML elements. + \note This is currently implemented for (X)HTML elements only. + + \sa setOuterXml(), setInnerXml(), toInnerXml() */ QString QWebElement::toOuterXml() const { @@ -285,11 +298,13 @@ QString QWebElement::toOuterXml() const } /*! - Replaces the content of this element with \a markup. - The string may contain HTML or XML tags, which is parsed and formatted - before insertion into the document. + Replaces the contents of this element with \a markup. The string may + contain HTML or XML tags, which is parsed and formatted before insertion + into the document. - \note This is currently only implemented for (X)HTML elements. + \note This is currently implemented for (X)HTML elements only. + + \sa toInnerXml(), toOuterXml(), setOuterXml() */ void QWebElement::setInnerXml(const QString &markup) { @@ -302,10 +317,11 @@ void QWebElement::setInnerXml(const QString &markup) } /*! - Returns the XML between the start and the end tag of this - element. + Returns the XML content between the element's start and end tags. - \note This is currently only implemented for (X)HTML elements. + \note This is currently implemented for (X)HTML elements only. + + \sa setInnerXml(), setOuterXml(), toOuterXml() */ QString QWebElement::toInnerXml() const { @@ -316,8 +332,10 @@ QString QWebElement::toInnerXml() const } /*! - Adds an attribute called \a name with the value \a value. If an attribute - with the same name exists, its value is replaced by \a value. + Adds an attribute with the given \a name and \a value. If an attribute with + the same name exists, its value is replaced by \a value. + + \sa attribute(), attributeNS(), setAttributeNS() */ void QWebElement::setAttribute(const QString &name, const QString &value) { @@ -328,9 +346,11 @@ void QWebElement::setAttribute(const QString &name, const QString &value) } /*! - Adds an attribute called \a name in the namespace described with \a namespaceUri - with the value \a value. If an attribute with the same name exists, its value is - replaced by \a value. + Adds an attribute with the given \a name in \a namespaceUri with \a value. + If an attribute with the same name exists, its value is replaced by + \a value. + + \sa attributeNS(), attribute(), setAttribute() */ void QWebElement::setAttributeNS(const QString &namespaceUri, const QString &name, const QString &value) { @@ -341,8 +361,10 @@ void QWebElement::setAttributeNS(const QString &namespaceUri, const QString &nam } /*! - Returns the attributed called \a name. If the attribute does not exist \a defaultValue is - returned. + Returns the attribute with the given \a name. If the attribute does not + exist, \a defaultValue is returned. + + \sa setAttribute(), setAttributeNS(), attributeNS() */ QString QWebElement::attribute(const QString &name, const QString &defaultValue) const { @@ -355,8 +377,10 @@ QString QWebElement::attribute(const QString &name, const QString &defaultValue) } /*! - Returns the attributed called \a name in the namespace described with \a namespaceUri. - If the attribute does not exist \a defaultValue is returned. + Returns the attribute with the given \a name in \a namespaceUri. If the + attribute does not exist, \a defaultValue is returned. + + \sa setAttributeNS(), setAttribute(), attribute() */ QString QWebElement::attributeNS(const QString &namespaceUri, const QString &name, const QString &defaultValue) const { @@ -369,7 +393,10 @@ QString QWebElement::attributeNS(const QString &namespaceUri, const QString &nam } /*! - Returns true if this element has an attribute called \a name; otherwise returns false. + Returns true if this element has an attribute with the given \a name; + otherwise returns false. + + \sa attribute(), setAttribute() */ bool QWebElement::hasAttribute(const QString &name) const { @@ -379,8 +406,10 @@ bool QWebElement::hasAttribute(const QString &name) const } /*! - Returns true if this element has an attribute called \a name in the namespace described - with \a namespaceUri; otherwise returns false. + Returns true if this element has an attribute with the given \a name, in + \a namespaceUri; otherwise returns false. + + \sa attributeNS(), setAttributeNS() */ bool QWebElement::hasAttributeNS(const QString &namespaceUri, const QString &name) const { @@ -390,7 +419,9 @@ bool QWebElement::hasAttributeNS(const QString &namespaceUri, const QString &nam } /*! - Removes the attribute called \a name from this element. + Removes the attribute with the given \a name from this element. + + \sa attribute(), setAttribute(), hasAttribute() */ void QWebElement::removeAttribute(const QString &name) { @@ -401,8 +432,10 @@ void QWebElement::removeAttribute(const QString &name) } /*! - Removes the attribute called \a name in the namespace described with \a namespaceUri - from this element. + Removes the attribute with the given \a name, in \a namespaceUri, from this + element. + + \sa attributeNS(), setAttributeNS(), hasAttributeNS() */ void QWebElement::removeAttributeNS(const QString &namespaceUri, const QString &name) { @@ -413,7 +446,10 @@ void QWebElement::removeAttributeNS(const QString &namespaceUri, const QString & } /*! - Returns true if the element has any attributes defined; otherwise returns false; + Returns true if the element has any attributes defined; otherwise returns + false; + + \sa attribute(), setAttribute() */ bool QWebElement::hasAttributes() const { @@ -423,7 +459,60 @@ bool QWebElement::hasAttributes() const } /*! + Return the list of attributes for the namespace given as \a namespaceUri. + + \sa attribute(), setAttribute() +*/ +QStringList QWebElement::attributeNames(const QString& namespaceUri) const +{ + if (!m_element) + return QStringList(); + + QStringList attributeNameList; + const NamedNodeMap* const attrs = m_element->attributes(/* read only = */ true); + if (attrs) { + const String namespaceUriString(namespaceUri); // convert QString -> String once + const unsigned attrsCount = attrs->length(); + for (unsigned i = 0; i < attrsCount; ++i) { + const Attribute* const attribute = attrs->attributeItem(i); + if (namespaceUriString == attribute->namespaceURI()) + attributeNameList.append(attribute->localName()); + } + } + return attributeNameList; +} + +/*! + Returns true if the element has keyboard input focus; otherwise, returns false + + \sa setFocus() +*/ +bool QWebElement::hasFocus() const +{ + if (!m_element) + return false; + if (m_element->document()) + return m_element == m_element->document()->focusedNode(); + return false; +} + +/*! + Gives keyboard input focus to this element + + \sa hasFocus() +*/ +void QWebElement::setFocus() +{ + if (!m_element) + return; + if (m_element->document() && m_element->isFocusable()) + m_element->document()->setFocusedNode(m_element); +} + +/*! Returns the geometry of this element, relative to its containing frame. + + \sa tagName() */ QRect QWebElement::geometry() const { @@ -434,6 +523,8 @@ QRect QWebElement::geometry() const /*! Returns the tag name of this element. + + \sa geometry() */ QString QWebElement::tagName() const { @@ -443,7 +534,8 @@ QString QWebElement::tagName() const } /*! - Returns the namespace prefix of the element or an empty string if the element has no namespace prefix. + Returns the namespace prefix of the element. If the element has no\ + namespace prefix, empty string is returned. */ QString QWebElement::prefix() const { @@ -453,8 +545,8 @@ QString QWebElement::prefix() const } /*! - If the element uses namespaces, this function returns the local name of the element; - otherwise it returns an empty string. + Returns the local name of the element. If the element does not use + namespaces, an empty string is returned. */ QString QWebElement::localName() const { @@ -464,7 +556,8 @@ QString QWebElement::localName() const } /*! - Returns the namespace URI of this element or an empty string if the element has no namespace URI. + Returns the namespace URI of this element. If the element has no namespace + URI, an empty string is returned. */ QString QWebElement::namespaceUri() const { @@ -474,8 +567,8 @@ QString QWebElement::namespaceUri() const } /*! - Returns the parent element of this element or a null element if this element - is the root document element. + Returns the parent element of this elemen. If this element is the root + document element, a null element is returned. */ QWebElement QWebElement::parent() const { @@ -485,9 +578,9 @@ QWebElement QWebElement::parent() const } /*! - Returns the first child element of this element. + Returns the element's first child. - \sa lastChild() previousSibling() nextSibling() + \sa lastChild(), previousSibling(), nextSibling() */ QWebElement QWebElement::firstChild() const { @@ -503,9 +596,9 @@ QWebElement QWebElement::firstChild() const } /*! - Returns the last child element of this element. + Returns the element's last child. - \sa firstChild() previousSibling() nextSibling() + \sa firstChild(), previousSibling(), nextSibling() */ QWebElement QWebElement::lastChild() const { @@ -521,9 +614,9 @@ QWebElement QWebElement::lastChild() const } /*! - Returns the next sibling element of this element. + Returns the element's next sibling. - \sa firstChild() previousSibling() lastChild() + \sa firstChild(), previousSibling(), lastChild() */ QWebElement QWebElement::nextSibling() const { @@ -539,9 +632,9 @@ QWebElement QWebElement::nextSibling() const } /*! - Returns the previous sibling element of this element. + Returns the element's previous sibling. - \sa firstChild() nextSibling() lastChild() + \sa firstChild(), nextSibling(), lastChild() */ QWebElement QWebElement::previousSibling() const { @@ -557,7 +650,7 @@ QWebElement QWebElement::previousSibling() const } /*! - Returns the document this element belongs to. + Returns the document which this element belongs to. */ QWebElement QWebElement::document() const { @@ -570,8 +663,8 @@ QWebElement QWebElement::document() const } /*! - Returns the web frame this elements is a part of. If the element is - a null element null is returned. + Returns the web frame which this element is a part of. If the element is a + null element, null is returned. */ QWebFrame *QWebElement::webFrame() const { @@ -605,7 +698,7 @@ static bool setupScriptContext(WebCore::Element* element, JSC::JSValue& thisValu if (!scriptController) return false; - state = scriptController->globalObject()->globalExec(); + state = scriptController->globalObject(mainThreadNormalWorld())->globalExec(); if (!state) return false; @@ -617,41 +710,10 @@ static bool setupScriptContext(WebCore::Element* element, JSC::JSValue& thisValu } -static bool setupScriptObject(WebCore::Element* element, ScriptObject& object, ScriptState*& state, ScriptController*& scriptController) -{ - if (!element) - return false; - - Document* document = element->document(); - if (!document) - return false; - - Frame* frame = document->frame(); - if (!frame) - return false; - - scriptController = frame->script(); - - state = scriptController->globalObject()->globalExec(); - - JSC::JSValue thisValue = toJS(state, element); - if (!thisValue) - return false; - - JSC::JSObject* thisObject = thisValue.toObject(state); - if (!thisObject) - return false; - - object = ScriptObject(state, thisObject); - return true; -} - /*! - Executes the \a scriptSource with this element as the `this' object. - - \sa callFunction() + Executes \a scriptSource with this element as \c this object. */ -QVariant QWebElement::evaluateScript(const QString& scriptSource) +QVariant QWebElement::evaluateJavaScript(const QString& scriptSource) { if (scriptSource.isEmpty()) return QVariant(); @@ -678,263 +740,40 @@ QVariant QWebElement::evaluateScript(const QString& scriptSource) } /*! - Calls the function with the given \a name and \a arguments. - - The underlying DOM element that QWebElement wraps may have dedicated functions depending - on its type. For example a form element can have the "submit" function, that would submit - the form to the destination specified in the HTML. - - \sa functions() -*/ -QVariant QWebElement::callFunction(const QString &name, const QVariantList &arguments) -{ - ScriptState* state = 0; - ScriptObject thisObject; - ScriptController* scriptController = 0; - - if (!setupScriptObject(m_element, thisObject, state, scriptController)) - return QVariant(); - - ScriptFunctionCall functionCall(state, thisObject, name); - - for (QVariantList::ConstIterator it = arguments.constBegin(), end = arguments.constEnd(); - it != end; ++it) - functionCall.appendArgument(JSC::Bindings::convertQVariantToValue(state, scriptController->bindingRootObject(), *it)); - - bool hadException = false; - ScriptValue result = functionCall.call(hadException); - if (hadException) - return QVariant(); - - int distance = 0; - return JSC::Bindings::convertValueToQVariant(state, result.jsValue(), QMetaType::Void, &distance); -} - -/*! - Returns a list of function names this element supports. - - The function names returned are the same functions that are callable from the DOM - element's JavaScript binding. - - \sa callFunction() -*/ -QStringList QWebElement::functions() const -{ - ScriptState* state = 0; - ScriptObject thisObject; - ScriptController* scriptController = 0; - - if (!setupScriptObject(m_element, thisObject, state, scriptController)) - return QStringList(); - - JSC::JSObject* object = thisObject.jsObject(); - if (!object) - return QStringList(); - - QStringList names; - - // Enumerate the contents of the object - JSC::PropertyNameArray properties(state); - object->getPropertyNames(state, properties); - for (JSC::PropertyNameArray::const_iterator it = properties.begin(); - it != properties.end(); ++it) { - - JSC::JSValue property = object->get(state, *it); - if (!property) - continue; - - JSC::JSObject* function = property.toObject(state); - if (!function) - continue; - - JSC::CallData callData; - JSC::CallType callType = function->getCallData(callData); - if (callType == JSC::CallTypeNone) - continue; - - JSC::UString ustring = (*it).ustring(); - names << QString::fromUtf16((const ushort*)ustring.rep()->data(), ustring.size()); - } - - if (state->hadException()) - state->clearException(); - - return names; -} - -/*! - Returns the value of the element's \a name property. - - If no such property exists, the returned variant is invalid. - - The return property has the same value as the corresponding property - in the element's JavaScript binding with the same name. - - Information about all available properties is provided through scriptProperties(). - - \sa setScriptableProperty(), scriptableProperties() -*/ -QVariant QWebElement::scriptableProperty(const QString &name) const -{ - ScriptState* state = 0; - ScriptObject thisObject; - ScriptController *scriptController = 0; - - if (!setupScriptObject(m_element, thisObject, state, scriptController)) - return QVariant(); - - String wcName(name); - JSC::JSValue property = thisObject.jsObject()->get(state, JSC::Identifier(state, wcName)); - - // ### - if (state->hadException()) - state->clearException(); - - int distance = 0; - return JSC::Bindings::convertValueToQVariant(state, property, QMetaType::Void, &distance); -} - -/*! - Sets the value of the element's \a name property to \a value. - - Information about all available properties is provided through scriptProperties(). - - Setting the property will affect the corresponding property - in the element's JavaScript binding with the same name. - - \sa scriptableProperty(), scriptableProperties() -*/ -void QWebElement::setScriptableProperty(const QString &name, const QVariant &value) -{ - ScriptState* state = 0; - ScriptObject thisObject; - ScriptController* scriptController = 0; - - if (!setupScriptObject(m_element, thisObject, state, scriptController)) - return; - - JSC::JSValue jsValue = JSC::Bindings::convertQVariantToValue(state, scriptController->bindingRootObject(), value); - if (!jsValue) - return; - - String wcName(name); - JSC::PutPropertySlot slot; - thisObject.jsObject()->put(state, JSC::Identifier(state, wcName), jsValue, slot); - if (state->hadException()) - state->clearException(); -} - -/*! - Returns a list of property names this element supports. - - The function names returned are the same properties that are accessible from the DOM - element's JavaScript binding. - - \sa setScriptableProperty(), scriptableProperty() -*/ -QStringList QWebElement::scriptableProperties() const -{ - if (!m_element) - return QStringList(); - - Document* document = m_element->document(); - if (!document) - return QStringList(); - - Frame* frame = document->frame(); - if (!frame) - return QStringList(); - - ScriptController* script = frame->script(); - JSC::ExecState* exec = script->globalObject()->globalExec(); - - JSC::JSValue thisValue = toJS(exec, m_element); - if (!thisValue) - return QStringList(); - - JSC::JSObject* object = thisValue.toObject(exec); - if (!object) - return QStringList(); - - QStringList names; - - // Enumerate the contents of the object - JSC::PropertyNameArray properties(exec); - object->getPropertyNames(exec, properties); - for (JSC::PropertyNameArray::const_iterator it = properties.begin(); - it != properties.end(); ++it) { - - JSC::JSValue property = object->get(exec, *it); - if (!property) - continue; - - JSC::JSObject* function = property.toObject(exec); - if (!function) - continue; - - JSC::CallData callData; - JSC::CallType callType = function->getCallData(callData); - if (callType != JSC::CallTypeNone) - continue; - - JSC::UString ustring = (*it).ustring(); - names << QString::fromUtf16((const ushort*)ustring.rep()->data(), ustring.size()); - } - - if (exec->hadException()) - exec->clearException(); - - return names; -} - -/*! - \enum QWebElement::ResolveRule - \since 4.6 + \enum QWebElement::StyleResolveStrategy This enum describes how QWebElement's styleProperty resolves the given property name. - \value IgnoreCascadingStyles Return the property value as it is defined - in the element, without respecting style inheritance and other CSS rules. - \value RespectCascadingStyles The property's value is determined using - the inheritance and importance rules defined in the document's stylesheet. + \value InlineStyle Return the property value as it is defined in + the element, without respecting style inheritance and other CSS + rules. + \value CascadedStyle The property's value is determined using the + inheritance and importance rules defined in the document's + stylesheet. + \value ComputedStyle The property's value is the absolute value + of the style property resolved from the environment. */ /*! - \enum QWebElement::StylePriority - \since 4.6 - - This enum describes the priority newly set CSS properties should have when - set using QWebElement::setStyleProperty(). - - \value NormalStylePriority Define the property without important - priority even if "!important" is explicitly set in \a value. - \value DeclaredStylePriority Define the property respecting the - priority specified in \a value. - \value ImportantStylePriority Define the property to have - an important priority, this is equal to appending "!important" to the value. -*/ - -/*! - Returns the value of the style named \a name or an empty string if such one - does not exist. - - If \a rule is IgnoreCascadingStyles, the value defined inside the element - (inline in CSS terminology) is returned. + Returns the value of the style with the given \a name using the specified + \a strategy. If a style with \a name does not exist, an empty string is + returned. - if \a rule is RespectCascadingStyles, the actual style applied to the - element is returned. + In CSS, the cascading part depends on which CSS rule has priority and is + thus applied. Generally, the last defined rule has priority. Thus, an + inline style rule has priority over an embedded block style rule, which + in return has priority over an external style rule. - In CSS, the cascading part has to do with which CSS rule has priority and - is thus applied. Generally speaking, the last defined rule has priority, - thus an inline style rule has priority over an embedded block style rule, - which in return has priority over an external style rule. + If the "!important" declaration is set on one of those, the declaration + receives highest priority, unless other declarations also use the + "!important" declaration. Then, the last "!important" declaration takes + predecence. - If the !important declaration is set on one of those, the declaration gets - highest priority, unless other declarations also use the !important - declaration, in which the last !important declaration takes predecence. + \sa setStyleProperty() */ -QString QWebElement::styleProperty(const QString &name, ResolveRule rule) const + +QString QWebElement::styleProperty(const QString &name, StyleResolveStrategy strategy) const { if (!m_element || !m_element->isStyledElement()) return QString(); @@ -946,10 +785,10 @@ QString QWebElement::styleProperty(const QString &name, ResolveRule rule) const CSSStyleDeclaration* style = static_cast<StyledElement*>(m_element)->style(); - if (rule == IgnoreCascadingStyles) + if (strategy == InlineStyle) return style->getPropertyValue(propID); - if (rule == RespectCascadingStyles) { + if (strategy == CascadedStyle) { if (style->getPropertyPriority(propID)) return style->getPropertyValue(propID); @@ -977,32 +816,33 @@ QString QWebElement::styleProperty(const QString &name, ResolveRule rule) const return style->getPropertyValue(propID); } + if (strategy == ComputedStyle) { + if (!m_element || !m_element->isStyledElement()) + return QString(); + + int propID = cssPropertyID(name); + + RefPtr<CSSComputedStyleDeclaration> style = computedStyle(m_element); + if (!propID || !style) + return QString(); + + return style->getPropertyValue(propID); + } + return QString(); } /*! - Sets the value of the style named \a name to \a value. + Sets the value of the inline style with the given \a name to \a value. - Setting a value, doesn't necessarily mean that it will become the applied + Setting a value, does not necessarily mean that it will become the applied value, due to the fact that the style property's value might have been set - earlier with priority in external or embedded style declarations. + earlier with a higher priority in external or embedded style declarations. - In order to ensure that the value will be applied, ImportantStylePriority - should be used as \a priority. - - Following the CSS syntax for property values, this is equal to appending + In order to ensure that the value will be applied, you may have to append "!important" to the value. - - This syntax is supported when using DeclaredStylePriority as \a priority. - - Using NormalStylePriority as \a priority, the property will have normal - priority, and any "!important" declaration will be ignored. On the other - hand, using ImportantStylePriority sets the important priority even when - not explicit passed in \a value. - By using DeclaredStylePriority as \a priority the property will respect the - priority specified in \a value. */ -void QWebElement::setStyleProperty(const QString &name, const QString &value, StylePriority priority) +void QWebElement::setStyleProperty(const QString &name, const QString &value) { if (!m_element || !m_element->isStyledElement()) return; @@ -1013,42 +853,7 @@ void QWebElement::setStyleProperty(const QString &name, const QString &value, St return; ExceptionCode exception = 0; - - const QRegExp hasImportantTest(QLatin1String("!\\s*important")); - int index = value.indexOf(hasImportantTest); - - QString newValue = (index != -1) ? value.left(index - 1) : value; - - switch (priority) { - case NormalStylePriority: - style->setProperty(name, newValue, "", exception); - break; - case DeclaredStylePriority: - style->setProperty(name, newValue, (index != -1) ? "important" : "", exception); - break; - case ImportantStylePriority: - style->setProperty(name, newValue, "important", exception); - break; - default: - break; - } -} - -/*! - Returns the computed value for style named \a name or an empty string if the style has no such name. -*/ -QString QWebElement::computedStyleProperty(const QString &name) const -{ - if (!m_element || !m_element->isStyledElement()) - return QString(); - - int propID = cssPropertyID(name); - - RefPtr<CSSComputedStyleDeclaration> style = computedStyle(m_element); - if (!propID || !style) - return QString(); - - return style->getPropertyValue(propID); + style->setProperty(name, value, exception); } /*! @@ -1083,7 +888,8 @@ QStringList QWebElement::classes() const } /*! - Returns true if this element has a class called \a name; otherwise returns false. + Returns true if this element has a class with the given \a name; otherwise + returns false. */ bool QWebElement::hasClass(const QString &name) const { @@ -1092,7 +898,7 @@ bool QWebElement::hasClass(const QString &name) const } /*! - Adds the specified class \a name to the element. + Adds the specified class with the given \a name to the element. */ void QWebElement::addClass(const QString &name) { @@ -1105,7 +911,7 @@ void QWebElement::addClass(const QString &name) } /*! - Removes the specified class \a name from the element. + Removes the specified class with the given \a name from the element. */ void QWebElement::removeClass(const QString &name) { @@ -1118,8 +924,8 @@ void QWebElement::removeClass(const QString &name) } /*! - Adds the specified class \a name if it is not present, - removes it if it is already present. + Adds the specified class with the given \a name if it is not present. If + the class is already present, it will be removed. */ void QWebElement::toggleClass(const QString &name) { @@ -1134,11 +940,11 @@ void QWebElement::toggleClass(const QString &name) } /*! - Appends \a element as the element's last child. + Appends the given \a element as the element's last child. - If \a element is the child of another element, it is re-parented - to this element. If \a element is a child of this element, then - its position in the list of children is changed. + If \a element is the child of another element, it is re-parented to this + element. If \a element is a child of this element, then its position in + the list of children is changed. Calling this function on a null element does nothing. @@ -1178,9 +984,9 @@ void QWebElement::appendInside(const QString &markup) /*! Prepends \a element as the element's first child. - If \a element is the child of another element, it is re-parented - to this element. If \a element is a child of this element, then - its position in the list of children is changed. + If \a element is the child of another element, it is re-parented to this + element. If \a element is a child of this element, then its position in + the list of children is changed. Calling this function on a null element does nothing. @@ -1227,10 +1033,10 @@ void QWebElement::prependInside(const QString &markup) /*! - Inserts \a element before this element. + Inserts the given \a element before this element. - If \a element is the child of another element, it is re-parented - to the parent of this element. + If \a element is the child of another element, it is re-parented to the + parent of this element. Calling this function on a null element does nothing. @@ -1274,10 +1080,10 @@ void QWebElement::prependOutside(const QString &markup) } /*! - Inserts \a element after this element. + Inserts the given \a element after this element. - If \a element is the child of another element, it is re-parented - to the parent of this element. + If \a element is the child of another element, it is re-parented to the + parent of this element. Calling this function on a null element does nothing. @@ -1342,13 +1148,12 @@ QWebElement QWebElement::clone() const } /*! - Removes this element from the document and returns a reference - to this. + Removes this element from the document and returns a reference to it. - The element is still valid after removal, and can be inserted into - other parts of the document. + The element is still valid after removal, and can be inserted into other + parts of the document. - \sa removeChildren(), removeFromDocument() + \sa removeAllChildren(), removeFromDocument() */ QWebElement &QWebElement::takeFromDocument() { @@ -1362,10 +1167,9 @@ QWebElement &QWebElement::takeFromDocument() } /*! - Removes this element from the document and makes this - a null element. + Removes this element from the document and makes it a null element. - \sa removeChildren(), takeFromDocument() + \sa removeAllChildren(), takeFromDocument() */ void QWebElement::removeFromDocument() { @@ -1383,7 +1187,7 @@ void QWebElement::removeFromDocument() \sa removeFromDocument(), takeFromDocument() */ -void QWebElement::removeChildren() +void QWebElement::removeAllChildren() { if (!m_element) return; @@ -1414,9 +1218,10 @@ static RefPtr<Node> findInsertionPoint(PassRefPtr<Node> root) } /*! - Enclose the contents of this element in \a element as the child - of the deepest descendant element within the structure of the - first element provided. + Encloses the contents of this element with \a element. This element becomes + the child of the deepest descendant within \a element. + + ### illustration \sa encloseWith() */ @@ -1446,9 +1251,8 @@ void QWebElement::encloseContentsWith(const QWebElement &element) } /*! - Enclose the contents of this element in the result of parsing - \a markup as the child of the deepest descendant element within - the structure of the first element provided. + Encloses the contents of this element with the result of parsing \a markup. + This element becomes the child of the deepest descendant within \a markup. \sa encloseWith() */ @@ -1490,9 +1294,8 @@ void QWebElement::encloseContentsWith(const QString &markup) } /*! - Enclose this element in \a element as the child of the deepest - descendant element within the structure of the first element - provided. + Encloses this element with \a element. This element becomes the child of + the deepest descendant within \a element. \sa replace() */ @@ -1523,8 +1326,8 @@ void QWebElement::encloseWith(const QWebElement &element) } /*! - Enclose this element in the result of parsing \a markup, - as the last child. + Encloses this element with the result of parsing \a markup. This element + becomes the child of the deepest descendant within \a markup. \sa replace() */ @@ -1569,8 +1372,7 @@ void QWebElement::encloseWith(const QString &markup) /*! Replaces this element with \a element. - It is not possible to replace the <html>, <head>, or <body> - elements using this method. + This method will not replace the <html>, <head> or <body> elements. \sa encloseWith() */ @@ -1586,8 +1388,7 @@ void QWebElement::replace(const QWebElement &element) /*! Replaces this element with the result of parsing \a markup. - It is not possible to replace the <html>, <head>, or <body> - elements using this method. + This method will not replace the <html>, <head> or <body> elements. \sa encloseWith() */ @@ -1601,13 +1402,629 @@ void QWebElement::replace(const QString &markup) } /*! + \internal + Walk \a node's parents until a valid QWebElement is found. + For example, a WebCore::Text node is not a valid Html QWebElement, but its + enclosing p tag is. +*/ +QWebElement QWebElement::enclosingElement(WebCore::Node* node) +{ + QWebElement element(node); + + while (element.isNull() && node) { + node = node->parentNode(); + element = QWebElement(node); + } + return element; +} + +/*! \fn inline bool QWebElement::operator==(const QWebElement& o) const; - Returns true if this element points to the same underlying DOM object than \a o; otherwise returns false. + Returns true if this element points to the same underlying DOM object as + \a o; otherwise returns false. */ /*! \fn inline bool QWebElement::operator!=(const QWebElement& o) const; - Returns true if this element points to a different underlying DOM object than \a o; otherwise returns false. + Returns true if this element points to a different underlying DOM object + than \a o; otherwise returns false. +*/ + + +/*! + Render the element into \a painter . +*/ +void QWebElement::render(QPainter* painter) +{ + WebCore::Element* e = m_element; + Document* doc = e ? e->document() : 0; + if (!doc) + return; + + Frame* frame = doc->frame(); + if (!frame || !frame->view() || !frame->contentRenderer()) + return; + + FrameView* view = frame->view(); + + view->layoutIfNeededRecursive(); + + IntRect rect = e->getRect(); + + if (rect.size().isEmpty()) + return; + + GraphicsContext context(painter); + + context.save(); + context.translate(-rect.x(), -rect.y()); + view->setNodeToDraw(e); + view->paintContents(&context, rect); + view->setNodeToDraw(0); + context.restore(); +} + +class QWebElementCollectionPrivate : public QSharedData +{ +public: + static QWebElementCollectionPrivate* create(const PassRefPtr<Node> &context, const QString &query); + + RefPtr<NodeList> m_result; + +private: + inline QWebElementCollectionPrivate() {} +}; + +QWebElementCollectionPrivate* QWebElementCollectionPrivate::create(const PassRefPtr<Node> &context, const QString &query) +{ + if (!context) + return 0; + + // Let WebKit do the hard work hehehe + ExceptionCode exception = 0; // ### + RefPtr<NodeList> nodes = context->querySelectorAll(query, exception); + if (!nodes) + return 0; + + QWebElementCollectionPrivate* priv = new QWebElementCollectionPrivate; + priv->m_result = nodes; + return priv; +} + +/*! + \class QWebElementCollection + \since 4.6 + \brief The QWebElementCollection class represents a collection of web elements. + \preliminary + + Elements in a document can be selected using QWebElement::findAll() or using the + QWebElement constructor. The collection is composed by choosing all elements in the + document that match a specified CSS selector expression. + + The number of selected elements is provided through the count() property. Individual + elements can be retrieved by index using at(). + + It is also possible to iterate through all elements in the collection using Qt's foreach + macro: + + \code + QWebElementCollection collection = document.findAll("p"); + foreach (QWebElement paraElement, collection) { + ... + } + \endcode +*/ + +/*! + Constructs an empty collection. +*/ +QWebElementCollection::QWebElementCollection() +{ +} + +/*! + Constructs a copy of \a other. +*/ +QWebElementCollection::QWebElementCollection(const QWebElementCollection &other) + : d(other.d) +{ +} + +/*! + Constructs a collection of elements from the list of child elements of \a contextElement that + match the specified CSS selector \a query. +*/ +QWebElementCollection::QWebElementCollection(const QWebElement &contextElement, const QString &query) +{ + d = QExplicitlySharedDataPointer<QWebElementCollectionPrivate>(QWebElementCollectionPrivate::create(contextElement.m_element, query)); +} + +/*! + Assigns \a other to this collection and returns a reference to this collection. +*/ +QWebElementCollection &QWebElementCollection::operator=(const QWebElementCollection &other) +{ + d = other.d; + return *this; +} + +/*! + Destroys the collection. +*/ +QWebElementCollection::~QWebElementCollection() +{ +} + +/*! \fn QWebElementCollection &QWebElementCollection::operator+=(const QWebElementCollection &other) + + Appends the items of the \a other list to this list and returns a + reference to this list. + + \sa operator+(), append() +*/ + +/*! + Returns a collection that contains all the elements of this collection followed + by all the elements in the \a other collection. Duplicates may occur in the result. + + \sa operator+=() +*/ +QWebElementCollection QWebElementCollection::operator+(const QWebElementCollection &other) const +{ + QWebElementCollection n = *this; n.d.detach(); n += other; return n; +} + +/*! + Extends the collection by appending all items of \a other. + + The resulting collection may include duplicate elements. + + \sa operator+=() +*/ +void QWebElementCollection::append(const QWebElementCollection &other) +{ + if (!d) { + *this = other; + return; + } + if (!other.d) + return; + Vector<RefPtr<Node> > nodes; + RefPtr<NodeList> results[] = { d->m_result, other.d->m_result }; + nodes.reserveInitialCapacity(results[0]->length() + results[1]->length()); + + for (int i = 0; i < 2; ++i) { + int j = 0; + Node* n = results[i]->item(j); + while (n) { + nodes.append(n); + n = results[i]->item(++j); + } + } + + d->m_result = StaticNodeList::adopt(nodes); +} + +/*! + Returns the number of elements in the collection. +*/ +int QWebElementCollection::count() const +{ + if (!d) + return 0; + return d->m_result->length(); +} + +/*! + Returns the element at index position \a i in the collection. +*/ +QWebElement QWebElementCollection::at(int i) const +{ + if (!d) + return QWebElement(); + Node* n = d->m_result->item(i); + return QWebElement(static_cast<Element*>(n)); +} + +/*! + \fn const QWebElement QWebElementCollection::operator[](int position) const + + Returns the element at the specified \a position in the collection. +*/ + +/*! \fn QWebElement QWebElementCollection::first() const + + Returns the first element in the collection. + + \sa last(), operator[](), at(), count() +*/ + +/*! \fn QWebElement QWebElementCollection::last() const + + Returns the last element in the collection. + + \sa first(), operator[](), at(), count() +*/ + +/*! + Returns a QList object with the elements contained in this collection. +*/ +QList<QWebElement> QWebElementCollection::toList() const +{ + if (!d) + return QList<QWebElement>(); + QList<QWebElement> elements; + int i = 0; + Node* n = d->m_result->item(i); + while (n) { + if (n->isElementNode()) + elements.append(QWebElement(static_cast<Element*>(n))); + n = d->m_result->item(++i); + } + return elements; +} + +/*! + \fn QWebElementCollection::const_iterator QWebElementCollection::begin() const + + Returns an STL-style iterator pointing to the first element in the collection. + + \sa end() +*/ + +/*! + \fn QWebElementCollection::const_iterator QWebElementCollection::end() const + + Returns an STL-style iterator pointing to the imaginary element after the + last element in the list. + + \sa begin() +*/ + +/*! + \class QWebElementCollection::const_iterator + \since 4.6 + \brief The QWebElementCollection::const_iterator class provides an STL-style const iterator for QWebElementCollection. + + QWebElementCollection provides STL style const iterators for fast low-level access to the elements. + + QWebElementCollection::const_iterator allows you to iterate over a QWebElementCollection. +*/ + +/*! + \fn QWebElementCollection::const_iterator::const_iterator(const const_iterator &other) + + Constructs a copy of \a other. +*/ + +/*! + \fn QWebElementCollection::const_iterator::const_iterator(const QWebElementCollection *collection, int index) + \internal +*/ + +/*! + \fn const QWebElement QWebElementCollection::const_iterator::operator*() const + + Returns the current element. +*/ + +/*! + \fn bool QWebElementCollection::const_iterator::operator==(const const_iterator &other) const + + Returns true if \a other points to the same item as this iterator; + otherwise returns false. + + \sa operator!=() +*/ + +/*! + \fn bool QWebElementCollection::const_iterator::operator!=(const const_iterator &other) const + + Returns true if \a other points to a different element than this; + iterator; otherwise returns false. + + \sa operator==() +*/ + +/*! + \fn QWebElementCollection::const_iterator &QWebElementCollection::const_iterator::operator++() + + The prefix ++ operator (\c{++it}) advances the iterator to the next element in the collection + and returns an iterator to the new current element. + + Calling this function on QWebElementCollection::end() leads to undefined results. + + \sa operator--() +*/ + +/*! + \fn QWebElementCollection::const_iterator QWebElementCollection::const_iterator::operator++(int) + + \overload + + The postfix ++ operator (\c{it++}) advances the iterator to the next element in the collection + and returns an iterator to the previously current element. + + Calling this function on QWebElementCollection::end() leads to undefined results. +*/ + +/*! + \fn QWebElementCollection::const_iterator &QWebElementCollection::const_iterator::operator--() + + The prefix -- operator (\c{--it}) makes the preceding element current and returns an + iterator to the new current element. + + Calling this function on QWebElementCollection::begin() leads to undefined results. + + \sa operator++() +*/ + +/*! + \fn QWebElementCollection::const_iterator QWebElementCollection::const_iterator::operator--(int) + + \overload + + The postfix -- operator (\c{it--}) makes the preceding element current and returns + an iterator to the previously current element. +*/ + +/*! + \fn QWebElementCollection::const_iterator &QWebElementCollection::const_iterator::operator+=(int j) + + Advances the iterator by \a j elements. If \a j is negative, the iterator goes backward. + + \sa operator-=(), operator+() +*/ + +/*! + \fn QWebElementCollection::const_iterator &QWebElementCollection::const_iterator::operator-=(int j) + + Makes the iterator go back by \a j elements. If \a j is negative, the iterator goes forward. + + \sa operator+=(), operator-() +*/ + +/*! + \fn QWebElementCollection::const_iterator QWebElementCollection::const_iterator::operator+(int j) const + + Returns an iterator to the element at \a j positions forward from this iterator. If \a j + is negative, the iterator goes backward. + + \sa operator-(), operator+=() +*/ + +/*! + \fn QWebElementCollection::const_iterator QWebElementCollection::const_iterator::operator-(int j) const + + Returns an iterator to the element at \a j positiosn backward from this iterator. + If \a j is negative, the iterator goes forward. + + \sa operator+(), operator-=() +*/ + +/*! + \fn int QWebElementCollection::const_iterator::operator-(const_iterator other) const + + Returns the number of elements between the item point to by \a other + and the element pointed to by this iterator. +*/ + +/*! + \fn bool QWebElementCollection::const_iterator::operator<(const const_iterator &other) const + + Returns true if the element pointed to by this iterator is less than the element pointed to + by the \a other iterator. +*/ + +/*! + \fn bool QWebElementCollection::const_iterator::operator<=(const const_iterator &other) const + + Returns true if the element pointed to by this iterator is less than or equal to the + element pointed to by the \a other iterator. +*/ + +/*! + \fn bool QWebElementCollection::const_iterator::operator>(const const_iterator &other) const + + Returns true if the element pointed to by this iterator is greater than the element pointed to + by the \a other iterator. +*/ + +/*! + \fn bool QWebElementCollection::const_iterator::operator>=(const const_iterator &other) const + + Returns true if the element pointed to by this iterator is greater than or equal to the + element pointed to by the \a other iterator. +*/ + +/*! + \fn QWebElementCollection::iterator QWebElementCollection::begin() + + Returns an STL-style iterator pointing to the first element in the collection. + + \sa end() +*/ + +/*! + \fn QWebElementCollection::iterator QWebElementCollection::end() + + Returns an STL-style iterator pointing to the imaginary element after the + last element in the list. + + \sa begin() +*/ + +/*! + \fn QWebElementCollection::const_iterator QWebElementCollection::constBegin() const + + Returns an STL-style iterator pointing to the first element in the collection. + + \sa end() +*/ + +/*! + \fn QWebElementCollection::const_iterator QWebElementCollection::constEnd() const + + Returns an STL-style iterator pointing to the imaginary element after the + last element in the list. + + \sa begin() +*/ + +/*! + \class QWebElementCollection::iterator + \since 4.6 + \brief The QWebElementCollection::iterator class provides an STL-style iterator for QWebElementCollection. + + QWebElementCollection provides STL style iterators for fast low-level access to the elements. + + QWebElementCollection::iterator allows you to iterate over a QWebElementCollection. +*/ + +/*! + \fn QWebElementCollection::iterator::iterator(const iterator &other) + + Constructs a copy of \a other. +*/ + +/*! + \fn QWebElementCollection::iterator::iterator(const QWebElementCollection *collection, int index) + \internal +*/ + +/*! + \fn const QWebElement QWebElementCollection::iterator::operator*() const + + Returns the current element. +*/ + +/*! + \fn bool QWebElementCollection::iterator::operator==(const iterator &other) const + + Returns true if \a other points to the same item as this iterator; + otherwise returns false. + + \sa operator!=() +*/ + +/*! + \fn bool QWebElementCollection::iterator::operator!=(const iterator &other) const + + Returns true if \a other points to a different element than this; + iterator; otherwise returns false. + + \sa operator==() +*/ + +/*! + \fn QWebElementCollection::iterator &QWebElementCollection::iterator::operator++() + + The prefix ++ operator (\c{++it}) advances the iterator to the next element in the collection + and returns an iterator to the new current element. + + Calling this function on QWebElementCollection::end() leads to undefined results. + + \sa operator--() +*/ + +/*! + \fn QWebElementCollection::iterator QWebElementCollection::iterator::operator++(int) + + \overload + + The postfix ++ operator (\c{it++}) advances the iterator to the next element in the collection + and returns an iterator to the previously current element. + + Calling this function on QWebElementCollection::end() leads to undefined results. +*/ + +/*! + \fn QWebElementCollection::iterator &QWebElementCollection::iterator::operator--() + + The prefix -- operator (\c{--it}) makes the preceding element current and returns an + iterator to the new current element. + + Calling this function on QWebElementCollection::begin() leads to undefined results. + + \sa operator++() +*/ + +/*! + \fn QWebElementCollection::iterator QWebElementCollection::iterator::operator--(int) + + \overload + + The postfix -- operator (\c{it--}) makes the preceding element current and returns + an iterator to the previously current element. +*/ + +/*! + \fn QWebElementCollection::iterator &QWebElementCollection::iterator::operator+=(int j) + + Advances the iterator by \a j elements. If \a j is negative, the iterator goes backward. + + \sa operator-=(), operator+() +*/ + +/*! + \fn QWebElementCollection::iterator &QWebElementCollection::iterator::operator-=(int j) + + Makes the iterator go back by \a j elements. If \a j is negative, the iterator goes forward. + + \sa operator+=(), operator-() +*/ + +/*! + \fn QWebElementCollection::iterator QWebElementCollection::iterator::operator+(int j) const + + Returns an iterator to the element at \a j positions forward from this iterator. If \a j + is negative, the iterator goes backward. + + \sa operator-(), operator+=() +*/ + +/*! + \fn QWebElementCollection::iterator QWebElementCollection::iterator::operator-(int j) const + + Returns an iterator to the element at \a j positiosn backward from this iterator. + If \a j is negative, the iterator goes forward. + + \sa operator+(), operator-=() +*/ + +/*! + \fn int QWebElementCollection::iterator::operator-(iterator other) const + + Returns the number of elements between the item point to by \a other + and the element pointed to by this iterator. +*/ + +/*! + \fn bool QWebElementCollection::iterator::operator<(const iterator &other) const + + Returns true if the element pointed to by this iterator is less than the element pointed to + by the \a other iterator. +*/ + +/*! + \fn bool QWebElementCollection::iterator::operator<=(const iterator &other) const + + Returns true if the element pointed to by this iterator is less than or equal to the + element pointed to by the \a other iterator. +*/ + +/*! + \fn bool QWebElementCollection::iterator::operator>(const iterator &other) const + + Returns true if the element pointed to by this iterator is greater than the element pointed to + by the \a other iterator. +*/ + +/*! + \fn bool QWebElementCollection::iterator::operator>=(const iterator &other) const + + Returns true if the element pointed to by this iterator is greater than or equal to the + element pointed to by the \a other iterator. */ diff --git a/WebKit/qt/Api/qwebelement.h b/WebKit/qt/Api/qwebelement.h index bc6f8a9..3833070 100644 --- a/WebKit/qt/Api/qwebelement.h +++ b/WebKit/qt/Api/qwebelement.h @@ -21,6 +21,7 @@ #define QWEBELEMENT_H #include <QString> +#include <QStringList> #include <QRect> #include <QVariant> #include <QExplicitlySharedDataPointer> @@ -31,7 +32,12 @@ namespace WebCore { class Node; } +QT_BEGIN_NAMESPACE +class QPainter; +QT_END_NAMESPACE + class QWebFrame; +class QWebElementCollection; class QWebElementPrivate; class QWEBKIT_EXPORT QWebElement { @@ -46,8 +52,8 @@ public: bool isNull() const; - QList<QWebElement> findAll(const QString& selectorQuery) const; - QWebElement findFirst(const QString& selectorQuery) const; + QWebElementCollection findAll(const QString &selectorQuery) const; + QWebElement findFirst(const QString &selectorQuery) const; void setPlainText(const QString& text); QString toPlainText() const; @@ -67,6 +73,7 @@ public: void removeAttribute(const QString& name); void removeAttributeNS(const QString& namespaceUri, const QString& name); bool hasAttributes() const; + QStringList attributeNames(const QString& namespaceUri = QString()) const; QStringList classes() const; bool hasClass(const QString& name) const; @@ -74,6 +81,9 @@ public: void removeClass(const QString& name); void toggleClass(const QString& name); + bool hasFocus() const; + void setFocus(); + QRect geometry() const; QString tagName() const; @@ -89,7 +99,7 @@ public: QWebElement document() const; QWebFrame *webFrame() const; - // TODO: Add QList<QWebElement> overloads + // TODO: Add QWebElementCollection overloads // docs need example snippet void appendInside(const QString& markup); void appendInside(const QWebElement& element); @@ -118,35 +128,131 @@ public: QWebElement clone() const; QWebElement& takeFromDocument(); void removeFromDocument(); - void removeChildren(); - - QVariant evaluateScript(const QString& scriptSource); + void removeAllChildren(); - QVariant callFunction(const QString& functionName, const QVariantList& arguments = QVariantList()); - QStringList functions() const; + QVariant evaluateJavaScript(const QString& scriptSource); - QVariant scriptableProperty(const QString& name) const; - void setScriptableProperty(const QString& name, const QVariant& value); - QStringList scriptableProperties() const; + enum StyleResolveStrategy { + InlineStyle, + CascadedStyle, + ComputedStyle, + }; + QString styleProperty(const QString& name, StyleResolveStrategy strategy) const; + void setStyleProperty(const QString& name, const QString& value); - enum ResolveRule { IgnoreCascadingStyles, RespectCascadingStyles }; - QString styleProperty(const QString& name, ResolveRule = IgnoreCascadingStyles) const; - - enum StylePriority { NormalStylePriority, DeclaredStylePriority, ImportantStylePriority }; - void setStyleProperty(const QString& name, const QString& value, StylePriority = DeclaredStylePriority); - - QString computedStyleProperty(const QString& name) const; + void render(QPainter* painter); private: explicit QWebElement(WebCore::Element*); explicit QWebElement(WebCore::Node*); + static QWebElement enclosingElement(WebCore::Node*); + friend class QWebFrame; + friend class QWebElementCollection; friend class QWebHitTestResult; friend class QWebHitTestResultPrivate; + friend class QWebPage; QWebElementPrivate* d; WebCore::Element* m_element; }; +class QWebElementCollectionPrivate; + +class QWEBKIT_EXPORT QWebElementCollection +{ +public: + QWebElementCollection(); + QWebElementCollection(const QWebElement &contextElement, const QString &query); + QWebElementCollection(const QWebElementCollection &); + QWebElementCollection &operator=(const QWebElementCollection &); + ~QWebElementCollection(); + + QWebElementCollection operator+(const QWebElementCollection &other) const; + inline QWebElementCollection &operator+=(const QWebElementCollection &other) + { + append(other); return *this; + } + + void append(const QWebElementCollection &collection); + + int count() const; + QWebElement at(int i) const; + inline QWebElement operator[](int i) const { return at(i); } + + inline QWebElement first() const { return at(0); } + inline QWebElement last() const { return at(count() - 1); } + + QList<QWebElement> toList() const; + + class const_iterator { + public: + inline const_iterator(const QWebElementCollection* collection, int index) : i(index), collection(collection) {} + inline const_iterator(const const_iterator& o) : i(o.i), collection(o.collection) {} + + inline const QWebElement operator*() const { return collection->at(i); } + + inline bool operator==(const const_iterator& o) const { return i == o.i && collection == o.collection; } + inline bool operator!=(const const_iterator& o) const { return i != o.i || collection != o.collection; } + inline bool operator<(const const_iterator& o) const { return i < o.i; } + inline bool operator<=(const const_iterator& o) const { return i <= o.i; } + inline bool operator>(const const_iterator& o) const { return i > o.i; } + inline bool operator>=(const const_iterator& o) const { return i >= o.i; } + + inline const_iterator& operator++() { ++i; return *this; } + inline const_iterator operator++(int) { const_iterator n(collection, i); ++i; return n; } + inline const_iterator& operator--() { i--; return *this; } + inline const_iterator operator--(int) { const_iterator n(collection, i); i--; return n; } + inline const_iterator& operator+=(int j) { i += j; return *this; } + inline const_iterator& operator-=(int j) { i -= j; return *this; } + inline const_iterator operator+(int j) const { return const_iterator(collection, i + j); } + inline const_iterator operator-(int j) const { return const_iterator(collection, i - j); } + inline int operator-(const_iterator j) const { return i - j.i; } + private: + int i; + const QWebElementCollection* const collection; + }; + friend class const_iterator; + + inline const_iterator begin() const { return constBegin(); } + inline const_iterator end() const { return constEnd(); } + inline const_iterator constBegin() const { return const_iterator(this, 0); } + inline const_iterator constEnd() const { return const_iterator(this, count()); }; + + class iterator { + public: + inline iterator(const QWebElementCollection* collection, int index) : i(index), collection(collection) {} + inline iterator(const iterator& o) : i(o.i), collection(o.collection) {} + + inline QWebElement operator*() const { return collection->at(i); } + + inline bool operator==(const iterator& o) const { return i == o.i && collection == o.collection; } + inline bool operator!=(const iterator& o) const { return i != o.i || collection != o.collection; } + inline bool operator<(const iterator& o) const { return i < o.i; } + inline bool operator<=(const iterator& o) const { return i <= o.i; } + inline bool operator>(const iterator& o) const { return i > o.i; } + inline bool operator>=(const iterator& o) const { return i >= o.i; } + + inline iterator& operator++() { ++i; return *this; } + inline iterator operator++(int) { iterator n(collection, i); ++i; return n; } + inline iterator& operator--() { i--; return *this; } + inline iterator operator--(int) { iterator n(collection, i); i--; return n; } + inline iterator& operator+=(int j) { i += j; return *this; } + inline iterator& operator-=(int j) { i -= j; return *this; } + inline iterator operator+(int j) const { return iterator(collection, i + j); } + inline iterator operator-(int j) const { return iterator(collection, i - j); } + inline int operator-(iterator j) const { return i - j.i; } + private: + int i; + const QWebElementCollection* const collection; + }; + friend class iterator; + + inline iterator begin() { return iterator(this, 0); } + inline iterator end() { return iterator(this, count()); } +private: + QExplicitlySharedDataPointer<QWebElementCollectionPrivate> d; +}; + #endif // QWEBELEMENT_H diff --git a/WebKit/qt/Api/qwebframe.cpp b/WebKit/qt/Api/qwebframe.cpp index c857df2..ef97c3b 100644 --- a/WebKit/qt/Api/qwebframe.cpp +++ b/WebKit/qt/Api/qwebframe.cpp @@ -56,6 +56,7 @@ #include "Scrollbar.h" #include "SelectionController.h" #include "SubstituteData.h" +#include "SVGSMILElement.h" #include "htmlediting.h" #include "markup.h" #include "qt_instance.h" @@ -77,14 +78,7 @@ #include <qpainter.h> #include <qprinter.h> #include <qregion.h> - -#if QT_VERSION < 0x040400 -#include "qwebnetworkinterface.h" -#endif - -#if QT_VERSION >= 0x040400 #include <qnetworkrequest.h> -#endif using namespace WebCore; @@ -93,6 +87,11 @@ QT_BEGIN_NAMESPACE extern Q_GUI_EXPORT int qt_defaultDpi(); QT_END_NAMESPACE +bool QWEBKIT_EXPORT qt_drt_hasDocumentElement(QWebFrame* qframe) +{ + return QWebFramePrivate::core(qframe)->document()->documentElement(); +} + void QWEBKIT_EXPORT qt_drt_setJavaScriptProfilingEnabled(QWebFrame* qframe, bool enabled) { #if ENABLE(JAVASCRIPT_DEBUGGER) @@ -150,6 +149,31 @@ bool QWEBKIT_EXPORT qt_drt_pauseTransitionOfProperty(QWebFrame *qframe, const QS return controller->pauseTransitionAtTime(coreNode->renderer(), propertyName, time); } +// Pause a given SVG animation on the target node at a specific time. +// This method is only intended to be used for testing the SVG animation system. +bool QWEBKIT_EXPORT qt_drt_pauseSVGAnimation(QWebFrame *qframe, const QString &animationId, double time, const QString &elementId) +{ +#if !ENABLE(SVG) + return false; +#else + Frame* frame = QWebFramePrivate::core(qframe); + if (!frame) + return false; + + Document* doc = frame->document(); + Q_ASSERT(doc); + + if (!doc->svgExtensions()) + return false; + + Node* coreNode = doc->getElementById(animationId); + if (!coreNode || !SVGSMILElement::isSMILElement(coreNode)) + return false; + + return doc->accessSVGExtensions()->sampleAnimationAtTime(elementId, static_cast<SVGSMILElement*>(coreNode), time); +#endif +} + // Returns the total number of currently running animations (includes both CSS transitions and CSS animations). int QWEBKIT_EXPORT qt_drt_numberOfActiveAnimations(QWebFrame *qframe) { @@ -185,6 +209,17 @@ void QWEBKIT_EXPORT qt_drt_garbageCollector_collectOnAlternateThread(bool waitUn gcController().garbageCollectOnAlternateThreadForDebugging(waitUntilDone); } +// Returns the value of counter in the element specified by \a id. +QString QWEBKIT_EXPORT qt_drt_counterValueForElementById(QWebFrame* qFrame, const QString& id) +{ + Frame* frame = QWebFramePrivate::core(qFrame); + if (Document* document = frame->document()) { + Element* element = document->getElementById(id); + return WebCore::counterValueForElement(element); + } + return QString(); +} + QWebFrameData::QWebFrameData(WebCore::Page* parentPage, WebCore::Frame* parentFrame, WebCore::HTMLFrameOwnerElement* ownerFrameElement, const WebCore::String& frameName) @@ -232,7 +267,7 @@ WebCore::Scrollbar* QWebFramePrivate::verticalScrollBar() const return frame->view()->verticalScrollbar(); } -void QWebFramePrivate::renderPrivate(QPainter *painter, const QRegion &clip) +void QWebFramePrivate::renderContentsLayerAbsoluteCoords(GraphicsContext* context, const QRegion& clip) { if (!frame->view() || !frame->contentRenderer()) return; @@ -241,24 +276,87 @@ void QWebFramePrivate::renderPrivate(QPainter *painter, const QRegion &clip) if (vector.isEmpty()) return; + QPainter* painter = context->platformContext(); + WebCore::FrameView* view = frame->view(); view->layoutIfNeededRecursive(); - GraphicsContext context(painter); + for (int i = 0; i < vector.size(); ++i) { + const QRect& clipRect = vector.at(i); - if (clipRenderToViewport) - view->paint(&context, vector.first()); - else - view->paintContents(&context, vector.first()); + painter->save(); + painter->setClipRect(clipRect, Qt::IntersectClip); + + context->save(); + view->paintContents(context, clipRect); + context->restore(); - for (int i = 1; i < vector.size(); ++i) { + painter->restore(); + } +} + +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); - if (clipRenderToViewport) - view->paint(&context, clipRect); - else - view->paintContents(&context, clipRect); + + 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(); } } @@ -268,6 +366,8 @@ void QWebFramePrivate::renderPrivate(QPainter *painter, const QRegion &clip) \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 @@ -277,7 +377,7 @@ void QWebFramePrivate::renderPrivate(QPainter *painter, const QRegion &clip) the HTML content readily available, you can use setHtml() instead. The page() function returns a pointer to the web page object. See - \l{Elements of QWebView} for an explanation of how web + \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 @@ -309,6 +409,19 @@ void QWebFramePrivate::renderPrivate(QPainter *painter, const QRegion &clip) \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) @@ -384,7 +497,7 @@ void QWebFrame::addToJavaScriptWindowObject(const QString &name, QObject *object return; JSC::JSLock lock(JSC::SilenceAssertionsOnly); - JSDOMWindow* window = toJSDOMWindow(d->frame); + JSDOMWindow* window = toJSDOMWindow(d->frame, mainThreadNormalWorld()); JSC::Bindings::RootObject* root = d->frame->script()->bindingRootObject(); if (!window) { qDebug() << "Warning: couldn't get window object"; @@ -424,7 +537,9 @@ QString QWebFrame::toPlainText() const d->frame->view()->layout(); Element *documentElement = d->frame->document()->documentElement(); - return documentElement->innerText(); + if (documentElement) + return documentElement->innerText(); + return QString(); } /*! @@ -436,7 +551,7 @@ QString QWebFrame::renderTreeDump() const if (d->frame->view() && d->frame->view()->layoutPending()) d->frame->view()->layout(); - return externalRepresentation(d->frame->contentRenderer()); + return externalRepresentation(d->frame); } /*! @@ -538,15 +653,26 @@ QUrl QWebFrame::url() const */ QUrl QWebFrame::requestedUrl() const { - // In the following edge cases (where the failing document - // loader does not get commited by the frame loader) it is - // safer to rely on outgoingReferrer than originalRequest. - if (!d->frame->loader()->activeDocumentLoader() - || (!d->frameLoaderClient->m_loadSucceeded - && !d->frame->loader()->outgoingReferrer().isEmpty())) - return QUrl(d->frame->loader()->outgoingReferrer()); + // 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 d->frame->loader()->originalRequest().url(); + return loader->originalRequest().url(); } /*! \since 4.6 @@ -597,51 +723,9 @@ QWebPage *QWebFrame::page() const */ void QWebFrame::load(const QUrl &url) { -#if QT_VERSION < 0x040400 - load(QWebNetworkRequest(ensureAbsoluteUrl(url))); -#else load(QNetworkRequest(ensureAbsoluteUrl(url))); -#endif } -#if QT_VERSION < 0x040400 -/*! - Loads a network request, \a req, into this frame. - - \note The view remains the same until enough data has arrived to display the new url. -*/ -void QWebFrame::load(const QWebNetworkRequest &req) -{ - if (d->parentFrame()) - d->page->d->insideOpenCall = true; - - QUrl url = ensureAbsoluteUrl(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, false); - - if (d->parentFrame()) - d->page->d->insideOpenCall = false; -} - -#else - /*! Loads a network request, \a req, into this frame, using the method specified in \a operation. @@ -676,6 +760,11 @@ void QWebFrame::load(const QNetworkRequest &req, case QNetworkAccessManager::PostOperation: request.setHTTPMethod("POST"); break; +#if QT_VERSION >= 0x040600 + case QNetworkAccessManager::DeleteOperation: + request.setHTTPMethod("DELETE"); + break; +#endif case QNetworkAccessManager::UnknownOperation: // eh? break; @@ -695,7 +784,6 @@ void QWebFrame::load(const QNetworkRequest &req, 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 @@ -708,7 +796,9 @@ void QWebFrame::load(const QNetworkRequest &req, 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. - \sa toHtml() + \note This method will not affect session or global history for the frame. + + \sa toHtml(), setContent() */ void QWebFrame::setHtml(const QString &html, const QUrl &baseUrl) { @@ -716,7 +806,7 @@ void QWebFrame::setHtml(const QString &html, const QUrl &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); + WebCore::SubstituteData substituteData(data, WebCore::String("text/html"), WebCore::String("utf-8"), KURL()); d->frame->loader()->load(request, substituteData, false); } @@ -729,7 +819,9 @@ void QWebFrame::setHtml(const QString &html, const QUrl &baseUrl) The \a data is loaded immediately; external objects are loaded asynchronously. - \sa toHtml() + \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) { @@ -739,11 +831,10 @@ void QWebFrame::setContent(const QByteArray &data, const QString &mimeType, cons QString actualMimeType = mimeType; if (actualMimeType.isEmpty()) actualMimeType = QLatin1String("text/html"); - WebCore::SubstituteData substituteData(buffer, WebCore::String(actualMimeType), WebCore::String(), kurl); + 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. @@ -801,13 +892,13 @@ void QWebFrame::setScrollBarPolicy(Qt::Orientation orientation, Qt::ScrollBarPol d->horizontalScrollBarPolicy = policy; if (d->frame->view()) { d->frame->view()->setHorizontalScrollbarMode((ScrollbarMode)policy); - d->frame->view()->updateDefaultScrollbarState(); + d->frame->view()->updateCanHaveScrollbars(); } } else { d->verticalScrollBarPolicy = policy; if (d->frame->view()) { d->frame->view()->setVerticalScrollbarMode((ScrollbarMode)policy); - d->frame->view()->updateDefaultScrollbarState(); + d->frame->view()->updateCanHaveScrollbars(); } } } @@ -873,6 +964,7 @@ int QWebFrame::scrollBarMaximum(Qt::Orientation orientation) const */ int QWebFrame::scrollBarMinimum(Qt::Orientation orientation) const { + Q_UNUSED(orientation) return 0; } @@ -931,44 +1023,49 @@ void QWebFrame::setScrollPosition(const QPoint &pos) } /*! - Render the frame into \a painter clipping to \a clip. + \since 4.6 + Render the \a layer of the frame using \a painter clipping to \a clip. \sa print() */ -void QWebFrame::render(QPainter *painter, const QRegion &clip) -{ - d->renderPrivate(painter, clip); -} -/*! - Render the frame into \a painter. -*/ -void QWebFrame::render(QPainter *painter) +void QWebFrame::render(QPainter* painter, RenderLayer layer, const QRegion& clip) { - if (!d->frame->view()) + GraphicsContext context(painter); + if (context.paintingDisabled() && !context.updatingControlTints()) return; - d->renderPrivate(painter, QRegion(d->frame->view()->frameRect())); + if (!clip.isEmpty()) + d->renderRelativeCoords(&context, layer, clip); + else if (d->frame->view()) + d->renderRelativeCoords(&context, layer, QRegion(d->frame->view()->frameRect())); } /*! - \since 4.6 - \property QWebFrame::clipRenderToViewport - - Returns true if render will clip content to viewport; otherwise returns false. + Render the frame into \a painter clipping to \a clip. */ -bool QWebFrame::clipRenderToViewport() const +void QWebFrame::render(QPainter* painter, const QRegion& clip) { - return d->clipRenderToViewport; + GraphicsContext context(painter); + if (context.paintingDisabled() && !context.updatingControlTints()) + return; + + d->renderRelativeCoords(&context, AllLayers, clip); } /*! - \since 4.6 - Sets whether the content of a frame will be clipped to viewport when rendered. + Render the frame into \a painter. */ -void QWebFrame::setClipRenderToViewport(bool clipRenderToViewport) +void QWebFrame::render(QPainter* painter) { - d->clipRenderToViewport = clipRenderToViewport; + if (!d->frame->view()) + return; + + GraphicsContext context(painter); + if (context.paintingDisabled() && !context.updatingControlTints()) + return; + + d->renderRelativeCoords(&context, AllLayers, QRegion(d->frame->view()->frameRect())); } /*! @@ -1024,7 +1121,8 @@ qreal QWebFrame::zoomFactor() const */ bool QWebFrame::hasFocus() const { - return QWebFramePrivate::kit(d->frame->page()->focusController()->focusedFrame()) == this; + WebCore::Frame* ff = d->frame->page()->focusController()->focusedFrame(); + return ff && QWebFramePrivate::kit(ff) == this; } /*! @@ -1098,7 +1196,7 @@ QWebElement QWebFrame::documentElement() const \sa QWebElement::findAll() */ -QList<QWebElement> QWebFrame::findAllElements(const QString &selectorQuery) const +QWebElementCollection QWebFrame::findAllElements(const QString &selectorQuery) const { return documentElement().findAll(selectorQuery); } @@ -1246,9 +1344,9 @@ QVariant QWebFrame::evaluateJavaScript(const QString& scriptSource) ScriptController *proxy = d->frame->script(); QVariant rc; if (proxy) { - JSC::JSValue v = proxy->evaluate(ScriptSourceCode(scriptSource)).jsValue(); + JSC::JSValue v = d->frame->script()->executeScript(ScriptSourceCode(scriptSource)).jsValue(); int distance = 0; - rc = JSC::Bindings::convertValueToQVariant(proxy->globalObject()->globalExec(), v, QMetaType::Void, &distance); + rc = JSC::Bindings::convertValueToQVariant(proxy->globalObject(mainThreadNormalWorld())->globalExec(), v, QMetaType::Void, &distance); } return rc; } @@ -1364,6 +1462,8 @@ QWebFrame* QWebFramePrivate::kit(WebCore::Frame* coreFrame) \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. */ @@ -1384,7 +1484,6 @@ QWebHitTestResultPrivate::QWebHitTestResultPrivate(const WebCore::HitTestResult if (!hitTest.innerNode()) return; pos = hitTest.point(); - boundingRect = hitTest.boundingBox(); WebCore::TextDirection dir; title = hitTest.title(dir); linkText = hitTest.textContent(); @@ -1394,6 +1493,7 @@ QWebHitTestResultPrivate::QWebHitTestResultPrivate(const WebCore::HitTestResult 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(); @@ -1641,4 +1741,3 @@ QWebFrame *QWebHitTestResult::frame() const return 0; return d->frame; } - diff --git a/WebKit/qt/Api/qwebframe.h b/WebKit/qt/Api/qwebframe.h index 55c73b4..c2a6e9b 100644 --- a/WebKit/qt/Api/qwebframe.h +++ b/WebKit/qt/Api/qwebframe.h @@ -26,9 +26,7 @@ #include <QtCore/qvariant.h> #include <QtGui/qicon.h> #include <QtScript/qscriptengine.h> -#if QT_VERSION >= 0x040400 #include <QtNetwork/qnetworkaccessmanager.h> -#endif #include "qwebkitglobal.h" QT_BEGIN_NAMESPACE @@ -50,6 +48,7 @@ class QWebHitTestResult; class QWebHistoryItem; class QWebSecurityOrigin; class QWebElement; +class QWebElementCollection; namespace WebCore { class WidgetPrivate; @@ -112,7 +111,6 @@ class QWEBKIT_EXPORT QWebFrame : public QObject { Q_PROPERTY(QIcon icon READ icon) Q_PROPERTY(QSize contentsSize READ contentsSize) Q_PROPERTY(QPoint scrollPosition READ scrollPosition WRITE setScrollPosition) - Q_PROPERTY(bool clipRenderToViewport READ clipRenderToViewport WRITE setClipRenderToViewport) Q_PROPERTY(bool focus READ hasFocus) private: QWebFrame(QWebPage *parent, QWebFrameData *frameData); @@ -123,13 +121,9 @@ public: QWebPage *page() const; void load(const QUrl &url); -#if QT_VERSION < 0x040400 - void load(const QWebNetworkRequest &request); -#else void load(const QNetworkRequest &request, QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation, const QByteArray &body = QByteArray()); -#endif void setHtml(const QString &html, const QUrl &baseUrl = QUrl()); void setContent(const QByteArray &data, const QString &mimeType = QString(), const QUrl &baseUrl = QUrl()); @@ -165,10 +159,17 @@ public: QPoint scrollPosition() const; void setScrollPosition(const QPoint &pos); - void render(QPainter *painter, const QRegion &clip); - void render(QPainter *painter); - bool clipRenderToViewport() const; - void setClipRenderToViewport(bool clipRenderToViewport); + enum RenderLayer { + ContentsLayer = 0x10, + ScrollBarLayer = 0x20, + PanIconLayer = 0x40, + + AllLayers = 0xff + }; + + void render(QPainter*); + void render(QPainter*, const QRegion& clip); + void render(QPainter*, RenderLayer layer, const QRegion& clip = QRegion()); void setTextSizeMultiplier(qreal factor); qreal textSizeMultiplier() const; @@ -184,7 +185,7 @@ public: QSize contentsSize() const; QWebElement documentElement() const; - QList<QWebElement> findAllElements(const QString &selectorQuery) const; + QWebElementCollection findAllElements(const QString &selectorQuery) const; QWebElement findFirstElement(const QString &selectorQuery) const; QWebHitTestResult hitTestContent(const QPoint &pos) const; diff --git a/WebKit/qt/Api/qwebframe_p.h b/WebKit/qt/Api/qwebframe_p.h index d6afc01..045c70e 100644 --- a/WebKit/qt/Api/qwebframe_p.h +++ b/WebKit/qt/Api/qwebframe_p.h @@ -25,6 +25,7 @@ #include "qwebpage_p.h" #include "EventHandler.h" +#include "GraphicsContext.h" #include "KURL.h" #include "PlatformString.h" #include "qwebelement.h" @@ -70,7 +71,6 @@ public: , allowsScrolling(true) , marginWidth(-1) , marginHeight(-1) - , clipRenderToViewport(true) {} void init(QWebFrame* qframe, QWebFrameData* frameData); @@ -79,15 +79,15 @@ public: WebCore::Scrollbar* horizontalScrollBar() const; WebCore::Scrollbar* verticalScrollBar() const; - Qt::ScrollBarPolicy horizontalScrollBarPolicy; - Qt::ScrollBarPolicy verticalScrollBarPolicy; - static WebCore::Frame* core(QWebFrame*); static QWebFrame* kit(WebCore::Frame*); - void renderPrivate(QPainter *painter, const QRegion &clip); + void renderRelativeCoords(WebCore::GraphicsContext*, QWebFrame::RenderLayer, const QRegion& clip); + void renderContentsLayerAbsoluteCoords(WebCore::GraphicsContext*, const QRegion& clip); QWebFrame *q; + Qt::ScrollBarPolicy horizontalScrollBarPolicy; + Qt::ScrollBarPolicy verticalScrollBarPolicy; WebCore::FrameLoaderClientQt *frameLoaderClient; WebCore::Frame *frame; QWebPage *page; @@ -95,7 +95,6 @@ public: bool allowsScrolling; int marginWidth; int marginHeight; - bool clipRenderToViewport; }; class QWebHitTestResultPrivate { diff --git a/WebKit/qt/Api/qwebhistory.cpp b/WebKit/qt/Api/qwebhistory.cpp index 1c1c72a..d852012 100644 --- a/WebKit/qt/Api/qwebhistory.cpp +++ b/WebKit/qt/Api/qwebhistory.cpp @@ -20,6 +20,7 @@ #include "config.h" #include "qwebhistory.h" #include "qwebhistory_p.h" +#include "qwebframe_p.h" #include "PlatformString.h" #include "Image.h" @@ -30,11 +31,18 @@ #include <QSharedData> #include <QDebug> +enum { + InitialHistoryVersion = 1, + DefaultHistoryVersion = InitialHistoryVersion +}; + /*! \class QWebHistoryItem \since 4.4 \brief The QWebHistoryItem class represents one item in the history of a QWebPage + \inmodule QtWebKit + Each QWebHistoryItem instance represents an entry in the history stack of a Web page, containing information about the page, its location, and when it was last visited. @@ -201,6 +209,8 @@ bool QWebHistoryItem::isValid() const \since 4.4 \brief The QWebHistory class represents the history of a QWebPage + \inmodule QtWebKit + Each QWebPage instance contains a history of visited pages that can be accessed by QWebPage::history(). QWebHistory represents this history and makes it possible to navigate it. @@ -221,7 +231,8 @@ bool QWebHistoryItem::isValid() const number of items is given by count(), and the history can be cleared with the clear() function. - QWebHistory's state can be saved with saveState() and loaded with restoreState(). + QWebHistory's state can be saved to a QDataStream using the >> operator and loaded + by using the << operator. \sa QWebHistoryItem, QWebHistoryInterface, QWebPage */ @@ -244,17 +255,27 @@ QWebHistory::~QWebHistory() */ void QWebHistory::clear() { - RefPtr<WebCore::HistoryItem> current = d->lst->currentItem(); - int capacity = d->lst->capacity(); - d->lst->setCapacity(0); + //shortcut to private BackForwardList + WebCore::BackForwardList* lst = d->lst; - WebCore::Page* page = d->lst->page(); + //clear visited links + WebCore::Page* page = lst->page(); if (page && page->groupPtr()) page->groupPtr()->removeVisitedLinks(); - d->lst->setCapacity(capacity); - d->lst->addItem(current.get()); - d->lst->goToItem(current.get()); + //if count() == 0 then just return + if (!lst->entries().size()) + return; + + RefPtr<WebCore::HistoryItem> current = lst->currentItem(); + int capacity = lst->capacity(); + lst->setCapacity(0); + + lst->setCapacity(capacity); //revert capacity + lst->addItem(current.get()); //insert old current item + lst->goToItem(current.get()); //and set it as current again + + d->page()->updateNavigationActions(); } /*! @@ -267,7 +288,7 @@ QList<QWebHistoryItem> QWebHistory::items() const const WebCore::HistoryItemVector &items = d->lst->entries(); QList<QWebHistoryItem> ret; - for (int i = 0; i < items.size(); ++i) { + for (unsigned i = 0; i < items.size(); ++i) { QWebHistoryItemPrivate *priv = new QWebHistoryItemPrivate(items[i].get()); ret.append(QWebHistoryItem(priv)); } @@ -286,7 +307,7 @@ QList<QWebHistoryItem> QWebHistory::backItems(int maxItems) const d->lst->backListWithLimit(maxItems, items); QList<QWebHistoryItem> ret; - for (int i = 0; i < items.size(); ++i) { + for (unsigned i = 0; i < items.size(); ++i) { QWebHistoryItemPrivate *priv = new QWebHistoryItemPrivate(items[i].get()); ret.append(QWebHistoryItem(priv)); } @@ -305,7 +326,7 @@ QList<QWebHistoryItem> QWebHistory::forwardItems(int maxItems) const d->lst->forwardListWithLimit(maxItems, items); QList<QWebHistoryItem> ret; - for (int i = 0; i < items.size(); ++i) { + for (unsigned i = 0; i < items.size(); ++i) { QWebHistoryItemPrivate *priv = new QWebHistoryItemPrivate(items[i].get()); ret.append(QWebHistoryItem(priv)); } @@ -341,9 +362,11 @@ bool QWebHistory::canGoForward() const */ void QWebHistory::back() { - d->lst->goBack(); - WebCore::Page* page = d->lst->page(); - page->goToItem(currentItem().d->item, WebCore::FrameLoadTypeIndexedBackForward); + if (canGoBack()) { + d->lst->goBack(); + WebCore::Page* page = d->lst->page(); + page->goToItem(currentItem().d->item, WebCore::FrameLoadTypeIndexedBackForward); + } } /*! @@ -354,9 +377,11 @@ void QWebHistory::back() */ void QWebHistory::forward() { - d->lst->goForward(); - WebCore::Page* page = d->lst->page(); - page->goToItem(currentItem().d->item, WebCore::FrameLoadTypeIndexedBackForward); + if (canGoForward()) { + d->lst->goForward(); + WebCore::Page* page = d->lst->page(); + page->goToItem(currentItem().d->item, WebCore::FrameLoadTypeIndexedBackForward); + } } /*! @@ -456,128 +481,75 @@ void QWebHistory::setMaximumItemCount(int count) } /*! - \enum QWebHistory::HistoryStateVersion + \since 4.6 + \fn QDataStream& operator<<(QDataStream& stream, const QWebHistory& history) + \relates QWebHistory - This enum describes the versions available for QWebHistory's saveState() function: + \brief The operator<< function streams a history into a data stream. - \value HistoryVersion_1 Version 1 (Qt 4.6) - \value DefaultHistoryVersion The current default version in 1. + It saves the \a history into the specified \a stream. */ +QDataStream& operator<<(QDataStream& target, const QWebHistory& history) +{ + QWebHistoryPrivate* d = history.d; + + int version = DefaultHistoryVersion; + + target << version; + target << history.count() << history.currentItemIndex(); + + const WebCore::HistoryItemVector &items = d->lst->entries(); + for (unsigned i = 0; i < items.size(); i++) + items[i].get()->saveState(target, version); + + return target; +} + /*! + \fn QDataStream& operator>>(QDataStream& stream, QWebHistory& history) + \relates QWebHistory \since 4.6 - Restores the state of QWebHistory from the given \a buffer. Returns true - if the history was successfully restored; otherwise returns false. + \brief The operator>> function loads a history from a data stream. - \sa saveState() + Loads a QWebHistory from the specified \a stream into the given \a history. */ -bool QWebHistory::restoreState(const QByteArray& buffer) + +QDataStream& operator>>(QDataStream& source, QWebHistory& history) { - QDataStream stream(buffer); + QWebHistoryPrivate* d = history.d; + int version; - bool result = false; - stream >> version; - switch (version) { - case HistoryVersion_1: { + source >> version; + + if (version == 1) { int count; int currentIndex; - stream >> count >> currentIndex; + source >> count >> currentIndex; - clear(); + history.clear(); // only if there are elements if (count) { // after clear() is new clear HistoryItem (at the end we had to remove it) - WebCore::HistoryItem *nullItem = d->lst->currentItem(); - for (int i = 0;i < count;i++) { + WebCore::HistoryItem* nullItem = d->lst->currentItem(); + for (int i = 0; i < count; i++) { WTF::PassRefPtr<WebCore::HistoryItem> item = WebCore::HistoryItem::create(); - item->restoreState(stream, version); + item->restoreState(source, version); d->lst->addItem(item); } d->lst->removeItem(nullItem); - goToItem(itemAt(currentIndex)); - result = stream.status() == QDataStream::Ok; + history.goToItem(history.itemAt(currentIndex)); } - break; - } - default: {} // result is false; } - return result; -}; + d->page()->updateNavigationActions(); -/*! - \since 4.6 - Saves the state of this QWebHistory into a QByteArray. - - Saves the current state of this QWebHistory. The version number, \a version, is - stored as part of the data. - - To restore the saved state, pass the return value to restoreState(). - - \sa restoreState() -*/ -QByteArray QWebHistory::saveState(HistoryStateVersion version) const -{ - QByteArray buffer; - QDataStream stream(&buffer, QIODevice::WriteOnly); - stream << version; - - switch (version) { - case HistoryVersion_1: { - stream << count() << currentItemIndex(); - - const WebCore::HistoryItemVector &items = d->lst->entries(); - for (int i = 0; i < items.size(); i++) - items[i].get()->saveState(stream, version); - - if (stream.status() != QDataStream::Ok) - buffer = QByteArray(); // make buffer isNull()==true and isEmpty()==true - break; - } - default: - buffer.clear(); - - } - - return buffer; -} - -/*! - \since 4.6 - \fn QDataStream& operator<<(QDataStream& stream, const QWebHistory& history) - \relates QWebHistory - - Saves the given \a history into the specified \a stream. This is a convenience function - and is equivalent to calling the saveState() method. - - \sa QWebHistory::saveState() -*/ - -QDataStream& operator<<(QDataStream& stream, const QWebHistory& history) -{ - return stream << history.saveState(); + return source; } -/*! - \fn QDataStream& operator>>(QDataStream& stream, QWebHistory& history) - \relates QWebHistory - \since 4.6 - - Loads a QWebHistory from the specified \a stream into the given \a history. - This is a convenience function and it is equivalent to calling the restoreState() - method. - - \sa QWebHistory::restoreState() -*/ - -QDataStream& operator>>(QDataStream& stream, QWebHistory& history) +QWebPagePrivate* QWebHistoryPrivate::page() { - QByteArray buffer; - stream >> buffer; - history.restoreState(buffer); - return stream; + return QWebFramePrivate::kit(lst->page()->mainFrame())->page()->handle(); } - - diff --git a/WebKit/qt/Api/qwebhistory.h b/WebKit/qt/Api/qwebhistory.h index e46f124..cce4553 100644 --- a/WebKit/qt/Api/qwebhistory.h +++ b/WebKit/qt/Api/qwebhistory.h @@ -42,9 +42,6 @@ public: QWebHistoryItem &operator=(const QWebHistoryItem &other); ~QWebHistoryItem(); - //bool restoreState(QByteArray& buffer); - //QByteArray saveState(QWebHistory::HistoryStateVersion version = DefaultHistoryVersion) const; - QUrl originalUrl() const; QUrl url() const; @@ -69,22 +66,10 @@ private: QExplicitlySharedDataPointer<QWebHistoryItemPrivate> d; }; -//QWEBKIT_EXPORT QDataStream & operator<<(QDataStream& out,const QWebHistoryItem& hist); -//QWEBKIT_EXPORT QDataStream & operator>>(QDataStream& in,QWebHistoryItem& hist); - class QWebHistoryPrivate; class QWEBKIT_EXPORT QWebHistory { public: - enum HistoryStateVersion { - HistoryVersion_1, - /*, HistoryVersion_2, */ - DefaultHistoryVersion = HistoryVersion_1 - }; - - bool restoreState(const QByteArray& buffer); - QByteArray saveState(HistoryStateVersion version = DefaultHistoryVersion) const; - void clear(); QList<QWebHistoryItem> items() const; diff --git a/WebKit/qt/Api/qwebhistory_p.h b/WebKit/qt/Api/qwebhistory_p.h index e77adef..a6682cd 100644 --- a/WebKit/qt/Api/qwebhistory_p.h +++ b/WebKit/qt/Api/qwebhistory_p.h @@ -25,13 +25,15 @@ #include <QtCore/qglobal.h> #include <QtCore/qshareddata.h> +class QWebPagePrivate; + class Q_AUTOTEST_EXPORT QWebHistoryItemPrivate : public QSharedData { public: - static QExplicitlySharedDataPointer<QWebHistoryItemPrivate> get(QWebHistoryItem *q) + static QExplicitlySharedDataPointer<QWebHistoryItemPrivate> get(QWebHistoryItem* q) { return q->d; } - QWebHistoryItemPrivate(WebCore::HistoryItem *i) + QWebHistoryItemPrivate(WebCore::HistoryItem* i) { if (i) i->ref(); @@ -43,30 +45,12 @@ public: item->deref(); } - /* QByteArray saveStateWithoutVersionControl(QWebHistory::HistoryStateVersion version) - { - QByteArray buffer; - switch(version){ - case QWebHistory::HistoryVersion1: - buffer=item->saveState(version); - break; - default:{} - } - return buffer; - } - - bool restoreStateWithoutVersionControl(QWebHistory::HistoryStateVersion version,QDataStream& stream) - { - - } -*/ - - WebCore::HistoryItem *item; + WebCore::HistoryItem* item; }; class QWebHistoryPrivate : public QSharedData { public: - QWebHistoryPrivate(WebCore::BackForwardList *l) + QWebHistoryPrivate(WebCore::BackForwardList* l) { l->ref(); lst = l; @@ -75,7 +59,10 @@ public: { lst->deref(); } - WebCore::BackForwardList *lst; + + QWebPagePrivate* page(); + + WebCore::BackForwardList* lst; }; diff --git a/WebKit/qt/Api/qwebhistoryinterface.cpp b/WebKit/qt/Api/qwebhistoryinterface.cpp index 87d52ce..80567d1 100644 --- a/WebKit/qt/Api/qwebhistoryinterface.cpp +++ b/WebKit/qt/Api/qwebhistoryinterface.cpp @@ -81,6 +81,8 @@ QWebHistoryInterface* QWebHistoryInterface::defaultInterface() \since 4.4 \brief The QWebHistoryInterface class provides an interface to implement link history. + \inmodule QtWebKit + The QWebHistoryInterface is an interface that can be used to implement link history. It contains two pure virtual methods that are called by the WebKit engine. addHistoryEntry() is used to add diff --git a/WebKit/qt/Api/qwebinspector.cpp b/WebKit/qt/Api/qwebinspector.cpp new file mode 100644 index 0000000..f43cbbf --- /dev/null +++ b/WebKit/qt/Api/qwebinspector.cpp @@ -0,0 +1,186 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + 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 "qwebinspector.h" + +#include "Element.h" +#include "InspectorController.h" +#include "qwebelement.h" +#include "qwebinspector_p.h" +#include "qwebpage_p.h" + +#include <QResizeEvent> + +/*! + \class QWebInspector + \since 4.6 + \brief The QWebInspector class allows the placement and control of a + QWebPage's inspector. + The inspector allows you to see a page current hierarchy and loading + statistics. + + The QWebPage to be inspected is determined with the setPage() method. + + A typical use of QWebInspector follows: + + \snippet webkitsnippets/qtwebkit_qwebinspector_snippet.cpp 0 + + \note A QWebInspector will display a blank widget if either: + \list + \o page() is null + \o QWebSettings::DeveloperExtrasEnabled is false + \endlist + + \section1 Resources + + This class acts mostly as a container and a controller for the inspector. + Most of the resources needed by the inspector are owned by the associated + QWebPage and are allocated the first time that: + \list + \o an element is inspected + \o the QWebInspector is shown. + \endlist + + \section1 Inspector configuration persistence + + The inspector allows the user to configure some options through its + interface (e.g. the resource tracking "Always enable" option). + These settings are persisted automatically by QtWebKit using QSettings. + + However since the QSettings object is instantiated using the empty + constructor, QCoreApplication::setOrganizationName() and + QCoreApplication::setApplicationName() must be called within your + application to enable the persistence of these options. +*/ + +/*! + Constructs an empty QWebInspector with parent \a parent. +*/ +QWebInspector::QWebInspector(QWidget* parent) + : QWidget(parent) + , d(new QWebInspectorPrivate(this)) +{ +} + +/*! + Destroys the inspector. +*/ +QWebInspector::~QWebInspector() +{ + // Remove association principally to prevent deleting a child frontend + setPage(0); +} + +/*! + Sets the QWebPage to be inspected. + + There can only be one QWebInspector associated with a QWebPage + and vices versa. + + Calling with \a page as null will break the current association, if any. + + If \a page is already associated to another QWebInspector, the association + will be replaced and the previous QWebInspector will have no page + associated. + + \sa page() +*/ +void QWebInspector::setPage(QWebPage* page) +{ + if (d->page) { + // Break currentPage-->this + d->page->d->setInspector(0); + } + if (page && page->d->inspector && page->d->inspector != this) { + // Break newPage<->newPageCurrentInspector + page->d->inspector->setPage(0); + } + + d->page = page; + + if (page) { + // Setup the reciprocal association + page->d->setInspector(this); + } +} + +/*! + Returns the inspected QWebPage. + If no web page is currently associated, a null pointer is returned. +*/ +QWebPage* QWebInspector::page() const +{ + return d->page; +} + +/*! \reimp */ +QSize QWebInspector::sizeHint() const +{ + return QSize(450, 300); +} + +/*! \reimp */ +bool QWebInspector::event(QEvent* ev) +{ + return QWidget::event(ev); +} + +/*! \reimp */ +void QWebInspector::resizeEvent(QResizeEvent* event) +{ + d->adjustFrontendSize(event->size()); +} + +/*! \reimp */ +void QWebInspector::showEvent(QShowEvent* event) +{ + // Allows QWebInspector::show() to init the inspector. + if (d->page) + d->page->d->inspectorController()->show(); +} + +/*! \reimp */ +void QWebInspector::hideEvent(QHideEvent* event) +{ + if (d->page) + d->page->d->inspectorController()->setWindowVisible(false); +} + +/*! \internal */ +void QWebInspectorPrivate::setFrontend(QWidget* newFrontend) +{ + if (frontend) + frontend->setParent(0); + + frontend = newFrontend; + + if (frontend) { + frontend->setParent(q); + frontend->show(); + adjustFrontendSize(q->size()); + } +} + +void QWebInspectorPrivate::adjustFrontendSize(const QSize& size) +{ + if (frontend) + frontend->resize(size); +} + diff --git a/WebKit/qt/Api/qcookiejar.h b/WebKit/qt/Api/qwebinspector.h index 7885cc1..a5c1ed5 100644 --- a/WebKit/qt/Api/qcookiejar.h +++ b/WebKit/qt/Api/qwebinspector.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2007 Staikos Computing Services Inc. + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -17,38 +17,39 @@ Boston, MA 02110-1301, USA. */ -#ifndef QCOOKIEJAR_H -#define QCOOKIEJAR_H +#ifndef QWEBINSPECTOR_H +#define QWEBINSPECTOR_H -#include <QtCore/qobject.h> -#include <QtCore/qurl.h> #include "qwebkitglobal.h" +#include "qwebpage.h" -class QCookieJarPrivate; +#include "qwebview.h" -class QWEBKIT_EXPORT QCookieJar : public QObject { - Q_OBJECT +class QWebInspectorPrivate; - Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) +class QWEBKIT_EXPORT QWebInspector : public QWidget { + Q_OBJECT public: - QCookieJar(); - ~QCookieJar(); - - virtual void setCookies(const QUrl& url, const QUrl& policyUrl, const QString& value); - virtual QString cookies(const QUrl& url); + QWebInspector(QWidget* parent = 0); + ~QWebInspector(); - bool isEnabled() const; + void setPage(QWebPage* page); + QWebPage* page() const; - static void setCookieJar(QCookieJar* jar); - static QCookieJar* cookieJar(); + QSize sizeHint() const; + bool event(QEvent*); -public slots: - virtual void setEnabled(bool enabled); +protected: + void resizeEvent(QResizeEvent* event); + void showEvent(QShowEvent* event); + void hideEvent(QHideEvent* event); private: - friend class QCookieJarPrivate; - QCookieJarPrivate* d; -}; - + QWebInspectorPrivate* d; + friend class QWebInspectorPrivate; + friend class QWebPage; + friend class QWebPagePrivate; + friend class WebCore::InspectorClientQt; +}; #endif diff --git a/WebKit/qt/Api/qwebinspector_p.h b/WebKit/qt/Api/qwebinspector_p.h new file mode 100644 index 0000000..4d327cc --- /dev/null +++ b/WebKit/qt/Api/qwebinspector_p.h @@ -0,0 +1,46 @@ +/* + Copyright (C) 2008, 2009 Nokia Corporation and/or its subsidiary(-ies) + + 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. +*/ + +#ifndef QWEBINSPECTOR_P_H +#define QWEBINSPECTOR_P_H + +QT_BEGIN_NAMESPACE +class QSize; +class QWidget; +QT_END_NAMESPACE +class QWebInspector; +class QWebPage; + +class QWebInspectorPrivate { +public: + QWebInspectorPrivate(QWebInspector* qq) + : q(qq) + , page(0) + , frontend(0) + {} + + void setFrontend(QWidget* newFrontend); + void adjustFrontendSize(const QSize& size); + + QWebInspector* q; + QWebPage* page; + QWidget* frontend; +}; + +#endif diff --git a/WebKit/qt/Api/qwebkitglobal.h b/WebKit/qt/Api/qwebkitglobal.h index 0885bdc..9e8979f 100644 --- a/WebKit/qt/Api/qwebkitglobal.h +++ b/WebKit/qt/Api/qwebkitglobal.h @@ -40,15 +40,4 @@ # endif #endif -#if QT_VERSION < 0x040400 - #ifndef QT_BEGIN_NAMESPACE - #define QT_BEGIN_NAMESPACE - #endif - - #ifndef QT_END_NAMESPACE - #define QT_END_NAMESPACE - #endif -#endif - - #endif // QWEBKITGLOBAL_H diff --git a/WebKit/qt/Api/qwebnetworkinterface.cpp b/WebKit/qt/Api/qwebnetworkinterface.cpp deleted file mode 100644 index cf99183..0000000 --- a/WebKit/qt/Api/qwebnetworkinterface.cpp +++ /dev/null @@ -1,1315 +0,0 @@ -/* - Copyright (C) 2006 Enrico Ros <enrico.ros@m31engineering.it> - Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) - Copyright (C) 2007 Staikos Computing Services Inc. <info@staikos.net> - - 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 <qglobal.h> -#if QT_VERSION < 0x040400 -#include "qwebframe.h" -#include "qwebnetworkinterface.h" -#include "qwebnetworkinterface_p.h" -#include "qwebpage.h" -#include "qcookiejar.h" -#include <qdebug.h> -#include <qfile.h> -#include <qnetworkproxy.h> -#include <qurl.h> -#include <QAuthenticator> -#include <QCoreApplication> -#include <QSslError> - -#include "ResourceHandle.h" -#include "ResourceHandleClient.h" -#include "ResourceHandleInternal.h" -#include "MIMETypeRegistry.h" -#include "CookieJar.h" - -#if 0 -#define DEBUG qDebug -#else -#define DEBUG if (1) {} else qDebug -#endif - -static QWebNetworkInterface *s_default_interface = 0; -static QWebNetworkManager *s_manager = 0; - -using namespace WebCore; - -uint qHash(const HostInfo &info) -{ - return qHash(info.host) + info.port; -} - -static bool operator==(const HostInfo &i1, const HostInfo &i2) -{ - return i1.port == i2.port && i1.host == i2.host; -} - -enum ParserState { - State_Begin, - State_FirstChar, - State_SecondChar -}; - -/* - * Decode URLs without doing any charset conversion. - * - * Most simple approach to do it without any lookahead. - */ -static QByteArray decodePercentEncoding(const QByteArray& input) -{ - int actualLength = 0; - QByteArray tmpVal; - QByteArray output; - ParserState state = State_Begin; - - output.resize(input.length()); - tmpVal.resize(2); - - for (int i = 0; i < input.length(); ++i) - if (state == State_Begin) { - if (input.at(i) == '%') - state = State_FirstChar; - else - output[actualLength++] = input[i]; - } else if (state == State_FirstChar) { - state = State_SecondChar; - tmpVal[0] = input[i]; - } else if (state == State_SecondChar) { - state = State_Begin; - tmpVal[1] = input[i]; - output[actualLength++] = tmpVal.toShort(0, 16); - } - - output.resize(actualLength); - return output; -} - -void QWebNetworkRequestPrivate::init(const WebCore::ResourceRequest &resourceRequest) -{ - KURL url = resourceRequest.url(); - QUrl qurl = QString(url.string()); - init(resourceRequest.httpMethod(), qurl, &resourceRequest); -} - -void QWebNetworkRequestPrivate::init(const QString& method, const QUrl& url, const WebCore::ResourceRequest* resourceRequest) -{ - httpHeader = QHttpRequestHeader(method, url.toString(QUrl::RemoveScheme|QUrl::RemoveAuthority)); - httpHeader.setValue(QLatin1String("Connection"), QLatin1String("Keep-Alive")); - setURL(url); - - if (resourceRequest) { - httpHeader.setValue(QLatin1String("User-Agent"), resourceRequest->httpUserAgent()); - const QString scheme = url.scheme().toLower(); - if (scheme == QLatin1String("http") || scheme == QLatin1String("https")) { - QString cookies = QCookieJar::cookieJar()->cookies(resourceRequest->url()); - if (!cookies.isEmpty()) - httpHeader.setValue(QLatin1String("Cookie"), cookies); - } - - - const HTTPHeaderMap& loaderHeaders = resourceRequest->httpHeaderFields(); - HTTPHeaderMap::const_iterator end = loaderHeaders.end(); - for (HTTPHeaderMap::const_iterator it = loaderHeaders.begin(); it != end; ++it) - httpHeader.setValue(it->first, it->second); - - // handle and perform a 'POST' request - if (method == "POST") { - Vector<char> data; - resourceRequest->httpBody()->flatten(data); - postData = QByteArray(data.data(), data.size()); - httpHeader.setValue(QLatin1String("content-length"), QString::number(postData.size())); - } - } -} - -void QWebNetworkRequestPrivate::setURL(const QUrl& u) -{ - url = u; - int port = url.port(); - const QString scheme = u.scheme(); - if (port > 0 && (port != 80 || scheme != "http") && (port != 443 || scheme != "https")) - httpHeader.setValue(QLatin1String("Host"), url.host() + QLatin1Char(':') + QString::number(port)); - else - httpHeader.setValue(QLatin1String("Host"), url.host()); -} - -/*! - \class QWebNetworkRequest - \internal - - The QWebNetworkRequest class represents a request for data from the network with all the - necessary information needed for retrieval. This includes the url, extra HTTP header fields - as well as data for a HTTP POST request. -*/ - -QWebNetworkRequest::QWebNetworkRequest() - : d(new QWebNetworkRequestPrivate) -{ -} - -QWebNetworkRequest::QWebNetworkRequest(const QUrl& url, Method method, const QByteArray& postData) - : d(new QWebNetworkRequestPrivate) -{ - d->init(method == Get ? "GET" : "POST", url); - d->postData = postData; -} - -QWebNetworkRequest::QWebNetworkRequest(const QWebNetworkRequest &other) - : d(new QWebNetworkRequestPrivate(*other.d)) -{ -} - -QWebNetworkRequest &QWebNetworkRequest::operator=(const QWebNetworkRequest& other) -{ - *d = *other.d; - return *this; -} - -/*! - \internal -*/ -QWebNetworkRequest::QWebNetworkRequest(const QWebNetworkRequestPrivate& priv) - : d(new QWebNetworkRequestPrivate(priv)) -{ -} - -/*! - \internal -*/ -QWebNetworkRequest::QWebNetworkRequest(const WebCore::ResourceRequest& request) - : d(new QWebNetworkRequestPrivate) -{ - d->init(request); -} - -QWebNetworkRequest::~QWebNetworkRequest() -{ - delete d; -} - -/*! - \internal - The requested URL -*/ -QUrl QWebNetworkRequest::url() const -{ - return d->url; -} - -/*! - \internal - Sets the URL to request. - - Note that setting the URL also sets the "Host" field in the HTTP header. -*/ -void QWebNetworkRequest::setUrl(const QUrl& url) -{ - d->setURL(url); -} - -/*! - \internal - The http request header information. -*/ -QHttpRequestHeader QWebNetworkRequest::httpHeader() const -{ - return d->httpHeader; -} - -void QWebNetworkRequest::setHttpHeader(const QHttpRequestHeader& header) const -{ - d->httpHeader = header; -} - -QString QWebNetworkRequest::httpHeaderField(const QString& key) const -{ - return d->httpHeader.value(key); -} - -void QWebNetworkRequest::setHttpHeaderField(const QString& key, const QString& value) -{ - d->httpHeader.setValue(key, value); -} - -/*! - \internal - Post data sent with HTTP POST requests. -*/ -QByteArray QWebNetworkRequest::postData() const -{ - return d->postData; -} - -void QWebNetworkRequest::setPostData(const QByteArray& data) -{ - d->postData = data; -} - -/*! - \class QWebNetworkJob - \internal - - The QWebNetworkJob class represents a network job, that needs to be - processed by the QWebNetworkInterface. - - This class is only required when implementing a new network layer (or - support for a special protocol) using QWebNetworkInterface. - - QWebNetworkJob objects are created and owned by the QtWebKit library. - Most of it's properties are read-only. - - The job is reference counted. This can be used to ensure that the job doesn't - get deleted while it's still stored in some data structure. -*/ - -/*! - \internal -*/ -QWebNetworkJob::QWebNetworkJob() - : d(new QWebNetworkJobPrivate) -{ -} - -/*! - \internal -*/ -QWebNetworkJob::~QWebNetworkJob() -{ - delete d; - d = 0; -} - -/*! - \internal - The requested URL -*/ -QUrl QWebNetworkJob::url() const -{ - return d->request.url; -} - -/*! - \internal - Post data associated with the job -*/ -QByteArray QWebNetworkJob::postData() const -{ - return d->request.postData; -} - -/*! - \internal - The HTTP request header that should be used to download the job. -*/ -QHttpRequestHeader QWebNetworkJob::httpHeader() const -{ - return d->request.httpHeader; -} - -/*! - \internal - The complete network request that should be used to download the job. -*/ -QWebNetworkRequest QWebNetworkJob::request() const -{ - return QWebNetworkRequest(d->request); -} - -/*! - \internal - The HTTP response header received from the network. -*/ -QHttpResponseHeader QWebNetworkJob::response() const -{ - return d->response; -} - -/*! - \internal - The last error of the Job. -*/ -QString QWebNetworkJob::errorString() const -{ - return d->errorString; -} - -/*! - \internal - Sets the HTTP reponse header. The response header has to be called before - emitting QWebNetworkInterface::started. -*/ -void QWebNetworkJob::setResponse(const QHttpResponseHeader& response) -{ - d->response = response; -} - -void QWebNetworkJob::setErrorString(const QString& errorString) -{ - d->errorString = errorString; -} - -/*! - \internal - returns true if the job has been cancelled by the WebKit framework -*/ -bool QWebNetworkJob::cancelled() const -{ - return !d->resourceHandle; -} - -/*! - \internal - reference the job. -*/ -void QWebNetworkJob::ref() -{ - ++d->ref; -} - -/*! - \internal - derefence the job. - - If the reference count drops to 0 this method also deletes the job. - - Returns false if the reference count has dropped to 0. -*/ -bool QWebNetworkJob::deref() -{ - if (!--d->ref) { - delete this; - return false; - } - return true; -} - -/*! - \internal - Returns the network interface that is associated with this job. -*/ -QWebNetworkInterface *QWebNetworkJob::networkInterface() const -{ - return d->interface; -} - -/*! - \internal - Returns the network interface that is associated with this job. -*/ -QWebFrame *QWebNetworkJob::frame() const -{ - if (!d->resourceHandle) { - ResourceHandleInternal *rhi = d->resourceHandle->getInternal(); - if (rhi) - return rhi->m_frame; - } - return 0; -} - -QWebNetworkJob::JobStatus QWebNetworkJob::status() const -{ - return d->jobStatus; -} - -void QWebNetworkJob::setStatus(const JobStatus& status) -{ - d->jobStatus = status; -} - -/*! - \class QWebNetworkManager - \internal -*/ -QWebNetworkManager::QWebNetworkManager() - : QObject(0) - , m_scheduledWork(false) -{ - connect(this, SIGNAL(scheduleWork()), SLOT(doWork()), Qt::QueuedConnection); -} - -QWebNetworkManager *QWebNetworkManager::self() -{ - // ensure everything's constructed and connected - QWebNetworkInterface::defaultInterface(); - - return s_manager; -} - -bool QWebNetworkManager::add(ResourceHandle* handle, QWebNetworkInterface* interface, JobMode jobMode) -{ - if (!interface) - interface = s_default_interface; - - ASSERT(interface); - - QWebNetworkJob *job = new QWebNetworkJob(); - handle->getInternal()->m_job = job; - job->d->resourceHandle = handle; - job->d->interface = interface; - - job->d->request.init(handle->request()); - - const QString method = handle->getInternal()->m_request.httpMethod(); - if (method != "POST" && method != "GET" && method != "HEAD") { - qWarning("REQUEST: [%s]\n", qPrintable(job->d->request.httpHeader.toString())); - return false; - } - - DEBUG() << "QWebNetworkManager::add:" << job->d->request.httpHeader.toString(); - - if (jobMode == SynchronousJob) { - Q_ASSERT(!m_synchronousJobs.contains(job)); - m_synchronousJobs[job] = 1; - } - - interface->addJob(job); - - return true; -} - -void QWebNetworkManager::cancel(ResourceHandle* handle) -{ - QWebNetworkJob *job = handle->getInternal()->m_job; - if (!job) - return; - DEBUG() << "QWebNetworkManager::cancel:" << job->d->request.httpHeader.toString(); - job->d->resourceHandle = 0; - job->d->interface->cancelJob(job); - handle->getInternal()->m_job = 0; -} - -/*! - \internal -*/ -void QWebNetworkManager::started(QWebNetworkJob* job) -{ - Q_ASSERT(job->d); - Q_ASSERT(job->status() == QWebNetworkJob::JobCreated || - job->status() == QWebNetworkJob::JobRecreated); - - job->setStatus(QWebNetworkJob::JobStarted); - ResourceHandleClient* client = 0; - - if (!job->d->resourceHandle) - return; - - client = job->d->resourceHandle->client(); - if (!client) - return; - - DEBUG() << "ResourceHandleManager::receivedResponse:"; - DEBUG() << job->d->response.toString(); - - QStringList cookies = job->d->response.allValues("Set-Cookie"); - KURL url(job->url()); - - foreach (QString c, cookies) - QCookieJar::cookieJar()->setCookies(url, url, c); - - QString contentType = job->d->response.value("Content-Type"); - QString encoding; - int idx = contentType.indexOf(QLatin1Char(';')); - if (idx > 0) { - QString remainder = contentType.mid(idx + 1).toLower(); - contentType = contentType.left(idx).trimmed(); - - idx = remainder.indexOf("charset"); - if (idx >= 0) { - idx = remainder.indexOf(QLatin1Char('='), idx); - if (idx >= 0) - encoding = remainder.mid(idx + 1).trimmed(); - } - } - if (contentType.isEmpty()) { - // let's try to guess from the extension - QString extension = job->d->request.url.path(); - int index = extension.lastIndexOf(QLatin1Char('.')); - if (index > 0) { - extension = extension.mid(index + 1); - contentType = MIMETypeRegistry::getMIMETypeForExtension(extension); - } - } -// qDebug() << "Content-Type=" << contentType; -// qDebug() << "Encoding=" << encoding; - - - ResourceResponse response(url, contentType, - 0 /* FIXME */, - encoding, - String() /* FIXME */); - - int statusCode = job->d->response.statusCode(); - if (job->url().scheme() != QLatin1String("file")) - response.setHTTPStatusCode(statusCode); - else if (statusCode == 404) - response.setHTTPStatusCode(statusCode); - - /* Fill in the other fields */ - - if (statusCode >= 300 && statusCode < 400) { - // we're on a redirect page! if the 'Location:' field is valid, we redirect - QString location = job->d->response.value("location"); - DEBUG() << "Redirection"; - if (!location.isEmpty()) { - QUrl newUrl = job->d->request.url.resolved(location); - if (job->d->resourceHandle) { - ResourceRequest newRequest = job->d->resourceHandle->request(); - newRequest.setURL(KURL(newUrl)); - if (client) - client->willSendRequest(job->d->resourceHandle, newRequest, response); - } - - QString method; - if (statusCode == 302 || statusCode == 303) { - // this is standard-correct for 303 and practically-correct (no standard-correct) for 302 - // also, it's required for Yahoo's login process for flickr.com which responds to a POST - // with a 302 which must be GET'ed - method = "GET"; - job->d->request.httpHeader.setContentLength(0); - } else - method = job->d->request.httpHeader.method(); - - job->d->request.httpHeader.setRequest(method, - newUrl.toString(QUrl::RemoveScheme|QUrl::RemoveAuthority)); - job->d->request.setURL(newUrl); - job->d->redirected = true; - return; - } - } - - if (client) - client->didReceiveResponse(job->d->resourceHandle, response); - -} - -void QWebNetworkManager::data(QWebNetworkJob* job, const QByteArray& data) -{ - Q_ASSERT(job->status() == QWebNetworkJob::JobStarted || - job->status() == QWebNetworkJob::JobReceivingData); - - job->setStatus(QWebNetworkJob::JobReceivingData); - ResourceHandleClient* client = 0; - - if (!job->d->resourceHandle) - return; - - client = job->d->resourceHandle->client(); - if (!client) - return; - - if (job->d->redirected) - return; // don't emit the "Document has moved here" type of HTML - - DEBUG() << "receivedData" << job->d->request.url.path(); - client->didReceiveData(job->d->resourceHandle, data.constData(), data.length(), data.length() /*FixMe*/); -} - -void QWebNetworkManager::finished(QWebNetworkJob* job, int errorCode) -{ - Q_ASSERT(errorCode == 1 || - job->status() == QWebNetworkJob::JobStarted || - job->status() == QWebNetworkJob::JobReceivingData); - - if (m_synchronousJobs.contains(job)) - m_synchronousJobs.remove(job); - - job->setStatus(QWebNetworkJob::JobFinished); - ResourceHandleClient* client = 0; - if (job->d->resourceHandle) { - client = job->d->resourceHandle->client(); - if (!client) - return; - } else { - job->deref(); - return; - } - - DEBUG() << "receivedFinished" << errorCode << job->url(); - - if (job->d->redirected) { - job->d->redirected = false; - job->setStatus(QWebNetworkJob::JobRecreated); - job->d->interface->addJob(job); - return; - } - - if (job->d->resourceHandle) - job->d->resourceHandle->getInternal()->m_job = 0; - - if (client) { - if (errorCode) { - //FIXME: error setting error was removed from ResourceHandle - client->didFail(job->d->resourceHandle, - ResourceError(job->d->request.url.host(), job->d->response.statusCode(), - job->d->request.url.toString(), job->d->errorString)); - } else - client->didFinishLoading(job->d->resourceHandle); - } - - DEBUG() << "receivedFinished done" << job->d->request.url; - - job->deref(); -} - -void QWebNetworkManager::addHttpJob(QWebNetworkJob* job) -{ - HostInfo hostInfo(job->url()); - WebCoreHttp *httpConnection = m_hostMapping.value(hostInfo); - if (!httpConnection) { - // #### fix custom ports - DEBUG() << " new connection to" << hostInfo.host << hostInfo.port; - httpConnection = new WebCoreHttp(this, hostInfo); - QObject::connect(httpConnection, SIGNAL(connectionClosed(const WebCore::HostInfo&)), - this, SLOT(httpConnectionClosed(const WebCore::HostInfo&))); - - m_hostMapping[hostInfo] = httpConnection; - } - httpConnection->request(job); -} - -void QWebNetworkManager::cancelHttpJob(QWebNetworkJob* job) -{ - WebCoreHttp *httpConnection = m_hostMapping.value(job->url()); - if (httpConnection) - httpConnection->cancel(job); -} - -void QWebNetworkManager::httpConnectionClosed(const WebCore::HostInfo& info) -{ - WebCoreHttp *connection = m_hostMapping.take(info); - connection->deleteLater(); -} - -void QWebNetworkInterfacePrivate::sendFileData(QWebNetworkJob* job, int statusCode, const QByteArray& data) -{ - int error = statusCode >= 400 ? 1 : 0; - if (!job->cancelled()) { - QHttpResponseHeader response; - response.setStatusLine(statusCode); - response.setContentLength(data.length()); - job->setResponse(response); - q->started(job); - if (!data.isEmpty()) - q->data(job, data); - } - q->finished(job, error); -} - -void QWebNetworkInterfacePrivate::parseDataUrl(QWebNetworkJob* job) -{ - QByteArray data = job->url().toString().toLatin1(); - //qDebug() << "handling data url:" << data; - - ASSERT(data.startsWith("data:")); - - // Here's the syntax of data URLs: - // dataurl := "data:" [ mediatype ] [ ";base64" ] "," data - // mediatype := [ type "/" subtype ] *( ";" parameter ) - // data := *urlchar - // parameter := attribute "=" value - QByteArray header; - bool base64 = false; - - int index = data.indexOf(','); - if (index != -1) { - header = data.mid(5, index - 5).toLower(); - //qDebug() << "header=" << header; - data = data.mid(index+1); - //qDebug() << "data=" << data; - - if (header.endsWith(";base64")) { - //qDebug() << "base64"; - base64 = true; - header = header.left(header.length() - 7); - //qDebug() << "mime=" << header; - } - } else - data = QByteArray(); - - if (base64) - data = QByteArray::fromBase64(data); - else - data = decodePercentEncoding(data); - - if (header.isEmpty()) - header = "text/plain;charset=US-ASCII"; - int statusCode = 200; - QHttpResponseHeader response; - response.setContentType(header); - response.setContentLength(data.size()); - job->setResponse(response); - - int error = statusCode >= 400 ? 1 : 0; - q->started(job); - if (!data.isEmpty()) - q->data(job, data); - q->finished(job, error); -} - -void QWebNetworkManager::queueStart(QWebNetworkJob* job) -{ - Q_ASSERT(job->d); - - QMutexLocker locker(&m_queueMutex); - job->ref(); - m_pendingWork.append(new JobWork(job)); - doScheduleWork(); -} - -void QWebNetworkManager::queueData(QWebNetworkJob* job, const QByteArray& data) -{ - ASSERT(job->d); - - QMutexLocker locker(&m_queueMutex); - job->ref(); - m_pendingWork.append(new JobWork(job, data)); - doScheduleWork(); -} - -void QWebNetworkManager::queueFinished(QWebNetworkJob* job, int errorCode) -{ - Q_ASSERT(job->d); - - QMutexLocker locker(&m_queueMutex); - job->ref(); - m_pendingWork.append(new JobWork(job, errorCode)); - doScheduleWork(); -} - -void QWebNetworkManager::doScheduleWork() -{ - if (!m_scheduledWork) { - m_scheduledWork = true; - emit scheduleWork(); - } -} - - -/* - * We will work on a copy of m_pendingWork. While dispatching m_pendingWork - * new work will be added that will be handled at a later doWork call. doWork - * will be called we set m_scheduledWork to false early in this method. - */ -void QWebNetworkManager::doWork() -{ - m_queueMutex.lock(); - m_scheduledWork = false; - bool hasSyncJobs = m_synchronousJobs.size(); - const QHash<QWebNetworkJob*, int> syncJobs = m_synchronousJobs; - m_queueMutex.unlock(); - - foreach (JobWork* work, m_pendingWork) { - if (hasSyncJobs && !syncJobs.contains(work->job)) - continue; - - if (work->workType == JobWork::JobStarted) - started(work->job); - else if (work->workType == JobWork::JobData) { - // This job was not yet started - if (static_cast<int>(work->job->status()) < QWebNetworkJob::JobStarted) - continue; - - data(work->job, work->data); - } else if (work->workType == JobWork::JobFinished) { - // This job was not yet started... we have no idea if data comes by... - // and it won't start in case of errors - if (static_cast<int>(work->job->status()) < QWebNetworkJob::JobStarted && work->errorCode != 1) - continue; - - finished(work->job, work->errorCode); - } - - m_queueMutex.lock(); - m_pendingWork.removeAll(work); - m_queueMutex.unlock(); - - work->job->deref(); - delete work; - } - - m_queueMutex.lock(); - if (hasSyncJobs && !m_synchronousJobs.size()) - doScheduleWork(); - m_queueMutex.unlock(); -} - -/*! - \class QWebNetworkInterface - \internal - - The QWebNetworkInterface class provides an abstraction layer for - WebKit's network interface. It allows to completely replace or - extend the builtin network layer. - - QWebNetworkInterface contains two virtual methods, addJob and - cancelJob that have to be reimplemented when implementing your own - networking layer. - - QWebNetworkInterface can by default handle the http, https, file and - data URI protocols. - -*/ - -static bool gRoutineAdded = false; - -static void gCleanupInterface() -{ - delete s_default_interface; - s_default_interface = 0; -} - -/*! - \internal - Sets a new default interface that will be used by all of WebKit - for downloading data from the internet. -*/ -void QWebNetworkInterface::setDefaultInterface(QWebNetworkInterface* defaultInterface) -{ - if (s_default_interface == defaultInterface) - return; - if (s_default_interface) - delete s_default_interface; - s_default_interface = defaultInterface; - if (!gRoutineAdded) { - qAddPostRoutine(gCleanupInterface); - gRoutineAdded = true; - } -} - -/*! - \internal - Returns the default interface that will be used by WebKit. If no - default interface has been set, QtWebkit will create an instance of - QWebNetworkInterface to do the work. -*/ -QWebNetworkInterface *QWebNetworkInterface::defaultInterface() -{ - if (!s_default_interface) - setDefaultInterface(new QWebNetworkInterface); - - return s_default_interface; -} - - -/*! - \internal - Constructs a QWebNetworkInterface object. -*/ -QWebNetworkInterface::QWebNetworkInterface(QObject* parent) - : QObject(parent) -{ - d = new QWebNetworkInterfacePrivate; - d->q = this; - - if (!s_manager) - s_manager = new QWebNetworkManager; -} - -/*! - \internal - Destructs the QWebNetworkInterface object. -*/ -QWebNetworkInterface::~QWebNetworkInterface() -{ - delete d; -} - -/*! - \internal - This virtual method gets called whenever QtWebkit needs to add a - new job to download. - - The QWebNetworkInterface should process this job, by first emitting - the started signal, then emitting data repeatedly as new data for - the Job is available, and finally ending the job with emitting a - finished signal. - - After the finished signal has been emitted, the QWebNetworkInterface - is not allowed to access the job anymore. -*/ -void QWebNetworkInterface::addJob(QWebNetworkJob* job) -{ - QString protocol = job->url().scheme(); - if (protocol == QLatin1String("http") || protocol == QLatin1String("https")) { - QWebNetworkManager::self()->addHttpJob(job); - return; - } - - // "file", "data" and all unhandled stuff go through here - //DEBUG() << "fileRequest"; - DEBUG() << "FileLoader::request" << job->url(); - - if (job->cancelled()) { - d->sendFileData(job, 400, QByteArray()); - return; - } - - QUrl url = job->url(); - if (protocol == QLatin1String("data")) { - d->parseDataUrl(job); - return; - } - - int statusCode = 200; - QByteArray data; - QString path = url.path(); - if (protocol == QLatin1String("qrc")) { - protocol = "file"; - path.prepend(QLatin1Char(':')); - } - - if (!(protocol.isEmpty() || protocol == QLatin1String("file"))) { - statusCode = 404; - } else { - // we simply ignore post data here. - QFile f(path); - DEBUG() << "opening" << QString(url.path()); - - if (f.open(QIODevice::ReadOnly)) { - QHttpResponseHeader response; - response.setStatusLine(200); - job->setResponse(response); - data = f.readAll(); - } else - statusCode = 404; - } - - if (statusCode == 404) { - QHttpResponseHeader response; - response.setStatusLine(404); - job->setResponse(response); - } - - d->sendFileData(job, statusCode, data); -} - -/*! - \internal - This virtual method gets called whenever QtWebkit needs to cancel a - new job. - - The QWebNetworkInterface acknowledge the canceling of the job, by - emitting the finished signal with an error code of 1. After emitting - the finished signal, the interface should not access the job - anymore. -*/ -void QWebNetworkInterface::cancelJob(QWebNetworkJob* job) -{ - QString protocol = job->url().scheme(); - if (protocol == QLatin1String("http") || protocol == QLatin1String("https")) - QWebNetworkManager::self()->cancelHttpJob(job); -} - -/*! - \internal -*/ -void QWebNetworkInterface::started(QWebNetworkJob* job) -{ - Q_ASSERT(s_manager); - s_manager->queueStart(job); -} - -/*! - \internal -*/ -void QWebNetworkInterface::data(QWebNetworkJob* job, const QByteArray& data) -{ - Q_ASSERT(s_manager); - s_manager->queueData(job, data); -} - -/*! - \internal -*/ -void QWebNetworkInterface::finished(QWebNetworkJob* job, int errorCode) -{ - Q_ASSERT(s_manager); - s_manager->queueFinished(job, errorCode); -} - -/*! - \fn void QWebNetworkInterface::sslErrors(QWebFrame *frame, const QUrl& url, const QList<QSslError>& errors, bool *continueAnyway); - \internal - - Signal is emitted when an SSL error occurs. -*/ - -/*! - \fn void QWebNetworkInterface::authenticate(QWebFrame *frame, const QUrl& url, const QString& hostname, quint16 port, QAuthenticator *auth); - \internal - - Signal is emitted when network authentication is required. -*/ - -/*! - \fn void QWebNetworkInterface::authenticateProxy(QWebFrame *frame, const QUrl& url, const QNetworkProxy& proxy, QAuthenticator *auth); - \internal - - Signal is emitted when proxy authentication is required. -*/ - -///////////////////////////////////////////////////////////////////////////// -WebCoreHttp::WebCoreHttp(QObject* parent, const HostInfo& hi) - : QObject(parent) - , info(hi) - , m_inCancel(false) -{ - for (int i = 0; i < 2; ++i) { - connection[i].http = new QHttp(info.host, (hi.protocol == QLatin1String("https")) ? QHttp::ConnectionModeHttps : QHttp::ConnectionModeHttp, info.port); - connect(connection[i].http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader&)), - this, SLOT(onResponseHeaderReceived(const QHttpResponseHeader&))); - connect(connection[i].http, SIGNAL(readyRead(const QHttpResponseHeader&)), - this, SLOT(onReadyRead())); - connect(connection[i].http, SIGNAL(requestFinished(int, bool)), - this, SLOT(onRequestFinished(int, bool))); - connect(connection[i].http, SIGNAL(done(bool)), - this, SLOT(onDone(bool))); - connect(connection[i].http, SIGNAL(stateChanged(int)), - this, SLOT(onStateChanged(int))); - connect(connection[i].http, SIGNAL(authenticationRequired(const QString&, quint16, QAuthenticator*)), - this, SLOT(onAuthenticationRequired(const QString&, quint16, QAuthenticator*))); - connect(connection[i].http, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)), - this, SLOT(onProxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*))); - connect(connection[i].http, SIGNAL(sslErrors(const QList<QSslError>&)), - this, SLOT(onSslErrors(const QList<QSslError>&))); - } -} - -WebCoreHttp::~WebCoreHttp() -{ - connection[0].http->deleteLater(); - connection[1].http->deleteLater(); -} - -void WebCoreHttp::request(QWebNetworkJob* job) -{ - m_pendingRequests.append(job); - scheduleNextRequest(); -} - -void WebCoreHttp::scheduleNextRequest() -{ - int c = 0; - for (; c < 2; ++c) { - if (!connection[c].current) - break; - } - if (c >= 2) - return; - - QWebNetworkJob *job = 0; - while (!job && !m_pendingRequests.isEmpty()) { - job = m_pendingRequests.takeFirst(); - if (job->cancelled()) { - job->networkInterface()->finished(job, 1); - job = 0; - } - } - if (!job) - return; - - QHttp* http = connection[c].http; - - connection[c].current = job; - connection[c].id = -1; -#ifndef QT_NO_NETWORKPROXY - int proxyId = http->setProxy(job->frame()->page()->networkProxy()); -#endif - - QByteArray postData = job->postData(); - if (!postData.isEmpty()) - connection[c].id = http->request(job->httpHeader(), postData); - else - connection[c].id = http->request(job->httpHeader()); - - DEBUG() << "WebCoreHttp::scheduleNextRequest: using connection" << c; - DEBUG() << job->httpHeader().toString(); -// DEBUG() << job->request.toString(); -} - -int WebCoreHttp::getConnection() -{ - QObject* o = sender(); - int c; - if (o == connection[0].http) { - c = 0; - } else { - Q_ASSERT(o == connection[1].http); - c = 1; - } - Q_ASSERT(connection[c].current); - return c; -} - -void WebCoreHttp::onResponseHeaderReceived(const QHttpResponseHeader& resp) -{ - QHttp* http = qobject_cast<QHttp*>(sender()); - if (!http->currentId()) { - qDebug() << "ERROR! Invalid job id. Why?"; // foxnews.com triggers this - return; - } - int c = getConnection(); - QWebNetworkJob* job = connection[c].current; - DEBUG() << "WebCoreHttp::slotResponseHeaderReceived connection=" << c; - DEBUG() << resp.toString(); - - job->setResponse(resp); - - job->networkInterface()->started(job); -} - -void WebCoreHttp::onReadyRead() -{ - QHttp* http = qobject_cast<QHttp*>(sender()); - if (!http->currentId()) { - qDebug() << "ERROR! Invalid job id. Why?"; // foxnews.com triggers this - return; - } - int c = getConnection(); - QWebNetworkJob* job = connection[c].current; - Q_ASSERT(http == connection[c].http); - //DEBUG() << "WebCoreHttp::slotReadyRead connection=" << c; - - QByteArray data; - data.resize(http->bytesAvailable()); - http->read(data.data(), data.length()); - job->networkInterface()->data(job, data); -} - -void WebCoreHttp::onRequestFinished(int id, bool error) -{ - int c = getConnection(); - if (connection[c].id != id) - return; - - QWebNetworkJob* job = connection[c].current; - if (!job) { - scheduleNextRequest(); - return; - } - - QHttp* http = connection[c].http; - DEBUG() << "WebCoreHttp::slotFinished connection=" << c << error << job; - if (error) { - DEBUG() << " error: " << http->errorString(); - job->setErrorString(http->errorString()); - } - - if (!error && http->bytesAvailable()) { - QByteArray data; - data.resize(http->bytesAvailable()); - http->read(data.data(), data.length()); - job->networkInterface()->data(job, data); - } - - job->networkInterface()->finished(job, error ? 1 : 0); - connection[c].current = 0; - connection[c].id = -1; - scheduleNextRequest(); -} - -void WebCoreHttp::onDone(bool error) -{ - DEBUG() << "WebCoreHttp::onDone" << error; -} - -void WebCoreHttp::onStateChanged(int state) -{ - DEBUG() << "State changed to" << state << "and connections are" << connection[0].current << connection[1].current; - if (state == QHttp::Closing || state == QHttp::Unconnected) { - if (!m_inCancel && m_pendingRequests.isEmpty() - && !connection[0].current && !connection[1].current) - emit connectionClosed(info); - } -} - -void WebCoreHttp::cancel(QWebNetworkJob* request) -{ - bool doEmit = true; - m_inCancel = true; - for (int i = 0; i < 2; ++i) { - if (request == connection[i].current) { - connection[i].http->abort(); - doEmit = false; - } - } - if (!m_pendingRequests.removeAll(request)) - doEmit = false; - m_inCancel = false; - - if (doEmit) - request->networkInterface()->finished(request, 1); - - if (m_pendingRequests.isEmpty() - && !connection[0].current && !connection[1].current) - emit connectionClosed(info); -} - -void WebCoreHttp::onSslErrors(const QList<QSslError>& errors) -{ - int c = getConnection(); - QWebNetworkJob *job = connection[c].current; - if (job) { - bool continueAnyway = false; - emit job->networkInterface()->sslErrors(job->frame(), job->url(), errors, &continueAnyway); -#ifndef QT_NO_OPENSSL - if (continueAnyway) - connection[c].http->ignoreSslErrors(); -#endif - } -} - -void WebCoreHttp::onAuthenticationRequired(const QString& hostname, quint16 port, QAuthenticator* auth) -{ - int c = getConnection(); - QWebNetworkJob *job = connection[c].current; - if (job) { - emit job->networkInterface()->authenticate(job->frame(), job->url(), hostname, port, auth); - if (auth->isNull()) - connection[c].http->abort(); - } -} - -void WebCoreHttp::onProxyAuthenticationRequired(const QNetworkProxy& proxy, QAuthenticator* auth) -{ - int c = getConnection(); - QWebNetworkJob *job = connection[c].current; - if (job) { - emit job->networkInterface()->authenticateProxy(job->frame(), job->url(), proxy, auth); - if (auth->isNull()) - connection[c].http->abort(); - } -} - -HostInfo::HostInfo(const QUrl& url) - : protocol(url.scheme()) - , host(url.host()) - , port(url.port()) -{ - if (port < 0) { - if (protocol == QLatin1String("http")) - port = 80; - else if (protocol == QLatin1String("https")) - port = 443; - } -} - -#endif diff --git a/WebKit/qt/Api/qwebnetworkinterface.h b/WebKit/qt/Api/qwebnetworkinterface.h deleted file mode 100644 index 7f96155..0000000 --- a/WebKit/qt/Api/qwebnetworkinterface.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) - - 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. -*/ - -#ifndef QWEBNETWORKINTERFACE_H -#define QWEBNETWORKINTERFACE_H - -#include <QtCore/qobject.h> -#include <QtCore/qurl.h> -#include <QtNetwork/qhttp.h> -#include <QtCore/qbytearray.h> - -#include "qwebkitglobal.h" - -#if QT_VERSION < 0x040400 - -class QAuthenticator; -class QNetworkProxy; -class QSslError; -class QWebFrame; -class QWebNetworkJobPrivate; -class QWebNetworkInterface; -class QWebObjectPluginConnector; - -namespace WebCore { - class WebCoreHttp; - class ResourceRequest; - class FrameLoaderClientQt; -} - -struct QWebNetworkRequestPrivate; -class QWEBKIT_EXPORT QWebNetworkRequest { -public: - enum Method { - Get, - Post - //Head - }; - - QWebNetworkRequest(); - explicit QWebNetworkRequest(const QUrl &url, Method method = Get, const QByteArray &postData = QByteArray()); - QWebNetworkRequest(const QWebNetworkRequest &other); - - QWebNetworkRequest &operator=(const QWebNetworkRequest &other); - ~QWebNetworkRequest(); - - QUrl url() const; - void setUrl(const QUrl &url); - - QHttpRequestHeader httpHeader() const; - void setHttpHeader(const QHttpRequestHeader &header) const; - - QString httpHeaderField(const QString &key) const; - void setHttpHeaderField(const QString &key, const QString &value); - - QByteArray postData() const; - void setPostData(const QByteArray &data); - -private: - explicit QWebNetworkRequest(const QWebNetworkRequestPrivate &priv); - explicit QWebNetworkRequest(const WebCore::ResourceRequest &request); - friend class QWebNetworkJob; - friend class WebCore::FrameLoaderClientQt; - - QWebNetworkRequestPrivate *d; - friend class QWebObjectPluginConnector; -}; - -class QWEBKIT_EXPORT QWebNetworkJob { -public: - - QUrl url() const; - QByteArray postData() const; - QHttpRequestHeader httpHeader() const; - QWebNetworkRequest request() const; - QString errorString() const; - - QHttpResponseHeader response() const; - void setResponse(const QHttpResponseHeader &response); - void setErrorString(const QString&); - - bool cancelled() const; - - void ref(); - bool deref(); - - QWebNetworkInterface *networkInterface() const; - - QWebFrame *frame() const; - -protected: - enum JobStatus { - JobCreated, - JobRecreated, - JobStarted, - JobReceivingData, - JobFinished - }; - - JobStatus status() const; - void setStatus(const JobStatus&); - -private: - QWebNetworkJob(); - ~QWebNetworkJob(); - - friend class QWebNetworkManager; - friend class QWebObjectPluginConnector; - friend class QWebNetworkJobPrivate; - - QWebNetworkJobPrivate *d; -}; - -class QWebNetworkInterfacePrivate; - -class QWEBKIT_EXPORT QWebNetworkInterface : public QObject { - Q_OBJECT -public: - QWebNetworkInterface(QObject *parent = 0); - ~QWebNetworkInterface(); - - static void setDefaultInterface(QWebNetworkInterface *defaultInterface); - static QWebNetworkInterface *defaultInterface(); - - virtual void addJob(QWebNetworkJob *job); - virtual void cancelJob(QWebNetworkJob *job); - -protected: - void started(QWebNetworkJob*); - void data(QWebNetworkJob*, const QByteArray &data); - void finished(QWebNetworkJob*, int errorCode); - -signals: - void sslErrors(QWebFrame *frame, const QUrl& url, const QList<QSslError>& errors, bool *continueAnyway); - void authenticate(QWebFrame *frame, const QUrl& url, const QString& hostname, quint16 port, QAuthenticator *auth); - void authenticateProxy(QWebFrame *frame, const QUrl& url, const QNetworkProxy& proxy, QAuthenticator *auth); - -private: - friend class QWebNetworkInterfacePrivate; - friend class WebCore::WebCoreHttp; - QWebNetworkInterfacePrivate *d; -}; - -#endif - -#endif diff --git a/WebKit/qt/Api/qwebnetworkinterface_p.h b/WebKit/qt/Api/qwebnetworkinterface_p.h deleted file mode 100644 index aec104b..0000000 --- a/WebKit/qt/Api/qwebnetworkinterface_p.h +++ /dev/null @@ -1,214 +0,0 @@ -/* - Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) - - 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. -*/ - -#ifndef QWEBNETWORKINTERFACE_P_H -#define QWEBNETWORKINTERFACE_P_H - -#include "qwebnetworkinterface.h" -#if QT_VERSION < 0x040400 -#include <qthread.h> -#include <qmutex.h> - -namespace WebCore { - struct HostInfo; - class ResourceRequest; -}; -uint qHash(const WebCore::HostInfo &info); -#include <qhash.h> - -namespace WebCore { - class ResourceHandle; -} - -struct QWebNetworkRequestPrivate { - QUrl url; - QHttpRequestHeader httpHeader; - QByteArray postData; - - void init(const WebCore::ResourceRequest &resourceRequest); - void init(const QString &method, const QUrl &url, const WebCore::ResourceRequest *resourceRequest = 0); - void setURL(const QUrl &u); -}; - -class QWebNetworkJobPrivate { -public: - QWebNetworkJobPrivate() - : ref(1) - , resourceHandle(0) - , redirected(false) - , interface(0) - , jobStatus(QWebNetworkJob::JobCreated) - {} - int ref; - - QWebNetworkRequestPrivate request; - QHttpResponseHeader response; - - WebCore::ResourceHandle *resourceHandle; - bool redirected; - - QWebNetworkInterface *interface; - QWebNetworkJob::JobStatus jobStatus; - QString errorString; -}; - -class QWebNetworkManager : public QObject { - Q_OBJECT -public: - enum JobMode { - AsynchronousJob, - SynchronousJob - }; - - static QWebNetworkManager *self(); - - bool add(WebCore::ResourceHandle *resourceHandle, QWebNetworkInterface *interface, JobMode = AsynchronousJob); - void cancel(WebCore::ResourceHandle *resourceHandle); - - void addHttpJob(QWebNetworkJob *job); - void cancelHttpJob(QWebNetworkJob *job); - -protected: - void queueStart(QWebNetworkJob*); - void queueData(QWebNetworkJob*, const QByteArray&); - void queueFinished(QWebNetworkJob*, int errorCode); - -private: - void started(QWebNetworkJob *); - void data(QWebNetworkJob *, const QByteArray &data); - void finished(QWebNetworkJob *, int errorCode); - void doScheduleWork(); - -signals: - void fileRequest(QWebNetworkJob*); - void scheduleWork(); - -private slots: - void httpConnectionClosed(const WebCore::HostInfo &); - void doWork(); - -private: - friend class QWebNetworkInterface; - QWebNetworkManager(); - QHash<WebCore::HostInfo, WebCore::WebCoreHttp *> m_hostMapping; - - struct JobWork { - enum WorkType { - JobStarted, - JobData, - JobFinished - }; - - explicit JobWork(QWebNetworkJob* _job) - : workType(JobStarted) - , errorCode(-1) - , job(_job) - {} - - explicit JobWork(QWebNetworkJob* _job, int _errorCode) - : workType(JobFinished) - , errorCode(_errorCode) - , job(_job) - {} - - explicit JobWork(QWebNetworkJob* _job, const QByteArray& _data) - : workType(JobData) - , errorCode(-1) - , job(_job) - , data(_data) - {} - - const WorkType workType; - int errorCode; - QByteArray data; - QWebNetworkJob* job; - }; - - QMutex m_queueMutex; - bool m_scheduledWork; - QList<JobWork*> m_pendingWork; - QHash<QWebNetworkJob*, int> m_synchronousJobs; -}; - - -namespace WebCore { - - class NetworkLoader; - - struct HostInfo { - HostInfo() {} - HostInfo(const QUrl& url); - QString protocol; - QString host; - int port; - }; - - class WebCoreHttp : public QObject { - Q_OBJECT - public: - WebCoreHttp(QObject* parent, const HostInfo&); - ~WebCoreHttp(); - - void request(QWebNetworkJob* resource); - void cancel(QWebNetworkJob*); - - signals: - void connectionClosed(const WebCore::HostInfo&); - - private slots: - void onResponseHeaderReceived(const QHttpResponseHeader& resp); - void onReadyRead(); - void onRequestFinished(int, bool); - void onDone(bool); - void onStateChanged(int); - void onSslErrors(const QList<QSslError>&); - void onAuthenticationRequired(const QString& hostname, quint16 port, QAuthenticator*); - void onProxyAuthenticationRequired(const QNetworkProxy& proxy, QAuthenticator*); - - void scheduleNextRequest(); - - int getConnection(); - - public: - HostInfo info; - private: - QList<QWebNetworkJob*> m_pendingRequests; - struct HttpConnection { - HttpConnection() : http(0), current(0), id(-1) {} - QHttp* http; - QWebNetworkJob* current; - int id; // the QHttp id - }; - HttpConnection connection[2]; - bool m_inCancel; - }; - -} - -class QWebNetworkInterfacePrivate { -public: - void sendFileData(QWebNetworkJob* job, int statusCode, const QByteArray& data); - void parseDataUrl(QWebNetworkJob* job); - - QWebNetworkInterface* q; -}; - -#endif - -#endif diff --git a/WebKit/qt/Api/qwebpage.cpp b/WebKit/qt/Api/qwebpage.cpp index 8e40339..ba6b9f3 100644 --- a/WebKit/qt/Api/qwebpage.cpp +++ b/WebKit/qt/Api/qwebpage.cpp @@ -27,6 +27,8 @@ #include "qwebframe_p.h" #include "qwebhistory.h" #include "qwebhistory_p.h" +#include "qwebinspector.h" +#include "qwebinspector_p.h" #include "qwebsettings.h" #include "qwebkitversion.h" @@ -64,19 +66,24 @@ #include "PluginDatabase.h" #include "ProgressTracker.h" #include "RefPtr.h" +#include "RenderTextControl.h" +#include "TextIterator.h" #include "HashMap.h" #include "HTMLFormElement.h" +#include "HTMLInputElement.h" +#include "HTMLNames.h" #include "HitTestResult.h" #include "WindowFeatures.h" #include "LocalizedStrings.h" #include "Cache.h" #include "runtime/InitializeThreading.h" +#include "PageGroup.h" +#include "QWebPageClient.h" #include <QApplication> #include <QBasicTimer> #include <QBitArray> #include <QDebug> -#include <QDesktopServices> #include <QDragEnterEvent> #include <QDragLeaveEvent> #include <QDragMoveEvent> @@ -94,11 +101,11 @@ #include <QSslSocket> #include <QStyle> #include <QSysInfo> -#if QT_VERSION >= 0x040400 +#include <QTextCharFormat> #include <QNetworkAccessManager> #include <QNetworkRequest> -#else -#include "qwebnetworkinterface.h" +#if defined(Q_WS_X11) +#include <QX11Info> #endif using namespace WebCore; @@ -108,7 +115,7 @@ void QWEBKIT_EXPORT qt_drt_overwritePluginDirectories() PluginDatabase* db = PluginDatabase::installedPlugins(/* populate */ false); Vector<String> paths; - String qtPath(getenv("QTWEBKIT_PLUGIN_PATH")); + String qtPath(qgetenv("QTWEBKIT_PLUGIN_PATH").data()); qtPath.split(UChar(':'), /* allowEmptyEntries */ false, paths); db->setPluginDirectories(paths); @@ -131,6 +138,102 @@ QString QWEBKIT_EXPORT qt_webpage_groupName(QWebPage* page) return page->handle()->page->groupName(); } +class QWebPageWidgetClient : public QWebPageClient { +public: + QWebPageWidgetClient(QWidget* view) + : view(view) + { + Q_ASSERT(view); + } + + virtual void scroll(int dx, int dy, const QRect&); + virtual void update(const QRect& dirtyRect); + virtual void setInputMethodEnabled(bool enable); + virtual bool inputMethodEnabled() const; +#if QT_VERSION >= 0x040600 + virtual void setInputMethodHint(Qt::InputMethodHint hint, bool enable); +#endif + +#ifndef QT_NO_CURSOR + virtual QCursor cursor() const; + virtual void updateCursor(const QCursor& cursor); +#endif + + virtual QPalette palette() const; + virtual int screenNumber() const; + virtual QWidget* ownerWidget() const; + + virtual QObject* pluginParent() const; + + QWidget* view; +}; + +void QWebPageWidgetClient::scroll(int dx, int dy, const QRect& rectToScroll) +{ + view->scroll(qreal(dx), qreal(dy), rectToScroll); +} + +void QWebPageWidgetClient::update(const QRect & dirtyRect) +{ + view->update(dirtyRect); +} + +void QWebPageWidgetClient::setInputMethodEnabled(bool enable) +{ + view->setAttribute(Qt::WA_InputMethodEnabled, enable); +} + +bool QWebPageWidgetClient::inputMethodEnabled() const +{ + return view->testAttribute(Qt::WA_InputMethodEnabled); +} + +#if QT_VERSION >= 0x040600 +void QWebPageWidgetClient::setInputMethodHint(Qt::InputMethodHint hint, bool enable) +{ + if (enable) + view->setInputMethodHints(view->inputMethodHints() | hint); + else + view->setInputMethodHints(view->inputMethodHints() & ~hint); +} +#endif +#ifndef QT_NO_CURSOR +QCursor QWebPageWidgetClient::cursor() const +{ + return view->cursor(); +} + +void QWebPageWidgetClient::updateCursor(const QCursor& cursor) +{ + view->setCursor(cursor); +} +#endif + +QPalette QWebPageWidgetClient::palette() const +{ + return view->palette(); +} + +int QWebPageWidgetClient::screenNumber() const +{ +#if defined(Q_WS_X11) + if (view) + return view->x11Info().screen(); +#endif + + return 0; +} + +QWidget* QWebPageWidgetClient::ownerWidget() const +{ + return view; +} + +QObject* QWebPageWidgetClient::pluginParent() const +{ + return view; +} + // Lookup table mapping QWebPage::WebActions to the associated Editor commands static const char* editorCommandWebActions[] = { @@ -226,18 +329,6 @@ const char* QWebPagePrivate::editorCommandForWebActions(QWebPage::WebAction acti return 0; } -#ifndef QT_NO_CURSOR -SetCursorEvent::SetCursorEvent(const QCursor& cursor) - : QEvent(static_cast<QEvent::Type>(EventType)) - , m_cursor(cursor) -{} - -QCursor SetCursorEvent::cursor() const -{ - return m_cursor; -} -#endif - // If you change this make sure to also adjust the docs for QWebPage::userAgentForUrl #define WEBKIT_VERSION "527+" @@ -265,48 +356,27 @@ static inline Qt::DropAction dragOpToDropAction(unsigned actions) return result; } -static void initializeApplicationCachePathIfNecessary() -{ -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - static bool initialized = false; - - if (initialized) - return; - - // Determine the path for HTML5 Application Cache DB - QString appCachePath; -#if QT_VERSION >= 0x040500 - appCachePath = QDesktopServices::storageLocation(QDesktopServices::CacheLocation); -#else - appCachePath = QDesktopServices::storageLocation(QDesktopServices::DataLocation); -#endif - - if (appCachePath.isEmpty()) - appCachePath = QDir::homePath() + QLatin1String("/.") + QCoreApplication::applicationName(); - - WebCore::cacheStorage().setCacheDirectory(appCachePath); - initialized = true; -#endif -} - QWebPagePrivate::QWebPagePrivate(QWebPage *qq) : q(qq) + , client(0) +#if QT_VERSION < 0x040600 , view(0) +#endif + , clickCausedFocus(false) , viewportSize(QSize(0, 0)) + , inspectorFrontend(0) + , inspector(0) + , inspectorIsInternalOnly(false) { WebCore::InitializeLoggingChannelsIfNecessary(); JSC::initializeThreading(); - WebCore::FrameLoader::setLocalLoadPolicy(WebCore::FrameLoader::AllowLocalLoadsForLocalAndSubstituteData); - initializeApplicationCachePathIfNecessary(); + WebCore::SecurityOrigin::setLocalLoadPolicy(WebCore::SecurityOrigin::AllowLocalLoadsForLocalAndSubstituteData); chromeClient = new ChromeClientQt(q); contextMenuClient = new ContextMenuClientQt(); editorClient = new EditorClientQt(q); page = new Page(chromeClient, contextMenuClient, editorClient, - new DragClientQt(q), new InspectorClientQt(q)); - - // ### should be configurable - page->settings()->setDefaultTextEncodingName("iso-8859-1"); + new DragClientQt(q), new InspectorClientQt(q), 0); settings = new QWebSettings(page->settings()); @@ -314,11 +384,7 @@ QWebPagePrivate::QWebPagePrivate(QWebPage *qq) undoStack = 0; #endif mainFrame = 0; -#if QT_VERSION < 0x040400 - networkInterface = 0; -#else networkManager = 0; -#endif pluginFactory = 0; insideOpenCall = false; forwardUnsupportedContent = false; @@ -331,6 +397,8 @@ QWebPagePrivate::QWebPagePrivate(QWebPage *qq) history.d = new QWebHistoryPrivate(page->backForwardList()); memset(actions, 0, sizeof(actions)); + + PageGroup::setShouldTrackVisitedLinks(true); } QWebPagePrivate::~QWebPagePrivate() @@ -345,15 +413,6 @@ QWebPagePrivate::~QWebPagePrivate() delete page; } -#if QT_VERSION < 0x040400 -bool QWebPagePrivate::acceptNavigationRequest(QWebFrame *frame, const QWebNetworkRequest &request, QWebPage::NavigationType type) -{ - if (insideOpenCall - && frame == mainFrame) - return true; - return q->acceptNavigationRequest(frame, request, type); -} -#else bool QWebPagePrivate::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type) { if (insideOpenCall @@ -361,7 +420,6 @@ bool QWebPagePrivate::acceptNavigationRequest(QWebFrame *frame, const QNetworkRe return true; return q->acceptNavigationRequest(frame, request, type); } -#endif void QWebPagePrivate::createMainFrame() { @@ -407,7 +465,7 @@ static QWebPage::WebAction webActionForContextMenuAction(WebCore::ContextMenuAct QMenu *QWebPagePrivate::createContextMenu(const WebCore::ContextMenu *webcoreMenu, const QList<WebCore::ContextMenuItem> *items, QBitArray *visitedWebActions) { - QMenu* menu = new QMenu(view); + QMenu* menu = new QMenu(q->view()); for (int i = 0; i < items->count(); ++i) { const ContextMenuItem &item = items->at(i); switch (item.type()) { @@ -465,13 +523,13 @@ void QWebPagePrivate::_q_webActionTriggered(bool checked) q->triggerAction(action, checked); } -#ifndef NDEBUG void QWebPagePrivate::_q_cleanupLeakMessages() { +#ifndef NDEBUG // Need this to make leak messages accurate. cache()->setCapacities(0, 0, 0); -} #endif +} void QWebPagePrivate::updateAction(QWebPage::WebAction action) { @@ -487,10 +545,10 @@ void QWebPagePrivate::updateAction(QWebPage::WebAction action) switch (action) { case QWebPage::Back: - enabled = loader->canGoBackOrForward(-1); + enabled = page->canGoBackOrForward(-1); break; case QWebPage::Forward: - enabled = loader->canGoBackOrForward(1); + enabled = page->canGoBackOrForward(1); break; case QWebPage::Stop: enabled = loader->isLoading(); @@ -608,6 +666,16 @@ void QWebPagePrivate::timerEvent(QTimerEvent *ev) q->QObject::timerEvent(ev); } +void QWebPagePrivate::mouseMoveEvent(QGraphicsSceneMouseEvent* ev) +{ + WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); + if (!frame->view()) + return; + + bool accepted = frame->eventHandler()->mouseMoved(PlatformMouseEvent(ev, 0)); + ev->setAccepted(accepted); +} + void QWebPagePrivate::mouseMoveEvent(QMouseEvent *ev) { WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); @@ -618,12 +686,38 @@ void QWebPagePrivate::mouseMoveEvent(QMouseEvent *ev) ev->setAccepted(accepted); } +void QWebPagePrivate::mousePressEvent(QGraphicsSceneMouseEvent* ev) +{ + WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); + if (!frame->view()) + return; + + if (tripleClickTimer.isActive() + && (ev->pos().toPoint() - tripleClick).manhattanLength() + < QApplication::startDragDistance()) { + mouseTripleClickEvent(ev); + return; + } + + bool accepted = false; + PlatformMouseEvent mev(ev, 1); + // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton + if (mev.button() != NoButton) + accepted = frame->eventHandler()->handleMousePressEvent(mev); + ev->setAccepted(accepted); +} + void QWebPagePrivate::mousePressEvent(QMouseEvent *ev) { WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); if (!frame->view()) return; + RefPtr<WebCore::Node> oldNode; + if (page->focusController()->focusedFrame() + && page->focusController()->focusedFrame()->document()) + oldNode = page->focusController()->focusedFrame()->document()->focusedNode(); + if (tripleClickTimer.isActive() && (ev->pos() - tripleClick).manhattanLength() < QApplication::startDragDistance()) { @@ -637,6 +731,31 @@ void QWebPagePrivate::mousePressEvent(QMouseEvent *ev) if (mev.button() != NoButton) accepted = frame->eventHandler()->handleMousePressEvent(mev); ev->setAccepted(accepted); + + RefPtr<WebCore::Node> newNode; + if (page->focusController()->focusedFrame() + && page->focusController()->focusedFrame()->document()) + newNode = page->focusController()->focusedFrame()->document()->focusedNode(); + + if (newNode && oldNode != newNode) + clickCausedFocus = true; +} + +void QWebPagePrivate::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *ev) +{ + WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); + if (!frame->view()) + return; + + bool accepted = false; + PlatformMouseEvent mev(ev, 2); + // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton + if (mev.button() != NoButton) + accepted = frame->eventHandler()->handleMousePressEvent(mev); + ev->setAccepted(accepted); + + tripleClickTimer.start(QApplication::doubleClickInterval(), q); + tripleClick = ev->pos().toPoint(); } void QWebPagePrivate::mouseDoubleClickEvent(QMouseEvent *ev) @@ -656,7 +775,7 @@ void QWebPagePrivate::mouseDoubleClickEvent(QMouseEvent *ev) tripleClick = ev->pos(); } -void QWebPagePrivate::mouseTripleClickEvent(QMouseEvent *ev) +void QWebPagePrivate::mouseTripleClickEvent(QGraphicsSceneMouseEvent *ev) { WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); if (!frame->view()) @@ -670,30 +789,33 @@ void QWebPagePrivate::mouseTripleClickEvent(QMouseEvent *ev) ev->setAccepted(accepted); } -void QWebPagePrivate::mouseReleaseEvent(QMouseEvent *ev) +void QWebPagePrivate::mouseTripleClickEvent(QMouseEvent *ev) { WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); if (!frame->view()) return; bool accepted = false; - PlatformMouseEvent mev(ev, 0); + PlatformMouseEvent mev(ev, 3); // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton if (mev.button() != NoButton) - accepted = frame->eventHandler()->handleMouseReleaseEvent(mev); + accepted = frame->eventHandler()->handleMousePressEvent(mev); ev->setAccepted(accepted); +} +void QWebPagePrivate::handleClipboard(QEvent* ev, Qt::MouseButton button) +{ #ifndef QT_NO_CLIPBOARD if (QApplication::clipboard()->supportsSelection()) { bool oldSelectionMode = Pasteboard::generalPasteboard()->isSelectionMode(); Pasteboard::generalPasteboard()->setSelectionMode(true); WebCore::Frame* focusFrame = page->focusController()->focusedOrMainFrame(); - if (ev->button() == Qt::LeftButton) { + if (button == Qt::LeftButton) { if (focusFrame && (focusFrame->editor()->canCopy() || focusFrame->editor()->canDHTMLCopy())) { focusFrame->editor()->copy(); ev->setAccepted(true); } - } else if (ev->button() == Qt::MidButton) { + } else if (button == Qt::MidButton) { if (focusFrame && (focusFrame->editor()->canPaste() || focusFrame->editor()->canDHTMLPaste())) { focusFrame->editor()->paste(); ev->setAccepted(true); @@ -704,12 +826,68 @@ void QWebPagePrivate::mouseReleaseEvent(QMouseEvent *ev) #endif } +void QWebPagePrivate::mouseReleaseEvent(QGraphicsSceneMouseEvent* ev) +{ + WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); + if (!frame->view()) + return; + + bool accepted = false; + PlatformMouseEvent mev(ev, 0); + // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton + if (mev.button() != NoButton) + accepted = frame->eventHandler()->handleMouseReleaseEvent(mev); + ev->setAccepted(accepted); + + handleClipboard(ev, ev->button()); + handleSoftwareInputPanel(ev->button()); +} + +void QWebPagePrivate::handleSoftwareInputPanel(Qt::MouseButton button) +{ +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + Frame* frame = page->focusController()->focusedFrame(); + if (!frame) + return; + + if (client && client->inputMethodEnabled() + && frame->document()->focusedNode() + && button == Qt::LeftButton && qApp->autoSipEnabled()) { + QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel( + client->ownerWidget()->style()->styleHint(QStyle::SH_RequestSoftwareInputPanel)); + if (!clickCausedFocus || behavior == QStyle::RSIP_OnMouseClick) { + QEvent event(QEvent::RequestSoftwareInputPanel); + QApplication::sendEvent(client->ownerWidget(), &event); + } + } + + clickCausedFocus = false; +#endif +} + +void QWebPagePrivate::mouseReleaseEvent(QMouseEvent *ev) +{ + WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); + if (!frame->view()) + return; + + bool accepted = false; + PlatformMouseEvent mev(ev, 0); + // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton + if (mev.button() != NoButton) + accepted = frame->eventHandler()->handleMouseReleaseEvent(mev); + ev->setAccepted(accepted); + + handleClipboard(ev, ev->button()); + handleSoftwareInputPanel(ev->button()); +} + #ifndef QT_NO_CONTEXTMENU -void QWebPagePrivate::contextMenuEvent(QContextMenuEvent *ev) +void QWebPagePrivate::contextMenuEvent(const QPoint& globalPos) { QMenu *menu = q->createStandardContextMenu(); if (menu) { - menu->exec(ev->globalPos()); + menu->exec(globalPos); delete menu; } } @@ -734,6 +912,17 @@ QMenu *QWebPage::createStandardContextMenu() } #ifndef QT_NO_WHEELEVENT +void QWebPagePrivate::wheelEvent(QGraphicsSceneWheelEvent* ev) +{ + WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); + if (!frame->view()) + return; + + WebCore::PlatformWheelEvent pev(ev); + bool accepted = frame->eventHandler()->handleWheelEvent(pev); + ev->setAccepted(accepted); +} + void QWebPagePrivate::wheelEvent(QWheelEvent *ev) { WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); @@ -804,7 +993,6 @@ void QWebPagePrivate::keyPressEvent(QKeyEvent *ev) { bool handled = false; WebCore::Frame* frame = page->focusController()->focusedOrMainFrame(); - WebCore::Editor* editor = frame->editor(); // we forward the key event to WebCore first to handle potential DOM // defined event handlers and later on end up in EditorClientQt::handleKeyboardEvent // to trigger editor commands via triggerAction(). @@ -813,10 +1001,9 @@ void QWebPagePrivate::keyPressEvent(QKeyEvent *ev) if (!handled) { handled = true; QFont defaultFont; - if (view) - defaultFont = view->font(); + if (q->view()) + defaultFont = q->view()->font(); QFontMetrics fm(defaultFont); - int fontHeight = fm.height(); if (!handleScrolling(ev, frame)) { switch (ev->key()) { case Qt::Key_Back: @@ -859,18 +1046,16 @@ void QWebPagePrivate::keyReleaseEvent(QKeyEvent *ev) ev->setAccepted(handled); } -void QWebPagePrivate::focusInEvent(QFocusEvent *ev) +void QWebPagePrivate::focusInEvent(QFocusEvent*) { FocusController *focusController = page->focusController(); - Frame *frame = focusController->focusedFrame(); focusController->setActive(true); - if (frame) - focusController->setFocused(true); - else + focusController->setFocused(true); + if (!focusController->focusedFrame()) focusController->setFocusedFrame(QWebFramePrivate::core(mainFrame)); } -void QWebPagePrivate::focusOutEvent(QFocusEvent *ev) +void QWebPagePrivate::focusOutEvent(QFocusEvent*) { // only set the focused frame inactive so that we stop painting the caret // and the focus frame. But don't tell the focus controller so that upon @@ -880,7 +1065,19 @@ void QWebPagePrivate::focusOutEvent(QFocusEvent *ev) focusController->setFocused(false); } -void QWebPagePrivate::dragEnterEvent(QDragEnterEvent *ev) +void QWebPagePrivate::dragEnterEvent(QGraphicsSceneDragDropEvent* ev) +{ +#ifndef QT_NO_DRAGANDDROP + DragData dragData(ev->mimeData(), ev->pos().toPoint(), + QCursor::pos(), dropActionToDragOp(ev->possibleActions())); + Qt::DropAction action = dragOpToDropAction(page->dragController()->dragEntered(&dragData)); + ev->setDropAction(action); + if (action != Qt::IgnoreAction) + ev->accept(); +#endif +} + +void QWebPagePrivate::dragEnterEvent(QDragEnterEvent* ev) { #ifndef QT_NO_DRAGANDDROP DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), @@ -892,7 +1089,7 @@ void QWebPagePrivate::dragEnterEvent(QDragEnterEvent *ev) #endif } -void QWebPagePrivate::dragLeaveEvent(QDragLeaveEvent *ev) +void QWebPagePrivate::dragLeaveEvent(QGraphicsSceneDragDropEvent* ev) { #ifndef QT_NO_DRAGANDDROP DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone); @@ -901,7 +1098,28 @@ void QWebPagePrivate::dragLeaveEvent(QDragLeaveEvent *ev) #endif } -void QWebPagePrivate::dragMoveEvent(QDragMoveEvent *ev) +void QWebPagePrivate::dragLeaveEvent(QDragLeaveEvent* ev) +{ +#ifndef QT_NO_DRAGANDDROP + DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone); + page->dragController()->dragExited(&dragData); + ev->accept(); +#endif +} + +void QWebPagePrivate::dragMoveEvent(QGraphicsSceneDragDropEvent* ev) +{ +#ifndef QT_NO_DRAGANDDROP + DragData dragData(ev->mimeData(), ev->pos().toPoint(), + QCursor::pos(), dropActionToDragOp(ev->possibleActions())); + Qt::DropAction action = dragOpToDropAction(page->dragController()->dragUpdated(&dragData)); + ev->setDropAction(action); + if (action != Qt::IgnoreAction) + ev->accept(); +#endif +} + +void QWebPagePrivate::dragMoveEvent(QDragMoveEvent* ev) { #ifndef QT_NO_DRAGANDDROP DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), @@ -913,7 +1131,18 @@ void QWebPagePrivate::dragMoveEvent(QDragMoveEvent *ev) #endif } -void QWebPagePrivate::dropEvent(QDropEvent *ev) +void QWebPagePrivate::dropEvent(QGraphicsSceneDragDropEvent* ev) +{ +#ifndef QT_NO_DRAGANDDROP + DragData dragData(ev->mimeData(), ev->pos().toPoint(), + QCursor::pos(), dropActionToDragOp(ev->possibleActions())); + Qt::DropAction action = dragOpToDropAction(page->dragController()->performDrag(&dragData)); + if (action != Qt::IgnoreAction) + ev->accept(); +#endif +} + +void QWebPagePrivate::dropEvent(QDropEvent* ev) { #ifndef QT_NO_DRAGANDDROP DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), @@ -924,7 +1153,7 @@ void QWebPagePrivate::dropEvent(QDropEvent *ev) #endif } -void QWebPagePrivate::leaveEvent(QEvent *ev) +void QWebPagePrivate::leaveEvent(QEvent*) { // Fake a mouse move event just outside of the widget, since all // the interesting mouse-out behavior like invalidating scrollbars @@ -967,13 +1196,53 @@ void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev) return; } + RenderObject* renderer = 0; + RenderTextControl* renderTextControl = 0; + + if (frame->selection()->rootEditableElement()) + renderer = frame->selection()->rootEditableElement()->shadowAncestorNode()->renderer(); + + if (renderer && renderer->isTextControl()) + renderTextControl = toRenderTextControl(renderer); + + Vector<CompositionUnderline> underlines; + + for (int i = 0; i < ev->attributes().size(); ++i) { + const QInputMethodEvent::Attribute& a = ev->attributes().at(i); + switch (a.type) { + case QInputMethodEvent::TextFormat: { + QTextCharFormat textCharFormat = a.value.value<QTextFormat>().toCharFormat(); + QColor qcolor = textCharFormat.underlineColor(); + underlines.append(CompositionUnderline(a.start, a.length, Color(makeRGBA(qcolor.red(), qcolor.green(), qcolor.blue(), qcolor.alpha())), false)); + break; + } + case QInputMethodEvent::Cursor: { + frame->setCaretVisible(a.length); //if length is 0 cursor is invisible + if (a.length > 0) { + RenderObject* caretRenderer = frame->selection()->caretRenderer(); + if (caretRenderer) { + QColor qcolor = a.value.value<QColor>(); + caretRenderer->style()->setColor(Color(makeRGBA(qcolor.red(), qcolor.green(), qcolor.blue(), qcolor.alpha()))); + } + } + break; + } +#if QT_VERSION >= 0x040600 + case QInputMethodEvent::Selection: { + if (renderTextControl) { + renderTextControl->setSelectionStart(a.start); + renderTextControl->setSelectionEnd(a.start + a.length); + } + break; + } +#endif + } + } + if (!ev->commitString().isEmpty()) editor->confirmComposition(ev->commitString()); - else { + else if (!ev->preeditString().isEmpty()) { QString preedit = ev->preeditString(); - // ### FIXME: use the provided QTextCharFormat (use color at least) - Vector<CompositionUnderline> underlines; - underlines.append(CompositionUnderline(0, preedit.length(), Color(0, 0, 0), false)); editor->setComposition(preedit, underlines, preedit.length(), 0); } ev->accept(); @@ -1026,16 +1295,16 @@ bool QWebPagePrivate::handleScrolling(QKeyEvent *ev, Frame *frame) granularity = ScrollByPage; direction = ScrollDown; } else if (ev == QKeySequence::MoveToPreviousPage - || (ev->key() == Qt::Key_Space) && (ev->modifiers() & Qt::ShiftModifier)) { + || ((ev->key() == Qt::Key_Space) && (ev->modifiers() & Qt::ShiftModifier))) { granularity = ScrollByPage; direction = ScrollUp; } else #endif // QT_NO_SHORTCUT - if (ev->key() == Qt::Key_Up && ev->modifiers() & Qt::ControlModifier + if ((ev->key() == Qt::Key_Up && ev->modifiers() & Qt::ControlModifier) || ev->key() == Qt::Key_Home) { granularity = ScrollByDocument; direction = ScrollUp; - } else if (ev->key() == Qt::Key_Down && ev->modifiers() & Qt::ControlModifier + } else if ((ev->key() == Qt::Key_Down && ev->modifiers() & Qt::ControlModifier) || ev->key() == Qt::Key_End) { granularity = ScrollByDocument; direction = ScrollDown; @@ -1076,45 +1345,139 @@ bool QWebPagePrivate::handleScrolling(QKeyEvent *ev, Frame *frame) */ QVariant QWebPage::inputMethodQuery(Qt::InputMethodQuery property) const { + Frame* frame = d->page->focusController()->focusedFrame(); + if (!frame) + return QVariant(); + + WebCore::Editor* editor = frame->editor(); + + RenderObject* renderer = 0; + RenderTextControl* renderTextControl = 0; + + if (frame->selection()->rootEditableElement()) + renderer = frame->selection()->rootEditableElement()->shadowAncestorNode()->renderer(); + + if (renderer && renderer->isTextControl()) + renderTextControl = toRenderTextControl(renderer); + switch (property) { - case Qt::ImMicroFocus: { - Frame *frame = d->page->focusController()->focusedFrame(); - if (frame) + case Qt::ImMicroFocus: { return QVariant(frame->selection()->absoluteCaretBounds()); - return QVariant(); - } - case Qt::ImFont: { - QWebView *webView = qobject_cast<QWebView *>(d->view); - if (webView) - return QVariant(webView->font()); - return QVariant(); - } - case Qt::ImCursorPosition: { - Frame *frame = d->page->focusController()->focusedFrame(); - if (frame) { - VisibleSelection selection = frame->selection()->selection(); - if (selection.isCaret()) - return QVariant(selection.start().deprecatedEditingOffset()); } - return QVariant(); - } - case Qt::ImSurroundingText: { - Frame *frame = d->page->focusController()->focusedFrame(); - if (frame) { - Document *document = frame->document(); - if (document->focusedNode()) - return QVariant(document->focusedNode()->nodeValue()); + case Qt::ImFont: { + if (renderTextControl) { + RenderStyle* renderStyle = renderTextControl->style(); + return QVariant(QFont(renderStyle->font().font())); + } + return QVariant(QFont()); } - return QVariant(); + case Qt::ImCursorPosition: { + if (renderTextControl) { + if (editor->hasComposition()) { + RefPtr<Range> range = editor->compositionRange(); + return QVariant(renderTextControl->selectionEnd() - TextIterator::rangeLength(range.get())); + } + return QVariant(renderTextControl->selectionEnd()); + } + return QVariant(); + } + case Qt::ImSurroundingText: { + if (renderTextControl) { + QString text = renderTextControl->text(); + RefPtr<Range> range = editor->compositionRange(); + if (range) { + text.remove(range->startPosition().offsetInContainerNode(), TextIterator::rangeLength(range.get())); + } + return QVariant(text); + } + return QVariant(); + } + case Qt::ImCurrentSelection: { + if (renderTextControl) { + int start = renderTextControl->selectionStart(); + int end = renderTextControl->selectionEnd(); + if (end > start) + return QVariant(QString(renderTextControl->text()).mid(start,end-start)); + } + return QVariant(); + + } +#if QT_VERSION >= 0x040600 + case Qt::ImAnchorPosition: { + if (renderTextControl) { + if (editor->hasComposition()) { + RefPtr<Range> range = editor->compositionRange(); + return QVariant(renderTextControl->selectionStart() - TextIterator::rangeLength(range.get())); + } + return QVariant(renderTextControl->selectionStart()); + } + return QVariant(); + } + case Qt::ImMaximumTextLength: { + if (frame->selection()->isContentEditable()) { + if (frame->document() && frame->document()->focusedNode()) { + if (frame->document()->focusedNode()->hasTagName(HTMLNames::inputTag)) { + HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(frame->document()->focusedNode()); + return QVariant(inputElement->maxLength()); + } + } + return QVariant(InputElement::s_maximumLength); + } + return QVariant(0); + } +#endif + default: + return QVariant(); } - case Qt::ImCurrentSelection: - return QVariant(selectedText()); - default: - return QVariant(); +} + +/*! + \internal +*/ +void QWebPagePrivate::setInspector(QWebInspector* insp) +{ + if (inspector) + inspector->d->setFrontend(0); + + if (inspectorIsInternalOnly) { + QWebInspector* inspToDelete = inspector; + inspector = 0; + inspectorIsInternalOnly = false; + delete inspToDelete; // Delete after to prevent infinite recursion } + + inspector = insp; + + // Give inspector frontend web view if previously created + if (inspector && inspectorFrontend) + inspector->d->setFrontend(inspectorFrontend); } /*! + \internal + Returns the inspector and creates it if it wasn't created yet. + The instance created here will not be available through QWebPage's API. +*/ +QWebInspector* QWebPagePrivate::getOrCreateInspector() +{ + if (!inspector) { + QWebInspector* insp = new QWebInspector; + insp->setPage(q); + inspectorIsInternalOnly = true; + + Q_ASSERT(inspector); // Associated through QWebInspector::setPage(q) + } + return inspector; +} + +/*! \internal */ +InspectorController* QWebPagePrivate::inspectorController() +{ + return page->inspectorController(); +} + + +/*! \enum QWebPage::FindFlag This enum describes the options available to QWebPage's findText() function. The options @@ -1252,6 +1615,8 @@ QVariant QWebPage::inputMethodQuery(Qt::InputMethodQuery property) const \since 4.4 \brief The QWebPage class provides an object to view and edit web documents. + \inmodule QtWebKit + QWebPage holds a main frame responsible for web content, settings, the history of navigated links and actions. This class can be used, together with QWebFrame, to provide functionality like QWebView in a widget-less environment. @@ -1302,7 +1667,7 @@ QVariant QWebPage::inputMethodQuery(Qt::InputMethodQuery property) const */ /*! - Constructs an empty QWebView with parent \a parent. + Constructs an empty QWebPage with parent \a parent. */ QWebPage::QWebPage(QObject *parent) : QObject(parent) @@ -1321,9 +1686,18 @@ QWebPage::QWebPage(QObject *parent) */ QWebPage::~QWebPage() { + d->createMainFrame(); FrameLoader *loader = d->mainFrame->d->frame->loader(); if (loader) loader->detachFromParent(); + if (d->inspector) { + // Since we have to delete an internal inspector, + // call setInspector(0) directly to prevent potential crashes + if (d->inspectorIsInternalOnly) + d->setInspector(0); + else + d->inspector->setPage(0); + } delete d; } @@ -1348,6 +1722,7 @@ QWebFrame *QWebPage::mainFrame() const */ QWebFrame *QWebPage::currentFrame() const { + d->createMainFrame(); return static_cast<WebCore::FrameLoaderClientQt *>(d->page->focusController()->focusedOrMainFrame()->loader()->client())->webFrame(); } @@ -1373,6 +1748,7 @@ QWebFrame* QWebPage::frameAt(const QPoint& pos) const */ QWebHistory *QWebPage::history() const { + d->createMainFrame(); return &d->history; } @@ -1383,8 +1759,19 @@ QWebHistory *QWebPage::history() const */ void QWebPage::setView(QWidget *view) { - d->view = view; - setViewportSize(view ? view->size() : QSize(0, 0)); + if (this->view() != view) { + d->view = view; + if (!view) { + delete d->client; + d->client = 0; + } else { + if (!d->client) + d->client = new QWebPageWidgetClient(view); + else + static_cast<QWebPageWidgetClient*>(d->client)->view = view; + } + setViewportSize(view ? view->size() : QSize(0, 0)); + } } /*! @@ -1394,7 +1781,11 @@ void QWebPage::setView(QWidget *view) */ QWidget *QWebPage::view() const { +#if QT_VERSION < 0x040600 return d->view; +#else + return d->view.data(); +#endif } /*! @@ -1419,8 +1810,9 @@ void QWebPage::javaScriptConsoleMessage(const QString& message, int lineNumber, */ void QWebPage::javaScriptAlert(QWebFrame *frame, const QString& msg) { + Q_UNUSED(frame) #ifndef QT_NO_MESSAGEBOX - QMessageBox::information(d->view, tr("JavaScript Alert - %1").arg(mainFrame()->url().host()), msg, QMessageBox::Ok); + QMessageBox::information(view(), tr("JavaScript Alert - %1").arg(mainFrame()->url().host()), msg, QMessageBox::Ok); #endif } @@ -1432,10 +1824,11 @@ void QWebPage::javaScriptAlert(QWebFrame *frame, const QString& msg) */ bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg) { + Q_UNUSED(frame) #ifdef QT_NO_MESSAGEBOX return true; #else - return QMessageBox::Yes == QMessageBox::information(d->view, tr("JavaScript Confirm - %1").arg(mainFrame()->url().host()), msg, QMessageBox::Yes, QMessageBox::No); + return QMessageBox::Yes == QMessageBox::information(view(), tr("JavaScript Confirm - %1").arg(mainFrame()->url().host()), msg, QMessageBox::Yes, QMessageBox::No); #endif } @@ -1450,9 +1843,10 @@ bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg) */ bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result) { + Q_UNUSED(frame) bool ok = false; #ifndef QT_NO_INPUTDIALOG - QString x = QInputDialog::getText(d->view, tr("JavaScript Prompt - %1").arg(mainFrame()->url().host()), msg, QLineEdit::Normal, defaultValue, &ok); + QString x = QInputDialog::getText(view(), tr("JavaScript Prompt - %1").arg(mainFrame()->url().host()), msg, QLineEdit::Normal, defaultValue, &ok); if (ok && result) *result = x; #endif @@ -1477,7 +1871,7 @@ bool QWebPage::shouldInterruptJavaScript() #ifdef QT_NO_MESSAGEBOX return false; #else - return QMessageBox::Yes == QMessageBox::information(d->view, tr("JavaScript Problem - %1").arg(mainFrame()->url().host()), tr("The script on this page appears to have a problem. Do you want to stop the script?"), QMessageBox::Yes, QMessageBox::No); + return QMessageBox::Yes == QMessageBox::information(view(), tr("JavaScript Problem - %1").arg(mainFrame()->url().host()), tr("The script on this page appears to have a problem. Do you want to stop the script?"), QMessageBox::Yes, QMessageBox::No); #endif } @@ -1494,7 +1888,7 @@ bool QWebPage::shouldInterruptJavaScript() */ QWebPage *QWebPage::createWindow(WebWindowType type) { - QWebView *webView = qobject_cast<QWebView *>(d->view); + QWebView *webView = qobject_cast<QWebView *>(view()); if (webView) { QWebView *newView = webView->createWindow(type); if (newView) @@ -1543,7 +1937,7 @@ static void openNewWindow(const QUrl& url, WebCore::Frame* frame) \sa action() */ -void QWebPage::triggerAction(WebAction action, bool checked) +void QWebPage::triggerAction(WebAction action, bool) { WebCore::Frame *frame = d->page->focusController()->focusedOrMainFrame(); if (!frame) @@ -1557,7 +1951,7 @@ void QWebPage::triggerAction(WebAction action, bool checked) WTF::RefPtr<WebCore::Frame> wcFrame = targetFrame->d->frame; targetFrame->d->frame->loader()->loadFrameRequest(frameLoadRequest(d->hitTestResult.linkUrl(), wcFrame.get()), /*lockHistory*/ false, /*lockBackForwardList*/ false, /*event*/ 0, - /*FormState*/ 0); + /*FormState*/ 0, SendReferrer); break; } // fall through @@ -1619,12 +2013,14 @@ void QWebPage::triggerAction(WebAction action, bool checked) case SetTextDirectionRightToLeft: editor->setBaseWritingDirection(RightToLeftWritingDirection); break; - case InspectElement: - if (!d->hitTestResult.isNull()) + case InspectElement: { + if (!d->hitTestResult.isNull()) { + d->getOrCreateInspector(); // Make sure the inspector is created + d->inspector->show(); // The inspector is expected to be shown on inspection d->page->inspectorController()->inspect(d->hitTestResult.d->innerNonSharedNode.get()); - else - d->page->inspectorController()->show(); + } break; + } default: command = QWebPagePrivate::editorCommandForWebActions(action); break; @@ -1665,7 +2061,7 @@ void QWebPage::setViewportSize(const QSize &size) const } } -QSize QWebPage::fixedContentsSize() const +QSize QWebPage::preferredContentsSize() const { QWebFrame* frame = d->mainFrame; if (frame) { @@ -1678,7 +2074,7 @@ QSize QWebPage::fixedContentsSize() const } /*! - \property QWebPage::fixedContentsSize + \property QWebPage::preferredContentsSize \since 4.6 \brief the size of the fixed layout @@ -1686,7 +2082,7 @@ QSize QWebPage::fixedContentsSize() const 1024x768 for example then webkit will layout the page as if the viewport were that size rather than something different. */ -void QWebPage::setFixedContentsSize(const QSize &size) const +void QWebPage::setPreferredContentsSize(const QSize &size) const { d->fixedLayoutSize = size; @@ -1719,12 +2115,9 @@ void QWebPage::setFixedContentsSize(const QSize &size) const \sa createWindow() */ -#if QT_VERSION >= 0x040400 bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type) -#else -bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QWebNetworkRequest &request, QWebPage::NavigationType type) -#endif { + Q_UNUSED(frame) if (type == NavigationTypeLinkClicked) { switch (d->linkPolicy) { case DontDelegateLinks: @@ -1754,6 +2147,7 @@ bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QWebNetworkReques */ QString QWebPage::selectedText() const { + d->createMainFrame(); return d->page->focusController()->focusedOrMainFrame()->selectedText(); } @@ -1809,27 +2203,19 @@ QAction *QWebPage::action(WebAction action) const case Back: text = contextMenuItemTagGoBack(); -#if QT_VERSION >= 0x040400 icon = style->standardIcon(QStyle::SP_ArrowBack); -#endif break; case Forward: text = contextMenuItemTagGoForward(); -#if QT_VERSION >= 0x040400 icon = style->standardIcon(QStyle::SP_ArrowForward); -#endif break; case Stop: text = contextMenuItemTagStop(); -#if QT_VERSION >= 0x040400 icon = style->standardIcon(QStyle::SP_BrowserStop); -#endif break; case Reload: text = contextMenuItemTagReload(); -#if QT_VERSION >= 0x040400 icon = style->standardIcon(QStyle::SP_BrowserReload); -#endif break; case Cut: @@ -2079,24 +2465,42 @@ bool QWebPage::event(QEvent *ev) case QEvent::MouseMove: d->mouseMoveEvent(static_cast<QMouseEvent*>(ev)); break; + case QEvent::GraphicsSceneMouseMove: + d->mouseMoveEvent(static_cast<QGraphicsSceneMouseEvent*>(ev)); + break; case QEvent::MouseButtonPress: d->mousePressEvent(static_cast<QMouseEvent*>(ev)); break; + case QEvent::GraphicsSceneMousePress: + d->mousePressEvent(static_cast<QGraphicsSceneMouseEvent*>(ev)); + break; case QEvent::MouseButtonDblClick: d->mouseDoubleClickEvent(static_cast<QMouseEvent*>(ev)); break; + case QEvent::GraphicsSceneMouseDoubleClick: + d->mouseDoubleClickEvent(static_cast<QGraphicsSceneMouseEvent*>(ev)); + break; case QEvent::MouseButtonRelease: d->mouseReleaseEvent(static_cast<QMouseEvent*>(ev)); break; + case QEvent::GraphicsSceneMouseRelease: + d->mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent*>(ev)); + break; #ifndef QT_NO_CONTEXTMENU case QEvent::ContextMenu: - d->contextMenuEvent(static_cast<QContextMenuEvent*>(ev)); + d->contextMenuEvent(static_cast<QContextMenuEvent*>(ev)->globalPos()); + break; + case QEvent::GraphicsSceneContextMenu: + d->contextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent*>(ev)->screenPos()); break; #endif #ifndef QT_NO_WHEELEVENT case QEvent::Wheel: d->wheelEvent(static_cast<QWheelEvent*>(ev)); break; + case QEvent::GraphicsSceneWheel: + d->wheelEvent(static_cast<QGraphicsSceneWheelEvent*>(ev)); + break; #endif case QEvent::KeyPress: d->keyPressEvent(static_cast<QKeyEvent*>(ev)); @@ -2114,15 +2518,27 @@ bool QWebPage::event(QEvent *ev) case QEvent::DragEnter: d->dragEnterEvent(static_cast<QDragEnterEvent*>(ev)); break; + case QEvent::GraphicsSceneDragEnter: + d->dragEnterEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev)); + break; case QEvent::DragLeave: d->dragLeaveEvent(static_cast<QDragLeaveEvent*>(ev)); break; + case QEvent::GraphicsSceneDragLeave: + d->dragLeaveEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev)); + break; case QEvent::DragMove: d->dragMoveEvent(static_cast<QDragMoveEvent*>(ev)); break; + case QEvent::GraphicsSceneDragMove: + d->dragMoveEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev)); + break; case QEvent::Drop: d->dropEvent(static_cast<QDropEvent*>(ev)); break; + case QEvent::GraphicsSceneDrop: + d->dropEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev)); + break; #endif case QEvent::InputMethod: d->inputMethodEvent(static_cast<QInputMethodEvent*>(ev)); @@ -2279,6 +2695,7 @@ void QWebPage::updatePositionDependentActions(const QPoint &pos) } } + d->createMainFrame(); WebCore::Frame* focusedFrame = d->page->focusController()->focusedOrMainFrame(); HitTestResult result = focusedFrame->eventHandler()->hitTestResultAtPoint(focusedFrame->view()->windowToContents(pos), /*allowShadowContent*/ false); @@ -2328,6 +2745,17 @@ void QWebPage::updatePositionDependentActions(const QPoint &pos) as a result of the user clicking on a "file upload" button in a HTML form where multiple file selection is allowed. + \omitvalue ErrorPageExtension (introduced in Qt 4.6) +*/ + +/*! + \enum QWebPage::ErrorDomain + \since 4.6 + \internal + + \value QtNetwork + \value Http + \value WebKit */ /*! @@ -2335,15 +2763,62 @@ void QWebPage::updatePositionDependentActions(const QPoint &pos) \since 4.4 \brief The ExtensionOption class provides an extended input argument to QWebPage's extension support. + \inmodule QtWebKit + \sa QWebPage::extension() */ /*! + \class QWebPage::ErrorPageExtensionOption + \since 4.6 + \brief The ErrorPageExtensionOption class describes the option + for the error page extension. + + \inmodule QtWebKit + + The ErrorPageExtensionOption class holds the \a url for which an error occoured as well as + the associated \a frame. + + The error itself is reported by an error \a domain, the \a error code as well as \a errorString. + + \sa QWebPage::ErrorPageExtensionReturn +*/ + +/*! + \class QWebPage::ErrorPageExtensionReturn + \since 4.6 + \brief The ErrorPageExtensionReturn describes the error page, which will be shown for the + frame for which the error occured. + + \inmodule QtWebKit + + The ErrorPageExtensionReturn class holds the data needed for creating an error page. Some are + optional such as \a contentType, which defaults to "text/html", as well as the \a encoding, which + is assumed to be UTF-8 if not indicated otherwise. + + The error page is stored in the \a content byte array, as HTML content. In order to convert a + QString to a byte array, the QString::toUtf8() method can be used. + + External objects such as stylesheets or images referenced in the HTML are located relative to + \a baseUrl. + + \sa QWebPage::ErrorPageExtensionOption, QString::toUtf8() +*/ + +/*! + \fn QWebPage::ErrorPageExtensionReturn::ErrorPageExtensionReturn() + + Constructs a new error page object. +*/ + +/*! \class QWebPage::ChooseMultipleFilesExtensionOption \since 4.5 \brief The ChooseMultipleFilesExtensionOption class describes the option for the multiple files selection extension. + \inmodule QtWebKit + The ChooseMultipleFilesExtensionOption class holds the frame originating the request and the suggested filenames which might be provided. @@ -2356,6 +2831,8 @@ void QWebPage::updatePositionDependentActions(const QPoint &pos) \brief The ChooseMultipleFilesExtensionReturn describes the return value for the multiple files selection extension. + \inmodule QtWebKit + The ChooseMultipleFilesExtensionReturn class holds the filenames selected by the user when the extension is invoked. @@ -2380,7 +2857,7 @@ bool QWebPage::extension(Extension extension, const ExtensionOption *option, Ext if (extension == ChooseMultipleFilesExtension) { // FIXME: do not ignore suggestedFiles QStringList suggestedFiles = static_cast<const ChooseMultipleFilesExtensionOption*>(option)->suggestedFileNames; - QStringList names = QFileDialog::getOpenFileNames(d->view, QString::null); + QStringList names = QFileDialog::getOpenFileNames(view(), QString::null); static_cast<ChooseMultipleFilesExtensionReturn*>(output)->fileNames = names; return true; } @@ -2460,46 +2937,21 @@ QWebSettings *QWebPage::settings() const */ QString QWebPage::chooseFile(QWebFrame *parentFrame, const QString& suggestedFile) { + Q_UNUSED(parentFrame) #ifndef QT_NO_FILEDIALOG - return QFileDialog::getOpenFileName(d->view, QString::null, suggestedFile); + return QFileDialog::getOpenFileName(view(), QString::null, suggestedFile); #else return QString::null; #endif } -#if QT_VERSION < 0x040400 && !defined qdoc - -void QWebPage::setNetworkInterface(QWebNetworkInterface *interface) -{ - d->networkInterface = interface; -} - -QWebNetworkInterface *QWebPage::networkInterface() const -{ - if (d->networkInterface) - return d->networkInterface; - else - return QWebNetworkInterface::defaultInterface(); -} - -#ifndef QT_NO_NETWORKPROXY -void QWebPage::setNetworkProxy(const QNetworkProxy& proxy) -{ - d->networkProxy = proxy; -} - -QNetworkProxy QWebPage::networkProxy() const -{ - return d->networkProxy; -} -#endif - -#else - /*! Sets the QNetworkAccessManager \a manager responsible for serving network requests for this QWebPage. + \note It is currently not supported to change the network access manager after the + QWebPage has used it. The results of doing this are undefined. + \sa networkAccessManager() */ void QWebPage::setNetworkAccessManager(QNetworkAccessManager *manager) @@ -2526,8 +2978,6 @@ QNetworkAccessManager *QWebPage::networkAccessManager() const return d->networkManager; } -#endif - /*! Sets the QWebPluginFactory \a factory responsible for creating plugins embedded into this QWebPage. @@ -2575,7 +3025,7 @@ QString QWebPage::userAgentForUrl(const QUrl& url) const Q_UNUSED(url) QString ua = QLatin1String("Mozilla/5.0 (" - // Plastform + // Platform #ifdef Q_WS_MAC "Macintosh" #elif defined Q_WS_QWS @@ -2584,19 +3034,22 @@ QString QWebPage::userAgentForUrl(const QUrl& url) const "Windows" #elif defined Q_WS_X11 "X11" +#elif defined Q_OS_SYMBIAN + "SymbianOS" #else "Unknown" #endif - "; " + // Placeholder for Platform Version + "%1; " // Placeholder for security strength (N or U) - "%1; " + "%2; " // Subplatform" #ifdef Q_OS_AIX "AIX" #elif defined Q_OS_WIN32 - "%2" + "%3" #elif defined Q_OS_DARWIN #ifdef __i386__ || __x86_64__ "Intel Mac OS X" @@ -2648,6 +3101,8 @@ QString QWebPage::userAgentForUrl(const QUrl& url) const "Sun Solaris" #elif defined Q_OS_ULTRIX "DEC Ultrix" +#elif defined Q_WS_S60 + "Series60" #elif defined Q_OS_UNIX "UNIX BSD/SYSV system" #elif defined Q_OS_UNIXWARE @@ -2655,7 +3110,28 @@ QString QWebPage::userAgentForUrl(const QUrl& url) const #else "Unknown" #endif - "; "); + // Placeholder for SubPlatform Version + "%4; "); + + // Platform Version + QString osVer; +#ifdef Q_OS_SYMBIAN + QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion(); + switch (symbianVersion) { + case QSysInfo::SV_9_2: + osVer = "/9.2"; + break; + case QSysInfo::SV_9_3: + osVer = "/9.3"; + break; + case QSysInfo::SV_9_4: + osVer = "/9.4"; + break; + default: + osVer = "Unknown"; + } +#endif + ua = ua.arg(osVer); QChar securityStrength(QLatin1Char('N')); #if !defined(QT_NO_OPENSSL) @@ -2698,6 +3174,11 @@ QString QWebPage::userAgentForUrl(const QUrl& url) const case QSysInfo::WV_VISTA: ver = "Windows NT 6.0"; break; +#if QT_VERSION > 0x040500 + case QSysInfo::WV_WINDOWS7: + ver = "Windows NT 6.1"; + break; +#endif case QSysInfo::WV_CE: ver = "Windows CE"; break; @@ -2714,10 +3195,30 @@ QString QWebPage::userAgentForUrl(const QUrl& url) const ua = QString(ua).arg(ver); #endif + // SubPlatform Version + QString subPlatformVer; +#ifdef Q_OS_SYMBIAN + QSysInfo::S60Version s60Version = QSysInfo::s60Version(); + switch (s60Version) { + case QSysInfo::SV_S60_3_1: + subPlatformVer = "/3.1"; + break; + case QSysInfo::SV_S60_3_2: + subPlatformVer = "/3.2"; + break; + case QSysInfo::SV_S60_5_0: + subPlatformVer = "/5.0"; + break; + default: + subPlatformVer = " Unknown"; + } +#endif + ua = ua.arg(subPlatformVer); + // Language QLocale locale; - if (d->view) - locale = d->view->locale(); + if (view()) + locale = view()->locale(); QString name = locale.name(); name[2] = QLatin1Char('-'); ua.append(name); @@ -2731,11 +3232,9 @@ QString QWebPage::userAgentForUrl(const QUrl& url) const QString appName = QCoreApplication::applicationName(); if (!appName.isEmpty()) { ua.append(appName); -#if QT_VERSION >= 0x040400 QString appVer = QCoreApplication::applicationVersion(); if (!appVer.isEmpty()) ua.append(QLatin1Char('/') + appVer); -#endif } else { // Qt version ua.append(QLatin1String("Qt/")); diff --git a/WebKit/qt/Api/qwebpage.h b/WebKit/qt/Api/qwebpage.h index 24741a1..4766cbd 100644 --- a/WebKit/qt/Api/qwebpage.h +++ b/WebKit/qt/Api/qwebpage.h @@ -25,18 +25,19 @@ #include "qwebkitglobal.h" #include <QtCore/qobject.h> +#include <QtCore/qurl.h> #include <QtGui/qwidget.h> QT_BEGIN_NAMESPACE class QNetworkProxy; class QUndoStack; -class QUrl; class QMenu; class QNetworkRequest; class QNetworkReply; class QNetworkAccessManager; QT_END_NAMESPACE +class QWebElement; class QWebFrame; class QWebNetworkRequest; class QWebHistory; @@ -55,6 +56,7 @@ namespace WebCore { class InspectorClientQt; class ResourceHandle; class HitTestResult; + class QNetworkReplyHandler; struct FrameLoadRequest; } @@ -65,7 +67,7 @@ class QWEBKIT_EXPORT QWebPage : public QObject { Q_PROPERTY(bool modified READ isModified) Q_PROPERTY(QString selectedText READ selectedText) Q_PROPERTY(QSize viewportSize READ viewportSize WRITE setViewportSize) - Q_PROPERTY(QSize fixedContentsSize READ fixedContentsSize WRITE setFixedContentsSize) + Q_PROPERTY(QSize preferredContentsSize READ preferredContentsSize WRITE setPreferredContentsSize) Q_PROPERTY(bool forwardUnsupportedContent READ forwardUnsupportedContent WRITE setForwardUnsupportedContent) Q_PROPERTY(LinkDelegationPolicy linkDelegationPolicy READ linkDelegationPolicy WRITE setLinkDelegationPolicy) Q_PROPERTY(QPalette palette READ palette WRITE setPalette) @@ -206,20 +208,8 @@ public: QUndoStack *undoStack() const; #endif -#if QT_VERSION < 0x040400 && !defined(qdoc) - void setNetworkInterface(QWebNetworkInterface *interface); - QWebNetworkInterface *networkInterface() const; - - // #### why is this in the page itself? -#ifndef QT_NO_NETWORKPROXY - void setNetworkProxy(const QNetworkProxy& proxy); - QNetworkProxy networkProxy() const; -#endif - -#else void setNetworkAccessManager(QNetworkAccessManager *manager); QNetworkAccessManager *networkAccessManager() const; -#endif void setPluginFactory(QWebPluginFactory *factory); QWebPluginFactory *pluginFactory() const; @@ -235,8 +225,8 @@ public: QSize viewportSize() const; void setViewportSize(const QSize &size) const; - QSize fixedContentsSize() const; - void setFixedContentsSize(const QSize &size) const; + QSize preferredContentsSize() const; + void setPreferredContentsSize(const QSize &size) const; virtual bool event(QEvent*); bool focusNextPrevChild(bool next); @@ -265,7 +255,8 @@ public: QMenu *createStandardContextMenu(); enum Extension { - ChooseMultipleFilesExtension + ChooseMultipleFilesExtension, + ErrorPageExtension }; class ExtensionOption {}; @@ -283,6 +274,26 @@ public: QStringList fileNames; }; + enum ErrorDomain { QtNetwork, Http, WebKit }; + class ErrorPageExtensionOption : public ExtensionOption { + public: + QUrl url; + QWebFrame* frame; + ErrorDomain domain; + int error; + QString errorString; + }; + + class ErrorPageExtensionReturn : public ExtensionReturn { + public: + ErrorPageExtensionReturn() : contentType(QLatin1String("text/html")), encoding(QLatin1String("utf-8")) {}; + QString contentType; + QString encoding; + QUrl baseUrl; + QByteArray content; + }; + + virtual bool extension(Extension extension, const ExtensionOption *option = 0, ExtensionReturn *output = 0); virtual bool supportsExtension(Extension extension) const; @@ -311,10 +322,8 @@ Q_SIGNALS: void statusBarVisibilityChangeRequested(bool visible); void menuBarVisibilityChangeRequested(bool visible); -#if QT_VERSION >= 0x040400 void unsupportedContent(QNetworkReply *reply); void downloadRequested(const QNetworkRequest &request); -#endif void microFocusChanged(); void contentsChanged(); @@ -327,11 +336,7 @@ protected: virtual QWebPage *createWindow(WebWindowType type); virtual QObject *createPlugin(const QString &classid, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues); -#if QT_VERSION >= 0x040400 virtual bool acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type); -#else - virtual bool acceptNavigationRequest(QWebFrame *frame, const QWebNetworkRequest &request, NavigationType type); -#endif virtual QString chooseFile(QWebFrame *originatingFrame, const QString& oldFile); virtual void javaScriptAlert(QWebFrame *originatingFrame, const QString& msg); virtual bool javaScriptConfirm(QWebFrame *originatingFrame, const QString& msg); @@ -343,19 +348,21 @@ protected: private: Q_PRIVATE_SLOT(d, void _q_onLoadProgressChanged(int)) Q_PRIVATE_SLOT(d, void _q_webActionTriggered(bool checked)) -#ifndef NDEBUG Q_PRIVATE_SLOT(d, void _q_cleanupLeakMessages()) -#endif + QWebPagePrivate *d; friend class QWebFrame; friend class QWebPagePrivate; friend class QWebView; + friend class QGraphicsWebView; + friend class QWebInspector; friend class WebCore::ChromeClientQt; friend class WebCore::EditorClientQt; friend class WebCore::FrameLoaderClientQt; friend class WebCore::InspectorClientQt; friend class WebCore::ResourceHandle; + friend class WebCore::QNetworkReplyHandler; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QWebPage::FindFlags) diff --git a/WebKit/qt/Api/qwebpage_p.h b/WebKit/qt/Api/qwebpage_p.h index 87c624d..5d97da4 100644 --- a/WebKit/qt/Api/qwebpage_p.h +++ b/WebKit/qt/Api/qwebpage_p.h @@ -25,6 +25,7 @@ #include <qnetworkproxy.h> #include <qpointer.h> #include <qevent.h> +#include <qgraphicssceneevent.h> #include "qwebpage.h" #include "qwebhistory.h" @@ -42,21 +43,10 @@ namespace WebCore { class ContextMenu; class EditorClientQt; class Element; + class InspectorController; class Node; class Page; class Frame; - -#ifndef QT_NO_CURSOR - class SetCursorEvent : public QEvent { - public: - static const int EventType = 724; - SetCursorEvent(const QCursor&); - - QCursor cursor() const; - private: - QCursor m_cursor; - }; -#endif } QT_BEGIN_NAMESPACE @@ -65,6 +55,9 @@ class QMenu; class QBitArray; QT_END_NAMESPACE +class QWebInspector; +class QWebPageClient; + class QWebPagePrivate { public: QWebPagePrivate(QWebPage*); @@ -75,9 +68,7 @@ public: #endif void _q_onLoadProgressChanged(int); void _q_webActionTriggered(bool checked); -#ifndef NDEBUG void _q_cleanupLeakMessages(); -#endif void updateAction(QWebPage::WebAction action); void updateNavigationActions(); void updateEditorActions(); @@ -85,32 +76,48 @@ public: void timerEvent(QTimerEvent*); void mouseMoveEvent(QMouseEvent*); + void mouseMoveEvent(QGraphicsSceneMouseEvent*); void mousePressEvent(QMouseEvent*); + void mousePressEvent(QGraphicsSceneMouseEvent*); void mouseDoubleClickEvent(QMouseEvent*); + void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*); void mouseTripleClickEvent(QMouseEvent*); + void mouseTripleClickEvent(QGraphicsSceneMouseEvent*); void mouseReleaseEvent(QMouseEvent*); + void mouseReleaseEvent(QGraphicsSceneMouseEvent*); #ifndef QT_NO_CONTEXTMENU - void contextMenuEvent(QContextMenuEvent*); + void contextMenuEvent(const QPoint& globalPos); #endif #ifndef QT_NO_WHEELEVENT void wheelEvent(QWheelEvent*); + void wheelEvent(QGraphicsSceneWheelEvent*); #endif void keyPressEvent(QKeyEvent*); void keyReleaseEvent(QKeyEvent*); void focusInEvent(QFocusEvent*); void focusOutEvent(QFocusEvent*); - void dragEnterEvent(QDragEnterEvent *); - void dragLeaveEvent(QDragLeaveEvent *); - void dragMoveEvent(QDragMoveEvent *); - void dropEvent(QDropEvent *); + void dragEnterEvent(QDragEnterEvent*); + void dragEnterEvent(QGraphicsSceneDragDropEvent*); + void dragLeaveEvent(QDragLeaveEvent*); + void dragLeaveEvent(QGraphicsSceneDragDropEvent*); + void dragMoveEvent(QDragMoveEvent*); + void dragMoveEvent(QGraphicsSceneDragDropEvent*); + void dropEvent(QDropEvent*); + void dropEvent(QGraphicsSceneDragDropEvent*); void inputMethodEvent(QInputMethodEvent*); void shortcutOverrideEvent(QKeyEvent*); - void leaveEvent(QEvent *); + void leaveEvent(QEvent*); + void handleClipboard(QEvent*, Qt::MouseButton); + void handleSoftwareInputPanel(Qt::MouseButton); bool handleScrolling(QKeyEvent*, WebCore::Frame*); + void setInspector(QWebInspector*); + QWebInspector* getOrCreateInspector(); + WebCore::InspectorController* inspectorController(); + #ifndef QT_NO_SHORTCUT static QWebPage::WebAction editorActionForKeyEvent(QKeyEvent* event); #endif @@ -124,10 +131,16 @@ public: QPointer<QWebFrame> mainFrame; QWebPage *q; + QWebPageClient* client; #ifndef QT_NO_UNDOSTACK QUndoStack *undoStack; #endif - QWidget *view; + +#if QT_VERSION >= 0x040600 + QWeakPointer<QWidget> view; +#else + QWidget* view; +#endif bool insideOpenCall; quint64 m_totalBytes; @@ -136,18 +149,10 @@ public: QPoint tripleClick; QBasicTimer tripleClickTimer; -#if QT_VERSION < 0x040400 - bool acceptNavigationRequest(QWebFrame *frame, const QWebNetworkRequest &request, QWebPage::NavigationType type); - - QWebNetworkInterface *networkInterface; -#ifndef QT_NO_NETWORKPROXY - QNetworkProxy networkProxy; -#endif + bool clickCausedFocus; -#else bool acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type); QNetworkAccessManager *networkManager; -#endif bool forwardUnsupportedContent; QWebPage::LinkDelegationPolicy linkPolicy; @@ -168,6 +173,10 @@ public: QWebPluginFactory *pluginFactory; + QWidget* inspectorFrontend; + QWebInspector* inspector; + bool inspectorIsInternalOnly; // True if created through the Inspect context menu action + static bool drtRun; }; diff --git a/WebKit/qt/Api/qwebplugindatabase.cpp b/WebKit/qt/Api/qwebplugindatabase.cpp index 8758c60..758e257 100644 --- a/WebKit/qt/Api/qwebplugindatabase.cpp +++ b/WebKit/qt/Api/qwebplugindatabase.cpp @@ -18,7 +18,6 @@ */ #include "config.h" -#include "qwebplugindatabase.h" #include "qwebplugindatabase_p.h" #include "PluginDatabase.h" @@ -27,23 +26,15 @@ using namespace WebCore; /*! + \internal \typedef QWebPluginInfo::MimeType \since 4.6 \brief Represents a single MIME type supported by a plugin. */ -QWebPluginInfoPrivate::QWebPluginInfoPrivate(RefPtr<PluginPackage> pluginPackage) - : plugin(pluginPackage) -{ -} - -QWebPluginDatabasePrivate::QWebPluginDatabasePrivate(PluginDatabase* pluginDatabase) - : database(pluginDatabase) -{ -} - /*! \class QWebPluginInfo + \internal \since 4.6 \brief The QWebPluginInfo class represents a single Netscape plugin. @@ -64,21 +55,25 @@ QWebPluginDatabasePrivate::QWebPluginDatabasePrivate(PluginDatabase* pluginDatab Constructs a null QWebPluginInfo. */ QWebPluginInfo::QWebPluginInfo() - : d(new QWebPluginInfoPrivate(0)) + : m_package(0) { } -QWebPluginInfo::QWebPluginInfo(PluginPackage* plugin) - : d(new QWebPluginInfoPrivate(plugin)) +QWebPluginInfo::QWebPluginInfo(PluginPackage* package) + : m_package(package) { + if (m_package) + m_package->ref(); } /*! Contructs a copy of \a other. */ QWebPluginInfo::QWebPluginInfo(const QWebPluginInfo& other) - : d(new QWebPluginInfoPrivate(other.d->plugin)) + : m_package(other.m_package) { + if (m_package) + m_package->ref(); } /*! @@ -86,7 +81,8 @@ QWebPluginInfo::QWebPluginInfo(const QWebPluginInfo& other) */ QWebPluginInfo::~QWebPluginInfo() { - delete d; + if (m_package) + m_package->deref(); } /*! @@ -96,9 +92,9 @@ QWebPluginInfo::~QWebPluginInfo() */ QString QWebPluginInfo::name() const { - if (!d->plugin) + if (!m_package) return QString(); - return d->plugin->name(); + return m_package->name(); } /*! @@ -108,9 +104,9 @@ QString QWebPluginInfo::name() const */ QString QWebPluginInfo::description() const { - if (!d->plugin) + if (!m_package) return QString(); - return d->plugin->description(); + return m_package->description(); } /*! @@ -120,28 +116,27 @@ QString QWebPluginInfo::description() const */ QList<QWebPluginInfo::MimeType> QWebPluginInfo::mimeTypes() const { - if (!d->plugin) - return QList<MimeType>(); + if (m_package && m_mimeTypes.isEmpty()) { + const MIMEToDescriptionsMap& mimeToDescriptions = m_package->mimeToDescriptions(); + MIMEToDescriptionsMap::const_iterator end = mimeToDescriptions.end(); - QList<MimeType> mimeTypes; - const MIMEToDescriptionsMap& mimeToDescriptions = d->plugin->mimeToDescriptions(); - MIMEToDescriptionsMap::const_iterator end = mimeToDescriptions.end(); - for (MIMEToDescriptionsMap::const_iterator it = mimeToDescriptions.begin(); it != end; ++it) { - MimeType mimeType; - mimeType.name = it->first; - mimeType.description = it->second; + for (MIMEToDescriptionsMap::const_iterator it = mimeToDescriptions.begin(); it != end; ++it) { + MimeType mimeType; + mimeType.name = it->first; + mimeType.description = it->second; - QStringList fileExtensions; - Vector<String> extensions = d->plugin->mimeToExtensions().get(mimeType.name); + QStringList fileExtensions; + Vector<String> extensions = m_package->mimeToExtensions().get(mimeType.name); - for (unsigned i = 0; i < extensions.size(); ++i) - fileExtensions.append(extensions[i]); + for (unsigned i = 0; i < extensions.size(); ++i) + fileExtensions.append(extensions[i]); - mimeType.fileExtensions = fileExtensions; - mimeTypes.append(mimeType); + mimeType.fileExtensions = fileExtensions; + m_mimeTypes.append(mimeType); + } } - return mimeTypes; + return m_mimeTypes; } /*! @@ -152,13 +147,9 @@ QList<QWebPluginInfo::MimeType> QWebPluginInfo::mimeTypes() const */ bool QWebPluginInfo::supportsMimeType(const QString& mimeType) const { - QList<MimeType> types = mimeTypes(); - foreach (const MimeType& type, types) { - if (type.name == mimeType) - return true; - } - - return false; + if (!m_package) + return false; + return m_package->mimeToDescriptions().contains(mimeType); } /*! @@ -166,9 +157,9 @@ bool QWebPluginInfo::supportsMimeType(const QString& mimeType) const */ QString QWebPluginInfo::path() const { - if (!d->plugin) + if (!m_package) return QString(); - return d->plugin->path(); + return m_package->path(); } /*! @@ -176,7 +167,7 @@ QString QWebPluginInfo::path() const */ bool QWebPluginInfo::isNull() const { - return !d->plugin; + return !m_package; } /*! @@ -189,9 +180,9 @@ bool QWebPluginInfo::isNull() const */ void QWebPluginInfo::setEnabled(bool enabled) { - if (!d->plugin) + if (!m_package) return; - d->plugin->setEnabled(enabled); + m_package->setEnabled(enabled); } /*! @@ -201,32 +192,49 @@ void QWebPluginInfo::setEnabled(bool enabled) */ bool QWebPluginInfo::isEnabled() const { - if (!d->plugin) + if (!m_package) return false; - return d->plugin->isEnabled(); + return m_package->isEnabled(); } +/*! + Returns true if this plugin info is the same as the \a other plugin info. +*/ bool QWebPluginInfo::operator==(const QWebPluginInfo& other) const { - return d->plugin == other.d->plugin; + return m_package == other.m_package; } +/*! + Returns true if this plugin info is different from the \a other plugin info. +*/ bool QWebPluginInfo::operator!=(const QWebPluginInfo& other) const { - return d->plugin != other.d->plugin; + return m_package != other.m_package; } +/*! + Assigns the \a other plugin info to this plugin info, and returns a reference + to this plugin info. +*/ QWebPluginInfo &QWebPluginInfo::operator=(const QWebPluginInfo& other) { if (this == &other) return *this; - d->plugin = other.d->plugin; + if (m_package) + m_package->deref(); + m_package = other.m_package; + if (m_package) + m_package->ref(); + m_mimeTypes = other.m_mimeTypes; + return *this; } /*! \class QWebPluginDatabase + \internal \since 4.6 \brief The QWebPluginDatabase class provides an interface for managing Netscape plugins used by WebKit in QWebPages. @@ -253,13 +261,12 @@ QWebPluginInfo &QWebPluginInfo::operator=(const QWebPluginInfo& other) QWebPluginDatabase::QWebPluginDatabase(QObject* parent) : QObject(parent) - , d(new QWebPluginDatabasePrivate(PluginDatabase::installedPlugins())) + , m_database(PluginDatabase::installedPlugins()) { } QWebPluginDatabase::~QWebPluginDatabase() { - delete d; } /*! @@ -273,7 +280,7 @@ QWebPluginDatabase::~QWebPluginDatabase() QList<QWebPluginInfo> QWebPluginDatabase::plugins() const { QList<QWebPluginInfo> qwebplugins; - const Vector<PluginPackage*>& plugins = d->database->plugins(); + const Vector<PluginPackage*>& plugins = m_database->plugins(); for (unsigned int i = 0; i < plugins.size(); ++i) { PluginPackage* plugin = plugins[i]; @@ -308,7 +315,7 @@ QStringList QWebPluginDatabase::searchPaths() const { QStringList paths; - const Vector<String>& directories = d->database->pluginDirectories(); + const Vector<String>& directories = m_database->pluginDirectories(); for (unsigned int i = 0; i < directories.size(); ++i) paths.append(directories[i]); @@ -325,12 +332,12 @@ void QWebPluginDatabase::setSearchPaths(const QStringList& paths) { Vector<String> directories; - for (unsigned int i = 0; i < paths.count(); ++i) + for (int i = 0; i < paths.count(); ++i) directories.append(paths.at(i)); - d->database->setPluginDirectories(directories); + m_database->setPluginDirectories(directories); // PluginDatabase::setPluginDirectories() does not refresh the database. - d->database->refresh(); + m_database->refresh(); } /*! @@ -341,7 +348,7 @@ void QWebPluginDatabase::setSearchPaths(const QStringList& paths) */ void QWebPluginDatabase::addSearchPath(const QString& path) { - d->database->addExtraPluginDirectory(path); + m_database->addExtraPluginDirectory(path); // PluginDatabase::addExtraPluginDirectory() does refresh the database. } @@ -355,7 +362,7 @@ void QWebPluginDatabase::addSearchPath(const QString& path) */ void QWebPluginDatabase::refresh() { - d->database->refresh(); + m_database->refresh(); } /*! @@ -365,7 +372,7 @@ void QWebPluginDatabase::refresh() */ QWebPluginInfo QWebPluginDatabase::pluginForMimeType(const QString& mimeType) { - return QWebPluginInfo(d->database->pluginForMIMEType(mimeType)); + return QWebPluginInfo(m_database->pluginForMIMEType(mimeType)); } /*! @@ -378,5 +385,5 @@ QWebPluginInfo QWebPluginDatabase::pluginForMimeType(const QString& mimeType) */ void QWebPluginDatabase::setPreferredPluginForMimeType(const QString& mimeType, const QWebPluginInfo& plugin) { - d->database->setPreferredPluginForMIMEType(mimeType, plugin.d->plugin.get()); + m_database->setPreferredPluginForMIMEType(mimeType, plugin.m_package); } diff --git a/WebKit/qt/Api/qwebplugindatabase.h b/WebKit/qt/Api/qwebplugindatabase.h deleted file mode 100644 index 4b50119..0000000 --- a/WebKit/qt/Api/qwebplugindatabase.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - Copyright (C) 2009 Jakub Wieczorek <faw217@gmail.com> - - 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. -*/ - -#ifndef QWEBPLUGINDATABASE_H -#define QWEBPLUGINDATABASE_H - -#include "qwebkitglobal.h" -#include "qwebpluginfactory.h" - -#include <QtCore/qobject.h> -#include <QtCore/qstringlist.h> - -namespace WebCore { - class PluginPackage; -} - -class QWebPluginInfoPrivate; -class QWEBKIT_EXPORT QWebPluginInfo { -public: - QWebPluginInfo(); - QWebPluginInfo(const QWebPluginInfo& other); - QWebPluginInfo &operator=(const QWebPluginInfo& other); - ~QWebPluginInfo(); - -private: - QWebPluginInfo(WebCore::PluginPackage* plugin); - -public: - typedef QWebPluginFactory::MimeType MimeType; - - QString name() const; - QString description() const; - QList<MimeType> mimeTypes() const; - bool supportsMimeType(const QString& mimeType) const; - QString path() const; - - bool isNull() const; - - void setEnabled(bool enabled); - bool isEnabled() const; - - bool operator==(const QWebPluginInfo& other) const; - bool operator!=(const QWebPluginInfo& other) const; - - friend class QWebPluginDatabase; - -private: - QWebPluginInfoPrivate *d; -}; - -class QWebPluginDatabasePrivate; -class QWEBKIT_EXPORT QWebPluginDatabase : public QObject { - Q_OBJECT - -private: - QWebPluginDatabase(QObject* parent = 0); - ~QWebPluginDatabase(); - -public: - QList<QWebPluginInfo> plugins() const; - - static QStringList defaultSearchPaths(); - QStringList searchPaths() const; - void setSearchPaths(const QStringList& paths); - void addSearchPath(const QString& path); - - void refresh(); - - QWebPluginInfo pluginForMimeType(const QString& mimeType); - void setPreferredPluginForMimeType(const QString& mimeType, const QWebPluginInfo& plugin); - - friend class QWebSettings; - -private: - QWebPluginDatabasePrivate *d; -}; - -#endif // QWEBPLUGINDATABASE_H diff --git a/WebKit/qt/Api/qwebplugindatabase_p.h b/WebKit/qt/Api/qwebplugindatabase_p.h index 714458f..b22c3de 100644 --- a/WebKit/qt/Api/qwebplugindatabase_p.h +++ b/WebKit/qt/Api/qwebplugindatabase_p.h @@ -17,30 +17,82 @@ Boston, MA 02110-1301, USA. */ -#ifndef QWEBPLUGINDATABASE_P_H -#define QWEBPLUGINDATABASE_P_H +#ifndef QWEBPLUGINDATABASE_H +#define QWEBPLUGINDATABASE_H #include "qwebkitglobal.h" +#include "qwebpluginfactory.h" -#include <wtf/RefPtr.h> +#include <QtCore/qobject.h> +#include <QtCore/qstringlist.h> namespace WebCore { - class PluginPackage; class PluginDatabase; -}; + class PluginPackage; +} -class QWebPluginInfoPrivate { +class QWebPluginInfoPrivate; +class QWEBKIT_EXPORT QWebPluginInfo { public: - QWebPluginInfoPrivate(RefPtr<WebCore::PluginPackage> pluginPackage); + QWebPluginInfo(); + QWebPluginInfo(const QWebPluginInfo& other); + QWebPluginInfo &operator=(const QWebPluginInfo& other); + ~QWebPluginInfo(); + +private: + QWebPluginInfo(WebCore::PluginPackage* package); + +public: + typedef QWebPluginFactory::MimeType MimeType; + + QString name() const; + QString description() const; + QList<MimeType> mimeTypes() const; + bool supportsMimeType(const QString& mimeType) const; + QString path() const; + + bool isNull() const; + + void setEnabled(bool enabled); + bool isEnabled() const; - RefPtr<WebCore::PluginPackage> plugin; + bool operator==(const QWebPluginInfo& other) const; + bool operator!=(const QWebPluginInfo& other) const; + + friend class QWebPluginDatabase; + +private: + QWebPluginInfoPrivate* d; + WebCore::PluginPackage* m_package; + mutable QList<MimeType> m_mimeTypes; }; -class QWebPluginDatabasePrivate { +class QWebPluginDatabasePrivate; +class QWEBKIT_EXPORT QWebPluginDatabase : public QObject { + Q_OBJECT + +private: + QWebPluginDatabase(QObject* parent = 0); + ~QWebPluginDatabase(); + public: - QWebPluginDatabasePrivate(WebCore::PluginDatabase* pluginDatabase); + QList<QWebPluginInfo> plugins() const; + + static QStringList defaultSearchPaths(); + QStringList searchPaths() const; + void setSearchPaths(const QStringList& paths); + void addSearchPath(const QString& path); + + void refresh(); + + QWebPluginInfo pluginForMimeType(const QString& mimeType); + void setPreferredPluginForMimeType(const QString& mimeType, const QWebPluginInfo& plugin); + + friend class QWebSettings; - WebCore::PluginDatabase* database; +private: + QWebPluginDatabasePrivate* d; + WebCore::PluginDatabase* m_database; }; -#endif // QWEBPLUGINDATABASE_P_H +#endif // QWEBPLUGINDATABASE_H diff --git a/WebKit/qt/Api/qwebpluginfactory.cpp b/WebKit/qt/Api/qwebpluginfactory.cpp index 7a8cabe..8ff13b1 100644 --- a/WebKit/qt/Api/qwebpluginfactory.cpp +++ b/WebKit/qt/Api/qwebpluginfactory.cpp @@ -26,6 +26,8 @@ \brief The QWebPluginFactory class creates plugins to be embedded into web pages. + \inmodule QtWebKit + QWebPluginFactory is a factory for creating plugins for QWebPage. A plugin factory can be installed on a QWebPage using QWebPage::setPluginFactory(). @@ -47,6 +49,8 @@ \class QWebPluginFactory::Plugin \since 4.4 \brief the QWebPluginFactory::Plugin structure describes the properties of a plugin a QWebPluginFactory can create. + + \inmodule QtWebKit */ /*! @@ -68,8 +72,13 @@ \class QWebPluginFactory::MimeType \since 4.4 \brief The QWebPluginFactory::MimeType structure describes a mime type supported by a plugin. + + \inmodule QtWebKit */ +/*! + Returns true if this mimetype is the same as the \a other mime type. +*/ bool QWebPluginFactory::MimeType::operator==(const MimeType& other) const { return name == other.name @@ -78,6 +87,12 @@ bool QWebPluginFactory::MimeType::operator==(const MimeType& other) const } /*! + \fn bool QWebPluginFactory::MimeType::operator!=(const MimeType& other) const + + Returns true if this mimetype is different from the \a other mime type. +*/ + +/*! \variable QWebPluginFactory::MimeType::name The full name of the MIME type; e.g., \c{text/plain} or \c{image/png}. @@ -143,7 +158,7 @@ void QWebPluginFactory::refreshPlugins() For example: \code - <object type="application/x-pdf" data="http://qtsoftware.com/document.pdf" width="500" height="400"> + <object type="application/x-pdf" data="http://qt.nokia.com/document.pdf" width="500" height="400"> <param name="showTableOfContents" value="true" /> <param name="hideThumbnails" value="false" /> </object> @@ -156,7 +171,7 @@ void QWebPluginFactory::refreshPlugins() \row \o mimeType \o "application/x-pdf" \row \o url - \o "http://qtsoftware.com/document.pdf" + \o "http://qt.nokia.com/document.pdf" \row \o argumentNames \o "showTableOfContents" "hideThumbnails" \row \o argumentVaues @@ -180,6 +195,8 @@ void QWebPluginFactory::refreshPlugins() \since 4.4 \brief The ExtensionOption class provides an extended input argument to QWebPluginFactory's extension support. + \inmodule QtWebKit + \sa QWebPluginFactory::extension() */ @@ -188,6 +205,8 @@ void QWebPluginFactory::refreshPlugins() \since 4.4 \brief The ExtensionOption class provides an extended output argument to QWebPluginFactory's extension support. + \inmodule QtWebKit + \sa QWebPluginFactory::extension() */ diff --git a/WebKit/qt/Api/qwebsecurityorigin.cpp b/WebKit/qt/Api/qwebsecurityorigin.cpp index d2eaf10..2a225c5 100644 --- a/WebKit/qt/Api/qwebsecurityorigin.cpp +++ b/WebKit/qt/Api/qwebsecurityorigin.cpp @@ -30,11 +30,23 @@ using namespace WebCore; +void QWEBKIT_EXPORT qt_drt_whiteListAccessFromOrigin(const QString& sourceOrigin, const QString& destinationProtocol, const QString& destinationHost, bool allowDestinationSubdomains) +{ + SecurityOrigin::whiteListAccessFromOrigin(*SecurityOrigin::createFromString(sourceOrigin), destinationProtocol, destinationHost, allowDestinationSubdomains); +} + +void QWEBKIT_EXPORT qt_drt_resetOriginAccessWhiteLists() +{ + SecurityOrigin::resetOriginAccessWhiteLists(); +} + /*! \class QWebSecurityOrigin \since 4.5 \brief The QWebSecurityOrigin class defines a security boundary for web sites. + \inmodule QtWebKit + QWebSecurityOrigin provides access to the security domains defined by web sites. An origin consists of a host name, a scheme, and a port number. Web sites with the same security origin can access each other's resources for client-side @@ -198,3 +210,42 @@ QList<QWebDatabase> QWebSecurityOrigin::databases() const return databases; } +/*! + \since 4.6 + + Adds the given \a scheme to the list of schemes that are considered equivalent + to the \c file: scheme. They are not subject to cross domain restrictions. +*/ +void QWebSecurityOrigin::addLocalScheme(const QString& scheme) +{ + SecurityOrigin::registerURLSchemeAsLocal(scheme); +} + +/*! + \since 4.6 + + Removes the given \a scheme from the list of local schemes. + + \sa addLocalScheme() +*/ +void QWebSecurityOrigin::removeLocalScheme(const QString& scheme) +{ + SecurityOrigin::removeURLSchemeRegisteredAsLocal(scheme); +} + +/*! + \since 4.6 + Returns a list of all the schemes that were set by the application as local schemes, + \sa addLocalScheme(), removeLocalScheme() +*/ +QStringList QWebSecurityOrigin::localSchemes() +{ + QStringList list; + const URLSchemesMap& map = SecurityOrigin::localURLSchemes(); + URLSchemesMap::const_iterator end = map.end(); + for (URLSchemesMap::const_iterator i = map.begin(); i != end; ++i) { + const QString scheme = *i; + list.append(scheme); + } + return list; +} diff --git a/WebKit/qt/Api/qwebsecurityorigin.h b/WebKit/qt/Api/qwebsecurityorigin.h index 3cfb0f4..16f8bc1 100644 --- a/WebKit/qt/Api/qwebsecurityorigin.h +++ b/WebKit/qt/Api/qwebsecurityorigin.h @@ -37,6 +37,9 @@ class QWebFrame; class QWEBKIT_EXPORT QWebSecurityOrigin { public: static QList<QWebSecurityOrigin> allOrigins(); + static void addLocalScheme(const QString& scheme); + static void removeLocalScheme(const QString& scheme); + static QStringList localSchemes(); ~QWebSecurityOrigin(); diff --git a/WebKit/qt/Api/qwebsettings.cpp b/WebKit/qt/Api/qwebsettings.cpp index 47b2818..9a5ab46 100644 --- a/WebKit/qt/Api/qwebsettings.cpp +++ b/WebKit/qt/Api/qwebsettings.cpp @@ -22,7 +22,7 @@ #include "qwebpage.h" #include "qwebpage_p.h" -#include "qwebplugindatabase.h" +#include "qwebplugindatabase_p.h" #include "Cache.h" #include "CrossOriginPreflightResultCache.h" @@ -37,7 +37,11 @@ #include "IntSize.h" #include "ApplicationCacheStorage.h" #include "DatabaseTracker.h" +#include "FileSystem.h" +#include <QApplication> +#include <QDesktopServices> +#include <QDir> #include <QHash> #include <QSharedData> #include <QUrl> @@ -55,7 +59,7 @@ public: QHash<int, bool> attributes; QUrl userStyleSheetLocation; QString defaultTextEncoding; - QString localStorageDatabasePath; + QString localStoragePath; QString offlineWebApplicationCachePath; qint64 offlineStorageDefaultQuota; @@ -75,6 +79,7 @@ static WebGraphicHash* graphics() hash->insert(QWebSettings::MissingPluginGraphic, QPixmap(QLatin1String(":webkit/resources/nullPlugin.png"))); hash->insert(QWebSettings::DefaultFrameIconGraphic, QPixmap(QLatin1String(":webkit/resources/urlIcon.png"))); hash->insert(QWebSettings::TextAreaSizeGripCornerGraphic, QPixmap(QLatin1String(":webkit/resources/textAreaResizeCorner.png"))); + hash->insert(QWebSettings::DeleteButtonGraphic, QPixmap(QLatin1String(":webkit/resources/deleteButton.png"))); } return hash; @@ -167,8 +172,8 @@ void QWebSettingsPrivate::apply() QString encoding = !defaultTextEncoding.isEmpty() ? defaultTextEncoding: global->defaultTextEncoding; settings->setDefaultTextEncodingName(encoding); - QString localStoragePath = !localStorageDatabasePath.isEmpty() ? localStorageDatabasePath : global->localStorageDatabasePath; - settings->setLocalStorageDatabasePath(localStoragePath); + QString storagePath = !localStoragePath.isEmpty() ? localStoragePath : global->localStoragePath; + settings->setLocalStorageDatabasePath(storagePath); value = attributes.value(QWebSettings::ZoomTextOnly, global->attributes.value(QWebSettings::ZoomTextOnly)); @@ -186,13 +191,15 @@ void QWebSettingsPrivate::apply() global->attributes.value(QWebSettings::OfflineWebApplicationCacheEnabled)); settings->setOfflineWebApplicationCacheEnabled(value); - value = attributes.value(QWebSettings::LocalStorageDatabaseEnabled, - global->attributes.value(QWebSettings::LocalStorageDatabaseEnabled)); + value = attributes.value(QWebSettings::LocalStorageEnabled, + global->attributes.value(QWebSettings::LocalStorageEnabled)); + settings->setLocalStorageEnabled(value); value = attributes.value(QWebSettings::LocalContentCanAccessRemoteUrls, global->attributes.value(QWebSettings::LocalContentCanAccessRemoteUrls)); settings->setAllowUniversalAccessFromFileURLs(value); + settings->setUsesPageCache(WebCore::pageCache()->capacity()); } else { QList<QWebSettingsPrivate*> settings = *::allSettings(); for (int i = 0; i < settings.count(); ++i) @@ -220,6 +227,8 @@ QWebSettings* QWebSettings::globalSettings() \brief The QWebSettings class provides an object to store the settings used by QWebPage and QWebFrame. + \inmodule QtWebKit + Each QWebPage object has its own QWebSettings object, which configures the settings for that page. If a setting is not configured, then it is looked up in the global settings object, which can be accessed using @@ -254,7 +263,7 @@ QWebSettings* QWebSettings::globalSettings() setOfflineStoragePath() with an appropriate file path, and can limit the quota for each application by calling setOfflineStorageDefaultQuota(). - \sa QWebPage::settings(), QWebView::settings(), {Browser} + \sa QWebPage::settings(), QWebView::settings(), {Web Browser} */ /*! @@ -302,6 +311,8 @@ QWebSettings* QWebSettings::globalSettings() \value AutoLoadImages Specifies whether images are automatically loaded in web pages. + \value DnsPrefetchEnabled Specifies whether QtWebkit will try to pre-fetch DNS entries to + speed up browsing. This only works as a global attribute. Only for Qt 4.6 and later. \value JavascriptEnabled Enables or disables the running of JavaScript programs. \value JavaEnabled Enables or disables Java applets. @@ -314,8 +325,9 @@ QWebSettings* QWebSettings::globalSettings() \value JavascriptCanAccessClipboard Specifies whether JavaScript programs can read or write to the clipboard. \value DeveloperExtrasEnabled Enables extra tools for Web developers. - Currently this enables the "Inspect" element in the context menu, - which shows the WebKit WebInspector for web site debugging. + Currently this enables the "Inspect" element in the context menu as + well as the use of QWebInspector which controls the WebKit WebInspector + for web site debugging. \value LinksIncludedInFocusChain Specifies whether hyperlinks should be included in the keyboard focus chain. \value ZoomTextOnly Specifies whether the zoom factor on a frame applies to @@ -323,11 +335,13 @@ QWebSettings* QWebSettings::globalSettings() \value PrintElementBackgrounds Specifies whether the background color and images are also drawn when the page is printed. \value OfflineStorageDatabaseEnabled Specifies whether support for the HTML 5 - offline storage feature is enabled or not. + offline storage feature is enabled or not. Disabled by default. \value OfflineWebApplicationCacheEnabled Specifies whether support for the HTML 5 - web application cache feature is enabled or not. - \value LocalStorageDatabaseEnabled Specifies whether support for the HTML 5 - local storage feature is enabled or not. + web application cache feature is enabled or not. Disabled by default. + \value LocalStorageEnabled Specifies whether support for the HTML 5 + local storage feature is enabled or not. Disabled by default. + \value LocalStorageDatabaseEnabled \e{This enum value is deprecated.} Use + QWebSettings::LocalStorageEnabled instead. \value LocalContentCanAccessRemoteUrls Specifies whether locally loaded documents are allowed to access remote urls. */ @@ -340,8 +354,8 @@ QWebSettings::QWebSettings() // Initialize our global defaults d->fontSizes.insert(QWebSettings::MinimumFontSize, 0); d->fontSizes.insert(QWebSettings::MinimumLogicalFontSize, 0); - d->fontSizes.insert(QWebSettings::DefaultFontSize, 14); - d->fontSizes.insert(QWebSettings::DefaultFixedFontSize, 14); + d->fontSizes.insert(QWebSettings::DefaultFontSize, 16); + d->fontSizes.insert(QWebSettings::DefaultFixedFontSize, 13); d->fontFamilies.insert(QWebSettings::StandardFont, QLatin1String("Arial")); d->fontFamilies.insert(QWebSettings::FixedFont, QLatin1String("Courier New")); d->fontFamilies.insert(QWebSettings::SerifFont, QLatin1String("Times New Roman")); @@ -350,15 +364,17 @@ QWebSettings::QWebSettings() d->fontFamilies.insert(QWebSettings::FantasyFont, QLatin1String("Arial")); d->attributes.insert(QWebSettings::AutoLoadImages, true); + d->attributes.insert(QWebSettings::DnsPrefetchEnabled, false); d->attributes.insert(QWebSettings::JavascriptEnabled, true); d->attributes.insert(QWebSettings::LinksIncludedInFocusChain, true); d->attributes.insert(QWebSettings::ZoomTextOnly, false); d->attributes.insert(QWebSettings::PrintElementBackgrounds, true); - d->attributes.insert(QWebSettings::OfflineStorageDatabaseEnabled, true); - d->attributes.insert(QWebSettings::OfflineWebApplicationCacheEnabled, true); - d->attributes.insert(QWebSettings::LocalStorageDatabaseEnabled, true); - d->attributes.insert(QWebSettings::LocalContentCanAccessRemoteUrls, true); + d->attributes.insert(QWebSettings::OfflineStorageDatabaseEnabled, false); + d->attributes.insert(QWebSettings::OfflineWebApplicationCacheEnabled, false); + d->attributes.insert(QWebSettings::LocalStorageEnabled, false); + d->attributes.insert(QWebSettings::LocalContentCanAccessRemoteUrls, false); d->offlineStorageDefaultQuota = 5 * 1024 * 1024; + d->defaultTextEncoding = QLatin1String("iso-8859-1"); } /*! @@ -422,7 +438,10 @@ void QWebSettings::resetFontSize(FontSize type) /*! Specifies the location of a user stylesheet to load with every web page. - The \a location can be a URL or a path on the local filesystem. + The \a location must be either a path on the local filesystem, or a data URL + with UTF-8 and Base64 encoded data, such as: + + "data:text/css;charset=utf-8;base64,cCB7IGJhY2tncm91bmQtY29sb3I6IHJlZCB9Ow==;" \sa userStyleSheetUrl() */ @@ -539,9 +558,9 @@ QIcon QWebSettings::iconForUrl(const QUrl& url) return* icon; } -/*! +/* Returns the plugin database object. -*/ + QWebPluginDatabase *QWebSettings::pluginDatabase() { static QWebPluginDatabase* database = 0; @@ -549,6 +568,7 @@ QWebPluginDatabase *QWebSettings::pluginDatabase() database = new QWebPluginDatabase(); return database; } +*/ /*! Sets \a graphic to be drawn when QtWebKit needs to draw an image of the @@ -607,21 +627,26 @@ void QWebSettings::clearMemoryCaches() // Invalidating the font cache and freeing all inactive font data. WebCore::fontCache()->invalidate(); -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - // Empty the application cache. - WebCore::cacheStorage().empty(); -#endif - // Empty the Cross-Origin Preflight cache WebCore::CrossOriginPreflightResultCache::shared().empty(); } /*! - Sets the maximum number of pages to hold in the memory cache to \a pages. + Sets the maximum number of pages to hold in the memory page cache to \a pages. + + The Page Cache allows for a nicer user experience when navigating forth or back + to pages in the forward/back history, by pausing and resuming up to \a pages + per page group. + + For more information about the feature, please refer to: + + http://webkit.org/blog/427/webkit-page-cache-i-the-basics/ */ void QWebSettings::setMaximumPagesInCache(int pages) { + QWebSettingsPrivate* global = QWebSettings::globalSettings()->d; WebCore::pageCache()->setCapacity(qMax(0, pages)); + global->apply(); } /*! @@ -867,37 +892,71 @@ qint64 QWebSettings::offlineWebApplicationCacheQuota() #endif } -/* - \since 4.5 +/*! + \since 4.6 \relates QWebSettings - Sets the path for HTML5 local storage databases to \a path. - - \a path must point to an existing directory where the cache is stored. + Sets the path for HTML5 local storage to \a path. + + For more information on HTML5 local storage see the + \l{http://www.w3.org/TR/webstorage/#the-localstorage-attribute}{Web Storage standard}. + + Support for local storage can enabled by setting the + \l{QWebSettings::LocalStorageEnabled}{LocalStorageEnabled} attribute. - Setting an empty path disables the feature. - - \sa localStorageDatabasePath() + \sa localStoragePath() */ -void QWEBKIT_EXPORT qt_websettings_setLocalStorageDatabasePath(QWebSettings* settings, const QString& path) +void QWebSettings::setLocalStoragePath(const QString& path) { - QWebSettingsPrivate* d = settings->handle(); - d->localStorageDatabasePath = path; + d->localStoragePath = path; d->apply(); } -/* - \since 4.5 +/*! + \since 4.6 \relates QWebSettings - Returns the path for HTML5 local storage databases - or an empty string if the feature is disabled. + Returns the path for HTML5 local storage. + + \sa setLocalStoragePath() +*/ +QString QWebSettings::localStoragePath() const +{ + return d->localStoragePath; +} + +/*! + \since 4.6 + \relates QWebSettings - \sa setLocalStorageDatabasePath() + Enables WebKit persistent data and sets the path to \a path. + If the \a path is empty the path for persistent data is set to the + user-specific data location specified by + \l{QDesktopServices::DataLocation}{DataLocation}. + + \sa localStoragePath() */ -QString QWEBKIT_EXPORT qt_websettings_localStorageDatabasePath(QWebSettings* settings) +void QWebSettings::enablePersistentStorage(const QString& path) { - return settings->handle()->localStorageDatabasePath; + QString storagePath; + + if (path.isEmpty()) { + storagePath = QDesktopServices::storageLocation(QDesktopServices::DataLocation); + + if (storagePath.isEmpty()) + storagePath = WebCore::pathByAppendingComponent(QDir::homePath(), QCoreApplication::applicationName()); + } else + storagePath = path; + + WebCore::makeAllDirectories(storagePath); + + QWebSettings::setIconDatabasePath(storagePath); + QWebSettings::setOfflineWebApplicationCachePath(storagePath); + QWebSettings::setOfflineStoragePath(WebCore::pathByAppendingComponent(storagePath, "Databases")); + QWebSettings::globalSettings()->setLocalStoragePath(WebCore::pathByAppendingComponent(storagePath, "LocalStorage")); + QWebSettings::globalSettings()->setAttribute(QWebSettings::LocalStorageEnabled, true); + QWebSettings::globalSettings()->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, true); + QWebSettings::globalSettings()->setAttribute(QWebSettings::OfflineWebApplicationCacheEnabled, true); } /*! diff --git a/WebKit/qt/Api/qwebsettings.h b/WebKit/qt/Api/qwebsettings.h index b7ea54b..69f3b11 100644 --- a/WebKit/qt/Api/qwebsettings.h +++ b/WebKit/qt/Api/qwebsettings.h @@ -62,14 +62,19 @@ public: PrintElementBackgrounds, OfflineStorageDatabaseEnabled, OfflineWebApplicationCacheEnabled, - LocalStorageDatabaseEnabled, - LocalContentCanAccessRemoteUrls + LocalStorageEnabled, +#ifdef QT_DEPRECATED + LocalStorageDatabaseEnabled = LocalStorageEnabled, +#endif + LocalContentCanAccessRemoteUrls, + DnsPrefetchEnabled }; enum WebGraphic { MissingImageGraphic, MissingPluginGraphic, DefaultFrameIconGraphic, - TextAreaSizeGripCornerGraphic + TextAreaSizeGripCornerGraphic, + DeleteButtonGraphic }; enum FontSize { MinimumFontSize, @@ -103,7 +108,7 @@ public: static void clearIconDatabase(); static QIcon iconForUrl(const QUrl &url); - static QWebPluginDatabase *pluginDatabase(); + //static QWebPluginDatabase *pluginDatabase(); static void setWebGraphic(WebGraphic type, const QPixmap &graphic); static QPixmap webGraphic(WebGraphic type); @@ -121,9 +126,14 @@ public: static QString offlineWebApplicationCachePath(); static void setOfflineWebApplicationCacheQuota(qint64 maximumSize); static qint64 offlineWebApplicationCacheQuota(); + + void setLocalStoragePath(const QString& path); + QString localStoragePath() const; static void clearMemoryCaches(); + static void enablePersistentStorage(const QString& path = QString()); + inline QWebSettingsPrivate* handle() const { return d; } private: diff --git a/WebKit/qt/Api/qwebview.cpp b/WebKit/qt/Api/qwebview.cpp index e1a0c98..7bc3168 100644 --- a/WebKit/qt/Api/qwebview.cpp +++ b/WebKit/qt/Api/qwebview.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) Copyright (C) 2008 Holger Hans Peter Freyther + Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -20,6 +21,8 @@ #include "config.h" #include "qwebview.h" + +#include "QWebPageClient.h" #include "qwebframe.h" #include "qwebpage_p.h" @@ -36,40 +39,24 @@ public: : view(view) , page(0) , renderHints(QPainter::TextAntialiasing) -#ifndef QT_NO_CURSOR - , cursorSetByWebCore(false) - , usesWebCoreCursor(true) -#endif - {} + { + Q_ASSERT(view); + } + + void _q_pageDestroyed(); QWebView *view; QWebPage *page; QPainter::RenderHints renderHints; - -#ifndef QT_NO_CURSOR - /* - * We keep track of if we have called setCursor and if the CursorChange - * event is sent due our setCursor call and if we currently use the WebCore - * Cursor and use it to decide if we can update to another WebCore Cursor. - */ - bool cursorSetByWebCore; - bool usesWebCoreCursor; - - void setCursor(const QCursor& newCursor) - { - webCoreCursor = newCursor; - - if (usesWebCoreCursor) { - cursorSetByWebCore = true; - view->setCursor(webCoreCursor); - } - } - - QCursor webCoreCursor; -#endif }; +void QWebViewPrivate::_q_pageDestroyed() +{ + page = 0; + view->setPage(0); +} + /*! \class QWebView \since 4.4 @@ -77,11 +64,13 @@ public: web documents. \ingroup advanced + \inmodule QtWebKit + QWebView is the main widget component of the QtWebKit web browsing module. It can be used in various applications to display web content live from the Internet. - The image below shows QWebView previewed in \QD with the Trolltech website. + The image below shows QWebView previewed in \QD with a Nokia website. \image qwebview-url.png @@ -160,7 +149,7 @@ QWebView::QWebView(QWidget *parent) { d = new QWebViewPrivate(this); -#if !defined(Q_WS_QWS) +#if !defined(Q_WS_QWS) && !defined(Q_OS_SYMBIAN) setAttribute(Qt::WA_InputMethodEnabled); #endif @@ -175,8 +164,15 @@ QWebView::QWebView(QWidget *parent) */ QWebView::~QWebView() { - if (d->page) + if (d->page) { +#if QT_VERSION >= 0x040600 + d->page->d->view.clear(); +#else d->page->d->view = 0; +#endif + delete d->page->d->client; + d->page->d->client = 0; + } if (d->page && d->page->parent() == this) delete d->page; @@ -211,6 +207,7 @@ void QWebView::setPage(QWebPage* page) if (d->page == page) return; if (d->page) { + d->page->d->client = 0; // unset the page client if (d->page->parent() == this) delete d->page; else @@ -222,12 +219,12 @@ void QWebView::setPage(QWebPage* page) d->page->setPalette(palette()); // #### connect signals QWebFrame *mainFrame = d->page->mainFrame(); - connect(mainFrame, SIGNAL(titleChanged(const QString&)), - this, SIGNAL(titleChanged(const QString&))); + connect(mainFrame, SIGNAL(titleChanged(QString)), + this, SIGNAL(titleChanged(QString))); connect(mainFrame, SIGNAL(iconChanged()), this, SIGNAL(iconChanged())); - connect(mainFrame, SIGNAL(urlChanged(const QUrl &)), - this, SIGNAL(urlChanged(const QUrl &))); + connect(mainFrame, SIGNAL(urlChanged(QUrl)), + this, SIGNAL(urlChanged(QUrl))); connect(d->page, SIGNAL(loadStarted()), this, SIGNAL(loadStarted())); @@ -235,97 +232,26 @@ void QWebView::setPage(QWebPage* page) this, SIGNAL(loadProgress(int))); connect(d->page, SIGNAL(loadFinished(bool)), this, SIGNAL(loadFinished(bool))); - connect(d->page, SIGNAL(statusBarMessage(const QString &)), - this, SIGNAL(statusBarMessage(const QString &))); - connect(d->page, SIGNAL(linkClicked(const QUrl &)), - this, SIGNAL(linkClicked(const QUrl &))); + connect(d->page, SIGNAL(statusBarMessage(QString)), + this, SIGNAL(statusBarMessage(QString))); + connect(d->page, SIGNAL(linkClicked(QUrl)), + this, SIGNAL(linkClicked(QUrl))); connect(d->page, SIGNAL(microFocusChanged()), this, SLOT(updateMicroFocus())); + connect(d->page, SIGNAL(destroyed()), + this, SLOT(_q_pageDestroyed())); } setAttribute(Qt::WA_OpaquePaintEvent, d->page); update(); } /*! - Returns a valid URL from a user supplied \a string if one can be deducted. - In the case that is not possible, an invalid QUrl() is returned. - - \since 4.6 - - Most applications that can browse the web, allow the user to input a URL - in the form of a plain string. This string can be manually typed into - a location bar, obtained from the clipboard, or passed in via command - line arguments. - - When the string is not already a valid URL, a best guess is performed, - making various web related assumptions. - - In the case the string corresponds to a valid file path on the system, - a file:// URL is constructed, using QUrl::fromLocalFile(). - - If that is not the case, an attempt is made to turn the string into a - http:// or ftp:// URL. The latter in the case the string starts with - 'ftp'. The result is then passed through QUrl's tolerant parser, and - in the case or success, a valid QUrl is returned, or else a QUrl(). - - \section1 Examples: - - \list - \o webkit.org becomes http://webkit.org - \o ftp.webkit.org becomes ftp://ftp.webkit.org - \o localhost becomes http://localhost - \o /home/user/test.html becomes file:///home/user/test.html (if exists) - \endlist - - \section2 Tips when dealing with URLs and strings: - - \list - \o When creating a QString from a QByteArray or a char*, always use - QString::fromUtf8(). - \o Do not use QUrl(string), nor QUrl::toString() anywhere where the URL might - be used, such as in the location bar, as those functions loose data. - Instead use QUrl::fromEncoded() and QUrl::toEncoded(), respectively. - \endlist - */ -QUrl QWebView::guessUrlFromString(const QString &string) -{ - QString trimmedString = string.trimmed(); - - // Check the most common case of a valid url with scheme and host first - QUrl url = QUrl::fromEncoded(trimmedString.toUtf8(), QUrl::TolerantMode); - if (url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty()) - return url; - - // Absolute files that exists - if (QDir::isAbsolutePath(trimmedString) && QFile::exists(trimmedString)) - return QUrl::fromLocalFile(trimmedString); - - // If the string is missing the scheme or the scheme is not valid prepend a scheme - QString scheme = url.scheme(); - if (scheme.isEmpty() || scheme.contains(QLatin1Char('.')) || scheme == QLatin1String("localhost")) { - // Do not do anything for strings such as "foo", only "foo.com" - int dotIndex = trimmedString.indexOf(QLatin1Char('.')); - if (dotIndex != -1 || trimmedString.startsWith(QLatin1String("localhost"))) { - const QString hostscheme = trimmedString.left(dotIndex).toLower(); - QByteArray scheme = (hostscheme == QLatin1String("ftp")) ? "ftp" : "http"; - trimmedString = QLatin1String(scheme) + QLatin1String("://") + trimmedString; - } - url = QUrl::fromEncoded(trimmedString.toUtf8(), QUrl::TolerantMode); - } - - if (url.isValid()) - return url; - - return QUrl(); -} - -/*! Loads the specified \a url and displays it. \note The view remains the same until enough data has arrived to display the new \a url. - \sa setUrl(), url(), urlChanged(), guessUrlFromString() + \sa setUrl(), url(), urlChanged(), QUrl::fromUserInput() */ void QWebView::load(const QUrl &url) { @@ -344,19 +270,11 @@ void QWebView::load(const QUrl &url) \sa url(), urlChanged() */ -#if QT_VERSION < 0x040400 && !defined(qdoc) -void QWebView::load(const QWebNetworkRequest &request) -#else void QWebView::load(const QNetworkRequest &request, QNetworkAccessManager::Operation operation, const QByteArray &body) -#endif { - page()->mainFrame()->load(request -#if QT_VERSION >= 0x040400 - , operation, body -#endif - ); + page()->mainFrame()->load(request, operation, body); } /*! @@ -613,10 +531,20 @@ qreal QWebView::textSizeMultiplier() const \since 4.6 \brief the default render hints for the view - These hints are used to initialize QPainter before painting the web page. + These hints are used to initialize QPainter before painting the Web page. QPainter::TextAntialiasing is enabled by default. + \note This property is not available on Symbian. However, the getter and + setter functions can still be used directly. + + \sa QPainter::renderHints() +*/ + +/*! + \since 4.6 + Returns the render hints used by the view to render content. + \sa QPainter::renderHints() */ QPainter::RenderHints QWebView::renderHints() const @@ -624,6 +552,12 @@ QPainter::RenderHints QWebView::renderHints() const return d->renderHints; } +/*! + \since 4.6 + Sets the render hints used by the view to the specified \a hints. + + \sa QPainter::setRenderHints() +*/ void QWebView::setRenderHints(QPainter::RenderHints hints) { if (hints == d->renderHints) @@ -633,11 +567,11 @@ void QWebView::setRenderHints(QPainter::RenderHints hints) } /*! - If \a enabled is true, the render hint \a hint is enabled; otherwise it - is disabled. - \since 4.6 - \sa renderHints + If \a enabled is true, enables the specified render \a hint; otherwise + disables it. + + \sa renderHints, QPainter::renderHints() */ void QWebView::setRenderHint(QPainter::RenderHint hint, bool enabled) { @@ -694,20 +628,17 @@ bool QWebView::event(QEvent *e) if (e->type() == QEvent::ShortcutOverride) { d->page->event(e); #ifndef QT_NO_CURSOR - } else if (e->type() == static_cast<QEvent::Type>(WebCore::SetCursorEvent::EventType)) { - d->setCursor(static_cast<WebCore::SetCursorEvent*>(e)->cursor()); -#if QT_VERSION >= 0x040400 } else if (e->type() == QEvent::CursorChange) { - // Okay we might use the WebCore Cursor now. - d->usesWebCoreCursor = d->cursorSetByWebCore; - d->cursorSetByWebCore = false; - - // Go back to the WebCore Cursor. QWidget::unsetCursor is appromixated with this - if (!d->usesWebCoreCursor && cursor().shape() == Qt::ArrowCursor) { - d->usesWebCoreCursor = true; - d->setCursor(d->webCoreCursor); - } -#endif + // An unsetCursor will set the cursor to Qt::ArrowCursor. + // Thus this cursor change might be a QWidget::unsetCursor() + // If this is not the case and it came from WebCore, the + // QWebPageClient already has set its cursor internally + // to Qt::ArrowCursor, so updating the cursor is always + // right, as it falls back to the last cursor set by + // WebCore. + // FIXME: Add a QEvent::CursorUnset or similar to Qt. + if (cursor().shape() == Qt::ArrowCursor) + d->page->d->client->resetCursor(); #endif } else if (e->type() == QEvent::Leave) d->page->event(e); @@ -818,8 +749,12 @@ void QWebView::paintEvent(QPaintEvent *ev) } /*! - This function is called whenever WebKit wants to create a new window of the given \a type, for example as a result of - a JavaScript request to open a document in a new window. + This function is called from the createWindow() method of the associated QWebPage, + each time the page wants to create a new window of the given \a type. This might + be the result, for example, of a JavaScript request to open a document in a new window. + + \note If the createWindow() method of the associated page is reimplemented, this + method is not called, unless explicitly done so in the reimplementation. \sa QWebPage::createWindow() */ @@ -1033,7 +968,7 @@ void QWebView::changeEvent(QEvent *e) /*! \fn void QWebView::statusBarMessage(const QString& text) - This signal is emitted when the statusbar \a text is changed by the page. + This signal is emitted when the status bar \a text is changed by the page. */ /*! @@ -1094,3 +1029,6 @@ void QWebView::changeEvent(QEvent *e) \sa QWebPage::linkDelegationPolicy() */ + +#include "moc_qwebview.cpp" + diff --git a/WebKit/qt/Api/qwebview.h b/WebKit/qt/Api/qwebview.h index e886144..d7910d9 100644 --- a/WebKit/qt/Api/qwebview.h +++ b/WebKit/qt/Api/qwebview.h @@ -27,9 +27,7 @@ #include <QtGui/qicon.h> #include <QtGui/qpainter.h> #include <QtCore/qurl.h> -#if QT_VERSION >= 0x040400 #include <QtNetwork/qnetworkaccessmanager.h> -#endif QT_BEGIN_NAMESPACE class QNetworkRequest; @@ -50,7 +48,13 @@ class QWEBKIT_EXPORT QWebView : public QWidget { //Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags WRITE setTextInteractionFlags) Q_PROPERTY(qreal textSizeMultiplier READ textSizeMultiplier WRITE setTextSizeMultiplier DESIGNABLE false) Q_PROPERTY(qreal zoomFactor READ zoomFactor WRITE setZoomFactor) + +// FIXME: temporary work around for elftran issue that it couldn't find the QPainter::staticMetaObject +// symbol from Qt lib; it should be reverted after the right symbol is exported. +// See bug: http://qt.nokia.com/developer/task-tracker/index_html?method=entry&id=258893 +#if defined(Q_QDOC) || !defined(Q_OS_SYMBIAN) Q_PROPERTY(QPainter::RenderHints renderHints READ renderHints WRITE setRenderHints) +#endif Q_FLAGS(QPainter::RenderHints) public: explicit QWebView(QWidget* parent = 0); @@ -59,16 +63,10 @@ public: QWebPage* page() const; void setPage(QWebPage* page); - static QUrl guessUrlFromString(const QString& string); - void load(const QUrl& url); -#if QT_VERSION < 0x040400 && !defined(qdoc) - void load(const QWebNetworkRequest& request); -#else void load(const QNetworkRequest& request, QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation, const QByteArray &body = QByteArray()); -#endif void setHtml(const QString& html, const QUrl& baseUrl = QUrl()); void setContent(const QByteArray& data, const QString& mimeType = QString(), const QUrl& baseUrl = QUrl()); @@ -162,6 +160,7 @@ protected: private: friend class QWebPage; QWebViewPrivate* d; + Q_PRIVATE_SLOT(d, void _q_pageDestroyed()) }; #endif // QWEBVIEW_H diff --git a/WebKit/qt/ChangeLog b/WebKit/qt/ChangeLog index 6b05b18..2c2722b 100644 --- a/WebKit/qt/ChangeLog +++ b/WebKit/qt/ChangeLog @@ -1,3 +1,3743 @@ +2009-12-07 Benjamin Poulain <benjamin.poulain@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Improve the autotests of QtWebkit + https://bugs.webkit.org/show_bug.cgi?id=32216 + + Remove the calls to qWait() of the autotest of QWebView + + * tests/qwebview/tst_qwebview.cpp: + (tst_QWebView::reusePage): + +2009-12-07 Benjamin Poulain <benjamin.poulain@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Improve the autotests of QtWebkit + https://bugs.webkit.org/show_bug.cgi?id=32216 + + Refactor tst_qwebframe to remove qWait() and use + the function waitForSignal() from util.h + + * tests/qwebframe/tst_qwebframe.cpp: + +2009-12-07 Benjamin Poulain <benjamin.poulain@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Improve the autotests of QtWebkit + https://bugs.webkit.org/show_bug.cgi?id=32216 + + Refactor the test of QGraphicsWebView: + -make waitForSignal() available to all the tests. + -remove QTest::qWait() + + * tests/qgraphicswebview/tst_qgraphicswebview.cpp: + (tst_QGraphicsWebView::crashOnViewlessWebPages): + * tests/util.h: + (waitForSignal): + +2009-12-07 Girish Ramakrishnan <girish@forwardbias.in> + + Reviewed by Simon Hausmann. + + [Qt] Plugins: Force windowless mode when there is no native window handle + + Inject wmode=opaque while instantiating the plugin for the case when the + webpage is not backed by a native window handle. + + https://bugs.webkit.org/show_bug.cgi?id=32059 + + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::createPlugin): + +2009-12-04 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Corrects QtLauncher style + + * QtLauncher/main.cpp: + (WebPage::acceptNavigationRequest): + (MainWindow::MainWindow): + (MainWindow::webPage): + (MainWindow::webView): + (MainWindow::changeLocation): + (MainWindow::loadFinished): + (MainWindow::showLinkHover): + (MainWindow::zoomIn): + (MainWindow::zoomOut): + (MainWindow::print): + (MainWindow::setEditable): + (MainWindow::dumpHtml): + (MainWindow::selectElements): + (MainWindow::newWindow): + (MainWindow::setupUI): + (WebPage::createWindow): + (WebPage::createPlugin): + (main): + +2009-12-04 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] QtLauncher: add a menu to show or hide the web inspector. + https://bugs.webkit.org/show_bug.cgi?id=32149 + + * QtLauncher/main.cpp: + (WebInspector::WebInspector): + (WebInspector::showEvent): + (WebInspector::hideEvent): + (MainWindow::MainWindow): + (MainWindow::setupUI): + +2009-12-04 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Antti Koivisto. + + Split out the renderPrivate in two methods, one for working on + relative coordinates (relative to the viewport) and one for + working on absolute coordinates. The latter is more effecient + for implementing tiling, as you don't need translate the coords, + and because it avoid clipping to the viewport. + + No behaviour changes, so no new tests. + + * Api/qwebframe.cpp: + (QWebFramePrivate::renderContentsLayerAbsoluteCoords): + (QWebFramePrivate::renderRelativeCoords): + (QWebFrame::render): + * Api/qwebframe_p.h: + +2009-12-04 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Allow removing 'qrc' as a local security origin scheme + + * tests/qwebpage/tst_qwebpage.cpp: + +2009-12-04 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Clean up argument parsing in the QtLauncher + + * QtLauncher/main.cpp: + +2009-12-04 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Prevent the inspector from closing its wrapping widget. + This is not necessary anymore since we now hide the embedded + close button. + https://bugs.webkit.org/show_bug.cgi?id=32149 + + * WebCoreSupport/InspectorClientQt.cpp: + (WebCore::InspectorClientQt::showWindow): + (WebCore::InspectorClientQt::closeWindow): + +2009-12-03 İsmail Dönmez <ismail@namtrac.org> + + Reviewed by Eric Seidel. + + Fix compilation when SVG is disabled. + + * Api/qwebframe.cpp: + (qt_drt_pauseSVGAnimation): + +2009-12-03 Brady Eidson <beidson@apple.com> + + Reviewed by Sam Weinig. + + <rdar://problem/7214236> and http://webkit.org/b/32052 - Implement HTML5 state object history API + + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::dispatchDidPushStateWithinPage): + (WebCore::FrameLoaderClientQt::dispatchDidReplaceStateWithinPage): + (WebCore::FrameLoaderClientQt::dispatchDidPopStateWithinPage): + * WebCoreSupport/FrameLoaderClientQt.h: + +2009-12-03 Pavel Feldman <pfeldman@dhcp-172-28-174-220.spb.corp.google.com> + + Reviewed by Timothy Hatcher. + + Web Inspector: Simplify the settings support in inspector controller. + + https://bugs.webkit.org/show_bug.cgi?id=32076 + + * WebCoreSupport/InspectorClientQt.cpp: + (WebCore::InspectorClientQt::populateSetting): + (WebCore::InspectorClientQt::storeSetting): + (WebCore::variantToSetting): + (WebCore::settingToVariant): + * WebCoreSupport/InspectorClientQt.h: + +2009-12-03 Ben Murdoch <benm@google.com> + + Reviewed by Brady Eidson. + + [Android] The FrameLoaderClient is unaware of BackForwardList changes. + https://bugs.webkit.org/show_bug.cgi?id=31914 + + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::dispatchDidAddBackForwardItem): Add an empty implementation. Method added to FrameLoaderClient by Android (see bug). + (WebCore::FrameLoaderClientQt::dispatchDidRemoveBackForwardItem): ditto. + (WebCore::FrameLoaderClientQt::dispatchDidChangeBackForwardIndex): ditto. + * WebCoreSupport/FrameLoaderClientQt.h: + +2009-12-01 Nikolas Zimmermann <nzimmermann@rim.com> + + Not reviewed. Try to fix Qt build. + + * Api/qwebframe.cpp: + (qt_drt_pauseSVGAnimation): + +2009-12-01 Nikolas Zimmermann <nzimmermann@rim.com> + + Reviewed by Simon Fraser. + + Add SVG animation test framework with 'snapshot' functionality + https://bugs.webkit.org/show_bug.cgi?id=31897 + + Add API used by the new 'sampleSVGAnimationForElementAtTime' DRT method, + forwarding the call to SVGDocumentExtensions, if SVG is enabled. + + Implemented just like the existing pauseAnimation* methods for CSS animations. + + * Api/qwebframe.cpp: + (qt_drt_pauseSVGAnimation): + +2009-12-01 Daniel Bates <dbates@webkit.org> + + Reviewed by Kenneth Rohde Christiansen. + + https://bugs.webkit.org/show_bug.cgi?id=31898 + + Makes QtLauncher default to the http scheme for URLs. + + * QtLauncher/main.cpp: + (MainWindow::MainWindow): + (MainWindow::changeLocation): + (main): + +2009-11-30 Abhinav Mithal <abhinav.mithal@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt][Symbian] Report SymbianOS in user agent string for Symbian + https://bugs.webkit.org/show_bug.cgi?id=31961 + + * Api/qwebpage.cpp: + (QWebPage::userAgentForUrl): + +2009-11-30 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Fix minor waning in QtWebKit + https://bugs.webkit.org/show_bug.cgi?id=31963 + + * tests/qwebpage/tst_qwebpage.cpp: + (ErrorPage::extension): Remove info wariable as it is + not used. + +2009-11-28 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] SoftwareInputPanelRequest event sent when clicking in newly loaded page + + https://bugs.webkit.org/show_bug.cgi?id=31401 + + Don't set the event unless there is a focused node we can use + for editing afterwards. + + * Api/qwebpage.cpp: + (QWebPagePrivate::handleSoftwareInputPanel): + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::inputMethods): + +2009-11-26 Simon Hausmann <simon.hausmann@nokia.com> + + Rubber-stamped by Holger Freyther. + + Removed unused ICO image plugin handler. + + * Plugins/ICOHandler.cpp: Removed. + * Plugins/ICOHandler.h: Removed. + * Plugins/Plugins.pro: Removed. + +2009-11-12 Holger Hans Peter Freyther <zecke@selfish.org> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Do not show the QWidget when the WebCore::Widget is hidden + https://bugs.webkit.org/show_bug.cgi?id=31203 + + The clipping code was making a QWidget visible even if the + WebCore::Widget was hidden. Fix the bug by calling setVisible + only if the WebCore::Widget Widget::isSelfVisible. + + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::QtPluginWidget::show): Override WebCore::Widget::show to call handleVisibility + (WebCore::QtPluginWidget::handleVisibility): New method to call setVisible when we are visible + (FrameLoaderClientQt::createPlugin): Hide the QWidget by default + +2009-11-23 David Boddie <dboddie@trolltech.com> + + Reviewed by Simon Hausmann. + + Updated the QWebElement documentation with links to examples and + external resources. + Fixed the project file for the webelement snippet and tidied up the + markers used for quoting the code. + + * Api/qwebelement.cpp: + * docs/webkitsnippets/webelement/main.cpp: + (findAll): + * docs/webkitsnippets/webelement/webelement.pro: + +2009-11-23 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Wrong runtime instance objects of wrapped QObjects may be used if + the wrapped object died before the gc removed the instance. + + https://bugs.webkit.org/show_bug.cgi?id=31681 + + Added a unit-test to verify that wrapping a QObject with the + same identity as a previously but now dead object works. + + * tests/qwebframe/tst_qwebframe.cpp: + +2009-11-19 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Add instantiation tests for QWebInspector. + + * tests/qwebinspector/qwebinspector.pro: Added. + * tests/qwebinspector/tst_qwebinspector.cpp: Added. + (tst_QWebInspector::attachAndDestroy): + * tests/tests.pro: + +2009-11-19 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Fix QWebInspector destruction problem. + https://bugs.webkit.org/show_bug.cgi?id=31664 + + * Api/qwebpage.cpp: + (QWebPage::~QWebPage): + +2009-11-19 Olivier Goffart <ogoffart@trolltech.com> + + Reviewed by Simon Hausmann. + + [Qt] Normalize signal and slot signatures. + + * Api/qgraphicswebview.cpp: + (QGraphicsWebView::setPage): + * Api/qwebview.cpp: + (QWebView::setPage): + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::setFrame): + * docs/webkitsnippets/qtwebkit_qwebinspector_snippet.cpp: + (wrapInFunction): + * tests/qwebframe/tst_qwebframe.cpp: + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::modified): + (tst_QWebPage::database): + +2009-11-18 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Remove support for Qt v4.3 or older versions + https://bugs.webkit.org/show_bug.cgi?id=29469 + + * Api/qcookiejar.cpp: Removed. + * Api/qcookiejar.h: Removed. + * Api/qgraphicswebview.cpp: + (QGraphicsWebView::event): + * Api/qwebframe.cpp: + (QWebFrame::load): + * Api/qwebframe.h: + * Api/qwebkitglobal.h: + * Api/qwebnetworkinterface.cpp: Removed. + * Api/qwebnetworkinterface.h: Removed. + * Api/qwebnetworkinterface_p.h: Removed. + * Api/qwebpage.cpp: + (QWebPagePrivate::QWebPagePrivate): + (QWebPagePrivate::acceptNavigationRequest): + (QWebPage::acceptNavigationRequest): + (QWebPage::action): + (QWebPage::userAgentForUrl): + * Api/qwebpage.h: + * Api/qwebpage_p.h: + * Api/qwebview.cpp: + (QWebView::load): + (QWebView::event): + * Api/qwebview.h: + * QtLauncher/main.cpp: + (MainWindow::print): + (MainWindow::setupUI): + (main): + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::download): + (WebCore::FrameLoaderClientQt::dispatchDecidePolicyForNewWindowAction): + (WebCore::FrameLoaderClientQt::dispatchDecidePolicyForNavigationAction): + (WebCore::FrameLoaderClientQt::startDownload): + (WebCore::FrameLoaderClientQt::createPlugin): + +2009-11-18 Shu Chang <Chang.Shu@nokia.com> + + Reviewed by Eric Seidel. + + [Qt] Add support for displaying deleteButton. + https://bugs.webkit.org/show_bug.cgi?id=31560 + + Test: LayoutTests/editing/deleting/5408255.html + + * Api/qwebsettings.cpp: + (graphics): + * Api/qwebsettings.h: + +2009-11-18 Paul Olav Tvete <paul.tvete@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Make the QWebElement::render() test pass when pixmaps aren't 32 bit. + + * tests/qwebelement/tst_qwebelement.cpp: + (tst_QWebElement::render): + +2009-11-18 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Tor Arne Vestbø. + + Clarify and simplify the legal section in the overview documentation, + after review with our legal team. + + * docs/qtwebkit.qdoc: + +2009-11-18 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Add QtLauncher support for opening links in the default browser + + This can be triggered by either the context menu or by clicking a link + while holding down the Alt key. Opening a link in a new windows is + triggered by holding down Shift. + + * QtLauncher/main.cpp: + +2009-11-17 Yael Aharon <yael.aharon@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] QGLLauncher does not support drag&drop of local files + https://bugs.webkit.org/show_bug.cgi?id=31057 + + Enable accepting files in QGraphicsWebView. + + * Api/qgraphicswebview.cpp: + (QGraphicsWebView::QGraphicsWebView): + (QGraphicsWebView::dragEnterEvent): + +2009-11-17 Antonio Gomes <tonikitoo@webkit.org> + + Reviewed by Kenneth Christiansen. + + [Qt] better test coverage for ErrorPageExtension + https://bugs.webkit.org/show_bug.cgi?id=31583 + + Improved the coverage of current ErrorPageExtension tests by + adding autotests involving frameset and iframes. + + * tests/qwebpage/tst_qwebpage.cpp: + (ErrorPage::extension): Make the ErrorPageExtension + to work for all frames, not only the main frame. + (tst_QWebPage::errorPageExtension): Stop using + the 'frameset.html' resouce in this method since + an autotest specific for frameset's is being added. + (tst_QWebPage::errorPageExtensionInIFrames): Added. + (tst_QWebPage::errorPageExtensionInFrameset): Added. + +2009-11-16 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + API documentation fixes. + + * Api/qgraphicswebview.cpp: Removed duplicate docs. + * Api/qwebelement.cpp: Added missing docs. + * Api/qwebsettings.cpp: Ditto. + +2009-11-14 Antonio Gomes <tonikitoo@webkit.org> + + Reviewed by Antti Koivisto. + + [Qt] Broken back/forward after using ErrorPageExtension to set error page + https://bugs.webkit.org/show_bug.cgi?id=30573 + + Implemented autotests for covering the back/forward + reset problem involving error pages. + + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::errorPageExtension): + +2009-11-13 Adam Roben <aroben@apple.com> + + Update for changes to FrameLoaderClient + + Fixes <http://webkit.org/b/31124> Tell the WebFrameLoadDelegate when + window objects in isolated worlds are cleared + + Reviewed by Dave Hyatt. + + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::dispatchDidClearWindowObjectInWorld): + * WebCoreSupport/FrameLoaderClientQt.h: + Replaced windowObjectCleared with this function. Does nothing if the + passed-in world is not the mainThreadNormalWorld(). + +2009-11-13 Andras Becsi <becsi.andras@stud.u-szeged.hu> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Enable Page Cache if setMaximumPagesInCache needs it. + This fixes https://bugs.webkit.org/show_bug.cgi?id=31266. + + * Api/qwebsettings.cpp: + (QWebSettingsPrivate::apply): + (QWebSettings::setMaximumPagesInCache): + +2009-11-13 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Fix initial QWebView focus behavior. + + focusController->setFocused(true) was not always called. + https://bugs.webkit.org/show_bug.cgi?id=31466 + + * Api/qwebpage.cpp: + (QWebPagePrivate::focusInEvent): + +2009-11-13 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Reviewed by Simon Hausmann. + + Update documentation for the Qt API + + * Api/qgraphicswebview.cpp: + * Api/qwebelement.cpp: + * Api/qwebframe.cpp: + * Api/qwebsettings.cpp: + * Api/qwebview.cpp: + +2009-11-13 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Reviewed by Simon Hausmann. + + Use correct install-path when running qdoc3 + + * docs/docs.pri: + +2009-11-12 Shinichiro Hamaji <hamaji@chromium.org> + + Reviewed by Darin Adler. + + externalRepresentation should take Frame as the argument + https://bugs.webkit.org/show_bug.cgi?id=31393 + + No new tests as this is just a refactoring. + + * Api/qwebframe.cpp: + (QWebFrame::renderTreeDump): + +2009-11-12 Antonio Gomes <tonikitoo@webkit.org> + + Reviewed by Jan Alonzo. + + [Qt] Various doc fixes + https://bugs.webkit.org/show_bug.cgi?id=31358 + + QWebPage's constructor docs are mentioning "QWebView": + "Constructs an empty QWebView with parent". + + * Api/qwebpage.cpp: + +2009-11-12 Benjamin Poulain <benjamin.poulain@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + Custom printing shrink factors + https://bugs.webkit.org/show_bug.cgi?id=29042 + + This reverts commit r49769. The public API for this needs to be reviewed + before its inclusion in Qt. + + * Api/qwebsettings.cpp: + (QWebSettingsPrivate::apply): + (QWebSettings::QWebSettings): + * Api/qwebsettings.h: + +2009-11-11 Antonio Gomes <tonikitoo@webkit.org> + + Reviewed by Kenneth Christiansen. + + [Qt] Various doc fixes + https://bugs.webkit.org/show_bug.cgi?id=31358 + + Fixed wrong documentation: item's dimensions do fit to Web page + content by default. + + Kenneth agreed to land this as a followup patch to the + just landed documentation patch. + + * Api/qgraphicswebview.cpp: + +2009-11-11 David Boddie <dboddie@trolltech.com> + + Reviewed by Kenneth Christiansen. + + [Qt] Various doc fixes + https://bugs.webkit.org/show_bug.cgi?id=31323 + + Fixed and synchronized QWebView related documentation. + + * Api/qgraphicswebview.cpp: + * Api/qwebview.cpp: + +2009-11-11 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Unreviewed buildbot fix. + + Export a method to the DRT to know if the document has a + document element. + + * Api/qwebframe.cpp: + (qt_drt_hasDocumentElement): + +2009-11-11 Liang QI <liang.qi@nokia.com> + + [Qt] Fix tst_qwebpage and tst_qwebframe compilation on Symbian. + + * tests/qwebframe/qwebframe.pro: + * tests/qwebframe/tst_qwebframe.cpp: + * tests/qwebpage/qwebpage.pro: + * tests/qwebpage/tst_qwebpage.cpp: + +2009-11-11 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Simon Hausmann. + + Fix a crash in the layout test plugins/document-open.html + + * Api/qwebframe.cpp: + (QWebFrame::toPlainText): + +2009-11-11 Warwick Allison <warwick.allison@nokia.com>, Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Tor Arne Vestbø. + + [Qt] Regression: Preserve the parent of plugin objects when using + QtWebKit with only a QWebPage. + + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::createPlugin): Don't reparent + plugins to 0. + * tests/qwebpage/tst_qwebpage.cpp: + (PluginCounterPage::PluginCounterPage): Initialize m_pluginParent to 0. + (PluginCounterPage::~PluginCounterPage): Delete the plugin parent later + (after the page) + (PluginTracerPage::createPlugin): Assign a dummy parent to the plugin. + (PluginTracerPage::PluginTracerPage): Set up the plugin parent. + (tst_QWebPage::createViewlessPlugin): Verify that for viewless pages the + plugin parent remains unchanged. + +2009-11-11 David Boddie <dboddie@trolltech.com> + + [Qt] Doc: Added internal or hidden placeholder documentation. + + * Api/qwebpage.cpp: + +2009-11-11 Martin Smith <msmith@trolltech.com> + + [Qt] doc: Changed Trolltech to Nokia + + * Api/qwebview.cpp: + +2009-11-11 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + https://bugs.webkit.org/show_bug.cgi?id=31323 + Fix a few compiler warnings + + * tests/qwebframe/tst_qwebframe.cpp: Add extra brackets + to make it explicit where the else case belongs + +2009-11-11 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Tor Arne Vestbø. + + Fix enabling of software input panel when activating editable elements + in QGraphicsWebView. + + * Api/qgraphicswebview.cpp: + (QGraphicsWebViewPrivate::inputMethodEnabled): Implement method to + query for input method support. + * Api/qwebpage.cpp: + (QWebPageWidgetClient::inputMethodEnabled): Ditto for QWidget. + (QWebPagePrivate::handleSoftwareInputPanel): Don't use view() to + test for input method support. Instead query using QWebPageClient + and send the SIPR event to the ownerWidget() instead of the view(). + The latter is null for QGraphicsWebView. + * tests/qwebpage/tst_qwebpage.cpp: + (EventSpy::EventSpy): + (EventSpy::eventFilter): + (tst_QWebPage::inputMethods): Modify the test to verify that SIPR + events are dispatched when activating focusable content. + +2009-11-10 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Unreviewed documentation fixes. + + Added a few improvements from Jocelyn Turcotte to the + createWindow docs. + + * Api/qwebview.cpp: + +2009-11-10 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Unreviewed documentation fix. + + [Qt] Make qwebpage's createWindow not qwebview dependent. + https://bugs.webkit.org/show_bug.cgi?id=30771 + + Update documentation to make it clear that a reimplementation + of the createWindow method of the associated QWebPage can + result in the QWebView::createWindow method to never be called. + + * Api/qwebview.cpp: + +2009-11-09 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Few classes have virtual functions but non-virtual destructor + https://bugs.webkit.org/show_bug.cgi?id=31269 + + * Api/qgraphicswebview.cpp: + (QGraphicsWebViewPrivate::~QGraphicsWebViewPrivate): Add virtual + destructor. + +2009-11-09 Benjamin Poulain <benjamin.poulain@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + https://bugs.webkit.org/show_bug.cgi?id=30628 + Add an API to get all the attributes from a QWebElement. + + * Api/qwebelement.cpp: + (QWebElement::attributesName): + * Api/qwebelement.h: + * tests/qwebelement/tst_qwebelement.cpp: + (tst_QWebElement::listAttributes): + +2009-11-09 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + Use explicit parentheses to silence gcc 4.4 -Wparentheses warnings + https://bugs.webkit.org/show_bug.cgi?id=31040 + + * Api/qwebpage.cpp: + (QWebPagePrivate::handleScrolling): + +2009-11-09 Mark Mentovai <mark@chromium.org> + + Reviewed by Dan Bernstein. + + Track "can have scrollbar" state within FrameView independently of the + individual scrollbar states in ScrollView. + + rdar://problem/7215132, https://bugs.webkit.org/show_bug.cgi?id=29167 + REGRESSION (r48064): mint.com loses scrollbars after coming out of + edit mode. + + rdar://problem/7314421, https://bugs.webkit.org/show_bug.cgi?id=30517 + REGRESSION (r48064): Extra scroll bars in GarageBand Lesson Store. + + Test: fast/overflow/scrollbar-restored.html + + * Api/qwebframe.cpp: + (QWebFrame::setScrollBarPolicy): + +2009-11-09 Benjamin Poulain <benjamin.poulain@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + https://bugs.webkit.org/show_bug.cgi?id=30772 + Add a non-const iterator to QWebElementCollection. + Move the two attributes of the iterator to private. + + * Api/qwebelement.h: + (const_iterator::begin): + (const_iterator::end): + (const_iterator::constBegin): + (const_iterator::constEnd): + (const_iterator::iterator::iterator): + (const_iterator::iterator::operator*): + (const_iterator::iterator::operator==): + (const_iterator::iterator::operator!=): + (const_iterator::iterator::operator<): + (const_iterator::iterator::operator<=): + (const_iterator::iterator::operator>): + (const_iterator::iterator::operator>=): + (const_iterator::iterator::operator++): + (const_iterator::iterator::operator--): + (const_iterator::iterator::operator+=): + (const_iterator::iterator::operator-=): + (const_iterator::iterator::operator+): + (const_iterator::iterator::operator-): + * tests/qwebelement/tst_qwebelement.cpp: + (tst_QWebElement::nonConstIterator): + (tst_QWebElement::constIterator): + +2009-11-09 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Kenneth Christiansen. + + [Qt] Remove the sessionStorage setting (per Page) + https://bugs.webkit.org/show_bug.cgi?id=31249 + + This setting allows to run sessionStorage on/off on a per page + basis. Remove this prematurely exposed API. + + * Api/qwebsettings.cpp: + (QWebSettingsPrivate::apply): + (QWebSettings::QWebSettings): + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::database): + (tst_QWebPage::testOptionalJSObjects): + +2009-11-09 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Remove the QWebPage:webInspectorTriggered signal. + User customization of the communication between QWebPage + and QWebInspector will be properly designed in the next version. + https://bugs.webkit.org/show_bug.cgi?id=30773 + + * Api/qwebinspector.cpp: + * Api/qwebpage.cpp: + (QWebPagePrivate::getOrCreateInspector): + (QWebPage::triggerAction): + * Api/qwebpage.h: + * QtLauncher/main.cpp: + (MainWindow::MainWindow): + +2009-11-05 Simon Hausmann <hausmann@webkit.org> + + Reviewed by Tor Arne Vestbø. + + Added a missing re-implementation of QGraphicsItem::inputMethodQuery(). + + * Api/qgraphicswebview.cpp: + (QGraphicsWebView::inputMethodQuery): + * Api/qgraphicswebview.h: + +2009-11-04 Simon Hausmann <hausmann@webkit.org> + + Reviewed by Tor Arne Vestbø. + + Provide a dummy re-implementation of QGraphicsLayoutItem::sizeHint(), + similar to QWebView. + + * Api/qgraphicswebview.cpp: + (QGraphicsWebView::sizeHint): + * Api/qgraphicswebview.h: + +2009-11-04 Simon Hausmann <hausmann@webkit.org> + + Reviewed by Tor Arne Vestbø. + + Removed zoomFactoryChanged() signal and added + linkClicked() to QGraphicsWebView, for consistency with + QWebView. + + * Api/qgraphicswebview.cpp: + (QGraphicsWebView::setPage): + (QGraphicsWebView::setZoomFactor): + * Api/qgraphicswebview.h: + +2009-11-04 Simon Hausmann <hausmann@webkit.org> + + Reviewed by Tor Arne Vestbø. + + Added QGraphicsWebView::findText() for convenience and consistency + with QWebView. + + * Api/qgraphicswebview.cpp: + (QGraphicsWebView::findText): + * Api/qgraphicswebview.h: + +2009-11-04 Simon Hausmann <hausmann@webkit.org> + + Reviewed by Tor Arne Vestbø. + + Added QGraphicsWebView::pageAction() and triggerPageAction(), for + consistency with QWebView. + + * Api/qgraphicswebview.cpp: + (QGraphicsWebView::pageAction): + (QGraphicsWebView::triggerPageAction): + * Api/qgraphicswebview.h: + +2009-11-04 Simon Hausmann <hausmann@webkit.org> + + Reviewed by Tor Arne Vestbø. + + Removed QGraphicsWebView::toHtml() after API review. + + That's consistent with QWebView and also based on the assumption that + toHtml() is called less frequently than setHtml(). + + * Api/qgraphicswebview.cpp: + * Api/qgraphicswebview.h: + * tests/qgraphicswebview/tst_qgraphicswebview.cpp: + (tst_QGraphicsWebView::qgraphicswebview): + +2009-11-04 Simon Hausmann <hausmann@webkit.org> + + Reviewed by Tor Arne Vestbø. + + Removed the interactive property of QGraphicsWebView. + + There are clearly use-cases for this feature, but it will require + more work to make this fully work with an enum to have fine-grained + control over the interactivity levels. For now it is easy to achieve + in user-code what the boolean property did. + + * Api/qgraphicswebview.cpp: + (QGraphicsWebViewPrivate::QGraphicsWebViewPrivate): + (QGraphicsWebView::hoverMoveEvent): + (QGraphicsWebView::mouseMoveEvent): + (QGraphicsWebView::mousePressEvent): + (QGraphicsWebView::mouseReleaseEvent): + (QGraphicsWebView::mouseDoubleClickEvent): + (QGraphicsWebView::keyPressEvent): + (QGraphicsWebView::keyReleaseEvent): + (QGraphicsWebView::dragLeaveEvent): + (QGraphicsWebView::dragMoveEvent): + (QGraphicsWebView::dropEvent): + (QGraphicsWebView::wheelEvent): + (QGraphicsWebView::inputMethodEvent): + * Api/qgraphicswebview.h: + * tests/qgraphicswebview/tst_qgraphicswebview.cpp: + (tst_QGraphicsWebView::qgraphicswebview): + +2009-11-04 Simon Hausmann <hausmann@webkit.org> + + Reviewed by Tor Arne Vestbø. + + Make the QGraphicsWebView constructor explicit. + + * Api/qgraphicswebview.h: + +2009-11-05 Shu Chang <Chang.Shu@nokia.com> + + Reviewed by Tor Arne Vestbø. + + Add support for Shift-PageUp and Shift-PageDown key events. + https://bugs.webkit.org/show_bug.cgi?id=31166 + + Test: LayoutTests/editing/selection/shrink-selection-after-shift-pagedown.html + + * WebCoreSupport/EditorClientQt.cpp: + (WebCore::EditorClientQt::handleKeyboardEvent): + +2009-11-05 Simon Hausmann <hausmann@webkit.org> + + Last Qt 4.5 build fix (*sigh*) + + * tests/qwebpage/tst_qwebpage.cpp: + (inputMethodHints): inputMethodHints() is only used for + Qt 4.6, so guard the whole function. + +2009-11-05 Simon Hausmann <hausmann@webkit.org> + + Another prospective build fix against Qt 4.5 (build bot) + + Don't compile & run the QGraphicsWebView portion of the + input methods auto test with Qt 4.5. + + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::inputMethods_data): + (inputMethodHints): + (inputMethodEnabled): + (tst_QWebPage::inputMethods): + +2009-11-05 Simon Hausmann <hausmann@webkit.org> + + Prospective build fix against Qt 4.5 (build bot) + + * Api/qgraphicswebview.cpp: + (QGraphicsWebViewPrivate::setInputMethodEnabled): Guard the + use of Qt 4.6 specific API with #ifdefs. + +2009-11-01 Simon Hausmann <hausmann@webkit.org> + + Reviewed by Kenneth Christiansen. + + [Qt] Fix enabling of input method support on QGraphicsWebView. + https://bugs.webkit.org/show_bug.cgi?id=30605 + + Instead of setting the unsupported widget attribute on the + QGraphicsWidget in setInputMethodEnabled() set the + ItemAcceptsInputMethod GraphicsItem flag directly. + + Changed the existing input method auto test to run once + on a QWebView and once on a QGraphicsWebView. + + * Api/qgraphicswebview.cpp: + (QGraphicsWebViewPrivate::setInputMethodEnabled): + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::inputMethods_data): + (inputMethodHints): + (inputMethodEnabled): + (tst_QWebPage::inputMethods): + +2009-11-04 Simon Hausmann <hausmann@webkit.org> + + Reviewed by Kenneth Christiansen. + + Added QGraphicsWebView::modified property, for consistency + with QWebView. + + * Api/qgraphicswebview.cpp: + (QGraphicsWebView::isModified): + * Api/qgraphicswebview.h: + * tests/qgraphicswebview/tst_qgraphicswebview.cpp: + (tst_QGraphicsWebView::qgraphicswebview): + +2009-11-04 Simon Hausmann <hausmann@webkit.org> + + Reviewed by Kenneth Christiansen. + + Removed status and progress properties of QGraphicsWebView. + Added loadProgress and statusBarMessage signals instead, + after API review. + + * Api/qgraphicswebview.cpp: + (QGraphicsWebViewPrivate::QGraphicsWebViewPrivate): + (QGraphicsWebView::setPage): + * Api/qgraphicswebview.h: + * tests/qgraphicswebview/tst_qgraphicswebview.cpp: + (tst_QGraphicsWebView::qgraphicswebview): + +2009-11-04 Yael Aharon <yael.aharon@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] REGRESSION: Allow applications to use their own QWidget bypassing QWebView. + https://bugs.webkit.org/show_bug.cgi?id=30979 + + Decouple QWebViewPrivate from QWebPageClient, and automatically create + QWebPageWidgetClient whenever the view is QWidget based. + + * Api/qwebpage.cpp: + (QWebPageWidgetClient::QWebPageWidgetClient): + (QWebPageWidgetClient::scroll): + (QWebPageWidgetClient::update): + (QWebPageWidgetClient::setInputMethodEnabled): + (QWebPageWidgetClient::setInputMethodHint): + (QWebPageWidgetClient::cursor): + (QWebPageWidgetClient::updateCursor): + (QWebPageWidgetClient::palette): + (QWebPageWidgetClient::screenNumber): + (QWebPageWidgetClient::ownerWidget): + (QWebPageWidgetClient::pluginParent): + (QWebPage::setView): + * Api/qwebview.cpp: + (QWebView::~QWebView): + (QWebView::setPage): + (QWebView::event): + +2009-11-03 Andras Becsi <becsi.andras@stud.u-szeged.hu> + + Reviewed by Simon Hausmann. + + [Qt] Fix build of unit-test after r50454. + + * tests/qwebpage/tst_qwebpage.cpp: + +2009-11-03 Simon Hausmann <hausmann@webkit.org> + + Reviewed by Tor Arne Vestbø. + + Make QWebPluginDatabase private API for now. + + https://bugs.webkit.org/show_bug.cgi?id=30775 + + * Api/headers.pri: + * Api/qwebplugindatabase.cpp: + * Api/qwebplugindatabase_p.h: Renamed from WebKit/qt/Api/qwebplugindatabase.h. + * Api/qwebsettings.cpp: + * Api/qwebsettings.h: + * QtLauncher/main.cpp: + (MainWindow::setupUI): + * tests/tests.pro: + +2009-11-03 Simon Hausmann <hausmann@webkit.org> + + Rubber-stamped by Tor Arne Vestbø. + + Oops, also remove the API docs of the removed networkRequestStarted() signal. + + * Api/qwebpage.cpp: + +2009-11-03 Simon Hausmann <hausmann@webkit.org> + + Reviewed by Tor Arne Vestbø. + + Replace the QWebPage::networkRequestStarted() signal with the originatingObject + property set to the QWebFrame that belongs to the request. + + https://bugs.webkit.org/show_bug.cgi?id=29975 + + * Api/qwebpage.h: + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::dispatchDecidePolicyForNewWindowAction): + (WebCore::FrameLoaderClientQt::dispatchDecidePolicyForNavigationAction): + (WebCore::FrameLoaderClientQt::startDownload): + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::loadFinished): + (TestNetworkManager::createRequest): + (tst_QWebPage::originatingObjectInNetworkRequests): + +2009-11-02 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Adam Barth. + + QWebView crash fix. + + The QWebView should not crash if the stop() method is called from + a function triggered by the loadProgress signal. + + A null pointer protection was added in the ProgressTracker::incrementProgress. + + New autotest was created. + + https://bugs.webkit.org/show_bug.cgi?id=29425 + + * tests/qwebview/tst_qwebview.cpp: + (WebViewCrashTest::WebViewCrashTest): + (WebViewCrashTest::loading): + (tst_QWebView::crashTests): + +2009-11-01 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Eric Seidel. + + Turn on warnings for QtWebKit for gcc + https://bugs.webkit.org/show_bug.cgi?id=30958 + + * Api/qwebpage.cpp: + (QWebPagePrivate::QWebPagePrivate): Reorder initialization list + to fix compiler warnings. + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::FrameLoaderClientQt): Ditto. + +2009-10-30 Evan Stade <estade@chromium.org> + + Reviewed by David Levin. + + Notify the chrome when the focused node has changed. + https://bugs.webkit.org/show_bug.cgi?id=30832 + + Added stub implementation for new ChromeClient function. + + * WebCoreSupport/ChromeClientQt.cpp: + (WebCore::ChromeClientQt::focusedNodeChanged): + * WebCoreSupport/ChromeClientQt.h: + +2009-10-30 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Tor Arne Vestbø. + + [Qt] Remove the QWebInspector::windowTitleChanged signal, + QEvent::WindowTitleChange can be used to achieve the same. + https://bugs.webkit.org/show_bug.cgi?id=30927 + + * Api/qwebinspector.cpp: + * Api/qwebinspector.h: + * WebCoreSupport/InspectorClientQt.cpp: + (WebCore::InspectorClientQt::updateWindowTitle): + +2009-10-29 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Tor Arne Vestbø. + + [Qt] Implement DELETE HTTP method for XmlHttpRequest + https://bugs.webkit.org/show_bug.cgi?id=30894 + + No new tests as this functionality is already tested by the + xmlhttprequest LayoutTests. As this patch depends on an unreleased + version of the dependent QtNetwork library and the tests will be + enabled later once the dependent library is released (and the + buildbot is updated). + + * Api/qwebframe.cpp: + (QWebFrame::load): + +2009-10-29 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Tor Arne Vestbø. + + Remove QWebView::guessUrlFromString() and replace its use + with the new QUrl::fromUserInput() if using Qt 4.6 or newer. + + * Api/qwebview.cpp: + * Api/qwebview.h: + * QGVLauncher/main.cpp: + (urlFromUserInput): + (WebPage::applyProxy): + (MainWindow::load): + * QtLauncher/main.cpp: + (urlFromUserInput): + (MainWindow::MainWindow): + (MainWindow::changeLocation): + * tests/qwebview/tst_qwebview.cpp: + +2009-10-28 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Tor Arne Vestbø. + + Serialize directly to the stream, and not first to an QByteArray, + that is later serialized. That is slower and also uses more bytes. + + * Api/qwebhistory.cpp: + (operator<<): + (operator>>): + +2009-10-28 Shinichiro Hamaji <hamaji@chromium.org> + + Reviewed by Eric Seidel. + + [Qt] WebFrame::counterValueForElementById must not be exposed + https://bugs.webkit.org/show_bug.cgi?id=30882 + + * Api/qwebframe.cpp: + (qt_drt_counterValueForElementById): + * Api/qwebframe.h: + +2009-10-27 Shinichiro Hamaji <hamaji@chromium.org> + + Reviewed by Darin Adler. + + Provide a way to get counter values with layoutTestContoller + https://bugs.webkit.org/show_bug.cgi?id=30555 + + * Api/qwebframe.cpp: + (QWebFrame::counterValueForElementById): + (QWebHitTestResult::frame): + * Api/qwebframe.h: + +2009-10-28 Antonio Gomes <tonikitoo@webkit.org> + + Pushing missing WebKit/qt/tests/qwebframe/resources/ dir from bug 29248. + + [Qt] [API] Make it possible to have 'invisible' loads + https://bugs.webkit.org/show_bug.cgi?id=29248 + + * tests/qwebframe/resources/image2.png: Copied from WebKit/qt/tests/qwebelement/image.png. + +2009-10-28 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Tor Arne Vestbø. + + [Qt] QWebHistory::saveState() is inconsistent with the Qt API + https://bugs.webkit.org/show_bug.cgi?id=30710 + + Make the versioning internal and enforce it in the WebCore + part. Adjust the comments, as well as remove now dead code. + + * Api/qwebhistory.cpp: + (operator<<): + (operator>>): + * Api/qwebhistory.h: + +2009-10-28 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Holger Freyther. + + [Qt] QWebHistory::saveState() is inconsistent with the Qt API + https://bugs.webkit.org/show_bug.cgi?id=30710 + + Remove the QWebHistory::saveState() and ::restoreState() as + they are inconsistent with the Qt API. + + Update unittests to reflect the change. + + * Api/qwebhistory.cpp: + (operator<<): + (operator>>): + * Api/qwebhistory.h: + * tests/qwebhistory/tst_qwebhistory.cpp: + (saveHistory): + (restoreHistory): + (tst_QWebHistory::saveAndRestore_crash_1): + (tst_QWebHistory::saveAndRestore_crash_2): + (tst_QWebHistory::saveAndRestore_crash_3): + (tst_QWebHistory::clear): + +2009-10-27 Antonio Gomes <tonikitoo@webkit.org> + + Reviewed by Holger Freyther. + + Complementary fix to bug 30779. + + By mistake I used QWeakPointer's toStrongRef() method which docs + explicitly say to not be used in this situation (when the tracked + pointer is devired from QObject). Instead QWeakPointer's data() + is recommended. + + * Api/qwebpage.cpp: + (QWebPage::view): + +2009-10-27 Holger Hans Peter Freyther <zecke@selfish.org> + + Reviewed by Simon Fraser. + + Change HitTestResult methods to use (3d) transformation aware methods + https://bugs.webkit.org/show_bug.cgi?id=27347 + + The HitTestResult::boundingBox method was removed. The + RenderObject must be used directly. In contrast to the + old HitTestResult::boundingBox method this code must use + a (3d) transformation aware method to not run into an + assert in SVGRenderBase::mapLocalToContainer. + + * Api/qwebframe.cpp: + (QWebHitTestResultPrivate::QWebHitTestResultPrivate): + +2009-10-27 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Rubberstamped by Oliver Hunt. + + Change two methods to be internal for DRT use only. + + Part of [Qt] Review all new API in Qt 4.6 + https://bugs.webkit.org/show_bug.cgi?id=29843#c11 + + * Api/qwebsecurityorigin.cpp: + (qt_drt_whiteListAccessFromOrigin): + (qt_drt_resetOriginAccessWhiteLists): + (QWebSecurityOrigin::localSchemes): + * Api/qwebsecurityorigin.h: + +2009-10-27 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Tor Arne Vestbø. + + Make sure that initiating a rotation while rotating won't make + it end up at rotation positions that are not a multiply of + 180 degrees. + + * QGVLauncher/main.cpp: + (MainView::animatedFlip): + +2009-10-27 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Unreviewed Qt build fix. + + Update the tests as well to the new API change. + + * tests/qwebelement/tst_qwebelement.cpp: + (tst_QWebElement::clear): + +2009-10-27 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Rubberstamped by Tor Arne Vestbø. + + [Qt] QWebElement::removeChildren() should be + QWebElement::removeAllChildren() + https://bugs.webkit.org/show_bug.cgi?id=30630 + + * Api/qwebelement.cpp: + (QWebElement::removeAllChildren): + * Api/qwebelement.h: + +2009-10-27 Antonio Gomes <tonikitoo@webkit.org> + + Reviewed by Antti Koivisto and Holger Freyther. + + Make QWebPagePrivate's (QWidget) view to be a QWeakPointer. + https://bugs.webkit.org/show_bug.cgi?id=30779 + + The fact that it was been set from external objects of qwebpage + and not being deleted internally can lead to dangling references. + + * Api/qgraphicswebview.cpp: + (QGraphicsWebView::~QGraphicsWebView): + * Api/qwebpage.cpp: + (QWebPagePrivate::QWebPagePrivate): + (QWebPagePrivate::createContextMenu): + (QWebPagePrivate::handleSoftwareInputPanel): + (QWebPagePrivate::keyPressEvent): + (QWebPage::setView): + (QWebPage::view): + (QWebPage::javaScriptAlert): + (QWebPage::javaScriptConfirm): + (QWebPage::javaScriptPrompt): + (QWebPage::shouldInterruptJavaScript): + (QWebPage::createWindow): + (QWebPage::extension): + (QWebPage::chooseFile): + (QWebPage::userAgentForUrl): + * Api/qwebpage_p.h: + * Api/qwebview.cpp: + (QWebView::~QWebView): + +2009-10-26 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Unreviewed documentation fix from David Boddie (Qt Doc Team) + + Removes the check around the RenderHints property documentation + that was clearly added to synchronize the source and header files + when the #if !defined(Q_OS_SYMBIAN) guards was added to the + property. + + The documentation has also been updated to ensure that Symbian + users know that there is no actual RenderHints property on their + platform. + + * Api/qwebview.cpp: + +2009-10-26 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Unreviewed documentation fix from David Boddie (Qt Doc Team) + + Ensure that qdoc will always see the RenderHints property. + + The property was only defined in the header file if the Q_OS_SYMBIAN + symbol was not defined, resulting in the property not showing up + in the Qt documentation just because one platform doesn't support it. + + A follow up commit will improve the documentation for the property + and note that it is not supported on the Symbiam platform. + + * Api/qwebview.h: + +2009-10-26 Benjamin Poulain <benjamin.poulain@nokia.com> + + Reviewed by Tor Arne Vestbø. + + [Qt] Reintroduce QWebElementCollection + + Revert the patch that has replaced QWebElementCollection + with QList<QWebElement>. Update the tests accordingly. + + Remove the constness of the return type of QWebElement operator[]. + + https://bugs.webkit.org/show_bug.cgi?id=30767 + + * Api/qwebelement.cpp: + (QWebElement::findAll): + (QWebElementCollectionPrivate::QWebElementCollectionPrivate): + (QWebElementCollectionPrivate::create): + (QWebElementCollection::QWebElementCollection): + (QWebElementCollection::operator=): + (QWebElementCollection::~QWebElementCollection): + (QWebElementCollection::operator+): + (QWebElementCollection::append): + (QWebElementCollection::count): + (QWebElementCollection::at): + (QWebElementCollection::toList): + * Api/qwebelement.h: + (const_iterator::begin): + (const_iterator::end): + (const_iterator::operator[]): + * Api/qwebframe.cpp: + (QWebFrame::findAllElements): + * Api/qwebframe.h: + * QtLauncher/main.cpp: + (MainWindow::selectElements): + * tests/qwebelement/tst_qwebelement.cpp: + (tst_QWebElement::simpleCollection): + (tst_QWebElement::iteration): + (tst_QWebElement::emptyCollection): + (tst_QWebElement::appendCollection): + (tst_QWebElement::nullSelect): + (tst_QWebElement::hasSetFocus): + (tst_QWebElement::render): + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::inputMethods): + +2009-10-24 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Holger Freyther. + + [Qt] [Symbian] Set the capability and memory required to run QtWebKit for Symbian + https://bugs.webkit.org/show_bug.cgi?id=30476 + + Assign ReadUserData WriteUserData NetworkServices Symbian capabilities + to all QtWebkit executables. + + * QGVLauncher/QGVLauncher.pro: + * QtLauncher/QtLauncher.pro: + * tests/benchmarks/loading/tst_loading.pro: + * tests/benchmarks/painting/tst_painting.pro: + * tests/qgraphicswebview/qgraphicswebview.pro: + * tests/qwebelement/qwebelement.pro: + * tests/qwebframe/qwebframe.pro: + * tests/qwebhistory/qwebhistory.pro: + * tests/qwebhistoryinterface/qwebhistoryinterface.pro: + * tests/qwebpage/qwebpage.pro: + * tests/qwebplugindatabase/qwebplugindatabase.pro: + * tests/qwebview/qwebview.pro: + +2009-10-22 Gavin Barraclough <barraclough@apple.com> + + Reviewed by NOBODY (speculative build fix - qt is currently already broken!) + Build fix following bug #30696. + + * Api/qwebelement.cpp: + (setupScriptContext): + * Api/qwebframe.cpp: + (QWebFrame::evaluateJavaScript): + +2009-10-22 Shu Chang <Chang.Shu@nokia.com> + + Reviewed by Eric Seidel. + + [Qt] Enable track visited links in QWebPage + https://bugs.webkit.org/show_bug.cgi?id=30574 + + Test: fast/history/clicked-link-is-visited.html + + * Api/qwebpage.cpp: + (QWebPagePrivate::QWebPagePrivate): + +2009-10-22 Girish Ramakrishnan <girish@forwardbias.in> + + Reviewed by Eric Seidel. + + [Qt] Add Print Shortcut to QtLauncher + + https://bugs.webkit.org/show_bug.cgi?id=30682 + + * QtLauncher/main.cpp: + (MainWindow::setupUI): + +2009-10-22 Antonio Gomes <tonikitoo@webkit.org> + + Rubberstamped by Tor Arne Vestbø. + + Code standarlization for QGVLauncher. + + 1) Made member initilization lists in constructors + to be per line. + 2) Made applyProxy method inline as all other methods in + WebPage class. + + * QGVLauncher/main.cpp: + (WebPage::WebPage): + (WebPage::applyProxy): + (MainView::MainView): + (MainWindow::MainWindow): + (MainWindow::init): + +2009-10-22 Antonio Gomes <tonikitoo@webkit.org> + + Reviewed by Tor Arne Vestbø. + + Add a Y-Axis rotation to QGVLauncher. + + It uses the QStateMachine API from Qt 4.6. + + * QGVLauncher/main.cpp: + (WebView::WebView): + (WebView::setYRotation): + (WebView::yRotation): + (MainView::flip): + (MainView::animatedYFlip): + (SharedScene::SharedScene): + (SharedScene::webView): + (MainWindow::init): + (MainWindow::animatedYFlip): + (MainWindow::buildUI): + +2009-10-20 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed By Adam Barth. + + Add some actions to the menu for cursor debugging. + + GraphicsView based launcher only. + + * QGVLauncher/main.cpp: + (MainView::setWaitCursor): + (MainView::resetCursor): + (MainView::flip): + (MainWindow::setWaitCursor): + (MainWindow::resetCursor): + (MainWindow::buildUI): + +2009-10-20 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Rubberstamped by Adam Barth. + + Remove clipRenderToViewport as agreed upon in + https://bugs.webkit.org/show_bug.cgi?id=29843 + + * Api/qwebframe.cpp: + * Api/qwebframe.h: + * Api/qwebframe_p.h: + (QWebFramePrivate::QWebFramePrivate): + +2009-10-20 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Adam Barth. + + Update the tests to test the new render functionality, and take + into consideration that render() clips to the frame itself as well + as the viewport. + + QWebFrame::render() now always clips, so the old tests were bogus. + + Rendering pure contents (no scrollbars etc) without clipping can now + be accomplished using QWebFrame::documentElement()->render(...) + + * Api/qwebframe.cpp: + * Api/qwebframe.h: + * Api/qwebframe_p.h: + (QWebFramePrivate::QWebFramePrivate): + * tests/qwebframe/tst_qwebframe.cpp: + +2009-10-20 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Rubberstamped by Adam Barth. + + As we do not support rendering a QWebFrame without it being clipped + the the frame as well as the viewport, we now set the viewport size + to the size of the contents. + + Rendering pure contents (no scrollbars etc) without clipping can be + acomplished using QWebFrame::documentElement()->render(...) + + * tests/qwebelement/tst_qwebelement.cpp: + (tst_QWebElement::render): + +2009-10-20 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Tor Arne Vestbø. + + Add menu item to dump the plugin list to the console, + which can be handy for debugging. + + * QtLauncher/main.cpp: + (MainWindow::dumpPlugins): + (MainWindow::setupUI): + +2009-10-19 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Tor Arne Vestbø. + + Introduce new render method on QWebFrame, which supports specifying + which layers to render (scrollbars, contents, pan-icon). + + * Api/qwebframe.cpp: + (QWebFramePrivate::renderPrivate): + (QWebFrame::render): + * Api/qwebframe.h: + * Api/qwebframe_p.h: + +2009-10-19 Antonio Gomes <tonikitoo@webkit.org> + + Reviewed by Ariya Hidayat. + + [Qt] Infinite loop (leading to crash) when setting cursor in QGraphicsWebView + https://bugs.webkit.org/show_bug.cgi?id=30549 + + Patch reimplements QGraphicsItem's itemChange method, and make + CursorChange event to be emitted after cursor has already been + set. + + QWidget::setCursor send the event just after it sets the cursor, + then patch makes both behaviors compatible. + + * Api/qgraphicswebview.cpp: + (QGraphicsWebView::itemChange): + * Api/qgraphicswebview.h: + +2009-10-19 Nate Chapin <japhet@chromium.org> + + Unreviewed, build fix. + + Update call to FrameLoader::loadFrameRequest(). + + * Api/qwebpage.cpp: + (QWebPage::triggerAction): + +2009-10-19 Viatcheslav Ostapenko <ostapenko.viatcheslav@nokia.com> + + Reviewed by Ariya Hidayat. + + Add QWebElement::render API which allows rendering of single + element. + + * Api/qwebelement.cpp: + (QWebElement::render): + * Api/qwebelement.h: + * tests/qwebelement/tst_qwebelement.cpp: + (tst_QWebElement::render): + * tests/qwebelement/qwebelement.qrc: + * tests/qwebelement/image.png: Added. + +2009-10-19 Markus Goetz <Markus.Goetz@nokia.com> + + Reviewed by Ariya Hidayat. + + QWebPage: Doc: setNetworkAccessManager should only be called once. + + * Api/qwebpage.cpp: + +2009-10-19 Antonio Gomes <tonikitoo@webkit.org> + + Reviewed by Tor Arne. + + Wrong ifdef combination in QGraphicsWebView's event method. + + * Api/qgraphicswebview.cpp: + (QGraphicsWebView::event): + +2009-10-19 Girish Ramakrishnan <girish@forwardbias.in> + + Reviewed by Holger Freyther. + + [Qt] Windowed Plugins: Don't crash when client is 0. + + Client is 0 when we use QWebPage without a QWebView or QGraphicsWebView. + In addition, setFrameRect()/updatePluginWidget() is called even if the + plugin was not succesfully loaded. updatePluginWidget() updates the + window rect which is, in theory, useful to draw something that indicates + that we didn't load successfully. + + So, a status check is added to setNPWindowIfNeeded. + + https://bugs.webkit.org/show_bug.cgi?id=30380 + + * tests/qwebpage/qwebpage.pro: + * tests/qwebpage/tst_qwebpage.cpp: + (takeScreenshot): + (tst_QWebPage::screenshot_data): + (tst_QWebPage::screenshot): + * tests/resources/test.swf: Copied from LayoutTests/fast/replaced/resources/test.swf. + +2009-10-19 Girish Ramakrishnan <girish@forwardbias.in> + + Reviewed by Holger Freyther. + + [Qt] Windowed Plugins: Fix crash when QWebPage is deleted after QWebView. + + Fixes various sources of crashes: + 1. The PluginContainer is a child of QWebView. When the view gets deleted, + the PluginView is not notified about the deletion of PluginContainer. + 2. QWebView destructor does not set client to 0. + 3. Sometimes pending paint events are sent after the plugin has died, so add + a check in PluginView::setNPWindowIfNeeded. + + https://bugs.webkit.org/show_bug.cgi?id=30354 + + * Api/qwebview.cpp: + (QWebView::~QWebView): + * tests/qwebview/qwebview.pro: + * tests/qwebview/tst_qwebview.cpp: + (tst_QWebView::reusePage_data): + (tst_QWebView::reusePage): + +2009-10-19 Jakob Truelsen <antialize@gmail.com> + + Reviewed by Adam Barth. + + https://bugs.webkit.org/show_bug.cgi?id=29042 + + Allow one to costumize the minimal and maximal shrink factors, + Added methods setPrintingMinimumShrinkFactor, printingMinimumShrinkFactor, + setPrintingMaximumShrinkFactor, printingMaximumShrinkFactor to QWebSettings. + + + * Api/qwebsettings.cpp: + (QWebSettingsPrivate::apply): + (QWebSettings::QWebSettings): + (QWebSettings::setPrintingMinimumShrinkFactor): + (QWebSettings::printingMinimumShrinkFactor): + (QWebSettings::setPrintingMaximumShrinkFactor): + (QWebSettings::printingMaximumShrinkFactor): + * Api/qwebsettings.h: + +2009-10-18 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Simon Hausmann. + + Rename fixedContentsSize property to preferredContentsSize as + agreed upon with Simon Hausmann and Matthias Ettrich. + + * Api/qwebpage.cpp: + (QWebPage::preferredContentsSize): + (QWebPage::setPreferredContentsSize): + * Api/qwebpage.h: + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::transitionToCommittedForNewPage): + +2009-10-16 Antonio Gomes <tonikitoo@webkit.org> + + Reviewed by Simon Hausmann. + + [Qt] QGLauncher leaks WebPage object + https://bugs.webkit.org/show_bug.cgi?id=30465 + + Make 'SharedScene' to own 'WebPage' reference and delete it at its destructor. + + * Api/qwebpage.cpp: + (QWebPage::view): + * Api/qwebpage_p.h: + * QGVLauncher/main.cpp: + (SharedScene::SharedScene): + (SharedScene::~SharedScene): + +2009-10-16 Antonio Gomes <tonikitoo@webkit.org> + + Reviewed by Simon Hausmann. + + [Qt] "dangling" pointer to qwebpage's view object can leads QGLauncher to crash + https://bugs.webkit.org/show_bug.cgi?id=30459 + + Remove all setView(ev->widget()) calls in QWebPage and QGWV event handling methods, + since QWebPageClient would do the trick. + + * Api/qgraphicswebview.cpp: + (QGraphicsWebView::hoverMoveEvent): + * Api/qwebpage.cpp: + (QWebPagePrivate::mouseMoveEvent): + (QWebPagePrivate::mousePressEvent): + (QWebPagePrivate::mouseDoubleClickEvent): + (QWebPagePrivate::mouseReleaseEvent): + (QWebPagePrivate::wheelEvent): + (QWebPagePrivate::dragEnterEvent): + (QWebPagePrivate::dragLeaveEvent): + (QWebPagePrivate::dragMoveEvent): + +2009-10-16 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Pull out r49676 as it caused build breakges on Symbian + + * Api/qwebpage.cpp: + +2009-10-16 Yael Aharon <yael.aharon@nokia.com> + + Reviewed by Tor Arne Vestbø. + + [Qt] Need a way to inform the application when a Netscape plugin is created or deleted + https://bugs.webkit.org/show_bug.cgi?id=30179 + + Added "c" style static methods for the application to hook up for + receiving notifications when a plugin is created or destroyed. + + * Api/qwebpage.cpp: + +2009-10-15 Antonio Gomes <tonikitoo@webkit.org> + + Rubberstamped by Tor Arne. + + Make QGLauncher's WebPage class constructor to get a QObject* as parent (not QWidget*). + + * QGVLauncher/main.cpp: + (WebPage::WebPage): + +2009-10-15 Antonio Gomes <tonikitoo@webkit.org> + + Reviewed by Tor Arne. + + [Qt] QGLauncher crashes while closing a window + https://bugs.webkit.org/show_bug.cgi?id=30385 + + Set page's pageClient reference to '0' at QGWV deletion. + + * Api/qgraphicswebview.cpp: + (QGraphicsWebView::~QGraphicsWebView): + * tests/qgraphicswebview/tst_qgraphicswebview.cpp: + (WebPage::WebPage): + (WebPage::aborting): + (tst_QGraphicsWebView::crashOnViewlessWebPages): + +2009-10-13 Antonio Gomes <tonikitoo@webkit.org> + + Reviewed by Simon Hausmann. + + [Qt] Make context menu to work in QGraphicsWebView + https://bugs.webkit.org/show_bug.cgi?id=30336 + + * Api/qgraphicswebview.cpp: + (QGraphicsWebView::event): + +2009-10-13 Girish Ramakrishnan <girish@forwardbias.in> + + Reviewed by Simon Hausmann. + + [Qt] Plugins : Remove all traces of winId. Use ownerWidget() instead. + + This is a bug for two reasons: + 1. Everytime we use winId(), we end up creating a native widget. This causes an + unnecessary copy of contents from the backing store to the native widget. + 2. Neither windowed nor windowless plugins require the winId of the QWebView or + QGraphicsView. + + Introduce ownerWidget() which returns a QWidget * without creating a native widget + (as opposed to QWidget::find(winId)). + + https://bugs.webkit.org/show_bug.cgi?id=30170 + + * Api/qgraphicswebview.cpp: + (QGraphicsWebViewPrivate::ownerWidget): + * Api/qwebview.cpp: + (QWebViewPrivate::ownerWidget): + +2009-10-13 Antonio Gomes <tonikitoo@webkit.org> + + Reviewed by Simon Hausmann. + + [Qt] Add some initial autotests for QWebPage's ErrorPageExtention + https://bugs.webkit.org/show_bug.cgi?id=30296 + + * tests/qwebpage/tst_qwebpage.cpp: + (ErrorPage::ErrorPage): + (ErrorPage::supportsExtension): + (ErrorPage::extension): + (tst_QWebPage::errorPageExtension): + +2009-10-13 Antonio Gomes <tonikitoo@webkit.org> + + Reviewed by Simon Hausmann. + + [Qt] better handle possible edge cases on qwebframe::requestedUrl use + https://bugs.webkit.org/show_bug.cgi?id=30216 + + QWebFrame::requestedUrl can be called at any time during the load + process, including: + + * An error handling (whereas an alternate error page for unsuccessful + load is being set); + * A ssl error exception call; + * During navigation notifications/callbacks (titleChanged, urlChanged, + progresses, addHistoryEntry, etc); + * Among others. + + This patch makes requestedUrl calls to fallback to FrameLoaderClient + m_loadError's failingURL when an error has occurred, unless it is + null/empty. + + Also, m_loadError is now being reset at each the main frame starts a + load, in order to avoid previous load errors footprints. + + * Api/qwebframe.cpp: + (QWebFrame::requestedUrl): + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::postProgressStartedNotification): + +2009-10-12 Jakub Wieczorek <faw217@gmail.com> + + Reviewed by Simon Hausmann. + + [Qt] Missing default value for the default text encoding. + https://bugs.webkit.org/show_bug.cgi?id=30311 + + QtWebKit has provided a default, hardcoded value for default charset but since + the addition of the defaultTextEncoding setting in QWebSettings, that hardcoded + value has had no effect. + + Added a regression test and unskipped fast/dom/Document/document-charset.html, + which is passing now. + + * Api/qwebpage.cpp: + (QWebPagePrivate::QWebPagePrivate): + * Api/qwebsettings.cpp: + (QWebSettings::QWebSettings): + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::defaultTextEncoding): + +2009-10-12 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Simon Hausmann. + + Implement the new palette() methods on the page clients + + * Api/qgraphicswebview.cpp: + (QGraphicsWebViewPrivate::palette): + * Api/qwebview.cpp: + (QWebViewPrivate::palette): + +2009-10-12 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Simon Hausmann. + + QWebPage's createViewlessPlugin autotest crash fix. + + It is possible that plugins that are QWidgets or QGraphicsWidgets + are created before a view has been assigned to a QWebPage. The + plug-ins won't be fully functional, as by design, they should + visualise something, but they won't crash and will stay in memory. + + An autotest that covers this use-case, is included. + + https://bugs.webkit.org/show_bug.cgi?id=30118 + + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::createPlugin): + * tests/qwebpage/tst_qwebpage.cpp: + (PluginTrackedPageWidget::PluginTrackedPageWidget): + (PluginTrackedPageGraphicsWidget::PluginTrackedPageGraphicsWidget): + (PluginTrackedPageGraphicsWidget::createPlugin): + (tst_QWebPage::destroyPlugin): + (tst_QWebPage::createViewlessPlugin): + +2009-10-09 Joe Ligman <joseph.ligman@nokia.com> + + Reviewed by Simon Hausmann. + + Sets Qt::WA_InputMethodEnabled and Qt::ImhHiddenText for password fields in EditorClientQt + setInputMethodState. This change is needed so widgets such as the s60 software + input panel can receive input method events for password fields. + It's up to the Qt platform to determine which widget will receive input method + events when these flags are set. + Also added implementation for setInputMethodEnabled and setInputMethodHint + to QGraphicsWebViewPrivate and QWebViewPrivate. This change removes the direct + dependency on QWebView and uses QWebPageClient. + Added autotest to tst_qwebpage.cpp + https://bugs.webkit.org/show_bug.cgi?id=30023 + + * Api/qgraphicswebview.cpp: + (QGraphicsWebViewPrivate::setInputMethodEnabled): + (QGraphicsWebViewPrivate::setInputMethodHint): + * Api/qwebview.cpp: + (QWebViewPrivate::setInputMethodEnabled): + (QWebViewPrivate::setInputMethodHint): + * WebCoreSupport/EditorClientQt.cpp: + (WebCore::EditorClientQt::setInputMethodState): + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::inputMethods): + +2009-10-08 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + Move executeScript from FrameLoader to ScriptController + https://bugs.webkit.org/show_bug.cgi?id=30200 + + Update API call. + + * Api/qwebframe.cpp: + (QWebFrame::evaluateJavaScript): + +2009-10-08 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Simon Hausmann. + + Part of testOptionalJSObjects autotest was marked as "expect to fail". + + Two places in tst_QWebPage::testOptionalJSObjects were marked as + expected to fail. The problem concern checking if a feature is enabled + or disabled. According to discussion on webkit dev mailing list + a disabled feature should be invisible from java script level, but + there are exceptions from the rule. So we decided to disable the test + for now. + + https://bugs.webkit.org/show_bug.cgi?id=29867 + + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::testOptionalJSObjects): + +2009-10-07 Adam Barth <abarth@webkit.org> + + Reviewed by Darin Adler. + + Factor PolicyChecker out of FrameLoader + https://bugs.webkit.org/show_bug.cgi?id=30155 + + Move the policy callback to the policy object. + + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::callPolicyFunction): + +2009-10-07 Antonio Gomes <tonikitoo@webkit.org> + + Reviewed by Simon Hausmann. + + [Qt] Get rid of useless loadFailed signal in QGraphicsWebView + https://bugs.webkit.org/show_bug.cgi?id=30166 + + * Api/qgraphicswebview.cpp: + (QGraphicsWebViewPrivate::_q_doLoadFinished): + * Api/qgraphicswebview.h: + * QGVLauncher/main.cpp: + (MainWindow::init): + (MainWindow::loadFinished): + +2009-10-07 Girish Ramakrishnan <girish@forwardbias.in> + + Reviewed by Simon Hausmann. + + Add a simple rotation effect to QGVLauncher + + https://bugs.webkit.org/show_bug.cgi?id=30162 + + * QGVLauncher/main.cpp: + (MainView::animatedFlip): + (MainWindow::animatedFlip): + (MainWindow::buildUI): + +2009-10-07 Volker Hilsheimer <volker.hilsheimer@nokia.com> + + Reviewed by Simon Hausmann. + + Doc: Document HTML and status as properties. + + * Api/qgraphicswebview.cpp: + +2009-10-07 Martin Smith <msmith@trolltech.com> + + Reviewed by Simon Hausmann. + + Fix qdoc warning about disabled renderHints property + on Symbian. + + * Api/qwebview.cpp: + * Api/qwebview.h: + +2009-10-06 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + Move setLocalLoadPolicy and friends to SecurityOrigin + https://bugs.webkit.org/show_bug.cgi?id=30110 + + Call the new API. + + * Api/qwebpage.cpp: + (QWebPagePrivate::QWebPagePrivate): + +2009-10-06 Benjamin C Meyer <bmeyer@rim.com> + + Reviewed by Ariya Hidayat. + + When the drag data contains an image set it on the QDrag so it will be visible to the user. + + * WebCoreSupport/DragClientQt.cpp: + (WebCore::DragClientQt::startDrag): + +2009-10-06 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Timothy Hatcher. + + Web Inspector: close inspector client view on + InspectorController::close API call. + + In order to run batch web inspector layout tests (and not affect + subsequent tests) we should close inspector client's view upon + InspectorController::close API call. + + https://bugs.webkit.org/show_bug.cgi?id=30009 + + * WebCoreSupport/InspectorClientQt.cpp: + (WebCore::InspectorClientQt::createPage): + +2009-10-06 Janne Koskinen <janne.p.koskinen@digia.com> + + Reviewed by Simon Hausmann. + + [Qt] don't enable input methods on Symbian by default. + https://bugs.webkit.org/show_bug.cgi?id=30117 + + If input methods are enabled Symbian FEP will be launched on every + pointer event making webpage navigation impossible with QWebView. + + * Api/qwebview.cpp: + (QWebView::QWebView): + +2009-10-05 Holger Hans Peter Freyther <zecke@selfish.org> + + Reviewed by Simon Hausmann. + + QtLauncher: print the number of loaded urls + + When using the -r mode print the number of URLs loaded so far. This + is extremly useful when opening the same URL over and over again and + one wants to see the progress. + + * QtLauncher/main.cpp: + (URLLoader::URLLoader): + (URLLoader::loadNext): + +2009-10-05 Girish Ramakrishnan <girish@forwardbias.in> + + Reviewed by Simon Hausmann. + + Add screenshot option to menubar + + https://bugs.webkit.org/show_bug.cgi?id=30067 + + * QtLauncher/main.cpp: + (MainWindow::screenshot): + (MainWindow::setupUI): + +2009-10-05 Girish Ramakrishnan <girish@forwardbias.in> + + Reviewed by Simon Hausmann. + + Setting the env QTLAUNCHER_USE_ARGB_VISUALS makes Qt use WA_TranslucentWindow. + + https://bugs.webkit.org/show_bug.cgi?id=30068 + + * QtLauncher/main.cpp: + (MainWindow::MainWindow): + +2009-10-05 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Rubberstamped by Simon Hausmann. + + Add documentation to the ErrorPageExtension. + + * Api/qwebpage.cpp: + +2009-10-02 Yael Aharon <yael.aharon@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Inform the application when a new request is created + https://bugs.webkit.org/show_bug.cgi?id=29975 + + Add a signal to QWebPage, to inform the application when a request is created. + + * Api/qwebpage.cpp: + * Api/qwebpage.h: + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::loadFinished): + +2009-10-05 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Simon Hausmann. + + ErrorPageExtension: Add a pointer to the QWebFrame that had + an error. + + * Api/qwebpage.h: + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::callErrorPageExtension): + +2009-10-05 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Tor Arne Vestbø. + + Do not empty the offline web appcache when clearing + memory caches. That one is not in memory, but stored + in sqlite. + + * Api/qwebsettings.cpp: + (QWebSettings::clearMemoryCaches): + +2009-10-05 J-P Nurmi <jpnurmi@gmail.com> + + Reviewed by Simon Hausmann. + + Added QGraphicsWidget-plugins support to FrameLoaderClientQt. + + https://bugs.webkit.org/show_bug.cgi?id=29710 + + * Api/qgraphicswebview.cpp: + (QGraphicsWebViewPrivate::pluginParent): + * Api/qwebview.cpp: + (QWebViewPrivate::pluginParent): + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::): + (WebCore::FrameLoaderClientQt::createPlugin): + +2009-10-03 Adam Barth <abarth@webkit.org> + + Unreview build fix. I wish I had a try server... + + * Api/qwebpage.cpp: + (QWebPagePrivate::updateAction): + +2009-10-02 Norbert Leser <norbert.leser@nokia.com> + + Reviewed by Simon Hausmann. + + Conditionally guard cursor code (cursor and updateCursor functions) with !QT_NO_CURSOR. + Otherwise, it is inconsistent with class declaration of QCursor. + + * Api/qgraphicswebview.cpp: + * Api/qwebview.cpp: + +2009-10-02 Prasanth Ullattil <prasanth.ullattil@nokia.com> + + Reviewed by Simon Hausmann. + + Fix compiler warnings about unused function arguments. + + * Api/qwebframe.cpp: + (QWebFrame::scrollBarMinimum): + * Api/qwebpage.cpp: + (QWebPagePrivate::focusInEvent): + (QWebPagePrivate::focusOutEvent): + (QWebPagePrivate::leaveEvent): + (QWebPage::javaScriptAlert): + (QWebPage::javaScriptConfirm): + (QWebPage::javaScriptPrompt): + (QWebPage::triggerAction): + (QWebPage::acceptNavigationRequest): + (QWebPage::chooseFile): + * WebCoreSupport/ChromeClientQt.cpp: + (WebCore::ChromeClientQt::repaint): + (WebCore::ChromeClientQt::mouseDidMoveOverElement): + (WebCore::ChromeClientQt::reachedMaxAppCacheSize): + * WebCoreSupport/ContextMenuClientQt.cpp: + (WebCore::ContextMenuClientQt::downloadURL): + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::dispatchWillPerformClientRedirect): + (WebCore::FrameLoaderClientQt::setMainFrameDocumentReady): + (WebCore::FrameLoaderClientQt::representationExistsForURLScheme): + (WebCore::FrameLoaderClientQt::generatedMIMETypeForURLScheme): + (WebCore::FrameLoaderClientQt::shouldGoToHistoryItem): + (WebCore::FrameLoaderClientQt::pluginWillHandleLoadError): + (WebCore::FrameLoaderClientQt::assignIdentifierToInitialRequest): + (WebCore::FrameLoaderClientQt::dispatchDidFinishLoading): + (WebCore::FrameLoaderClientQt::createJavaAppletWidget): + * WebCoreSupport/InspectorClientQt.cpp: + (WebCore::InspectorClientQt::setAttachedWindowHeight): + (WebCore::InspectorClientQt::highlight): + (WebCore::InspectorClientQt::removeSetting): + +2009-10-01 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Tor Arne Vestbø. + + Make Software Input Panel requests work with QGraphicsWebView + _and_ QWebView by sharing the event code in handleSoftwareInputPanel(). + + * Api/qwebpage.cpp: + (QWebPagePrivate::mouseReleaseEvent): + (QWebPagePrivate::handleSoftwareInputPanel): + * Api/qwebpage_p.h: + +2009-10-01 Alexis Menard <alexis.menard@nokia.com> + + Reviewed by Tor Arne Vestbø. + + Rename QWebGraphicsItem to QGraphicsWebView + + * Api/headers.pri: + * Api/qwebpage.h: + * Api/qwebgraphicsitem.cpp: Renamed. + * Api/qwebgraphicsitem.h: Renamed. + * WebKit/qt/QGVLauncher/main.cpp: + * tests/tests.pro: + * tests/qwebgraphicsitem/qwebgraphicsitem.pro: Renamed. + * tests/qwebgraphicsitem/tst_qwebgraphicsitem.cpp: Renamed. + +2009-10-01 Antonio Gomes <tonikitoo@webkit.org> + + Reviewed by Simon Hausmann. + + https://bugs.webkit.org/show_bug.cgi?id=29248 + [Qt] [API] Make it possible to have 'invisible' loads + + Make QWebFrame's setHtml and setContent methods to not change + session and global history at all. + + * Api/qwebframe.cpp: + (QWebFrame::setHtml): + (QWebFrame::setContent): + * tests/qwebframe/qwebframe.pro: + * tests/qwebframe/tst_qwebframe.cpp: + +2009-10-01 Kristian Amlie <kristian.amlie@nokia.com> + + Reviewed by Simon Hausmann. + + Fixed software input panel support on web input elements. + + Send the RequestSoftwareInputPanel event if the element supports focus + and the element is clicked. + + * Api/qwebpage.cpp: + (QWebPagePrivate::QWebPagePrivate): + (QWebPagePrivate::mousePressEvent): + (QWebPagePrivate::mouseReleaseEvent): + * Api/qwebpage_p.h: + +2009-10-01 Joe Ligman <joseph.ligman@nokia.com> + + Reviewed by Simon Hausmann. + + Implementation for QWebPage::inputMethodQuery and QWebPagePrivate::inputMethodEvent + + https://bugs.webkit.org/show_bug.cgi?id=29681 + + Some additional changes from Kristian Amlie <kristian.amlie@nokia.com>: + + * Fixed surrounding text to exclude preedit string + * Avoid emission of microFocusChanged during setComposition() + + * Api/qwebpage.cpp: + (QWebPagePrivate::inputMethodEvent): + (QWebPage::inputMethodQuery): + * WebCoreSupport/EditorClientQt.cpp: + (WebCore::EditorClientQt::respondToChangedSelection): + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::inputMethods): + +2009-09-30 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by David Hyatt. + + Add the failed URL to the ErrorPageExtension, as it is quite + useful for creating error pages. + + * Api/qwebpage.h: + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::callErrorPageExtension): + +2009-09-29 Andras Becsi <becsi.andras@stud.u-szeged.hu> + + Reviewed by Tor Arne Vestbø. + + [Qt] Default font size reconciliation to 16px/13px to match other platform's de-facto standard. + This fixes https://bugs.webkit.org/show_bug.cgi?id=19674. + + * Api/qwebsettings.cpp: + (QWebSettings::QWebSettings): + +2009-09-29 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Simon Hausmann. + + https://bugs.webkit.org/show_bug.cgi?id=29844 + + QWebPage dependency autotest fix. + + Fix for database() autotest. All opened databases should be removed at + end of test. + + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::database): + +2009-09-29 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Simon Hausmann. + + Some QWebHistory and QWebPage autotest crash fixes. + + Some checking for m_mainFrame were added. MainFrame should be created + at some point of QWebPage live cicle. + + https://bugs.webkit.org/show_bug.cgi?id=29803 + + * Api/qwebpage.cpp: + (QWebPage::~QWebPage): + (QWebPage::currentFrame): + (QWebPage::history): + (QWebPage::selectedText): + (QWebPage::updatePositionDependentActions): + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::crashTests_LazyInitializationOfMainFrame): + +2009-09-29 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Simon Hausmann and Tor Arne Vestbø. + + Implement QWebPage Extension for error pages, incl. + an example on how to use it in QtLauncher. + + Correct our use of ResourceError. + + * Api/qwebpage.h: + (ExtensionOption::): + (ExtensionOption::ErrorPageExtensionReturn::ErrorPageExtensionReturn): + * QtLauncher/main.cpp: + (WebPage::supportsExtension): + (MainWindow::MainWindow): + (MainWindow::selectElements): + (WebPage::extension): + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::cancelledError): + (WebCore::FrameLoaderClientQt::blockedError): + (WebCore::FrameLoaderClientQt::cannotShowURLError): + (WebCore::FrameLoaderClientQt::interruptForPolicyChangeError): + (WebCore::FrameLoaderClientQt::cannotShowMIMETypeError): + (WebCore::FrameLoaderClientQt::fileDoesNotExistError): + (WebCore::FrameLoaderClientQt::callErrorPageExtension): + (WebCore::FrameLoaderClientQt::dispatchDidFailProvisionalLoad): + (WebCore::FrameLoaderClientQt::dispatchDidFailLoad): + * WebCoreSupport/FrameLoaderClientQt.h: + +2009-09-28 Andre Poenitz <andre.poenitz@trolltech.com> + + Reviewed by Simon Hausmann. + + Compile fix with namespaced Qt. + + * Api/qwebinspector_p.h: + +2009-09-27 Joe Ligman <joseph.ligman@mindspring.com> + + Reviewed by Simon Hausmann. + + [Qt] Adding API setFocus and hasFocus to QWebElement. This API is needed for + clients that want to check/set the focus node of the document. + https://bugs.webkit.org/show_bug.cgi?id=29682 + + * Api/qwebelement.cpp: + (QWebElement::hasFocus): + (QWebElement::setFocus): + * Api/qwebelement.h: + * tests/qwebelement/tst_qwebelement.cpp: + (tst_QWebElement::hasSetFocus): + +2009-09-25 Csaba Osztrogonac <oszi@inf.u-szeged.hu> + + Reviewed by Simon Hausmann. + + [Qt] Make tst_qwebframe work if Qt built without SSL support + https://bugs.webkit.org/show_bug.cgi?id=29735 + + * tests/qwebframe/tst_qwebframe.cpp: Missing #ifndef blocks added. + +2009-09-24 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Update QWebElement API to remove script related methods. + QWebElement::evaluateScript is the only one kept, these are + removed to postpone most of the QtWebKit<->JavaScript API design + after 4.6. + https://bugs.webkit.org/show_bug.cgi?id=29708 + + * Api/qwebelement.cpp: + * Api/qwebelement.h: + Methods removed: + - QWebElement::callFunction + - QWebElement::functions + - QWebElement::scriptableProperty + - QWebElement::setScriptableProperty + - QWebElement::scriptableProperties + * tests/qwebelement/tst_qwebelement.cpp: + (tst_QWebElement::evaluateScript): + +2009-09-25 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Rename QWebElement::evaluateScript + to QWebElement::evaluateJavaScript. + https://bugs.webkit.org/show_bug.cgi?id=29709 + + * Api/qwebelement.cpp: + (QWebElement::evaluateJavaScript): + * Api/qwebelement.h: + * tests/qwebelement/tst_qwebelement.cpp: + (tst_QWebElement::evaluateJavaScript): + +2009-09-25 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Update the stypeProperty API of QWebElement. + https://bugs.webkit.org/show_bug.cgi?id=29711 + + * Api/qwebelement.cpp: + (QWebElement::styleProperty): + - Merge the stypeProperty and the computedStyleProperty methods + - Remove the default value for the style resolving enum + - Rename ResolveRule to StyleResolveStrategy + (QWebElement::setStyleProperty): + - Remove the priority argument since it is possible to control the + behaviour by adding !important or removing in the value. + * Api/qwebelement.h: + * tests/qwebelement/tst_qwebelement.cpp: + (tst_QWebElement::style): + (tst_QWebElement::computedStyle): + * tests/qwebframe/tst_qwebframe.cpp: + +2009-09-24 Jon Honeycutt <jhoneycutt@apple.com> + + Reviewed by Alice Liu. + + * Api/qwebpage.cpp: + (QWebPagePrivate::QWebPagePrivate): + Pass 0 for new Page constructor argument. + +2009-09-24 Martin Smith <msmith@trolltech.com> + + Reviewed by Simon Hausmann. + + qdoc: Added \brief texts to all the since 4.6 functions. + + * Api/qwebhistory.cpp: + +2009-09-23 J-P Nurmi <jpnurmi@gmail.com> + + Reviewed by Simon Hausmann. + + Prevent QWebPage::setView() from changing the viewport size on the fly + in case the view doesn't actually change. QWebPage::setView() is + called upon every QWebGraphicsItem::hoverMoveEvent(), which forced + the viewport size to be equal to the size of the whole graphics view. + + https://bugs.webkit.org/show_bug.cgi?id=29676 + + * Api/qwebpage.cpp: + (QWebPage::setView): + +2009-09-23 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Crash fix in QWebHistory back and forward methods. + + QWebHistory::back() and QWebHistory::forward() were crashing on + ASSERT in WebCore::BackForwardList. The methods should check + canGoBack() and canGoForward() at the beginning. + + https://bugs.webkit.org/show_bug.cgi?id=29675 + + * Api/qwebhistory.cpp: + (QWebHistory::back): + (QWebHistory::forward): + +2009-09-23 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Bug fix. QWebHistory should call QWebPage::updateNavigationActions + + In QWebHistory's methods that change item count or current item call + to QWebPage::updateNavigationActions should be executed. + QWebHistory::clear() and QWebHistory::restorState() were changed. + New helper method, QWebPagePrivate accesor, were created in + QWebHistoryPrivate class. + Two autotest were developed. + + https://bugs.webkit.org/show_bug.cgi?id=29246 + + * Api/qwebhistory.cpp: + (QWebHistory::clear): + (QWebHistory::restoreState): + (QWebHistoryPrivate::page): + * Api/qwebhistory_p.h: + * tests/qwebhistory/tst_qwebhistory.cpp: + (tst_QWebHistory::saveAndRestore_1): + (tst_QWebHistory::clear): + +2009-09-23 Norbert Leser <norbert.leser@nokia.com> + + Reviewed by Tor Arne Vestbø. + + Need to guard QX11Info include with Q_WS_X11. + That class may not be available (in QT 4.5 for Symbian, for instance). + Completes fixes in r48627 and r48604. + + * Api/qwebgraphicsitem.cpp: + * Api/qwebview.cpp: + +2009-09-22 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Add default timeout while waiting for signals in QWebPage auto + tests. + https://bugs.webkit.org/show_bug.cgi?id=29637 + + * tests/qwebpage/tst_qwebpage.cpp: + (waitForSignal): + +2009-09-22 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Reivewed by Simon Hausmann. + + Fix the Qt/Mac build after r48604 (Implement new QWebPageClient class) + + There's no QWidget::x11Info() on Mac, and setPlatformPluginWidget() + takes a QWidget*, not a QWebPageClient* + + * Api/qwebgraphicsitem.cpp: + (QWebGraphicsItemPrivate::screenNumber): + * Api/qwebview.cpp: + (QWebViewPrivate::screenNumber): + +2009-09-21 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Simon Hausmann. + + For Qt, platformPageClient() will now return a class derived from + the QWebPageClient, so the patch adapts our Qt hooks to go though + this class and not depend on the QWebView. + + * Api/qwebgraphicsitem.cpp: + (QWebGraphicsItemPrivate::scroll): + (QWebGraphicsItemPrivate::update): + (QWebGraphicsItemPrivate::cursor): + (QWebGraphicsItemPrivate::updateCursor): + (QWebGraphicsItemPrivate::screenNumber): + (QWebGraphicsItemPrivate::winId): + (QWebGraphicsItem::event): + (QWebGraphicsItem::setPage): + * Api/qwebgraphicsitem.h: + * Api/qwebpage.cpp: + (QWebPagePrivate::QWebPagePrivate): + * Api/qwebpage_p.h: + * Api/qwebview.cpp: + (QWebViewPrivate::scroll): + (QWebViewPrivate::update): + (QWebViewPrivate::cursor): + (QWebViewPrivate::updateCursor): + (QWebViewPrivate::screenNumber): + (QWebViewPrivate::winId): + (QWebView::setPage): + (QWebView::event): + * WebCoreSupport/ChromeClientQt.cpp: + (WebCore::ChromeClientQt::repaint): + (WebCore::ChromeClientQt::scroll): + (WebCore::ChromeClientQt::platformPageClient): + +2009-09-21 Yael Aharon <yael.aharon@nokia.com> + + Reviewed by Simon Hausmann. + + https://bugs.webkit.org/show_bug.cgi?id=29609 + Build fix for windows when using Qt 4.5.0. + + * Api/qwebpage.cpp: + (QWebPage::userAgentForUrl): + +2009-09-19 Benjamin Poulain <benjamin.poulain@nokia.com> + + Reviewed by Simon Hausmann. + + https://bugs.webkit.org/show_bug.cgi?id=29345 + The tests of QWebFrame did not use QTRY_VERIFY for + tests involving the event loop. + + * tests/qwebframe/tst_qwebframe.cpp: + * tests/util.h: Added. Copy of tests/shared/util.h of Qt + +2009-09-19 Jakub Wieczorek <faw217@gmail.com> + + Reviewed by Simon Hausmann. + + [Qt] Add an autotest stub for QWebGraphicsItem. + + It just calls all the functions and makes sure they don't crash. + + * tests/qwebgraphicsitem/qwebgraphicsitem.pro: Added. + * tests/qwebgraphicsitem/tst_qwebgraphicsitem.cpp: Added. + (tst_QWebGraphicsItem::qwebgraphicsitem): + * tests/tests.pro: + +2009-09-18 Norbert Leser <norbert.leser@nokia.com> + + Reviewed by Eric Seidel. + + Corrected the Symbian specific UID3 values to be assigned + from the "unprotected" pool that permits self-signing of + those test and demo executables. (Added new UID3 values + where they were missing for new components.) + + * QGVLauncher/QGVLauncher.pro: + * QtLauncher/QtLauncher.pro: + * tests/benchmarks/loading/tst_loading.pro: + * tests/benchmarks/painting/tst_painting.pro: + * tests/qwebelement/qwebelement.pro: + * tests/qwebframe/qwebframe.pro: + * tests/qwebhistory/qwebhistory.pro: + * tests/qwebhistoryinterface/qwebhistoryinterface.pro: + * tests/qwebpage/qwebpage.pro: + * tests/qwebplugindatabase/qwebplugindatabase.pro: + * tests/qwebview/qwebview.pro: + +2009-09-17 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Simon Hausmann. + + Make PlatformWindow return something else than PlatformWidget + https://bugs.webkit.org/show_bug.cgi?id=29085 + + Reflect the rename of platformWindow and it's return type. + + * WebCoreSupport/ChromeClientQt.cpp: + (WebCore::ChromeClientQt::platformPageClient): + * WebCoreSupport/ChromeClientQt.h: + +2009-09-18 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Add persistence support for configuration options in the + inspector. + + * Api/qwebinspector.cpp: + * QtLauncher/main.cpp: + (main): + * WebCoreSupport/InspectorClientQt.cpp: + (WebCore::InspectorClientQt::populateSetting): + (WebCore::InspectorClientQt::storeSetting): + (WebCore::variantToSetting): + (WebCore::settingToVariant): + +2009-09-18 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Ariya Hidayat. + + Fixed a bunch of documentation warnings. + + * Api/qwebgraphicsitem.cpp: + * Api/qwebplugindatabase.cpp: + * Api/qwebpluginfactory.cpp: + * Api/qwebsecurityorigin.cpp: + +2009-09-18 Warwick Allison <warwick.allison@nokia.com> + + Reviewed by Simon Hausmann. + + Added a test that console output works. + + * tests/qwebpage/tst_qwebpage.cpp: + (ConsolePage::ConsolePage): + (ConsolePage::javaScriptConsoleMessage): + (tst_QWebPage::consoleOutput): + +2009-09-17 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Simon Hausmann. + + Improve documentation for Page Cache. + + * Api/qwebsettings.cpp: + +2009-09-17 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Update QWebSettings::setUserStyleSheetUrl() docs and test + + https://bugs.webkit.org/show_bug.cgi?id=29081 + + The documentation now specifies that the URL has to be a local file + or a a data-URL (with utf-8 and base64-encoded data), as these are the + only two schemes that the current code path accepts. + + The auto-test has been updated to reflect this limitation. + + At a later point we should concider adding API for the new way of + doing both user defined stylesheets and scripts. + + * Api/qwebsettings.cpp: + * tests/qwebpage/tst_qwebpage.cpp: + +2009-09-17 Janne Koskinen <janne.p.koskinen@digia.com> + + Reviewed by Simon Hausmann. + + Symbian build fix. + + Moved the #ifdefs around _q_cleanupLeakMessages() into the function + definition. + + QMake is not being able to distinguish between release and debug builds + in Symbian build. This is a Symbian toolchain issue. + + * Api/qwebpage.cpp: + (QWebPagePrivate::_q_cleanupLeakMessages): + * Api/qwebpage.h: + * Api/qwebpage_p.h: + +2009-09-17 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Simon Hausmann. + + Small cosmetic documentation fixlet in the QWebInspector. + + * Api/qwebinspector.cpp: + +2009-09-16 Benjamin C Meyer <benjamin.meyer@torchmobile.com> + + Reviewed by Eric Seidel. + + Detect and add Windows7 properly to the user agent. + + * Api/qwebpage.cpp: + (QWebPage::userAgentForUrl): + +2009-09-16 Andras Becsi <andrewbecsi@yahoo.co.uk> + + Rubberstamped by Kenneth Christiansen. + + [Qt] Build fix for previous changes. + + * QGVLauncher/main.cpp: + (MainView::flip): + +2009-09-16 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Unreviewed potential Qt < 4.6 build fix. + + * QGVLauncher/main.cpp: + (MainView::flip): + +2009-09-16 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Simon Hausmann. + + Add a "Flip effect" to our GraphicsView based launcher. + + * QGVLauncher/main.cpp: + (MainView::resizeEvent): + (MainView::flip): + (MainWindow::flip): + (MainWindow::buildUI): + +2009-09-16 Zoltan Herczeg <zherczeg@inf.u-szeged.hu> + + Rubber-stamped by Simon Hausmann. + + [Qt] Typo fix. Pass the window object to the Format + menu. In this way Qt can free its internal graphical + objects during exit. + + * QtLauncher/main.cpp: + (MainWindow::setupUI): + +2009-09-16 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Tor Arne Vestbø. + + [Qt] Build break fix on gcc ARM. + + * Api/qwebgraphicsitem.cpp: + (QWebGraphicsItemPrivate::_q_doLoadProgress): + +2009-09-16 Warwick Allison <warwick.allison@nokia.com> + + Reviewed by Simon Hausmann. + + Fix a crash in QWebFrame::hasFocus() with a simple null pointer check + when the focused frame is null. We do the same check in other places + where we call kit(). + + * Api/qwebframe.cpp: + (QWebFrame::hasFocus): + +2009-09-16 Jure Repinc <jlp@holodeck1.com> + + Reviewed by Simon Hausmann. + + Fixed a typo found during translation. + + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::interruptForPolicyChangeError): + +2009-09-14 Jakub Wieczorek <faw217@gmail.com> + + Reviewed by Simon Hausmann. + + [Qt] QWebGraphicsItem should check for null QWebPage. + https://bugs.webkit.org/show_bug.cgi?id=29185 + + Don't crash in QWebGraphicsItem when the page is still null, by + either checking if it's the case or constructing the default one. + + * Api/qwebgraphicsitem.cpp: + (QWebGraphicsItem::icon): + (QWebGraphicsItem::setZoomFactor): + (QWebGraphicsItem::zoomFactor): + (QWebGraphicsItem::setGeometry): + (QWebGraphicsItem::load): + (QWebGraphicsItem::setHtml): + (QWebGraphicsItem::toHtml): + (QWebGraphicsItem::setContent): + (QWebGraphicsItem::history): + (QWebGraphicsItem::settings): + +2009-09-11 David Boddie <dboddie@trolltech.com> + + Reviewed by Simon Hausmann. + + Doc: Note that Netscape plugins are only available on desktop platforms. + + * docs/qtwebkit.qdoc: + +2009-09-11 Martin Smith <msmith@trolltech.com> + + Reviewed by Simon Hausmann. + + Adjust the name of the contentspage for the documentation + to the new name used in Qt 4.6. + + * docs/qtwebkit.qdoc: + +2009-09-11 Ariya Hidayat <ariya.hidayat@nokia.com> + + Reviewed by Simon Hausmann. + + Changed URLs from qtsoftware.com to qt.nokia.com, as part of a general + renaming. + + * Api/qwebpluginfactory.cpp: + * docs/webkitsnippets/simple/main.cpp: + (main): + * docs/webkitsnippets/webpage/main.cpp: + (main): + +2009-09-11 Volker Hilsheimer <volker.hilsheimer@nokia.com> + + Reviewed by Simon Hausmann. + + Restructure the documentation, both on a file and on a content level. + + * Api/qwebdatabase.cpp: + * Api/qwebelement.cpp: + * Api/qwebframe.cpp: + * Api/qwebhistory.cpp: + * Api/qwebhistoryinterface.cpp: + * Api/qwebpage.cpp: + * Api/qwebpluginfactory.cpp: + * Api/qwebsecurityorigin.cpp: + * Api/qwebsettings.cpp: + * Api/qwebview.cpp: + * docs/qtwebkit.qdoc: + +2009-09-11 Yongjun Zhang <yongjun.zhang@nokia.com> + + Reviewed by Simon Hausmann. + + https://bugs.webkit.org/show_bug.cgi?id=29136 + [Qt] emit microFocusChanged() signal when no QWidget-based view is present. + + emit microFocusChange() signal regardless of view. + + * WebCoreSupport/EditorClientQt.cpp: + (WebCore::EditorClientQt::setInputMethodState): + +2009-09-11 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Simon Hausmann. + + https://bugs.webkit.org/show_bug.cgi?id=28806 + + [Qt] Make the WebInspector available as a QWidget. + + * Api/headers.pri: + * Api/qwebelement.cpp: + (QWebElement::enclosingElement): + * Api/qwebelement.h: + * Api/qwebinspector.cpp: Added. + * Api/qwebinspector.h: Added. + * Api/qwebinspector_p.h: Added. + * Api/qwebpage.cpp: + (QWebPagePrivate::QWebPagePrivate): + (QWebPagePrivate::setInspector): + (QWebPagePrivate::getOrCreateInspector): + (QWebPagePrivate::inspectorController): + (QWebPage::~QWebPage): + (QWebPage::triggerAction): + * Api/qwebpage.h: + * Api/qwebpage_p.h: + * Api/qwebsettings.cpp: + * QtLauncher/main.cpp: + (MainWindow::MainWindow): + * WebCoreSupport/InspectorClientQt.cpp: + (WebCore::InspectorClientWebPage::InspectorClientWebPage): + (WebCore::InspectorClientWebPage::createWindow): + (WebCore::InspectorClientQt::createPage): + (WebCore::InspectorClientQt::showWindow): + (WebCore::InspectorClientQt::closeWindow): + (WebCore::InspectorClientQt::attachWindow): + (WebCore::InspectorClientQt::detachWindow): + (WebCore::InspectorClientQt::updateWindowTitle): + * WebCoreSupport/InspectorClientQt.h: + * docs/webkitsnippets/qtwebkit_qwebinspector_snippet.cpp: Added. + +2009-09-10 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Eric Seidel. + + [Qt] Fix comparison between signed and unsigned integer warnings + https://bugs.webkit.org/show_bug.cgi?id=29162 + + No functional change. + + * Api/qwebelement.cpp: + (QWebElement::findAll): + * Api/qwebhistory.cpp: + (QWebHistory::items): + (QWebHistory::backItems): + (QWebHistory::forwardItems): + (QWebHistory::saveState): + * Api/qwebplugindatabase.cpp: + (QWebPluginDatabase::setSearchPaths): + * WebCoreSupport/ChromeClientQt.cpp: + (WebCore::ChromeClientQt::runOpenPanel): + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::createPlugin): + +2009-09-10 Simon Hausmann <hausmann@webkit.org> + + Rubber-stamped by Ariya Hidayat. + + Fix a bunch of qdoc warnings: Invalid references, non-standard + wording, etc. + + * Api/qwebelement.cpp: + * Api/qwebgraphicsitem.cpp: + * Api/qwebsecurityorigin.cpp: + +2009-09-10 Simon Hausmann <hausmann@webkit.org> + + Reviewed by Ariya Hidayat. + + Fix context menu event delivery with QWebGraphicsItem. + + Re-implement the correct context menu virtual function using + a QGraphicsSceneContextMenuEvent and forward & handle it in + QWebPage. + + * Api/qwebgraphicsitem.cpp: + (QWebGraphicsItem::contextMenuEvent): + * Api/qwebgraphicsitem.h: + * Api/qwebpage.cpp: + (QWebPagePrivate::contextMenuEvent): + (QWebPage::event): + * Api/qwebpage_p.h: + +2009-09-10 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Unreviewed. + + Build fix for QtWebKit for Mac after r48219. + + qevent and qstyleoption are QtGui interfaces. + + * Api/qwebgraphicsitem.cpp: + * Api/qwebgraphicsitem.h: + +2009-09-09 Simon Hausmann <hausmann@webkit.org> + + Reviewed by Tor Arne Vestbø. + + Call the right base class function QGraphicsWidget::event() instead + of skipping it and using QObject::event() instead. + + * Api/qwebgraphicsitem.cpp: + (QWebGraphicsItem::event): + +2009-09-09 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Unreviewed. + + Fix comment at Tor Arne Vestbø's request. + + * Api/qwebgraphicsitem.cpp: + (QWebGraphicsItem::sceneEvent): + (QWebGraphicsItem::event): + +2009-09-09 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Tor Arne Vestbø. + + Implement some virtual event methods so that we can fix + event-related bugs in Qt patch releases. + + * Api/qwebgraphicsitem.cpp: + (QWebGraphicsItem::sceneEvent): + (QWebGraphicsItem::event): + * Api/qwebgraphicsitem.h: + +2009-09-09 Kenneth Rohde Christiansen <kenneth@webkit.org>, Antonio Gomes <antonio.gomes@openbossa.org> + + Reviewed by Simon Hausmann. + + Add a new QGraphicsWidget based version of the "QWebView" + under the name "QWebGraphicsItem". + + https://bugs.webkit.org/show_bug.cgi?id=28862 + + Includes an alternative Qt launcher using the QGraphicsView. + + * Api/headers.pri: + * Api/qwebgraphicsitem.cpp: Added. + * Api/qwebgraphicsitem.h: Added. + * Api/qwebpage.h: + * QGVLauncher/QGVLauncher.pro: Copied from WebKit/qt/QtLauncher/QtLauncher.pro. + * QGVLauncher/main.cpp: Added. + * WebCoreSupport/ChromeClientQt.cpp: + (WebCore::ChromeClientQt::repaint): + (WebCore::ChromeClientQt::scroll): + +2009-09-08 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Unreviewed build fix. + + Potential build fix for Qt 4.5 + + * Api/qwebpage.cpp: + (QWebPagePrivate::mousePressEvent): + +2009-09-08 Benjamin Poulain <benjamin.poulain@nokia.com> + + Reviewed by Simon Hausmann. + + https://bugs.webkit.org/show_bug.cgi?id=29007 + Add a test for the signal QWebFrame::javaScriptWindowObjectCleared() + + * tests/qwebframe/tst_qwebframe.cpp: + +2009-09-08 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Fix unused variable warnings + https://bugs.webkit.org/show_bug.cgi?id=29018 + + * Api/qwebpage.cpp: + (QWebPagePrivate::keyPressEvent): + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::startDownload): + (WebCore::FrameLoaderClientQt::createFrame): + +2009-09-08 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Ariya Hidayat. + + [Qt] Use the declaration order in initializer lists + https://bugs.webkit.org/show_bug.cgi?id=29017 + + * Api/qwebframe_p.h: + +2009-09-08 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Simon Hausmann. + + Add support for handling QGraphicsScene events. + + * Api/qwebpage.cpp: + (QWebPagePrivate::mouseMoveEvent): + (QWebPagePrivate::mousePressEvent): + (QWebPagePrivate::mouseDoubleClickEvent): + (QWebPagePrivate::mouseTripleClickEvent): + (QWebPagePrivate::handleClipboard): + (QWebPagePrivate::mouseReleaseEvent): + (QWebPagePrivate::wheelEvent): + (QWebPagePrivate::dragEnterEvent): + (QWebPagePrivate::dragLeaveEvent): + (QWebPagePrivate::dragMoveEvent): + (QWebPagePrivate::dropEvent): + (QWebPage::event): + * Api/qwebpage_p.h: + +2009-09-08 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Simon Hausmann. + + [Qt] Make cursor set cleaner in QtWebKit Api: eliminate SetCursorEvent hack. + https://bugs.webkit.org/show_bug.cgi?id=28865 + + Clean up the unserCursor hack to use the QCursor set + as a property of the QWidget by WebCore::WidgetQt. + + Remove all code that are no longer necessary for getting + cursor change events. + + Patch by Kenneth Rohde Christiansen <kenneth@webkit.org> and + Antonio Gomes <antonio.gomes@openbossa.org> on 2009-09-07 + + * Api/qwebpage.cpp: + * Api/qwebpage_p.h: + * Api/qwebview.cpp: + (QWebViewPrivate::QWebViewPrivate): + (QWebView::event): + +2009-09-08 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] QtWebKit single API to enable persistency + https://bugs.webkit.org/show_bug.cgi?id=28682 + + Disable LocalStorage, ApplicationCache, HTML5 offline storage by + default. + + If persistency is enabled the default directory for LocalStorage and + ApplicationCache is now based on QDesktopServices::DataLocation and not + QDesktopServices::CacheLocation (as it is expected to keep this data + around after a reboot). + + If persistency is enabled initialize HTML5 offline storage as well - this + fixed offline Storage for QtLauncher. + + * Api/qwebpage.cpp: + (QWebPagePrivate::QWebPagePrivate): + * Api/qwebsettings.cpp: + (QWebSettings::QWebSettings): + (QWebSettings::enablePersistentStorage): + * Api/qwebsettings.h: Add a new API called enablePersistentStorage + * QtLauncher/main.cpp: Use the new enablePersistentStorage API + (main): + +2009-09-07 Jakub Wieczorek <faw217@gmail.com> + + Reviewed by Simon Hausmann. + + Speed up the QWebPluginInfo::supportsMimeType() function. + https://bugs.webkit.org/show_bug.cgi?id=27651 + + Instead of going through the MIME types list constructed with + mimeTypes() function, look up the internal mimeToDescriptions map. + + * Api/qwebplugindatabase.cpp: + (QWebPluginInfo::supportsMimeType): + +2009-09-07 Jakub Wieczorek <faw217@gmail.com> + + Reviewed by Simon Hausmann. + + Speed up the QWebPluginInfo::mimeTypes() function. + https://bugs.webkit.org/show_bug.cgi?id=27651 + + Instead of constructing a list of MIME types every time it is called, + do this only once. + + * Api/qwebplugindatabase.cpp: + (QWebPluginInfo::mimeTypes): + (QWebPluginInfo::operator=): + * Api/qwebplugindatabase.h: + * tests/qwebplugindatabase/tst_qwebplugindatabase.cpp: + (tst_QWebPluginDatabase::operatorassign_data): + (tst_QWebPluginDatabase::operatorassign): + +2009-09-07 Jakub Wieczorek <faw217@gmail.com> + + Reviewed by Simon Hausmann. + + Remove the private classes from QWebPluginDatabase. + https://bugs.webkit.org/show_bug.cgi?id=27651 + + Instead, hold the PluginDatabase and PluginPackage objects as class + members and take care of refcounting on our own instead of using RefPtr. + + This way we not only made the code cleaner but also got rid of + redundant allocations when constructing null QWebPluginInfo objects. + + The private classes have been forward-declared and the d-pointers left + to be on the safe side. + + * Api/qwebplugindatabase.cpp: + (QWebPluginInfo::QWebPluginInfo): + (QWebPluginInfo::~QWebPluginInfo): + (QWebPluginInfo::name): + (QWebPluginInfo::description): + (QWebPluginInfo::mimeTypes): + (QWebPluginInfo::path): + (QWebPluginInfo::isNull): + (QWebPluginInfo::setEnabled): + (QWebPluginInfo::isEnabled): + (QWebPluginInfo::operator==): + (QWebPluginInfo::operator!=): + (QWebPluginInfo::operator=): + (QWebPluginDatabase::QWebPluginDatabase): + (QWebPluginDatabase::~QWebPluginDatabase): + (QWebPluginDatabase::plugins): + (QWebPluginDatabase::searchPaths): + (QWebPluginDatabase::setSearchPaths): + (QWebPluginDatabase::addSearchPath): + (QWebPluginDatabase::refresh): + (QWebPluginDatabase::pluginForMimeType): + (QWebPluginDatabase::setPreferredPluginForMimeType): + * Api/qwebplugindatabase.h: + * Api/qwebplugindatabase_p.h: Removed. + +2009-09-05 Jakub Wieczorek <faw217@gmail.com> + + Reviewed by Eric Seidel. + + [Qt] r47424 broke binary compatibility + https://bugs.webkit.org/show_bug.cgi?id=28996 + + Append the new DnsPrefetchEnabled attribute at the end of the enum. + + * Api/qwebsettings.h: + +2009-09-04 Mark Mentovai <mark@chromium.org> + + Reviewed by Dave Hyatt. + + https://bugs.webkit.org/show_bug.cgi?id=28614 + + Account for scrollbar state changes that occur during layout. + + * Api/qwebframe.cpp: + (QWebFrame::setScrollBarPolicy): + + Eliminate duplicated (and incorrect) scrollbar mode tracking between + FrameView and ScrollView. + +2009-09-04 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Eric Seidel. + + [Qt] Fix tst_QWebPage::database autotest failure + https://bugs.webkit.org/show_bug.cgi?id=28961 + + Make sure that the test case enables the feature before + the feature gets tested + + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::database): + +2009-09-04 Benjamin C Meyer <benjamin.meyer@torchmobile.com> + + Reviewed by Eric Seidel. + + Any QtWebKit application crashes on exit if the inspector is + used during the session rather then exiting. + + If a QWebView has a QWebPage that is destroyed the QWebView + does not update its pointer and will crash the next time + it access the page pointers (such as in its destructor). + + InspectorClientView should not call deleteLater when the page + is destroyed because it does not have a parent and is a top + level widget. close() needs to be called so that QApplication + can exit the application if quitOnLastWindowClosed is set + and a InspectorClientView is the last window, otherwise + the application will never exit. + + * Api/qwebview.cpp: + (QWebViewPrivate::_q_pageDestroyed): + (QWebView::setPage): + * Api/qwebview.h: + * WebCoreSupport/InspectorClientQt.cpp: + (WebCore::InspectorClientView::InspectorClientView): + +2009-09-03 Adam Barth <abarth@webkit.org> + + Reviewed by eric@webkit.org. + + https://bugs.webkit.org/show_bug.cgi?id=24696 + + Stub implementations of mixed content methods of FrameLoaderClient. + + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::didDisplayInsecureContent): + (WebCore::FrameLoaderClientQt::didRunInsecureContent): + * WebCoreSupport/FrameLoaderClientQt.h: + +2009-09-03 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Eric Seidel. + + [Qt] Add a setting to turn SessionStorage on/off + https://bugs.webkit.org/show_bug.cgi?id=28836 + + * Api/qwebsettings.cpp: + (QWebSettingsPrivate::apply): + (QWebSettings::QWebSettings): + * Api/qwebsettings.h: + * tests/qwebpage/tst_qwebpage.cpp: + (testFlag): + (tst_QWebPage::testOptionalJSObjects): + +2009-09-02 Richard Moore <rich@kde.org> + + Reviewed by Tor Arne Vestbø. + + [Qt] Make sure we relayout the page after evaluating JS + + https://bugs.webkit.org/show_bug.cgi?id=28235 + + QtWebKit does not always seem to reflow the page when evaluating + javascript. This patch changes the way evaluateJavaScript works to + use the frameloader which ensures that this is done properly. + + * Api/qwebframe.cpp: + (QWebFrame::evaluateJavaScript): + * tests/qwebframe/tst_qwebframe.cpp: + +2009-08-28 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk> + + Reviewed by Holger Freyther. + + https://bugs.webkit.org/show_bug.cgi?id=25889 + [GTK] scrollbar policy for main frame is not implementable + + Add empty implementation for new ChromeClient method. + + * WebCoreSupport/ChromeClientQt.h: + (WebCore::ChromeClientQt::scrollbarsModeDidChange): + +2009-08-27 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Ariya Hidayat. + + QWebHistory::clear() modifications. + + Clear() method was changed. If QWebHistory is empty (there is no + elements even current) clear() do nothing. If there at least one + element clear() will delete everything apart of current. + + New autotests in QWebHistory + + New autotests were added to QWebHistory. They should check some crashes + in save and restore state process and clear() method and general + behavior on where QWebHistory::count() == 0 or QWebHistory::count() == 1 + + Bugzilla: https://bugs.webkit.org/show_bug.cgi?id=28711 + + * Api/qwebhistory.cpp: + (QWebHistory::clear): + * tests/qwebhistory/tst_qwebhistory.cpp: + (tst_QWebHistory::back): + (tst_QWebHistory::forward): + (tst_QWebHistory::saveAndRestore_crash_1): + (tst_QWebHistory::saveAndRestore_crash_2): + (tst_QWebHistory::saveAndRestore_crash_3): + (tst_QWebHistory::clear): + +2009-08-27 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Ariya Hidayat. + + [Qt] Cleanup, old and commented part of source code was removed. + Fix some formatting problems. + + https://bugs.webkit.org/show_bug.cgi?id=28712 + + * Api/qwebhistory_p.h: + (QWebHistoryPrivate::QWebHistoryPrivate): + +2009-08-26 Adam Barth <abarth@webkit.org> + + Reviewed by Oliver Hunt. + + Don't let local files access web URLs + https://bugs.webkit.org/show_bug.cgi?id=28480 + + * Api/qwebsettings.cpp: + (QWebSettings::QWebSettings): + +2009-08-25 Antonio Gomes <antonio.gomes@openbossa.org> + + Reviewed by Ariya Hidayat. + + Bug 28708 - Make possible to better use ResourceError in FrameLoaderClientQt class. + + * Api/qwebframe.cpp: + (QWebFrame::requestedUrl): + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::FrameLoaderClientQt): + (WebCore::FrameLoaderClientQt::dispatchDidFinishLoad): + (WebCore::FrameLoaderClientQt::postProgressFinishedNotification): + (WebCore::FrameLoaderClientQt::dispatchDidFailProvisionalLoad): + (WebCore::FrameLoaderClientQt::dispatchDidFailLoad): + * WebCoreSupport/FrameLoaderClientQt.h: + +2009-08-22 Adam Barth <abarth@webkit.org> + + Revert 47684. We're going to do this later once clients have had a + chance to opt into the setting they like. + + * Api/qwebsettings.cpp: + (QWebSettings::QWebSettings): + +2009-08-22 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + Don't let local files access web URLs + https://bugs.webkit.org/show_bug.cgi?id=28480 + + * Api/qwebsettings.cpp: + (QWebSettings::QWebSettings): + +2009-08-19 Aaron Boodman <aa@chromium.org> + + Speculative build break fix for qt. + + * Api/qwebsecurityorigin.cpp: + (QWebSecurityOrigin::whiteListAccessFromOrigin): + * Api/qwebsecurityorigin.h: + +2009-08-19 Aaron Boodman <aa@chromium.org> + + Reviewed by David Levin. + + https://bugs.webkit.org/show_bug.cgi?id=24853: Provide a way for WebKit clients to + specify a more granular policy for cross-origin XHR access. + + * Api/qwebsecurityorigin.cpp: Add API to manipulate origin access whitelists. + (QWebSecurityOrigin::whiteListAccessFromOrigin): Ditto. + (QWebSecurityOrigin::resetOriginAccessWhiteLists): Ditto. + * Api/qwebsecurityorigin.h: Ditto. + +2009-08-18 Markus Goetz <Markus.Goetz@nokia.com> + + Reviwed by Ariya Hidayat. + + [Qt] For prefecthDNS, the pre-fetching has to be enabled in the + WebSettings. + + * Api/qwebsettings.cpp: + (QWebSettings::QWebSettings): + * Api/qwebsettings.h: + +2009-08-17 Darin Adler <darin@apple.com> + + Try to fix Qt build again. + + * WebCoreSupport/EditorClientQt.cpp: Move "using namespace". + +2009-08-17 Darin Adler <darin@apple.com> + + Try to fix Qt build. + + * WebCoreSupport/EditorClientQt.cpp: + (WebCore::EditorClientQt::shouldShowDeleteInterface): + Use getAttribute(classAttr) instead of className() function. + +2009-08-14 Yongjun Zhang <yongjun.zhang@nokia.com> + + Reviewed by Simon Hausmann. + + RVCT elftran fails to resolve QPainter::staticMetaObject coming with + QWebView::RenderHints property. + + This is a temporary fix and will be revereted when the right symbols + exported from Qt lib in S60. + + https://bugs.webkit.org/show_bug.cgi?id=28181 + + * Api/qwebview.h: + +2009-08-14 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Public API to configure the storage path for HTML5 localStorage + https://bugs.webkit.org/show_bug.cgi?id=28036 + + Disables LocalStorage for QtWebKit by default by setting + QWebSettings::LocalStorageEnabled to false. + + Sets up a default for the LocalStorage path so that clients would only + need to enable the LocalStorageEnabled setting to turn on LocalStoragre + support. + + Turn on LocalStorage support for QtLauncher and the relevant test + since LocalStorage is now disabled by default for QtWebkit. + + * Api/qwebpage.cpp: + (defaultCachePath): + (initializeApplicationCachePathIfNecessary): + (QWebPagePrivate::QWebPagePrivate): + * Api/qwebsettings.cpp: + (QWebSettingsPrivate::apply): + (QWebSettings::QWebSettings): + (QWebSettings::setLocalStoragePath): + (QWebSettings::localStoragePath): + * Api/qwebsettings.h: + * QtLauncher/main.cpp: + (main): + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::multiplePageGroupsAndLocalStorage): + +2009-08-14 Yael Aharon <yael.aharon@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Allow applications to register their own local URL scheme. + https://bugs.webkit.org/show_bug.cgi?id=28240 + + * Api/qwebsecurityorigin.cpp: + (QWebSecurityOrigin::addLocalScheme): + (QWebSecurityOrigin::removeLocalScheme): + (QWebSecurityOrigin::localSchemes): + * Api/qwebsecurityorigin.h: + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::localURLSchemes): + +2009-08-13 Mark Rowe <mrowe@apple.com> + + Try and fix the Qt build. + + * Api/qwebelement.cpp: + +2009-08-13 Kavindra Devi Palaraja <kavindra.palaraja@nokia.com> + + Reviewed by Simon Hausmann. + + Doc - Some cleanup on the documentation of QWebElement + + * Api/qwebelement.cpp: + +2009-08-13 Norbert Leser <norbert.leser@nokia.com> + + Reviewed by Simon Hausmann. + + Symbian target components (library and executable files) + require Unique Identifiers (i.e., UID3). + These identifiers are defined in the respective project + files, conditionally for "symbian" platform. + + * QtLauncher/QtLauncher.pro: + * tests/qwebelement/qwebelement.pro: + * tests/qwebframe/qwebframe.pro: + * tests/qwebhistory/qwebhistory.pro: + * tests/qwebhistoryinterface/qwebhistoryinterface.pro: + * tests/qwebpage/qwebpage.pro: + * tests/qwebview/qwebview.pro: + +2009-08-12 George Wright <george.wright@torchmobile.com> + + Reviewed by Adam Treat. + + Initialise zoom levels independent of whether a URL is valid or not to + fix https://bugs.webkit.org/show_bug.cgi?id=28162 + + * QtLauncher/main.cpp: + (MainWindow::MainWindow): + +2009-08-12 Joerg Bornemann <joerg.bornemann@trolltech.com> + + Reviewed by Simon Hausmann. + + QtWebKit compile fix for Windows CE + + There's no getenv on Windows CE, use qgetenv instead. + + * Api/qwebpage.cpp: + (qt_drt_overwritePluginDirectories): + 2009-08-10 Kavindra Palaraja <kavindra.palaraja@nokia.com> Reviewed by Simon Hausmann. @@ -2956,7 +6696,7 @@ Reviewed by Simon Hausmann. - http://www.qtsoftware.com/developer/task-tracker/index_html?id=238391&method=entry + http://qt.nokia.com/developer/task-tracker/index_html?id=238391&method=entry [Qt] If QPainter fails to start on a QPrinter instance, do not continue printing. @@ -3149,7 +6889,7 @@ Rubber-stamped by Simon Hausmann. - http://www.qtsoftware.com/developer/task-tracker/index_html?id=219344&method=entry + http://qt.nokia.com/developer/task-tracker/index_html?id=219344&method=entry [Qt] API documentation for QWebPage::WebAction enum. @@ -3204,7 +6944,7 @@ Reviewed by Simon Hausmann. - http://www.qtsoftware.com/developer/task-tracker/index_html?id=241144&method=entry + http://qt.nokia.com/developer/task-tracker/index_html?id=241144&method=entry [Qt] Create actions for text selection and editing for QWebPage. Also properly disable and enable them when contentEditable is toggled. diff --git a/WebKit/qt/Plugins/ICOHandler.cpp b/WebKit/qt/Plugins/ICOHandler.cpp deleted file mode 100644 index d7fae07..0000000 --- a/WebKit/qt/Plugins/ICOHandler.cpp +++ /dev/null @@ -1,460 +0,0 @@ -/* - * kimgio import filter for MS Windows .ico files - * - * Distributed under the terms of the LGPL - * Copyright (c) 2000 Malte Starostik <malte@kde.org> - * - */ - -#include "config.h" -#include "ICOHandler.h" - -#include <cstring> -#include <cstdlib> -#include <algorithm> -#include <vector> - -#include <QtGui/QImage> -#include <QtGui/QBitmap> -#include <QtGui/QApplication> -#include <QtCore/QVector> -#include <QtGui/QDesktopWidget> - -namespace -{ - // Global header (see http://www.daubnet.com/formats/ICO.html) - struct IcoHeader - { - enum Type { Icon = 1, Cursor }; - quint16 reserved; - quint16 type; - quint16 count; - }; - - inline QDataStream& operator >>( QDataStream& s, IcoHeader& h ) - { - return s >> h.reserved >> h.type >> h.count; - } - - // Based on qt_read_dib et al. from qimage.cpp - // (c) 1992-2002 Nokia Corporation and/or its subsidiary(-ies). - struct BMP_INFOHDR - { - static const quint32 Size = 40; - quint32 biSize; // size of this struct - quint32 biWidth; // pixmap width - quint32 biHeight; // pixmap height - quint16 biPlanes; // should be 1 - quint16 biBitCount; // number of bits per pixel - enum Compression { RGB = 0 }; - quint32 biCompression; // compression method - quint32 biSizeImage; // size of image - quint32 biXPelsPerMeter; // horizontal resolution - quint32 biYPelsPerMeter; // vertical resolution - quint32 biClrUsed; // number of colors used - quint32 biClrImportant; // number of important colors - }; - const quint32 BMP_INFOHDR::Size; - - QDataStream& operator >>( QDataStream &s, BMP_INFOHDR &bi ) - { - s >> bi.biSize; - if ( bi.biSize == BMP_INFOHDR::Size ) - { - s >> bi.biWidth >> bi.biHeight >> bi.biPlanes >> bi.biBitCount; - s >> bi.biCompression >> bi.biSizeImage; - s >> bi.biXPelsPerMeter >> bi.biYPelsPerMeter; - s >> bi.biClrUsed >> bi.biClrImportant; - } - return s; - } - -#if 0 - QDataStream &operator<<( QDataStream &s, const BMP_INFOHDR &bi ) - { - s << bi.biSize; - s << bi.biWidth << bi.biHeight; - s << bi.biPlanes; - s << bi.biBitCount; - s << bi.biCompression; - s << bi.biSizeImage; - s << bi.biXPelsPerMeter << bi.biYPelsPerMeter; - s << bi.biClrUsed << bi.biClrImportant; - return s; - } -#endif - - // Header for every icon in the file - struct IconRec - { - unsigned char width; - unsigned char height; - quint16 colors; - quint16 hotspotX; - quint16 hotspotY; - quint32 size; - quint32 offset; - }; - - inline QDataStream& operator >>( QDataStream& s, IconRec& r ) - { - return s >> r.width >> r.height >> r.colors - >> r.hotspotX >> r.hotspotY >> r.size >> r.offset; - } - - struct LessDifference - { - LessDifference( unsigned s, unsigned c ) - : size( s ), colors( c ) {} - - bool operator ()( const IconRec& lhs, const IconRec& rhs ) const - { - // closest size match precedes everything else - if ( std::abs( int( lhs.width - size ) ) < - std::abs( int( rhs.width - size ) ) ) return true; - else if ( std::abs( int( lhs.width - size ) ) > - std::abs( int( rhs.width - size ) ) ) return false; - else if ( colors == 0 ) - { - // high/true color requested - if ( lhs.colors == 0 ) return true; - else if ( rhs.colors == 0 ) return false; - else return lhs.colors > rhs.colors; - } - else - { - // indexed icon requested - if ( lhs.colors == 0 && rhs.colors == 0 ) return false; - else if ( lhs.colors == 0 ) return false; - else return std::abs( int( lhs.colors - colors ) ) < - std::abs( int( rhs.colors - colors ) ); - } - } - unsigned size; - unsigned colors; - }; - - bool loadFromDIB( QDataStream& stream, const IconRec& rec, QImage& icon ) - { - BMP_INFOHDR header; - stream >> header; - if ( stream.atEnd() || header.biSize != BMP_INFOHDR::Size || - header.biSize > rec.size || - header.biCompression != BMP_INFOHDR::RGB || - ( header.biBitCount != 1 && header.biBitCount != 4 && - header.biBitCount != 8 && header.biBitCount != 24 && - header.biBitCount != 32 ) ) return false; - - unsigned paletteSize, paletteEntries; - - if (header.biBitCount > 8) - { - paletteEntries = 0; - paletteSize = 0; - } - else - { - paletteSize = (1 << header.biBitCount); - paletteEntries = paletteSize; - if (header.biClrUsed && header.biClrUsed < paletteSize) - paletteEntries = header.biClrUsed; - } - - // Always create a 32-bit image to get the mask right - // Note: this is safe as rec.width, rec.height are bytes - icon = QImage( rec.width, rec.height, QImage::Format_ARGB32 ); - if ( icon.isNull() ) return false; - - QVector< QRgb > colorTable( paletteSize ); - - colorTable.fill( QRgb( 0 ) ); - for ( unsigned i = 0; i < paletteEntries; ++i ) - { - unsigned char rgb[ 4 ]; - stream.readRawData( reinterpret_cast< char* >( &rgb ), - sizeof( rgb ) ); - colorTable[ i ] = qRgb( rgb[ 2 ], rgb[ 1 ], rgb[ 0 ] ); - } - - unsigned bpl = ( rec.width * header.biBitCount + 31 ) / 32 * 4; - - unsigned char* buf = new unsigned char[ bpl ]; - for ( unsigned y = rec.height; !stream.atEnd() && y--; ) - { - stream.readRawData( reinterpret_cast< char* >( buf ), bpl ); - unsigned char* pixel = buf; - QRgb* p = reinterpret_cast< QRgb* >( icon.scanLine( y ) ); - switch ( header.biBitCount ) - { - case 1: - for ( unsigned x = 0; x < rec.width; ++x ) - *p++ = colorTable[ - ( pixel[ x / 8 ] >> ( 7 - ( x & 0x07 ) ) ) & 1 ]; - break; - case 4: - for ( unsigned x = 0; x < rec.width; ++x ) - if ( x & 1 ) *p++ = colorTable[ pixel[ x / 2 ] & 0x0f ]; - else *p++ = colorTable[ pixel[ x / 2 ] >> 4 ]; - break; - case 8: - for ( unsigned x = 0; x < rec.width; ++x ) - *p++ = colorTable[ pixel[ x ] ]; - break; - case 24: - for ( unsigned x = 0; x < rec.width; ++x ) - *p++ = qRgb( pixel[ 3 * x + 2 ], - pixel[ 3 * x + 1 ], - pixel[ 3 * x ] ); - break; - case 32: - for ( unsigned x = 0; x < rec.width; ++x ) - *p++ = qRgba( pixel[ 4 * x + 2 ], - pixel[ 4 * x + 1 ], - pixel[ 4 * x ], - pixel[ 4 * x + 3] ); - break; - } - } - delete[] buf; - - if ( header.biBitCount < 32 ) - { - // Traditional 1-bit mask - bpl = ( rec.width + 31 ) / 32 * 4; - buf = new unsigned char[ bpl ]; - for ( unsigned y = rec.height; y--; ) - { - stream.readRawData( reinterpret_cast< char* >( buf ), bpl ); - QRgb* p = reinterpret_cast< QRgb* >( icon.scanLine( y ) ); - for ( unsigned x = 0; x < rec.width; ++x, ++p ) - if ( ( ( buf[ x / 8 ] >> ( 7 - ( x & 0x07 ) ) ) & 1 ) ) - *p &= RGB_MASK; - } - delete[] buf; - } - return true; - } -} - -ICOHandler::ICOHandler() -{ -} - -bool ICOHandler::canRead() const -{ - return canRead(device()); -} - -bool ICOHandler::read(QImage *outImage) -{ - - qint64 offset = device()->pos(); - - QDataStream stream( device() ); - stream.setByteOrder( QDataStream::LittleEndian ); - IcoHeader header; - stream >> header; - if ( stream.atEnd() || !header.count || - ( header.type != IcoHeader::Icon && header.type != IcoHeader::Cursor) ) - return false; - - unsigned requestedSize = 32; - unsigned requestedColors = QApplication::desktop()->depth() > 8 ? 0 : QApplication::desktop()->depth(); - int requestedIndex = -1; -#if 0 - if ( io->parameters() ) - { - QStringList params = QString(io->parameters()).split( ';', QString::SkipEmptyParts ); - QMap< QString, QString > options; - for ( QStringList::ConstIterator it = params.begin(); - it != params.end(); ++it ) - { - QStringList tmp = (*it).split( '=', QString::SkipEmptyParts ); - if ( tmp.count() == 2 ) options[ tmp[ 0 ] ] = tmp[ 1 ]; - } - if ( options[ "index" ].toUInt() ) - requestedIndex = options[ "index" ].toUInt(); - if ( options[ "size" ].toUInt() ) - requestedSize = options[ "size" ].toUInt(); - if ( options[ "colors" ].toUInt() ) - requestedColors = options[ "colors" ].toUInt(); - } -#endif - - typedef std::vector< IconRec > IconList; - IconList icons; - for ( unsigned i = 0; i < header.count; ++i ) - { - if ( stream.atEnd() ) - return false; - IconRec rec; - stream >> rec; - icons.push_back( rec ); - } - IconList::const_iterator selected; - if (requestedIndex >= 0) { - selected = std::min( icons.begin() + requestedIndex, icons.end() ); - } else { - selected = std::min_element( icons.begin(), icons.end(), - LessDifference( requestedSize, requestedColors ) ); - } - if ( stream.atEnd() || selected == icons.end() || - offset + selected->offset > device()->size() ) - return false; - - device()->seek( offset + selected->offset ); - QImage icon; - if ( loadFromDIB( stream, *selected, icon ) ) - { -#ifndef QT_NO_IMAGE_TEXT - icon.setText( "X-Index", 0, QString::number( selected - icons.begin() ) ); - if ( header.type == IcoHeader::Cursor ) - { - icon.setText( "X-HotspotX", 0, QString::number( selected->hotspotX ) ); - icon.setText( "X-HotspotY", 0, QString::number( selected->hotspotY ) ); - } -#endif - *outImage = icon; - return true; - } - return false; -} - -bool ICOHandler::write(const QImage &/*image*/) -{ -#if 0 - if (image.isNull()) - return; - - QByteArray dibData; - QDataStream dib(dibData, QIODevice::ReadWrite); - dib.setByteOrder(QDataStream::LittleEndian); - - QImage pixels = image; - QImage mask; - if (io->image().hasAlphaBuffer()) - mask = image.createAlphaMask(); - else - mask = image.createHeuristicMask(); - mask.invertPixels(); - for ( int y = 0; y < pixels.height(); ++y ) - for ( int x = 0; x < pixels.width(); ++x ) - if ( mask.pixel( x, y ) == 0 ) pixels.setPixel( x, y, 0 ); - - if (!qt_write_dib(dib, pixels)) - return; - - uint hdrPos = dib.device()->at(); - if (!qt_write_dib(dib, mask)) - return; - memmove(dibData.data() + hdrPos, dibData.data() + hdrPos + BMP_WIN + 8, dibData.size() - hdrPos - BMP_WIN - 8); - dibData.resize(dibData.size() - BMP_WIN - 8); - - QDataStream ico(device()); - ico.setByteOrder(QDataStream::LittleEndian); - IcoHeader hdr; - hdr.reserved = 0; - hdr.type = Icon; - hdr.count = 1; - ico << hdr.reserved << hdr.type << hdr.count; - IconRec rec; - rec.width = image.width(); - rec.height = image.height(); - if (image.numColors() <= 16) - rec.colors = 16; - else if (image.depth() <= 8) - rec.colors = 256; - else - rec.colors = 0; - rec.hotspotX = 0; - rec.hotspotY = 0; - rec.dibSize = dibData.size(); - ico << rec.width << rec.height << rec.colors - << rec.hotspotX << rec.hotspotY << rec.dibSize; - rec.dibOffset = ico.device()->at() + sizeof(rec.dibOffset); - ico << rec.dibOffset; - - BMP_INFOHDR dibHeader; - dib.device()->at(0); - dib >> dibHeader; - dibHeader.biHeight = image.height() << 1; - dib.device()->at(0); - dib << dibHeader; - - ico.writeRawBytes(dibData.data(), dibData.size()); - return true; -#endif - return false; -} - -QByteArray ICOHandler::name() const -{ - return "ico"; -} - -bool ICOHandler::canRead(QIODevice *device) -{ - if (!device) { - qWarning("ICOHandler::canRead() called with no device"); - return false; - } - - const qint64 oldPos = device->pos(); - - char head[8]; - qint64 readBytes = device->read(head, sizeof(head)); - const bool readOk = readBytes == sizeof(head); - - if (device->isSequential()) { - while (readBytes > 0) - device->ungetChar(head[readBytes-- - 1]); - } else { - device->seek(oldPos); - } - - if ( !readOk ) - return false; - - return head[2] == '\001' && head[3] == '\000' && // type should be 1 - ( head[6] == 16 || head[6] == 32 || head[6] == 64 ) && // width can only be one of those - ( head[7] == 16 || head[7] == 32 || head[7] == 64 ); // same for height -} - -class ICOPlugin : public QImageIOPlugin -{ -public: - QStringList keys() const; - Capabilities capabilities(QIODevice *device, const QByteArray &format) const; - QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const; -}; - -QStringList ICOPlugin::keys() const -{ - return QStringList() << "ico" << "ICO"; -} - -QImageIOPlugin::Capabilities ICOPlugin::capabilities(QIODevice *device, const QByteArray &format) const -{ - if (format == "ico" || format == "ICO") - return Capabilities(CanRead); - if (!format.isEmpty()) - return 0; - if (!device->isOpen()) - return 0; - - Capabilities cap; - if (device->isReadable() && ICOHandler::canRead(device)) - cap |= CanRead; - return cap; -} - -QImageIOHandler *ICOPlugin::create(QIODevice *device, const QByteArray &format) const -{ - QImageIOHandler *handler = new ICOHandler; - handler->setDevice(device); - handler->setFormat(format); - return handler; -} - -Q_EXPORT_STATIC_PLUGIN(ICOPlugin) -Q_EXPORT_PLUGIN2(qtwebico, ICOPlugin) diff --git a/WebKit/qt/Plugins/ICOHandler.h b/WebKit/qt/Plugins/ICOHandler.h deleted file mode 100644 index 4f1f1d6..0000000 --- a/WebKit/qt/Plugins/ICOHandler.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * ico.h - kimgio import filter for MS Windows .ico files - * - * Distributed under the terms of the LGPL - * Copyright (c) 2000 Malte Starostik <malte@kde.org> - * - */ - -// You can use QImageIO::setParameters() to request a specific -// Icon out of an .ico file: -// -// Options consist of a name=value pair and are separated by a semicolon. -// Available options are: -// size=<size> select the icon that most closely matches <size> (pixels) -// default: 32 -// colors=<num> select the icon that has <num> colors (or comes closest) -// default: 1 << display depth or 0 (RGB) if display depth > 8 -// index=<index> select the indexth icon from the file. If this option -// is present, the size and colors options will be ignored. -// default: none -// If both size and colors are given, size takes precedence. -// -// The old format is still supported: -// the parameters consist of a single string in the form -// "<size>[:<colors>]" which correspond to the options above -// -// If an icon was returned (i.e. the file is valid and the index option -// if present was not out of range), the icon's index within the .ico -// file is returned in the text tag "X-Index" of the image. -// If the icon is in fact a cursor, its hotspot coordinates are returned -// in the text tags "X-HotspotX" and "X-HotspotY". - -#ifndef _ICOHANDLER_H_ -#define _ICOHANDLER_H_ - -#include <QtGui/QImageIOPlugin> - -class ICOHandler : public QImageIOHandler -{ -public: - ICOHandler(); - - bool canRead() const; - bool read(QImage *image); - bool write(const QImage &image); - - QByteArray name() const; - - static bool canRead(QIODevice *device); -}; - -#endif diff --git a/WebKit/qt/Plugins/Plugins.pro b/WebKit/qt/Plugins/Plugins.pro deleted file mode 100644 index a9b4f82..0000000 --- a/WebKit/qt/Plugins/Plugins.pro +++ /dev/null @@ -1,14 +0,0 @@ -TEMPLATE = lib -TARGET = qtwebico -CONFIG += plugin -HEADERS += ICOHandler.h -SOURCES += ICOHandler.cpp - -include(../../WebKit.pri) - -contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols -unix:contains(QT_CONFIG, reduce_relocations):CONFIG += bsymbolic_functions - -target.path = $$[QT_INSTALL_PLUGINS]/imageformats -INSTALLS += target - diff --git a/WebKit/qt/QGVLauncher/QGVLauncher.pro b/WebKit/qt/QGVLauncher/QGVLauncher.pro new file mode 100644 index 0000000..059ec1a --- /dev/null +++ b/WebKit/qt/QGVLauncher/QGVLauncher.pro @@ -0,0 +1,16 @@ +TEMPLATE = app +SOURCES += main.cpp +CONFIG -= app_bundle +CONFIG += uitools +DESTDIR = ../../../bin + +include(../../../WebKit.pri) + +QT += network +macx:QT+=xml +QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR + +symbian { + TARGET.UID3 = 0xA000E544 + TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices +} diff --git a/WebKit/qt/QGVLauncher/main.cpp b/WebKit/qt/QGVLauncher/main.cpp new file mode 100644 index 0000000..2021cb6 --- /dev/null +++ b/WebKit/qt/QGVLauncher/main.cpp @@ -0,0 +1,445 @@ +/* + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + * Copyright (C) 2006 George Staikos <staikos@kde.org> + * Copyright (C) 2006 Dirk Mueller <mueller@kde.org> + * Copyright (C) 2006 Zack Rusin <zack@kde.org> + * Copyright (C) 2006 Simon Hausmann <hausmann@kde.org> + * Copyright (C) 2009 Kenneth Christiansen <kenneth@webkit.org> + * Copyright (C) 2009 Antonio Gomes <antonio.gomes@openbossa.org> + * Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in> + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <QDebug> +#include <QFile> +#include <QGraphicsScene> +#include <QGraphicsView> +#include <QGraphicsWidget> +#include <QNetworkRequest> +#include <QTextStream> +#include <QVector> +#include <QtGui> +#include <QtNetwork/QNetworkProxy> +#include <cstdio> +#include <qwebelement.h> +#include <qwebframe.h> +#include <qgraphicswebview.h> +#include <qwebpage.h> +#include <qwebsettings.h> +#include <qwebview.h> + +static QUrl urlFromUserInput(const QString& string) +{ + QString input(string); + QFileInfo fi(input); + if (fi.exists() && fi.isRelative()) + input = fi.absoluteFilePath(); + +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + return QUrl::fromUserInput(input); +#else + return QUrl(input); +#endif +} + +class WebView : public QGraphicsWebView { + Q_OBJECT + Q_PROPERTY(qreal yRotation READ yRotation WRITE setYRotation) + +public: + WebView(QGraphicsItem* parent = 0) + : QGraphicsWebView(parent) + { + } + void setYRotation(qreal angle) + { +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + QRectF r = boundingRect(); + setTransform(QTransform() + .translate(r.width() / 2, r.height() / 2) + .rotate(angle, Qt::YAxis) + .translate(-r.width() / 2, -r.height() / 2)); +#endif + m_yRotation = angle; + } + qreal yRotation() const + { + return m_yRotation; + } + +private: + qreal m_yRotation; +}; + +class WebPage : public QWebPage { + Q_OBJECT + +public: + WebPage(QObject* parent = 0) + : QWebPage(parent) + { + applyProxy(); + } + virtual QWebPage* createWindow(QWebPage::WebWindowType); + +private: + void applyProxy() + { + QUrl proxyUrl = urlFromUserInput(qgetenv("http_proxy")); + + if (proxyUrl.isValid() && !proxyUrl.host().isEmpty()) { + int proxyPort = (proxyUrl.port() > 0) ? proxyUrl.port() : 8080; + networkAccessManager()->setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, proxyUrl.host(), proxyPort)); + } + } +}; + +class MainView : public QGraphicsView { + Q_OBJECT + +public: + MainView(QWidget* parent) + : QGraphicsView(parent) + , m_mainWidget(0) + { + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + setFrameShape(QFrame::NoFrame); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + } + + void setMainWidget(QGraphicsWidget* widget) + { + QRectF rect(QRect(QPoint(0, 0), size())); + widget->setGeometry(rect); + m_mainWidget = widget; + } + + void resizeEvent(QResizeEvent* event) + { + QGraphicsView::resizeEvent(event); + if (!m_mainWidget) + return; + QRectF rect(QPoint(0, 0), event->size()); + m_mainWidget->setGeometry(rect); + } + + void setWaitCursor() + { + m_mainWidget->setCursor(Qt::WaitCursor); + } + + void resetCursor() + { + m_mainWidget->unsetCursor(); + } + +public slots: + void flip() + { +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + QSizeF center = m_mainWidget->boundingRect().size() / 2; + QPointF centerPoint = QPointF(center.width(), center.height()); + m_mainWidget->setTransformOriginPoint(centerPoint); + + m_mainWidget->setRotation(m_mainWidget->rotation() ? 0 : 180); +#endif + } + + void animatedFlip() + { +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + QSizeF center = m_mainWidget->boundingRect().size() / 2; + QPointF centerPoint = QPointF(center.width(), center.height()); + m_mainWidget->setTransformOriginPoint(centerPoint); + + QPropertyAnimation* animation = new QPropertyAnimation(m_mainWidget, "rotation", this); + animation->setDuration(1000); + + int rotation = int(m_mainWidget->rotation()); + + animation->setStartValue(rotation); + animation->setEndValue(rotation + 180 - (rotation % 180)); + + animation->start(QAbstractAnimation::DeleteWhenStopped); +#endif + } + + void animatedYFlip() + { + emit flipRequest(); + } + +signals: + void flipRequest(); + +private: + QGraphicsWidget* m_mainWidget; +}; + +class SharedScene : public QSharedData { +public: + SharedScene() + { + m_scene = new QGraphicsScene; + m_item = new WebView; + m_item->setPage((m_page = new WebPage)); + + m_scene->addItem(m_item); + m_scene->setActiveWindow(m_item); + } + + ~SharedScene() + { + delete m_item; + delete m_scene; + delete m_page; + } + + QGraphicsScene* scene() const { return m_scene; } + WebView* webView() const { return m_item; } + +private: + QGraphicsScene* m_scene; + WebView* m_item; + WebPage* m_page; +}; + +class MainWindow : public QMainWindow { + Q_OBJECT + +public: + MainWindow(QExplicitlySharedDataPointer<SharedScene> other) + : QMainWindow() + , view(new MainView(this)) + , scene(other) + { + init(); + } + + MainWindow() + : QMainWindow() + , view(new MainView(this)) + , scene(new SharedScene()) + { + init(); + } + + void init() + { + setAttribute(Qt::WA_DeleteOnClose); + + view->setScene(scene->scene()); + + setCentralWidget(view); + + view->setMainWidget(scene->webView()); + + connect(scene->webView(), SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool))); + connect(scene->webView(), SIGNAL(titleChanged(const QString&)), this, SLOT(setWindowTitle(const QString&))); + connect(scene->webView()->page(), SIGNAL(windowCloseRequested()), this, SLOT(close())); + +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + QStateMachine *machine = new QStateMachine(this); + QState *s0 = new QState(machine); + s0->assignProperty(scene->webView(), "yRotation", 0); + + QState *s1 = new QState(machine); + s1->assignProperty(scene->webView(), "yRotation", 90); + + QAbstractTransition *t1 = s0->addTransition(view, SIGNAL(flipRequest()), s1); + QPropertyAnimation *yRotationAnim = new QPropertyAnimation(scene->webView(), "yRotation", this); + yRotationAnim->setDuration(1000); + t1->addAnimation(yRotationAnim); + + QState *s2 = new QState(machine); + s2->assignProperty(scene->webView(), "yRotation", -90); + s1->addTransition(s1, SIGNAL(polished()), s2); + + QAbstractTransition *t2 = s2->addTransition(s0); + t2->addAnimation(yRotationAnim); + + machine->setInitialState(s0); + machine->start(); +#endif + + resize(640, 480); + buildUI(); + } + + void load(const QString& url) + { + QUrl deducedUrl = urlFromUserInput(url); + if (!deducedUrl.isValid()) + deducedUrl = QUrl("http://" + url + "/"); + + urlEdit->setText(deducedUrl.toEncoded()); + scene->webView()->load(deducedUrl); + scene->webView()->setFocus(Qt::OtherFocusReason); + } + + QWebPage* page() const + { + return scene->webView()->page(); + } + +protected slots: + void changeLocation() + { + load(urlEdit->text()); + } + + void loadFinished(bool) + { + QUrl url = scene->webView()->url(); + urlEdit->setText(url.toString()); + + QUrl::FormattingOptions opts; + opts |= QUrl::RemoveScheme; + opts |= QUrl::RemoveUserInfo; + opts |= QUrl::StripTrailingSlash; + QString s = url.toString(opts); + s = s.mid(2); + if (s.isEmpty()) + return; + //FIXME: something missing here + } + +public slots: + void newWindow(const QString &url = QString()) + { + MainWindow* mw = new MainWindow(); + mw->load(url); + mw->show(); + } + + void clone() + { + MainWindow* mw = new MainWindow(scene); + mw->show(); + } + + void setWaitCursor() + { + view->setWaitCursor(); + } + + void resetCursor() + { + view->resetCursor(); + } + + void flip() + { + view->flip(); + } + + void animatedFlip() + { + view->animatedFlip(); + } + + void animatedYFlip() + { + view->animatedYFlip(); + } + +private: + void buildUI() + { + QWebPage* page = scene->webView()->page(); + urlEdit = new QLineEdit(this); + urlEdit->setSizePolicy(QSizePolicy::Expanding, urlEdit->sizePolicy().verticalPolicy()); + connect(urlEdit, SIGNAL(returnPressed()), SLOT(changeLocation())); + + QToolBar* bar = addToolBar("Navigation"); + bar->addAction(page->action(QWebPage::Back)); + bar->addAction(page->action(QWebPage::Forward)); + bar->addAction(page->action(QWebPage::Reload)); + bar->addAction(page->action(QWebPage::Stop)); + bar->addWidget(urlEdit); + + QMenu* fileMenu = menuBar()->addMenu("&File"); + fileMenu->addAction("New Window", this, SLOT(newWindow())); + fileMenu->addAction("Clone view", this, SLOT(clone())); + fileMenu->addAction("Close", this, SLOT(close())); + + QMenu* viewMenu = menuBar()->addMenu("&View"); + viewMenu->addAction(page->action(QWebPage::Stop)); + viewMenu->addAction(page->action(QWebPage::Reload)); + + QMenu* testMenu = menuBar()->addMenu("&Tests"); + testMenu->addAction("Set Wait Cursor", this, SLOT(setWaitCursor()), QKeySequence("Ctrl+W")); + testMenu->addAction("Reset Cursor", this, SLOT(resetCursor()), QKeySequence("Ctrl+Shift+W")); + + QMenu* fxMenu = menuBar()->addMenu("&Effects"); + fxMenu->addAction("Flip", this, SLOT(flip())); + fxMenu->addAction("Animated Flip", this, SLOT(animatedFlip()), QKeySequence("Ctrl+R")); + fxMenu->addAction("Animated Y-Flip", this, SLOT(animatedYFlip()), QKeySequence("Ctrl+Y")); + } + +private: + MainView* view; + QExplicitlySharedDataPointer<SharedScene> scene; + + QLineEdit* urlEdit; +}; + +QWebPage* WebPage::createWindow(QWebPage::WebWindowType) +{ + MainWindow* mw = new MainWindow; + mw->show(); + return mw->page(); +} + +int main(int argc, char** argv) +{ + QApplication app(argc, argv); + QString url = QString("file://%1/%2").arg(QDir::homePath()).arg(QLatin1String("index.html")); + + app.setApplicationName("GQVLauncher"); + + QWebSettings::setObjectCacheCapacities((16 * 1024 * 1024) / 8, (16 * 1024 * 1024) / 8, 16 * 1024 * 1024); + QWebSettings::setMaximumPagesInCache(4); + QWebSettings::globalSettings()->setAttribute(QWebSettings::PluginsEnabled, true); + QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true); + QWebSettings::globalSettings()->setAttribute(QWebSettings::LocalStorageEnabled, true); + + const QStringList args = app.arguments(); + if (args.count() > 1) + url = args.at(1); + + MainWindow* window = new MainWindow; + window->load(url); + + for (int i = 2; i < args.count(); i++) + window->newWindow(args.at(i)); + + window->show(); + return app.exec(); +} + +#include "main.moc" diff --git a/WebKit/qt/QtLauncher/QtLauncher.pro b/WebKit/qt/QtLauncher/QtLauncher.pro index 42138c8..133869c 100644 --- a/WebKit/qt/QtLauncher/QtLauncher.pro +++ b/WebKit/qt/QtLauncher/QtLauncher.pro @@ -9,3 +9,8 @@ include(../../../WebKit.pri) QT += network macx:QT+=xml QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR + +symbian { + TARGET.UID3 = 0xA000E543 + TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices +} diff --git a/WebKit/qt/QtLauncher/main.cpp b/WebKit/qt/QtLauncher/main.cpp index 9cbab53..2286712 100644 --- a/WebKit/qt/QtLauncher/main.cpp +++ b/WebKit/qt/QtLauncher/main.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + * Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in> * Copyright (C) 2006 George Staikos <staikos@kde.org> * Copyright (C) 2006 Dirk Mueller <mueller@kde.org> * Copyright (C) 2006 Zack Rusin <zack@kde.org> @@ -29,16 +30,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <qwebpage.h> -#include <qwebview.h> -#include <qwebframe.h> -#include <qwebsettings.h> -#include <qwebelement.h> - #include <QtGui> -#include <QDebug> #include <QtNetwork/QNetworkProxy> -#if QT_VERSION >= 0x040400 && !defined(QT_NO_PRINTER) +#include <QtNetwork/QNetworkRequest> +#if !defined(QT_NO_PRINTER) #include <QPrintPreviewDialog> #endif @@ -46,37 +41,143 @@ #include <QtUiTools/QUiLoader> #endif -#include <QVector> -#include <QTextStream> +#include <QDebug> #include <QFile> +#include <QTextStream> +#include <QVector> + #include <cstdio> +#include <qwebelement.h> +#include <qwebframe.h> +#include <qwebinspector.h> +#include <qwebpage.h> +#include <qwebsettings.h> +#include <qwebview.h> + #ifndef NDEBUG void QWEBKIT_EXPORT qt_drt_garbageCollector_collect(); #endif -class WebPage : public QWebPage +static QUrl urlFromUserInput(const QString& input) { +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + return QUrl::fromUserInput(input); +#else + return QUrl(input); +#endif +} + +class WebView : public QWebView { + Q_OBJECT +public: + WebView(QWidget* parent) : QWebView(parent) {} + +protected: + virtual void contextMenuEvent(QContextMenuEvent* event) + { + QMenu* menu = page()->createStandardContextMenu(); + + QWebHitTestResult r = page()->mainFrame()->hitTestContent(event->pos()); + + if (!r.linkUrl().isEmpty()) { + QAction* newTabAction = menu->addAction(tr("Open in Default &Browser"), this, SLOT(openUrlInDefaultBrowser())); + newTabAction->setData(r.linkUrl()); + menu->insertAction(menu->actions().at(2), newTabAction); + } + + menu->exec(mapToGlobal(event->pos())); + delete menu; + } + + virtual void mousePressEvent(QMouseEvent* event) + { + mouseButtons = event->buttons(); + keyboardModifiers = event->modifiers(); + + QWebView::mousePressEvent(event); + } + +public slots: + void openUrlInDefaultBrowser(const QUrl &url = QUrl()) + { + if (QAction* action = qobject_cast<QAction*>(sender())) + QDesktopServices::openUrl(action->data().toUrl()); + else + QDesktopServices::openUrl(url); + } + +public: + Qt::MouseButtons mouseButtons; + Qt::KeyboardModifiers keyboardModifiers; +}; + +class WebPage : public QWebPage { public: WebPage(QWidget *parent) : QWebPage(parent) {} virtual QWebPage *createWindow(QWebPage::WebWindowType); virtual QObject* createPlugin(const QString&, const QUrl&, const QStringList&, const QStringList&); + virtual bool supportsExtension(QWebPage::Extension extension) const + { + if (extension == QWebPage::ErrorPageExtension) + return true; + return false; + } + virtual bool extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output); + + + virtual bool acceptNavigationRequest(QWebFrame* frame, const QNetworkRequest &request, NavigationType type) + { + WebView* webView = static_cast<WebView*>(view()); + if (webView->keyboardModifiers & Qt::ShiftModifier) { + QWebPage* page = createWindow(QWebPage::WebBrowserWindow); + page->mainFrame()->load(request); + return false; + } + if (webView->keyboardModifiers & Qt::AltModifier) { + webView->openUrlInDefaultBrowser(request.url()); + return false; + } + + return QWebPage::acceptNavigationRequest(frame, request, type); + } }; -class MainWindow : public QMainWindow -{ +class WebInspector : public QWebInspector { Q_OBJECT public: - MainWindow(QString url = QString()): currentZoom(100) { + WebInspector(QWidget* parent) : QWebInspector(parent) {} +signals: + void visibleChanged(bool nowVisible); +protected: + void showEvent(QShowEvent* event) + { + QWebInspector::showEvent(event); + emit visibleChanged(true); + } + void hideEvent(QHideEvent* event) + { + QWebInspector::hideEvent(event); + emit visibleChanged(false); + } +}; + +class MainWindow : public QMainWindow { + Q_OBJECT +public: + MainWindow(QString url = QString()): currentZoom(100) + { setAttribute(Qt::WA_DeleteOnClose); + if (qgetenv("QTLAUNCHER_USE_ARGB_VISUALS").toInt() == 1) + setAttribute(Qt::WA_TranslucentBackground); - view = new QWebView(this); - setCentralWidget(view); + QSplitter* splitter = new QSplitter(Qt::Vertical, this); + setCentralWidget(splitter); + view = new WebView(splitter); WebPage* page = new WebPage(view); view->setPage(page); - connect(view, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished())); connect(view, SIGNAL(titleChanged(const QString&)), @@ -85,10 +186,16 @@ public: this, SLOT(showLinkHover(const QString&, const QString&))); connect(view->page(), SIGNAL(windowCloseRequested()), this, SLOT(close())); + inspector = new WebInspector(splitter); + inspector->setPage(page); + inspector->hide(); + connect(this, SIGNAL(destroyed()), inspector, SLOT(deleteLater())); + setupUI(); - // set the proxy to the http_proxy env variable - if present - QUrl proxyUrl = view->guessUrlFromString(qgetenv("http_proxy")); + // set the proxy to the http_proxy env variable - if present + QUrl proxyUrl = urlFromUserInput(qgetenv("http_proxy")); + if (proxyUrl.isValid() && !proxyUrl.host().isEmpty()) { int proxyPort = (proxyUrl.port() > 0) ? proxyUrl.port() : 8080; page->networkAccessManager()->setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, proxyUrl.host(), proxyPort)); @@ -98,39 +205,47 @@ public: if (fi.exists() && fi.isRelative()) url = fi.absoluteFilePath(); - QUrl qurl = view->guessUrlFromString(url); + QUrl qurl = urlFromUserInput(url); + if (qurl.scheme().isEmpty()) + qurl = QUrl("http://" + url + "/"); if (qurl.isValid()) { urlEdit->setText(qurl.toEncoded()); view->load(qurl); - - // the zoom values are chosen to be like in Mozilla Firefox 3 - zoomLevels << 30 << 50 << 67 << 80 << 90; - zoomLevels << 100; - zoomLevels << 110 << 120 << 133 << 150 << 170 << 200 << 240 << 300; } + + // the zoom values are chosen to be like in Mozilla Firefox 3 + zoomLevels << 30 << 50 << 67 << 80 << 90; + zoomLevels << 100; + zoomLevels << 110 << 120 << 133 << 150 << 170 << 200 << 240 << 300; } - QWebPage* webPage() const { + QWebPage* webPage() const + { return view->page(); } - QWebView* webView() const { + QWebView* webView() const + { return view; } protected slots: - void changeLocation() { + void changeLocation() + { QString string = urlEdit->text(); - QUrl url = view->guessUrlFromString(string); - if (!url.isValid()) + QUrl url = urlFromUserInput(string); + if (url.scheme().isEmpty()) url = QUrl("http://" + string + "/"); - urlEdit->setText(url.toEncoded()); - view->load(url); - view->setFocus(Qt::OtherFocusReason); + if (url.isValid()) { + urlEdit->setText(url.toEncoded()); + view->load(url); + view->setFocus(Qt::OtherFocusReason); + } } - void loadFinished() { + void loadFinished() + { urlEdit->setText(view->url().toString()); QUrl::FormattingOptions opts; @@ -147,7 +262,8 @@ protected slots: urlModel.setStringList(urlList); } - void showLinkHover(const QString &link, const QString &toolTip) { + void showLinkHover(const QString &link, const QString &toolTip) + { statusBar()->showMessage(link); #ifndef QT_NO_TOOLTIP if (!toolTip.isEmpty()) @@ -155,22 +271,24 @@ protected slots: #endif } - void zoomIn() { + void zoomIn() + { int i = zoomLevels.indexOf(currentZoom); Q_ASSERT(i >= 0); if (i < zoomLevels.count() - 1) currentZoom = zoomLevels[i + 1]; - view->setZoomFactor(qreal(currentZoom)/100.0); + view->setZoomFactor(qreal(currentZoom) / 100.0); } - void zoomOut() { + void zoomOut() + { int i = zoomLevels.indexOf(currentZoom); Q_ASSERT(i >= 0); if (i > 0) currentZoom = zoomLevels[i - 1]; - view->setZoomFactor(qreal(currentZoom)/100.0); + view->setZoomFactor(qreal(currentZoom) / 100.0); } void resetZoom() @@ -184,8 +302,9 @@ protected slots: view->page()->settings()->setAttribute(QWebSettings::ZoomTextOnly, b); } - void print() { -#if QT_VERSION >= 0x040400 && !defined(QT_NO_PRINTER) + void print() + { +#if !defined(QT_NO_PRINTER) QPrintPreviewDialog dlg(this); connect(&dlg, SIGNAL(paintRequested(QPrinter *)), view, SLOT(print(QPrinter *))); @@ -193,21 +312,53 @@ protected slots: #endif } - void setEditable(bool on) { + void screenshot() + { + QPixmap pixmap = QPixmap::grabWidget(view); + QLabel* label = new QLabel; + label->setAttribute(Qt::WA_DeleteOnClose); + label->setWindowTitle("Screenshot - Preview"); + label->setPixmap(pixmap); + label->show(); + + QString fileName = QFileDialog::getSaveFileName(label, "Screenshot"); + if (!fileName.isEmpty()) { + pixmap.save(fileName, "png"); + label->setWindowTitle(QString("Screenshot - Saved at %1").arg(fileName)); + } + } + + void setEditable(bool on) + { view->page()->setContentEditable(on); formatMenuAction->setVisible(on); } - void dumpHtml() { + /* + void dumpPlugins() { + QList<QWebPluginInfo> plugins = QWebSettings::pluginDatabase()->plugins(); + foreach (const QWebPluginInfo plugin, plugins) { + qDebug() << "Plugin:" << plugin.name(); + foreach (const QWebPluginInfo::MimeType mime, plugin.mimeTypes()) { + qDebug() << " " << mime.name; + } + } + } + */ + + void dumpHtml() + { qDebug() << "HTML: " << view->page()->mainFrame()->toHtml(); } - void selectElements() { + void selectElements() + { bool ok; QString str = QInputDialog::getText(this, "Select elements", "Choose elements", QLineEdit::Normal, "a", &ok); + if (ok && !str.isEmpty()) { - QList<QWebElement> result = view->page()->mainFrame()->findAllElements(str); + QWebElementCollection result = view->page()->mainFrame()->findAllElements(str); foreach (QWebElement e, result) e.setStyleProperty("background-color", "yellow"); statusBar()->showMessage(QString("%1 element(s) selected").arg(result.count()), 5000); @@ -216,8 +367,9 @@ protected slots: public slots: - void newWindow(const QString &url = QString()) { - MainWindow *mw = new MainWindow(url); + void newWindow(const QString &url = QString()) + { + MainWindow* mw = new MainWindow(url); mw->show(); } @@ -227,7 +379,8 @@ private: int currentZoom; // create the status bar, tool bar & menu - void setupUI() { + void setupUI() + { progress = new QProgressBar(this); progress->setRange(0, 100); progress->setMinimumSize(100, 20); @@ -243,25 +396,24 @@ private: urlEdit->setSizePolicy(QSizePolicy::Expanding, urlEdit->sizePolicy().verticalPolicy()); connect(urlEdit, SIGNAL(returnPressed()), SLOT(changeLocation())); - QCompleter *completer = new QCompleter(this); + QCompleter* completer = new QCompleter(this); urlEdit->setCompleter(completer); completer->setModel(&urlModel); - QToolBar *bar = addToolBar("Navigation"); + QToolBar* bar = addToolBar("Navigation"); bar->addAction(view->pageAction(QWebPage::Back)); bar->addAction(view->pageAction(QWebPage::Forward)); bar->addAction(view->pageAction(QWebPage::Reload)); bar->addAction(view->pageAction(QWebPage::Stop)); bar->addWidget(urlEdit); - QMenu *fileMenu = menuBar()->addMenu("&File"); - QAction *newWindow = fileMenu->addAction("New Window", this, SLOT(newWindow())); -#if QT_VERSION >= 0x040400 - fileMenu->addAction(tr("Print"), this, SLOT(print())); -#endif + QMenu* fileMenu = menuBar()->addMenu("&File"); + QAction* newWindow = fileMenu->addAction("New Window", this, SLOT(newWindow())); + fileMenu->addAction(tr("Print"), this, SLOT(print()), QKeySequence::Print); + QAction* screenshot = fileMenu->addAction("Screenshot", this, SLOT(screenshot())); fileMenu->addAction("Close", this, SLOT(close())); - QMenu *editMenu = menuBar()->addMenu("&Edit"); + QMenu* editMenu = menuBar()->addMenu("&Edit"); editMenu->addAction(view->pageAction(QWebPage::Undo)); editMenu->addAction(view->pageAction(QWebPage::Redo)); editMenu->addSeparator(); @@ -269,34 +421,36 @@ private: editMenu->addAction(view->pageAction(QWebPage::Copy)); editMenu->addAction(view->pageAction(QWebPage::Paste)); editMenu->addSeparator(); - QAction *setEditable = editMenu->addAction("Set Editable", this, SLOT(setEditable(bool))); + QAction* setEditable = editMenu->addAction("Set Editable", this, SLOT(setEditable(bool))); setEditable->setCheckable(true); - QMenu *viewMenu = menuBar()->addMenu("&View"); + QMenu* viewMenu = menuBar()->addMenu("&View"); viewMenu->addAction(view->pageAction(QWebPage::Stop)); viewMenu->addAction(view->pageAction(QWebPage::Reload)); viewMenu->addSeparator(); - QAction *zoomIn = viewMenu->addAction("Zoom &In", this, SLOT(zoomIn())); - QAction *zoomOut = viewMenu->addAction("Zoom &Out", this, SLOT(zoomOut())); - QAction *resetZoom = viewMenu->addAction("Reset Zoom", this, SLOT(resetZoom())); - QAction *zoomTextOnly = viewMenu->addAction("Zoom Text Only", this, SLOT(toggleZoomTextOnly(bool))); + QAction* zoomIn = viewMenu->addAction("Zoom &In", this, SLOT(zoomIn())); + QAction* zoomOut = viewMenu->addAction("Zoom &Out", this, SLOT(zoomOut())); + QAction* resetZoom = viewMenu->addAction("Reset Zoom", this, SLOT(resetZoom())); + QAction* zoomTextOnly = viewMenu->addAction("Zoom Text Only", this, SLOT(toggleZoomTextOnly(bool))); zoomTextOnly->setCheckable(true); zoomTextOnly->setChecked(false); viewMenu->addSeparator(); viewMenu->addAction("Dump HTML", this, SLOT(dumpHtml())); + //viewMenu->addAction("Dump plugins", this, SLOT(dumpPlugins())); - QMenu *formatMenu = new QMenu("F&ormat"); + QMenu* formatMenu = new QMenu("F&ormat", this); formatMenuAction = menuBar()->addMenu(formatMenu); formatMenuAction->setVisible(false); formatMenu->addAction(view->pageAction(QWebPage::ToggleBold)); formatMenu->addAction(view->pageAction(QWebPage::ToggleItalic)); formatMenu->addAction(view->pageAction(QWebPage::ToggleUnderline)); - QMenu *writingMenu = formatMenu->addMenu(tr("Writing Direction")); + QMenu* writingMenu = formatMenu->addMenu(tr("Writing Direction")); writingMenu->addAction(view->pageAction(QWebPage::SetTextDirectionDefault)); writingMenu->addAction(view->pageAction(QWebPage::SetTextDirectionLeftToRight)); writingMenu->addAction(view->pageAction(QWebPage::SetTextDirectionRightToLeft)); newWindow->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_N)); + screenshot->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_S)); view->pageAction(QWebPage::Back)->setShortcut(QKeySequence::Back); view->pageAction(QWebPage::Stop)->setShortcut(Qt::Key_Escape); view->pageAction(QWebPage::Forward)->setShortcut(QKeySequence::Forward); @@ -313,29 +467,45 @@ private: view->pageAction(QWebPage::ToggleItalic)->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_I)); view->pageAction(QWebPage::ToggleUnderline)->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_U)); - QMenu *toolsMenu = menuBar()->addMenu("&Tools"); + QMenu* toolsMenu = menuBar()->addMenu("&Tools"); toolsMenu->addAction("Select elements...", this, SLOT(selectElements())); + QAction* showInspectorAction = toolsMenu->addAction("Show inspector", inspector, SLOT(setVisible(bool))); + showInspectorAction->setCheckable(true); + showInspectorAction->setShortcuts(QList<QKeySequence>() << QKeySequence(tr("F12"))); + showInspectorAction->connect(inspector, SIGNAL(visibleChanged(bool)), SLOT(setChecked(bool))); } - QWebView *view; - QLineEdit *urlEdit; - QProgressBar *progress; + QWebView* view; + QLineEdit* urlEdit; + QProgressBar* progress; + WebInspector* inspector; - QAction *formatMenuAction; + QAction* formatMenuAction; QStringList urlList; QStringListModel urlModel; }; -QWebPage *WebPage::createWindow(QWebPage::WebWindowType) +bool WebPage::extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output) +{ + const QWebPage::ErrorPageExtensionOption* info = static_cast<const QWebPage::ErrorPageExtensionOption*>(option); + QWebPage::ErrorPageExtensionReturn* errorPage = static_cast<QWebPage::ErrorPageExtensionReturn*>(output); + + errorPage->content = QString("<html><head><title>Failed loading page</title></head><body>%1</body></html>") + .arg(info->errorString).toUtf8(); + + return true; +} + +QWebPage* WebPage::createWindow(QWebPage::WebWindowType) { - MainWindow *mw = new MainWindow; + MainWindow* mw = new MainWindow; mw->show(); return mw->webPage(); } -QObject *WebPage::createPlugin(const QString &classId, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues) +QObject* WebPage::createPlugin(const QString &classId, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues) { Q_UNUSED(url); Q_UNUSED(paramNames); @@ -349,13 +519,13 @@ QObject *WebPage::createPlugin(const QString &classId, const QUrl &url, const QS #endif } -class URLLoader : public QObject -{ +class URLLoader : public QObject { Q_OBJECT public: URLLoader(QWebView* view, const QString& inputFileName) : m_view(view) , m_stdOut(stdout) + , m_loaded(0) { init(inputFileName); } @@ -367,7 +537,7 @@ public slots: if (getUrl(qstr)) { QUrl url(qstr, QUrl::StrictMode); if (url.isValid()) { - m_stdOut << "Loading " << qstr << " ......" << endl; + m_stdOut << "Loading " << qstr << " ......" << ++m_loaded << endl; m_view->load(url); } else loadNext(); @@ -410,6 +580,7 @@ private: int m_index; QWebView* m_view; QTextStream m_stdOut; + int m_loaded; }; #include "main.moc" @@ -429,19 +600,22 @@ int launcherMain(const QApplication& app) int main(int argc, char **argv) { QApplication app(argc, argv); - QString url = QString("%1/%2").arg(QDir::homePath()).arg(QLatin1String("index.html")); + QString defaultUrl = QString("file://%1/%2").arg(QDir::homePath()).arg(QLatin1String("index.html")); QWebSettings::setMaximumPagesInCache(4); app.setApplicationName("QtLauncher"); -#if QT_VERSION >= 0x040400 app.setApplicationVersion("0.1"); -#endif QWebSettings::setObjectCacheCapacities((16*1024*1024) / 8, (16*1024*1024) / 8, 16*1024*1024); QWebSettings::globalSettings()->setAttribute(QWebSettings::PluginsEnabled, true); QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true); + QWebSettings::enablePersistentStorage(); + + // To allow QWebInspector's configuration persistence + QCoreApplication::setOrganizationName("Nokia"); + QCoreApplication::setApplicationName("QtLauncher"); const QStringList args = app.arguments(); @@ -453,21 +627,28 @@ int main(int argc, char **argv) exit(0); } MainWindow* window = new MainWindow; - QWebView *view = window->webView(); + QWebView* view = window->webView(); URLLoader loader(view, listFile); QObject::connect(view, SIGNAL(loadFinished(bool)), &loader, SLOT(loadNext())); loader.loadNext(); window->show(); launcherMain(app); } else { - if (args.count() > 1) - url = args.at(1); - - MainWindow* window = new MainWindow(url); + MainWindow* window = 0; + + // Look though the args for something we can open + for (int i = 1; i < args.count(); i++) { + if (!args.at(i).startsWith("-")) { + if (!window) + window = new MainWindow(args.at(i)); + else + window->newWindow(args.at(i)); + } + } - // Opens every given urls in new windows - for (int i = 2; i < args.count(); i++) - window->newWindow(args.at(i)); + // If not, just open the default URL + if (!window) + window = new MainWindow(defaultUrl); window->show(); launcherMain(app); diff --git a/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp b/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp index d659833..eb7ac9a 100644 --- a/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp +++ b/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp @@ -39,12 +39,14 @@ #include "WindowFeatures.h" #include "DatabaseTracker.h" #include "SecurityOrigin.h" +#include "QWebPageClient.h" #include "qwebpage.h" #include "qwebpage_p.h" #include "qwebframe_p.h" #include "qwebsecurityorigin.h" #include "qwebsecurityorigin_p.h" +#include "qwebview.h" #include <qtooltip.h> #include <qtextdocument.h> @@ -139,6 +141,11 @@ void ChromeClientQt::takeFocus(FocusDirection) } +void ChromeClientQt::focusedNodeChanged(WebCore::Node*) +{ +} + + Page* ChromeClientQt::createWindow(Frame*, const FrameLoadRequest& request, const WindowFeatures& features) { QWebPage *newPage = m_webPage->createWindow(features.dialog ? QWebPage::WebModalDialog : QWebPage::WebBrowserWindow); @@ -303,16 +310,15 @@ IntRect ChromeClientQt::windowResizerRect() const return IntRect(); } -void ChromeClientQt::repaint(const IntRect& windowRect, bool contentChanged, bool immediate, bool repaintContentOnly) +void ChromeClientQt::repaint(const IntRect& windowRect, bool contentChanged, bool, bool) { // No double buffer, so only update the QWidget if content changed. if (contentChanged) { - QWidget* view = m_webPage->view(); - if (view) { + if (platformPageClient()) { QRect rect(windowRect); rect = rect.intersected(QRect(QPoint(0, 0), m_webPage->viewportSize())); if (!rect.isEmpty()) - view->update(rect); + platformPageClient()->update(rect); } emit m_webPage->repaintRequested(windowRect); } @@ -323,9 +329,8 @@ void ChromeClientQt::repaint(const IntRect& windowRect, bool contentChanged, boo void ChromeClientQt::scroll(const IntSize& delta, const IntRect& scrollViewRect, const IntRect&) { - QWidget* view = m_webPage->view(); - if (view) - view->scroll(delta.width(), delta.height(), scrollViewRect); + if (platformPageClient()) + platformPageClient()->scroll(delta.width(), delta.height(), scrollViewRect); emit m_webPage->scrollRequested(delta.width(), delta.height(), scrollViewRect); } @@ -341,9 +346,9 @@ IntPoint ChromeClientQt::screenToWindow(const IntPoint& point) const return point; } -PlatformWidget ChromeClientQt::platformWindow() const +PlatformPageClient ChromeClientQt::platformPageClient() const { - return m_webPage->view(); + return m_webPage->d->client; } void ChromeClientQt::contentsSizeChanged(Frame* frame, const IntSize& size) const @@ -351,7 +356,7 @@ void ChromeClientQt::contentsSizeChanged(Frame* frame, const IntSize& size) cons emit QWebFramePrivate::kit(frame)->contentsSizeChanged(size); } -void ChromeClientQt::mouseDidMoveOverElement(const HitTestResult& result, unsigned modifierFlags) +void ChromeClientQt::mouseDidMoveOverElement(const HitTestResult& result, unsigned) { TextDirection dir; if (result.absoluteLinkURL() != lastHoverURL @@ -402,7 +407,7 @@ void ChromeClientQt::exceededDatabaseQuota(Frame* frame, const String& databaseN #endif #if ENABLE(OFFLINE_WEB_APPLICATIONS) -void ChromeClientQt::reachedMaxAppCacheSize(int64_t spaceNeeded) +void ChromeClientQt::reachedMaxAppCacheSize(int64_t) { // FIXME: Free some space. notImplemented(); @@ -419,7 +424,7 @@ void ChromeClientQt::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> prpFileC option.parentFrame = QWebFramePrivate::kit(frame); if (!fileChooser->filenames().isEmpty()) - for (int i = 0; i < fileChooser->filenames().size(); ++i) + for (unsigned i = 0; i < fileChooser->filenames().size(); ++i) option.suggestedFileNames += fileChooser->filenames()[i]; QWebPage::ChooseMultipleFilesExtensionReturn output; diff --git a/WebKit/qt/WebCoreSupport/ChromeClientQt.h b/WebKit/qt/WebCoreSupport/ChromeClientQt.h index 96c7fab..939fe04 100644 --- a/WebKit/qt/WebCoreSupport/ChromeClientQt.h +++ b/WebKit/qt/WebCoreSupport/ChromeClientQt.h @@ -63,6 +63,8 @@ namespace WebCore { virtual bool canTakeFocus(FocusDirection); virtual void takeFocus(FocusDirection); + virtual void focusedNodeChanged(Node*); + virtual Page* createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures&); virtual void show(); @@ -105,9 +107,10 @@ namespace WebCore { virtual void scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect); virtual IntPoint screenToWindow(const IntPoint&) const; virtual IntRect windowToScreen(const IntRect&) const; - virtual PlatformWidget platformWindow() const; + virtual PlatformPageClient platformPageClient() const; virtual void contentsSizeChanged(Frame*, const IntSize&) const; + virtual void scrollbarsModeDidChange() const { } virtual void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags); virtual void setToolTip(const String&, TextDirection); diff --git a/WebKit/qt/WebCoreSupport/ContextMenuClientQt.cpp b/WebKit/qt/WebCoreSupport/ContextMenuClientQt.cpp index ed79946..b4400ff 100644 --- a/WebKit/qt/WebCoreSupport/ContextMenuClientQt.cpp +++ b/WebKit/qt/WebCoreSupport/ContextMenuClientQt.cpp @@ -52,7 +52,7 @@ void ContextMenuClientQt::contextMenuItemSelected(ContextMenuItem*, const Contex notImplemented(); } -void ContextMenuClientQt::downloadURL(const KURL& url) +void ContextMenuClientQt::downloadURL(const KURL&) { notImplemented(); } diff --git a/WebKit/qt/WebCoreSupport/DragClientQt.cpp b/WebKit/qt/WebCoreSupport/DragClientQt.cpp index 0df0768..99e438d 100644 --- a/WebKit/qt/WebCoreSupport/DragClientQt.cpp +++ b/WebKit/qt/WebCoreSupport/DragClientQt.cpp @@ -66,6 +66,8 @@ void DragClientQt::startDrag(DragImageRef, const IntPoint&, const IntPoint&, Cli QWidget* view = m_webPage->view(); if (view) { QDrag *drag = new QDrag(view); + if (clipboardData->hasImage()) + drag->setPixmap(qvariant_cast<QPixmap>(clipboardData->imageData())); drag->setMimeData(clipboardData); drag->start(); } diff --git a/WebKit/qt/WebCoreSupport/EditorClientQt.cpp b/WebKit/qt/WebCoreSupport/EditorClientQt.cpp index 995d61d..3091a43 100644 --- a/WebKit/qt/WebCoreSupport/EditorClientQt.cpp +++ b/WebKit/qt/WebCoreSupport/EditorClientQt.cpp @@ -41,12 +41,15 @@ #include "FocusController.h" #include "Frame.h" #include "HTMLElement.h" +#include "HTMLInputElement.h" +#include "HTMLNames.h" #include "KeyboardCodes.h" #include "KeyboardEvent.h" #include "NotImplemented.h" #include "Page.h" #include "Page.h" #include "PlatformKeyboardEvent.h" +#include "QWebPageClient.h" #include "Range.h" #include <stdio.h> @@ -96,6 +99,7 @@ static QString dumpRange(WebCore::Range *range) namespace WebCore { +using namespace HTMLNames; bool EditorClientQt::shouldDeleteRange(Range* range) { @@ -108,7 +112,7 @@ bool EditorClientQt::shouldDeleteRange(Range* range) bool EditorClientQt::shouldShowDeleteInterface(HTMLElement* element) { if (QWebPagePrivate::drtRun) - return element->className() == "needsDeletionUI"; + return element->getAttribute(classAttr) == "needsDeletionUI"; return false; } @@ -218,7 +222,9 @@ void EditorClientQt::respondToChangedSelection() m_page->d->updateEditorActions(); emit m_page->selectionChanged(); - emit m_page->microFocusChanged(); + Frame* frame = m_page->d->page->focusController()->focusedOrMainFrame(); + if (!frame->editor()->ignoreCompositionSelectionChange()) + emit m_page->microFocusChanged(); } void EditorClientQt::didEndEditing() @@ -401,28 +407,38 @@ void EditorClientQt::handleKeyboardEvent(KeyboardEvent* event) case VK_LEFT: if (kevent->shiftKey()) frame->editor()->command("MoveLeftAndModifySelection").execute(); - else frame->editor()->command("MoveLeft").execute(); + else + frame->editor()->command("MoveLeft").execute(); break; case VK_RIGHT: if (kevent->shiftKey()) frame->editor()->command("MoveRightAndModifySelection").execute(); - else frame->editor()->command("MoveRight").execute(); + else + frame->editor()->command("MoveRight").execute(); break; case VK_UP: if (kevent->shiftKey()) frame->editor()->command("MoveUpAndModifySelection").execute(); - else frame->editor()->command("MoveUp").execute(); + else + frame->editor()->command("MoveUp").execute(); break; case VK_DOWN: if (kevent->shiftKey()) frame->editor()->command("MoveDownAndModifySelection").execute(); - else frame->editor()->command("MoveDown").execute(); + else + frame->editor()->command("MoveDown").execute(); break; case VK_PRIOR: // PageUp - frame->editor()->command("MovePageUp").execute(); + if (kevent->shiftKey()) + frame->editor()->command("MovePageUpAndModifySelection").execute(); + else + frame->editor()->command("MovePageUp").execute(); break; case VK_NEXT: // PageDown - frame->editor()->command("MovePageDown").execute(); + if (kevent->shiftKey()) + frame->editor()->command("MovePageDownAndModifySelection").execute(); + else + frame->editor()->command("MovePageDown").execute(); break; case VK_TAB: return; @@ -592,11 +608,27 @@ bool EditorClientQt::isEditing() const void EditorClientQt::setInputMethodState(bool active) { - QWidget *view = m_page->view(); - if (view) { - view->setAttribute(Qt::WA_InputMethodEnabled, active); - emit m_page->microFocusChanged(); + QWebPageClient* webPageClient = m_page->d->client; + if (webPageClient) { +#if QT_VERSION >= 0x040600 + bool isPasswordField = false; + if (!active) { + // Setting the Qt::WA_InputMethodEnabled attribute true and Qt::ImhHiddenText flag + // for password fields. The Qt platform is responsible for determining which widget + // will receive input method events for password fields. + Frame* frame = m_page->d->page->focusController()->focusedOrMainFrame(); + if (frame && frame->document() && frame->document()->focusedNode()) { + if (frame->document()->focusedNode()->hasTagName(HTMLNames::inputTag)) { + HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(frame->document()->focusedNode()); + active = isPasswordField = inputElement->isPasswordField(); + } + } + } + webPageClient->setInputMethodHint(Qt::ImhHiddenText, isPasswordField); +#endif + webPageClient->setInputMethodEnabled(active); } + emit m_page->microFocusChanged(); } } diff --git a/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp b/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp index 5cf86b1..3c30ab5 100644 --- a/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp +++ b/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp @@ -1,9 +1,10 @@ /* * Copyright (C) 2006 Zack Rusin <zack@kde.org> * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. - * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) * Copyright (C) 2008 Collabora Ltd. All rights reserved. * Coypright (C) 2008 Holger Hans Peter Freyther + * Coypright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in> * * All rights reserved. * @@ -53,10 +54,13 @@ #include "QNetworkReplyHandler.h" #include "ResourceHandleInternal.h" #include "ResourceHandle.h" -#include "Settings.h" +#include "ScriptController.h" #include "ScriptString.h" +#include "Settings.h" +#include "QWebPageClient.h" #include "qwebpage.h" +#include "qwebpage_p.h" #include "qwebframe.h" #include "qwebframe_p.h" #include "qwebhistoryinterface.h" @@ -66,12 +70,10 @@ #include <QCoreApplication> #include <QDebug> -#if QT_VERSION >= 0x040400 +#include <QGraphicsScene> +#include <QGraphicsWidget> #include <QNetworkRequest> #include <QNetworkReply> -#else -#include "qwebnetworkinterface_p.h" -#endif #include "qwebhistory_p.h" static bool dumpFrameLoaderCallbacks = false; @@ -141,10 +143,10 @@ namespace WebCore FrameLoaderClientQt::FrameLoaderClientQt() : m_frame(0) , m_webFrame(0) + , m_firstData(false) , m_pluginView(0) , m_hasSentResponseToPlugin(false) - , m_firstData(false) - , m_loadSucceeded(false) + , m_loadError (ResourceError()) { } @@ -172,8 +174,8 @@ void FrameLoaderClientQt::setFrame(QWebFrame* webFrame, Frame* frame) m_webFrame->page(), SIGNAL(loadFinished(bool))); connect(this, SIGNAL(loadFinished(bool)), m_webFrame, SIGNAL(loadFinished(bool))); - connect(this, SIGNAL(titleChanged(const QString&)), - m_webFrame, SIGNAL(titleChanged(const QString&))); + connect(this, SIGNAL(titleChanged(QString)), + m_webFrame, SIGNAL(titleChanged(QString))); } QWebFrame* FrameLoaderClientQt::webFrame() const @@ -183,7 +185,7 @@ QWebFrame* FrameLoaderClientQt::webFrame() const void FrameLoaderClientQt::callPolicyFunction(FramePolicyFunction function, PolicyAction action) { - (m_frame->loader()->*function)(action); + (m_frame->loader()->policyChecker()->*function)(action); } bool FrameLoaderClientQt::hasWebView() const @@ -210,12 +212,12 @@ void FrameLoaderClientQt::transitionToCommittedForNewPage() QColor backgroundColor = brush.style() == Qt::SolidPattern ? brush.color() : QColor(); QWebPage* page = m_webFrame->page(); - const QSize fixedLayoutSize = page->fixedContentsSize(); + const QSize preferredLayoutSize = page->preferredContentsSize(); m_frame->createView(m_webFrame->page()->viewportSize(), backgroundColor, !backgroundColor.alpha(), - fixedLayoutSize.isValid() ? IntSize(fixedLayoutSize) : IntSize(), - fixedLayoutSize.isValid(), + preferredLayoutSize.isValid() ? IntSize(preferredLayoutSize) : IntSize(), + preferredLayoutSize.isValid(), (ScrollbarMode)m_webFrame->scrollBarPolicy(Qt::Horizontal), (ScrollbarMode)m_webFrame->scrollBarPolicy(Qt::Vertical)); } @@ -282,9 +284,7 @@ void FrameLoaderClientQt::dispatchDidCancelClientRedirect() } -void FrameLoaderClientQt::dispatchWillPerformClientRedirect(const KURL& url, - double interval, - double fireDate) +void FrameLoaderClientQt::dispatchWillPerformClientRedirect(const KURL& url, double, double) { if (dumpFrameLoaderCallbacks) printf("%s - willPerformClientRedirectToURL: %s \n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)), qPrintable(drtDescriptionSuitableForTestResult(url))); @@ -305,6 +305,29 @@ void FrameLoaderClientQt::dispatchDidChangeLocationWithinPage() m_webFrame->page()->d->updateNavigationActions(); } +void FrameLoaderClientQt::dispatchDidPushStateWithinPage() +{ + if (dumpFrameLoaderCallbacks) + printf("%s - dispatchDidPushStateWithinPage\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame))); + + notImplemented(); +} + +void FrameLoaderClientQt::dispatchDidReplaceStateWithinPage() +{ + if (dumpFrameLoaderCallbacks) + printf("%s - dispatchDidReplaceStateWithinPage\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame))); + + notImplemented(); +} + +void FrameLoaderClientQt::dispatchDidPopStateWithinPage() +{ + if (dumpFrameLoaderCallbacks) + printf("%s - dispatchDidPopStateWithinPage\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame))); + + notImplemented(); +} void FrameLoaderClientQt::dispatchWillClose() { @@ -376,7 +399,8 @@ void FrameLoaderClientQt::dispatchDidFinishLoad() if (dumpFrameLoaderCallbacks) printf("%s - didFinishLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame))); - m_loadSucceeded = true; + // Clears the previous error. + m_loadError = ResourceError(); if (!m_webFrame) return; @@ -430,6 +454,8 @@ void FrameLoaderClientQt::revertToProvisionalState(DocumentLoader*) void FrameLoaderClientQt::postProgressStartedNotification() { if (m_webFrame && m_frame->page()) { + // A new load starts, so lets clear the previous error. + m_loadError = ResourceError(); emit loadStarted(); postProgressEstimateChangedNotification(); } @@ -461,10 +487,10 @@ void FrameLoaderClientQt::postProgressFinishedNotification() } if (m_webFrame && m_frame->page()) - emit loadFinished(m_loadSucceeded); + emit loadFinished(m_loadError.isNull()); } -void FrameLoaderClientQt::setMainFrameDocumentReady(bool b) +void FrameLoaderClientQt::setMainFrameDocumentReady(bool) { // this is only interesting once we provide an external API for the DOM } @@ -514,13 +540,13 @@ bool FrameLoaderClientQt::canShowMIMEType(const String& MIMEType) const return false; } -bool FrameLoaderClientQt::representationExistsForURLScheme(const String& URLScheme) const +bool FrameLoaderClientQt::representationExistsForURLScheme(const String&) const { return false; } -String FrameLoaderClientQt::generatedMIMETypeForURLScheme(const String& URLScheme) const +String FrameLoaderClientQt::generatedMIMETypeForURLScheme(const String&) const { notImplemented(); return String(); @@ -595,8 +621,11 @@ bool FrameLoaderClientQt::canHandleRequest(const WebCore::ResourceRequest&) cons return true; } -void FrameLoaderClientQt::windowObjectCleared() +void FrameLoaderClientQt::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world) { + if (world != mainThreadNormalWorld()) + return; + if (dumpFrameLoaderCallbacks) printf("%s - didClearWindowObjectForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame))); @@ -632,11 +661,33 @@ void FrameLoaderClientQt::updateGlobalHistoryRedirectLinks() { } -bool FrameLoaderClientQt::shouldGoToHistoryItem(WebCore::HistoryItem *item) const +bool FrameLoaderClientQt::shouldGoToHistoryItem(WebCore::HistoryItem *) const { return true; } +void FrameLoaderClientQt::dispatchDidAddBackForwardItem(WebCore::HistoryItem*) const +{ +} + +void FrameLoaderClientQt::dispatchDidRemoveBackForwardItem(WebCore::HistoryItem*) const +{ +} + +void FrameLoaderClientQt::dispatchDidChangeBackForwardIndex() const +{ +} + +void FrameLoaderClientQt::didDisplayInsecureContent() +{ + notImplemented(); +} + +void FrameLoaderClientQt::didRunInsecureContent(WebCore::SecurityOrigin*) +{ + notImplemented(); +} + void FrameLoaderClientQt::saveViewStateToItem(WebCore::HistoryItem* item) { QWebHistoryItem historyItem(new QWebHistoryItemPrivate(item)); @@ -692,8 +743,10 @@ void FrameLoaderClientQt::committedLoad(WebCore::DocumentLoader* loader, const c WebCore::ResourceError FrameLoaderClientQt::cancelledError(const WebCore::ResourceRequest& request) { - return ResourceError("Error", -999, request.url().prettyURL(), + ResourceError error = ResourceError("QtNetwork", QNetworkReply::OperationCanceledError, request.url().prettyURL(), QCoreApplication::translate("QWebFrame", "Request cancelled", 0, QCoreApplication::UnicodeUTF8)); + error.setIsCancellation(true); + return error; } // copied from WebKit/Misc/WebKitErrors[Private].h @@ -709,36 +762,36 @@ enum { WebCore::ResourceError FrameLoaderClientQt::blockedError(const WebCore::ResourceRequest& request) { - return ResourceError("Error", WebKitErrorCannotUseRestrictedPort, request.url().prettyURL(), + return ResourceError("WebKit", WebKitErrorCannotUseRestrictedPort, request.url().prettyURL(), QCoreApplication::translate("QWebFrame", "Request blocked", 0, QCoreApplication::UnicodeUTF8)); } WebCore::ResourceError FrameLoaderClientQt::cannotShowURLError(const WebCore::ResourceRequest& request) { - return ResourceError("Error", WebKitErrorCannotShowURL, request.url().string(), + return ResourceError("WebKit", WebKitErrorCannotShowURL, request.url().string(), QCoreApplication::translate("QWebFrame", "Cannot show URL", 0, QCoreApplication::UnicodeUTF8)); } WebCore::ResourceError FrameLoaderClientQt::interruptForPolicyChangeError(const WebCore::ResourceRequest& request) { - return ResourceError("Error", WebKitErrorFrameLoadInterruptedByPolicyChange, request.url().string(), - QCoreApplication::translate("QWebFrame", "Frame load interruped by policy change", 0, QCoreApplication::UnicodeUTF8)); + return ResourceError("WebKit", WebKitErrorFrameLoadInterruptedByPolicyChange, request.url().string(), + QCoreApplication::translate("QWebFrame", "Frame load interrupted by policy change", 0, QCoreApplication::UnicodeUTF8)); } WebCore::ResourceError FrameLoaderClientQt::cannotShowMIMETypeError(const WebCore::ResourceResponse& response) { - return ResourceError("Error", WebKitErrorCannotShowMIMEType, response.url().string(), + return ResourceError("WebKit", WebKitErrorCannotShowMIMEType, response.url().string(), QCoreApplication::translate("QWebFrame", "Cannot show mimetype", 0, QCoreApplication::UnicodeUTF8)); } WebCore::ResourceError FrameLoaderClientQt::fileDoesNotExistError(const WebCore::ResourceResponse& response) { - return ResourceError("Error", -998 /* ### */, response.url().string(), + return ResourceError("QtNetwork", QNetworkReply::ContentNotFoundError, response.url().string(), QCoreApplication::translate("QWebFrame", "File does not exist", 0, QCoreApplication::UnicodeUTF8)); } -WebCore::ResourceError FrameLoaderClientQt::pluginWillHandleLoadError(const WebCore::ResourceResponse& response) +WebCore::ResourceError FrameLoaderClientQt::pluginWillHandleLoadError(const WebCore::ResourceResponse&) { notImplemented(); return ResourceError(); @@ -760,7 +813,6 @@ WTF::PassRefPtr<WebCore::DocumentLoader> FrameLoaderClientQt::createDocumentLoad void FrameLoaderClientQt::download(WebCore::ResourceHandle* handle, const WebCore::ResourceRequest&, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&) { -#if QT_VERSION >= 0x040400 if (!m_webFrame) return; @@ -773,10 +825,9 @@ void FrameLoaderClientQt::download(WebCore::ResourceHandle* handle, const WebCor else reply->abort(); } -#endif } -void FrameLoaderClientQt::assignIdentifierToInitialRequest(unsigned long identifier, WebCore::DocumentLoader* loader, const WebCore::ResourceRequest& request) +void FrameLoaderClientQt::assignIdentifierToInitialRequest(unsigned long identifier, WebCore::DocumentLoader*, const WebCore::ResourceRequest& request) { if (dumpResourceLoadCallbacks) dumpAssignedUrls[identifier] = drtDescriptionSuitableForTestResult(request.url()); @@ -823,7 +874,7 @@ void FrameLoaderClientQt::dispatchDidReceiveContentLength(WebCore::DocumentLoade { } -void FrameLoaderClientQt::dispatchDidFinishLoading(WebCore::DocumentLoader* loader, unsigned long) +void FrameLoaderClientQt::dispatchDidFinishLoading(WebCore::DocumentLoader*, unsigned long) { } @@ -850,20 +901,58 @@ void FrameLoaderClientQt::dispatchDidLoadResourceByXMLHttpRequest(unsigned long, notImplemented(); } -void FrameLoaderClientQt::dispatchDidFailProvisionalLoad(const WebCore::ResourceError&) +void FrameLoaderClientQt::callErrorPageExtension(const WebCore::ResourceError& error) +{ + QWebPage* page = m_webFrame->page(); + if (page->supportsExtension(QWebPage::ErrorPageExtension)) { + QWebPage::ErrorPageExtensionOption option; + + if (error.domain() == "QtNetwork") + option.domain = QWebPage::QtNetwork; + else if (error.domain() == "HTTP") + option.domain = QWebPage::Http; + else if (error.domain() == "WebKit") + option.domain = QWebPage::WebKit; + else + return; + + option.url = QUrl(error.failingURL()); + option.frame = m_webFrame; + option.error = error.errorCode(); + option.errorString = error.localizedDescription(); + + QWebPage::ErrorPageExtensionReturn output; + if (!page->extension(QWebPage::ErrorPageExtension, &option, &output)) + return; + + KURL baseUrl(output.baseUrl); + KURL failingUrl(option.url); + + WebCore::ResourceRequest request(baseUrl); + WTF::RefPtr<WebCore::SharedBuffer> buffer = WebCore::SharedBuffer::create(output.content.constData(), output.content.length()); + WebCore::SubstituteData substituteData(buffer, output.contentType, output.encoding, failingUrl); + m_frame->loader()->load(request, substituteData, false); + } +} + +void FrameLoaderClientQt::dispatchDidFailProvisionalLoad(const WebCore::ResourceError& error) { if (dumpFrameLoaderCallbacks) printf("%s - didFailProvisionalLoadWithError\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame))); - m_loadSucceeded = false; + m_loadError = error; + if (!error.isNull() && !error.isCancellation()) + callErrorPageExtension(error); } -void FrameLoaderClientQt::dispatchDidFailLoad(const WebCore::ResourceError&) +void FrameLoaderClientQt::dispatchDidFailLoad(const WebCore::ResourceError& error) { if (dumpFrameLoaderCallbacks) printf("%s - didFailLoadWithError\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame))); - m_loadSucceeded = false; + m_loadError = error; + if (!error.isNull() && !error.isCancellation()) + callErrorPageExtension(error); } WebCore::Frame* FrameLoaderClientQt::dispatchCreatePage() @@ -888,11 +977,7 @@ void FrameLoaderClientQt::dispatchDecidePolicyForMIMEType(FramePolicyFunction fu void FrameLoaderClientQt::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const WebCore::NavigationAction& action, const WebCore::ResourceRequest& request, PassRefPtr<WebCore::FormState>, const WebCore::String&) { Q_ASSERT(m_webFrame); -#if QT_VERSION < 0x040400 - QWebNetworkRequest r(request); -#else - QNetworkRequest r(request.toNetworkRequest()); -#endif + QNetworkRequest r(request.toNetworkRequest(m_webFrame)); QWebPage* page = m_webFrame->page(); if (!page->d->acceptNavigationRequest(0, r, QWebPage::NavigationType(action.type()))) { @@ -913,11 +998,7 @@ void FrameLoaderClientQt::dispatchDecidePolicyForNewWindowAction(FramePolicyFunc void FrameLoaderClientQt::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const WebCore::NavigationAction& action, const WebCore::ResourceRequest& request, PassRefPtr<WebCore::FormState>) { Q_ASSERT(m_webFrame); -#if QT_VERSION < 0x040400 - QWebNetworkRequest r(request); -#else - QNetworkRequest r(request.toNetworkRequest()); -#endif + QNetworkRequest r(request.toNetworkRequest(m_webFrame)); QWebPage*page = m_webFrame->page(); if (!page->d->acceptNavigationRequest(m_webFrame, r, QWebPage::NavigationType(action.type()))) { @@ -942,13 +1023,10 @@ void FrameLoaderClientQt::dispatchUnableToImplementPolicy(const WebCore::Resourc void FrameLoaderClientQt::startDownload(const WebCore::ResourceRequest& request) { -#if QT_VERSION >= 0x040400 if (!m_webFrame) return; - QWebPage *page = m_webFrame->page(); - emit m_webFrame->page()->downloadRequested(request.toNetworkRequest()); -#endif + emit m_webFrame->page()->downloadRequested(request.toNetworkRequest(m_webFrame)); } PassRefPtr<Frame> FrameLoaderClientQt::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, @@ -976,9 +1054,6 @@ PassRefPtr<Frame> FrameLoaderClientQt::createFrame(const KURL& url, const String // ### set override encoding if we have one - FrameLoadType loadType = m_frame->loader()->loadType(); - FrameLoadType childLoadType = FrameLoadTypeRedirectWithLockedBackForwardList; - frameData.frame->loader()->loadURLIntoChildFrame(frameData.url, frameData.referrer, frameData.frame.get()); // The frame's onload handler may have removed it from the document. @@ -1068,11 +1143,74 @@ public: QRegion clipRegion = QRegion(clipRect); platformWidget()->setMask(clipRegion); + handleVisibility(); + } + + virtual void show() + { + Widget::show(); + handleVisibility(); + } + +private: + void handleVisibility() + { + if (!isVisible()) + return; + // if setMask is set with an empty QRegion, no clipping will // be performed, so in that case we hide the platformWidget - platformWidget()->setVisible(!clipRegion.isEmpty()); + QRegion mask = platformWidget()->mask(); + platformWidget()->setVisible(!mask.isEmpty()); + } +}; + +#if QT_VERSION >= 0x040600 +class QtPluginGraphicsWidget: public Widget +{ +public: + static RefPtr<QtPluginGraphicsWidget> create(QGraphicsWidget* w = 0) + { + return adoptRef(new QtPluginGraphicsWidget(w)); + } + + ~QtPluginGraphicsWidget() + { + if (graphicsWidget) + graphicsWidget->deleteLater(); + } + virtual void invalidateRect(const IntRect& r) + { + QGraphicsScene* scene = graphicsWidget ? graphicsWidget->scene() : 0; + if (scene) + scene->update(QRect(r)); + } + virtual void frameRectsChanged() + { + if (!graphicsWidget) + return; + + IntRect windowRect = convertToContainingWindow(IntRect(0, 0, frameRect().width(), frameRect().height())); + graphicsWidget->setGeometry(QRect(windowRect)); + + // FIXME: clipping of graphics widgets + } + virtual void show() + { + if (graphicsWidget) + graphicsWidget->show(); + } + virtual void hide() + { + if (graphicsWidget) + graphicsWidget->hide(); } +private: + QtPluginGraphicsWidget(QGraphicsWidget* w = 0): Widget(0), graphicsWidget(w) {} + + QGraphicsWidget* graphicsWidget; }; +#endif PassRefPtr<Widget> FrameLoaderClientQt::createPlugin(const IntSize& pluginSize, HTMLPlugInElement* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually) @@ -1087,12 +1225,12 @@ PassRefPtr<Widget> FrameLoaderClientQt::createPlugin(const IntSize& pluginSize, QStringList values; QString classid(element->getAttribute("classid")); - for (int i = 0; i < paramNames.size(); ++i) { + for (unsigned i = 0; i < paramNames.size(); ++i) { params.append(paramNames[i]); if (paramNames[i] == "classid") classid = paramValues[i]; } - for (int i = 0; i < paramValues.size(); ++i) + for (unsigned i = 0; i < paramValues.size(); ++i) values.append(paramValues[i]); QString urlStr(url.string()); @@ -1110,7 +1248,7 @@ PassRefPtr<Widget> FrameLoaderClientQt::createPlugin(const IntSize& pluginSize, if (!styleSheet.isEmpty()) styleSheet += QLatin1Char(';'); - for (int i = 0; i < numqStyleSheetProperties; ++i) { + for (unsigned i = 0; i < numqStyleSheetProperties; ++i) { CSSPropertyID property = qstyleSheetProperties[i]; styleSheet += QString::fromLatin1(::getPropertyName(property)); @@ -1124,31 +1262,62 @@ PassRefPtr<Widget> FrameLoaderClientQt::createPlugin(const IntSize& pluginSize, #endif // QT_NO_STYLE_STYLESHEET } -#if QT_VERSION >= 0x040400 if (!object) { QWebPluginFactory* factory = m_webFrame->page()->pluginFactory(); if (factory) object = factory->create(mimeType, qurl, params, values); } -#endif if (object) { QWidget* widget = qobject_cast<QWidget*>(object); if (widget) { - QWidget* view = m_webFrame->page()->view(); - if (view) - widget->setParent(view); + QWidget* parentWidget = 0; + if (m_webFrame->page()->d->client) + parentWidget = qobject_cast<QWidget*>(m_webFrame->page()->d->client->pluginParent()); + if (parentWidget) // don't reparent to nothing (i.e. keep whatever parent QWebPage::createPlugin() chose. + widget->setParent(parentWidget); + widget->hide(); RefPtr<QtPluginWidget> w = adoptRef(new QtPluginWidget()); w->setPlatformWidget(widget); // Make sure it's invisible until properly placed into the layout w->setFrameRect(IntRect(0, 0, 0, 0)); return w; } +#if QT_VERSION >= 0x040600 + QGraphicsWidget* graphicsWidget = qobject_cast<QGraphicsWidget*>(object); + if (graphicsWidget) { + QGraphicsObject* parentWidget = 0; + if (m_webFrame->page()->d->client) + parentWidget = qobject_cast<QGraphicsObject*>(m_webFrame->page()->d->client->pluginParent()); + graphicsWidget->hide(); + if (parentWidget) // don't reparent to nothing (i.e. keep whatever parent QWebPage::createPlugin() chose. + graphicsWidget->setParentItem(parentWidget); + RefPtr<QtPluginGraphicsWidget> w = QtPluginGraphicsWidget::create(graphicsWidget); + // Make sure it's invisible until properly placed into the layout + w->setFrameRect(IntRect(0, 0, 0, 0)); + return w; + } +#endif // FIXME: make things work for widgetless plugins as well delete object; } else { // NPAPI Plugins + Vector<String> params = paramNames; + Vector<String> values = paramValues; + if (mimeType == "application/x-shockwave-flash") { + QWebPageClient* client = m_webFrame->page()->d->client; + if (!client || !qobject_cast<QWidget*>(client->pluginParent())) { + // inject wmode=opaque when there is no client or the client is not a QWebView + size_t wmodeIndex = params.find("wmode"); + if (wmodeIndex == -1) { + params.append("wmode"); + values.append("opaque"); + } else + values[wmodeIndex] = "opaque"; + } + } + RefPtr<PluginView> pluginView = PluginView::create(m_frame, pluginSize, element, url, - paramNames, paramValues, mimeType, loadManually); + params, values, mimeType, loadManually); return pluginView; } @@ -1162,8 +1331,8 @@ void FrameLoaderClientQt::redirectDataToPlugin(Widget* pluginWidget) m_hasSentResponseToPlugin = false; } -PassRefPtr<Widget> FrameLoaderClientQt::createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const KURL& baseURL, - const Vector<String>& paramNames, const Vector<String>& paramValues) +PassRefPtr<Widget> FrameLoaderClientQt::createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const KURL&, + const Vector<String>&, const Vector<String>&) { notImplemented(); return 0; diff --git a/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h b/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h index 754d8bc..32b9caa 100644 --- a/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h +++ b/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h @@ -59,6 +59,7 @@ namespace WebCore { friend class ::QWebFrame; void callPolicyFunction(FramePolicyFunction function, PolicyAction action); + void callErrorPageExtension(const ResourceError&); signals: void loadStarted(); void loadProgress(int d); @@ -102,6 +103,9 @@ namespace WebCore { virtual void dispatchDidCancelClientRedirect(); virtual void dispatchWillPerformClientRedirect(const KURL&, double interval, double fireDate); virtual void dispatchDidChangeLocationWithinPage(); + virtual void dispatchDidPushStateWithinPage(); + virtual void dispatchDidReplaceStateWithinPage(); + virtual void dispatchDidPopStateWithinPage(); virtual void dispatchWillClose(); virtual void dispatchDidReceiveIcon(); virtual void dispatchDidStartProvisionalLoad(); @@ -147,6 +151,11 @@ namespace WebCore { virtual void updateGlobalHistory(); virtual void updateGlobalHistoryRedirectLinks(); virtual bool shouldGoToHistoryItem(HistoryItem*) const; + virtual void dispatchDidAddBackForwardItem(HistoryItem*) const; + virtual void dispatchDidRemoveBackForwardItem(HistoryItem*) const; + virtual void dispatchDidChangeBackForwardIndex() const; + virtual void didDisplayInsecureContent(); + virtual void didRunInsecureContent(SecurityOrigin*); virtual ResourceError cancelledError(const ResourceRequest&); virtual ResourceError blockedError(const ResourceRequest&); @@ -193,7 +202,7 @@ namespace WebCore { virtual ObjectContentType objectContentType(const KURL& url, const String& mimeType); virtual String overrideMediaType() const; - virtual void windowObjectCleared(); + virtual void dispatchDidClearWindowObjectInWorld(DOMWrapperWorld*); virtual void documentElementAvailable(); virtual void didPerformFirstNavigation() const; @@ -211,7 +220,7 @@ namespace WebCore { WebCore::PluginView* m_pluginView; bool m_hasSentResponseToPlugin; - bool m_loadSucceeded; + ResourceError m_loadError; }; } diff --git a/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp b/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp index d7f03d1..d5683c4 100644 --- a/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp +++ b/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp @@ -31,10 +31,13 @@ #include "config.h" #include "InspectorClientQt.h" +#include "qwebinspector.h" +#include "qwebinspector_p.h" #include "qwebpage.h" #include "qwebpage_p.h" #include "qwebview.h" +#include <QtCore/QSettings> #include <QtCore/QCoreApplication> #include "InspectorController.h" @@ -44,49 +47,32 @@ namespace WebCore { -class InspectorClientWebPage : public QWebPage -{ - Q_OBJECT - friend class InspectorClientQt; -public: - QWebPage* createWindow(QWebPage::WebWindowType) - { - QWidget *w = new QWebView(0); - QWebPage *page = new QWebPage(w); - page->setView(w); - connect(page, SIGNAL(destroyed()), w, SLOT(deleteLater())); - return page; - } - -Q_SIGNALS: - void attachRequested(); - void detachRequested(); -}; +static const QLatin1String settingStoragePrefix("Qt/QtWebKit/QWebInspector/"); +static const QLatin1String settingStorageTypeSuffix(".type"); +static String variantToSetting(const QVariant& qvariant); +static QVariant settingToVariant(const String& value); -class InspectorClientView : public QWebView { +class InspectorClientWebPage : public QWebPage { + Q_OBJECT + friend class InspectorClientQt; public: - InspectorClientView(InspectorController* controller) - : QWebView(0) - , m_controller(controller) + InspectorClientWebPage(QObject* parent = 0) + : QWebPage(parent) { - setPage(new InspectorClientWebPage); - connect(page(), SIGNAL(destroyed()), SLOT(deleteLater())); + settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, false); } -protected: - - void closeEvent(QCloseEvent* ev) + QWebPage* createWindow(QWebPage::WebWindowType) { - QWidget::closeEvent(ev); - m_controller->setWindowVisible(false); + QWebView* view = new QWebView; + QWebPage* page = new QWebPage; + view->setPage(page); + view->setAttribute(Qt::WA_DeleteOnClose); + return page; } - -private: - InspectorController* m_controller; }; - InspectorClientQt::InspectorClientQt(QWebPage* page) : m_inspectedWebPage(page) {} @@ -98,14 +84,16 @@ void InspectorClientQt::inspectorDestroyed() Page* InspectorClientQt::createPage() { - if (m_webPage) - return m_webPage->d->page; + QWebView* inspectorView = new QWebView; + InspectorClientWebPage* inspectorPage = new InspectorClientWebPage(inspectorView); + inspectorView->setPage(inspectorPage); + m_inspectorView.set(inspectorView); + + inspectorPage->mainFrame()->load(QString::fromLatin1("qrc:/webkit/inspector/inspector.html")); + m_inspectedWebPage->d->inspectorFrontend = inspectorView; + m_inspectedWebPage->d->getOrCreateInspector()->d->setFrontend(inspectorView); - InspectorClientView* view = new InspectorClientView(m_inspectedWebPage->d->page->inspectorController()); - m_webPage.set(qobject_cast<InspectorClientWebPage*>(view->page())); - m_webPage->mainFrame()->load(QString::fromLatin1("qrc:/webkit/inspector/inspector.html")); - m_webPage->view()->setMinimumSize(400,300); - return m_webPage->d->page; + return m_inspectorView->page()->d->page; } String InspectorClientQt::localizedStringsURL() @@ -122,52 +110,32 @@ String InspectorClientQt::hiddenPanels() void InspectorClientQt::showWindow() { - if (!m_webPage) - return; - updateWindowTitle(); - m_webPage->view()->show(); - m_inspectedWebPage->d->page->inspectorController()->setWindowVisible(true); -} - -void InspectorClientQt::closeWindow() -{ - if (!m_webPage) - return; - m_webPage->view()->hide(); - m_inspectedWebPage->d->page->inspectorController()->setWindowVisible(false); + m_inspectedWebPage->d->inspectorController()->setWindowVisible(true, true); } -bool InspectorClientQt::windowVisible() +void InspectorClientQt::closeWindow() { - if (!m_webPage) - return false; - return m_webPage->view()->isVisible(); + m_inspectedWebPage->d->inspectorController()->setWindowVisible(false); } void InspectorClientQt::attachWindow() { - if (!m_webPage) - return; - - emit m_webPage->attachRequested(); + notImplemented(); } void InspectorClientQt::detachWindow() { - if (!m_webPage) - return; - - emit m_webPage->detachRequested(); + notImplemented(); } -void InspectorClientQt::setAttachedWindowHeight(unsigned height) +void InspectorClientQt::setAttachedWindowHeight(unsigned) { notImplemented(); } -void InspectorClientQt::highlight(Node* node) +void InspectorClientQt::highlight(Node*) { notImplemented(); } @@ -190,26 +158,63 @@ void InspectorClientQt::inspectorWindowObjectCleared() void InspectorClientQt::updateWindowTitle() { - if (!m_webPage) + if (m_inspectedWebPage->d->inspector) { + QString caption = QCoreApplication::translate("QWebPage", "Web Inspector - %2").arg(m_inspectedURL); + m_inspectedWebPage->d->inspector->setWindowTitle(caption); + } +} + +void InspectorClientQt::populateSetting(const String& key, String* setting) +{ + QSettings qsettings; + if (qsettings.status() == QSettings::AccessError) { + // QCoreApplication::setOrganizationName and QCoreApplication::setApplicationName haven't been called + qWarning("QWebInspector: QSettings couldn't read configuration setting [%s].", + qPrintable(static_cast<QString>(key))); return; + } - QString caption = QCoreApplication::translate("QWebPage", "Web Inspector - %2"); - m_webPage->view()->setWindowTitle(caption.arg(m_inspectedURL)); + QString settingKey(settingStoragePrefix + key); + QString storedValueType = qsettings.value(settingKey + settingStorageTypeSuffix).toString(); + QVariant storedValue = qsettings.value(settingKey); + storedValue.convert(QVariant::nameToType(storedValueType.toAscii().data())); + *setting = variantToSetting(storedValue); } -void InspectorClientQt::populateSetting(const String& key, InspectorController::Setting& setting) +void InspectorClientQt::storeSetting(const String& key, const String& setting) { - notImplemented(); + QSettings qsettings; + if (qsettings.status() == QSettings::AccessError) { + qWarning("QWebInspector: QSettings couldn't persist configuration setting [%s].", + qPrintable(static_cast<QString>(key))); + return; + } + + QVariant valueToStore = settingToVariant(setting); + QString settingKey(settingStoragePrefix + key); + qsettings.setValue(settingKey, valueToStore); + qsettings.setValue(settingKey + settingStorageTypeSuffix, QVariant::typeToName(valueToStore.type())); } -void InspectorClientQt::storeSetting(const String& key, const InspectorController::Setting& setting) +static String variantToSetting(const QVariant& qvariant) { - notImplemented(); + String retVal; + + switch (qvariant.type()) { + case QVariant::Bool: + retVal = qvariant.toBool() ? "true" : "false"; + case QVariant::String: + retVal = qvariant.toString(); + } + + return retVal; } -void InspectorClientQt::removeSetting(const String& key) +static QVariant settingToVariant(const String& setting) { - notImplemented(); + QVariant retVal; + retVal.setValue(static_cast<QString>(setting)); + return retVal; } } diff --git a/WebKit/qt/WebCoreSupport/InspectorClientQt.h b/WebKit/qt/WebCoreSupport/InspectorClientQt.h index 03c684a..923bab4 100644 --- a/WebKit/qt/WebCoreSupport/InspectorClientQt.h +++ b/WebKit/qt/WebCoreSupport/InspectorClientQt.h @@ -35,12 +35,12 @@ #include <QtCore/QString> class QWebPage; +class QWebView; namespace WebCore { class Node; class Page; class String; - class InspectorClientWebPage; class InspectorClientQt : public InspectorClient { public: @@ -56,7 +56,6 @@ namespace WebCore { virtual void showWindow(); virtual void closeWindow(); - virtual bool windowVisible(); virtual void attachWindow(); virtual void detachWindow(); @@ -67,16 +66,15 @@ namespace WebCore { virtual void hideHighlight(); virtual void inspectedURLChanged(const String& newURL); - virtual void populateSetting(const String& key, InspectorController::Setting&); - virtual void storeSetting(const String& key, const InspectorController::Setting&); - virtual void removeSetting(const String& key); + virtual void populateSetting(const String& key, String* value); + virtual void storeSetting(const String& key, const String& value); virtual void inspectorWindowObjectCleared(); private: void updateWindowTitle(); QWebPage* m_inspectedWebPage; - OwnPtr<InspectorClientWebPage> m_webPage; + OwnPtr<QWebView> m_inspectorView; QString m_inspectedURL; }; } diff --git a/WebKit/qt/docs/docs.pri b/WebKit/qt/docs/docs.pri index 4a8c165..804817b 100644 --- a/WebKit/qt/docs/docs.pri +++ b/WebKit/qt/docs/docs.pri @@ -1,9 +1,9 @@ include(../../../WebKit.pri) unix { - QDOC = SRCDIR=$$PWD/../../.. OUTPUT_DIR=$$OUTPUT_DIR $$(QTDIR)/tools/qdoc3/qdoc3 + QDOC = SRCDIR=$$PWD/../../.. OUTPUT_DIR=$$OUTPUT_DIR $$(QTDIR)/bin/qdoc3 } else { - QDOC = $$(QTDIR)\tools\qdoc3\release\qdoc3.exe + QDOC = $$(QTDIR)\bin\qdoc3.exe } unix { diff --git a/WebKit/qt/docs/qtwebkit.qdoc b/WebKit/qt/docs/qtwebkit.qdoc index f3681ee..411762a 100644 --- a/WebKit/qt/docs/qtwebkit.qdoc +++ b/WebKit/qt/docs/qtwebkit.qdoc @@ -1,18 +1,67 @@ /*! \module QtWebKit \title QtWebKit Module - \contentspage Qt's Modules + \contentspage All Qt Modules \previouspage QtSvg \nextpage QtXml - \ingroup architecture \ingroup modules - \brief An introduction to the QtWebKit module. + \brief The QtWebKit module provides a web browser engine as well as + classes to render and interact with web content. - \keyword Browser - \keyword Web Browser + To include the definitions of the module's classes, use the + following directive: + + \snippet webkitsnippets/qtwebkit_build_snippet.qdoc 1 + + To link against the module, add this line to your \l qmake \c + .pro file: + + \snippet webkitsnippets/qtwebkit_build_snippet.qdoc 0 + + \section1 License Information + + This is a snapshot of the Qt port of WebKit. The exact version information + can be found in the \c{src/3rdparty/webkit/VERSION} file supplied with Qt. + + Qt Commercial Edition licensees that wish to distribute applications that + use the QtWebKit module need to be aware of their obligations under the + GNU Library General Public License (LGPL). + + Developers using the Open Source Edition can choose to redistribute + the module under the appropriate version of the GNU LGPL. + + \legalese + WebKit is licensed under the GNU Library General Public License. + Individual contributor names and copyright dates can be found + inline in the code. + + 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. + \endlegalese +*/ + +/*! + \page webintegration.html + \title Integrating Web Content with QtWebKit \since 4.4 + \ingroup frameworks-technologies + + \keyword Browser + \keyword Web Browser + QtWebKit provides a Web browser engine that makes it easy to embed content from the World Wide Web into your Qt application. At the same time Web content can be enhanced with native controls. @@ -55,20 +104,6 @@ \tableofcontents - \section1 Configuring the Build Process - - Applications using QtWebKit's classes need to be configured to be built - against the QtWebKit module. The following declaration in a \c qmake - project file ensures that an application is compiled and linked - appropriately: - - \snippet webkitsnippets/qtwebkit_build_snippet.qdoc 0 - - To include the definitions of the module's classes, use the following - directive: - - \snippet webkitsnippets/qtwebkit_build_snippet.qdoc 1 - \section1 Architecture The easiest way to render content is through the QWebView class. As a @@ -101,15 +136,18 @@ \section1 Netscape Plugin Support + \note Netscape plugin support is only available on desktop platforms. + Since WebKit supports the Netscape Plugin API, Qt applications can display - Web pages that embed common plugins, as long as the user has the appropriate + Web pages that embed common plugins on platforms for which those plugins + are available. To enable plugin support, the user must have the appropriate binary files for those plugins installed and the \l{QWebSettings::PluginsEnabled} - attribute is enabled for the application. + attribute must be enabled for the application. The following locations are searched for plugins: \table - \header \o Linux/Unix \o Windows + \header \o Linux/Unix (X11) \o Windows \row \o{1,3} \list \o \c{.mozilla/plugins} in the user's home directory @@ -158,40 +196,4 @@ \o The system \c{/Library/Internet Plug-Ins} directory \endlist \endtable - - \section1 License Information - - This is a snapshot of the Qt port of WebKit. The exact version information - can be found in the \c{src/3rdparty/webkit/VERSION} file supplied with Qt. - - Qt Commercial Edition licensees that wish to distribute applications that - use the QtWebKit module need to be aware of their obligations under the - GNU Lesser General Public License (LGPL). - - Developers using the Open Source Edition can choose to redistribute - the module under the appropriate version of the GNU LGPL; version 2.1 - for applications and libraries licensed under the GNU GPL version 2, - or version 3 for applications and libraries licensed under the GNU - GPL version 2. - - \legalese - WebKit is licensed under the GNU Library General Public License. - Individual contributor names and copyright dates can be found - inline in the code. - - 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. - \endlegalese */ diff --git a/WebKit/qt/docs/webkitsnippets/qtwebkit_qwebinspector_snippet.cpp b/WebKit/qt/docs/webkitsnippets/qtwebkit_qwebinspector_snippet.cpp new file mode 100644 index 0000000..a6b6620 --- /dev/null +++ b/WebKit/qt/docs/webkitsnippets/qtwebkit_qwebinspector_snippet.cpp @@ -0,0 +1,17 @@ + +void wrapInFunction() +{ + +//! [0] + // ... + QWebPage *page = new QWebPage; + // ... + + QWebInspector *inspector = new QWebInspector; + inspector->setPage(page); + + connect(page, SIGNAL(webInspectorTriggered(QWebElement)), inspector, SLOT(show())); +//! [0] + +} + diff --git a/WebKit/qt/docs/webkitsnippets/simple/main.cpp b/WebKit/qt/docs/webkitsnippets/simple/main.cpp index 82f5b6c..408630e 100644 --- a/WebKit/qt/docs/webkitsnippets/simple/main.cpp +++ b/WebKit/qt/docs/webkitsnippets/simple/main.cpp @@ -27,7 +27,7 @@ int main(int argc, char *argv[]) QWidget *parent = 0; //! [Using QWebView] QWebView *view = new QWebView(parent); - view->load(QUrl("http://qtsoftware.com/")); + view->load(QUrl("http://qt.nokia.com/")); view->show(); //! [Using QWebView] return app.exec(); diff --git a/WebKit/qt/docs/webkitsnippets/webelement/main.cpp b/WebKit/qt/docs/webkitsnippets/webelement/main.cpp index d437a6f..2707ffb 100644 --- a/WebKit/qt/docs/webkitsnippets/webelement/main.cpp +++ b/WebKit/qt/docs/webkitsnippets/webelement/main.cpp @@ -22,7 +22,6 @@ #include <qwebview.h> #include <qwebframe.h> #include <qwebelement.h> -#include <qdebug.h> static QWebFrame *frame; @@ -53,9 +52,10 @@ static void findAll() </p> */ +//! [FindAll intro] QList<QWebElement> allSpans = document.findAll("span"); QList<QWebElement> introSpans = document.findAll("p.intro span"); -//! [FindAll] +//! [FindAll intro] //! [FindAll] } int main(int argc, char *argv[]) diff --git a/WebKit/qt/docs/webkitsnippets/webelement/webelement.pro b/WebKit/qt/docs/webkitsnippets/webelement/webelement.pro index f9b403b..8ca4b59 100644 --- a/WebKit/qt/docs/webkitsnippets/webelement/webelement.pro +++ b/WebKit/qt/docs/webkitsnippets/webelement/webelement.pro @@ -1,5 +1,8 @@ TEMPLATE = app CONFIG -= app_bundle +CONFIG(QTDIR_build) { + QT += webkit +} SOURCES = main.cpp include(../../../../../WebKit.pri) QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR diff --git a/WebKit/qt/docs/webkitsnippets/webpage/main.cpp b/WebKit/qt/docs/webkitsnippets/webpage/main.cpp index b91bc30..393b16a 100644 --- a/WebKit/qt/docs/webkitsnippets/webpage/main.cpp +++ b/WebKit/qt/docs/webkitsnippets/webpage/main.cpp @@ -45,7 +45,7 @@ int main(int argc, char *argv[]) { QApplication app(argc, argv); - Thumbnailer thumbnail(QUrl("http://qtsoftware.com")); + Thumbnailer thumbnail(QUrl("http://qt.nokia.com")); QObject::connect(&thumbnail, SIGNAL(finished()), &app, SLOT(quit())); diff --git a/WebKit/qt/tests/benchmarks/loading/tst_loading.pro b/WebKit/qt/tests/benchmarks/loading/tst_loading.pro index af0387e..bc5e75f 100644 --- a/WebKit/qt/tests/benchmarks/loading/tst_loading.pro +++ b/WebKit/qt/tests/benchmarks/loading/tst_loading.pro @@ -4,3 +4,8 @@ include(../../../../../WebKit.pri) SOURCES += tst_loading.cpp QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR + +symbian { + TARGET.UID3 = 0xA000E541 + TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices +} diff --git a/WebKit/qt/tests/benchmarks/painting/tst_painting.pro b/WebKit/qt/tests/benchmarks/painting/tst_painting.pro index 496210e..48c7072 100644 --- a/WebKit/qt/tests/benchmarks/painting/tst_painting.pro +++ b/WebKit/qt/tests/benchmarks/painting/tst_painting.pro @@ -4,3 +4,8 @@ include(../../../../../WebKit.pri) SOURCES += tst_painting.cpp QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR + +symbian { + TARGET.UID3 = 0xA000E542 + TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices +} diff --git a/WebKit/qt/tests/qgraphicswebview/qgraphicswebview.pro b/WebKit/qt/tests/qgraphicswebview/qgraphicswebview.pro new file mode 100644 index 0000000..57b4437 --- /dev/null +++ b/WebKit/qt/tests/qgraphicswebview/qgraphicswebview.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = tst_qgraphicswebview +include(../../../../WebKit.pri) +SOURCES += tst_qgraphicswebview.cpp +QT += testlib network +QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR + +symbian { + TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices +} diff --git a/WebKit/qt/tests/qgraphicswebview/tst_qgraphicswebview.cpp b/WebKit/qt/tests/qgraphicswebview/tst_qgraphicswebview.cpp new file mode 100644 index 0000000..657e09f --- /dev/null +++ b/WebKit/qt/tests/qgraphicswebview/tst_qgraphicswebview.cpp @@ -0,0 +1,107 @@ +/* + Copyright (C) 2009 Jakub Wieczorek <faw217@gmail.com> + + 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 "../util.h" +#include <QtTest/QtTest> +#include <QGraphicsView> +#include <qgraphicswebview.h> +#include <qwebpage.h> +#include <qwebframe.h> + +class tst_QGraphicsWebView : public QObject +{ + Q_OBJECT + +private slots: + void qgraphicswebview(); + void crashOnViewlessWebPages(); +}; + +void tst_QGraphicsWebView::qgraphicswebview() +{ + QGraphicsWebView item; + item.url(); + item.title(); + item.icon(); + item.zoomFactor(); + item.history(); + item.settings(); + item.page(); + item.setPage(0); + item.page(); + item.setUrl(QUrl()); + item.setZoomFactor(0); + item.load(QUrl()); + item.setHtml(QString()); + item.setContent(QByteArray()); + item.isModified(); +} + +class WebPage : public QWebPage +{ + Q_OBJECT + +public: + WebPage(QObject* parent = 0): QWebPage(parent) + { + } + + QGraphicsWebView* webView; + +private slots: + // Force a webview deletion during the load. + // It should not cause WebPage to crash due to + // it accessing invalid pageClient pointer. + void aborting() + { + delete webView; + } +}; + +void tst_QGraphicsWebView::crashOnViewlessWebPages() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + + QGraphicsWebView* webView = new QGraphicsWebView; + WebPage* page = new WebPage; + webView->setPage(page); + page->webView = webView; + connect(page->mainFrame(), SIGNAL(initialLayoutCompleted()), page, SLOT(aborting())); + + scene.addItem(webView); + + view.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + view.resize(600, 480); + webView->resize(view.geometry().size()); + QCoreApplication::processEvents(); + view.show(); + + page->mainFrame()->setHtml(QString("data:text/html," + "<frameset cols=\"25%,75%\">" + "<frame src=\"data:text/html,foo \">" + "<frame src=\"data:text/html,bar\">" + "</frameset>")); + + QVERIFY(waitForSignal(page, SIGNAL(loadFinished(bool)))); +} + +QTEST_MAIN(tst_QGraphicsWebView) + +#include "tst_qgraphicswebview.moc" diff --git a/WebKit/qt/tests/qwebelement/image.png b/WebKit/qt/tests/qwebelement/image.png Binary files differnew file mode 100644 index 0000000..8d70364 --- /dev/null +++ b/WebKit/qt/tests/qwebelement/image.png diff --git a/WebKit/qt/tests/qwebelement/qwebelement.pro b/WebKit/qt/tests/qwebelement/qwebelement.pro index dd0b88a..c45a9ac 100644 --- a/WebKit/qt/tests/qwebelement/qwebelement.pro +++ b/WebKit/qt/tests/qwebelement/qwebelement.pro @@ -5,3 +5,8 @@ SOURCES += tst_qwebelement.cpp RESOURCES += qwebelement.qrc QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR + +symbian { + TARGET.UID3 = 0xA000E53A + TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices +} diff --git a/WebKit/qt/tests/qwebelement/qwebelement.qrc b/WebKit/qt/tests/qwebelement/qwebelement.qrc index ed01440..28b9d7b 100644 --- a/WebKit/qt/tests/qwebelement/qwebelement.qrc +++ b/WebKit/qt/tests/qwebelement/qwebelement.qrc @@ -2,5 +2,6 @@ <qresource prefix="/"> <file>style.css</file> <file>style2.css</file> +<file>image.png</file> </qresource> </RCC> diff --git a/WebKit/qt/tests/qwebelement/tst_qwebelement.cpp b/WebKit/qt/tests/qwebelement/tst_qwebelement.cpp index 0819a3a..e9dae18 100644 --- a/WebKit/qt/tests/qwebelement/tst_qwebelement.cpp +++ b/WebKit/qt/tests/qwebelement/tst_qwebelement.cpp @@ -68,18 +68,20 @@ private slots: void simpleCollection(); void attributes(); void attributesNS(); + void listAttributes(); void classes(); void namespaceURI(); + void iteration(); + void nonConstIterator(); + void constIterator(); void foreachManipulation(); - void evaluateScript(); - void callFunction(); - void callFunctionSubmitForm(); - void functionNames(); + void emptyCollection(); + void appendCollection(); + void evaluateJavaScript(); void documentElement(); void frame(); void style(); void computedStyle(); - void properties(); void appendAndPrepend(); void insertBeforeAndAfter(); void remove(); @@ -90,6 +92,8 @@ private slots: void nullSelect(); void firstChildNextSibling(); void lastChildPreviousSibling(); + void hasSetFocus(); + void render(); private: QWebView* m_view; @@ -136,7 +140,7 @@ void tst_QWebElement::simpleCollection() m_mainFrame->setHtml(html); QWebElement body = m_mainFrame->documentElement(); - QList<QWebElement> list = body.findAll("p"); + QWebElementCollection list = body.findAll("p"); QCOMPARE(list.count(), 2); QCOMPARE(list.at(0).toPlainText(), QString("first para")); QCOMPARE(list.at(1).toPlainText(), QString("second para")); @@ -184,6 +188,29 @@ void tst_QWebElement::attributesNS() QCOMPARE(svg.attributeNS("http://www.w3.org/2000/svg", "foobar", "defaultblah"), QString("true")); } +void tst_QWebElement::listAttributes() +{ + QString content = "<html xmlns=\"http://www.w3.org/1999/xhtml\" " + "xmlns:svg=\"http://www.w3.org/2000/svg\">" + "<body><svg:svg foo=\"\" svg:bar=\"\">" + "</svg:svg></body></html>"; + + m_mainFrame->setContent(content.toUtf8(), "application/xhtml+xml"); + + QWebElement svg = m_mainFrame->findFirstElement("svg"); + QVERIFY(!svg.isNull()); + + QVERIFY(svg.attributeNames().contains("foo")); + QVERIFY(svg.attributeNames("http://www.w3.org/2000/svg").contains("bar")); + + svg.setAttributeNS("http://www.w3.org/2000/svg", "svg:foobar", "true"); + QVERIFY(svg.attributeNames().contains("foo")); + QStringList attributes = svg.attributeNames("http://www.w3.org/2000/svg"); + QCOMPARE(attributes.size(), 2); + QVERIFY(attributes.contains("bar")); + QVERIFY(attributes.contains("foobar")); +} + void tst_QWebElement::classes() { m_mainFrame->setHtml("<body><p class=\"a b c d a c\">Test"); @@ -269,6 +296,72 @@ void tst_QWebElement::namespaceURI() } +void tst_QWebElement::iteration() +{ + QString html = "<body><p>first para</p><p>second para</p></body>"; + m_mainFrame->setHtml(html); + QWebElement body = m_mainFrame->documentElement(); + + QWebElementCollection paras = body.findAll("p"); + QList<QWebElement> referenceList = paras.toList(); + + QList<QWebElement> foreachList; + foreach(QWebElement p, paras) { + foreachList.append(p); + } + QVERIFY(foreachList.count() == 2); + QCOMPARE(foreachList.count(), referenceList.count()); + QCOMPARE(foreachList.at(0), referenceList.at(0)); + QCOMPARE(foreachList.at(1), referenceList.at(1)); + + QList<QWebElement> forLoopList; + for (int i = 0; i < paras.count(); ++i) { + forLoopList.append(paras.at(i)); + } + QVERIFY(foreachList.count() == 2); + QCOMPARE(foreachList.count(), referenceList.count()); + QCOMPARE(foreachList.at(0), referenceList.at(0)); + QCOMPARE(foreachList.at(1), referenceList.at(1)); + + for (int i = 0; i < paras.count(); ++i) { + QCOMPARE(paras.at(i), paras[i]); + } + + QCOMPARE(paras.at(0), paras.first()); + QCOMPARE(paras.at(1), paras.last()); +} + +void tst_QWebElement::nonConstIterator() +{ + QString html = "<body><p>first para</p><p>second para</p></body>"; + m_mainFrame->setHtml(html); + QWebElement body = m_mainFrame->documentElement(); + QWebElementCollection paras = body.findAll("p"); + + QWebElementCollection::iterator it = paras.begin(); + QCOMPARE(*it, paras.at(0)); + ++it; + (*it).encloseWith("<div>"); + QCOMPARE(*it, paras.at(1)); + ++it; + QCOMPARE(it, paras.end()); +} + +void tst_QWebElement::constIterator() +{ + QString html = "<body><p>first para</p><p>second para</p></body>"; + m_mainFrame->setHtml(html); + QWebElement body = m_mainFrame->documentElement(); + const QWebElementCollection paras = body.findAll("p"); + + QWebElementCollection::const_iterator it = paras.begin(); + QCOMPARE(*it, paras.at(0)); + ++it; + QCOMPARE(*it, paras.at(1)); + ++it; + QCOMPARE(it, paras.end()); +} + void tst_QWebElement::foreachManipulation() { QString html = "<body><p>first para</p><p>second para</p></body>"; @@ -282,69 +375,68 @@ void tst_QWebElement::foreachManipulation() QCOMPARE(body.findAll("div").count(), 4); } -void tst_QWebElement::evaluateScript() +void tst_QWebElement::emptyCollection() +{ + QWebElementCollection emptyCollection; + QCOMPARE(emptyCollection.count(), 0); +} + +void tst_QWebElement::appendCollection() +{ + QString html = "<body><span class='a'>aaa</span><p>first para</p><div>foo</div>" + "<span class='b'>bbb</span><p>second para</p><div>bar</div></body>"; + m_mainFrame->setHtml(html); + QWebElement body = m_mainFrame->documentElement(); + + QWebElementCollection collection = body.findAll("p"); + QCOMPARE(collection.count(), 2); + + collection.append(body.findAll("div")); + QCOMPARE(collection.count(), 4); + + collection += body.findAll("span.a"); + QCOMPARE(collection.count(), 5); + + QWebElementCollection all = collection + body.findAll("span.b"); + QCOMPARE(all.count(), 6); + QCOMPARE(collection.count(), 5); + + all += collection; + QCOMPARE(all.count(), 11); + + QCOMPARE(collection.count(), 5); + QWebElementCollection test; + test.append(collection); + QCOMPARE(test.count(), 5); + test.append(QWebElementCollection()); + QCOMPARE(test.count(), 5); +} + +void tst_QWebElement::evaluateJavaScript() { QVariant result; m_mainFrame->setHtml("<body><p>test"); QWebElement para = m_mainFrame->findFirstElement("p"); - result = para.evaluateScript("this.tagName"); + result = para.evaluateJavaScript("this.tagName"); QVERIFY(result.isValid()); QVERIFY(result.type() == QVariant::String); QCOMPARE(result.toString(), QLatin1String("P")); - QVERIFY(para.functions().contains("hasAttributes")); - result = para.evaluateScript("this.hasAttributes()"); + result = para.evaluateJavaScript("this.hasAttributes()"); QVERIFY(result.isValid()); QVERIFY(result.type() == QVariant::Bool); QVERIFY(!result.toBool()); - para.evaluateScript("this.setAttribute('align', 'left');"); + para.evaluateJavaScript("this.setAttribute('align', 'left');"); QCOMPARE(para.attribute("align"), QLatin1String("left")); - result = para.evaluateScript("this.hasAttributes()"); + result = para.evaluateJavaScript("this.hasAttributes()"); QVERIFY(result.isValid()); QVERIFY(result.type() == QVariant::Bool); QVERIFY(result.toBool()); } -void tst_QWebElement::callFunction() -{ - m_mainFrame->setHtml("<body><p>test"); - QWebElement body = m_mainFrame->documentElement(); - QVERIFY(body.functions().contains("hasChildNodes")); - QVariant result = body.callFunction("hasChildNodes"); - QVERIFY(result.isValid()); - QVERIFY(result.type() == QVariant::Bool); - QVERIFY(result.toBool()); - - body.callFunction("setAttribute", QVariantList() << "foo" << "bar"); - QCOMPARE(body.attribute("foo"), QString("bar")); -} - -void tst_QWebElement::callFunctionSubmitForm() -{ - m_mainFrame->setHtml(QString("<html><body><form name='tstform' action='data:text/html,foo'method='get'>" - "<input type='text'><input type='submit'></form></body></html>"), QUrl()); - - QWebElement form = m_mainFrame->documentElement().findAll("form").at(0); - QVERIFY(form.functions().contains("submit")); - QVERIFY(!form.isNull()); - form.callFunction("submit"); - - waitForSignal(m_page, SIGNAL(loadFinished(bool))); - QCOMPARE(m_mainFrame->url().toString(), QString("data:text/html,foo?")); -} - -void tst_QWebElement::functionNames() -{ - m_mainFrame->setHtml("<body><p>Test"); - - QWebElement body = m_mainFrame->documentElement(); - - QVERIFY(body.functions().contains("setAttribute")); -} - void tst_QWebElement::documentElement() { m_mainFrame->setHtml("<body><p>Test"); @@ -398,27 +490,27 @@ void tst_QWebElement::style() m_mainFrame->setHtml(html); QWebElement p = m_mainFrame->documentElement().findAll("p").at(0); - QCOMPARE(p.styleProperty("color"), QLatin1String("blue")); - QVERIFY(p.styleProperty("cursor").isEmpty()); + QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("blue")); + QVERIFY(p.styleProperty("cursor", QWebElement::InlineStyle).isEmpty()); p.setStyleProperty("color", "red"); p.setStyleProperty("cursor", "auto"); - QCOMPARE(p.styleProperty("color"), QLatin1String("red")); - QCOMPARE(p.styleProperty("color", QWebElement::RespectCascadingStyles), QLatin1String("yellow")); - QCOMPARE(p.styleProperty("cursor"), QLatin1String("auto")); + QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("red")); + QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("yellow")); + QCOMPARE(p.styleProperty("cursor", QWebElement::InlineStyle), QLatin1String("auto")); p.setStyleProperty("color", "green !important"); - QCOMPARE(p.styleProperty("color"), QLatin1String("green")); - QCOMPARE(p.styleProperty("color", QWebElement::RespectCascadingStyles), QLatin1String("green")); + QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("green")); + QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("green")); p.setStyleProperty("color", "blue"); - QCOMPARE(p.styleProperty("color"), QLatin1String("green")); - QCOMPARE(p.styleProperty("color", QWebElement::RespectCascadingStyles), QLatin1String("green")); + QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("green")); + QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("green")); - p.setStyleProperty("color", "blue", QWebElement::ImportantStylePriority); - QCOMPARE(p.styleProperty("color"), QLatin1String("blue")); - QCOMPARE(p.styleProperty("color", QWebElement::RespectCascadingStyles), QLatin1String("blue")); + p.setStyleProperty("color", "blue !important"); + QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("blue")); + QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("blue")); QString html2 = "<head>" "<style type='text/css'>" @@ -434,8 +526,8 @@ void tst_QWebElement::style() m_mainFrame->setHtml(html2); p = m_mainFrame->documentElement().findAll("p").at(0); - QCOMPARE(p.styleProperty("color"), QLatin1String("blue")); - QCOMPARE(p.styleProperty("color", QWebElement::RespectCascadingStyles), QLatin1String("blue")); + QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("blue")); + QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("blue")); QString html3 = "<head>" "<style type='text/css'>" @@ -451,8 +543,8 @@ void tst_QWebElement::style() m_mainFrame->setHtml(html3); p = m_mainFrame->documentElement().findAll("p").at(0); - QCOMPARE(p.styleProperty("color"), QLatin1String("blue")); - QCOMPARE(p.styleProperty("color", QWebElement::RespectCascadingStyles), QLatin1String("blue")); + QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("blue")); + QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("blue")); QString html5 = "<head>" "<style type='text/css'>" @@ -468,8 +560,8 @@ void tst_QWebElement::style() m_mainFrame->setHtml(html5); p = m_mainFrame->documentElement().findAll("p").at(0); - QCOMPARE(p.styleProperty("color"), QLatin1String("")); - QCOMPARE(p.styleProperty("color", QWebElement::RespectCascadingStyles), QLatin1String("red")); + QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("")); + QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("red")); QString html6 = "<head>" "<link rel='stylesheet' href='qrc:/style.css' type='text/css' />" @@ -489,8 +581,8 @@ void tst_QWebElement::style() QTest::qWait(200); p = m_mainFrame->documentElement().findAll("p").at(0); - QCOMPARE(p.styleProperty("color"), QLatin1String("blue")); - QCOMPARE(p.styleProperty("color", QWebElement::RespectCascadingStyles), QLatin1String("black")); + QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("blue")); + QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("black")); QString html7 = "<head>" "<style type='text/css'>" @@ -507,15 +599,15 @@ void tst_QWebElement::style() QTest::qWait(200); p = m_mainFrame->documentElement().findAll("p").at(0); - QCOMPARE(p.styleProperty("color", QWebElement::RespectCascadingStyles), QLatin1String("black")); + QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("black")); QString html8 = "<body><p>some text</p></body>"; m_mainFrame->setHtml(html8); p = m_mainFrame->documentElement().findAll("p").at(0); - QCOMPARE(p.styleProperty("color"), QLatin1String("")); - QCOMPARE(p.styleProperty("color", QWebElement::RespectCascadingStyles), QLatin1String("")); + QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("")); + QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("")); } void tst_QWebElement::computedStyle() @@ -524,47 +616,16 @@ void tst_QWebElement::computedStyle() m_mainFrame->setHtml(html); QWebElement p = m_mainFrame->documentElement().findAll("p").at(0); - QCOMPARE(p.computedStyleProperty("cursor"), QLatin1String("auto")); - QVERIFY(!p.computedStyleProperty("cursor").isEmpty()); - QVERIFY(p.styleProperty("cursor").isEmpty()); + QCOMPARE(p.styleProperty("cursor", QWebElement::ComputedStyle), QLatin1String("auto")); + QVERIFY(!p.styleProperty("cursor", QWebElement::ComputedStyle).isEmpty()); + QVERIFY(p.styleProperty("cursor", QWebElement::InlineStyle).isEmpty()); p.setStyleProperty("cursor", "text"); p.setStyleProperty("color", "red"); - QCOMPARE(p.computedStyleProperty("cursor"), QLatin1String("text")); - QCOMPARE(p.computedStyleProperty("color"), QLatin1String("rgb(255, 0, 0)")); - QCOMPARE(p.styleProperty("color"), QLatin1String("red")); -} - -void tst_QWebElement::properties() -{ - m_mainFrame->setHtml("<body><form><input type=checkbox id=ourcheckbox checked=true>"); - - QWebElement checkBox = m_mainFrame->findFirstElement("#ourcheckbox"); - QVERIFY(!checkBox.isNull()); - - QVERIFY(checkBox.scriptableProperties().contains("checked")); - - QCOMPARE(checkBox.scriptableProperty("checked"), QVariant(true)); - checkBox.setScriptableProperty("checked", false); - QCOMPARE(checkBox.scriptableProperty("checked"), QVariant(false)); - - QVERIFY(!checkBox.scriptableProperties().contains("non_existant")); - QCOMPARE(checkBox.scriptableProperty("non_existant"), QVariant()); - - checkBox.setScriptableProperty("non_existant", "test"); - - QCOMPARE(checkBox.scriptableProperty("non_existant"), QVariant("test")); - QVERIFY(checkBox.scriptableProperties().contains("non_existant")); - - // removing scriptableProperties is currently not supported. We should look into this - // and consider the option of just allowing through the QtScript API only. -#if 0 - checkBox.setScriptableProperty("non_existant", QVariant()); - - QCOMPARE(checkBox.scriptableProperty("non_existant"), QVariant()); - QVERIFY(!checkBox.scriptableProperties().contains("non_existant")); -#endif + QCOMPARE(p.styleProperty("cursor", QWebElement::ComputedStyle), QLatin1String("text")); + QCOMPARE(p.styleProperty("color", QWebElement::ComputedStyle), QLatin1String("rgb(255, 0, 0)")); + QCOMPARE(p.styleProperty("color", QWebElement::InlineStyle), QLatin1String("red")); } void tst_QWebElement::appendAndPrepend() @@ -700,7 +761,7 @@ void tst_QWebElement::clear() QCOMPARE(body.findAll("div").count(), 1); QCOMPARE(body.findAll("p").count(), 3); - body.findFirst("div").removeChildren(); + body.findFirst("div").removeAllChildren(); QCOMPARE(body.findAll("div").count(), 1); QCOMPARE(body.findAll("p").count(), 2); } @@ -844,7 +905,7 @@ void tst_QWebElement::nullSelect() { m_mainFrame->setHtml("<body><p>Test"); - QList<QWebElement> collection = m_mainFrame->findAllElements("invalid{syn(tax;;%#$f223e>>"); + QWebElementCollection collection = m_mainFrame->findAllElements("invalid{syn(tax;;%#$f223e>>"); QVERIFY(collection.count() == 0); } @@ -878,5 +939,103 @@ void tst_QWebElement::lastChildPreviousSibling() QVERIFY(p.previousSibling().isNull()); } +void tst_QWebElement::hasSetFocus() +{ + m_mainFrame->setHtml("<html><body>" \ + "<input type='text' id='input1'/>" \ + "<br>"\ + "<input type='text' id='input2'/>" \ + "</body></html>"); + + QWebElementCollection inputs = m_mainFrame->documentElement().findAll("input"); + QWebElement input1 = inputs.at(0); + input1.setFocus(); + QVERIFY(input1.hasFocus()); + + QWebElement input2 = inputs.at(1); + input2.setFocus(); + QVERIFY(!input1.hasFocus()); + QVERIFY(input2.hasFocus()); +} + +void tst_QWebElement::render() +{ + QString html( "<html>" + "<head><style>" + "body, iframe { margin: 0px; border: none; }" + "</style></head>" + "<body><table width='300px' height='300px' border='1'>" + "<tr>" + "<td>test" + "</td>" + "<td><img src='qrc:///image.png'>" + "</td>" + "</tr>" + "</table>" + "</body>" + "</html>" + ); + + QWebPage page; + QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool))); + page.mainFrame()->setHtml(html); + + waitForSignal(&page, SIGNAL(loadFinished(bool))); + QCOMPARE(loadSpy.count(), 1); + + QSize size = page.mainFrame()->contentsSize(); + page.setViewportSize(size); + + QWebElementCollection imgs = page.mainFrame()->findAllElements("img"); + QCOMPARE(imgs.count(), 1); + + QImage resource(":/image.png"); + QRect imageRect(0, 0, resource.width(), resource.height()); + + QImage testImage(resource.width(), resource.height(), QImage::Format_ARGB32); + QPainter painter0(&testImage); + painter0.fillRect(imageRect, Qt::white); + // render() uses pixmaps internally, and pixmaps might have bit depths + // other than 32, giving different pixel values due to rounding. + QPixmap pix = QPixmap::fromImage(resource); + painter0.drawPixmap(0, 0, pix); + painter0.end(); + + QImage image1(resource.width(), resource.height(), QImage::Format_ARGB32); + QPainter painter1(&image1); + painter1.fillRect(imageRect, Qt::white); + imgs[0].render(&painter1); + painter1.end(); + + QVERIFY(image1 == testImage); + + // render image 2nd time to make sure that cached rendering works fine + QImage image2(resource.width(), resource.height(), QImage::Format_ARGB32); + QPainter painter2(&image2); + painter2.fillRect(imageRect, Qt::white); + imgs[0].render(&painter2); + painter2.end(); + + QVERIFY(image2 == testImage); + + // compare table rendered through QWebElement::render to whole page table rendering + QRect tableRect(0, 0, 300, 300); + QWebElementCollection tables = page.mainFrame()->findAllElements("table"); + QCOMPARE(tables.count(), 1); + + QImage image3(300, 300, QImage::Format_ARGB32); + QPainter painter3(&image3); + painter3.fillRect(tableRect, Qt::white); + tables[0].render(&painter3); + painter3.end(); + + QImage image4(300, 300, QImage::Format_ARGB32); + QPainter painter4(&image4); + page.mainFrame()->render(&painter4, tableRect); + painter4.end(); + + QVERIFY(image3 == image4); +} + QTEST_MAIN(tst_QWebElement) #include "tst_qwebelement.moc" diff --git a/WebKit/qt/tests/qwebframe/qwebframe.pro b/WebKit/qt/tests/qwebframe/qwebframe.pro index e45e6dc..b8734cd 100644 --- a/WebKit/qt/tests/qwebframe/qwebframe.pro +++ b/WebKit/qt/tests/qwebframe/qwebframe.pro @@ -5,3 +5,9 @@ SOURCES += tst_qwebframe.cpp RESOURCES += qwebframe.qrc QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR +!symbian:DEFINES += SRCDIR=\\\"$$PWD/resources\\\" + +symbian { + TARGET.UID3 = 0xA000E53D + TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices +} diff --git a/WebKit/qt/tests/qwebframe/resources/image2.png b/WebKit/qt/tests/qwebframe/resources/image2.png Binary files differnew file mode 100644 index 0000000..8d70364 --- /dev/null +++ b/WebKit/qt/tests/qwebframe/resources/image2.png diff --git a/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp b/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp index 17dea99..7c13fd0 100644 --- a/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp +++ b/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp @@ -33,37 +33,14 @@ #include <QRegExp> #include <QNetworkRequest> #include <QNetworkReply> +#ifndef QT_NO_OPENSSL #include <qsslerror.h> +#endif +#include "../util.h" -//TESTED_CLASS= -//TESTED_FILES= - -// Task 160192 -/** - * Starts an event loop that runs until the given signal is received. - Optionally the event loop - * can return earlier on a timeout. - * - * \return \p true if the requested signal was received - * \p false on timeout - */ -static bool waitForSignal(QObject* obj, const char* signal, int timeout = 0) -{ - QEventLoop loop; - QObject::connect(obj, signal, &loop, SLOT(quit())); - QTimer timer; - QSignalSpy timeoutSpy(&timer, SIGNAL(timeout())); - if (timeout > 0) { - QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); - timer.setSingleShot(true); - timer.start(timeout); - } - loop.exec(); - return timeoutSpy.isEmpty(); -} - -/* Mostly a test for the JavaScript related parts of QWebFrame */ - +#if defined(Q_OS_SYMBIAN) +# define SRCDIR "" +#endif struct CustomType { QString string; @@ -578,8 +555,12 @@ private slots: void urlChange(); void domCycles(); void requestedUrl(); + void javaScriptWindowObjectCleared_data(); + void javaScriptWindowObjectCleared(); + void javaScriptWindowObjectClearedOnEvaluate(); void setHtml(); void setHtmlWithResource(); + void setHtmlWithBaseURL(); void ipv6HostEncoding(); void metaData(); void popupFocus(); @@ -592,6 +573,8 @@ private slots: void hasSetFocus(); void render(); void scrollPosition(); + void evaluateWillCauseRepaint(); + void qObjectWrapperWithSameIdentity(); private: QString evalJS(const QString&s) { @@ -692,6 +675,7 @@ void tst_QWebFrame::init() m_page = m_view->page(); m_myObject = new MyQObject(); m_page->mainFrame()->addToJavaScriptWindowObject("myObject", m_myObject); + QDir::setCurrent(SRCDIR); } void tst_QWebFrame::cleanup() @@ -2178,8 +2162,11 @@ public: if (request.url() == QUrl("qrc:/test1.html")) { setHeader(QNetworkRequest::LocationHeader, QString("qrc:/test2.html")); setAttribute(QNetworkRequest::RedirectionTargetAttribute, QUrl("qrc:/test2.html")); - } else if (request.url() == QUrl("qrc:/fake-ssl-error.html")) + } +#ifndef QT_NO_OPENSSL + else if (request.url() == QUrl("qrc:/fake-ssl-error.html")) setError(QNetworkReply::SslHandshakeFailedError, tr("Fake error !")); // force a ssl error +#endif else if (request.url() == QUrl("http://abcdef.abcdef/")) setError(QNetworkReply::HostNotFoundError, tr("Invalid URL")); @@ -2206,8 +2193,10 @@ private slots: emit error(this->error()); else if (request().url() == QUrl("http://abcdef.abcdef/")) emit metaDataChanged(); +#ifndef QT_NO_OPENSSL else if (request().url() == QUrl("qrc:/fake-ssl-error.html")) return; +#endif emit readyRead(); emit finished(); @@ -2224,15 +2213,18 @@ protected: virtual QNetworkReply* createRequest(Operation op, const QNetworkRequest& request, QIODevice* outgoingData) { QString url = request.url().toString(); - if (op == QNetworkAccessManager::GetOperation) + if (op == QNetworkAccessManager::GetOperation) { if (url == "qrc:/test1.html" || url == "http://abcdef.abcdef/") return new FakeReply(request, this); +#ifndef QT_NO_OPENSSL else if (url == "qrc:/fake-ssl-error.html") { FakeReply* reply = new FakeReply(request, this); QList<QSslError> errors; emit sslErrors(reply, errors << QSslError(QSslError::UnspecifiedError)); return reply; } +#endif + } return QNetworkAccessManager::createRequest(op, request, outgoingData); } @@ -2249,32 +2241,68 @@ void tst_QWebFrame::requestedUrl() page.setNetworkAccessManager(networkManager); frame->setUrl(QUrl("qrc:/test1.html")); - QTest::qWait(200); + waitForSignal(frame, SIGNAL(loadFinished(bool)), 200); QCOMPARE(spy.count(), 1); QCOMPARE(frame->requestedUrl(), QUrl("qrc:/test1.html")); QCOMPARE(frame->url(), QUrl("qrc:/test2.html")); frame->setUrl(QUrl("qrc:/non-existent.html")); - QTest::qWait(200); + waitForSignal(frame, SIGNAL(loadFinished(bool)), 200); QCOMPARE(spy.count(), 2); QCOMPARE(frame->requestedUrl(), QUrl("qrc:/non-existent.html")); QCOMPARE(frame->url(), QUrl("qrc:/non-existent.html")); frame->setUrl(QUrl("http://abcdef.abcdef")); - QTest::qWait(200); + waitForSignal(frame, SIGNAL(loadFinished(bool)), 200); QCOMPARE(spy.count(), 3); QCOMPARE(frame->requestedUrl(), QUrl("http://abcdef.abcdef/")); QCOMPARE(frame->url(), QUrl("http://abcdef.abcdef/")); +#ifndef QT_NO_OPENSSL qRegisterMetaType<QList<QSslError> >("QList<QSslError>"); qRegisterMetaType<QNetworkReply* >("QNetworkReply*"); - QSignalSpy spy2(page.networkAccessManager(), SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError>&))); + QSignalSpy spy2(page.networkAccessManager(), SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>))); frame->setUrl(QUrl("qrc:/fake-ssl-error.html")); - QTest::qWait(200); + waitForSignal(frame, SIGNAL(loadFinished(bool)), 200); QCOMPARE(spy2.count(), 1); QCOMPARE(frame->requestedUrl(), QUrl("qrc:/fake-ssl-error.html")); QCOMPARE(frame->url(), QUrl("qrc:/fake-ssl-error.html")); +#endif +} + +void tst_QWebFrame::javaScriptWindowObjectCleared_data() +{ + QTest::addColumn<QString>("html"); + QTest::addColumn<int>("signalCount"); + QTest::newRow("with <script>") << "<html><body><script></script><p>hello world</p></body></html>" << 1; + QTest::newRow("without <script>") << "<html><body><p>hello world</p></body></html>" << 0; +} + +void tst_QWebFrame::javaScriptWindowObjectCleared() +{ + QWebPage page; + QWebFrame* frame = page.mainFrame(); + QSignalSpy spy(frame, SIGNAL(javaScriptWindowObjectCleared())); + QFETCH(QString, html); + frame->setHtml(html); + + QFETCH(int, signalCount); + QCOMPARE(spy.count(), signalCount); +} + +void tst_QWebFrame::javaScriptWindowObjectClearedOnEvaluate() +{ + QWebPage page; + QWebFrame* frame = page.mainFrame(); + QSignalSpy spy(frame, SIGNAL(javaScriptWindowObjectCleared())); + frame->setHtml("<html></html>"); + QCOMPARE(spy.count(), 0); + frame->evaluateJavaScript("var a = 'a';"); + QCOMPARE(spy.count(), 1); + // no new clear for a new script: + frame->evaluateJavaScript("var a = 1;"); + QCOMPARE(spy.count(), 1); } void tst_QWebFrame::setHtml() @@ -2294,7 +2322,7 @@ void tst_QWebFrame::setHtmlWithResource() // in few seconds, the image should be completey loaded QSignalSpy spy(&page, SIGNAL(loadFinished(bool))); frame->setHtml(html); - QTest::qWait(200); + waitForSignal(frame, SIGNAL(loadFinished(bool)), 200); QCOMPARE(spy.count(), 1); QCOMPARE(frame->evaluateJavaScript("document.images.length").toInt(), 1); @@ -2313,11 +2341,33 @@ void tst_QWebFrame::setHtmlWithResource() // in few seconds, the CSS should be completey loaded frame->setHtml(html2); - QTest::qWait(200); + waitForSignal(frame, SIGNAL(loadFinished(bool)), 200); QCOMPARE(spy.size(), 2); QWebElement p = frame->documentElement().findAll("p").at(0); - QCOMPARE(p.styleProperty("color", QWebElement::RespectCascadingStyles), QLatin1String("red")); + QCOMPARE(p.styleProperty("color", QWebElement::CascadedStyle), QLatin1String("red")); +} + +void tst_QWebFrame::setHtmlWithBaseURL() +{ + QString html("<html><body><p>hello world</p><img src='resources/image2.png'/></body></html>"); + + QWebPage page; + QWebFrame* frame = page.mainFrame(); + + // in few seconds, the image should be completey loaded + QSignalSpy spy(&page, SIGNAL(loadFinished(bool))); + + frame->setHtml(html, QUrl::fromLocalFile(QDir::currentPath())); + waitForSignal(frame, SIGNAL(loadFinished(bool)), 200); + QCOMPARE(spy.count(), 1); + + QCOMPARE(frame->evaluateJavaScript("document.images.length").toInt(), 1); + QCOMPARE(frame->evaluateJavaScript("document.images[0].width").toInt(), 128); + QCOMPARE(frame->evaluateJavaScript("document.images[0].height").toInt(), 128); + + // no history item has to be added. + QCOMPARE(m_view->page()->history()->count(), 0); } class TestNetworkManager : public QNetworkAccessManager @@ -2408,33 +2458,27 @@ void tst_QWebFrame::popupFocus() view.resize(400, 100); view.show(); view.setFocus(); - QTest::qWait(200); - QVERIFY2(view.hasFocus(), - "The WebView should be created"); + QTRY_VERIFY(view.hasFocus()); // open the popup by clicking. check if focus is on the popup QTest::mouseClick(&view, Qt::LeftButton, 0, QPoint(25, 25)); QObject* webpopup = firstChildByClassName(&view, "WebCore::QWebPopup"); QComboBox* combo = qobject_cast<QComboBox*>(webpopup); - QTest::qWait(500); - QVERIFY2(!view.hasFocus() && combo->view()->hasFocus(), - "Focus sould be on the Popup"); + QTRY_VERIFY(!view.hasFocus() && combo->view()->hasFocus()); // Focus should be on the popup // hide the popup and check if focus is on the page combo->hidePopup(); - QTest::qWait(500); - QVERIFY2(view.hasFocus() && !combo->view()->hasFocus(), - "Focus sould be back on the WebView"); + QTRY_VERIFY(view.hasFocus() && !combo->view()->hasFocus()); // Focus should be back on the WebView - // triple the flashing time, should at least blink twice already - int delay = qApp->cursorFlashTime() * 3; + // double the flashing time, should at least blink once already + int delay = qApp->cursorFlashTime() * 2; // focus the lineedit and check if it blinks QTest::mouseClick(&view, Qt::LeftButton, 0, QPoint(200, 25)); m_popupTestView = &view; view.installEventFilter( this ); QTest::qWait(delay); - QVERIFY2(m_popupTestPaintCount >= 4, + QVERIFY2(m_popupTestPaintCount >= 3, "The input field should have a blinking caret"); } @@ -2578,7 +2622,7 @@ void tst_QWebFrame::hasSetFocus() QSignalSpy loadSpy(m_page, SIGNAL(loadFinished(bool))); m_page->mainFrame()->setHtml(html); - QTest::qWait(200); + waitForSignal(m_page->mainFrame(), SIGNAL(loadFinished(bool)), 200); QCOMPARE(loadSpy.size(), 1); QList<QWebFrame*> children = m_page->mainFrame()->childFrames(); @@ -2588,20 +2632,20 @@ void tst_QWebFrame::hasSetFocus() "</body></html>"); frame->setHtml(innerHtml); - QTest::qWait(200); + waitForSignal(frame, SIGNAL(loadFinished(bool)), 200); QCOMPARE(loadSpy.size(), 2); m_page->mainFrame()->setFocus(); - QVERIFY(m_page->mainFrame()->hasFocus()); + QTRY_VERIFY(m_page->mainFrame()->hasFocus()); for (int i = 0; i < children.size(); ++i) { children.at(i)->setFocus(); - QVERIFY(children.at(i)->hasFocus()); + QTRY_VERIFY(children.at(i)->hasFocus()); QVERIFY(!m_page->mainFrame()->hasFocus()); } m_page->mainFrame()->setFocus(); - QVERIFY(m_page->mainFrame()->hasFocus()); + QTRY_VERIFY(m_page->mainFrame()->hasFocus()); } void tst_QWebFrame::render() @@ -2623,26 +2667,24 @@ void tst_QWebFrame::render() QPicture picture; - // render clipping to Viewport - frame->setClipRenderToViewport(true); + QSize size = page.mainFrame()->contentsSize(); + page.setViewportSize(size); + + // render contents layer only (the iframe is smaller than the image, so it will have scrollbars) QPainter painter1(&picture); - frame->render(&painter1); + frame->render(&painter1, QWebFrame::ContentsLayer); painter1.end(); - QSize size = page.mainFrame()->contentsSize(); - page.setViewportSize(size); - QCOMPARE(size.width(), picture.boundingRect().width()); // 100px - QCOMPARE(size.height(), picture.boundingRect().height()); // 100px + QCOMPARE(size.width(), picture.boundingRect().width() + frame->scrollBarGeometry(Qt::Vertical).width()); + QCOMPARE(size.height(), picture.boundingRect().height() + frame->scrollBarGeometry(Qt::Horizontal).height()); - // render without clipping to Viewport - frame->setClipRenderToViewport(false); + // render everything, should be the size of the iframe QPainter painter2(&picture); - frame->render(&painter2); + frame->render(&painter2, QWebFrame::AllLayers); painter2.end(); - QImage resource(":/image.png"); - QCOMPARE(resource.width(), picture.boundingRect().width()); // resource width: 128px - QCOMPARE(resource.height(), picture.boundingRect().height()); // resource height: 128px + QCOMPARE(size.width(), picture.boundingRect().width()); // width: 100px + QCOMPARE(size.height(), picture.boundingRect().height()); // height: 100px } void tst_QWebFrame::scrollPosition() @@ -2669,5 +2711,59 @@ void tst_QWebFrame::scrollPosition() QCOMPARE(y, 29); } +void tst_QWebFrame::evaluateWillCauseRepaint() +{ + QWebView view; + QString html("<html><body>top<div id=\"junk\" style=\"display: block;\">" + "junk</div>bottom</body></html>"); + view.setHtml(html); + view.show(); + + QTest::qWaitForWindowShown(&view); + + view.page()->mainFrame()->evaluateJavaScript( + "document.getElementById('junk').style.display = 'none';"); + + ::waitForSignal(view.page(), SIGNAL(repaintRequested(QRect))); +} + +class TestFactory : public QObject +{ + Q_OBJECT +public: + TestFactory() + : obj(0), counter(0) + {} + + Q_INVOKABLE QObject* getNewObject() + { + delete obj; + obj = new QObject(this); + obj->setObjectName(QLatin1String("test") + QString::number(++counter)); + return obj; + + } + + QObject* obj; + int counter; +}; + +void tst_QWebFrame::qObjectWrapperWithSameIdentity() +{ + m_view->setHtml("<script>function triggerBug() { document.getElementById('span1').innerText = test.getNewObject().objectName; }</script>" + "<body><span id='span1'>test</span></body>"); + + QWebFrame* mainFrame = m_view->page()->mainFrame(); + QCOMPARE(mainFrame->toPlainText(), QString("test")); + + mainFrame->addToJavaScriptWindowObject("test", new TestFactory, QScriptEngine::ScriptOwnership); + + mainFrame->evaluateJavaScript("triggerBug();"); + QCOMPARE(mainFrame->toPlainText(), QString("test1")); + + mainFrame->evaluateJavaScript("triggerBug();"); + QCOMPARE(mainFrame->toPlainText(), QString("test2")); +} + QTEST_MAIN(tst_QWebFrame) #include "tst_qwebframe.moc" diff --git a/WebKit/qt/tests/qwebhistory/qwebhistory.pro b/WebKit/qt/tests/qwebhistory/qwebhistory.pro index fd1074c..7445e3b 100644 --- a/WebKit/qt/tests/qwebhistory/qwebhistory.pro +++ b/WebKit/qt/tests/qwebhistory/qwebhistory.pro @@ -5,3 +5,8 @@ SOURCES += tst_qwebhistory.cpp RESOURCES += tst_qwebhistory.qrc QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR + +symbian { + TARGET.UID3 = 0xA000E53B + TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices +} diff --git a/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp b/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp index 5b55613..ec2d497 100644 --- a/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp +++ b/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp @@ -18,6 +18,7 @@ */ #include <QtTest/QtTest> +#include <QAction> #include "qwebpage.h" #include "qwebview.h" @@ -55,9 +56,11 @@ private slots: void serialize_1(); //QWebHistory countity void serialize_2(); //QWebHistory index void serialize_3(); //QWebHistoryItem - void saveAndRestore_1(); //simple checks saveState and restoreState - void saveAndRestore_2(); //bad parameters saveState and restoreState - void saveAndRestore_3(); //try use different version + void saveAndRestore_crash_1(); + void saveAndRestore_crash_2(); + void saveAndRestore_crash_3(); + void clear(); + private: QWebPage* page; @@ -119,6 +122,8 @@ void tst_QWebHistory::back() hist->back(); waitForLoadFinished.exec(); } + //try one more time (too many). crash test + hist->back(); } /** @@ -137,6 +142,8 @@ void tst_QWebHistory::forward() hist->forward(); waitForLoadFinished.exec(); } + //try one more time (too many). crash test + hist->forward(); } /** @@ -284,42 +291,83 @@ void tst_QWebHistory::serialize_3() QVERIFY(load.atEnd()); } -/** Simple checks should be a bit redundant to streaming operators */ -void tst_QWebHistory::saveAndRestore_1() +static void saveHistory(QWebHistory* history, QByteArray* in) { - hist->back(); - waitForLoadFinished.exec(); - QByteArray buffer(hist->saveState()); - hist->clear(); - QVERIFY(hist->count() == 1); - hist->restoreState(buffer); + in->clear(); + QDataStream save(in, QIODevice::WriteOnly); + save << *history; +} - //check only few values, do not make full test - //because most of the code is shared with streaming operators - //and these are checked before - QCOMPARE(hist->count(), histsize); - QCOMPARE(hist->currentItemIndex(), histsize - 2); - QCOMPARE(hist->itemAt(0).title(), QString("page1")); - QCOMPARE(hist->itemAt(histsize - 1).title(), QString("page") + QString::number(histsize)); +static void restoreHistory(QWebHistory* history, QByteArray* out) +{ + QDataStream load(out, QIODevice::ReadOnly); + load >> *history; } -/** Check returns value if there are bad parameters. Actually, result - * is no so importent. The test shouldn't crash :-) */ -void tst_QWebHistory::saveAndRestore_2() +/** The test shouldn't crash */ +void tst_QWebHistory::saveAndRestore_crash_1() { QByteArray buffer; - hist->restoreState(buffer); - QVERIFY(hist->count() == 1); - QVERIFY(hist->itemAt(0).isValid()); + saveHistory(hist, &buffer); + for (unsigned i = 0; i < 5; i++) { + restoreHistory(hist, &buffer); + saveHistory(hist, &buffer); + } +} + +/** The test shouldn't crash */ +void tst_QWebHistory::saveAndRestore_crash_2() +{ + QByteArray buffer; + saveHistory(hist, &buffer); + QWebPage* page2 = new QWebPage(this); + QWebHistory* hist2 = page2->history(); + for (unsigned i = 0; i < 5; i++) { + restoreHistory(hist2, &buffer); + saveHistory(hist2, &buffer); + } + delete page2; +} + +/** The test shouldn't crash */ +void tst_QWebHistory::saveAndRestore_crash_3() +{ + QByteArray buffer; + saveHistory(hist, &buffer); + QWebPage* page2 = new QWebPage(this); + QWebHistory* hist1 = hist; + QWebHistory* hist2 = page2->history(); + for (unsigned i = 0; i < 5; i++) { + restoreHistory(hist1, &buffer); + restoreHistory(hist2, &buffer); + QVERIFY(hist1->count() == hist2->count()); + QVERIFY(hist1->count() == histsize); + hist2->back(); + saveHistory(hist2, &buffer); + hist2->clear(); + } + delete page2; } -/** Try to use bad version value */ -void tst_QWebHistory::saveAndRestore_3() +/** ::clear */ +void tst_QWebHistory::clear() { - QByteArray tmp = hist->saveState((QWebHistory::HistoryStateVersion)29999); - QVERIFY(hist->saveState((QWebHistory::HistoryStateVersion)29999).isEmpty()); - QVERIFY(hist->count() == histsize); - QVERIFY(hist->itemAt(3).isValid()); + QByteArray buffer; + + QAction* actionBack = page->action(QWebPage::Back); + QVERIFY(actionBack->isEnabled()); + saveHistory(hist, &buffer); + QVERIFY(hist->count() > 1); + hist->clear(); + QVERIFY(hist->count() == 1); // Leave current item. + QVERIFY(!actionBack->isEnabled()); + + QWebPage* page2 = new QWebPage(this); + QWebHistory* hist2 = page2->history(); + QVERIFY(hist2->count() == 0); + hist2->clear(); + QVERIFY(hist2->count() == 0); // Do not change anything. + delete page2; } QTEST_MAIN(tst_QWebHistory) diff --git a/WebKit/qt/tests/qwebhistoryinterface/qwebhistoryinterface.pro b/WebKit/qt/tests/qwebhistoryinterface/qwebhistoryinterface.pro index af3b348..764f806 100644 --- a/WebKit/qt/tests/qwebhistoryinterface/qwebhistoryinterface.pro +++ b/WebKit/qt/tests/qwebhistoryinterface/qwebhistoryinterface.pro @@ -4,3 +4,8 @@ include(../../../../WebKit.pri) SOURCES += tst_qwebhistoryinterface.cpp QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR + +symbian { + TARGET.UID3 = 0xA000E53C + TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices +} diff --git a/WebKit/qt/tests/qwebinspector/qwebinspector.pro b/WebKit/qt/tests/qwebinspector/qwebinspector.pro new file mode 100644 index 0000000..520887e --- /dev/null +++ b/WebKit/qt/tests/qwebinspector/qwebinspector.pro @@ -0,0 +1,6 @@ +TEMPLATE = app +TARGET = tst_qwebinspector +include(../../../../WebKit.pri) +SOURCES += tst_qwebinspector.cpp +QT += testlib network +QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR diff --git a/WebKit/qt/tests/qwebinspector/tst_qwebinspector.cpp b/WebKit/qt/tests/qwebinspector/tst_qwebinspector.cpp new file mode 100644 index 0000000..12cd630 --- /dev/null +++ b/WebKit/qt/tests/qwebinspector/tst_qwebinspector.cpp @@ -0,0 +1,68 @@ +/* + Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + + 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 <QtTest/QtTest> + +#include <qdir.h> +#include <qwebinspector.h> +#include <qwebpage.h> +#include <qwebsettings.h> + +class tst_QWebInspector : public QObject { + Q_OBJECT + +private slots: + void attachAndDestroy(); +}; + +void tst_QWebInspector::attachAndDestroy() +{ + { // External inspector + manual destruction of page first + QWebPage* page = new QWebPage(); + page->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true); + QWebInspector* inspector = new QWebInspector(); + inspector->setPage(page); + page->updatePositionDependentActions(QPoint(0, 0)); + page->triggerAction(QWebPage::InspectElement); + + delete page; + delete inspector; + } + { // External inspector + manual destruction of inspector first + QWebPage* page = new QWebPage(); + page->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true); + QWebInspector* inspector = new QWebInspector(); + inspector->setPage(page); + page->updatePositionDependentActions(QPoint(0, 0)); + page->triggerAction(QWebPage::InspectElement); + + delete inspector; + delete page; + } + { // Internal inspector + QWebPage page; + page.settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true); + page.updatePositionDependentActions(QPoint(0, 0)); + page.triggerAction(QWebPage::InspectElement); + } +} + +QTEST_MAIN(tst_QWebInspector) + +#include "tst_qwebinspector.moc" diff --git a/WebKit/qt/tests/qwebpage/qwebpage.pro b/WebKit/qt/tests/qwebpage/qwebpage.pro index 2f3a108..7853b28 100644 --- a/WebKit/qt/tests/qwebpage/qwebpage.pro +++ b/WebKit/qt/tests/qwebpage/qwebpage.pro @@ -5,3 +5,9 @@ SOURCES += tst_qwebpage.cpp RESOURCES += tst_qwebpage.qrc QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR +!symbian:DEFINES += SRCDIR=\\\"$$PWD/\\\" + +symbian { + TARGET.UID3 = 0xA000E53E + TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices +} diff --git a/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp index 966f049..2a52631 100644 --- a/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp +++ b/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp @@ -1,5 +1,6 @@ /* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -20,8 +21,13 @@ #include <QtTest/QtTest> +#include <qgraphicsscene.h> +#include <qgraphicsview.h> +#include <qgraphicswebview.h> +#include <qwebelement.h> #include <qwebpage.h> #include <qwidget.h> +#include <QGraphicsWidget> #include <qwebview.h> #include <qwebframe.h> #include <qwebhistory.h> @@ -32,6 +38,11 @@ #include <qwebsecurityorigin.h> #include <qwebdatabase.h> #include <QPushButton> +#include <QDir> + +#if defined(Q_OS_SYMBIAN) +# define SRCDIR "" +#endif // Will try to wait for the condition while allowing event processing #define QTRY_COMPARE(__expr, __expected) \ @@ -59,7 +70,7 @@ * \return \p true if the requested signal was received * \p false on timeout */ -static bool waitForSignal(QObject* obj, const char* signal, int timeout = 0) +static bool waitForSignal(QObject* obj, const char* signal, int timeout = 10000) { QEventLoop loop; QObject::connect(obj, signal, &loop, SLOT(quit())); @@ -74,6 +85,22 @@ static bool waitForSignal(QObject* obj, const char* signal, int timeout = 0) return timeoutSpy.isEmpty(); } +class EventSpy : public QObject, public QList<QEvent::Type> +{ + Q_OBJECT +public: + EventSpy(QObject* objectToSpy) + { + objectToSpy->installEventFilter(this); + } + + virtual bool eventFilter(QObject* receiver, QEvent* event) + { + append(event->type()); + return false; + } +}; + class tst_QWebPage : public QObject { Q_OBJECT @@ -100,7 +127,9 @@ private slots: void contextMenuCrash(); void database(); void createPlugin(); + void destroyPlugin_data(); void destroyPlugin(); + void createViewlessPlugin_data(); void createViewlessPlugin(); void multiplePageGroupsAndLocalStorage(); void cursorMovements(); @@ -110,9 +139,23 @@ private slots: void frameAt(); void requestCache(); void protectBindingsRuntimeObjectsFromCollector(); + void localURLSchemes(); + void testOptionalJSObjects(); + void testEnablePersistentStorage(); + void consoleOutput(); + void inputMethods_data(); + void inputMethods(); + void defaultTextEncoding(); + void errorPageExtension(); + void errorPageExtensionInIFrames(); + void errorPageExtensionInFrameset(); -private: + void crashTests_LazyInitializationOfMainFrame(); + + void screenshot_data(); + void screenshot(); + void originatingObjectInNetworkRequests(); private: QWebView* m_view; @@ -217,6 +260,8 @@ void tst_QWebPage::infiniteLoopJS() void tst_QWebPage::loadFinished() { + qRegisterMetaType<QWebFrame*>("QWebFrame*"); + qRegisterMetaType<QNetworkRequest*>("QNetworkRequest*"); QSignalSpy spyLoadStarted(m_view, SIGNAL(loadStarted())); QSignalSpy spyLoadFinished(m_view, SIGNAL(loadFinished(bool))); @@ -238,6 +283,31 @@ void tst_QWebPage::loadFinished() QCOMPARE(spyLoadFinished.count(), 1); } +class ConsolePage : public QWebPage +{ +public: + ConsolePage(QObject* parent = 0) : QWebPage(parent) {} + + virtual void javaScriptConsoleMessage(const QString& message, int lineNumber, const QString& sourceID) + { + messages.append(message); + lineNumbers.append(lineNumber); + sourceIDs.append(sourceID); + } + + QStringList messages; + QList<int> lineNumbers; + QStringList sourceIDs; +}; + +void tst_QWebPage::consoleOutput() +{ + ConsolePage page; + page.mainFrame()->evaluateJavaScript("this is not valid JavaScript"); + QCOMPARE(page.messages.count(), 1); + QCOMPARE(page.lineNumbers.at(0), 1); +} + class TestPage : public QWebPage { public: @@ -302,9 +372,11 @@ public: TestNetworkManager(QObject* parent) : QNetworkAccessManager(parent) {} QList<QUrl> requestedUrls; + QList<QNetworkRequest> requests; protected: virtual QNetworkReply* createRequest(Operation op, const QNetworkRequest &request, QIODevice* outgoingData) { + requests.append(request); requestedUrls.append(request.url()); return QNetworkAccessManager::createRequest(op, request, outgoingData); } @@ -316,13 +388,13 @@ void tst_QWebPage::userStyleSheet() m_page->setNetworkAccessManager(networkManager); networkManager->requestedUrls.clear(); - m_page->settings()->setUserStyleSheetUrl(QUrl("data:text/css,p { background-image: url('http://does.not/exist.png');}")); + m_page->settings()->setUserStyleSheetUrl(QUrl("data:text/css;charset=utf-8;base64," + + QByteArray("p { background-image: url('http://does.not/exist.png');}").toBase64())); m_view->setHtml("<p>hello world</p>"); QVERIFY(::waitForSignal(m_view, SIGNAL(loadFinished(bool)))); - QVERIFY(networkManager->requestedUrls.count() >= 2); - QCOMPARE(networkManager->requestedUrls.at(0), QUrl("data:text/css,p { background-image: url('http://does.not/exist.png');}")); - QCOMPARE(networkManager->requestedUrls.at(1), QUrl("http://does.not/exist.png")); + QVERIFY(networkManager->requestedUrls.count() >= 1); + QCOMPARE(networkManager->requestedUrls.at(0), QUrl("http://does.not/exist.png")); } void tst_QWebPage::modified() @@ -378,7 +450,7 @@ void tst_QWebPage::modified() m_page->mainFrame()->setUrl(QUrl("data:text/html,<body>This is fourth page")); QVERIFY(m_page->history()->count() == 2); m_page->mainFrame()->setUrl(QUrl("data:text/html,<body>This is fifth page")); - QVERIFY(::waitForSignal(m_page, SIGNAL(saveFrameStateRequested(QWebFrame*, QWebHistoryItem*)))); + QVERIFY(::waitForSignal(m_page, SIGNAL(saveFrameStateRequested(QWebFrame*,QWebHistoryItem*)))); } void tst_QWebPage::contextMenuCrash() @@ -405,13 +477,16 @@ void tst_QWebPage::database() QWebSettings::setOfflineStorageDefaultQuota(1024 * 1024); QVERIFY(QWebSettings::offlineStorageDefaultQuota() == 1024 * 1024); + m_page->settings()->setAttribute(QWebSettings::LocalStorageEnabled, true); + m_page->settings()->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, true); + QString dbFileName = path + "Databases.db"; if (QFile::exists(dbFileName)) QFile::remove(dbFileName); qRegisterMetaType<QWebFrame*>("QWebFrame*"); - QSignalSpy spy(m_page, SIGNAL(databaseQuotaExceeded(QWebFrame *, QString))); + QSignalSpy spy(m_page, SIGNAL(databaseQuotaExceeded(QWebFrame*,QString))); m_view->setHtml(QString("<html><head><script>var db; db=openDatabase('testdb', '1.0', 'test database API', 50000); </script></head><body><div></div></body></html>"), QUrl("http://www.myexample.com")); QTRY_COMPARE(spy.count(), 1); m_page->mainFrame()->evaluateJavaScript("var db2; db2=openDatabase('testdb', '1.0', 'test database API', 50000);"); @@ -432,14 +507,19 @@ void tst_QWebPage::database() m_page->mainFrame()->evaluateJavaScript("var db3; db3=openDatabase('testdb', '1.0', 'test database API', 50000);db3.transaction(function(tx) { tx.executeSql('CREATE TABLE IF NOT EXISTS Test (text TEXT)', []); }, function(tx, result) { }, function(tx, error) { });"); QTest::qWait(200); + // Remove all databases. QWebSecurityOrigin origin = m_page->mainFrame()->securityOrigin(); QList<QWebDatabase> dbs = origin.databases(); - if (dbs.count() > 0) { - QString fileName = dbs[0].fileName(); + for (int i = 0; i < dbs.count(); i++) { + QString fileName = dbs[i].fileName(); QVERIFY(QFile::exists(fileName)); - QWebDatabase::removeDatabase(dbs[0]); + QWebDatabase::removeDatabase(dbs[i]); QVERIFY(!QFile::exists(fileName)); } + QVERIFY(!origin.databases().size()); + // Remove removed test :-) + QWebDatabase::removeAllDatabases(); + QVERIFY(!origin.databases().size()); QTest::qWait(1000); } @@ -578,56 +658,121 @@ void tst_QWebPage::createPlugin() QCOMPARE(newPage->calls.count(), 0); } -class PluginTrackedPage : public QWebPage -{ + +// Standard base class for template PluginTracerPage. In tests it is used as interface. +class PluginCounterPage : public QWebPage { public: + int m_count; + QPointer<QObject> m_widget; + QObject* m_pluginParent; + PluginCounterPage(QObject* parent = 0) + : QWebPage(parent) + , m_count(0) + , m_widget(0) + , m_pluginParent(0) + { + settings()->setAttribute(QWebSettings::PluginsEnabled, true); + } + ~PluginCounterPage() + { + if (m_pluginParent) + m_pluginParent->deleteLater(); + } +}; - int count; - QPointer<QWidget> widget; +template<class T> +class PluginTracerPage : public PluginCounterPage { +public: + PluginTracerPage(QObject* parent = 0) + : PluginCounterPage(parent) + { + // this is a dummy parent object for the created plugin + m_pluginParent = new T; + } + virtual QObject* createPlugin(const QString&, const QUrl&, const QStringList&, const QStringList&) + { + m_count++; + m_widget = new T; + // need a cast to the specific type, as QObject::setParent cannot be called, + // because it is not virtual. Instead it is necesary to call QWidget::setParent, + // which also takes a QWidget* instead of a QObject*. Therefore we need to + // upcast to T*, which is a QWidget. + static_cast<T*>(m_widget.data())->setParent(static_cast<T*>(m_pluginParent)); + return m_widget; + } +}; - PluginTrackedPage(QWidget *parent = 0) : QWebPage(parent), count(0) { - settings()->setAttribute(QWebSettings::PluginsEnabled, true); +class PluginFactory { +public: + enum FactoredType {QWidgetType, QGraphicsWidgetType}; + static PluginCounterPage* create(FactoredType type, QObject* parent = 0) + { + PluginCounterPage* result = 0; + switch (type) { + case QWidgetType: + result = new PluginTracerPage<QWidget>(parent); + break; + case QGraphicsWidgetType: + result = new PluginTracerPage<QGraphicsWidget>(parent); + break; + default: {/*Oops*/}; + } + return result; } - virtual QObject* createPlugin(const QString&, const QUrl&, const QStringList&, const QStringList&) { - count++; - QWidget *w = new QWidget; - widget = w; - return w; + static void prepareTestData() + { + QTest::addColumn<int>("type"); + QTest::newRow("QWidget") << (int)PluginFactory::QWidgetType; + QTest::newRow("QGraphicsWidget") << (int)PluginFactory::QGraphicsWidgetType; } }; +void tst_QWebPage::destroyPlugin_data() +{ + PluginFactory::prepareTestData(); +} + void tst_QWebPage::destroyPlugin() { - PluginTrackedPage* page = new PluginTrackedPage(m_view); + QFETCH(int, type); + PluginCounterPage* page = PluginFactory::create((PluginFactory::FactoredType)type, m_view); m_view->setPage(page); // we create the plugin, so the widget should be constructed QString content("<html><body><object type=\"application/x-qt-plugin\" classid=\"QProgressBar\"></object></body></html>"); m_view->setHtml(content); - QVERIFY(page->widget != 0); - QCOMPARE(page->count, 1); + QVERIFY(page->m_widget); + QCOMPARE(page->m_count, 1); // navigate away, the plugin widget should be destructed m_view->setHtml("<html><body>Hi</body></html>"); QTestEventLoop::instance().enterLoop(1); - QVERIFY(page->widget == 0); + QVERIFY(!page->m_widget); +} + +void tst_QWebPage::createViewlessPlugin_data() +{ + PluginFactory::prepareTestData(); } void tst_QWebPage::createViewlessPlugin() { - PluginTrackedPage* page = new PluginTrackedPage; + QFETCH(int, type); + PluginCounterPage* page = PluginFactory::create((PluginFactory::FactoredType)type); QString content("<html><body><object type=\"application/x-qt-plugin\" classid=\"QProgressBar\"></object></body></html>"); page->mainFrame()->setHtml(content); - QCOMPARE(page->count, 1); - QVERIFY(page->widget != 0); + QCOMPARE(page->m_count, 1); + QVERIFY(page->m_widget); + QVERIFY(page->m_pluginParent); + QVERIFY(page->m_widget->parent() == page->m_pluginParent); delete page; + } // import private API void QWEBKIT_EXPORT qt_webpage_setGroupName(QWebPage* page, const QString& groupName); QString QWEBKIT_EXPORT qt_webpage_groupName(QWebPage* page); -void QWEBKIT_EXPORT qt_websettings_setLocalStorageDatabasePath(QWebSettings* settings, const QString& path); void tst_QWebPage::multiplePageGroupsAndLocalStorage() { @@ -638,9 +783,11 @@ void tst_QWebPage::multiplePageGroupsAndLocalStorage() QWebView view1; QWebView view2; - qt_websettings_setLocalStorageDatabasePath(view1.page()->settings(), QDir::toNativeSeparators(QDir::currentPath() + "/path1")); + view1.page()->settings()->setAttribute(QWebSettings::LocalStorageEnabled, true); + view1.page()->settings()->setLocalStoragePath(QDir::toNativeSeparators(QDir::currentPath() + "/path1")); qt_webpage_setGroupName(view1.page(), "group1"); - qt_websettings_setLocalStorageDatabasePath(view2.page()->settings(), QDir::toNativeSeparators(QDir::currentPath() + "/path2")); + view2.page()->settings()->setAttribute(QWebSettings::LocalStorageEnabled, true); + view2.page()->settings()->setLocalStoragePath(QDir::toNativeSeparators(QDir::currentPath() + "/path2")); qt_webpage_setGroupName(view2.page(), "group2"); QCOMPARE(qt_webpage_groupName(view1.page()), QString("group1")); QCOMPARE(qt_webpage_groupName(view2.page()), QString("group2")); @@ -1165,6 +1312,200 @@ void tst_QWebPage::frameAt() frameAtHelper(webPage, webPage->mainFrame(), webPage->mainFrame()->pos()); } +void tst_QWebPage::inputMethods_data() +{ + QTest::addColumn<QString>("viewType"); + QTest::newRow("QWebView") << "QWebView"; +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + QTest::newRow("QGraphicsWebView") << "QGraphicsWebView"; +#endif +} + +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) +static Qt::InputMethodHints inputMethodHints(QObject* object) +{ + if (QGraphicsObject* o = qobject_cast<QGraphicsObject*>(object)) + return o->inputMethodHints(); + if (QWidget* w = qobject_cast<QWidget*>(object)) + return w->inputMethodHints(); + return Qt::InputMethodHints(); +} +#endif + +static bool inputMethodEnabled(QObject* object) +{ +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + if (QGraphicsObject* o = qobject_cast<QGraphicsObject*>(object)) + return o->flags() & QGraphicsItem::ItemAcceptsInputMethod; +#endif + if (QWidget* w = qobject_cast<QWidget*>(object)) + return w->testAttribute(Qt::WA_InputMethodEnabled); + return false; +} + +void tst_QWebPage::inputMethods() +{ + QFETCH(QString, viewType); + QWebPage* page = new QWebPage; + QObject* view = 0; + QObject* container = 0; + if (viewType == "QWebView") { + QWebView* wv = new QWebView; + wv->setPage(page); + view = wv; + container = view; + } +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + else if (viewType == "QGraphicsWebView") { + QGraphicsWebView* wv = new QGraphicsWebView; + wv->setPage(page); + view = wv; + + QGraphicsView* gv = new QGraphicsView; + QGraphicsScene* scene = new QGraphicsScene(gv); + gv->setScene(scene); + scene->addItem(wv); + wv->setGeometry(QRect(0, 0, 500, 500)); + + container = gv; + } +#endif + else + QVERIFY2(false, "Unknown view type"); + + page->mainFrame()->setHtml("<html><body>" \ + "<input type='text' id='input1' style='font-family: serif' value='' maxlength='20'/><br>" \ + "<input type='password'/>" \ + "</body></html>"); + page->mainFrame()->setFocus(); + + EventSpy viewEventSpy(container); + + QWebElementCollection inputs = page->mainFrame()->documentElement().findAll("input"); + + QMouseEvent evpres(QEvent::MouseButtonPress, inputs.at(0).geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); + page->event(&evpres); + QMouseEvent evrel(QEvent::MouseButtonRelease, inputs.at(0).geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); + page->event(&evrel); + +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + QVERIFY(!viewEventSpy.contains(QEvent::RequestSoftwareInputPanel)); +#endif + viewEventSpy.clear(); + + page->event(&evpres); + page->event(&evrel); + +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + QVERIFY(viewEventSpy.contains(QEvent::RequestSoftwareInputPanel)); +#endif + + //ImMicroFocus + QVariant variant = page->inputMethodQuery(Qt::ImMicroFocus); + QRect focusRect = variant.toRect(); + QVERIFY(inputs.at(0).geometry().contains(variant.toRect().topLeft())); + + //ImFont + variant = page->inputMethodQuery(Qt::ImFont); + QFont font = variant.value<QFont>(); + QCOMPARE(QString("-webkit-serif"), font.family()); + + QList<QInputMethodEvent::Attribute> inputAttributes; + + //Insert text. + { + QInputMethodEvent eventText("QtWebKit", inputAttributes); + QSignalSpy signalSpy(page, SIGNAL(microFocusChanged())); + page->event(&eventText); + QCOMPARE(signalSpy.count(), 0); + } + + { + QInputMethodEvent eventText("", inputAttributes); + eventText.setCommitString(QString("QtWebKit"), 0, 0); + page->event(&eventText); + } + +#if QT_VERSION >= 0x040600 + //ImMaximumTextLength + variant = page->inputMethodQuery(Qt::ImMaximumTextLength); + QCOMPARE(20, variant.toInt()); + + //Set selection + inputAttributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 3, 2, QVariant()); + QInputMethodEvent eventSelection("",inputAttributes); + page->event(&eventSelection); + + //ImAnchorPosition + variant = page->inputMethodQuery(Qt::ImAnchorPosition); + int anchorPosition = variant.toInt(); + QCOMPARE(anchorPosition, 3); + + //ImCursorPosition + variant = page->inputMethodQuery(Qt::ImCursorPosition); + int cursorPosition = variant.toInt(); + QCOMPARE(cursorPosition, 5); + + //ImCurrentSelection + variant = page->inputMethodQuery(Qt::ImCurrentSelection); + QString selectionValue = variant.value<QString>(); + QCOMPARE(selectionValue, QString("eb")); +#endif + + //ImSurroundingText + variant = page->inputMethodQuery(Qt::ImSurroundingText); + QString value = variant.value<QString>(); + QCOMPARE(value, QString("QtWebKit")); + +#if QT_VERSION >= 0x040600 + { + QList<QInputMethodEvent::Attribute> attributes; + // Clear the selection, so the next test does not clear any contents. + QInputMethodEvent::Attribute newSelection(QInputMethodEvent::Selection, 0, 0, QVariant()); + attributes.append(newSelection); + QInputMethodEvent event("composition", attributes); + page->event(&event); + } + + // A ongoing composition should not change the surrounding text before it is committed. + variant = page->inputMethodQuery(Qt::ImSurroundingText); + value = variant.value<QString>(); + QCOMPARE(value, QString("QtWebKit")); +#endif + + //ImhHiddenText + QMouseEvent evpresPassword(QEvent::MouseButtonPress, inputs.at(1).geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); + page->event(&evpresPassword); + QMouseEvent evrelPassword(QEvent::MouseButtonRelease, inputs.at(1).geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); + page->event(&evrelPassword); + + QVERIFY(inputMethodEnabled(view)); +#if QT_VERSION >= 0x040600 + QVERIFY(inputMethodHints(view) & Qt::ImhHiddenText); + + page->event(&evpres); + page->event(&evrel); + QVERIFY(!(inputMethodHints(view) & Qt::ImhHiddenText)); +#endif + + page->mainFrame()->setHtml("<html><body><p>nothing to input here"); + viewEventSpy.clear(); + + QWebElement para = page->mainFrame()->findFirstElement("p"); + { + QMouseEvent evpres(QEvent::MouseButtonPress, para.geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); + page->event(&evpres); + QMouseEvent evrel(QEvent::MouseButtonRelease, para.geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); + page->event(&evrel); + } + +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + QVERIFY(!viewEventSpy.contains(QEvent::RequestSoftwareInputPanel)); +#endif + + delete container; +} + // import a little DRT helper function to trigger the garbage collector void QWEBKIT_EXPORT qt_drt_garbageCollector_collect(); @@ -1190,5 +1531,288 @@ void tst_QWebPage::protectBindingsRuntimeObjectsFromCollector() newPage->mainFrame()->evaluateJavaScript("testme('bar')"); } +void tst_QWebPage::localURLSchemes() +{ + int i = QWebSecurityOrigin::localSchemes().size(); + + QWebSecurityOrigin::removeLocalScheme("file"); + QTRY_COMPARE(QWebSecurityOrigin::localSchemes().size(), i); + QWebSecurityOrigin::addLocalScheme("file"); + QTRY_COMPARE(QWebSecurityOrigin::localSchemes().size(), i); + + QWebSecurityOrigin::removeLocalScheme("qrc"); + QTRY_COMPARE(QWebSecurityOrigin::localSchemes().size(), i - 1); + QWebSecurityOrigin::addLocalScheme("qrc"); + QTRY_COMPARE(QWebSecurityOrigin::localSchemes().size(), i); + + QString myscheme = "myscheme"; + QWebSecurityOrigin::addLocalScheme(myscheme); + QTRY_COMPARE(QWebSecurityOrigin::localSchemes().size(), i + 1); + QVERIFY(QWebSecurityOrigin::localSchemes().contains(myscheme)); + QWebSecurityOrigin::removeLocalScheme(myscheme); + QTRY_COMPARE(QWebSecurityOrigin::localSchemes().size(), i); + QWebSecurityOrigin::removeLocalScheme(myscheme); + QTRY_COMPARE(QWebSecurityOrigin::localSchemes().size(), i); +} + +static inline bool testFlag(QWebPage& webPage, QWebSettings::WebAttribute settingAttribute, const QString& jsObjectName, bool settingValue) +{ + webPage.settings()->setAttribute(settingAttribute, settingValue); + return webPage.mainFrame()->evaluateJavaScript(QString("(window.%1 != undefined)").arg(jsObjectName)).toBool(); +} + +void tst_QWebPage::testOptionalJSObjects() +{ + // Once a feature is enabled and the JS object is accessed turning off the setting will not turn off + // the visibility of the JS object any more. For this reason this test uses two QWebPage instances. + // Part of the test is to make sure that the QWebPage instances do not interfere with each other so turning on + // a feature for one instance will not turn it on for another. + + QWebPage webPage1; + QWebPage webPage2; + + webPage1.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl()); + webPage2.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl()); + + QEXPECT_FAIL("","Feature enabled/disabled checking problem. Look at bugs.webkit.org/show_bug.cgi?id=29867", Continue); + QCOMPARE(testFlag(webPage1, QWebSettings::OfflineWebApplicationCacheEnabled, "applicationCache", false), false); + QCOMPARE(testFlag(webPage2, QWebSettings::OfflineWebApplicationCacheEnabled, "applicationCache", true), true); + QEXPECT_FAIL("","Feature enabled/disabled checking problem. Look at bugs.webkit.org/show_bug.cgi?id=29867", Continue); + QCOMPARE(testFlag(webPage1, QWebSettings::OfflineWebApplicationCacheEnabled, "applicationCache", false), false); + QCOMPARE(testFlag(webPage2, QWebSettings::OfflineWebApplicationCacheEnabled, "applicationCache", false), true); + + QCOMPARE(testFlag(webPage1, QWebSettings::LocalStorageEnabled, "localStorage", false), false); + QCOMPARE(testFlag(webPage2, QWebSettings::LocalStorageEnabled, "localStorage", true), true); + QCOMPARE(testFlag(webPage1, QWebSettings::LocalStorageEnabled, "localStorage", false), false); + QCOMPARE(testFlag(webPage2, QWebSettings::LocalStorageEnabled, "localStorage", false), true); +} + +void tst_QWebPage::testEnablePersistentStorage() +{ + QWebPage webPage; + + // By default all persistent options should be disabled + QCOMPARE(webPage.settings()->testAttribute(QWebSettings::LocalStorageEnabled), false); + QCOMPARE(webPage.settings()->testAttribute(QWebSettings::OfflineStorageDatabaseEnabled), false); + QCOMPARE(webPage.settings()->testAttribute(QWebSettings::OfflineWebApplicationCacheEnabled), false); + QVERIFY(webPage.settings()->iconDatabasePath().isEmpty()); + + QWebSettings::enablePersistentStorage(); + + // Give it some time to initialize - icon database needs it + QTest::qWait(1000); + + QCOMPARE(webPage.settings()->testAttribute(QWebSettings::LocalStorageEnabled), true); + QCOMPARE(webPage.settings()->testAttribute(QWebSettings::OfflineStorageDatabaseEnabled), true); + QCOMPARE(webPage.settings()->testAttribute(QWebSettings::OfflineWebApplicationCacheEnabled), true); + + QVERIFY(!webPage.settings()->offlineStoragePath().isEmpty()); + QVERIFY(!webPage.settings()->offlineWebApplicationCachePath().isEmpty()); + QVERIFY(!webPage.settings()->iconDatabasePath().isEmpty()); +} + +void tst_QWebPage::defaultTextEncoding() +{ + QWebFrame* mainFrame = m_page->mainFrame(); + + QString defaultCharset = mainFrame->evaluateJavaScript("document.defaultCharset").toString(); + QVERIFY(!defaultCharset.isEmpty()); + QCOMPARE(QWebSettings::globalSettings()->defaultTextEncoding(), defaultCharset); + + m_page->settings()->setDefaultTextEncoding(QString("utf-8")); + QString charset = mainFrame->evaluateJavaScript("document.defaultCharset").toString(); + QCOMPARE(charset, QString("utf-8")); + QCOMPARE(m_page->settings()->defaultTextEncoding(), charset); + + m_page->settings()->setDefaultTextEncoding(QString()); + charset = mainFrame->evaluateJavaScript("document.defaultCharset").toString(); + QVERIFY(!charset.isEmpty()); + QCOMPARE(charset, defaultCharset); + + QWebSettings::globalSettings()->setDefaultTextEncoding(QString("utf-8")); + charset = mainFrame->evaluateJavaScript("document.defaultCharset").toString(); + QCOMPARE(charset, QString("utf-8")); + QCOMPARE(QWebSettings::globalSettings()->defaultTextEncoding(), charset); +} + +class ErrorPage : public QWebPage +{ +public: + + ErrorPage(QWidget* parent = 0): QWebPage(parent) + { + } + + virtual bool supportsExtension(Extension extension) const + { + return extension == ErrorPageExtension; + } + + virtual bool extension(Extension, const ExtensionOption* option, ExtensionReturn* output) + { + ErrorPageExtensionReturn* errorPage = static_cast<ErrorPageExtensionReturn*>(output); + + errorPage->content = "data:text/html,error"; + return true; + } +}; + +void tst_QWebPage::errorPageExtension() +{ + ErrorPage* page = new ErrorPage; + m_view->setPage(page); + + QSignalSpy spyLoadFinished(m_view, SIGNAL(loadFinished(bool))); + + m_view->setUrl(QUrl("data:text/html,foo")); + QTRY_COMPARE(spyLoadFinished.count(), 1); + + page->mainFrame()->setUrl(QUrl("http://non.existent/url")); + QTRY_COMPARE(spyLoadFinished.count(), 2); + QCOMPARE(page->mainFrame()->toPlainText(), QString("data:text/html,error")); + QCOMPARE(page->history()->count(), 2); + QCOMPARE(page->history()->currentItem().url(), QUrl("http://non.existent/url")); + QCOMPARE(page->history()->canGoBack(), true); + QCOMPARE(page->history()->canGoForward(), false); + + page->triggerAction(QWebPage::Back); + QTest::qWait(2000); + QCOMPARE(page->history()->canGoBack(), false); + QCOMPARE(page->history()->canGoForward(), true); + + page->triggerAction(QWebPage::Forward); + QTest::qWait(2000); + QCOMPARE(page->history()->canGoBack(), true); + QCOMPARE(page->history()->canGoForward(), false); + + page->triggerAction(QWebPage::Back); + QTest::qWait(2000); + QCOMPARE(page->history()->canGoBack(), false); + QCOMPARE(page->history()->canGoForward(), true); + QCOMPARE(page->history()->currentItem().url(), QUrl("data:text/html,foo")); + + m_view->setPage(0); +} + +void tst_QWebPage::errorPageExtensionInIFrames() +{ + ErrorPage* page = new ErrorPage; + m_view->setPage(page); + + m_view->setHtml(QString("data:text/html," + "<h1>h1</h1>" + "<iframe src='data:text/html,<p/>p'></iframe>" + "<iframe src='non-existent.html'></iframe>")); + QSignalSpy spyLoadFinished(m_view, SIGNAL(loadFinished(bool))); + QTRY_COMPARE(spyLoadFinished.count(), 1); + + QCOMPARE(page->mainFrame()->childFrames()[1]->toPlainText(), QString("data:text/html,error")); + + m_view->setPage(0); +} + +void tst_QWebPage::errorPageExtensionInFrameset() +{ + ErrorPage* page = new ErrorPage; + m_view->setPage(page); + + m_view->load(QUrl("qrc:///frametest/index.html")); + + QSignalSpy spyLoadFinished(m_view, SIGNAL(loadFinished(bool))); + QTRY_COMPARE(spyLoadFinished.count(), 1); + QCOMPARE(page->mainFrame()->childFrames()[1]->toPlainText(), QString("data:text/html,error")); + + m_view->setPage(0); +} + +void tst_QWebPage::crashTests_LazyInitializationOfMainFrame() +{ + { + QWebPage webPage; + } + { + QWebPage webPage; + webPage.selectedText(); + } + { + QWebPage webPage; + webPage.triggerAction(QWebPage::Back, true); + } + { + QWebPage webPage; + QPoint pos(10,10); + webPage.updatePositionDependentActions(pos); + } +} + +static void takeScreenshot(QWebPage* page) +{ + QWebFrame* mainFrame = page->mainFrame(); + page->setViewportSize(mainFrame->contentsSize()); + QImage image(page->viewportSize(), QImage::Format_ARGB32); + QPainter painter(&image); + mainFrame->render(&painter); + painter.end(); +} + +void tst_QWebPage::screenshot_data() +{ + QTest::addColumn<QString>("html"); + QTest::newRow("WithoutPlugin") << "<html><body id='b'>text</body></html>"; + QTest::newRow("WindowedPlugin") << QString("<html><body id='b'>text<embed src='resources/test.swf'></embed></body></html>"); + QTest::newRow("WindowlessPlugin") << QString("<html><body id='b'>text<embed src='resources/test.swf' wmode='transparent'></embed></body></html>"); +} + +void tst_QWebPage::screenshot() +{ + QDir::setCurrent(SRCDIR); + + QFETCH(QString, html); + QWebPage* page = new QWebPage; + page->settings()->setAttribute(QWebSettings::PluginsEnabled, true); + QWebFrame* mainFrame = page->mainFrame(); + mainFrame->setHtml(html, QUrl::fromLocalFile(QDir::currentPath())); + if (html.contains("</embed>")) { + // some reasonable time for the PluginStream to feed test.swf to flash and start painting + QTest::qWait(2000); + } + + // take screenshot without a view + takeScreenshot(page); + + QWebView* view = new QWebView; + view->setPage(page); + + // take screenshot when attached to a view + takeScreenshot(page); + + delete page; + delete view; + + QDir::setCurrent(QApplication::applicationDirPath()); +} + +void tst_QWebPage::originatingObjectInNetworkRequests() +{ + TestNetworkManager* networkManager = new TestNetworkManager(m_page); + m_page->setNetworkAccessManager(networkManager); + networkManager->requests.clear(); + + m_view->setHtml(QString("data:text/html,<frameset cols=\"25%,75%\"><frame src=\"data:text/html," + "<head><meta http-equiv='refresh' content='1'></head>foo \">" + "<frame src=\"data:text/html,bar\"></frameset>"), QUrl()); + QVERIFY(::waitForSignal(m_view, SIGNAL(loadFinished(bool)))); + + QCOMPARE(networkManager->requests.count(), 2); + + QList<QWebFrame*> childFrames = m_page->mainFrame()->childFrames(); + QCOMPARE(childFrames.count(), 2); + +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + for (int i = 0; i < 2; ++i) + QVERIFY(qobject_cast<QWebFrame*>(networkManager->requests.at(i).originatingObject()) == childFrames.at(i)); +#endif +} + QTEST_MAIN(tst_QWebPage) #include "tst_qwebpage.moc" diff --git a/WebKit/qt/tests/qwebplugindatabase/qwebplugindatabase.pro b/WebKit/qt/tests/qwebplugindatabase/qwebplugindatabase.pro index 5d10993..569146a 100644 --- a/WebKit/qt/tests/qwebplugindatabase/qwebplugindatabase.pro +++ b/WebKit/qt/tests/qwebplugindatabase/qwebplugindatabase.pro @@ -4,3 +4,8 @@ include(../../../../WebKit.pri) SOURCES += tst_qwebplugindatabase.cpp QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR + +symbian { + TARGET.UID3 = 0xA000E540 + TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices +} diff --git a/WebKit/qt/tests/qwebplugindatabase/tst_qwebplugindatabase.cpp b/WebKit/qt/tests/qwebplugindatabase/tst_qwebplugindatabase.cpp index c0533ad..1ee6206 100644 --- a/WebKit/qt/tests/qwebplugindatabase/tst_qwebplugindatabase.cpp +++ b/WebKit/qt/tests/qwebplugindatabase/tst_qwebplugindatabase.cpp @@ -40,6 +40,8 @@ private slots: void operatorequal_data(); void operatorequal(); void preferredPlugin(); + void operatorassign_data(); + void operatorassign(); }; typedef QWebPluginInfo::MimeType MimeType; @@ -396,6 +398,40 @@ void tst_QWebPluginDatabase::preferredPlugin() } } +void tst_QWebPluginDatabase::operatorassign_data() +{ + QTest::addColumn<QWebPluginInfo>("first"); + QTest::addColumn<QWebPluginInfo>("second"); + + QWebPluginDatabase* database = QWebSettings::pluginDatabase(); + QTest::newRow("null") << QWebPluginInfo() << QWebPluginInfo(); + + QList<QWebPluginInfo> plugins = database->plugins(); + for (int i = 0; i < (plugins.count() - 1); ++i) { + QWebPluginInfo first = plugins.at(i); + QWebPluginInfo second = plugins.at(i + 1); + + QTest::newRow(QString("%1=%2").arg(first.name(), second.name()).toUtf8().constData()) << first << second; + } +} + +void tst_QWebPluginDatabase::operatorassign() +{ + QFETCH(QWebPluginInfo, first); + QFETCH(QWebPluginInfo, second); + + QWebPluginInfo info; + QCOMPARE(info.mimeTypes(), QList<MimeType>()); + QCOMPARE(info = first, first); + QCOMPARE(info, first); + QCOMPARE(info.mimeTypes(), first.mimeTypes()); + QCOMPARE(info = second, second); + QCOMPARE(info, second); + QCOMPARE(info.mimeTypes(), second.mimeTypes()); + QCOMPARE(info = QWebPluginInfo(), QWebPluginInfo()); + QCOMPARE(info.mimeTypes(), QList<MimeType>()); +} + QTEST_MAIN(tst_QWebPluginDatabase) #include "tst_qwebplugindatabase.moc" diff --git a/WebKit/qt/tests/qwebview/data/frame_a.html b/WebKit/qt/tests/qwebview/data/frame_a.html new file mode 100644 index 0000000..9ff68f1 --- /dev/null +++ b/WebKit/qt/tests/qwebview/data/frame_a.html @@ -0,0 +1,2 @@ +<a href="http://google.com" target="frame_b"><img src="" width=100 height=100 alt="Google"></a> +<a href="http://yahoo.com" target="frame_b"><img src="" width=100 height=100 alt="Yahoo"></a> diff --git a/WebKit/qt/tests/qwebview/data/index.html b/WebKit/qt/tests/qwebview/data/index.html new file mode 100644 index 0000000..c53ad09 --- /dev/null +++ b/WebKit/qt/tests/qwebview/data/index.html @@ -0,0 +1,4 @@ +<frameset cols="25%,75%"> + <frame src="frame_a.html" name="frame_a"> + <frame src="frame_b.html" name="frame_b"> +</frameset> diff --git a/WebKit/qt/tests/qwebview/qwebview.pro b/WebKit/qt/tests/qwebview/qwebview.pro index 799ccfb..735537b 100644 --- a/WebKit/qt/tests/qwebview/qwebview.pro +++ b/WebKit/qt/tests/qwebview/qwebview.pro @@ -4,3 +4,10 @@ include(../../../../WebKit.pri) SOURCES += tst_qwebview.cpp QT += testlib network QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR +RESOURCES += tst_qwebview.qrc +DEFINES += SRCDIR=\\\"$$PWD/\\\" + +symbian { + TARGET.UID3 = 0xA000E53F + TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices +} diff --git a/WebKit/qt/tests/qwebview/tst_qwebview.cpp b/WebKit/qt/tests/qwebview/tst_qwebview.cpp index 01d0e92..bd2f185 100644 --- a/WebKit/qt/tests/qwebview/tst_qwebview.cpp +++ b/WebKit/qt/tests/qwebview/tst_qwebview.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) Copyright (C) 2009 Torch Mobile Inc. + Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -19,6 +20,7 @@ */ #include <qtest.h> +#include "../util.h" #include <qpainter.h> #include <qwebview.h> @@ -26,6 +28,7 @@ #include <qnetworkrequest.h> #include <qdiriterator.h> #include <qwebkitversion.h> +#include <qwebframe.h> class tst_QWebView : public QObject { @@ -39,9 +42,12 @@ public slots: private slots: void renderHints(); - void guessUrlFromString_data(); - void guessUrlFromString(); void getWebKitVersion(); + + void reusePage_data(); + void reusePage(); + + void crashTests(); }; // This will be called before the first test function is executed. @@ -100,73 +106,91 @@ void tst_QWebView::renderHints() QVERIFY(!(webView.renderHints() & QPainter::HighQualityAntialiasing)); } -void tst_QWebView::guessUrlFromString_data() +void tst_QWebView::getWebKitVersion() { - QTest::addColumn<QString>("string"); - QTest::addColumn<QUrl>("guessUrlFromString"); - - // Null - QTest::newRow("null") << QString() << QUrl(); - - // File - QDirIterator it(QDir::homePath()); - QString fileString; - int c = 0; - while (it.hasNext()) { - it.next(); - QTest::newRow(QString("file-%1").arg(c++).toLatin1()) << it.filePath() << QUrl::fromLocalFile(it.filePath()); - } + QVERIFY(qWebKitVersion().toDouble() > 0); +} - // basic latin1 - QTest::newRow("unicode-0") << QString::fromUtf8("å.com/") << QUrl::fromEncoded(QString::fromUtf8("http://å.com/").toUtf8(), QUrl::TolerantMode); - // unicode - QTest::newRow("unicode-1") << QString::fromUtf8("λ.com/") << QUrl::fromEncoded(QString::fromUtf8("http://λ.com/").toUtf8(), QUrl::TolerantMode); - - // no scheme - QTest::newRow("add scheme-0") << "webkit.org" << QUrl("http://webkit.org"); - QTest::newRow("add scheme-1") << "www.webkit.org" << QUrl("http://www.webkit.org"); - QTest::newRow("add scheme-2") << "ftp.webkit.org" << QUrl("ftp://ftp.webkit.org"); - QTest::newRow("add scheme-3") << "webkit" << QUrl("webkit"); - - // QUrl's tolerant parser should already handle this - QTest::newRow("not-encoded-0") << "http://webkit.org/test page.html" << QUrl("http://webkit.org/test%20page.html"); - - // Make sure the :80, i.e. port doesn't screw anything up - QUrl portUrl("http://webkit.org"); - portUrl.setPort(80); - QTest::newRow("port-0") << "webkit.org:80" << portUrl; - QTest::newRow("port-1") << "http://webkit.org:80" << portUrl; - - // mailto doesn't have a ://, but is valid - QUrl mailto("ben@meyerhome.net"); - mailto.setScheme("mailto"); - QTest::newRow("mailto") << "mailto:ben@meyerhome.net" << mailto; - - // misc - QTest::newRow("localhost-0") << "localhost" << QUrl("http://localhost"); - QTest::newRow("localhost-1") << "localhost:80" << QUrl("http://localhost:80"); - QTest::newRow("spaces-0") << " http://webkit.org/test page.html " << QUrl("http://webkit.org/test%20page.html"); - - // FYI: The scheme in the resulting url user - QUrl authUrl("user:pass@domain.com"); - QTest::newRow("misc-1") << "user:pass@domain.com" << authUrl; +void tst_QWebView::reusePage_data() +{ + QTest::addColumn<QString>("html"); + QTest::newRow("WithoutPlugin") << "<html><body id='b'>text</body></html>"; + QTest::newRow("WindowedPlugin") << QString("<html><body id='b'>text<embed src='resources/test.swf'></embed></body></html>"); + QTest::newRow("WindowlessPlugin") << QString("<html><body id='b'>text<embed src='resources/test.swf' wmode=\"transparent\"></embed></body></html>"); } -// public static QUrl guessUrlFromString(QString const& string) -void tst_QWebView::guessUrlFromString() +void tst_QWebView::reusePage() { - QFETCH(QString, string); - QFETCH(QUrl, guessUrlFromString); + QDir::setCurrent(SRCDIR); + + QFETCH(QString, html); + QWebView* view1 = new QWebView; + QPointer<QWebPage> page = new QWebPage; + view1->setPage(page); + page->settings()->setAttribute(QWebSettings::PluginsEnabled, true); + QWebFrame* mainFrame = page->mainFrame(); + mainFrame->setHtml(html, QUrl::fromLocalFile(QDir::currentPath())); + if (html.contains("</embed>")) { + // some reasonable time for the PluginStream to feed test.swf to flash and start painting + waitForSignal(view1, SIGNAL(loadFinished(bool)), 2000); + } + + view1->show(); + QTest::qWaitForWindowShown(view1); + delete view1; + QVERIFY(page != 0); // deleting view must not have deleted the page, since it's not a child of view - QUrl url = QWebView::guessUrlFromString(string); - QCOMPARE(url, guessUrlFromString); + QWebView *view2 = new QWebView; + view2->setPage(page); + view2->show(); // in Windowless mode, you should still be able to see the plugin here + QTest::qWaitForWindowShown(view2); + delete view2; + + delete page; // must not crash + + QDir::setCurrent(QApplication::applicationDirPath()); } -void tst_QWebView::getWebKitVersion() +// Class used in crashTests +class WebViewCrashTest : public QObject { + Q_OBJECT + QWebView* m_view; +public: + bool m_executed; + + + WebViewCrashTest(QWebView* view) + : m_view(view) + , m_executed(false) + { + view->connect(view, SIGNAL(loadProgress(int)), this, SLOT(loading(int))); + } + +private slots: + void loading(int progress) + { + if (progress >= 20 && progress < 90) { + QVERIFY(!m_executed); + m_view->stop(); + m_executed = true; + } + } +}; + + +// Should not crash. +void tst_QWebView::crashTests() { - QVERIFY(qWebKitVersion().toDouble() > 0); + // Test if loading can be stopped in loadProgress handler without crash. + // Test page should have frames. + QWebView view; + WebViewCrashTest tester(&view); + QUrl url("qrc:///data/index.html"); + view.load(url); + QTRY_VERIFY(tester.m_executed); // If fail it means that the test wasn't executed. } + QTEST_MAIN(tst_QWebView) #include "tst_qwebview.moc" diff --git a/WebKit/qt/tests/qwebview/tst_qwebview.qrc b/WebKit/qt/tests/qwebview/tst_qwebview.qrc new file mode 100644 index 0000000..ede34a9 --- /dev/null +++ b/WebKit/qt/tests/qwebview/tst_qwebview.qrc @@ -0,0 +1,7 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource> + <file>data/index.html</file> + <file>data/frame_a.html</file> +</qresource> +</RCC> + diff --git a/WebKit/qt/tests/resources/test.swf b/WebKit/qt/tests/resources/test.swf Binary files differnew file mode 100644 index 0000000..8952982 --- /dev/null +++ b/WebKit/qt/tests/resources/test.swf diff --git a/WebKit/qt/tests/tests.pro b/WebKit/qt/tests/tests.pro index b5f66ee..b967ca9 100644 --- a/WebKit/qt/tests/tests.pro +++ b/WebKit/qt/tests/tests.pro @@ -1,4 +1,4 @@ TEMPLATE = subdirs -SUBDIRS = qwebframe qwebpage qwebelement qwebhistoryinterface qwebplugindatabase qwebview qwebhistory +SUBDIRS = qwebframe qwebpage qwebelement qgraphicswebview qwebhistoryinterface qwebview qwebhistory qwebinspector greaterThan(QT_MINOR_VERSION, 4): SUBDIRS += benchmarks/painting/tst_painting.pro benchmarks/loading/tst_loading.pro diff --git a/WebKit/qt/tests/util.h b/WebKit/qt/tests/util.h new file mode 100644 index 0000000..15af262 --- /dev/null +++ b/WebKit/qt/tests/util.h @@ -0,0 +1,74 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + 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. +*/ +// Functions and macros that really need to be in QTestLib + +#include <QEventLoop> +#include <QSignalSpy> +#include <QTimer> + +/** + * Starts an event loop that runs until the given signal is received. + * Optionally the event loop + * can return earlier on a timeout. + * + * \return \p true if the requested signal was received + * \p false on timeout + */ +static bool waitForSignal(QObject* obj, const char* signal, int timeout = 10000) +{ + QEventLoop loop; + QObject::connect(obj, signal, &loop, SLOT(quit())); + QTimer timer; + QSignalSpy timeoutSpy(&timer, SIGNAL(timeout())); + if (timeout > 0) { + QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); + timer.setSingleShot(true); + timer.start(timeout); + } + loop.exec(); + return timeoutSpy.isEmpty(); +} + +// Will try to wait for the condition while allowing event processing +#define QTRY_VERIFY(__expr) \ + do { \ + const int __step = 50; \ + const int __timeout = 5000; \ + if (!(__expr)) { \ + QTest::qWait(0); \ + } \ + for (int __i = 0; __i < __timeout && !(__expr); __i+=__step) { \ + QTest::qWait(__step); \ + } \ + QVERIFY(__expr); \ + } while(0) + +// Will try to wait for the condition while allowing event processing +#define QTRY_COMPARE(__expr, __expected) \ + do { \ + const int __step = 50; \ + const int __timeout = 5000; \ + if ((__expr) != (__expected)) { \ + QTest::qWait(0); \ + } \ + for (int __i = 0; __i < __timeout && ((__expr) != (__expected)); __i+=__step) { \ + QTest::qWait(__step); \ + } \ + QCOMPARE(__expr, __expected); \ + } while(0) |
