diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-01-06 14:44:00 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-01-06 14:44:00 +0100 |
commit | 40736c5763bf61337c8c14e16d8587db021a87d4 (patch) | |
tree | b17a9c00042ad89cb1308e2484491799aa14e9f8 /Source/WebKit2/UIProcess/API/qt | |
download | qtwebkit-40736c5763bf61337c8c14e16d8587db021a87d4.tar.gz |
Imported WebKit commit 2ea9d364d0f6efa8fa64acf19f451504c59be0e4 (http://svn.webkit.org/repository/webkit/trunk@104285)
Diffstat (limited to 'Source/WebKit2/UIProcess/API/qt')
76 files changed, 6191 insertions, 0 deletions
diff --git a/Source/WebKit2/UIProcess/API/qt/qquicknetworkreply.cpp b/Source/WebKit2/UIProcess/API/qt/qquicknetworkreply.cpp new file mode 100644 index 000000000..4e8810302 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qquicknetworkreply.cpp @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2011 Zeno Albisser <zeno@webkit.org> + * + * 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 program 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 program; 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 "qquicknetworkreply_p.h" + +#include "QtNetworkReplyData.h" +#include "QtNetworkRequestData.h" +#include "qquickwebview_p.h" +#include <QDateTime> + +using namespace WebKit; + +QQuickNetworkReply::QQuickNetworkReply(QObject* parent) + : QObject(parent) + , m_networkReplyData(adoptRef(new WebKit::QtNetworkReplyData)) +{ + Q_ASSERT(parent); +} + +QString QQuickNetworkReply::contentType() const +{ + return m_networkReplyData->m_contentType; +} + +void QQuickNetworkReply::setContentType(const QString& contentType) +{ + m_networkReplyData->m_contentType = contentType; +} + +QNetworkAccessManager::Operation QQuickNetworkReply::operation() const +{ + return m_networkReplyData->m_operation; +} + +void QQuickNetworkReply::setOperation(QNetworkAccessManager::Operation operation) +{ + m_networkReplyData->m_operation = operation; +} + +QString QQuickNetworkReply::contentDisposition() const +{ + return m_networkReplyData->m_contentDisposition; +} + +void QQuickNetworkReply::setContentDisposition(const QString& disposition) +{ + m_networkReplyData->m_contentDisposition = disposition; +} + +QString QQuickNetworkReply::location() const +{ + return m_networkReplyData->m_location; +} + +void QQuickNetworkReply::setLocation(const QString& location) +{ + m_networkReplyData->m_location = location; +} + +QString QQuickNetworkReply::lastModified() const +{ + return QDateTime::fromMSecsSinceEpoch(m_networkReplyData->m_lastModified).toString(Qt::ISODate); +} + +void QQuickNetworkReply::setLastModified(const QString& lastModified) +{ + m_networkReplyData->m_lastModified = QDateTime::fromString(lastModified, Qt::ISODate).toMSecsSinceEpoch(); +} + +QString QQuickNetworkReply::cookie() const +{ + return m_networkReplyData->m_cookie; +} + +void QQuickNetworkReply::setCookie(const QString& cookie) +{ + m_networkReplyData->m_cookie = cookie; +} + +QString QQuickNetworkReply::userAgent() const +{ + return m_networkReplyData->m_userAgent; +} + +void QQuickNetworkReply::setUserAgent(const QString& userAgent) +{ + m_networkReplyData->m_userAgent = userAgent; +} + +QString QQuickNetworkReply::server() const +{ + return m_networkReplyData->m_server; +} + +void QQuickNetworkReply::setServer(const QString& server) +{ + m_networkReplyData->m_server = server; +} + +QString QQuickNetworkReply::data() const +{ + if (m_networkReplyData->m_dataHandle.isNull()) + return QString(); + RefPtr<SharedMemory> sm = SharedMemory::create(m_networkReplyData->m_dataHandle, SharedMemory::ReadOnly); + if (!sm) + return QString(); + + uint64_t stringLength = m_networkReplyData->m_contentLength / sizeof(UChar); + return QString(reinterpret_cast<const QChar*>(sm->data()), stringLength); +} + +void QQuickNetworkReply::setData(const QString& data) +{ + // This function can be called several times. In this case the previous SharedMemory handles + // will be overwritten and the previously allocated SharedMemory will die with the last handle. + m_networkReplyData->m_contentLength = 0; + + if (data.isNull()) + return; + const UChar* ucharData = reinterpret_cast<const UChar*>(data.constData()); + uint64_t smLength = sizeof(UChar) * data.length(); + + RefPtr<SharedMemory> sm = SharedMemory::create(smLength); + if (!sm) + return; + // The size of the allocated shared memory can be bigger than requested. + // Usually the size will be rounded up to the next multiple of a page size. + memcpy(sm->data(), ucharData, smLength); + + if (!sm->createHandle(m_networkReplyData->m_dataHandle, SharedMemory::ReadOnly)) + return; + m_networkReplyData->m_contentLength = smLength; +} + +void QQuickNetworkReply::send() +{ + QObject* schemeParent = parent()->parent(); + if (!schemeParent) + return; + QQuickWebViewExperimental* webViewExperimental = qobject_cast<QQuickWebViewExperimental*>(schemeParent->parent()); + if (!webViewExperimental) + return; + webViewExperimental->sendApplicationSchemeReply(this); +} + +WTF::RefPtr<WebKit::QtNetworkRequestData> QQuickNetworkReply::networkRequestData() const +{ + return m_networkRequestData; +} + +void QQuickNetworkReply::setNetworkRequestData(WTF::RefPtr<WebKit::QtNetworkRequestData> data) +{ + m_networkRequestData = data; + m_networkReplyData->m_replyUuid = data->m_replyUuid; +} + +WTF::RefPtr<WebKit::QtNetworkReplyData> QQuickNetworkReply::networkReplyData() const +{ + return m_networkReplyData; +} + +#include "moc_qquicknetworkreply_p.cpp" diff --git a/Source/WebKit2/UIProcess/API/qt/qquicknetworkreply_p.h b/Source/WebKit2/UIProcess/API/qt/qquicknetworkreply_p.h new file mode 100644 index 000000000..ffe45f3c9 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qquicknetworkreply_p.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2011 Zeno Albisser <zeno@webkit.org> + * + * 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 program 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 program; 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 qquicknetworkreply_p_h +#define qquicknetworkreply_p_h + +#include "QtNetworkReplyData.h" +#include "QtNetworkRequestData.h" +#include "qwebkitglobal.h" +#include <QNetworkAccessManager> +#include <QObject> +#include <QtDeclarative/qdeclarativelist.h> +#include <QtQuick/qquickitem.h> + +class QWEBKIT_EXPORT QQuickNetworkReply : public QObject { + Q_OBJECT + Q_PROPERTY(QString contentType READ contentType WRITE setContentType) + Q_PROPERTY(QString data READ data WRITE setData) + Q_ENUMS(QNetworkAccessManager::Operation) + +public: + QQuickNetworkReply(QObject* parent); + QString contentType() const; + void setContentType(const QString&); + QNetworkAccessManager::Operation operation() const; + void setOperation(QNetworkAccessManager::Operation); + QString contentDisposition() const; + void setContentDisposition(const QString&); + QString location() const; + void setLocation(const QString&); + QString lastModified() const; + void setLastModified(const QString&); + QString cookie() const; + void setCookie(const QString&); + QString userAgent() const; + void setUserAgent(const QString&); + QString server() const; + void setServer(const QString&); + + QString data() const; + void setData(const QString& data); + + WTF::RefPtr<WebKit::QtNetworkRequestData> networkRequestData() const; + void setNetworkRequestData(WTF::RefPtr<WebKit::QtNetworkRequestData> data); + WTF::RefPtr<WebKit::QtNetworkReplyData> networkReplyData() const; + +public Q_SLOTS: + void send(); + +private: + WTF::RefPtr<WebKit::QtNetworkRequestData> m_networkRequestData; + WTF::RefPtr<WebKit::QtNetworkReplyData> m_networkReplyData; +}; + +QML_DECLARE_TYPE(QQuickNetworkReply) + +#endif // qquicknetworkreply_p_h + diff --git a/Source/WebKit2/UIProcess/API/qt/qquicknetworkrequest_p.h b/Source/WebKit2/UIProcess/API/qt/qquicknetworkrequest_p.h new file mode 100644 index 000000000..113114c87 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qquicknetworkrequest_p.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2011 Zeno Albisser <zeno@webkit.org> + * + * 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 program 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 program; 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 qquicknetworkrequest_p_h +#define qquicknetworkrequest_p_h + +#include "qwebkitglobal.h" +#include <QObject> +#include <QtDeclarative/qdeclarativelist.h> +#include <QtQuick/qquickitem.h> + +class QWEBKIT_EXPORT QQuickNetworkRequest : public QObject { + Q_OBJECT + Q_PROPERTY(QString url READ url) + +public: + QQuickNetworkRequest(QObject* parent) + : QObject(parent) + { + Q_ASSERT(parent); + } + + QString url() const { return m_url; } + void setUrl(const QString& url) { m_url = url; } + +private: + QString m_url; +}; + +QML_DECLARE_TYPE(QQuickNetworkRequest) + +#endif // qquicknetworkrequest_p_h + diff --git a/Source/WebKit2/UIProcess/API/qt/qquickurlschemedelegate.cpp b/Source/WebKit2/UIProcess/API/qt/qquickurlschemedelegate.cpp new file mode 100644 index 000000000..e5d63043b --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qquickurlschemedelegate.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2011 Zeno Albisser <zeno@webkit.org> + * + * 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 program 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 program; 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 "qquickurlschemedelegate_p.h" + +#include "qquicknetworkreply_p.h" +#include "qquicknetworkrequest_p.h" + +QQuickUrlSchemeDelegate::QQuickUrlSchemeDelegate(QObject* parent) + : QObject(parent) + , m_request(new QQuickNetworkRequest(this)) + , m_reply(new QQuickNetworkReply(this)) +{ } + +QString QQuickUrlSchemeDelegate::scheme() const +{ + return m_scheme; +} + +void QQuickUrlSchemeDelegate::setScheme(const QString& scheme) +{ + m_scheme = scheme; + emit schemeChanged(); +} + +QQuickNetworkRequest* QQuickUrlSchemeDelegate::request() const +{ + return m_request; +} + +QQuickNetworkReply* QQuickUrlSchemeDelegate::reply() const +{ + return m_reply; +} + +#include "moc_qquickurlschemedelegate_p.cpp" diff --git a/Source/WebKit2/UIProcess/API/qt/qquickurlschemedelegate_p.h b/Source/WebKit2/UIProcess/API/qt/qquickurlschemedelegate_p.h new file mode 100644 index 000000000..6ee602754 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qquickurlschemedelegate_p.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2011 Zeno Albisser <zeno@webkit.org> + * + * 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 program 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 program; 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 qquickurlschemedelegate_p_h +#define qquickurlschemedelegate_p_h + +#include "qwebkitglobal.h" +#include <QObject> +#include <QtQuick/qquickitem.h> + +class QQuickNetworkRequest; +class QQuickNetworkReply; + +class QWEBKIT_EXPORT QQuickUrlSchemeDelegate : public QObject { + Q_OBJECT + Q_PROPERTY(QString scheme READ scheme WRITE setScheme NOTIFY schemeChanged) + Q_PROPERTY(QQuickNetworkRequest* request READ request) + Q_PROPERTY(QQuickNetworkReply* reply READ reply) + +public: + QQuickUrlSchemeDelegate(QObject* parent = 0); + QString scheme() const; + void setScheme(const QString& scheme); + QQuickNetworkRequest* request() const; + QQuickNetworkReply* reply() const; + +Q_SIGNALS: + void schemeChanged(); + void receivedRequest(); + +private: + QString m_scheme; + QQuickNetworkRequest* m_request; + QQuickNetworkReply* m_reply; +}; + +QML_DECLARE_TYPE(QQuickUrlSchemeDelegate) + +#endif // qquickurlschemedelegate_p_h + + diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp new file mode 100644 index 000000000..7d3b2d6a6 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp @@ -0,0 +1,339 @@ +/* + * Copyright (C) 2010, 2011 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 program 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 program; 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 "qquickwebpage_p.h" + +#include "LayerTreeHostProxy.h" +#include "QtWebPageEventHandler.h" +#include "TransformationMatrix.h" +#include "qquickwebpage_p_p.h" +#include <QtQuick/QQuickCanvas> +#include <QtQuick/QSGGeometryNode> +#include <QtQuick/QSGMaterial> + +QQuickWebPage::QQuickWebPage(QQuickItem* parent) + : QQuickItem(parent) + , d(new QQuickWebPagePrivate(this)) +{ + setFlag(ItemHasContents); + + // We do the transform from the top left so the viewport can assume the position 0, 0 + // is always where rendering starts. + setTransformOrigin(TopLeft); +} + +QQuickWebPage::~QQuickWebPage() +{ + delete d; +} + +QtSGUpdateQueue *QQuickWebPage::sceneGraphUpdateQueue() const +{ + return &d->sgUpdateQueue; +} + +void QQuickWebPage::keyPressEvent(QKeyEvent* event) +{ + this->event(event); +} + +void QQuickWebPage::keyReleaseEvent(QKeyEvent* event) +{ + this->event(event); +} + +void QQuickWebPage::inputMethodEvent(QInputMethodEvent* event) +{ + this->event(event); +} + +void QQuickWebPage::focusInEvent(QFocusEvent* event) +{ + this->event(event); +} + +void QQuickWebPage::focusOutEvent(QFocusEvent* event) +{ + this->event(event); +} + +void QQuickWebPage::mousePressEvent(QMouseEvent* event) +{ + forceActiveFocus(); + this->event(event); +} + +void QQuickWebPage::mouseMoveEvent(QMouseEvent* event) +{ + this->event(event); +} + +void QQuickWebPage::mouseReleaseEvent(QMouseEvent* event) +{ + this->event(event); +} + +void QQuickWebPage::mouseDoubleClickEvent(QMouseEvent* event) +{ + this->event(event); +} + +void QQuickWebPage::wheelEvent(QWheelEvent* event) +{ + this->event(event); +} + +void QQuickWebPage::hoverEnterEvent(QHoverEvent* event) +{ + this->event(event); +} + +void QQuickWebPage::hoverMoveEvent(QHoverEvent* event) +{ + this->event(event); +} + +void QQuickWebPage::hoverLeaveEvent(QHoverEvent* event) +{ + this->event(event); +} + +void QQuickWebPage::dragMoveEvent(QDragMoveEvent* event) +{ + this->event(event); +} + +void QQuickWebPage::dragEnterEvent(QDragEnterEvent* event) +{ + this->event(event); +} + +void QQuickWebPage::dragLeaveEvent(QDragLeaveEvent* event) +{ + this->event(event); +} + +void QQuickWebPage::dropEvent(QDropEvent* event) +{ + this->event(event); +} + +void QQuickWebPage::geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry) +{ + QQuickItem::geometryChanged(newGeometry, oldGeometry); + if (newGeometry.size() != oldGeometry.size()) + d->setDrawingAreaSize(newGeometry.size().toSize()); +} + +bool QQuickWebPage::event(QEvent* ev) +{ + if (d->eventHandler.data()->handleEvent(ev)) + return true; + if (ev->type() == QEvent::InputMethod) + return false; // This is necessary to avoid an endless loop in connection with QQuickItem::event(). + return QQuickItem::event(ev); +} + +void QQuickWebPage::touchEvent(QTouchEvent* event) +{ + forceActiveFocus(); + this->event(event); +} + +QQuickWebPagePrivate::QQuickWebPagePrivate(QQuickWebPage* q) + : q(q) + , webPageProxy(0) + , sgUpdateQueue(q) + , paintingIsInitialized(false) + , m_paintNode(0) +{ +} + +void QQuickWebPagePrivate::initialize(WebKit::WebPageProxy* webPageProxy) +{ + this->webPageProxy = webPageProxy; + eventHandler.reset(new QtWebPageEventHandler(toAPI(webPageProxy), q)); +} + +static float computeEffectiveOpacity(const QQuickItem* item) +{ + if (!item) + return 1; + + float opacity = item->opacity(); + if (opacity < 0.01) + return 0; + + return opacity * computeEffectiveOpacity(item->parentItem()); +} + +void QQuickWebPagePrivate::setDrawingAreaSize(const QSize& size) +{ + DrawingAreaProxy* drawingArea = webPageProxy->drawingArea(); + if (!drawingArea) + return; + drawingArea->setSize(WebCore::IntSize(size), WebCore::IntSize()); +} + +void QQuickWebPagePrivate::paintToCurrentGLContext() +{ + if (!q->isVisible()) + return; + + QTransform transform = q->itemTransform(0, 0); + + float opacity = computeEffectiveOpacity(q); + QRectF clipRect = q->parentItem()->mapRectToScene(q->parentItem()->boundingRect()); + + if (!clipRect.isValid()) + return; + + DrawingAreaProxy* drawingArea = webPageProxy->drawingArea(); + if (!drawingArea) + return; + + // Make sure that no GL error code stays from previous QT operations. + glGetError(); + + glEnable(GL_SCISSOR_TEST); + ASSERT(!glGetError()); + const int left = clipRect.left(); + const int width = clipRect.width(); + const int bottom = q->canvas()->height() - (clipRect.bottom() + 1); + const int height = clipRect.height(); + + glScissor(left, bottom, width, height); + ASSERT(!glGetError()); + + drawingArea->paintToCurrentGLContext(transform, opacity); + + glDisable(GL_SCISSOR_TEST); + ASSERT(!glGetError()); +} + +struct PageProxyMaterial; +struct PageProxyNode; + +// FIXME: temporary until Qt Scenegraph will support custom painting. +struct PageProxyMaterialShader : public QSGMaterialShader { + virtual void updateState(const RenderState& state, QSGMaterial* newMaterial, QSGMaterial* oldMaterial); + virtual char const* const* attributeNames() const + { + static char const* const attr[] = { "vertex", 0 }; + return attr; + } + + // vertexShader and fragmentShader are no-op shaders. + // All real painting is gone by TextureMapper through LayerTreeHostProxy. + virtual const char* vertexShader() const + { + return "attribute highp vec4 vertex; \n" + "void main() { gl_Position = vertex; }"; + } + + virtual const char* fragmentShader() const + { + return "void main() { gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); }"; + } +}; + +struct PageProxyMaterial : public QSGMaterial { + PageProxyMaterial(PageProxyNode* node) : m_node(node) { } + + QSGMaterialType* type() const + { + static QSGMaterialType type; + return &type; + } + + QSGMaterialShader* createShader() const + { + return new PageProxyMaterialShader; + } + + PageProxyNode* m_node; +}; + +struct PageProxyNode : public QSGGeometryNode { + PageProxyNode(QQuickWebPagePrivate* page) : + m_pagePrivate(page) + , m_material(this) + , m_geometry(QSGGeometry::defaultAttributes_Point2D(), 4) + { + setGeometry(&m_geometry); + setMaterial(&m_material); + } + + ~PageProxyNode() + { + if (m_pagePrivate) + m_pagePrivate->resetPaintNode(); + } + + QQuickWebPagePrivate* m_pagePrivate; + PageProxyMaterial m_material; + QSGGeometry m_geometry; +}; + +void PageProxyMaterialShader::updateState(const RenderState& state, QSGMaterial* newMaterial, QSGMaterial* oldMaterial) +{ + if (!newMaterial) + return; + + PageProxyNode* node = static_cast<PageProxyMaterial*>(newMaterial)->m_node; + // FIXME: Normally we wouldn't paint inside QSGMaterialShader::updateState, + // but this is a temporary hack until custom paint nodes are available. + if (node->m_pagePrivate) + node->m_pagePrivate->paintToCurrentGLContext(); +} + +QSGNode* QQuickWebPage::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*) +{ + if (!(flags() & ItemHasContents)) { + if (oldNode) + delete oldNode; + return 0; + } + + PageProxyNode* proxyNode = static_cast<PageProxyNode*>(oldNode); + if (!proxyNode) { + proxyNode = new PageProxyNode(d); + d->m_paintNode = proxyNode; + } + + return proxyNode; +} + +void QQuickWebPagePrivate::resetPaintNode() +{ + m_paintNode = 0; + DrawingAreaProxy* drawingArea = webPageProxy->drawingArea(); + if (drawingArea && drawingArea->layerTreeHostProxy()) + drawingArea->layerTreeHostProxy()->purgeGLResources(); +} + +QQuickWebPagePrivate::~QQuickWebPagePrivate() +{ + if (m_paintNode) + static_cast<PageProxyNode*>(m_paintNode)->m_pagePrivate = 0; +} + +#include "moc_qquickwebpage_p.cpp" diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p.h new file mode 100644 index 000000000..f7c35064e --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2011 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 program 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 program; 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 qquickwebpage_p_h +#define qquickwebpage_p_h + +#include "qwebkitglobal.h" + +#include <QtCore/QSharedPointer> +#include <QtQuick/QQuickItem> + +class QQuickWebPagePrivate; +class QWebPreferences; + +namespace WebKit { +class QtSGUpdateQueue; +} + +class QWEBKIT_EXPORT QQuickWebPage : public QQuickItem { + Q_OBJECT +public: + QQuickWebPage(QQuickItem* parent = 0); + virtual ~QQuickWebPage(); + + // Internal. To be removed soon. + WebKit::QtSGUpdateQueue* sceneGraphUpdateQueue() const; + +protected: + virtual void keyPressEvent(QKeyEvent*); + virtual void keyReleaseEvent(QKeyEvent*); + virtual void inputMethodEvent(QInputMethodEvent*); + virtual void focusInEvent(QFocusEvent*); + virtual void focusOutEvent(QFocusEvent*); + virtual void mousePressEvent(QMouseEvent*); + virtual void mouseMoveEvent(QMouseEvent*); + virtual void mouseReleaseEvent(QMouseEvent *); + virtual void mouseDoubleClickEvent(QMouseEvent*); + virtual void wheelEvent(QWheelEvent*); + virtual void hoverEnterEvent(QHoverEvent*); + virtual void hoverMoveEvent(QHoverEvent*); + virtual void hoverLeaveEvent(QHoverEvent*); + virtual void dragMoveEvent(QDragMoveEvent*); + virtual void dragEnterEvent(QDragEnterEvent*); + virtual void dragLeaveEvent(QDragLeaveEvent*); + virtual void dropEvent(QDropEvent*); + virtual void touchEvent(QTouchEvent*); + virtual bool event(QEvent*); + virtual void geometryChanged(const QRectF&, const QRectF&); + virtual QSGNode* updatePaintNode(QSGNode*, UpdatePaintNodeData*); + +private: + QQuickWebPagePrivate* d; + friend class QQuickWebView; + friend class QQuickWebViewPrivate; +}; + +QML_DECLARE_TYPE(QQuickWebPage) + +#endif // qquickwebpage_p_h diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h new file mode 100644 index 000000000..7224f3975 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2011 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 program 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 program; 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 qquickwebpage_p_p_h +#define qquickwebpage_p_p_h + +#include "QtSGUpdateQueue.h" +#include "qquickwebpage_p.h" + +namespace WebKit { +class WebPageProxy; +class QtViewportInteractionEngine; +} + +class QtWebPageEventHandler; + +class QQuickWebPagePrivate { +public: + QQuickWebPagePrivate(QQuickWebPage* q); + ~QQuickWebPagePrivate(); + + void initialize(WebKit::WebPageProxy*); + void setDrawingAreaSize(const QSize&); + + void paintToCurrentGLContext(); + void resetPaintNode(); + + QScopedPointer<QtWebPageEventHandler> eventHandler; + QQuickWebPage* const q; + WebKit::WebPageProxy* webPageProxy; + WebKit::QtSGUpdateQueue sgUpdateQueue; + bool paintingIsInitialized; + QSGNode* m_paintNode; +}; + +#endif // qquickwebpage_p_p_h diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp new file mode 100644 index 000000000..7bbef9182 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp @@ -0,0 +1,988 @@ +/* + * Copyright (C) 2011 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 program 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 program; 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 "qquickwebview_p.h" + +#include "DownloadProxy.h" +#include "DrawingAreaProxyImpl.h" +#include "QtDialogRunner.h" +#include "QtDownloadManager.h" +#include "QtWebContext.h" +#include "QtWebIconDatabaseClient.h" +#include "QtWebPageEventHandler.h" +#include "UtilsQt.h" +#include "WebBackForwardList.h" +#include "WebPageGroup.h" +#include "WebPreferences.h" + +#include "qquicknetworkreply_p.h" +#include "qquickwebpage_p_p.h" +#include "qquickwebview_p_p.h" +#include "qwebdownloaditem_p_p.h" +#include "qwebnavigationhistory_p.h" +#include "qwebnavigationhistory_p_p.h" +#include "qwebpreferences_p.h" +#include "qwebpreferences_p_p.h" +#include "qwebviewportinfo_p.h" + +#include <JavaScriptCore/InitializeThreading.h> +#include <QDeclarativeEngine> +#include <QFileDialog> +#include <QtQuick/QQuickCanvas> +#include <WKOpenPanelResultListener.h> +#include <wtf/text/WTFString.h> + +QQuickWebViewPrivate::QQuickWebViewPrivate(QQuickWebView* viewport) + : q_ptr(viewport) + , alertDialog(0) + , confirmDialog(0) + , promptDialog(0) + , itemSelector(0) + , postTransitionState(adoptPtr(new PostTransitionState(this))) + , isTransitioningToNewPage(false) + , pageIsSuspended(false) + , m_navigatorQtObjectEnabled(false) +{ + viewport->setFlags(QQuickItem::ItemClipsChildrenToShape); + QObject::connect(viewport, SIGNAL(visibleChanged()), viewport, SLOT(_q_onVisibleChanged())); + pageView.reset(new QQuickWebPage(viewport)); +} + +QQuickWebViewPrivate::~QQuickWebViewPrivate() +{ + if (interactionEngine) + interactionEngine->disconnect(); + webPageProxy->close(); +} + +// Note: we delay this initialization to make sure that QQuickWebView has its d-ptr in-place. +void QQuickWebViewPrivate::initialize(WKContextRef contextRef, WKPageGroupRef pageGroupRef) +{ + RefPtr<WebPageGroup> pageGroup; + if (pageGroupRef) + pageGroup = toImpl(pageGroupRef); + else + pageGroup = WebPageGroup::create(); + + context = contextRef ? QtWebContext::create(toImpl(contextRef)) : QtWebContext::defaultContext(); + webPageProxy = context->createWebPage(&pageClient, pageGroup.get()); + + QQuickWebPagePrivate* const pageViewPrivate = pageView.data()->d; + pageViewPrivate->initialize(webPageProxy.get()); + + pageLoadClient.reset(new QtWebPageLoadClient(toAPI(webPageProxy.get()), q_ptr)); + pagePolicyClient.reset(new QtWebPagePolicyClient(toAPI(webPageProxy.get()), q_ptr)); + pageUIClient.reset(new QtWebPageUIClient(toAPI(webPageProxy.get()), q_ptr)); + navigationHistory = adoptPtr(QWebNavigationHistoryPrivate::createHistory(toAPI(webPageProxy.get()))); + + QtWebIconDatabaseClient* iconDatabase = context->iconDatabase(); + QObject::connect(iconDatabase, SIGNAL(iconChangedForPageURL(QUrl, QUrl)), q_ptr, SLOT(_q_onIconChangedForPageURL(QUrl, QUrl))); + QObject::connect(q_ptr, SIGNAL(urlChanged(QUrl)), iconDatabase, SLOT(requestIconForPageURL(QUrl))); + + // Any page setting should preferrable be set before creating the page. + setUseTraditionalDesktopBehaviour(false); + webPageProxy->pageGroup()->preferences()->setAcceleratedCompositingEnabled(true); + + pageClient.initialize(q_ptr, pageViewPrivate->eventHandler.data(), &undoController); + webPageProxy->initializeWebPage(); + + // Trigger setting of correct visibility flags after everything was allocated and initialized. + _q_onVisibleChanged(); +} + +void QQuickWebViewPrivate::enableMouseEvents() +{ + Q_Q(QQuickWebView); + q->setAcceptedMouseButtons(Qt::MouseButtonMask); + q->setAcceptHoverEvents(true); + pageView->setAcceptedMouseButtons(Qt::MouseButtonMask); + pageView->setAcceptHoverEvents(true); +} + +void QQuickWebViewPrivate::disableMouseEvents() +{ + Q_Q(QQuickWebView); + q->setAcceptedMouseButtons(Qt::NoButton); + q->setAcceptHoverEvents(false); + pageView->setAcceptedMouseButtons(Qt::NoButton); + pageView->setAcceptHoverEvents(false); +} + +void QQuickWebViewPrivate::initializeDesktop(QQuickWebView* viewport) +{ + if (interactionEngine) { + QObject::disconnect(interactionEngine.data(), SIGNAL(contentSuspendRequested()), viewport, SLOT(_q_suspend())); + QObject::disconnect(interactionEngine.data(), SIGNAL(contentResumeRequested()), viewport, SLOT(_q_resume())); + QObject::disconnect(interactionEngine.data(), SIGNAL(viewportTrajectoryVectorChanged(const QPointF&)), viewport, SLOT(_q_viewportTrajectoryVectorChanged(const QPointF&))); + } + interactionEngine.reset(0); + pageView->d->eventHandler->setViewportInteractionEngine(0); + enableMouseEvents(); +} + +void QQuickWebViewPrivate::initializeTouch(QQuickWebView* viewport) +{ + interactionEngine.reset(new QtViewportInteractionEngine(viewport, pageView.data())); + pageView->d->eventHandler->setViewportInteractionEngine(interactionEngine.data()); + disableMouseEvents(); + QObject::connect(interactionEngine.data(), SIGNAL(contentSuspendRequested()), viewport, SLOT(_q_suspend())); + QObject::connect(interactionEngine.data(), SIGNAL(contentResumeRequested()), viewport, SLOT(_q_resume())); + QObject::connect(interactionEngine.data(), SIGNAL(viewportTrajectoryVectorChanged(const QPointF&)), viewport, SLOT(_q_viewportTrajectoryVectorChanged(const QPointF&))); + updateViewportSize(); +} + +void QQuickWebViewPrivate::loadDidCommit() +{ + // Due to entering provisional load before committing, we + // might actually be suspended here. + + if (useTraditionalDesktopBehaviour) + return; + + isTransitioningToNewPage = true; +} + +void QQuickWebViewPrivate::didFinishFirstNonEmptyLayout() +{ + if (useTraditionalDesktopBehaviour) + return; + + if (!pageIsSuspended) { + isTransitioningToNewPage = false; + postTransitionState->apply(); + } +} + +void QQuickWebViewPrivate::_q_onIconChangedForPageURL(const QUrl& pageURL, const QUrl& iconURL) +{ + Q_Q(QQuickWebView); + if (q->url() != pageURL) + return; + + setIcon(iconURL); +} + +void QQuickWebViewPrivate::_q_suspend() +{ + pageIsSuspended = true; +} + +void QQuickWebViewPrivate::_q_resume() +{ + pageIsSuspended = false; + + if (isTransitioningToNewPage) { + isTransitioningToNewPage = false; + postTransitionState->apply(); + } + + updateVisibleContentRectAndScale(); +} + +void QQuickWebViewPrivate::didChangeContentsSize(const QSize& newSize) +{ + Q_Q(QQuickWebView); + if (useTraditionalDesktopBehaviour) + return; + + // FIXME: We probably want to handle suspend here as well + if (isTransitioningToNewPage) { + postTransitionState->contentsSize = newSize; + return; + } + + pageView->setWidth(newSize.width()); + pageView->setHeight(newSize.height()); + + q->m_experimental->viewportInfo()->didUpdateContentsSize(); +} + +void QQuickWebViewPrivate::didChangeViewportProperties(const WebCore::ViewportArguments& args) +{ + if (useTraditionalDesktopBehaviour) + return; + + viewportArguments = args; + + if (isTransitioningToNewPage) + return; + + interactionEngine->applyConstraints(computeViewportConstraints()); +} + +void QQuickWebViewPrivate::didChangeBackForwardList() +{ + navigationHistory->d->reset(); +} + +void QQuickWebViewPrivate::pageDidRequestScroll(const QPoint& pos) +{ + if (useTraditionalDesktopBehaviour) + return; + + if (isTransitioningToNewPage) { + postTransitionState->position = pos; + return; + } + + interactionEngine->pagePositionRequest(pos); +} + +void QQuickWebViewPrivate::processDidCrash() +{ + emit q_ptr->navigationStateChanged(); + pageView->d->eventHandler->resetGestureRecognizers(); + WebCore::KURL url(WebCore::ParsedURLString, webPageProxy->urlAtProcessExit()); + qWarning("WARNING: The web process experienced a crash on '%s'.", qPrintable(QUrl(url).toString(QUrl::RemoveUserInfo))); +} + +void QQuickWebViewPrivate::didRelaunchProcess() +{ + emit q_ptr->navigationStateChanged(); + qWarning("WARNING: The web process has been successfully restarted."); + pageView->d->setDrawingAreaSize(viewSize()); +} + +PassOwnPtr<DrawingAreaProxy> QQuickWebViewPrivate::createDrawingAreaProxy() +{ + return DrawingAreaProxyImpl::create(webPageProxy.get()); +} + +void QQuickWebViewPrivate::handleDownloadRequest(DownloadProxy* download) +{ + Q_Q(QQuickWebView); + // This function is responsible for hooking up a DownloadProxy to our API layer + // by creating a QWebDownloadItem. It will then wait for the QWebDownloadItem to be + // ready (filled with the ResourceResponse information) so we can pass it through to + // our WebViews. + QWebDownloadItem* downloadItem = new QWebDownloadItem(); + downloadItem->d->downloadProxy = download; + + q->connect(downloadItem->d, SIGNAL(receivedResponse(QWebDownloadItem*)), q, SLOT(_q_onReceivedResponseFromDownload(QWebDownloadItem*))); + context->downloadManager()->addDownload(download, downloadItem); +} + +void QQuickWebViewPrivate::updateVisibleContentRectAndScale() +{ + DrawingAreaProxy* drawingArea = webPageProxy->drawingArea(); + if (!drawingArea) + return; + + Q_Q(QQuickWebView); + const QRectF visibleRectInPageViewCoordinates = q->mapRectToItem(pageView.data(), q->boundingRect()).intersected(pageView->boundingRect()); + float scale = pageView->scale(); + + QRect alignedVisibleContentRect = visibleRectInPageViewCoordinates.toAlignedRect(); + drawingArea->setVisibleContentsRectAndScale(alignedVisibleContentRect, scale); + + // FIXME: Once we support suspend and resume, this should be delayed until the page is active if the page is suspended. + webPageProxy->setFixedVisibleContentRect(alignedVisibleContentRect); + q->m_experimental->viewportInfo()->didUpdateCurrentScale(); +} + +void QQuickWebViewPrivate::_q_viewportTrajectoryVectorChanged(const QPointF& trajectoryVector) +{ + DrawingAreaProxy* drawingArea = webPageProxy->drawingArea(); + if (!drawingArea) + return; + drawingArea->setVisibleContentRectTrajectoryVector(trajectoryVector); +} + +void QQuickWebViewPrivate::_q_onVisibleChanged() +{ + webPageProxy->viewStateDidChange(WebPageProxy::ViewIsVisible); +} + +void QQuickWebViewPrivate::_q_onReceivedResponseFromDownload(QWebDownloadItem* downloadItem) +{ + // Now that our downloadItem has everything we need we can emit downloadRequested. + if (!downloadItem) + return; + + Q_Q(QQuickWebView); + QDeclarativeEngine::setObjectOwnership(downloadItem, QDeclarativeEngine::JavaScriptOwnership); + emit q->experimental()->downloadRequested(downloadItem); +} + +void QQuickWebViewPrivate::updateViewportSize() +{ + Q_Q(QQuickWebView); + QSize viewportSize = q->boundingRect().size().toSize(); + + if (viewportSize.isEmpty()) + return; + + // Let the WebProcess know about the new viewport size, so that + // it can resize the content accordingly. + webPageProxy->setViewportSize(viewportSize); + + interactionEngine->applyConstraints(computeViewportConstraints()); + updateVisibleContentRectAndScale(); +} + +void QQuickWebViewPrivate::PostTransitionState::apply() +{ + p->interactionEngine->reset(); + p->interactionEngine->applyConstraints(p->computeViewportConstraints()); + p->interactionEngine->pagePositionRequest(position); + + if (contentsSize.isValid()) { + p->pageView->setWidth(contentsSize.width()); + p->pageView->setHeight(contentsSize.height()); + p->q_ptr->experimental()->viewportInfo()->didUpdateContentsSize(); + } + + position = QPoint(); + contentsSize = QSize(); +} + +QtViewportInteractionEngine::Constraints QQuickWebViewPrivate::computeViewportConstraints() +{ + Q_Q(QQuickWebView); + + QtViewportInteractionEngine::Constraints newConstraints; + QSize availableSize = q->boundingRect().size().toSize(); + + // Return default values for zero sized viewport. + if (availableSize.isEmpty()) + return newConstraints; + + WebPreferences* wkPrefs = webPageProxy->pageGroup()->preferences(); + + // FIXME: Remove later; Hardcode some values for now to make sure the DPI adjustment is being tested. + wkPrefs->setDeviceDPI(240); + wkPrefs->setDeviceWidth(480); + wkPrefs->setDeviceHeight(720); + + int minimumLayoutFallbackWidth = qMax<int>(wkPrefs->layoutFallbackWidth(), availableSize.width()); + + WebCore::ViewportAttributes attr = WebCore::computeViewportAttributes(viewportArguments, minimumLayoutFallbackWidth, wkPrefs->deviceWidth(), wkPrefs->deviceHeight(), wkPrefs->deviceDPI(), availableSize); + WebCore::restrictMinimumScaleFactorToViewportSize(attr, availableSize); + WebCore::restrictScaleFactorToInitialScaleIfNotUserScalable(attr); + + newConstraints.initialScale = attr.initialScale; + newConstraints.minimumScale = attr.minimumScale; + newConstraints.maximumScale = attr.maximumScale; + newConstraints.devicePixelRatio = attr.devicePixelRatio; + newConstraints.isUserScalable = !!attr.userScalable; + newConstraints.layoutSize = attr.layoutSize; + + q->m_experimental->viewportInfo()->didUpdateViewportConstraints(); + + return newConstraints; +} + +void QQuickWebViewPrivate::runJavaScriptAlert(const QString& alertText) +{ + if (!alertDialog) + return; + + Q_Q(QQuickWebView); + QtDialogRunner dialogRunner; + if (!dialogRunner.initForAlert(alertDialog, q, alertText)) + return; + setViewInAttachedProperties(dialogRunner.dialog()); + + disableMouseEvents(); + dialogRunner.exec(); + enableMouseEvents(); +} + +bool QQuickWebViewPrivate::runJavaScriptConfirm(const QString& message) +{ + if (!confirmDialog) + return true; + + Q_Q(QQuickWebView); + QtDialogRunner dialogRunner; + if (!dialogRunner.initForConfirm(confirmDialog, q, message)) + return true; + setViewInAttachedProperties(dialogRunner.dialog()); + + disableMouseEvents(); + dialogRunner.exec(); + enableMouseEvents(); + + return dialogRunner.wasAccepted(); +} + +QString QQuickWebViewPrivate::runJavaScriptPrompt(const QString& message, const QString& defaultValue, bool& ok) +{ + if (!promptDialog) { + ok = true; + return defaultValue; + } + + Q_Q(QQuickWebView); + QtDialogRunner dialogRunner; + if (!dialogRunner.initForPrompt(promptDialog, q, message, defaultValue)) { + ok = true; + return defaultValue; + } + setViewInAttachedProperties(dialogRunner.dialog()); + + disableMouseEvents(); + dialogRunner.exec(); + enableMouseEvents(); + + ok = dialogRunner.wasAccepted(); + return dialogRunner.result(); +} + +void QQuickWebViewPrivate::chooseFiles(WKOpenPanelResultListenerRef listenerRef, const QStringList& selectedFileNames, QtWebPageUIClient::FileChooserType type) +{ +#ifndef QT_NO_FILEDIALOG + Q_Q(QQuickWebView); + openPanelResultListener = listenerRef; + + // Qt does not support multiple files suggestion, so we get just the first suggestion. + QString selectedFileName; + if (!selectedFileNames.isEmpty()) + selectedFileName = selectedFileNames.at(0); + + Q_ASSERT(!fileDialog); + + QWindow* window = q->canvas(); + if (!window) + return; + + fileDialog = new QFileDialog(0, QString(), selectedFileName); + fileDialog->window()->winId(); // Ensure that the dialog has a window + Q_ASSERT(fileDialog->window()->windowHandle()); + fileDialog->window()->windowHandle()->setTransientParent(window); + + fileDialog->open(q, SLOT(_q_onOpenPanelFilesSelected())); + + q->connect(fileDialog, SIGNAL(finished(int)), SLOT(_q_onOpenPanelFinished(int))); +#endif +} + +void QQuickWebViewPrivate::_q_onOpenPanelFilesSelected() +{ + const QStringList fileList = fileDialog->selectedFiles(); + Vector<RefPtr<APIObject> > wkFiles(fileList.size()); + + for (unsigned i = 0; i < fileList.size(); ++i) + wkFiles[i] = WebURL::create(QUrl::fromLocalFile(fileList.at(i)).toString()); + + WKOpenPanelResultListenerChooseFiles(openPanelResultListener, toAPI(ImmutableArray::adopt(wkFiles).leakRef())); +} + +void QQuickWebViewPrivate::_q_onOpenPanelFinished(int result) +{ + if (result == QDialog::Rejected) + WKOpenPanelResultListenerCancel(openPanelResultListener); + + fileDialog->deleteLater(); + fileDialog = 0; +} + +void QQuickWebViewPrivate::setUseTraditionalDesktopBehaviour(bool enable) +{ + Q_Q(QQuickWebView); + + // Do not guard, testing for the same value, as we call this from the constructor. + + webPageProxy->setUseFixedLayout(!enable); + + useTraditionalDesktopBehaviour = enable; + if (useTraditionalDesktopBehaviour) + initializeDesktop(q); + else + initializeTouch(q); +} + +void QQuickWebViewPrivate::setViewInAttachedProperties(QObject* object) +{ + Q_Q(QQuickWebView); + QQuickWebViewAttached* attached = static_cast<QQuickWebViewAttached*>(qmlAttachedPropertiesObject<QQuickWebView>(object)); + attached->setView(q); +} + +void QQuickWebViewPrivate::setIcon(const QUrl& iconURL) +{ + Q_Q(QQuickWebView); + if (m_iconURL == iconURL) + return; + + String oldPageURL = QUrl::fromPercentEncoding(m_iconURL.encodedFragment()); + String newPageURL = webPageProxy->mainFrame()->url(); + + if (oldPageURL != newPageURL) { + QtWebIconDatabaseClient* iconDatabase = context->iconDatabase(); + if (!oldPageURL.isEmpty()) + iconDatabase->releaseIconForPageURL(oldPageURL); + + if (!newPageURL.isEmpty()) + iconDatabase->retainIconForPageURL(newPageURL); + } + + m_iconURL = iconURL; + emit q->iconChanged(m_iconURL); +} + +bool QQuickWebViewPrivate::navigatorQtObjectEnabled() const +{ + return m_navigatorQtObjectEnabled; +} + +void QQuickWebViewPrivate::setNavigatorQtObjectEnabled(bool enabled) +{ + ASSERT(enabled != m_navigatorQtObjectEnabled); + // FIXME: Currently we have to keep this information in both processes and the setting is asynchronous. + m_navigatorQtObjectEnabled = enabled; + context->setNavigatorQtObjectEnabled(webPageProxy.get(), enabled); +} + +WebCore::IntSize QQuickWebViewPrivate::viewSize() const +{ + return WebCore::IntSize(pageView->width(), pageView->height()); +} + +void QQuickWebViewPrivate::didReceiveMessageFromNavigatorQtObject(const String& message) +{ + QVariantMap variantMap; + variantMap.insert(QLatin1String("data"), QString(message)); + variantMap.insert(QLatin1String("origin"), q_ptr->url()); + emit q_ptr->experimental()->messageReceived(variantMap); +} + +/*! + \qmlsignal WebView::onNavigationRequested(request) + + This signal is emitted for every navigation request. The request object contains url, button and modifiers properties + describing the navigation action, e.g. "a middle click with shift key pressed to 'http://qt-project.org'". + + The navigation will be accepted by default. To change that, one can set the action property to WebView.IgnoreRequest to reject + the request or WebView.DownloadRequest to trigger a download instead of navigating to the url. + + The request object cannot be used after the signal handler function ends. +*/ + +QQuickWebViewAttached::QQuickWebViewAttached(QObject* object) + : QObject(object) + , m_view(0) +{ + +} + +void QQuickWebViewAttached::setView(QQuickWebView* view) +{ + if (m_view == view) + return; + m_view = view; + emit viewChanged(); +} + +QQuickWebViewExperimental::QQuickWebViewExperimental(QQuickWebView *webView) + : QObject(webView) + , q_ptr(webView) + , d_ptr(webView->d_ptr.data()) + , schemeParent(new QObject(this)) + , m_viewportInfo(new QWebViewportInfo(webView->d_ptr.data(), this)) +{ +} + +QQuickWebViewExperimental::~QQuickWebViewExperimental() +{ +} + +void QQuickWebViewExperimental::setUseTraditionalDesktopBehaviour(bool enable) +{ + Q_D(QQuickWebView); + + if (enable == d->useTraditionalDesktopBehaviour) + return; + + d->setUseTraditionalDesktopBehaviour(enable); +} + +void QQuickWebViewExperimental::postMessage(const QString& message) +{ + Q_D(QQuickWebView); + d->context->postMessageToNavigatorQtObject(d->webPageProxy.get(), message); +} + +QDeclarativeComponent* QQuickWebViewExperimental::alertDialog() const +{ + Q_D(const QQuickWebView); + return d->alertDialog; +} + +void QQuickWebViewExperimental::setAlertDialog(QDeclarativeComponent* alertDialog) +{ + Q_D(QQuickWebView); + if (d->alertDialog == alertDialog) + return; + d->alertDialog = alertDialog; + emit alertDialogChanged(); +} + +QDeclarativeComponent* QQuickWebViewExperimental::confirmDialog() const +{ + Q_D(const QQuickWebView); + return d->confirmDialog; +} + +void QQuickWebViewExperimental::setConfirmDialog(QDeclarativeComponent* confirmDialog) +{ + Q_D(QQuickWebView); + if (d->confirmDialog == confirmDialog) + return; + d->confirmDialog = confirmDialog; + emit confirmDialogChanged(); +} + +QWebNavigationHistory* QQuickWebViewExperimental::navigationHistory() const +{ + return d_ptr->navigationHistory.get(); +} + +QDeclarativeComponent* QQuickWebViewExperimental::promptDialog() const +{ + Q_D(const QQuickWebView); + return d->promptDialog; +} + +QWebPreferences* QQuickWebViewExperimental::preferences() const +{ + QQuickWebViewPrivate* const d = d_ptr; + if (!d->preferences) + d->preferences = adoptPtr(QWebPreferencesPrivate::createPreferences(d)); + return d->preferences.get(); +} + +void QQuickWebViewExperimental::setPromptDialog(QDeclarativeComponent* promptDialog) +{ + Q_D(QQuickWebView); + if (d->promptDialog == promptDialog) + return; + d->promptDialog = promptDialog; + emit promptDialogChanged(); +} + +QDeclarativeComponent* QQuickWebViewExperimental::itemSelector() const +{ + Q_D(const QQuickWebView); + return d->itemSelector; +} + +void QQuickWebViewExperimental::setItemSelector(QDeclarativeComponent* itemSelector) +{ + Q_D(QQuickWebView); + if (d->itemSelector == itemSelector) + return; + d->itemSelector = itemSelector; + emit itemSelectorChanged(); +} + +bool QQuickWebViewExperimental::useTraditionalDesktopBehaviour() const +{ + Q_D(const QQuickWebView); + return d->useTraditionalDesktopBehaviour; +} + +QQuickUrlSchemeDelegate* QQuickWebViewExperimental::schemeDelegates_At(QDeclarativeListProperty<QQuickUrlSchemeDelegate>* property, int index) +{ + const QObjectList children = property->object->children(); + if (index < children.count()) + return static_cast<QQuickUrlSchemeDelegate*>(children.at(index)); + return 0; +} + +void QQuickWebViewExperimental::schemeDelegates_Append(QDeclarativeListProperty<QQuickUrlSchemeDelegate>* property, QQuickUrlSchemeDelegate *scheme) +{ + QObject* schemeParent = property->object; + scheme->setParent(schemeParent); + QQuickWebViewExperimental* webViewExperimental = qobject_cast<QQuickWebViewExperimental*>(property->object->parent()); + if (!webViewExperimental) + return; + QQuickWebViewPrivate* d = webViewExperimental->d_func(); + d->webPageProxy->registerApplicationScheme(scheme->scheme()); +} + +int QQuickWebViewExperimental::schemeDelegates_Count(QDeclarativeListProperty<QQuickUrlSchemeDelegate>* property) +{ + return property->object->children().count(); +} + +void QQuickWebViewExperimental::schemeDelegates_Clear(QDeclarativeListProperty<QQuickUrlSchemeDelegate>* property) +{ + const QObjectList children = property->object->children(); + for (int index = 0; index < children.count(); index++) { + QObject* child = children.at(index); + child->setParent(0); + delete child; + } +} + +QDeclarativeListProperty<QQuickUrlSchemeDelegate> QQuickWebViewExperimental::schemeDelegates() +{ + return QDeclarativeListProperty<QQuickUrlSchemeDelegate>(schemeParent, 0, + QQuickWebViewExperimental::schemeDelegates_Append, + QQuickWebViewExperimental::schemeDelegates_Count, + QQuickWebViewExperimental::schemeDelegates_At, + QQuickWebViewExperimental::schemeDelegates_Clear); +} + +void QQuickWebViewExperimental::invokeApplicationSchemeHandler(PassRefPtr<QtNetworkRequestData> request) +{ + const QObjectList children = schemeParent->children(); + for (int index = 0; index < children.count(); index++) { + QQuickUrlSchemeDelegate* delegate = qobject_cast<QQuickUrlSchemeDelegate*>(children.at(index)); + if (!delegate) + continue; + if (!delegate->scheme().compare(QString(request->m_scheme), Qt::CaseInsensitive)) { + delegate->reply()->setNetworkRequestData(request); + emit delegate->receivedRequest(); + return; + } + } +} + +void QQuickWebViewExperimental::sendApplicationSchemeReply(QQuickNetworkReply* reply) +{ + d_ptr->webPageProxy->sendApplicationSchemeReply(reply); +} + +void QQuickWebViewExperimental::goForwardTo(int index) +{ + d_ptr->navigationHistory->d->goForwardTo(index); +} + +void QQuickWebViewExperimental::goBackTo(int index) +{ + d_ptr->navigationHistory->d->goBackTo(index); +} + +QWebViewportInfo* QQuickWebViewExperimental::viewportInfo() +{ + return m_viewportInfo; +} + +QQuickWebPage* QQuickWebViewExperimental::page() +{ + return q_ptr->page(); +} + +QQuickWebView::QQuickWebView(QQuickItem* parent) + : QQuickItem(parent) + , d_ptr(new QQuickWebViewPrivate(this)) + , m_experimental(new QQuickWebViewExperimental(this)) +{ + Q_D(QQuickWebView); + d->initialize(); + d->initializeTouch(this); +} + +QQuickWebView::QQuickWebView(WKContextRef contextRef, WKPageGroupRef pageGroupRef, QQuickItem* parent) + : QQuickItem(parent) + , d_ptr(new QQuickWebViewPrivate(this)) + , m_experimental(new QQuickWebViewExperimental(this)) +{ + Q_D(QQuickWebView); + d->initialize(contextRef, pageGroupRef); +} + +QQuickWebView::~QQuickWebView() +{ +} + +QQuickWebPage* QQuickWebView::page() +{ + Q_D(QQuickWebView); + return d->pageView.data(); +} + +void QQuickWebView::load(const QUrl& url) +{ + Q_D(QQuickWebView); + d->webPageProxy->loadURL(url.toString()); +} + +void QQuickWebView::goBack() +{ + Q_D(QQuickWebView); + d->webPageProxy->goBack(); +} + +void QQuickWebView::goForward() +{ + Q_D(QQuickWebView); + d->webPageProxy->goForward(); +} + +void QQuickWebView::stop() +{ + Q_D(QQuickWebView); + d->webPageProxy->stopLoading(); +} + +void QQuickWebView::reload() +{ + Q_D(QQuickWebView); + const bool reloadFromOrigin = true; + d->webPageProxy->reload(reloadFromOrigin); +} + +QUrl QQuickWebView::url() const +{ + Q_D(const QQuickWebView); + RefPtr<WebFrameProxy> mainFrame = d->webPageProxy->mainFrame(); + if (!mainFrame) + return QUrl(); + return QUrl(QString(mainFrame->url())); +} + +QUrl QQuickWebView::icon() const +{ + Q_D(const QQuickWebView); + return d->m_iconURL; +} + +int QQuickWebView::loadProgress() const +{ + Q_D(const QQuickWebView); + return d->pageLoadClient->loadProgress(); +} + +bool QQuickWebView::canGoBack() const +{ + Q_D(const QQuickWebView); + return d->webPageProxy->canGoBack(); +} + +bool QQuickWebView::canGoForward() const +{ + Q_D(const QQuickWebView); + return d->webPageProxy->canGoForward(); +} + +bool QQuickWebView::loading() const +{ + Q_D(const QQuickWebView); + RefPtr<WebKit::WebFrameProxy> mainFrame = d->webPageProxy->mainFrame(); + return mainFrame && !(WebFrameProxy::LoadStateFinished == mainFrame->loadState()); +} + +bool QQuickWebView::canReload() const +{ + Q_D(const QQuickWebView); + RefPtr<WebKit::WebFrameProxy> mainFrame = d->webPageProxy->mainFrame(); + if (mainFrame) + return (WebFrameProxy::LoadStateFinished == mainFrame->loadState()); + return d->webPageProxy->backForwardList()->currentItem(); +} + +QString QQuickWebView::title() const +{ + Q_D(const QQuickWebView); + return d->webPageProxy->pageTitle(); +} + +QVariant QQuickWebView::inputMethodQuery(Qt::InputMethodQuery property) const +{ + Q_D(const QQuickWebView); + const EditorState& state = d->webPageProxy->editorState(); + + switch(property) { + case Qt::ImCursorRectangle: + return QRectF(state.microFocus); + case Qt::ImFont: + return QVariant(); + case Qt::ImCursorPosition: + return QVariant(static_cast<int>(state.cursorPosition)); + case Qt::ImAnchorPosition: + return QVariant(static_cast<int>(state.anchorPosition)); + case Qt::ImSurroundingText: + return QString(state.surroundingText); + case Qt::ImCurrentSelection: + return QString(state.selectedText); + case Qt::ImMaximumTextLength: + return QVariant(); // No limit. + default: + // Rely on the base implementation for ImEnabled, ImHints and ImPreferredLanguage. + return QQuickItem::inputMethodQuery(property); + } +} + +QQuickWebViewExperimental* QQuickWebView::experimental() const +{ + return m_experimental; +} + +QQuickWebViewAttached* QQuickWebView::qmlAttachedProperties(QObject* object) +{ + return new QQuickWebViewAttached(object); +} + +void QQuickWebView::platformInitialize() +{ + JSC::initializeThreading(); + WTF::initializeMainThread(); +} + +void QQuickWebView::geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry) +{ + Q_D(QQuickWebView); + QQuickItem::geometryChanged(newGeometry, oldGeometry); + if (newGeometry.size() != oldGeometry.size()) { + if (d->useTraditionalDesktopBehaviour) { + d->pageView->setWidth(newGeometry.width()); + d->pageView->setHeight(newGeometry.height()); + } else + d->updateViewportSize(); + } +} + +void QQuickWebView::focusInEvent(QFocusEvent* event) +{ + Q_D(QQuickWebView); + d->pageView->event(event); +} + +void QQuickWebView::focusOutEvent(QFocusEvent* event) +{ + Q_D(QQuickWebView); + d->pageView->event(event); +} + +WKPageRef QQuickWebView::pageRef() const +{ + Q_D(const QQuickWebView); + return toAPI(d->webPageProxy.get()); +} + +/*! + Loads the specified \a html as the content of the web view. + + External objects such as stylesheets or images referenced in the HTML + document are located relative to \a baseUrl. + + \sa load() +*/ +void QQuickWebView::loadHtml(const QString& html, const QUrl& baseUrl) +{ + Q_D(QQuickWebView); + d->webPageProxy->loadHTMLString(html, baseUrl.toString()); +} + +#include "moc_qquickwebview_p.cpp" diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h new file mode 100644 index 000000000..e5d3f1e5a --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2011 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 program 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 program; 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 qquickwebview_p_h +#define qquickwebview_p_h + +#include "qquickurlschemedelegate_p.h" +#include "qwebkitglobal.h" +#include <QtDeclarative/qdeclarativelist.h> +#include <QtQuick/qquickitem.h> + +class QWebNavigationRequest; +class QDeclarativeComponent; +class QQuickWebPage; +class QQuickWebViewAttached; +class QQuickWebViewPrivate; +class QQuickWebViewExperimental; +class QWebDownloadItem; +class QWebNavigationHistory; +class QWebPreferences; +class QWebPermissionRequest; +class QWebViewportInfo; +class QQuickNetworkReply; + +namespace WTR { +class PlatformWebView; +} + +namespace WebKit { +class QtNetworkRequestData; +} + +namespace WTF { +template<class T> class PassRefPtr; +} + +typedef const struct OpaqueWKContext* WKContextRef; +typedef const struct OpaqueWKPageGroup* WKPageGroupRef; +typedef const struct OpaqueWKPage* WKPageRef; + +QT_BEGIN_NAMESPACE +class QPainter; +class QUrl; +QT_END_NAMESPACE + +class QWEBKIT_EXPORT QQuickWebView : public QQuickItem { + Q_OBJECT + Q_PROPERTY(QString title READ title NOTIFY titleChanged) + Q_PROPERTY(QUrl url READ url NOTIFY urlChanged) + Q_PROPERTY(QUrl icon READ icon NOTIFY iconChanged FINAL) + Q_PROPERTY(int loadProgress READ loadProgress NOTIFY loadProgressChanged) + Q_PROPERTY(bool canGoBack READ canGoBack NOTIFY navigationStateChanged FINAL) + Q_PROPERTY(bool canGoForward READ canGoForward NOTIFY navigationStateChanged FINAL) + Q_PROPERTY(bool loading READ loading NOTIFY navigationStateChanged FINAL) + Q_PROPERTY(bool canReload READ canReload NOTIFY navigationStateChanged FINAL) + Q_ENUMS(NavigationRequestAction) + Q_ENUMS(ErrorDomain) + +public: + enum NavigationRequestAction { + AcceptRequest, + IgnoreRequest + }; + + enum ErrorDomain { + InternalErrorDomain, + NetworkErrorDomain, + HttpErrorDomain, + DownloadErrorDomain + }; + QQuickWebView(QQuickItem* parent = 0); + virtual ~QQuickWebView(); + + QUrl url() const; + QUrl icon() const; + QString title() const; + int loadProgress() const; + + bool canGoBack() const; + bool canGoForward() const; + bool loading() const; + bool canReload() const; + + virtual QVariant inputMethodQuery(Qt::InputMethodQuery property) const; + + QQuickWebPage* page(); + + QQuickWebViewExperimental* experimental() const; + static QQuickWebViewAttached* qmlAttachedProperties(QObject*); + + static void platformInitialize(); // Only needed by WTR. + +public Q_SLOTS: + void load(const QUrl&); + void loadHtml(const QString& html, const QUrl& baseUrl = QUrl()); + + void goBack(); + void goForward(); + void stop(); + void reload(); + +Q_SIGNALS: + void titleChanged(const QString& title); + void loadStarted(); + void loadSucceeded(); + void loadFailed(QQuickWebView::ErrorDomain errorDomain, int errorCode, const QUrl& url, const QString& description); + void loadProgressChanged(int progress); + void urlChanged(const QUrl& url); + void iconChanged(const QUrl& iconURL); + void linkHovered(const QUrl& url, const QString& title); + void navigationStateChanged(); + void navigationRequested(QWebNavigationRequest* request); + +protected: + virtual void geometryChanged(const QRectF&, const QRectF&); + virtual void focusInEvent(QFocusEvent*); + virtual void focusOutEvent(QFocusEvent*); + +private: + Q_DECLARE_PRIVATE(QQuickWebView) + + QQuickWebView(WKContextRef, WKPageGroupRef, QQuickItem* parent = 0); + WKPageRef pageRef() const; + + Q_PRIVATE_SLOT(d_func(), void _q_suspend()); + Q_PRIVATE_SLOT(d_func(), void _q_resume()); + Q_PRIVATE_SLOT(d_func(), void _q_viewportTrajectoryVectorChanged(const QPointF&)); + Q_PRIVATE_SLOT(d_func(), void _q_onOpenPanelFilesSelected()); + Q_PRIVATE_SLOT(d_func(), void _q_onOpenPanelFinished(int result)); + Q_PRIVATE_SLOT(d_func(), void _q_onVisibleChanged()); + Q_PRIVATE_SLOT(d_func(), void _q_onReceivedResponseFromDownload(QWebDownloadItem*)); + Q_PRIVATE_SLOT(d_func(), void _q_onIconChangedForPageURL(const QUrl&, const QUrl&)); + // Hides QObject::d_ptr allowing us to use the convenience macros. + QScopedPointer<QQuickWebViewPrivate> d_ptr; + QQuickWebViewExperimental* m_experimental; + + friend class QtWebPageLoadClient; + friend class QtWebPagePolicyClient; + friend class QtWebPageUIClient; + friend class WTR::PlatformWebView; + friend class QQuickWebViewExperimental; +}; + +QML_DECLARE_TYPE(QQuickWebView) + +class QWEBKIT_EXPORT QQuickWebViewAttached : public QObject { + Q_OBJECT + Q_PROPERTY(QQuickWebView* view READ view NOTIFY viewChanged FINAL) + +public: + QQuickWebViewAttached(QObject* object); + QQuickWebView* view() const { return m_view; } + void setView(QQuickWebView*); + +Q_SIGNALS: + void viewChanged(); + +private: + QQuickWebView* m_view; +}; + +QML_DECLARE_TYPEINFO(QQuickWebView, QML_HAS_ATTACHED_PROPERTIES) + +class QWEBKIT_EXPORT QQuickWebViewExperimental : public QObject { + Q_OBJECT + Q_PROPERTY(QQuickWebPage* page READ page CONSTANT FINAL) + Q_PROPERTY(QWebNavigationHistory* navigationHistory READ navigationHistory CONSTANT FINAL) + Q_PROPERTY(QDeclarativeComponent* alertDialog READ alertDialog WRITE setAlertDialog NOTIFY alertDialogChanged) + Q_PROPERTY(QDeclarativeComponent* confirmDialog READ confirmDialog WRITE setConfirmDialog NOTIFY confirmDialogChanged) + Q_PROPERTY(QDeclarativeComponent* promptDialog READ promptDialog WRITE setPromptDialog NOTIFY promptDialogChanged) + Q_PROPERTY(QDeclarativeComponent* itemSelector READ itemSelector WRITE setItemSelector NOTIFY itemSelectorChanged) + Q_PROPERTY(QWebPreferences* preferences READ preferences CONSTANT FINAL) + Q_PROPERTY(bool useTraditionalDesktopBehaviour READ useTraditionalDesktopBehaviour WRITE setUseTraditionalDesktopBehaviour) + Q_PROPERTY(QWebViewportInfo* viewportInfo READ viewportInfo CONSTANT FINAL) + Q_PROPERTY(QDeclarativeListProperty<QQuickUrlSchemeDelegate> urlSchemeDelegates READ schemeDelegates) + Q_ENUMS(NavigationRequestAction) + +public: + enum NavigationRequestAction { + DownloadRequest = 2 + }; + + QQuickWebViewExperimental(QQuickWebView* webView); + virtual ~QQuickWebViewExperimental(); + + QDeclarativeComponent* alertDialog() const; + void setAlertDialog(QDeclarativeComponent*); + QDeclarativeComponent* confirmDialog() const; + void setConfirmDialog(QDeclarativeComponent*); + QDeclarativeComponent* promptDialog() const; + void setPromptDialog(QDeclarativeComponent*); + QDeclarativeComponent* itemSelector() const; + void setItemSelector(QDeclarativeComponent*); + + QWebViewportInfo* viewportInfo(); + + QWebPreferences* preferences() const; + bool useTraditionalDesktopBehaviour() const; + QWebNavigationHistory* navigationHistory() const; + QQuickWebPage* page(); + + static QQuickUrlSchemeDelegate* schemeDelegates_At(QDeclarativeListProperty<QQuickUrlSchemeDelegate>*, int index); + static void schemeDelegates_Append(QDeclarativeListProperty<QQuickUrlSchemeDelegate>*, QQuickUrlSchemeDelegate*); + static int schemeDelegates_Count(QDeclarativeListProperty<QQuickUrlSchemeDelegate>*); + static void schemeDelegates_Clear(QDeclarativeListProperty<QQuickUrlSchemeDelegate>*); + QDeclarativeListProperty<QQuickUrlSchemeDelegate> schemeDelegates(); + void invokeApplicationSchemeHandler(WTF::PassRefPtr<WebKit::QtNetworkRequestData>); + void sendApplicationSchemeReply(QQuickNetworkReply*); + +public Q_SLOTS: + void setUseTraditionalDesktopBehaviour(bool enable); + void goBackTo(int index); + void goForwardTo(int index); + void postMessage(const QString&); + +Q_SIGNALS: + void alertDialogChanged(); + void confirmDialogChanged(); + void promptDialogChanged(); + void itemSelectorChanged(); + void downloadRequested(QWebDownloadItem* downloadItem); + void permissionRequested(QWebPermissionRequest* permission); + void messageReceived(const QVariantMap& message); + +private: + QQuickWebView* q_ptr; + QQuickWebViewPrivate* d_ptr; + QObject* schemeParent; + QWebViewportInfo* m_viewportInfo; + + friend class QtWebPageUIClient; + + Q_DECLARE_PRIVATE(QQuickWebView) + Q_DECLARE_PUBLIC(QQuickWebView) +}; + +#endif // qquickwebview_p_h diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h new file mode 100644 index 000000000..3b999282b --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2011 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 program 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 program; 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 qquickwebview_p_p_h +#define qquickwebview_p_p_h + +#include "DrawingAreaProxy.h" +#include "QtPageClient.h" +#include "QtViewportInteractionEngine.h" +#include "QtWebPageLoadClient.h" +#include "QtWebPagePolicyClient.h" +#include "QtWebPageUIClient.h" +#include "QtWebUndoController.h" +#include "WebPageProxy.h" + +#include "qquickwebview_p.h" +#include "qquickwebpage_p.h" + +#include <QtCore/QObject> +#include <QtCore/QScopedPointer> +#include <wtf/OwnPtr.h> +#include <wtf/RefPtr.h> + +namespace WebKit { +class DownloadProxy; +class QtWebContext; +class WebPageProxy; +} +class QWebNavigationHistory; +class QWebViewportInfo; + +QT_BEGIN_NAMESPACE +class QDeclarativeComponent; +class QFileDialog; +QT_END_NAMESPACE + +class QQuickWebViewPrivate { + Q_DECLARE_PUBLIC(QQuickWebView) + friend class QQuickWebViewExperimental; + friend class QQuickWebPage; + friend class QWebPreferencesPrivate; + friend class QWebViewportInfo; + +public: + static QQuickWebViewPrivate* get(QQuickWebView* q) { return q->d_ptr.data(); } + + QQuickWebViewPrivate(QQuickWebView* viewport); + virtual ~QQuickWebViewPrivate(); + + void initialize(WKContextRef contextRef = 0, WKPageGroupRef pageGroupRef = 0); + + void initializeTouch(QQuickWebView* viewport); + void initializeDesktop(QQuickWebView* viewport); + void enableMouseEvents(); + void disableMouseEvents(); + + void loadDidCommit(); + + void didFinishFirstNonEmptyLayout(); + void didChangeViewportProperties(const WebCore::ViewportArguments& args); + void didChangeBackForwardList(); + + void updateViewportSize(); + QtViewportInteractionEngine::Constraints computeViewportConstraints(); + + void updateVisibleContentRectAndScale(); + + void _q_suspend(); + void _q_resume(); + void _q_viewportTrajectoryVectorChanged(const QPointF&); + void _q_onOpenPanelFilesSelected(); + void _q_onOpenPanelFinished(int result); + void _q_onVisibleChanged(); + void _q_onReceivedResponseFromDownload(QWebDownloadItem*); + void _q_onIconChangedForPageURL(const QUrl& pageURL, const QUrl& iconURLString); + + void chooseFiles(WKOpenPanelResultListenerRef, const QStringList& selectedFileNames, QtWebPageUIClient::FileChooserType); + void runJavaScriptAlert(const QString&); + bool runJavaScriptConfirm(const QString&); + QString runJavaScriptPrompt(const QString&, const QString& defaultValue, bool& ok); + + void setUseTraditionalDesktopBehaviour(bool enable); + void setViewInAttachedProperties(QObject*); + void setIcon(const QUrl&); + + bool navigatorQtObjectEnabled() const; + void setNavigatorQtObjectEnabled(bool); + + // PageClient. + WebCore::IntSize viewSize() const; + void didReceiveMessageFromNavigatorQtObject(const String& message); + void pageDidRequestScroll(const QPoint& pos); + void didChangeContentsSize(const QSize& newSize); + void processDidCrash(); + void didRelaunchProcess(); + PassOwnPtr<DrawingAreaProxy> createDrawingAreaProxy(); + void handleDownloadRequest(DownloadProxy*); + +private: + // This class is responsible for collecting and applying all properties + // on the viewport item, when transitioning from page A to page B is finished. + // See more at https://trac.webkit.org/wiki/QtWebKitLayoutInteraction + class PostTransitionState { + public: + PostTransitionState(QQuickWebViewPrivate* parent) + : p(parent) + { } + + void apply(); + + QQuickWebViewPrivate* p; + QSize contentsSize; + QPoint position; + }; + + RefPtr<QtWebContext> context; + RefPtr<WebKit::WebPageProxy> webPageProxy; + + QtPageClient pageClient; + QtWebUndoController undoController; + OwnPtr<QWebNavigationHistory> navigationHistory; + OwnPtr<QWebPreferences> preferences; + + QScopedPointer<QtWebPageLoadClient> pageLoadClient; + QScopedPointer<QtWebPagePolicyClient> pagePolicyClient; + QScopedPointer<QtWebPageUIClient> pageUIClient; + + QScopedPointer<QQuickWebPage> pageView; + QScopedPointer<QtViewportInteractionEngine> interactionEngine; + + QQuickWebView* q_ptr; + + QDeclarativeComponent* alertDialog; + QDeclarativeComponent* confirmDialog; + QDeclarativeComponent* promptDialog; + QDeclarativeComponent* itemSelector; + + WebCore::ViewportArguments viewportArguments; + OwnPtr<PostTransitionState> postTransitionState; + QFileDialog* fileDialog; + WKOpenPanelResultListenerRef openPanelResultListener; + + bool isTransitioningToNewPage; + bool pageIsSuspended; + + bool useTraditionalDesktopBehaviour; + bool m_navigatorQtObjectEnabled; + QUrl m_iconURL; +}; + +#endif // qquickwebview_p_p_h diff --git a/Source/WebKit2/UIProcess/API/qt/qwebdownloaditem.cpp b/Source/WebKit2/UIProcess/API/qt/qwebdownloaditem.cpp new file mode 100644 index 000000000..85476431f --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qwebdownloaditem.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2011 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 program 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 program; 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 "qwebdownloaditem_p.h" + +#include "DownloadProxy.h" +#include "qwebdownloaditem_p_p.h" + +QWebDownloadItemPrivate::QWebDownloadItemPrivate(QWebDownloadItem* qq) + : q(qq) + , downloadProxy(0) + , expectedContentLength(0) + , totalBytesReceived(0) +{ +} + +QWebDownloadItem::QWebDownloadItem(QObject* parent) + : QObject(parent) + , d(new QWebDownloadItemPrivate(this)) +{ +} + +QWebDownloadItem::~QWebDownloadItem() +{ + delete d; +} + +QUrl QWebDownloadItem::url() const +{ + return d->sourceUrl; +} + +QString QWebDownloadItem::destinationPath() const +{ + return d->destinationPath; +} + +void QWebDownloadItem::setDestinationPath(const QString& destination) +{ + d->destinationPath = destination; +} + +QString QWebDownloadItem::suggestedFilename() const +{ + return d->suggestedFilename; +} + +QString QWebDownloadItem::mimeType() const +{ + return d->mimeType; +} + +quint64 QWebDownloadItem::expectedContentLength() const +{ + return d->expectedContentLength; +} + +quint64 QWebDownloadItem::totalBytesReceived() const +{ + return d->totalBytesReceived; +} + +void QWebDownloadItem::cancel() +{ + ASSERT(d->downloadProxy); + d->downloadProxy->cancel(); +} + +void QWebDownloadItem::start() +{ + ASSERT(!d->suggestedFilename.isEmpty()); + + if (d->destinationPath.isEmpty()) + d->destinationPath = d->suggestedFilename; + + d->downloadProxy->startTransfer(d->destinationPath); +} + diff --git a/Source/WebKit2/UIProcess/API/qt/qwebdownloaditem_p.h b/Source/WebKit2/UIProcess/API/qt/qwebdownloaditem_p.h new file mode 100644 index 000000000..79659753b --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qwebdownloaditem_p.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2011 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 program 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 program; 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 qwebdownloaditem_p_h +#define qwebdownloaditem_p_h + +#include "qwebkitglobal.h" +#include <QObject> +#include <QUrl> + +class QWebDownloadItemPrivate; +class QtWebError; + +QT_BEGIN_NAMESPACE +class QString; +QT_END_NAMESPACE + +namespace WebKit { +class QtDownloadManager; +} + +class QWEBKIT_EXPORT QWebDownloadItem : public QObject { + Q_OBJECT + Q_PROPERTY(quint64 expectedContentLength READ expectedContentLength CONSTANT FINAL) + Q_PROPERTY(QString destinationPath READ destinationPath WRITE setDestinationPath) + Q_PROPERTY(QString suggestedFilename READ suggestedFilename CONSTANT FINAL) + Q_PROPERTY(quint64 totalBytesReceived READ totalBytesReceived NOTIFY totalBytesReceivedChanged FINAL) + Q_PROPERTY(QUrl url READ url CONSTANT FINAL) + Q_ENUMS(DownloadError) +public: + virtual ~QWebDownloadItem(); + + enum DownloadError { + Aborted = 0, + CannotWriteToFile, + CannotOpenFile, + DestinationAlreadyExists, + Cancelled, + CannotDetermineFilename, + NetworkFailure + }; + + QUrl url() const; + QString destinationPath() const; + QString suggestedFilename() const; + QString mimeType() const; + quint64 expectedContentLength() const; + quint64 totalBytesReceived() const; + void setDestinationPath(const QString& destination); + +public Q_SLOTS: + void start(); + void cancel(); + +Q_SIGNALS: + void destinationFileCreated(const QString& destinationPath); + void totalBytesReceivedChanged(quint64 bytesReceived); + void succeeded(); + void failed(QWebDownloadItem::DownloadError error, const QUrl& url, const QString& description); + +private: + QWebDownloadItem(QObject* parent = 0); + QWebDownloadItemPrivate* d; + + friend class WebKit::QtDownloadManager; + friend class QQuickWebViewPrivate; +}; + +#endif // qwebdownloaditem_p_h diff --git a/Source/WebKit2/UIProcess/API/qt/qwebdownloaditem_p_p.h b/Source/WebKit2/UIProcess/API/qt/qwebdownloaditem_p_p.h new file mode 100644 index 000000000..780848be6 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qwebdownloaditem_p_p.h @@ -0,0 +1,53 @@ +/* + Copyright (C) 2011 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 qwebdownloaditem_p_p_h +#define qwebdownloaditem_p_p_h + +#include "qwebdownloaditem_p.h" +#include <QUrl> + +namespace WebKit { +class DownloadProxy; +} + +class QWebDownloadItemPrivate : public QObject { + Q_OBJECT +public: + QWebDownloadItemPrivate(QWebDownloadItem*); + + void didReceiveResponse(QWebDownloadItem* download) { emit receivedResponse(download); } + + QWebDownloadItem* q; + + WebKit::DownloadProxy* downloadProxy; + + QUrl sourceUrl; + QString suggestedFilename; + QString destinationPath; + QString mimeType; + quint64 expectedContentLength; + quint64 totalBytesReceived; + +Q_SIGNALS: + void receivedResponse(QWebDownloadItem*); +}; + +#endif // qwebdownloaditem_p_p_h diff --git a/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider.cpp b/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider.cpp new file mode 100644 index 000000000..dce6ee9df --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider.cpp @@ -0,0 +1,66 @@ +/* + Copyright (C) 2011 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 "qwebiconimageprovider_p.h" + +#include "QtWebContext.h" +#include "QtWebIconDatabaseClient.h" +#include <QtCore/QUrl> +#include <QtGui/QImage> +#include <wtf/text/WTFString.h> + +using namespace WebKit; + +QWebIconImageProvider::QWebIconImageProvider() + : QDeclarativeImageProvider(QDeclarativeImageProvider::Image) +{ +} + +QWebIconImageProvider::~QWebIconImageProvider() +{ +} + +QImage QWebIconImageProvider::requestImage(const QString& id, QSize* size, const QSize& requestedSize) +{ + QString decodedIconUrl = id; + decodedIconUrl.remove(0, decodedIconUrl.indexOf('#') + 1); + String pageURL = QString::fromUtf8(QUrl(decodedIconUrl).toEncoded()); + + // The string identifier has the leading image://webicon/ already stripped, so we just + // need to truncate from the first slash to get the context id. + QString contextIDAsString = id; + contextIDAsString.truncate(contextIDAsString.indexOf(QLatin1Char('/'))); + bool ok = false; + uint64_t contextId = contextIDAsString.toUInt(&ok); + if (!ok) + return QImage(); + QtWebContext* context = QtWebContext::contextByID(contextId); + if (!context) + return QImage(); + + QtWebIconDatabaseClient* iconDatabase = context->iconDatabase(); + QImage icon = requestedSize.isValid() ? iconDatabase->iconImageForPageURL(pageURL, requestedSize) : iconDatabase->iconImageForPageURL(pageURL); + ASSERT(!icon.isNull()); + + if (size) + *size = icon.size(); + + return icon; +} diff --git a/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider_p.h b/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider_p.h new file mode 100644 index 000000000..8815d7b76 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qwebiconimageprovider_p.h @@ -0,0 +1,33 @@ +/* + Copyright (C) 2011 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 qwebiconimageprovider_p_h +#define qwebiconimageprovider_p_h + +#include "qwebkitglobal.h" +#include <QtDeclarative/QDeclarativeImageProvider> + +class QWEBKIT_EXPORT QWebIconImageProvider : public QDeclarativeImageProvider { +public: + QWebIconImageProvider(); + ~QWebIconImageProvider(); + QImage requestImage(const QString& id, QSize* size, const QSize& requestedSize); +}; + +#endif diff --git a/Source/WebKit2/UIProcess/API/qt/qwebnavigationhistory.cpp b/Source/WebKit2/UIProcess/API/qt/qwebnavigationhistory.cpp new file mode 100644 index 000000000..ff77dae6b --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qwebnavigationhistory.cpp @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2010 Juha Savolainen (juha.savolainen@weego.fi) + * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies) + * + * 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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 "config.h" +#include "qwebnavigationhistory_p.h" + +#include "WKBackForwardList.h" +#include "WKStringQt.h" +#include "WKURL.h" +#include "WKURLQt.h" +#include "WebBackForwardList.h" + +#include "qwebnavigationhistory_p_p.h" +#include <QDeclarativeEngine> +#include <QString> +#include <QUrl> +#include <WebKit2/WKArray.h> +#include <WebKit2/WKBackForwardListItem.h> +#include <WebKit2/WKBase.h> +#include <WebKit2/WKRetainPtr.h> + +using namespace WebKit; + +QWebNavigationListModelPrivate::QWebNavigationListModelPrivate(WKBackForwardListRef list) + : m_backForwardList(list) + , indexSign(0) +{ +} + +QWebNavigationListModel* QWebNavigationListModelPrivate::createWebNavigationModel(WKBackForwardListRef list) +{ + QWebNavigationListModel* model = new QWebNavigationListModel(); + model->d = new QWebNavigationListModelPrivate(list); + return model; +} + + +QWebNavigationHistoryPrivate::QWebNavigationHistoryPrivate(WKPageRef page) + : m_page(page) + , m_backForwardList(WKPageGetBackForwardList(page)) + , m_backNavigationModel(adoptPtr(QWebNavigationListModelPrivate::createWebNavigationModel(m_backForwardList.get()))) + , m_forwardNavigationModel(adoptPtr(QWebNavigationListModelPrivate::createWebNavigationModel(m_backForwardList.get()))) +{ + m_backNavigationModel->d->count = &WKBackForwardListGetBackListCount; + m_backNavigationModel->d->indexSign = -1; + m_forwardNavigationModel->d->count = &WKBackForwardListGetForwardListCount; + m_forwardNavigationModel->d->indexSign = 1; +} + +QWebNavigationHistory* QWebNavigationHistoryPrivate::createHistory(WKPageRef page) +{ + QWebNavigationHistory* history = new QWebNavigationHistory(); + history->d = new QWebNavigationHistoryPrivate(page); + return history; +} + +void QWebNavigationHistoryPrivate::reset() +{ + m_backNavigationModel->reset(); + m_forwardNavigationModel->reset(); +} + +void QWebNavigationHistoryPrivate::goBackTo(int index) +{ + WKRetainPtr<WKBackForwardListItemRef> itemRef = WKBackForwardListGetItemAtIndex(m_backForwardList.get(), -(index + 1)); + if (itemRef && m_page) + WKPageGoToBackForwardListItem(m_page.get(), itemRef.get()); +} + +void QWebNavigationHistoryPrivate::goForwardTo(int index) +{ + WKRetainPtr<WKBackForwardListItemRef> itemRef = WKBackForwardListGetItemAtIndex(m_backForwardList.get(), index + 1); + if (itemRef && m_page) + WKPageGoToBackForwardListItem(m_page.get(), itemRef.get()); +} + +QWebNavigationListModel::QWebNavigationListModel() + : QAbstractListModel() +{ + QHash<int, QByteArray> roles; + roles[QWebNavigationHistory::UrlRole] = "url"; + roles[QWebNavigationHistory::TitleRole] = "title"; + setRoleNames(roles); +} + +QWebNavigationListModel::~QWebNavigationListModel() +{ + delete d; +} + +int QWebNavigationListModel::rowCount(const QModelIndex&) const +{ + return d->count(d->m_backForwardList.get()); +} + +QVariant QWebNavigationListModel::data(const QModelIndex& index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (role < QWebNavigationHistory::UrlRole || role > QWebNavigationHistory::TitleRole) + return QVariant(); + + WKRetainPtr<WKBackForwardListItemRef> itemRef = WKBackForwardListGetItemAtIndex(d->m_backForwardList.get(), (index.row() + 1) * d->indexSign); + if (role == QWebNavigationHistory::UrlRole) { + WKRetainPtr<WKURLRef> url(AdoptWK, WKBackForwardListItemCopyURL(itemRef.get())); + return WKURLCopyQUrl(url.get()); + } + + if (role == QWebNavigationHistory::TitleRole) { + WKRetainPtr<WKStringRef> title(AdoptWK, WKBackForwardListItemCopyTitle(itemRef.get())); + return WKStringCopyQString(title.get()); + } + + return QVariant(); +} + +QWebNavigationHistory::QWebNavigationHistory() + : QObject() +{ +} + +QWebNavigationHistory::~QWebNavigationHistory() +{ + delete d; +} + +QWebNavigationListModel* QWebNavigationHistory::backItems() const +{ + return d->m_backNavigationModel.get(); +} + +QWebNavigationListModel* QWebNavigationHistory::forwardItems() const +{ + return d->m_forwardNavigationModel.get(); +} + +#include "moc_qwebnavigationhistory_p.cpp" diff --git a/Source/WebKit2/UIProcess/API/qt/qwebnavigationhistory_p.h b/Source/WebKit2/UIProcess/API/qt/qwebnavigationhistory_p.h new file mode 100644 index 000000000..929114472 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qwebnavigationhistory_p.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2010 Juha Savolainen (juha.savolainen@weego.fi) + * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies) + * + * 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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. +*/ + +#ifndef qwebnavigationhistory_p_h +#define qwebnavigationhistory_p_h + +#include "qwebkitglobal.h" +#include <QAbstractListModel> +#include <QObject> +#include <QUrl> +#include <QVariant> +#include <qdeclarative.h> + +class QAbstractListModel; +class QWebNavigationHistoryPrivate; +class QWebNavigationListModelPrivate; +class QUrl; +class QString; + +class QWEBKIT_EXPORT QWebNavigationListModel : public QAbstractListModel { + Q_OBJECT +public: + virtual ~QWebNavigationListModel(); + + int rowCount(const QModelIndex& parent = QModelIndex()) const; + QVariant data(const QModelIndex& index, int role) const; + +private: + QWebNavigationListModel(); + QWebNavigationListModelPrivate* d; + friend class QWebNavigationListModelPrivate; + friend class QWebNavigationHistory; + friend class QWebNavigationHistoryPrivate; +}; + +QML_DECLARE_TYPE(QWebNavigationListModel) + +class QWEBKIT_EXPORT QWebNavigationHistory : public QObject { + Q_OBJECT + Q_PROPERTY(QWebNavigationListModel* backItems READ backItems CONSTANT FINAL) + Q_PROPERTY(QWebNavigationListModel* forwardItems READ forwardItems CONSTANT FINAL) +public: + enum NavigationHistoryRoles { + UrlRole = Qt::UserRole + 1, + TitleRole = Qt::UserRole + 2 + }; + + QWebNavigationListModel* backItems() const; + QWebNavigationListModel* forwardItems() const; + + virtual ~QWebNavigationHistory(); + +private: + QWebNavigationHistory(); + + QWebNavigationHistoryPrivate* d; + friend class QWebNavigationHistoryPrivate; + friend class QQuickWebViewPrivate; + friend class QQuickWebViewExperimental; +}; + +QML_DECLARE_TYPE(QWebNavigationHistory) + +#endif /* qwebnavigationhistory_p_h */ diff --git a/Source/WebKit2/UIProcess/API/qt/qwebnavigationhistory_p_p.h b/Source/WebKit2/UIProcess/API/qt/qwebnavigationhistory_p_p.h new file mode 100644 index 000000000..c8cc5ab32 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qwebnavigationhistory_p_p.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2010 Juha Savolainen (juha.savolainen@weego.fi) + * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies) + * + * 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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. +*/ + +#ifndef qwebnavigationhistory_p_p_h +#define qwebnavigationhistory_p_p_h + +#include "qwebkitglobal.h" + +#include <QObject> +#include <WebKit2/WKBase.h> +#include <WebKit2/WKRetainPtr.h> +#include <wtf/OwnPtr.h> +#include <wtf/PassRefPtr.h> + +namespace WebKit { +class WebBackForwardList; +} + +class QWebNavigationHistory; +class QWebNavigationListModel; + +class QWebNavigationListModelPrivate { +public: + QWebNavigationListModelPrivate(WKBackForwardListRef); + + static QWebNavigationListModel* createWebNavigationModel(WKBackForwardListRef); + + unsigned (*count)(WKBackForwardListRef); + WKRetainPtr<WKBackForwardListRef> m_backForwardList; + int indexSign; +}; + +class QWebNavigationHistoryPrivate { +public: + static QWebNavigationHistory* createHistory(WKPageRef); + + QWebNavigationHistoryPrivate(WKPageRef); + void reset(); + void goBackTo(int index); + void goForwardTo(int index); + + WKRetainPtr<WKPageRef> m_page; + WKRetainPtr<WKBackForwardListRef> m_backForwardList; + OwnPtr<QWebNavigationListModel> m_backNavigationModel; + OwnPtr<QWebNavigationListModel> m_forwardNavigationModel; +}; + +#endif /* qwebnavigationhistory_p_p_h */ diff --git a/Source/WebKit2/UIProcess/API/qt/qwebnavigationrequest.cpp b/Source/WebKit2/UIProcess/API/qt/qwebnavigationrequest.cpp new file mode 100644 index 000000000..5208a061c --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qwebnavigationrequest.cpp @@ -0,0 +1,92 @@ +/* + Copyright (C) 2011 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 "qwebnavigationrequest_p.h" + +#include "qquickwebview_p.h" + +class QWebNavigationRequestPrivate { +public: + QWebNavigationRequestPrivate(const QUrl& url, const QUrl& originatingUrl, Qt::MouseButton button, Qt::KeyboardModifiers modifiers) + : url(url) + , originatingUrl(originatingUrl) + , button(button) + , modifiers(modifiers) + , action(QQuickWebView::AcceptRequest) + { + } + + ~QWebNavigationRequestPrivate() + { + } + + QUrl url; + QUrl originatingUrl; + Qt::MouseButton button; + Qt::KeyboardModifiers modifiers; + int action; +}; + +QWebNavigationRequest::QWebNavigationRequest(const QUrl& url, const QUrl& originatingUrl, Qt::MouseButton button, Qt::KeyboardModifiers modifiers, QObject* parent) + : QObject(parent) + , d(new QWebNavigationRequestPrivate(url, originatingUrl, button, modifiers)) +{ +} + +QWebNavigationRequest::~QWebNavigationRequest() +{ + delete d; +} + +void QWebNavigationRequest::setAction(int action) +{ + if (d->action == action) + return; + + d->action = action; + emit actionChanged(); +} + +QUrl QWebNavigationRequest::url() const +{ + return d->url; +} + +QUrl QWebNavigationRequest::originatingUrl() const +{ + return d->originatingUrl; +} + +int QWebNavigationRequest::button() const +{ + return int(d->button); +} + +int QWebNavigationRequest::modifiers() const +{ + return int(d->modifiers); +} + +int QWebNavigationRequest::action() const +{ + return int(d->action); +} + diff --git a/Source/WebKit2/UIProcess/API/qt/qwebnavigationrequest_p.h b/Source/WebKit2/UIProcess/API/qt/qwebnavigationrequest_p.h new file mode 100644 index 000000000..986b1c12d --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qwebnavigationrequest_p.h @@ -0,0 +1,57 @@ +/* + Copyright (C) 2011 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 qwebnavigationrequest_p_h +#define qwebnavigationrequest_p_h + +#include "qwebkitglobal.h" + +#include <QtCore/QObject> +#include <QtCore/QUrl> + +class QWebNavigationRequestPrivate; + +class QWEBKIT_EXPORT QWebNavigationRequest : public QObject { + Q_OBJECT + Q_PROPERTY(QUrl url READ url CONSTANT FINAL) + Q_PROPERTY(QUrl originatingUrl READ originatingUrl CONSTANT FINAL) + Q_PROPERTY(int button READ button CONSTANT FINAL) + Q_PROPERTY(int modifiers READ modifiers CONSTANT FINAL) + Q_PROPERTY(int action READ action WRITE setAction NOTIFY actionChanged FINAL) + +public: + QWebNavigationRequest(const QUrl& url, const QUrl& originatingUrl, Qt::MouseButton button, Qt::KeyboardModifiers modifiers, QObject* parent = 0); + ~QWebNavigationRequest(); + + QUrl url() const; + QUrl originatingUrl() const; + int button() const; + int modifiers() const; + int action() const; + + void setAction(int action); + +Q_SIGNALS: + void actionChanged(); + +private: + QWebNavigationRequestPrivate* d; +}; + +#endif // qwebnavigationrequest_h diff --git a/Source/WebKit2/UIProcess/API/qt/qwebpermissionrequest.cpp b/Source/WebKit2/UIProcess/API/qt/qwebpermissionrequest.cpp new file mode 100644 index 000000000..16a438560 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qwebpermissionrequest.cpp @@ -0,0 +1,106 @@ +/* + Copyright (C) 2011 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 "qwebpermissionrequest_p.h" + +#include "WKStringQt.h" +#include <WebKit2/WKBase.h> +#include <WebKit2/WKRetainPtr.h> + + +class QWebPermissionRequestPrivate : public QSharedData { +public: + QWebPermissionRequestPrivate(WKSecurityOriginRef securityOrigin, WKGeolocationPermissionRequestRef permissionRequest) + : origin(securityOrigin) + , type(QWebPermissionRequest::Geolocation) + , request(permissionRequest) + , allow(false) + { + } + ~QWebPermissionRequestPrivate() + { + } + + WKRetainPtr<WKSecurityOriginRef> origin; + QWebPermissionRequest::RequestType type; + WKRetainPtr<WKGeolocationPermissionRequestRef> request; + bool allow; +}; + +QWebPermissionRequest* QWebPermissionRequest::create(WKSecurityOriginRef origin, WKGeolocationPermissionRequestRef request) +{ + return new QWebPermissionRequest(origin, request); +} + +QWebPermissionRequest::QWebPermissionRequest(WKSecurityOriginRef securityOrigin, WKGeolocationPermissionRequestRef permissionRequest, QObject* parent) + : QObject(parent) + , d(new QWebPermissionRequestPrivate(securityOrigin, permissionRequest)) +{ +} + +QWebPermissionRequest::~QWebPermissionRequest() +{ +} + +QWebPermissionRequest::RequestType QWebPermissionRequest::type() const +{ + return d->type; +} + +void QWebPermissionRequest::setAllow(bool accepted) +{ + d->allow = accepted; + switch (type()) { + case Geolocation: { + if (accepted) + WKGeolocationPermissionRequestAllow(d->request.get()); + else + WKGeolocationPermissionRequestDeny(d->request.get()); + break; + } + default: + ASSERT_NOT_REACHED(); + } + + deleteLater(); +} + +bool QWebPermissionRequest::allow() const +{ + return d->allow; +} + +QString QWebPermissionRequest::scheme() const +{ + WKRetainPtr<WKStringRef> url = adoptWK(WKSecurityOriginCopyProtocol(d->origin.get())); + return WKStringCopyQString(url.get()); +} + +QString QWebPermissionRequest::host() const +{ + WKRetainPtr<WKStringRef> origin = adoptWK(WKSecurityOriginCopyHost(d->origin.get())); + return WKStringCopyQString(origin.get()); +} + +int QWebPermissionRequest::port() const +{ + return static_cast<int>(WKSecurityOriginGetPort(d->origin.get())); +} diff --git a/Source/WebKit2/UIProcess/API/qt/qwebpermissionrequest_p.h b/Source/WebKit2/UIProcess/API/qt/qwebpermissionrequest_p.h new file mode 100644 index 000000000..5824c4ccd --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qwebpermissionrequest_p.h @@ -0,0 +1,67 @@ +/* + Copyright (C) 2011 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 qwebpermissionrequest_p_h +#define qwebpermissionrequest_p_h + +#include "qwebkitglobal.h" + +#include <QtCore/QObject> +#include <QtCore/qshareddata.h> +#include <WebKit2/WKGeolocationPermissionRequest.h> +#include <WebKit2/WKSecurityOrigin.h> + +class QWebPermissionRequestPrivate; + +class QWEBKIT_EXPORT QWebPermissionRequest : public QObject { + Q_OBJECT + Q_PROPERTY(bool allow READ allow WRITE setAllow) + Q_PROPERTY(RequestType type READ type) + Q_PROPERTY(QString scheme READ scheme) + Q_PROPERTY(QString host READ host) + Q_PROPERTY(int port READ port) + Q_ENUMS(RequestType) + +public: + enum RequestType { + Geolocation + }; + + static QWebPermissionRequest* create(WKSecurityOriginRef, WKGeolocationPermissionRequestRef); + virtual ~QWebPermissionRequest(); + + RequestType type() const; + bool allow() const; + QString scheme() const; + QString host() const; + int port() const; + +public Q_SLOTS: + void setAllow(bool); + +private: + friend class QWebPermissionRequestPrivate; + QWebPermissionRequest(WKSecurityOriginRef securityOrigin, WKGeolocationPermissionRequestRef permissionRequest, QObject* parent = 0); + +private: + QExplicitlySharedDataPointer<QWebPermissionRequestPrivate> d; +}; + + +#endif // qwebpermissionrequest_h diff --git a/Source/WebKit2/UIProcess/API/qt/qwebpreferences.cpp b/Source/WebKit2/UIProcess/API/qt/qwebpreferences.cpp new file mode 100644 index 000000000..71c11afe5 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qwebpreferences.cpp @@ -0,0 +1,404 @@ +/* + Copyright (C) 2011 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 "qwebpreferences_p.h" + +#include "WKPageGroup.h" +#include "WKPreferences.h" +#include "WKPreferencesPrivate.h" +#include "WKRetainPtr.h" +#include "WKStringQt.h" +#include "qquickwebview_p_p.h" +#include "qwebpreferences_p_p.h" + +QWebPreferences* QWebPreferencesPrivate::createPreferences(QQuickWebViewPrivate* webViewPrivate) +{ + QWebPreferences* prefs = new QWebPreferences; + prefs->d->webViewPrivate = webViewPrivate; + return prefs; +} + +bool QWebPreferencesPrivate::testAttribute(QWebPreferencesPrivate::WebAttribute attr) const +{ + switch (attr) { + case AutoLoadImages: + return WKPreferencesGetLoadsImagesAutomatically(preferencesRef()); + case JavascriptEnabled: + return WKPreferencesGetJavaScriptEnabled(preferencesRef()); + case PluginsEnabled: + return WKPreferencesGetPluginsEnabled(preferencesRef()); + case OfflineWebApplicationCacheEnabled: + return WKPreferencesGetOfflineWebApplicationCacheEnabled(preferencesRef()); + case LocalStorageEnabled: + return WKPreferencesGetLocalStorageEnabled(preferencesRef()); + case XSSAuditingEnabled: + return WKPreferencesGetXSSAuditorEnabled(preferencesRef()); + case PrivateBrowsingEnabled: + return WKPreferencesGetPrivateBrowsingEnabled(preferencesRef()); + case DnsPrefetchEnabled: + return WKPreferencesGetDNSPrefetchingEnabled(preferencesRef()); + default: + ASSERT_NOT_REACHED(); + return false; + } +} + +void QWebPreferencesPrivate::setAttribute(QWebPreferencesPrivate::WebAttribute attr, bool enable) +{ + switch (attr) { + case AutoLoadImages: + WKPreferencesSetLoadsImagesAutomatically(preferencesRef(), enable); + break; + case JavascriptEnabled: + WKPreferencesSetJavaScriptEnabled(preferencesRef(), enable); + break; + case PluginsEnabled: + WKPreferencesSetPluginsEnabled(preferencesRef(), enable); + break; + case OfflineWebApplicationCacheEnabled: + WKPreferencesSetOfflineWebApplicationCacheEnabled(preferencesRef(), enable); + break; + case LocalStorageEnabled: + WKPreferencesSetLocalStorageEnabled(preferencesRef(), enable); + break; + case XSSAuditingEnabled: + WKPreferencesSetXSSAuditorEnabled(preferencesRef(), enable); + break; + case PrivateBrowsingEnabled: + WKPreferencesSetPrivateBrowsingEnabled(preferencesRef(), enable); + break; + case DnsPrefetchEnabled: + WKPreferencesSetDNSPrefetchingEnabled(preferencesRef(), enable); + break; + default: + ASSERT_NOT_REACHED(); + } +} + +void QWebPreferencesPrivate::setFontFamily(QWebPreferencesPrivate::FontFamily which, const QString& family) +{ + switch (which) { + case StandardFont: + WKPreferencesSetStandardFontFamily(preferencesRef(), WKStringCreateWithQString(family)); + break; + case FixedFont: + WKPreferencesSetFixedFontFamily(preferencesRef(), WKStringCreateWithQString(family)); + break; + case SerifFont: + WKPreferencesSetSerifFontFamily(preferencesRef(), WKStringCreateWithQString(family)); + break; + case SansSerifFont: + WKPreferencesSetSansSerifFontFamily(preferencesRef(), WKStringCreateWithQString(family)); + break; + case CursiveFont: + WKPreferencesSetCursiveFontFamily(preferencesRef(), WKStringCreateWithQString(family)); + break; + case FantasyFont: + WKPreferencesSetFantasyFontFamily(preferencesRef(), WKStringCreateWithQString(family)); + break; + default: + break; + } +} + +QString QWebPreferencesPrivate::fontFamily(QWebPreferencesPrivate::FontFamily which) const +{ + switch (which) { + case StandardFont: { + WKRetainPtr<WKStringRef> stringRef(AdoptWK, WKPreferencesCopyStandardFontFamily(preferencesRef())); + return WKStringCopyQString(stringRef.get()); + } + case FixedFont: { + WKRetainPtr<WKStringRef> stringRef(AdoptWK, WKPreferencesCopyFixedFontFamily(preferencesRef())); + return WKStringCopyQString(stringRef.get()); + } + case SerifFont: { + WKRetainPtr<WKStringRef> stringRef(AdoptWK, WKPreferencesCopySerifFontFamily(preferencesRef())); + return WKStringCopyQString(stringRef.get()); + } + case SansSerifFont: { + WKRetainPtr<WKStringRef> stringRef(AdoptWK, WKPreferencesCopySansSerifFontFamily(preferencesRef())); + return WKStringCopyQString(stringRef.get()); + } + case CursiveFont: { + WKRetainPtr<WKStringRef> stringRef(AdoptWK, WKPreferencesCopyCursiveFontFamily(preferencesRef())); + return WKStringCopyQString(stringRef.get()); + } + case FantasyFont: { + WKRetainPtr<WKStringRef> stringRef(AdoptWK, WKPreferencesCopyFantasyFontFamily(preferencesRef())); + return WKStringCopyQString(stringRef.get()); + } + default: + return QString(); + } +} + +void QWebPreferencesPrivate::setFontSize(QWebPreferencesPrivate::FontSizeType type, unsigned size) +{ + switch (type) { + case MinimumFontSize: + WKPreferencesSetMinimumFontSize(preferencesRef(), size); + break; + case DefaultFontSize: + WKPreferencesSetDefaultFontSize(preferencesRef(), size); + break; + case DefaultFixedFontSize: + WKPreferencesSetDefaultFixedFontSize(preferencesRef(), size); + break; + default: + ASSERT_NOT_REACHED(); + } +} + +unsigned QWebPreferencesPrivate::fontSize(QWebPreferencesPrivate::FontSizeType type) const +{ + switch (type) { + case MinimumFontSize: + return WKPreferencesGetMinimumFontSize(preferencesRef()); + case DefaultFontSize: + return WKPreferencesGetDefaultFontSize(preferencesRef()); + case DefaultFixedFontSize: + return WKPreferencesGetDefaultFixedFontSize(preferencesRef()); + default: + ASSERT_NOT_REACHED(); + return false; + } +} + +QWebPreferences::QWebPreferences() + : d(new QWebPreferencesPrivate) +{ +} + +QWebPreferences::~QWebPreferences() +{ + delete d; +} + +bool QWebPreferences::autoLoadImages() const +{ + return d->testAttribute(QWebPreferencesPrivate::AutoLoadImages); +} + +void QWebPreferences::setAutoLoadImages(bool enable) +{ + d->setAttribute(QWebPreferencesPrivate::AutoLoadImages, enable); + emit autoLoadImagesChanged(); +} + +bool QWebPreferences::javascriptEnabled() const +{ + return d->testAttribute(QWebPreferencesPrivate::JavascriptEnabled); +} + +void QWebPreferences::setJavascriptEnabled(bool enable) +{ + d->setAttribute(QWebPreferencesPrivate::JavascriptEnabled, enable); + emit javascriptEnabledChanged(); +} + +bool QWebPreferences::pluginsEnabled() const +{ + return d->testAttribute(QWebPreferencesPrivate::PluginsEnabled); +} + +void QWebPreferences::setPluginsEnabled(bool enable) +{ + d->setAttribute(QWebPreferencesPrivate::PluginsEnabled, enable); + emit pluginsEnabledChanged(); +} + +bool QWebPreferences::offlineWebApplicationCacheEnabled() const +{ + return d->testAttribute(QWebPreferencesPrivate::OfflineWebApplicationCacheEnabled); +} + +void QWebPreferences::setOfflineWebApplicationCacheEnabled(bool enable) +{ + d->setAttribute(QWebPreferencesPrivate::OfflineWebApplicationCacheEnabled, enable); + emit offlineWebApplicationCacheEnabledChanged(); +} + +bool QWebPreferences::localStorageEnabled() const +{ + return d->testAttribute(QWebPreferencesPrivate::LocalStorageEnabled); +} + +void QWebPreferences::setLocalStorageEnabled(bool enable) +{ + d->setAttribute(QWebPreferencesPrivate::LocalStorageEnabled, enable); + emit localStorageEnabledChanged(); +} + +bool QWebPreferences::xssAuditingEnabled() const +{ + return d->testAttribute(QWebPreferencesPrivate::XSSAuditingEnabled); +} + +void QWebPreferences::setXssAuditingEnabled(bool enable) +{ + d->setAttribute(QWebPreferencesPrivate::XSSAuditingEnabled, enable); + emit xssAuditingEnabledChanged(); +} + +bool QWebPreferences::privateBrowsingEnabled() const +{ + return d->testAttribute(QWebPreferencesPrivate::PrivateBrowsingEnabled); +} + +void QWebPreferences::setPrivateBrowsingEnabled(bool enable) +{ + d->setAttribute(QWebPreferencesPrivate::PrivateBrowsingEnabled, enable); + emit privateBrowsingEnabledChanged(); +} + +bool QWebPreferences::dnsPrefetchEnabled() const +{ + return d->testAttribute(QWebPreferencesPrivate::DnsPrefetchEnabled); +} + +void QWebPreferences::setDnsPrefetchEnabled(bool enable) +{ + d->setAttribute(QWebPreferencesPrivate::DnsPrefetchEnabled, enable); + emit dnsPrefetchEnabledChanged(); +} + +bool QWebPreferences::navigatorQtObjectEnabled() const +{ + return d->webViewPrivate->navigatorQtObjectEnabled(); +} + +void QWebPreferences::setNavigatorQtObjectEnabled(bool enable) +{ + if (enable == navigatorQtObjectEnabled()) + return; + d->webViewPrivate->setNavigatorQtObjectEnabled(enable); + emit navigatorQtObjectEnabledChanged(); +} + +QString QWebPreferences::standardFontFamily() const +{ + return d->fontFamily(QWebPreferencesPrivate::StandardFont); +} + +void QWebPreferences::setStandardFontFamily(const QString& family) +{ + d->setFontFamily(QWebPreferencesPrivate::StandardFont, family); + emit standardFontFamilyChanged(); +} + +QString QWebPreferences::fixedFontFamily() const +{ + return d->fontFamily(QWebPreferencesPrivate::FixedFont); +} + +void QWebPreferences::setFixedFontFamily(const QString& family) +{ + d->setFontFamily(QWebPreferencesPrivate::FixedFont, family); + emit fixedFontFamilyChanged(); +} + +QString QWebPreferences::serifFontFamily() const +{ + return d->fontFamily(QWebPreferencesPrivate::SerifFont); +} + +void QWebPreferences::setSerifFontFamily(const QString& family) +{ + d->setFontFamily(QWebPreferencesPrivate::SerifFont, family); + emit serifFontFamilyChanged(); +} + +QString QWebPreferences::sansSerifFontFamily() const +{ + return d->fontFamily(QWebPreferencesPrivate::SansSerifFont); +} + +void QWebPreferences::setSansSerifFontFamily(const QString& family) +{ + d->setFontFamily(QWebPreferencesPrivate::SansSerifFont, family); + emit sansSerifFontFamilyChanged(); +} + +QString QWebPreferences::cursiveFontFamily() const +{ + return d->fontFamily(QWebPreferencesPrivate::CursiveFont); +} + +void QWebPreferences::setCursiveFontFamily(const QString& family) +{ + d->setFontFamily(QWebPreferencesPrivate::CursiveFont, family); + emit cursiveFontFamilyChanged(); +} + +QString QWebPreferences::fantasyFontFamily() const +{ + return d->fontFamily(QWebPreferencesPrivate::FantasyFont); +} + +void QWebPreferences::setFantasyFontFamily(const QString& family) +{ + d->setFontFamily(QWebPreferencesPrivate::FantasyFont, family); + emit fantasyFontFamilyChanged(); +} + +unsigned QWebPreferences::minimumFontSize() const +{ + return d->fontSize(QWebPreferencesPrivate::MinimumFontSize); +} + +void QWebPreferences::setMinimumFontSize(unsigned size) +{ + d->setFontSize(QWebPreferencesPrivate::MinimumFontSize, size); + emit minimumFontSizeChanged(); +} + +unsigned QWebPreferences::defaultFontSize() const +{ + return d->fontSize(QWebPreferencesPrivate::DefaultFontSize); +} + +void QWebPreferences::setDefaultFontSize(unsigned size) +{ + d->setFontSize(QWebPreferencesPrivate::DefaultFontSize, size); + emit defaultFontSizeChanged(); +} + +unsigned QWebPreferences::defaultFixedFontSize() const +{ + return d->fontSize(QWebPreferencesPrivate::DefaultFixedFontSize); +} + +void QWebPreferences::setDefaultFixedFontSize(unsigned size) +{ + d->setFontSize(QWebPreferencesPrivate::DefaultFixedFontSize, size); + emit defaultFixedFontSizeChanged(); +} + +WKPreferencesRef QWebPreferencesPrivate::preferencesRef() const +{ + WKPageGroupRef pageGroupRef = toAPI(webViewPrivate->webPageProxy->pageGroup()); + return WKPageGroupGetPreferences(pageGroupRef); +} + +QWebPreferencesPrivate* QWebPreferencesPrivate::get(QWebPreferences* preferences) +{ + return preferences->d; +} diff --git a/Source/WebKit2/UIProcess/API/qt/qwebpreferences_p.h b/Source/WebKit2/UIProcess/API/qt/qwebpreferences_p.h new file mode 100644 index 000000000..29df04cea --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qwebpreferences_p.h @@ -0,0 +1,141 @@ +/* + Copyright (C) 2011 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 qwebpreferences_p_h +#define qwebpreferences_p_h + +#include "qwebkitglobal.h" + +#include <QtCore/QObject> + +class QWebPreferencesPrivate; + +class QWEBKIT_EXPORT QWebPreferences : public QObject { + Q_OBJECT +public: + ~QWebPreferences(); + + Q_PROPERTY(bool autoLoadImages READ autoLoadImages WRITE setAutoLoadImages NOTIFY autoLoadImagesChanged FINAL) + Q_PROPERTY(bool javascriptEnabled READ javascriptEnabled WRITE setJavascriptEnabled NOTIFY javascriptEnabledChanged FINAL) + Q_PROPERTY(bool pluginsEnabled READ pluginsEnabled WRITE setPluginsEnabled NOTIFY pluginsEnabledChanged FINAL) + Q_PROPERTY(bool offlineWebApplicationCacheEnabled READ offlineWebApplicationCacheEnabled WRITE setOfflineWebApplicationCacheEnabled NOTIFY offlineWebApplicationCacheEnabledChanged FINAL) + Q_PROPERTY(bool localStorageEnabled READ localStorageEnabled WRITE setLocalStorageEnabled NOTIFY localStorageEnabledChanged FINAL) + Q_PROPERTY(bool xssAuditingEnabled READ xssAuditingEnabled WRITE setXssAuditingEnabled NOTIFY xssAuditingEnabledChanged FINAL) + Q_PROPERTY(bool privateBrowsingEnabled READ privateBrowsingEnabled WRITE setPrivateBrowsingEnabled NOTIFY privateBrowsingEnabledChanged FINAL) + Q_PROPERTY(bool dnsPrefetchEnabled READ dnsPrefetchEnabled WRITE setDnsPrefetchEnabled NOTIFY dnsPrefetchEnabledChanged FINAL) + Q_PROPERTY(bool navigatorQtObjectEnabled READ navigatorQtObjectEnabled WRITE setNavigatorQtObjectEnabled NOTIFY navigatorQtObjectEnabledChanged FINAL) + + Q_PROPERTY(QString standardFontFamily READ standardFontFamily WRITE setStandardFontFamily NOTIFY standardFontFamilyChanged FINAL) + Q_PROPERTY(QString fixedFontFamily READ fixedFontFamily WRITE setFixedFontFamily NOTIFY fixedFontFamilyChanged FINAL) + Q_PROPERTY(QString serifFontFamily READ serifFontFamily WRITE setSerifFontFamily NOTIFY serifFontFamilyChanged FINAL) + Q_PROPERTY(QString sansSerifFontFamily READ sansSerifFontFamily WRITE setSansSerifFontFamily NOTIFY sansSerifFontFamilyChanged FINAL) + Q_PROPERTY(QString cursiveFontFamily READ cursiveFontFamily WRITE setCursiveFontFamily NOTIFY cursiveFontFamilyChanged FINAL) + Q_PROPERTY(QString fantasyFontFamily READ fantasyFontFamily WRITE setFantasyFontFamily NOTIFY fantasyFontFamilyChanged FINAL) + + Q_PROPERTY(unsigned minimumFontSize READ minimumFontSize WRITE setMinimumFontSize NOTIFY minimumFontSizeChanged FINAL) + Q_PROPERTY(unsigned defaultFontSize READ defaultFontSize WRITE setDefaultFontSize NOTIFY defaultFontSizeChanged FINAL) + Q_PROPERTY(unsigned defaultFixedFontSize READ defaultFixedFontSize WRITE setDefaultFixedFontSize NOTIFY defaultFixedFontSizeChanged FINAL) + + bool autoLoadImages() const; + void setAutoLoadImages(bool enable); + + bool javascriptEnabled() const; + void setJavascriptEnabled(bool enable); + + bool pluginsEnabled() const; + void setPluginsEnabled(bool enable); + + bool offlineWebApplicationCacheEnabled() const; + void setOfflineWebApplicationCacheEnabled(bool enable); + + bool localStorageEnabled() const; + void setLocalStorageEnabled(bool enable); + + bool xssAuditingEnabled() const; + void setXssAuditingEnabled(bool enable); + + bool privateBrowsingEnabled() const; + void setPrivateBrowsingEnabled(bool enable); + + bool dnsPrefetchEnabled() const; + void setDnsPrefetchEnabled(bool enable); + + bool navigatorQtObjectEnabled() const; + void setNavigatorQtObjectEnabled(bool); + + QString standardFontFamily() const; + void setStandardFontFamily(const QString& family); + + QString fixedFontFamily() const; + void setFixedFontFamily(const QString& family); + + QString serifFontFamily() const; + void setSerifFontFamily(const QString& family); + + QString sansSerifFontFamily() const; + void setSansSerifFontFamily(const QString& family); + + QString cursiveFontFamily() const; + void setCursiveFontFamily(const QString& family); + + QString fantasyFontFamily() const; + void setFantasyFontFamily(const QString& family); + + unsigned minimumFontSize() const; + void setMinimumFontSize(unsigned size); + + unsigned defaultFontSize() const; + void setDefaultFontSize(unsigned size); + + unsigned defaultFixedFontSize() const; + void setDefaultFixedFontSize(unsigned size); + +Q_SIGNALS: + void autoLoadImagesChanged(); + void pluginsEnabledChanged(); + void javascriptEnabledChanged(); + void offlineWebApplicationCacheEnabledChanged(); + void localStorageEnabledChanged(); + void xssAuditingEnabledChanged(); + void privateBrowsingEnabledChanged(); + void dnsPrefetchEnabledChanged(); + void navigatorQtObjectEnabledChanged(); + + void standardFontFamilyChanged(); + void fixedFontFamilyChanged(); + void serifFontFamilyChanged(); + void sansSerifFontFamilyChanged(); + void cursiveFontFamilyChanged(); + void fantasyFontFamilyChanged(); + + void minimumFontSizeChanged(); + void defaultFontSizeChanged(); + void defaultFixedFontSizeChanged(); + +private: + Q_DISABLE_COPY(QWebPreferences) + + QWebPreferences(); + + QWebPreferencesPrivate *d; + + friend class QWebPreferencesPrivate; +}; + +#endif // qwebpreferences_p_h diff --git a/Source/WebKit2/UIProcess/API/qt/qwebpreferences_p_p.h b/Source/WebKit2/UIProcess/API/qt/qwebpreferences_p_p.h new file mode 100644 index 000000000..f4ef13c21 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qwebpreferences_p_p.h @@ -0,0 +1,75 @@ +/* + Copyright (C) 2010 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 qwebpreferences_p_p_h +#define qwebpreferences_p_p_h + +#include "WKPreferences.h" + +class QQuickWebViewPrivate; + +class QWebPreferencesPrivate { +public: + + enum WebAttribute { + AutoLoadImages, + JavascriptEnabled, + PluginsEnabled, + OfflineWebApplicationCacheEnabled, + LocalStorageEnabled, + XSSAuditingEnabled, + FrameFlatteningEnabled, + PrivateBrowsingEnabled, + DnsPrefetchEnabled + }; + + enum FontFamily { + StandardFont, + FixedFont, + SerifFont, + SansSerifFont, + CursiveFont, + FantasyFont + }; + + enum FontSizeType { + MinimumFontSize, + DefaultFontSize, + DefaultFixedFontSize + }; + + static QWebPreferences* createPreferences(QQuickWebViewPrivate*); + + void setAttribute(WebAttribute attr, bool enable); + bool testAttribute(WebAttribute attr) const; + + void setFontFamily(FontFamily which, const QString& family); + QString fontFamily(FontFamily which) const; + + void setFontSize(FontSizeType type, unsigned size); + unsigned fontSize(FontSizeType type) const; + + WKPreferencesRef preferencesRef() const; + + QQuickWebViewPrivate* webViewPrivate; + + static QWebPreferencesPrivate* get(QWebPreferences*); +}; + +#endif // qwebpreferences_p_p_h diff --git a/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo.cpp b/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo.cpp new file mode 100644 index 000000000..8b6fb418b --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2011 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 program 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 program; 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 "qwebviewportinfo_p.h" + +#include "qquickwebview_p.h" +#include "qquickwebview_p_p.h" + +QWebViewportInfo::QWebViewportInfo(QQuickWebViewPrivate* webViewPrivate, QObject* parent) + : QObject(parent) + , m_webViewPrivate(webViewPrivate) +{ + +} + +QWebViewportInfo::~QWebViewportInfo() +{ + +} + +QSize QWebViewportInfo::contentsSize() const +{ + return QSize(m_webViewPrivate->pageView->width(), m_webViewPrivate->pageView->height()); +} + +QVariant QWebViewportInfo::currentScale() const +{ + if (!m_webViewPrivate->interactionEngine) + return QVariant(); + + return m_webViewPrivate->interactionEngine->currentCSSScale(); +} + +QVariant QWebViewportInfo::devicePixelRatio() const +{ + if (!m_webViewPrivate->interactionEngine) + return QVariant(); + + return m_webViewPrivate->interactionEngine->constraints().devicePixelRatio; +} + +QVariant QWebViewportInfo::initialScale() const +{ + if (!m_webViewPrivate->interactionEngine) + return QVariant(); + + return m_webViewPrivate->interactionEngine->constraints().initialScale; +} + +QVariant QWebViewportInfo::minimumScale() const +{ + if (!m_webViewPrivate->interactionEngine) + return QVariant(); + + return m_webViewPrivate->interactionEngine->constraints().minimumScale; +} + +QVariant QWebViewportInfo::maximumScale() const +{ + if (!m_webViewPrivate->interactionEngine) + return QVariant(); + + return m_webViewPrivate->interactionEngine->constraints().maximumScale; +} + +QVariant QWebViewportInfo::isScalable() const +{ + if (!m_webViewPrivate->interactionEngine) + return QVariant(); + + return m_webViewPrivate->interactionEngine->constraints().isUserScalable; +} + +QVariant QWebViewportInfo::layoutSize() const +{ + if (!m_webViewPrivate->interactionEngine) + return QVariant(); + + return m_webViewPrivate->interactionEngine->constraints().layoutSize; +} + +void QWebViewportInfo::didUpdateContentsSize() +{ + emit contentsSizeUpdated(); +} + +void QWebViewportInfo::didUpdateCurrentScale() +{ + emit currentScaleUpdated(); +} + +void QWebViewportInfo::didUpdateViewportConstraints() +{ + emit viewportConstraintsUpdated(); + emit currentScaleUpdated(); +} diff --git a/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo_p.h b/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo_p.h new file mode 100644 index 000000000..e1dea6575 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo_p.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2011 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 program 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 program; 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 qwebviewportinfp_p_h +#define qwebviewportinfo_p_h + +#include "qwebkitglobal.h" + +#include <QtCore/QObject> +#include <QtCore/QPointer> +#include <QtCore/QSize> +#include <QtCore/QVariant> +#include <QtDeclarative/QtDeclarative> + +namespace WebCore { +class ViewportAttributes; +} +class QQuickWebViewPrivate; + +class QWEBKIT_EXPORT QWebViewportInfo : public QObject { + Q_OBJECT + Q_PROPERTY(QSize contentsSize READ contentsSize NOTIFY contentsSizeUpdated) + Q_PROPERTY(QVariant currentScale READ currentScale NOTIFY currentScaleUpdated) + Q_PROPERTY(QVariant devicePixelRatio READ devicePixelRatio NOTIFY viewportConstraintsUpdated) + Q_PROPERTY(QVariant initialScale READ initialScale NOTIFY viewportConstraintsUpdated) + Q_PROPERTY(QVariant isScalable READ isScalable NOTIFY viewportConstraintsUpdated) + Q_PROPERTY(QVariant maximumScale READ maximumScale NOTIFY viewportConstraintsUpdated) + Q_PROPERTY(QVariant minimumScale READ minimumScale NOTIFY viewportConstraintsUpdated) + Q_PROPERTY(QVariant layoutSize READ layoutSize NOTIFY viewportConstraintsUpdated) + +signals: + void contentsSizeUpdated(); + void currentScaleUpdated(); + void viewportConstraintsUpdated(); + +public: + QWebViewportInfo(QQuickWebViewPrivate* webviewPrivate, QObject* parent = 0); + virtual ~QWebViewportInfo(); + + QSize contentsSize() const; + QVariant currentScale() const; + QVariant devicePixelRatio() const; + QVariant initialScale() const; + QVariant isScalable() const; + QVariant layoutSize() const; + QVariant maximumScale() const; + QVariant minimumScale() const; + + void didUpdateContentsSize(); + void didUpdateCurrentScale(); + void didUpdateViewportConstraints(); + +private: + QQuickWebViewPrivate* m_webViewPrivate; +}; + +#endif // qwebviewportinfo_p diff --git a/Source/WebKit2/UIProcess/API/qt/tests/html/basic_page.html b/Source/WebKit2/UIProcess/API/qt/tests/html/basic_page.html new file mode 100644 index 000000000..b4eea41bd --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/html/basic_page.html @@ -0,0 +1 @@ +<h1>Basic page</h1> diff --git a/Source/WebKit2/UIProcess/API/qt/tests/html/basic_page2.html b/Source/WebKit2/UIProcess/API/qt/tests/html/basic_page2.html new file mode 100644 index 000000000..f8cff2969 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/html/basic_page2.html @@ -0,0 +1 @@ +<h1>Basic page 2</h1> diff --git a/Source/WebKit2/UIProcess/API/qt/tests/html/direct-image-compositing.html b/Source/WebKit2/UIProcess/API/qt/tests/html/direct-image-compositing.html new file mode 100644 index 000000000..2fd91418a --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/html/direct-image-compositing.html @@ -0,0 +1,66 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html lang="en"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <title>Testing direct image layer optimisation</title> + <style type="text/css" media="screen"> + img { + float: left; + width: 150px; + height: 150px; + } + img { + -webkit-transform: rotate3d(0, 0, 1, 0); + } + .test { + float: left; + height: 200px; + width: 260px; + } + </style> +</head> +<body> + + <h1>Image optimisation in layers</h1> + + <p> + This test exercises direct compositing of images with hardware acceleration. The visual results + using ACCELERATED_COMPOSITING and regular TOT should be identical. Running this test manually with + the correct debug options will show which elements are directly composited. See + <a href="https://bugs.webkit.org/show_bug.cgi?id=23361">https://bugs.webkit.org/show_bug.cgi?id=23361</a> + </p> + + <div class="test"> + <img src="resources/simple_image.png"> + Basic image - no style - can be directly composited + </div> + + <div class="test"> + <img src="resources/simple_image.png" style="border: 5px solid blue;"> + 5px blue border - can NOT be directly composited + </div> + + <div class="test"> + <img src="resources/simple_image.png" style="margin: 5px 5px;"> + margin - can NOT be directly composited + </div> + + <div class="test"> + <img src="resources/simple_image.png" style="background-color: grey;"> + solid background - can be directly composited + </div> + + <div class="test"> + <img src="resources/simple_image.png" style="background: orange url(resources/simple_image.png) -50px -50px;"> + background image - can NOT be directly composited + </div> + + <div class="test"> + <img src="resources/simple_image.png" style="-webkit-transform: rotate3d(0, 0, 1, 10deg);"> + rotated but otherwise no style - can be directly composited + </div> + +</body> +</html> diff --git a/Source/WebKit2/UIProcess/API/qt/tests/html/resources/simple_image.png b/Source/WebKit2/UIProcess/API/qt/tests/html/resources/simple_image.png Binary files differnew file mode 100644 index 000000000..4685399ca --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/html/resources/simple_image.png diff --git a/Source/WebKit2/UIProcess/API/qt/tests/html/scroll.html b/Source/WebKit2/UIProcess/API/qt/tests/html/scroll.html new file mode 100644 index 000000000..6b9b2d652 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/html/scroll.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html> +<meta name="viewport" content="width=200, height=500, user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1"/> +<script type="text/javascript"> +function pageScroll() { + window.scrollBy(0,50); // horizontal and vertical scroll increments +} +</script> +<style> + body { + background-color: blue; + margin: 50 50 50 50; + } + div { + font-color: white; + background-color: green; + width: 300px; + height: 1000px; + } +</style> + +<head> +<title>Scroll test </title> +</head> +<body onload="pageScroll()"> +<div> +</div> +</body> +</html> diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/DesktopWebView.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/DesktopWebView.qml new file mode 100644 index 000000000..4dce0918b --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/DesktopWebView.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 +import QtWebKit 3.0 +import QtWebKit.experimental 3.0 + +WebView { + id: component + experimental.useTraditionalDesktopBehaviour: true +} + diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_linkHovered.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_linkHovered.qml new file mode 100644 index 000000000..c98958319 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_linkHovered.qml @@ -0,0 +1,85 @@ +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 + +DesktopWebView { + id: webView + width: 200 + height: 400 + focus: true + + property string lastUrl + property string lastTitle + + SignalSpy { + id: spy + target: webView + signalName: "linkHovered" + } + + SignalSpy { + id: loadSpy + target: webView + signalName: "loadSucceeded" + } + + onLinkHovered: { + webView.lastUrl = url + webView.lastTitle = title + } + + TestCase { + name: "DesktopWebViewLinkHovered" + + // Delayed windowShown to workaround problems with Qt5 in debug mode. + when: false + Timer { + running: parent.windowShown + repeat: false + interval: 1 + onTriggered: parent.when = true + } + + function init() { + webView.lastUrl = "" + webView.lastTitle = "" + spy.clear() + } + + function test_linkHovered() { + compare(spy.count, 0) + webView.load(Qt.resolvedUrl("../common/test2.html")) + loadSpy.wait() + mouseMove(webView, 100, 100) + spy.wait() + compare(spy.count, 1) + compare(webView.lastUrl, Qt.resolvedUrl("../common/test1.html")) + compare(webView.lastTitle, "A title") + mouseMove(webView, 100, 300) + spy.wait() + compare(spy.count, 2) + compare(webView.lastUrl, "") + compare(webView.lastTitle, "") + } + + function test_linkHoveredDoesntEmitRepeated() { + compare(spy.count, 0) + webView.load(Qt.resolvedUrl("../common/test2.html")) + loadSpy.wait() + + for (var i = 0; i < 100; i += 10) + mouseMove(webView, 100, 100 + i) + + spy.wait() + compare(spy.count, 1) + compare(webView.lastUrl, Qt.resolvedUrl("../common/test1.html")) + + for (var i = 0; i < 100; i += 10) + mouseMove(webView, 100, 300 + i) + + spy.wait() + compare(spy.count, 2) + compare(webView.lastUrl, "") + } + } +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_loadHtml.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_loadHtml.qml new file mode 100644 index 000000000..b45b01ac8 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_loadHtml.qml @@ -0,0 +1,60 @@ +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 + +DesktopWebView { + id: webView + width: 200 + height: 400 + focus: true + + property string lastUrl + + SignalSpy { + id: loadSpy + target: webView + signalName: "loadSucceeded" + } + + SignalSpy { + id: linkHoveredSpy + target: webView + signalName: "linkHovered" + } + + onLinkHovered: { + webView.lastUrl = url + } + + TestCase { + name: "DesktopWebViewLoadHtml" + + // Delayed windowShown to workaround problems with Qt5 in debug mode. + when: false + Timer { + running: parent.windowShown + repeat: false + interval: 1 + onTriggered: parent.when = true + } + + function init() { + webView.lastUrl = "" + linkHoveredSpy.clear() + loadSpy.clear() + } + + function test_baseUrlAfterLoadHtml() { + loadSpy.clear() + linkHoveredSpy.clear() + compare(linkHoveredSpy.count, 0) + webView.loadHtml("<html><head><title>Test page with huge link area</title></head><body><a title=\"A title\" href=\"test1.html\"><img width=200 height=200></a></body></html>", "http://www.example.foo.com") + loadSpy.wait() + compare("http://www.example.foo.com/", webView.url) + mouseMove(webView, 100, 100) + linkHoveredSpy.wait() + compare(linkHoveredSpy.count, 1) + compare(webView.lastUrl, "http://www.example.foo.com/test1.html") + } + } +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_messaging.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_messaging.qml new file mode 100644 index 000000000..7fcc91a64 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_messaging.qml @@ -0,0 +1,108 @@ +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 +import QtWebKit.experimental 3.0 + +Item { + DesktopWebView { + id: webView + property variant lastMessage + experimental.preferences.navigatorQtObjectEnabled: true + experimental.onMessageReceived: { + lastMessage = message + } + } + + DesktopWebView { + id: otherWebView + property variant lastMessage + experimental.preferences.navigatorQtObjectEnabled: true + experimental.onMessageReceived: { + lastMessage = message + } + } + + DesktopWebView { + id: disabledWebView + property bool receivedMessage + experimental.preferences.navigatorQtObjectEnabled: false + experimental.onMessageReceived: { + receivedMessage = true + } + } + + SignalSpy { + id: loadSpy + target: webView + signalName: "loadSucceeded" + } + + SignalSpy { + id: messageSpy + target: webView.experimental + signalName: "messageReceived" + } + + SignalSpy { + id: otherLoadSpy + target: otherWebView + signalName: "loadSucceeded" + } + + SignalSpy { + id: otherMessageSpy + target: otherWebView.experimental + signalName: "messageReceived" + } + + SignalSpy { + id: disabledWebViewLoadSpy + target: disabledWebView + signalName: "loadSucceeded" + } + + TestCase { + name: "DesktopWebViewMessaging" + property url testUrl: Qt.resolvedUrl("../common/messaging.html") + + function init() { + loadSpy.clear() + messageSpy.clear() + webView.lastMessage = null + otherLoadSpy.clear() + otherMessageSpy.clear() + otherWebView.lastMessage = null + } + + function test_basic() { + webView.load(testUrl) + loadSpy.wait() + webView.experimental.postMessage("HELLO") + messageSpy.wait() + compare(webView.lastMessage.data, "OLLEH") + compare(webView.lastMessage.origin.toString(), testUrl.toString()) + } + + function test_twoWebViews() { + webView.load(testUrl) + otherWebView.load(testUrl) + loadSpy.wait() + otherLoadSpy.wait() + webView.experimental.postMessage("FIRST") + otherWebView.experimental.postMessage("SECOND") + messageSpy.wait() + otherMessageSpy.wait() + compare(webView.lastMessage.data, "TSRIF") + compare(otherWebView.lastMessage.data, "DNOCES") + } + + function test_disabled() { + disabledWebView.load(testUrl) + verify(!disabledWebView.experimental.preferences.navigatorQtObjectEnabled) + disabledWebViewLoadSpy.wait() + disabledWebView.experimental.postMessage("HI") + wait(1000) + verify(!disabledWebView.receivedMessage) + } + } +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_navigationRequested.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_navigationRequested.qml new file mode 100644 index 000000000..3ef7d5516 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_navigationRequested.qml @@ -0,0 +1,151 @@ +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 +import QtWebKit.experimental 3.0 + +Item { + property int expectedLength: 0 + property int totalBytes: 0 + property bool shouldDownload: false + property string originatingUrl: "" + property url beginUrl: Qt.resolvedUrl("../common/test2.html") + property url endUrl: Qt.resolvedUrl("../common/test1.html") + + DesktopWebView { + id: webView + width: 200 + height: 200 + + signal downloadFinished() + + onNavigationRequested: { + if (shouldDownload) + request.action = WebViewExperimental.DownloadRequest + else if (request.button == Qt.MiddleButton && request.modifiers & Qt.ControlModifier) { + otherWebView.load(request.url) + request.action = WebView.IgnoreRequest + } + originatingUrl = request.originatingUrl + } + + experimental.onDownloadRequested: { + download.target = downloadItem + expectedLength = downloadItem.expectedContentLength + downloadItem.destinationPath = downloadItem.suggestedFilename + downloadItem.start() + } + + Connections { + id: download + ignoreUnknownSignals: true + onSucceeded: { + totalBytes = download.target.totalBytesReceived + webView.downloadFinished() + } + } + } + + SignalSpy { + id: spy + target: webView + signalName: "loadSucceeded" + } + + DesktopWebView { + id: otherWebView + } + + SignalSpy { + id: otherSpy + target: otherWebView + signalName: "loadSucceeded" + } + + SignalSpy { + id: downloadSpy + target: webView.experimental + signalName: "downloadRequested" + } + + SignalSpy { + id: downloadFinishedSpy + target: webView + signalName: "downloadFinished" + } + + TestCase { + name: "DesktopWebViewNavigationRequested" + + // Delayed windowShown to workaround problems with Qt5 in debug mode. + when: false + Timer { + running: parent.windowShown + repeat: false + interval: 1 + onTriggered: parent.when = true + } + + function init() { + spy.clear() + otherSpy.clear() + downloadSpy.clear() + downloadFinishedSpy.clear() + shouldDownload = false + originatingUrl = "" + } + + function test_usePolicy() { + webView.load(beginUrl) + spy.wait() + spy.clear() + mouseClick(webView, 100, 100, Qt.LeftButton) + spy.wait() + compare(spy.count, 1) + compare(webView.title, "Test page 1") + compare(webView.url, endUrl) + } + + function test_ignorePolicy() { + webView.load(beginUrl) + spy.wait() + spy.clear() + compare(spy.count, 0) + compare(otherSpy.count, 0) + mouseClick(webView, 100, 100, Qt.MiddleButton, Qt.ControlModifier) + otherSpy.wait() + compare(spy.count, 0) + compare(otherSpy.count, 1) + compare(webView.url, beginUrl) + compare(otherWebView.title, "Test page 1") + compare(otherWebView.url, endUrl) + } + + function test_downloadPolicy() { + webView.load(beginUrl) + spy.wait() + spy.clear() + compare(spy.count, 0) + downloadSpy.clear() + downloadFinishedSpy.clear() + expectedLength = 0 + shouldDownload = true + mouseClick(webView, 100, 100, Qt.LeftButton) + downloadSpy.wait() + compare(downloadSpy.count, 1) + downloadFinishedSpy.wait() + compare(downloadFinishedSpy.count, 1) + compare(totalBytes, expectedLength) + } + + function test_originatingUrl() { + webView.load(beginUrl) + spy.wait() + spy.clear() + mouseClick(webView, 100, 100, Qt.LeftButton) + spy.wait() + compare(webView.title, "Test page 1") + compare(webView.url, endUrl) + compare(originatingUrl, beginUrl) + } + } +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_applicationScheme.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_applicationScheme.qml new file mode 100644 index 000000000..29774e117 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_applicationScheme.qml @@ -0,0 +1,41 @@ +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 +import QtWebKit.experimental 3.0 + +WebView { + id: webView + width: 400 + height: 300 + + experimental { + urlSchemeDelegates: [ + UrlSchemeDelegate { + scheme: "applicationScheme" + onReceivedRequest: { + reply.data = "<html><head><title>Test Application Scheme</title></head><body>A test page.</body></html>" + reply.send() + } + } + ] + } + + SignalSpy { + id: spyTitle + target: webView + signalName: "titleChanged" + } + + TestCase { + name: "WebViewApplicationSchemes" + + function test_applicationScheme() { + compare(spyTitle.count, 0) + var testUrl = "applicationScheme://something" + webView.load(testUrl) + spyTitle.wait() + compare(webView.title, "Test Application Scheme") + } + } + +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_download.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_download.qml new file mode 100644 index 000000000..6c25af3bc --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_download.qml @@ -0,0 +1,86 @@ +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 +import QtWebKit.experimental 3.0 + +WebView { + id: webView + width: 200 + height: 200 + + property int expectedLength: 0 + property int totalBytes: 0 + + signal downloadFinished() + + SignalSpy { + id: spy + target: experimental + signalName: "downloadRequested" + } + + SignalSpy { + id: downloadFinishedSpy + target: webView + signalName: "downloadFinished" + } + + experimental.onDownloadRequested: { + download.target = downloadItem + expectedLength = downloadItem.expectedContentLength + downloadItem.destinationPath = downloadItem.suggestedFilename + downloadItem.start() + } + + Connections { + id: download + ignoreUnknownSignals: true + onSucceeded: { + totalBytes = download.target.totalBytesReceived + webView.downloadFinished() + } + } + + TestCase { + name: "WebViewDownload" + + // Delayed windowShown to workaround problems with Qt5 in debug mode. + when: false + Timer { + running: parent.windowShown + repeat: false + interval: 1 + onTriggered: parent.when = true + } + + function init() { + spy.clear() + downloadFinishedSpy.clear() + expectedLength = 0 + } + + function test_downloadRequest() { + compare(spy.count, 0) + webView.load(Qt.resolvedUrl("../common/download.zip")) + spy.wait() + compare(spy.count, 1) + } + + function test_expectedLength() { + compare(spy.count, 0) + webView.load(Qt.resolvedUrl("../common/download.zip")) + spy.wait() + compare(spy.count, 1) + compare(expectedLength, 325) + } + + function test_succeeded() { + compare(spy.count, 0) + webView.load(Qt.resolvedUrl("../common/download.zip")) + spy.wait() + compare(spy.count, 1) + downloadFinishedSpy.wait() + compare(totalBytes, expectedLength) + } + } +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_favIconLoad.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_favIconLoad.qml new file mode 100644 index 000000000..121809316 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_favIconLoad.qml @@ -0,0 +1,60 @@ +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 + +WebView { + id: webView + + SignalSpy { + id: spy + target: webView + signalName: "iconChanged" + } + + SignalSpy { + id: loadSpy + target: webView + signalName: "loadSucceeded" + } + + Image { + id: favicon + source: webView.icon + } + + TestCase { + id: test + name: "WebViewLoadFavIcon" + + function init() { + if (webView.icon != '') { + // If this is not the first test, then load a blank page without favicon, restoring the initial state. + webView.load('about:blank') + spy.wait() + loadSpy.wait() + } + loadSpy.clear() + spy.clear() + } + + function test_favIconLoad() { + compare(spy.count, 0) + var url = Qt.resolvedUrl("../common/favicon.html") + webView.load(url) + spy.wait() + compare(spy.count, 1) + compare(favicon.width, 48) + compare(favicon.height, 48) + } + + function test_favIconLoadEncodedUrl() { + compare(spy.count, 0) + var url = Qt.resolvedUrl("../common/favicon2.html?favicon=load should work with#whitespace!") + webView.load(url) + spy.wait() + compare(spy.count, 1) + compare(favicon.width, 16) + compare(favicon.height, 16) + } + } +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_geopermission.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_geopermission.qml new file mode 100644 index 000000000..697ab085a --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_geopermission.qml @@ -0,0 +1,54 @@ +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 +import QtWebKit.experimental 3.0 + +WebView { + id: webView + width: 200 + height: 200 + + property bool expectedPermission: false + + SignalSpy { + id: spy + target: experimental + signalName: "permissionRequested" + } + + experimental.onPermissionRequested: { + //Must be false by default + if (!permission.allow) { + permission.allow = true + } else + console.log("Fail: permission must be set to false") + + if (permission.type == PermissionRequest.Geolocation) { + console.log("Permission is geotype") + } + } + + TestCase { + name: "WebViewGeopermission" + + // Delayed windowShown to workaround problems with Qt5 in debug mode. + when: false + Timer { + running: parent.windowShown + repeat: false + interval: 1 + onTriggered: parent.when = true + } + + function init() { + spy.clear() + } + + function test_permissionRequest() { + compare(spy.count, 0) + webView.load(Qt.resolvedUrl("../common/geolocation.html")) + spy.wait() + compare(spy.count, 1) + } + } +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_itemSelector.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_itemSelector.qml new file mode 100644 index 000000000..03d68be5b --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_itemSelector.qml @@ -0,0 +1,119 @@ +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 +import QtWebKit.experimental 3.0 + +// FIXME: used because we want to have mouseClick() to open the <select> tag. We can remove this +// when TestCase starts supporting touch events, see https://bugreports.qt.nokia.com/browse/QTBUG-23083. +import "../DesktopBehavior" + +DesktopWebView { + id: webView + + width: 400 + height: 400 + + property int initialSelection + property int finalSelection + property bool useAcceptDirectly + property bool selectorLoaded + + experimental.itemSelector: Item { + Component.onCompleted: { + if (WebView.view.initialSelection != -1) + model.items.select(WebView.view.initialSelection) + + if (WebView.view.finalSelection == -1) + model.reject() + else { + if (useAcceptDirectly) { + model.accept(WebView.view.finalSelection) + } else { + model.items.select(WebView.view.finalSelection) + model.accept() + } + } + + WebView.view.selectorLoaded = true + } + } + + SignalSpy { + id: loadSpy + target: webView + signalName: "loadSucceeded" + } + + SignalSpy { + id: titleSpy + target: webView + signalName: "titleChanged" + } + + TestCase { + id: test + name: "WebViewItemSelector" + when: windowShown + + function init() { + webView.initialSelection = -1 + webView.finalSelection = -1 + webView.useAcceptDirectly = false + webView.selectorLoaded = false + loadSpy.clear() + webView.load(Qt.resolvedUrl("../common/select.html")) + loadSpy.wait() + titleSpy.clear() + } + + function openItemSelector() { + mouseClick(webView, 15, 15, Qt.LeftButton) + } + + function test_accept() { + webView.finalSelection = 1 + openItemSelector() + titleSpy.wait() + compare(webView.title, "__closed__") + } + + function test_acceptDirectly() { + webView.finalSelection = 1 + webView.useAcceptDirectly = true + openItemSelector() + titleSpy.wait() + compare(webView.title, "__closed__") + } + + function test_selectFirstThenAccept() { + webView.initialSelection = 1 + webView.finalSelection = 2 + openItemSelector() + titleSpy.wait() + compare(webView.title, "__all__") + } + + function test_selectFirstThenAcceptDirectly() { + webView.initialSelection = 1 + webView.finalSelection = 2 + webView.useAcceptDirectly = true + openItemSelector() + titleSpy.wait() + compare(webView.title, "__all__") + } + + function test_reject() { + openItemSelector() + tryCompare(webView, "selectorLoaded", true) + compare(webView.title, "No new selection was made") + } + + function test_selectFirstThenReject() { + webView.initialSelection = 1 + webView.finalSelection = -1 + openItemSelector() + tryCompare(webView, "selectorLoaded", true) + compare(webView.title, "No new selection was made") + } + } +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_javaScriptDialogs.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_javaScriptDialogs.qml new file mode 100644 index 000000000..56c34abcd --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_javaScriptDialogs.qml @@ -0,0 +1,125 @@ +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 +import QtWebKit.experimental 3.0 + +WebView { + id: webView + + property bool modelMessageEqualsMessage: false + property string messageFromAlertDialog: "" + property int confirmCount: 0 + property int promptCount: 0 + + experimental.alertDialog: Item { + Timer { + running: true + interval: 1 + onTriggered: { + // Testing both attached property and id defined in the Component context. + parent.WebView.view.messageFromAlertDialog = message + webView.modelMessageEqualsMessage = Boolean(model.message == message) + model.dismiss() + } + } + } + + experimental.confirmDialog: Item { + Timer { + running: true + interval: 1 + onTriggered: { + parent.WebView.view.confirmCount += 1 + if (message == "ACCEPT") + model.accept() + else + model.reject() + } + } + } + + experimental.promptDialog: Item { + Timer { + running: true + interval: 1 + onTriggered: { + parent.WebView.view.promptCount += 1 + if (message == "REJECT") + model.reject() + else { + var reversedDefaultValue = defaultValue.split("").reverse().join("") + model.accept(reversedDefaultValue) + } + } + } + } + + SignalSpy { + id: loadSpy + target: webView + signalName: "loadSucceeded" + } + + TestCase { + id: test + name: "WebViewJavaScriptDialogs" + + function init() { + webView.modelMessageEqualsMessage = false + webView.messageFromAlertDialog = "" + webView.confirmCount = 0 + webView.promptCount = 0 + loadSpy.clear() + } + + function test_alert() { + webView.load(Qt.resolvedUrl("../common/alert.html")) + loadSpy.wait() + compare(loadSpy.count, 1) + compare(webView.messageFromAlertDialog, "Hello Qt") + verify(webView.modelMessageEqualsMessage) + } + + function test_alertWithoutDialog() { + webView.experimental.alertDialog = null + webView.load(Qt.resolvedUrl("../common/alert.html")) + loadSpy.wait() + compare(loadSpy.count, 1) + compare(webView.messageFromAlertDialog, "") + } + + function test_confirm() { + webView.load(Qt.resolvedUrl("../common/confirm.html")) + loadSpy.wait() + compare(loadSpy.count, 1) + compare(webView.confirmCount, 2) + compare(webView.title, "ACCEPTED REJECTED") + } + + function test_confirmWithoutDialog() { + webView.experimental.confirmDialog = null + webView.load(Qt.resolvedUrl("../common/confirm.html")) + loadSpy.wait() + compare(loadSpy.count, 1) + compare(webView.confirmCount, 0) + compare(webView.title, "ACCEPTED ACCEPTED") + } + + function test_prompt() { + webView.load(Qt.resolvedUrl("../common/prompt.html")) + loadSpy.wait() + compare(loadSpy.count, 1) + compare(webView.promptCount, 2) + compare(webView.title, "tQ olleH") + } + + function test_promptWithoutDialog() { + webView.experimental.promptDialog = null + webView.load(Qt.resolvedUrl("../common/prompt.html")) + loadSpy.wait() + compare(loadSpy.count, 1) + compare(webView.promptCount, 0) + compare(webView.title, "FAIL") + } + } +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadFail.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadFail.qml new file mode 100644 index 000000000..26a42c0b7 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadFail.qml @@ -0,0 +1,35 @@ +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 + +WebView { + id: webView + width: 400 + height: 300 + + property variant testUrl + + SignalSpy { + id: spy + target: webView + signalName: "loadFailed" + } + + TestCase { + id: test + name: "WebViewLoadFail" + function test_fail() { + compare(spy.count, 0) + testUrl = Qt.resolvedUrl("file_that_does_not_exist.html") + webView.load(testUrl) + spy.wait() + compare(spy.count, 1) + } + } + + onLoadFailed: { + test.compare(url, testUrl) + test.compare(errorCode, NetworkReply.ContentNotFoundError) + test.compare(errorDomain, WebView.NetworkErrorDomain) + } +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadHtml.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadHtml.qml new file mode 100644 index 000000000..b57df66a6 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadHtml.qml @@ -0,0 +1,28 @@ +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 + +WebView { + id: webView + width: 200 + height: 400 + + SignalSpy { + id: loadSpy + target: webView + signalName: "loadSucceeded" + } + + TestCase { + name: "WebViewLoadHtml" + + function test_loadProgressAfterLoadHtml() { + loadSpy.clear() + compare(loadSpy.count, 0) + compare(webView.loadProgress, 0) + webView.loadHtml("<html><head><title>Test page 1</title></head><body>Hello.</body></html>") + loadSpy.wait() + compare(webView.loadProgress, 100) + } + } +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadProgress.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadProgress.qml new file mode 100644 index 000000000..a51d6f69f --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadProgress.qml @@ -0,0 +1,28 @@ +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 + +WebView { + id: webView + width: 400 + height: 300 + + SignalSpy { + id: spy + target: webView + signalName: "loadSucceeded" + } + + TestCase { + name: "WebViewLoadProgress" + + function test_loadProgress() { + compare(spy.count, 0) + compare(webView.loadProgress, 0) + webView.load(Qt.resolvedUrl("../common/test1.html")) + compare(webView.loadProgress, 0) + spy.wait() + compare(webView.loadProgress, 100) + } + } +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadProgressSignal.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadProgressSignal.qml new file mode 100644 index 000000000..10ac879a8 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadProgressSignal.qml @@ -0,0 +1,38 @@ +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 + +WebView { + id: webView + width: 400 + height: 300 + + SignalSpy { + id: spy + target: webView + signalName: "loadSucceeded" + } + + SignalSpy { + id: spyProgress + target: webView + signalName: "loadProgressChanged" + } + + TestCase { + name: "WebViewLoadProgressSignal" + + function test_loadProgressSignal() { + compare(spyProgress.count, 0) + compare(webView.loadProgress, 0) + webView.load(Qt.resolvedUrl("../common/test1.html")) + spyProgress.wait() + compare(true, webView.loadProgress > -1 && webView.loadProgress < 101) + if (webView.loadProgress > 0 && webView.loadProgress < 100) { + spy.wait() + spyProgress.wait() + compare(webView.loadProgress, 100) + } + } + } +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_navigationHistory.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_navigationHistory.qml new file mode 100644 index 000000000..68aeeb556 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_navigationHistory.qml @@ -0,0 +1,108 @@ +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 +import QtWebKit.experimental 3.0 + +WebView { + id: webView + width: 400 + height: 300 + + SignalSpy { + id: spy + target: webView + signalName: "loadSucceeded" + } + + ListView { + id: backItemsList + anchors.fill: parent + model: webView.experimental.navigationHistory.backItems + delegate: + Text { + color:"black" + text: "title : " + title + } + } + + ListView { + id: forwardItemsList + anchors.fill: parent + model: webView.experimental.navigationHistory.forwardItems + delegate: + Text { + color:"black" + text: "title : " + title + } + } + + TestCase { + name: "WebViewNavigationHistory" + + function test_navigationHistory() { + compare(spy.count, 0) + compare(webView.loadProgress, 0) + webView.load(Qt.resolvedUrl("../common/test1.html")) + spy.wait() + compare(webView.canGoBack, false) + compare(webView.canGoForward, false) + compare(backItemsList.count, 0) + compare(forwardItemsList.count, 0) + spy.clear() + webView.load(Qt.resolvedUrl("../common/test2.html")) + spy.wait() + compare(webView.url, Qt.resolvedUrl("../common/test2.html")) + compare(webView.canGoBack, true) + compare(webView.canGoForward, false) + compare(backItemsList.count, 1) + spy.clear() + webView.experimental.goBackTo(0) + spy.wait() + compare(webView.url, Qt.resolvedUrl("../common/test1.html")) + compare(webView.canGoBack, false) + compare(webView.canGoForward, true) + compare(backItemsList.count, 0) + compare(forwardItemsList.count, 1) + spy.clear() + webView.goForward() + spy.wait() + compare(webView.url, Qt.resolvedUrl("../common/test2.html")) + compare(webView.canGoBack, true) + compare(webView.canGoForward, false) + compare(backItemsList.count, 1) + compare(forwardItemsList.count, 0) + spy.clear() + webView.load(Qt.resolvedUrl("../common/javascript.html")) + spy.wait() + compare(webView.url, Qt.resolvedUrl("../common/javascript.html")) + compare(webView.canGoBack, true) + compare(webView.canGoForward, false) + compare(backItemsList.count, 2) + compare(forwardItemsList.count, 0) + spy.clear() + webView.experimental.goBackTo(1) + spy.wait() + compare(webView.url, Qt.resolvedUrl("../common/test1.html")) + compare(webView.canGoBack, false) + compare(webView.canGoForward, true) + compare(backItemsList.count, 0) + compare(forwardItemsList.count, 2) + spy.clear() + webView.experimental.goForwardTo(1) + spy.wait() + compare(webView.url, Qt.resolvedUrl("../common/javascript.html")) + compare(webView.canGoBack, true) + compare(webView.canGoForward, false) + compare(backItemsList.count, 2) + compare(forwardItemsList.count, 0) + spy.clear() + webView.goBack() + spy.wait() + compare(webView.url, Qt.resolvedUrl("../common/test2.html")) + compare(webView.canGoBack, true) + compare(webView.canGoForward, true) + compare(backItemsList.count, 1) + compare(forwardItemsList.count, 1) + } + } +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_preferences.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_preferences.qml new file mode 100644 index 000000000..0554abb2d --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_preferences.qml @@ -0,0 +1,101 @@ +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 +import QtWebKit.experimental 3.0 + +Item { + WebView { + id: webView + width: 400 + height: 300 + + experimental.preferences.javascriptEnabled: true + experimental.preferences.localStorageEnabled: true + experimental.preferences.pluginsEnabled: true + + WebView { + id: webView2 + width: 400 + height: 300 + } + + SignalSpy { + id: spy + target: webView + signalName: "loadSucceeded" + } + + SignalSpy { + id: otherSpy + target: webView2 + signalName: "loadSucceeded" + } + + TestCase { + name: "WebViewPreferences" + + function init() { + webView.experimental.preferences.javascriptEnabled = true + webView.experimental.preferences.localStorageEnabled = true + webView.experimental.preferences.pluginsEnabled = true + spy.clear() + } + + function test_javascriptEnabled() { + webView.experimental.preferences.javascriptEnabled = true + var testUrl = Qt.resolvedUrl("../common/javascript.html") + webView.load(testUrl) + spy.wait() + compare(webView.title, "New Title") + } + + function test_javascriptDisabled() { + webView.experimental.preferences.javascriptEnabled = false + var testUrl = Qt.resolvedUrl("../common/javascript.html") + webView.load(testUrl) + spy.wait() + compare(webView.title, "Original Title") + } + + function test_localStorageDisabled() { + webView.experimental.preferences.localStorageEnabled = false + var testUrl = Qt.resolvedUrl("../common/localStorage.html") + webView.load(testUrl) + spy.wait() + compare(webView.title, "Original Title") + } + + function test_localStorageEnabled() { + webView.experimental.preferences.localStorageEnabled = true + var testUrl = Qt.resolvedUrl("../common/localStorage.html") + webView.load(testUrl) + spy.wait() + spy.clear() + webView.load(testUrl) + spy.wait() + compare(webView.title, "New Title") + } + + function test_preferencesAffectCurrentViewOnly() { + webView.experimental.preferences.javascriptEnabled = true + webView2.experimental.preferences.javascriptEnabled = true + var testUrl = Qt.resolvedUrl("../common/javascript.html") + webView.load(testUrl) + spy.wait() + webView2.load(testUrl) + otherSpy.wait() + compare(webView.title, "New Title") + compare(webView2.title, "New Title") + spy.clear() + otherSpy.clear() + webView.experimental.preferences.javascriptEnabled = false + webView.load(testUrl) + spy.wait() + webView2.load(testUrl) + otherSpy.wait() + compare(webView.title, "Original Title") + compare(webView2.title, "New Title") + } + } + } +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_properties.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_properties.qml new file mode 100644 index 000000000..4761cd322 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_properties.qml @@ -0,0 +1,34 @@ +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 + +WebView { + id: webView + width: 400 + height: 300 + + SignalSpy { + id: spy + target: webView + signalName: "loadSucceeded" + } + + TestCase { + name: "WebViewProperties" + + function test_title() { + compare(spy.count, 0) + webView.load(Qt.resolvedUrl("../common/test1.html")) + spy.wait() + compare(webView.title, "Test page 1") + } + + function test_url() { + compare(spy.count, 1) + var testUrl = Qt.resolvedUrl("../common/test1.html") + webView.load(testUrl) + spy.wait() + compare(webView.url, testUrl) + } + } +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_titleChanged.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_titleChanged.qml new file mode 100644 index 000000000..f36ea8579 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_titleChanged.qml @@ -0,0 +1,35 @@ +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 + +WebView { + id: webView + width: 400 + height: 300 + + SignalSpy { + id: spy + target: webView + signalName: "loadSucceeded" + } + + SignalSpy { + id: spyTitle + target: webView + signalName: "titleChanged" + } + + TestCase { + name: "WebViewTitleChangedSignal" + + function test_titleFirstLoad() { + compare(spyTitle.count, 0) + var testUrl = Qt.resolvedUrl("../common/test3.html") + webView.load(testUrl) + spyTitle.wait() + compare(webView.title, "Test page 3") + spyTitle.wait() + compare(webView.title, "New Title") + } + } +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/alert.html b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/alert.html new file mode 100644 index 000000000..a75b9a60f --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/alert.html @@ -0,0 +1,8 @@ +<!doctype html> +<html> +<head> +<script>alert("Hello Qt");</script> +</head> +<body> +</body> +</html> diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/confirm.html b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/confirm.html new file mode 100644 index 000000000..5dd6081d4 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/confirm.html @@ -0,0 +1,19 @@ +<!doctype html> +<html> +<head> +<script> +document.title = ""; +function updateTitle(accepted) { + if (accepted) + document.title += " ACCEPTED"; + else + document.title += " REJECTED"; +} + +updateTitle(confirm("ACCEPT")); +updateTitle(confirm("REJECT")); +</script> +</head> +<body> +</body> +</html> diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/download.zip b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/download.zip Binary files differnew file mode 100644 index 000000000..b5456351a --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/download.zip diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/favicon.html b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/favicon.html new file mode 100644 index 000000000..c9f225c52 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/favicon.html @@ -0,0 +1,10 @@ +<html> +<head> +</head> +<link type="image/png" href="favicon.png" sizes="48x48" rel="icon" /> +<body> +<p>It's expected that you see a favicon displayed for this page when you open it as a local file.</p> +<p>The favicon looks like this:</p> +<img src="favicon.png"/> +</body> +</html> diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/favicon.png b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/favicon.png Binary files differnew file mode 100644 index 000000000..35717cca5 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/favicon.png diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/favicon2.html b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/favicon2.html new file mode 100644 index 000000000..5548b867f --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/favicon2.html @@ -0,0 +1,10 @@ +<html> +<head> +</head> +<link type="image/png" href="small-favicon.png" sizes="16x16" rel="icon" /> +<body> +<p>It's expected that you see a favicon displayed for this page when you open it as a local file.</p> +<p>The favicon looks like this:</p> +<img src="small-favicon.png"/> +</body> +</html> diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/geolocation.html b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/geolocation.html new file mode 100644 index 000000000..2d41cab3e --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/geolocation.html @@ -0,0 +1,29 @@ +<head> +<title>Geolocation Permission API Test</title> +<meta content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" name="viewport"/> +<script> +var watchId = 0; + +function successHandler(location) { + var message = document.getElementById("message"), html = []; + html.push("<img width='256' height='256' src='http://maps.google.com/maps/api/staticmap?center=", location.coords.latitude, ",", location.coords.longitude, "&markers=size:small|color:blue|", location.coords.latitude, ",", location.coords.longitude, "&zoom=14&size=256x256&sensor=false' />"); + html.push("<p>Longitude: ", location.coords.longitude, "</p>"); + html.push("<p>Latitude: ", location.coords.latitude, "</p>"); + html.push("<p>Accuracy: ", location.coords.accuracy, " meters</p>"); + message.innerHTML = html.join(""); +} + +function errorHandler(error) { + alert('Attempt to get location failed: ' + error.message); +} + +<!-- One shot example --> +navigator.geolocation.getCurrentPosition(successHandler, errorHandler); + +</script> +</head> +<body> +<div id="message">Location unknown</div> +</body> +</html> + diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/javascript.html b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/javascript.html new file mode 100644 index 000000000..7a3dc0a1c --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/javascript.html @@ -0,0 +1,8 @@ +<html> +<head><title>Original Title</title></head> +<body> +<script type="text/javascript"> +document.title = "New Title"; +</script> +</body> +</html> diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/localStorage.html b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/localStorage.html new file mode 100644 index 000000000..a4e395f48 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/localStorage.html @@ -0,0 +1,9 @@ +<html> +<head><title>Original Title</title></head> +<body> +<script type="text/javascript"> +document.title = localStorage.getItem('title'); +localStorage.setItem('title', 'New Title'); +</script> +</body> +</html> diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/messaging.html b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/messaging.html new file mode 100644 index 000000000..7e3dd7230 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/messaging.html @@ -0,0 +1,15 @@ +<!doctype html> +<html> +<head> +<script> + function initialize() { + navigator.qt.onmessage = function(ev) { + var reversed = ev.data.split("").reverse().join(""); + navigator.qt.postMessage(reversed); + } + } +</script> +</head> +<body onload="initialize();"> +</body> +</html> diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/prompt.html b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/prompt.html new file mode 100644 index 000000000..f35e30204 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/prompt.html @@ -0,0 +1,13 @@ +<!doctype html> +<html> +<head> +<script> +document.title = prompt("Please, reverse the default value", "Hello Qt"); +if (prompt("REJECT") !== null) { + document.title = "FAIL"; +} +</script> +</head> +<body> +</body> +</html> diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/select.html b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/select.html new file mode 100644 index 000000000..46080f6e4 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/select.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> +<title>No new selection was made</title> +<script> +function updateTitle(selectElement) { + var index = selectElement.selectedIndex; + document.title = selectElement.options[index].value; +} +</script> +</head> +<body> +<select onchange="updateTitle(this)"> +<option value="__open__" >Open</option> +<option value="__closed__" >Closed</option> +<option value="__all__" >All</option> +</select> +</html> diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/small-favicon.png b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/small-favicon.png Binary files differnew file mode 100644 index 000000000..4462752a5 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/small-favicon.png diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/test1.html b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/test1.html new file mode 100644 index 000000000..5c09f06ed --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/test1.html @@ -0,0 +1,6 @@ +<html> +<head><title>Test page 1</title></head> +<body> +Hello. +</body> +</html> diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/test2.html b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/test2.html new file mode 100644 index 000000000..629c2a063 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/test2.html @@ -0,0 +1,6 @@ +<html> +<head><title>Test page with huge link area</title></head> +<body> +<a title="A title" href="test1.html"><img width=200 height=200></a> +</body> +</html> diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/test3.html b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/test3.html new file mode 100644 index 000000000..0c0e4eebf --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/test3.html @@ -0,0 +1,18 @@ +<html> +<head> +<title>Test page 3</title> +</head> +<script type="text/javascript"> +function kickOffTitleChange() +{ + var t = setTimeout("changeTitle('New Title')",3000); +} +function changeTitle(title) +{ + document.title = title; +} +</script> +<body onload="kickOffTitleChange()"> +Hello. +</body> +</html> diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/qmltests.pro b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/qmltests.pro new file mode 100644 index 000000000..7e449a224 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/qmltests.pro @@ -0,0 +1,31 @@ +include(../tests.pri) + +CONFIG += qtwebkit-private +CONFIG += warn_on testcase + +QT -= testlib +QT += qmltest + +# QML files tested are the ones in WebKit source repository. +DEFINES += QUICK_TEST_SOURCE_DIR=\"\\\"$$PWD\\\"\" +DEFINES += IMPORT_DIR=\"\\\"$${ROOT_BUILD_DIR}$${QMAKE_DIR_SEP}imports\\\"\" + +OTHER_FILES += \ + DesktopBehavior/DesktopWebView.qml \ + DesktopBehavior/tst_linkHovered.qml \ + DesktopBehavior/tst_loadHtml.qml \ + DesktopBehavior/tst_messaging.qml \ + DesktopBehavior/tst_navigationRequested.qml \ + WebView/tst_favIconLoad.qml \ + WebView/tst_download.qml \ + WebView/tst_geopermission.qml \ + WebView/tst_itemSelector.qml \ + WebView/tst_javaScriptDialogs.qml \ + WebView/tst_loadFail.qml \ + WebView/tst_loadHtml.qml \ + WebView/tst_loadProgress.qml \ + WebView/tst_loadProgressSignal.qml \ + WebView/tst_preferences.qml \ + WebView/tst_properties.qml \ + WebView/tst_titleChanged.qml \ + WebView/tst_applicationScheme.qml diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/tst_qmltests.cpp b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/tst_qmltests.cpp new file mode 100644 index 000000000..e8d9aab0e --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/tst_qmltests.cpp @@ -0,0 +1,45 @@ +/* + Copyright (C) 2011 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 "../util.h" + +#include <QVarLengthArray> +#include <QtQuickTest/quicktest.h> +#include <QtWidgets/QApplication> + +int main(int argc, char** argv) +{ + QVarLengthArray<char*, 8> arguments; + for (int i = 0; i < argc; ++i) + arguments.append(argv[i]); + + arguments.append(const_cast<char*>("-import")); + arguments.append(const_cast<char*>(IMPORT_DIR)); + + argc = arguments.count(); + argv = arguments.data(); + + suppressDebugOutput(); + addQtWebProcessToPath(); + + // Instantiate QApplication to prevent quick_test_main to instantiate a QGuiApplication. + // This can be removed as soon as we do not use QtWidgets any more. + QApplication app(argc, argv); + return quick_test_main(argc, argv, "qmltests", 0, QUICK_TEST_SOURCE_DIR); +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/qquickwebview.pro b/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/qquickwebview.pro new file mode 100644 index 000000000..728521f8a --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/qquickwebview.pro @@ -0,0 +1,2 @@ +include(../tests.pri) +CONFIG += qtwebkit-private diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp b/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp new file mode 100644 index 000000000..57b7ec14a --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp @@ -0,0 +1,290 @@ +/* + Copyright (C) 2011 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 "../testwindow.h" +#include "../util.h" + +#include <QScopedPointer> +#include <QtTest/QtTest> +#include <qquickwebpage_p.h> +#include <qquickwebview_p.h> + +class tst_QQuickWebView : public QObject { + Q_OBJECT +public: + tst_QQuickWebView(); + +private slots: + void init(); + void cleanup(); + + void accessPage(); + void navigationStatusAtStartup(); + void stopEnabledAfterLoadStarted(); + void baseUrl(); + void loadEmptyUrl(); + void loadEmptyPageViewVisible(); + void loadEmptyPageViewHidden(); + void loadNonexistentFileUrl(); + void backAndForward(); + void reload(); + void stop(); + void loadProgress(); + void scrollRequest(); + + void show(); + void showWebView(); + void removeFromCanvas(); + +private: + inline QQuickWebView* webView() const; + QScopedPointer<TestWindow> m_window; +}; + +tst_QQuickWebView::tst_QQuickWebView() +{ + addQtWebProcessToPath(); + qRegisterMetaType<QQuickWebPage*>("QQuickWebPage*"); +} + +void tst_QQuickWebView::init() +{ + m_window.reset(new TestWindow(new QQuickWebView())); +} + +void tst_QQuickWebView::cleanup() +{ + m_window.reset(); +} + +inline QQuickWebView* tst_QQuickWebView::webView() const +{ + return static_cast<QQuickWebView*>(m_window->webView.data()); +} + +void tst_QQuickWebView::accessPage() +{ + QQuickWebPage* const pageDirectAccess = webView()->page(); + + QVariant pagePropertyValue = webView()->experimental()->property("page"); + QQuickWebPage* const pagePropertyAccess = pagePropertyValue.value<QQuickWebPage*>(); + QCOMPARE(pagePropertyAccess, pageDirectAccess); +} + +void tst_QQuickWebView::navigationStatusAtStartup() +{ + QCOMPARE(webView()->canGoBack(), false); + + QCOMPARE(webView()->canGoForward(), false); + + QCOMPARE(webView()->loading(), false); + + QCOMPARE(webView()->canReload(), false); +} + +class LoadStartedCatcher : public QObject { + Q_OBJECT +public: + LoadStartedCatcher(QQuickWebView* webView) + : m_webView(webView) + { + connect(m_webView, SIGNAL(loadStarted()), this, SLOT(onLoadStarted())); + } + +public slots: + void onLoadStarted() + { + QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); + + QCOMPARE(m_webView->loading(), true); + } + +signals: + void finished(); + +private: + QQuickWebView* m_webView; +}; + +void tst_QQuickWebView::stopEnabledAfterLoadStarted() +{ + QCOMPARE(webView()->loading(), false); + + LoadStartedCatcher catcher(webView()); + webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + waitForSignal(&catcher, SIGNAL(finished())); + + QCOMPARE(webView()->loading(), true); + + waitForSignal(webView(), SIGNAL(loadSucceeded())); +} + +void tst_QQuickWebView::baseUrl() +{ + // Test the url is in a well defined state when instanciating the view, but before loading anything. + QVERIFY(webView()->url().isEmpty()); +} + +void tst_QQuickWebView::loadEmptyUrl() +{ + webView()->load(QUrl()); + webView()->load(QUrl(QLatin1String(""))); +} + +void tst_QQuickWebView::loadEmptyPageViewVisible() +{ + m_window->show(); + loadEmptyPageViewHidden(); +} + +void tst_QQuickWebView::loadEmptyPageViewHidden() +{ + QSignalSpy loadStartedSpy(webView(), SIGNAL(loadStarted())); + + webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + + QCOMPARE(loadStartedSpy.size(), 1); +} + +void tst_QQuickWebView::loadNonexistentFileUrl() +{ + QSignalSpy loadFailedSpy(webView(), SIGNAL(loadStarted())); + + webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/file_that_does_not_exist.html"))); + QVERIFY(waitForSignal(webView(), SIGNAL(loadFailed(QQuickWebView::ErrorDomain, int, QUrl, QString)))); + + QCOMPARE(loadFailedSpy.size(), 1); +} + +void tst_QQuickWebView::backAndForward() +{ + webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + + QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")); + + webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page2.html"))); + QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + + QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page2.html")); + + webView()->goBack(); + QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + + QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")); + + webView()->goForward(); + QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + + QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page2.html")); +} + +void tst_QQuickWebView::reload() +{ + webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + + QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")); + + webView()->reload(); + QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + + QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")); +} + +void tst_QQuickWebView::stop() +{ + webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + + QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")); + + // FIXME: This test should be fleshed out. Right now it's just here to make sure we don't crash. + webView()->stop(); +} + +void tst_QQuickWebView::loadProgress() +{ + QCOMPARE(webView()->loadProgress(), 0); + + webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QSignalSpy loadProgressChangedSpy(webView(), SIGNAL(loadProgressChanged(int))); + QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + + QVERIFY(loadProgressChangedSpy.count() >= 1); + + QCOMPARE(webView()->loadProgress(), 100); +} + +void tst_QQuickWebView::show() +{ + // This should not crash. + m_window->show(); + QTest::qWait(200); + m_window->hide(); +} + +void tst_QQuickWebView::showWebView() +{ + webView()->setSize(QSizeF(300, 400)); + + webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/direct-image-compositing.html"))); + QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + + m_window->show(); + // This should not crash. + webView()->setVisible(true); + QTest::qWait(200); + webView()->setVisible(false); + QTest::qWait(200); +} + +void tst_QQuickWebView::removeFromCanvas() +{ + showWebView(); + + // This should not crash. + QQuickItem* parent = webView()->parentItem(); + QQuickItem noCanvasItem; + webView()->setParentItem(&noCanvasItem); + QTest::qWait(200); + webView()->setParentItem(parent); + webView()->setVisible(true); + QTest::qWait(200); +} + +void tst_QQuickWebView::scrollRequest() +{ + webView()->setSize(QSizeF(300, 400)); + + webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/scroll.html"))); + QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + + // COMPARE with the position requested in the html + // Use qRound as that is also used when calculating the position + // in WebKit. + int y = -qRound(50 * webView()->page()->scale()); + QVERIFY(webView()->page()->pos().y() == y); +} + +QTWEBKIT_API_TEST_MAIN(tst_QQuickWebView) + +#include "tst_qquickwebview.moc" + diff --git a/Source/WebKit2/UIProcess/API/qt/tests/tests.pri b/Source/WebKit2/UIProcess/API/qt/tests/tests.pri new file mode 100644 index 000000000..297bcec92 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/tests.pri @@ -0,0 +1,15 @@ +TEMPLATE = app + +VPATH += $$_PRO_FILE_PWD_ +TARGET = tst_$$TARGET + +SOURCES += $${TARGET}.cpp \ + ../util.cpp +INCLUDEPATH += $$PWD + +QT += testlib declarative widgets + +CONFIG += qtwebkit + +DEFINES += TESTS_SOURCE_DIR=\\\"$$PWD\\\" \ + QWP_PATH=\\\"$${ROOT_BUILD_DIR}/bin\\\" diff --git a/Source/WebKit2/UIProcess/API/qt/tests/testwindow.h b/Source/WebKit2/UIProcess/API/qt/tests/testwindow.h new file mode 100644 index 000000000..1eaa43772 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/testwindow.h @@ -0,0 +1,54 @@ +/* + Copyright (C) 2011 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 testwindow_h +#define testwindow_h + +#include <QResizeEvent> +#include <QScopedPointer> +#include <QtQuick/qquickitem.h> +#include <QtQuick/qquickview.h> + +// TestWindow: Utility class to ignore QQuickView details. +class TestWindow : public QQuickView { +public: + inline TestWindow(QQuickItem* webView); + QScopedPointer<QQuickItem> webView; + +protected: + inline void resizeEvent(QResizeEvent*); +}; + +inline TestWindow::TestWindow(QQuickItem* webView) + : webView(webView) +{ + Q_ASSERT(webView); + webView->setParentItem(rootItem()); +} + +inline void TestWindow::resizeEvent(QResizeEvent* event) +{ + QQuickView::resizeEvent(event); + webView->setX(0); + webView->setY(0); + webView->setWidth(event->size().width()); + webView->setHeight(event->size().height()); +} + +#endif /* testwindow_h */ diff --git a/Source/WebKit2/UIProcess/API/qt/tests/util.cpp b/Source/WebKit2/UIProcess/API/qt/tests/util.cpp new file mode 100644 index 000000000..e230221e6 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/util.cpp @@ -0,0 +1,67 @@ +/* + Copyright (C) 2011 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 "util.h" +#include <stdio.h> + +void addQtWebProcessToPath() +{ + // Since tests won't find ./QtWebProcess, add it to PATH (at the end to prevent surprises). + // QWP_PATH should be defined by qmake. + qputenv("PATH", qgetenv("PATH") + ":" + QWP_PATH); +} + +/** + * 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 + */ +bool waitForSignal(QObject* obj, const char* signal, int timeout) +{ + 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(); +} + +static void messageHandler(QtMsgType type, const char* message) +{ + if (type == QtCriticalMsg) { + fprintf(stderr, "%s\n", message); + return; + } + // Do nothing +} + +void suppressDebugOutput() +{ + qInstallMsgHandler(messageHandler); \ + if (qgetenv("QT_WEBKIT_SUPPRESS_WEB_PROCESS_OUTPUT").isEmpty()) \ + qputenv("QT_WEBKIT_SUPPRESS_WEB_PROCESS_OUTPUT", "1"); +} diff --git a/Source/WebKit2/UIProcess/API/qt/tests/util.h b/Source/WebKit2/UIProcess/API/qt/tests/util.h new file mode 100644 index 000000000..007964fe5 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/util.h @@ -0,0 +1,41 @@ +/* + Copyright (C) 2011 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> + +#if !defined(TESTS_SOURCE_DIR) +#define TESTS_SOURCE_DIR "" +#endif + +void addQtWebProcessToPath(); +bool waitForSignal(QObject*, const char* signal, int timeout = 10000); +void suppressDebugOutput(); + +#define QTWEBKIT_API_TEST_MAIN(TestObject) \ +int main(int argc, char** argv) \ +{ \ + suppressDebugOutput(); \ + QApplication app(argc, argv); \ + QTEST_DISABLE_KEYPAD_NAVIGATION \ + TestObject tc; \ + return QTest::qExec(&tc, argc, argv); \ +} |