summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/qml/README3
-rw-r--r--examples/qml/example.qml117
-rw-r--r--examples/qml/index.html59
-rw-r--r--examples/standalone/main.cpp60
-rw-r--r--examples/standalone/standalone.pro2
-rw-r--r--src/imports/webchannel/plugin.cpp9
-rw-r--r--src/imports/webchannel/plugins.qmltypes96
-rw-r--r--src/imports/webchannel/qmlwebchannel.cpp45
-rw-r--r--src/imports/webchannel/qmlwebchannel.h16
-rw-r--r--src/imports/webchannel/qmlwebviewtransport.cpp103
-rw-r--r--src/imports/webchannel/webchannel.pro6
-rw-r--r--src/webchannel/qmetaobjectpublisher.cpp10
-rw-r--r--src/webchannel/qmetaobjectpublisher_p.h15
-rw-r--r--src/webchannel/qwebchannel.cpp32
-rw-r--r--src/webchannel/qwebchannel.h8
-rw-r--r--src/webchannel/qwebchannel.js30
-rw-r--r--src/webchannel/qwebchannel_p.h7
-rw-r--r--src/webchannel/qwebchannelabstracttransport.cpp (renamed from tests/auto/qml/data/testsetup.js)19
-rw-r--r--src/webchannel/qwebchannelabstracttransport.h (renamed from src/webchannel/qwebsockettransport_p.h)51
-rw-r--r--src/webchannel/qwebchanneltransportinterface.h94
-rw-r--r--src/webchannel/qwebchannelwebsockettransport.cpp (renamed from tests/auto/qml/TestWebView.qml)62
-rw-r--r--src/webchannel/qwebchannelwebsockettransport.h68
-rw-r--r--src/webchannel/qwebsockettransport.cpp212
-rw-r--r--src/webchannel/qwebsockettransport.h81
-rw-r--r--src/webchannel/webchannel.pro8
-rw-r--r--sync.profile3
-rw-r--r--tests/auto/qml/Client.qml (renamed from tests/auto/qml/WebChannelTest.qml)133
-rw-r--r--tests/auto/qml/data/bench_init.html13
-rw-r--r--tests/auto/qml/data/disconnect.html21
-rw-r--r--tests/auto/qml/data/grouping.html17
-rw-r--r--tests/auto/qml/data/method.html17
-rw-r--r--tests/auto/qml/data/multiclient.html19
-rw-r--r--tests/auto/qml/data/property.html21
-rw-r--r--tests/auto/qml/data/receiveRaw.html15
-rw-r--r--tests/auto/qml/data/send.html17
-rw-r--r--tests/auto/qml/data/signal.html17
-rw-r--r--tests/auto/qml/data/wrapper.html28
-rw-r--r--tests/auto/qml/qml.cpp14
-rw-r--r--tests/auto/qml/qml.pro6
-rw-r--r--tests/auto/qml/testtransport.cpp57
-rw-r--r--tests/auto/qml/testtransport.h (renamed from src/imports/webchannel/qmlwebviewtransport.h)32
-rw-r--r--tests/auto/qml/tst_bench.qml38
-rw-r--r--tests/auto/qml/tst_metaobjectpublisher.qml177
-rw-r--r--tests/auto/qml/tst_multiclient.qml56
-rw-r--r--tests/auto/qml/tst_webchannel.qml37
-rw-r--r--tests/auto/webchannel/tst_webchannel.cpp15
-rw-r--r--tests/auto/webchannel/tst_webchannel.h19
47 files changed, 662 insertions, 1323 deletions
diff --git a/examples/qml/README b/examples/qml/README
deleted file mode 100644
index cf0e041..0000000
--- a/examples/qml/README
+++ /dev/null
@@ -1,3 +0,0 @@
-To run this example, install QtWebKit, QtWebChannel and QtQuickControls modules, then run:
-
-qmlscene ./example.qml
diff --git a/examples/qml/example.qml b/examples/qml/example.qml
deleted file mode 100644
index 2d51f27..0000000
--- a/examples/qml/example.qml
+++ /dev/null
@@ -1,117 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtWebChannel module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.1
-
-import QtWebChannel 1.0
-
-import QtQuick.Controls 1.0
-import QtQuick.Layouts 1.0
-
-import QtWebKit 3.0
-import QtWebKit.experimental 1.0
-
-ApplicationWindow {
- id: window
- title: "QtWebChannel Example: QML Server to QtWebKit WebView Client"
- width: 600
- height: 400
-
- WebChannel {
- id: webChannel
-
- connections: WebViewTransport {
- webViewExperimental: webView.experimental
- onMessageReceived: {
- textEdit.text += "Received message: " + message + "\n";
- }
- }
- }
-
- RowLayout {
- id: myRow
- anchors.fill: parent
- ColumnLayout {
- id: myCol
- Label {
- id: caption
- text: "QML Server"
- font.bold: true
- }
- TextArea {
- Layout.fillHeight: true
- Layout.fillWidth: true
- id: textEdit
- readOnly: true
- }
- RowLayout {
- Label {
- id: label
- text: "Input: "
- }
- TextField {
- id: input
- Layout.fillWidth: true
- }
- Button {
- id: send
- text: "Send"
- onClicked: {
- if (input.text) {
- webChannel.sendMessage("message", input.text);
- textEdit.text += "Sent message: " + input.text + "\n";
- input.text = ""
- }
- }
- }
- }
- }
- WebView {
- Layout.fillWidth: true
- Layout.fillHeight: true
- Layout.minimumWidth: window.width / 2
- id: webView
- url: "index.html"
- experimental.preferences.developerExtrasEnabled: true
- experimental.preferences.navigatorQtObjectEnabled: true
- }
- }
-}
diff --git a/examples/qml/index.html b/examples/qml/index.html
deleted file mode 100644
index 8b65dd2..0000000
--- a/examples/qml/index.html
+++ /dev/null
@@ -1,59 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <script type="text/javascript" src="qrc:///qwebchannel/qwebchannel.js"></script>
- <script type="text/javascript">
- //BEGIN SETUP
- new QWebChannel(navigator.qt, function(channel) {
- document.getElementById("send").onclick = function() {
- var input = document.getElementById("input");
- var text = input.value;
- if (!text) {
- return;
- }
- var output = document.getElementById("output");
- output.innerHTML = output.innerHTML + "Sent message: " + text + "\n";
- input.value = "";
- channel.send(text);
- }
-
- channel.subscribe("message", function(text) {
- var output = document.getElementById("output");
- output.innerHTML = output.innerHTML + "Received message: " + text + "\n";
- });
- }, true /* raw web channel */);
- //END SETUP
- </script>
- <style type="text/css">
- * {
- padding: 0;
- margin: 0;
- font-size: 40px;
- }
- html, body {
- height: 100%;
- width: 100%;
- }
- #div {
- height: 100%;
- padding: 0 10%;
- }
- #input {
- width: 50%;
- margin: 0 10px;
- }
- #output {
- width: 100%;
- height: 80%;
- }
- </style>
- </head>
- <body>
- <div id="div">
- <h1>HTML Client</h1>
- <textarea id="output" readonly></textarea><br />
- Input: <input id="input" /><input type="submit" id="send" value="Send" onclick="javascript:click();" />
- </div>
- </body>
-</html>
diff --git a/examples/standalone/main.cpp b/examples/standalone/main.cpp
index 47f7ea2..05deb24 100644
--- a/examples/standalone/main.cpp
+++ b/examples/standalone/main.cpp
@@ -40,7 +40,6 @@
****************************************************************************/
#include "qwebchannel.h"
-#include "qwebsockettransport.h"
#include <QApplication>
#include <QDialog>
@@ -49,6 +48,10 @@
#include <QUrl>
#include <QDebug>
+#include <QtWebSockets/QWebSocketServer>
+#include <QtWebSockets/QWebSocket>
+#include <QtWebChannel/QWebChannelWebSocketTransport>
+
#include "ui_dialog.h"
class Dialog : public QObject
@@ -56,15 +59,18 @@ class Dialog : public QObject
Q_OBJECT
public:
- explicit Dialog(QWebSocketTransport *transport, QObject *parent = 0)
+ explicit Dialog(const QString &baseUrl, QObject *parent = 0)
: QObject(parent)
{
ui.setupUi(&dialog);
dialog.show();
connect(ui.send, SIGNAL(clicked()), SLOT(clicked()));
- connect(transport, SIGNAL(baseUrlChanged(QString)),
- SLOT(baseUrlChanged(QString)));
+
+ QUrl url = QUrl::fromLocalFile(SOURCE_DIR "/index.html");
+ url.setQuery(QStringLiteral("webChannelBaseUrl=") + baseUrl);
+ ui.output->appendPlainText(tr("Initialization complete, opening browser at %1.").arg(url.toDisplayString()));
+ QDesktopServices::openUrl(url);
}
signals:
@@ -91,29 +97,55 @@ private slots:
ui.input->clear();
}
- void baseUrlChanged(const QString &baseUrl)
+private:
+ QDialog dialog;
+ Ui::Dialog ui;
+};
+
+// boiler plate code to connect incoming WebSockets to the WebChannel, such that they receive
+// messages and can access the published objects.
+class TransportHandler : public QObject
+{
+ Q_OBJECT
+
+public:
+ TransportHandler(QWebChannel *channel, QObject *parent = 0)
+ : QObject(parent)
+ , m_server(QStringLiteral("QWebChannel Standalone Example Server"), QWebSocketServer::NonSecureMode)
+ , m_channel(channel)
+ {
+ if (!m_server.listen(QHostAddress::LocalHost)) {
+ qFatal("Failed to open web socket server.");
+ }
+
+ connect(&m_server, &QWebSocketServer::newConnection,
+ this, &TransportHandler::handleNewConnection);
+ }
+
+ QString baseUrl() const
{
- ui.output->appendPlainText(tr("Initialization complete, opening browser."));
+ return m_server.serverUrl().toString();
+ }
- QUrl url = QUrl::fromLocalFile(SOURCE_DIR "/index.html");
- url.setQuery(QStringLiteral("webChannelBaseUrl=") + baseUrl);
- QDesktopServices::openUrl(url);
+private slots:
+ void handleNewConnection()
+ {
+ m_channel->connectTo(new QWebChannelWebSocketTransport(m_server.nextPendingConnection()));
}
private:
- QDialog dialog;
- Ui::Dialog ui;
+ QWebSocketServer m_server;
+ QWebChannel *m_channel;
};
int main(int argc, char** argv)
{
QApplication app(argc, argv);
- QWebSocketTransport transport;
QWebChannel channel;
- channel.connectTo(&transport);
+ TransportHandler transportHandler(&channel);
- Dialog dialog(&transport);
+ Dialog dialog(transportHandler.baseUrl());
channel.registerObject(QStringLiteral("dialog"), &dialog);
diff --git a/examples/standalone/standalone.pro b/examples/standalone/standalone.pro
index 7ce0f2b..114be58 100644
--- a/examples/standalone/standalone.pro
+++ b/examples/standalone/standalone.pro
@@ -1,4 +1,4 @@
-QT += gui webchannel widgets
+QT += gui webchannel widgets websockets
CONFIG += warn_on
diff --git a/src/imports/webchannel/plugin.cpp b/src/imports/webchannel/plugin.cpp
index 589e3cb..6507112 100644
--- a/src/imports/webchannel/plugin.cpp
+++ b/src/imports/webchannel/plugin.cpp
@@ -43,11 +43,6 @@
#include <QtQml/QQmlExtensionPlugin>
#include "qmlwebchannel.h"
-#include "qwebsockettransport.h"
-#include "qmlwebviewtransport.h"
-#include "qwebchanneltransportinterface.h"
-
-QML_DECLARE_INTERFACE_HASMETATYPE(QWebChannelTransportInterface);
QT_BEGIN_NAMESPACE
@@ -62,13 +57,9 @@ public:
void QWebChannelPlugin::registerTypes(const char *uri)
{
- qmlRegisterInterface<QWebChannelTransportInterface>("QWebChannelTransportInterface");
-
int major = 1;
int minor = 0;
qmlRegisterType<QmlWebChannel>(uri, major, minor, "WebChannel");
- qmlRegisterType<QWebSocketTransport>(uri, major, minor, "WebSocketTransport");
- qmlRegisterType<QmlWebViewTransport>(uri, major, minor, "WebViewTransport");
}
QT_END_NAMESPACE
diff --git a/src/imports/webchannel/plugins.qmltypes b/src/imports/webchannel/plugins.qmltypes
index 6d08f9c..789f2b4 100644
--- a/src/imports/webchannel/plugins.qmltypes
+++ b/src/imports/webchannel/plugins.qmltypes
@@ -4,95 +4,65 @@ import QtQuick.tooling 1.1
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -notrelocatable QtWebChannel 5.3'
+// 'qmlplugindump -notrelocatable QtWebChannel 1.0'
Module {
Component {
- name: "QMetaObjectPublisher"
+ name: "QWebChannel"
prototype: "QObject"
- exports: ["QtWebChannel/MetaObjectPublisher 5.3"]
- exportMetaObjectRevisions: [0]
- Property { name: "webChannel"; type: "QWebChannel"; isPointer: true }
Property { name: "blockUpdates"; type: "bool" }
Signal {
- name: "webChannelChanged"
- Parameter { name: "channel"; type: "QWebChannel"; isPointer: true }
- }
- Signal {
name: "blockUpdatesChanged"
Parameter { name: "block"; type: "bool" }
}
Method {
- name: "classInfoForObjects"
- type: "QVariantMap"
- Parameter { name: "objects"; type: "QVariantMap" }
- }
- Method {
- name: "classInfoForObject"
- type: "QVariantMap"
- Parameter { name: "object"; type: "QObject"; isPointer: true }
+ name: "sendMessage"
+ Parameter { name: "id"; type: "QJsonValue" }
+ Parameter { name: "data"; type: "QJsonValue" }
}
Method {
- name: "registerObjects"
- Parameter { name: "objects"; type: "QVariantMap" }
+ name: "sendMessage"
+ Parameter { name: "id"; type: "QJsonValue" }
}
Method {
- name: "handleRequest"
- type: "bool"
- Parameter { name: "message"; type: "QJsonObject" }
+ name: "registerObject"
+ Parameter { name: "id"; type: "string" }
+ Parameter { name: "object"; type: "QObject"; isPointer: true }
}
- Method { name: "bench_ensureUpdatesInitialized" }
- Method { name: "bench_sendPendingPropertyUpdates" }
Method {
- name: "bench_registerObjects"
- Parameter { name: "objects"; type: "QVariantMap" }
+ name: "deregisterObject"
+ Parameter { name: "object"; type: "QObject"; isPointer: true }
}
- Method { name: "bench_initializeClients" }
- Method { name: "test_clientIsIdle"; type: "bool" }
}
Component {
- name: "QWebChannel"
- prototype: "QObject"
- exports: ["QtWebChannel/WebChannel 5.3"]
+ name: "QmlWebChannel"
+ prototype: "QWebChannel"
+ exports: ["QtWebChannel/WebChannel 1.0"]
exportMetaObjectRevisions: [0]
- Property { name: "baseUrl"; type: "string"; isReadonly: true }
- Property { name: "useSecret"; type: "bool" }
- Signal {
- name: "baseUrlChanged"
- Parameter { name: "baseUrl"; type: "string" }
- }
- Signal {
- name: "rawMessageReceived"
- Parameter { name: "rawMessage"; type: "string" }
- }
- Signal { name: "pongReceived" }
- Signal { name: "initialized" }
- Signal {
- name: "failed"
- Parameter { name: "reason"; type: "string" }
- }
+ attachedType: "QmlWebChannelAttached"
+ Property { name: "transports"; type: "QObject"; isList: true; isReadonly: true }
+ Property { name: "registeredObjects"; type: "QObject"; isList: true; isReadonly: true }
Method {
- name: "sendMessage"
- Parameter { name: "id"; type: "QJsonValue" }
- Parameter { name: "data"; type: "QJsonValue" }
- }
- Method {
- name: "sendMessage"
- Parameter { name: "id"; type: "QJsonValue" }
+ name: "registerObjects"
+ Parameter { name: "objects"; type: "QVariantMap" }
}
+ Method { name: "test_clientIsIdle"; type: "bool" }
Method {
- name: "respond"
- Parameter { name: "messageId"; type: "QJsonValue" }
- Parameter { name: "data"; type: "QJsonValue" }
+ name: "connectTo"
+ Parameter { name: "transport"; type: "QObject"; isPointer: true }
}
Method {
- name: "respond"
- Parameter { name: "messageId"; type: "QJsonValue" }
+ name: "disconnectFrom"
+ Parameter { name: "transport"; type: "QObject"; isPointer: true }
}
- Method {
- name: "sendRawMessage"
- Parameter { name: "rawMessage"; type: "string" }
+ }
+ Component {
+ name: "QmlWebChannelAttached"
+ prototype: "QObject"
+ Property { name: "id"; type: "string" }
+ Signal {
+ name: "idChanged"
+ Parameter { name: "id"; type: "string" }
}
- Method { name: "ping" }
}
}
diff --git a/src/imports/webchannel/qmlwebchannel.cpp b/src/imports/webchannel/qmlwebchannel.cpp
index dc7398d..e61e9c8 100644
--- a/src/imports/webchannel/qmlwebchannel.cpp
+++ b/src/imports/webchannel/qmlwebchannel.cpp
@@ -43,6 +43,7 @@
#include "qwebchannel_p.h"
#include "qmetaobjectpublisher_p.h"
+#include "qwebchannelabstracttransport.h"
#include <QtQml/QQmlContext>
@@ -100,32 +101,19 @@ QmlWebChannelAttached *QmlWebChannel::qmlAttachedProperties(QObject *obj)
void QmlWebChannel::connectTo(QObject *transport)
{
- if (QWebChannelTransportInterface *iface = qobject_cast<QWebChannelTransportInterface*>(transport)) {
- m_connectedObjects.insert(transport, iface);
- QWebChannel::connectTo(iface);
- connect(transport, SIGNAL(destroyed(QObject*)), SLOT(transportDestroyed(QObject*)), Qt::UniqueConnection);
+ if (QWebChannelAbstractTransport *realTransport = qobject_cast<QWebChannelAbstractTransport*>(transport)) {
+ QWebChannel::connectTo(realTransport);
} else {
- qWarning() << "Cannot connect to transport" << transport << " - it does not implement the QWebChannelTransportInterface.";
+ qWarning() << "Cannot connect to transport" << transport << " - it is not a QWebChannelAbstractTransport.";
}
}
void QmlWebChannel::disconnectFrom(QObject *transport)
{
- if (QWebChannelTransportInterface *iface = qobject_cast<QWebChannelTransportInterface*>(transport)) {
- QWebChannel::disconnectFrom(iface);
- disconnect(transport, SIGNAL(destroyed(QObject*)), this, SLOT(transportDestroyed(QObject*)));
- m_connectedObjects.remove(transport);
+ if (QWebChannelAbstractTransport *realTransport = qobject_cast<QWebChannelAbstractTransport*>(transport)) {
+ QWebChannel::disconnectFrom(realTransport);
} else {
- qWarning() << "Cannot disconnect from transport" << transport << " - it does not implement the QWebChannelTransportInterface.";
- }
-}
-
-void QmlWebChannel::transportDestroyed(QObject *transport)
-{
- QWebChannelTransportInterface *iface = m_connectedObjects.take(transport);
- const int idx = d->transports.indexOf(iface);
- if (idx != -1) {
- d->transports.remove(idx);
+ qWarning() << "Cannot disconnect from transport" << transport << " - it is not a QWebChannelAbstractTransport.";
}
}
@@ -175,35 +163,36 @@ void QmlWebChannel::registeredObjects_clear(QQmlListProperty<QObject> *prop)
return channel->m_registeredObjects.clear();
}
-QQmlListProperty<QWebChannelTransportInterface> QmlWebChannel::transports()
+QQmlListProperty<QObject> QmlWebChannel::transports()
{
- return QQmlListProperty<QWebChannelTransportInterface>(this, 0,
+ return QQmlListProperty<QObject>(this, 0,
transports_append,
transports_count,
transports_at,
transports_clear);
}
-void QmlWebChannel::transports_append(QQmlListProperty<QWebChannelTransportInterface> *prop, QWebChannelTransportInterface *transport)
+void QmlWebChannel::transports_append(QQmlListProperty<QObject> *prop, QObject *transport)
{
- QWebChannel *channel = static_cast<QWebChannel*>(prop->object);
+ QmlWebChannel *channel = static_cast<QmlWebChannel*>(prop->object);
channel->connectTo(transport);
}
-int QmlWebChannel::transports_count(QQmlListProperty<QWebChannelTransportInterface> *prop)
+int QmlWebChannel::transports_count(QQmlListProperty<QObject> *prop)
{
return static_cast<QmlWebChannel*>(prop->object)->d->transports.size();
}
-QWebChannelTransportInterface *QmlWebChannel::transports_at(QQmlListProperty<QWebChannelTransportInterface> *prop, int index)
+QObject *QmlWebChannel::transports_at(QQmlListProperty<QObject> *prop, int index)
{
- return static_cast<QmlWebChannel*>(prop->object)->d->transports.at(index);
+ QmlWebChannel *channel = static_cast<QmlWebChannel*>(prop->object);
+ return dynamic_cast<QObject*>(channel->d->transports.at(index));
}
-void QmlWebChannel::transports_clear(QQmlListProperty<QWebChannelTransportInterface> *prop)
+void QmlWebChannel::transports_clear(QQmlListProperty<QObject> *prop)
{
QWebChannel *channel = static_cast<QWebChannel*>(prop->object);
- foreach (QWebChannelTransportInterface *transport, channel->d->transports) {
+ foreach (QWebChannelAbstractTransport *transport, channel->d->transports) {
channel->disconnectFrom(transport);
}
Q_ASSERT(channel->d->transports.isEmpty());
diff --git a/src/imports/webchannel/qmlwebchannel.h b/src/imports/webchannel/qmlwebchannel.h
index 3610307..6bc7127 100644
--- a/src/imports/webchannel/qmlwebchannel.h
+++ b/src/imports/webchannel/qmlwebchannel.h
@@ -45,7 +45,6 @@
#include <qwebchannel.h>
#include "qmlwebchannelattached.h"
-#include "qwebchanneltransportinterface.h"
#include <QVector>
@@ -58,7 +57,7 @@ class QmlWebChannel : public QWebChannel
{
Q_OBJECT
- Q_PROPERTY( QQmlListProperty<QWebChannelTransportInterface> connections READ transports );
+ Q_PROPERTY( QQmlListProperty<QObject> transports READ transports );
Q_PROPERTY( QQmlListProperty<QObject> registeredObjects READ registeredObjects )
public:
@@ -68,7 +67,7 @@ public:
Q_INVOKABLE void registerObjects(const QVariantMap &objects);
QQmlListProperty<QObject> registeredObjects();
- QQmlListProperty<QWebChannelTransportInterface> transports();
+ QQmlListProperty<QObject> transports();
// TODO: remove this by replacing QML with C++ tests
Q_INVOKABLE bool test_clientIsIdle() const;
@@ -80,7 +79,6 @@ public:
private Q_SLOTS:
void objectIdChanged(const QString &newId);
- void transportDestroyed(QObject *transport);
private:
static void registeredObjects_append(QQmlListProperty<QObject> *prop, QObject *item);
@@ -88,14 +86,12 @@ private:
static QObject *registeredObjects_at(QQmlListProperty<QObject> *prop, int index);
static void registeredObjects_clear(QQmlListProperty<QObject> *prop);
- static void transports_append(QQmlListProperty<QWebChannelTransportInterface> *prop, QWebChannelTransportInterface *item);
- static int transports_count(QQmlListProperty<QWebChannelTransportInterface> *prop);
- static QWebChannelTransportInterface *transports_at(QQmlListProperty<QWebChannelTransportInterface> *prop, int index);
- static void transports_clear(QQmlListProperty<QWebChannelTransportInterface> *prop);
+ static void transports_append(QQmlListProperty<QObject> *prop, QObject *item);
+ static int transports_count(QQmlListProperty<QObject> *prop);
+ static QObject *transports_at(QQmlListProperty<QObject> *prop, int index);
+ static void transports_clear(QQmlListProperty<QObject> *prop);
QVector<QObject*> m_registeredObjects;
- // required as when the object is destroyed, we must still find the address of the base class somehow
- QHash<QObject*, QWebChannelTransportInterface*> m_connectedObjects;
};
QML_DECLARE_TYPE( QmlWebChannel )
diff --git a/src/imports/webchannel/qmlwebviewtransport.cpp b/src/imports/webchannel/qmlwebviewtransport.cpp
deleted file mode 100644
index 3d4e2ed..0000000
--- a/src/imports/webchannel/qmlwebviewtransport.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtWebChannel module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmlwebviewtransport.h"
-
-#include <QVariantMap>
-
-QT_USE_NAMESPACE
-
-QmlWebViewTransport::QmlWebViewTransport(QObject *parent)
- : QObject(parent)
- , m_webViewExperimental(Q_NULLPTR)
- , m_handler(Q_NULLPTR)
-{
-}
-
-QmlWebViewTransport::~QmlWebViewTransport()
-{
-
-}
-
-void QmlWebViewTransport::setWebViewExperimental(QObject *webViewExperimental)
-{
- if (webViewExperimental != m_webViewExperimental) {
- if (m_webViewExperimental) {
- disconnect(m_webViewExperimental, 0, this, 0);
- }
- m_webViewExperimental = webViewExperimental;
- connect(m_webViewExperimental, SIGNAL(messageReceived(QVariantMap)), this, SLOT(handleWebViewMessage(QVariantMap)));
- emit webViewChanged(webViewExperimental);
- }
-}
-
-QObject *QmlWebViewTransport::webViewExperimental() const
-{
- return m_webViewExperimental;
-}
-
-void QmlWebViewTransport::sendMessage(const QString &message, int /*clientId*/) const
-{
- if (!m_webViewExperimental) {
- qWarning("Cannot send message - did you forget to set the webViewExperimental property?");
- return;
- }
- QMetaObject::invokeMethod(m_webViewExperimental, "postMessage", Q_ARG(QString, message));
-}
-
-void QmlWebViewTransport::sendMessage(const QByteArray &message, int clientId) const
-{
- sendMessage(QString::fromUtf8(message), clientId);
-}
-
-void QmlWebViewTransport::handleWebViewMessage(const QVariantMap &message)
-{
- if (m_handler) {
- const QString &data = message[QStringLiteral("data")].toString();
- m_handler->handleMessage(data, this, -1);
- emit messageReceived(data);
- }
-}
-
-void QmlWebViewTransport::setMessageHandler(QWebChannelMessageHandlerInterface *handler)
-{
- m_handler = handler;
-}
diff --git a/src/imports/webchannel/webchannel.pro b/src/imports/webchannel/webchannel.pro
index 3042854..c1959f5 100644
--- a/src/imports/webchannel/webchannel.pro
+++ b/src/imports/webchannel/webchannel.pro
@@ -6,12 +6,10 @@ VPATH += ../../webchannel
SOURCES += \
plugin.cpp \
qmlwebchannel.cpp \
- qmlwebchannelattached.cpp \
- qmlwebviewtransport.cpp
+ qmlwebchannelattached.cpp
HEADERS += \
qmlwebchannel.h \
- qmlwebchannelattached.h \
- qmlwebviewtransport.h
+ qmlwebchannelattached.h
load(qml_plugin)
diff --git a/src/webchannel/qmetaobjectpublisher.cpp b/src/webchannel/qmetaobjectpublisher.cpp
index 2914714..096bf7b 100644
--- a/src/webchannel/qmetaobjectpublisher.cpp
+++ b/src/webchannel/qmetaobjectpublisher.cpp
@@ -42,6 +42,7 @@
#include "qmetaobjectpublisher_p.h"
#include "qwebchannel.h"
#include "qwebchannel_p.h"
+#include "qwebchannelabstracttransport.h"
#include <QEvent>
#include <QJsonDocument>
@@ -394,7 +395,7 @@ QByteArray QMetaObjectPublisher::invokeMethod(QObject *const object, const int m
void QMetaObjectPublisher::signalEmitted(const QObject *object, const int signalIndex, const QVariantList &arguments)
{
- if (!webChannel) {
+ if (!webChannel || webChannel->d->transports.isEmpty()) {
return;
}
if (!signalToPropertyMap.value(object).contains(signalIndex)) {
@@ -544,15 +545,18 @@ QByteArray QMetaObjectPublisher::handleRequest(const QJsonObject &message)
return QByteArray();
}
-void QMetaObjectPublisher::handleMessage(const QString &message, QWebChannelTransportInterface *transport, int clientId)
+void QMetaObjectPublisher::handleMessage(const QString &message)
{
+ QWebChannelAbstractTransport *transport = qobject_cast<QWebChannelAbstractTransport*>(sender());
+ Q_ASSERT(transport);
+
const QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8());
if (!doc.isObject()) {
return;
}
const QByteArray &response = handleRequest(doc.object());
if (!response.isEmpty()) {
- transport->sendMessage(response, clientId);
+ transport->sendTextMessage(QString::fromUtf8(response));
}
}
diff --git a/src/webchannel/qmetaobjectpublisher_p.h b/src/webchannel/qmetaobjectpublisher_p.h
index 49b3ed0..dda18ae 100644
--- a/src/webchannel/qmetaobjectpublisher_p.h
+++ b/src/webchannel/qmetaobjectpublisher_p.h
@@ -51,16 +51,14 @@
#include <QPointer>
#include "qwebchannelglobal.h"
-#include "qwebchanneltransportinterface.h"
QT_BEGIN_NAMESPACE
class QWebChannel;
-
-class Q_WEBCHANNEL_EXPORT QMetaObjectPublisher : public QObject, public QWebChannelMessageHandlerInterface
+class Q_WEBCHANNEL_EXPORT QMetaObjectPublisher : public QObject
{
Q_OBJECT
- Q_INTERFACES(QWebChannelMessageHandlerInterface)
+
public:
explicit QMetaObjectPublisher(QWebChannel *webChannel);
virtual ~QMetaObjectPublisher();
@@ -161,13 +159,14 @@ public:
*/
void setBlockUpdates(bool block);
+Q_SIGNALS:
+ void blockUpdatesChanged(bool block);
+
+public Q_SLOTS:
/**
* Parse the message as JSON and if it succeeds, call handleRequest with the obtained JSON object.
*/
- void handleMessage(const QString &message, QWebChannelTransportInterface* transport, int clientId) Q_DECL_OVERRIDE;
-
-Q_SIGNALS:
- void blockUpdatesChanged(bool block);
+ void handleMessage(const QString &message);
protected:
void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE;
diff --git a/src/webchannel/qwebchannel.cpp b/src/webchannel/qwebchannel.cpp
index 75d1a4b..e4cf0d6 100644
--- a/src/webchannel/qwebchannel.cpp
+++ b/src/webchannel/qwebchannel.cpp
@@ -43,7 +43,7 @@
#include "qwebchannel.h"
#include "qwebchannel_p.h"
#include "qmetaobjectpublisher_p.h"
-#include "qwebchanneltransportinterface.h"
+#include "qwebchannelabstracttransport.h"
#include <QJsonDocument>
#include <QJsonObject>
@@ -64,6 +64,14 @@ QByteArray generateJSONMessage(const QJsonValue &id, const QJsonValue &data, boo
return doc.toJson(QJsonDocument::Compact);
}
+void QWebChannelPrivate::_q_transportDestroyed(QObject *object)
+{
+ const int idx = transports.indexOf(static_cast<QWebChannelAbstractTransport*>(object));
+ if (idx != -1) {
+ transports.remove(idx);
+ }
+}
+
QWebChannel::QWebChannel(QObject *parent)
: QObject(parent)
, d(new QWebChannelPrivate)
@@ -75,9 +83,6 @@ QWebChannel::QWebChannel(QObject *parent)
QWebChannel::~QWebChannel()
{
- foreach (QWebChannelTransportInterface *transport, d->transports) {
- transport->setMessageHandler(Q_NULLPTR);
- }
}
void QWebChannel::registerObjects(const QHash< QString, QObject * > &objects)
@@ -109,20 +114,24 @@ void QWebChannel::setBlockUpdates(bool block)
d->publisher->setBlockUpdates(block);
}
-void QWebChannel::connectTo(QWebChannelTransportInterface *transport)
+void QWebChannel::connectTo(QWebChannelAbstractTransport *transport)
{
Q_ASSERT(transport);
if (!d->transports.contains(transport)) {
d->transports << transport;
- transport->setMessageHandler(d->publisher);
+ connect(transport, &QWebChannelAbstractTransport::textMessageReceived,
+ d->publisher, &QMetaObjectPublisher::handleMessage,
+ Qt::UniqueConnection);
+ connect(transport, SIGNAL(destroyed(QObject*)),
+ this, SLOT(_q_transportDestroyed(QObject*)));
}
}
-void QWebChannel::disconnectFrom(QWebChannelTransportInterface *transport)
+void QWebChannel::disconnectFrom(QWebChannelAbstractTransport *transport)
{
const int idx = d->transports.indexOf(transport);
if (idx != -1) {
- transport->setMessageHandler(Q_NULLPTR);
+ disconnect(transport, 0, this, 0);
d->transports.remove(idx);
}
}
@@ -135,9 +144,12 @@ void QWebChannel::sendMessage(const QJsonValue &id, const QJsonValue &data) cons
}
const QByteArray &message = generateJSONMessage(id, data, false);
- foreach (QWebChannelTransportInterface *transport, d->transports) {
- transport->sendMessage(message);
+ const QString &messageText = QString::fromUtf8(message);
+ foreach (QWebChannelAbstractTransport *transport, d->transports) {
+ transport->sendTextMessage(messageText);
}
}
QT_END_NAMESPACE
+
+#include "moc_qwebchannel.cpp"
diff --git a/src/webchannel/qwebchannel.h b/src/webchannel/qwebchannel.h
index 76e77b8..5016b52 100644
--- a/src/webchannel/qwebchannel.h
+++ b/src/webchannel/qwebchannel.h
@@ -51,7 +51,7 @@
QT_BEGIN_NAMESPACE
struct QWebChannelPrivate;
-class QWebChannelTransportInterface;
+class QWebChannelAbstractTransport;
class Q_WEBCHANNEL_EXPORT QWebChannel : public QObject
{
@@ -89,8 +89,8 @@ public:
*/
void setBlockUpdates(bool block);
- void connectTo(QWebChannelTransportInterface *transport);
- void disconnectFrom(QWebChannelTransportInterface *transport);
+ void connectTo(QWebChannelAbstractTransport *transport);
+ void disconnectFrom(QWebChannelAbstractTransport *transport);
Q_SIGNALS:
void blockUpdatesChanged(bool block);
@@ -100,6 +100,8 @@ public Q_SLOTS:
private:
QScopedPointer<QWebChannelPrivate> d;
+ Q_PRIVATE_SLOT(d, void _q_transportDestroyed(QObject*));
+ friend class QMetaObjectPublisher;
friend class QmlWebChannel;
friend class TestWebChannel;
};
diff --git a/src/webchannel/qwebchannel.js b/src/webchannel/qwebchannel.js
index 278f423..291c10b 100644
--- a/src/webchannel/qwebchannel.js
+++ b/src/webchannel/qwebchannel.js
@@ -102,10 +102,8 @@ var QWebChannel = function(baseUrlOrSocket, initCallback, rawChannel)
this.socket.onmessage = this.messageReceived
setTimeout(this.initialized, 0);
} else {
- ///TODO: use ssl?
- var socketUrl = "ws://" + baseUrlOrSocket;
///TODO: use QWebChannel protocol, once custom protcols are supported by QtWebSocket
- this.socket = new WebSocket(socketUrl /*, "QWebChannel" */);
+ this.socket = new WebSocket(baseUrlOrSocket/*, "QWebChannel" */);
this.socket.onopen = this.initialized
this.socket.onclose = function()
@@ -147,7 +145,7 @@ var QWebChannel = function(baseUrlOrSocket, initCallback, rawChannel)
channel.send({"id": id, "data": data});
};
- this.objectMap = {};
+ this.objects = {};
this.initMetaObjectPublisher = function(doneCallback)
{
@@ -157,7 +155,7 @@ var QWebChannel = function(baseUrlOrSocket, initCallback, rawChannel)
channel.subscribe(
QWebChannelMessageTypes.signal,
function(payload) {
- var object = window[payload.object] || channel.objectMap[payload.object];
+ var object = channel.objects[payload.object];
if (object) {
object.signalEmitted(payload.signal, payload.args);
} else {
@@ -171,7 +169,7 @@ var QWebChannel = function(baseUrlOrSocket, initCallback, rawChannel)
function(payload) {
for (var i in payload) {
var data = payload[i];
- var object = window[data.object] || channel.objectMap[data.object];
+ var object = channel.objects[data.object];
if (object) {
object.propertyUpdate(data.signals, data.properties);
} else {
@@ -192,7 +190,6 @@ var QWebChannel = function(baseUrlOrSocket, initCallback, rawChannel)
for (var objectName in payload) {
var data = payload[objectName];
var object = new QObject(objectName, data, channel);
- window[objectName] = object;
}
if (doneCallback) {
doneCallback(channel);
@@ -213,7 +210,7 @@ var QWebChannel = function(baseUrlOrSocket, initCallback, rawChannel)
function QObject(name, data, webChannel)
{
this.__id__ = name;
- webChannel.objectMap[name] = this;
+ webChannel.objects[name] = this;
// List of callbacks that get invoked upon signal emission
this.__objectSignals__ = {};
@@ -233,18 +230,23 @@ function QObject(name, data, webChannel)
return response;
}
var objectId = response.id;
- if (webChannel.objectMap[objectId])
- return webChannel.objectMap[objectId];
+ if (webChannel.objects[objectId])
+ return webChannel.objects[objectId];
var qObject = new QObject( objectId, response.data, webChannel );
qObject.destroyed.connect(function() {
- if (webChannel.objectMap[objectId] === qObject) {
- delete webChannel.objectMap[objectId];
+ if (webChannel.objects[objectId] === qObject) {
+ delete webChannel.objects[objectId];
// reset the now deleted QObject to an empty {} object
// just assigning {} though would not have the desired effect, but the
// below also ensures all external references will see the empty map
- for (var prop in qObject) {
- delete qObject[prop];
+ // NOTE: this detour is necessary to workaround QTBUG-40021
+ var propertyNames = [];
+ for (var propertyName in qObject) {
+ propertyNames.push(propertyName);
+ }
+ for (var idx in propertyNames) {
+ delete qObject[propertyNames[idx]];
}
}
});
diff --git a/src/webchannel/qwebchannel_p.h b/src/webchannel/qwebchannel_p.h
index b81640e..fbdf2ef 100644
--- a/src/webchannel/qwebchannel_p.h
+++ b/src/webchannel/qwebchannel_p.h
@@ -43,22 +43,23 @@
#define QWEBCHANNEL_P_H
#include "qwebchannelglobal.h"
-#include "qwebchanneltransportinterface.h"
#include <QVector>
QT_BEGIN_NAMESPACE
class QJsonValue;
-class QWebChannelTransportInterface;
+class QWebChannelAbstractTransport;
class QMetaObjectPublisher;
Q_WEBCHANNEL_EXPORT QByteArray generateJSONMessage(const QJsonValue &id, const QJsonValue &data, bool response);
struct Q_WEBCHANNEL_EXPORT QWebChannelPrivate
{
- QVector<QWebChannelTransportInterface*> transports;
+ QVector<QWebChannelAbstractTransport*> transports;
QMetaObjectPublisher *publisher;
+
+ void _q_transportDestroyed(QObject* object);
};
QT_END_NAMESPACE
diff --git a/tests/auto/qml/data/testsetup.js b/src/webchannel/qwebchannelabstracttransport.cpp
index c0db83a..86c3121 100644
--- a/tests/auto/qml/data/testsetup.js
+++ b/src/webchannel/qwebchannelabstracttransport.cpp
@@ -39,9 +39,20 @@
**
****************************************************************************/
-window.createWebChannel = function(callback, raw)
+#include "qwebchannelabstracttransport.h"
+
+QT_BEGIN_NAMESPACE
+
+QWebChannelAbstractTransport::QWebChannelAbstractTransport(QObject *parent)
+: QObject(parent)
{
- var baseUrlMatch = /[?&]webChannelBaseUrl=([A-Za-z0-9\-:/\.]+)/.exec(location.search);
- var transport = baseUrlMatch ? baseUrlMatch[1] : navigator.qt;
- return new QWebChannel(transport, callback, raw);
+
}
+
+QWebChannelAbstractTransport::~QWebChannelAbstractTransport()
+{
+
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/webchannel/qwebsockettransport_p.h b/src/webchannel/qwebchannelabstracttransport.h
index b9bd9b0..c90f4b1 100644
--- a/src/webchannel/qwebsockettransport_p.h
+++ b/src/webchannel/qwebchannelabstracttransport.h
@@ -39,51 +39,34 @@
**
****************************************************************************/
-#ifndef QWEBCHANNELSOCKET_P_H
-#define QWEBCHANNELSOCKET_P_H
+#ifndef QWEBCHANNELABSTRACTTRANSPORT_H
+#define QWEBCHANNELABSTRACTTRANSPORT_H
-#include <QtWebSockets/QWebSocketServer>
-
-#include "qwebchanneltransportinterface.h"
+#include <QObject>
+#include <qwebchannelglobal.h>
QT_BEGIN_NAMESPACE
-class QWebSocketTransport;
-class QWebSocketTransportPrivate : public QWebSocketServer
+class Q_WEBCHANNEL_EXPORT QWebChannelAbstractTransport : public QObject
{
Q_OBJECT
public:
- QString m_secret;
- QString m_baseUrl;
- QWebChannelMessageHandlerInterface *m_messageHandler;
- QWebSocketTransport *m_transport;
-
- bool m_useSecret;
- bool m_starting;
-
- explicit QWebSocketTransportPrivate(QWebSocketTransport* transport, QObject *parent = 0);
- virtual ~QWebSocketTransportPrivate();
+ explicit QWebChannelAbstractTransport(QObject *parent = 0);
+ virtual ~QWebChannelAbstractTransport();
- void initLater();
- void sendMessage(const QString &message, int clientId);
+public Q_SLOTS:
+ /**
+ * Send a text @p message to the remote client.
+ */
+ virtual void sendTextMessage(const QString &message) = 0;
Q_SIGNALS:
- void failed(const QString &reason);
- void initialized();
- void baseUrlChanged(const QString &baseUrl);
- void textDataReceived(const QString &message);
-
-private Q_SLOTS:
- void validateNewConnection();
- void init();
- void socketError();
- void messageReceived(const QString &message);
- void clientDisconnected();
-
-private:
- QVector<QWebSocket*> m_clients;
+ /**
+ * Emitted when a new text message was received from the remote client.
+ */
+ void textMessageReceived(const QString &message);
};
QT_END_NAMESPACE
-#endif // QWEBCHANNELSOCKET_P_H
+#endif // QWEBCHANNELABSTRACTTRANSPORT_H
diff --git a/src/webchannel/qwebchanneltransportinterface.h b/src/webchannel/qwebchanneltransportinterface.h
deleted file mode 100644
index c532732..0000000
--- a/src/webchannel/qwebchanneltransportinterface.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtWebChannel module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWEBCHANNELTRANSPORTINTERFACE_H
-#define QWEBCHANNELTRANSPORTINTERFACE_H
-
-#include <QObject>
-
-#include <QtWebChannel/qwebchannelglobal.h>
-
-QT_BEGIN_NAMESPACE
-
-class QWebChannelTransportInterface;
-class Q_WEBCHANNEL_EXPORT QWebChannelMessageHandlerInterface
-{
-public:
- virtual ~QWebChannelMessageHandlerInterface() {}
-
- /**
- * Handle a text message from a web channel client.
- */
- virtual void handleMessage(const QString &message, QWebChannelTransportInterface* transport, int clientId) = 0;
-};
-
-#define QWebChannelMessageHandlerInterface_iid "org.qt-project.Qt.QWebChannelMessageHandlerInterface"
-Q_DECLARE_INTERFACE(QWebChannelMessageHandlerInterface, QWebChannelMessageHandlerInterface_iid);
-Q_DECLARE_METATYPE(QWebChannelMessageHandlerInterface*)
-
-class Q_WEBCHANNEL_EXPORT QWebChannelTransportInterface
-{
-public:
- virtual ~QWebChannelTransportInterface() {}
-
- /**
- * Send a text message to all web channel clients.
- */
- virtual void sendMessage(const QString &message, int clientId = -1) const = 0;
-
- /**
- * Send a binary message to all web channel clients.
- */
- virtual void sendMessage(const QByteArray &message, int clientId = -1) const = 0;
-
- /**
- * Sets the message handler that will be called on incoming messages from web channel clients.
- */
- virtual void setMessageHandler(QWebChannelMessageHandlerInterface *handler) = 0;
-};
-
-#define QWebChannelTransportInterface_iid "org.qt-project.Qt.QWebChannelTransportInterface"
-Q_DECLARE_INTERFACE(QWebChannelTransportInterface, QWebChannelTransportInterface_iid);
-Q_DECLARE_METATYPE(QWebChannelTransportInterface*)
-
-QT_END_NAMESPACE
-
-#endif // QWEBCHANNELTRANSPORTINTERFACE_H
diff --git a/tests/auto/qml/TestWebView.qml b/src/webchannel/qwebchannelwebsockettransport.cpp
index 3b12f38..59c9538 100644
--- a/tests/auto/qml/TestWebView.qml
+++ b/src/webchannel/qwebchannelwebsockettransport.cpp
@@ -39,43 +39,41 @@
**
****************************************************************************/
-import QtQuick 2.0
-import QtTest 1.0
+#include "qwebchannelwebsockettransport.h"
-import QtWebKit 3.0
-import QtWebKit.experimental 1.0
+/*!
+ \inmodule QtWebChannel
+ \brief QWebChannelAbstractSocket implementation that uses a QWebSocket internally.
-WebView {
- id: view
- property var lastLoadStatus
+ The transport delegates all messages received over the QWebSocket over its
+ textMessageReceived signal. Analogously, all calls to sendTextMessage will
+ be send over the QWebSocket to the remote client.
+*/
- experimental.preferences.developerExtrasEnabled: true
- experimental.preferences.navigatorQtObjectEnabled: true
+QT_BEGIN_NAMESPACE
- onLoadingChanged: {
- // NOTE: we cannot use spy.signalArguments nor save the loadRequest anywhere, as it gets
- // deleted after the slots connected to the signal have finished... i.e. it's a weak pointer,
- // not a shared pointer. As such, we have to copy out the interesting data we need later on here...
- lastLoadStatus = loadRequest.status
- }
+struct QWebChannelWebSocketTransportPrivate
+{
+ QWebSocket *socket;
+};
- SignalSpy {
- id: loadingSpy
- target: view
- signalName: "onLoadingChanged"
- }
+QWebChannelWebSocketTransport::QWebChannelWebSocketTransport(QWebSocket *socket)
+: QWebChannelAbstractTransport(socket)
+, d(new QWebChannelWebSocketTransportPrivate)
+{
+ d->socket = socket;
+ connect(socket, &QWebSocket::textMessageReceived,
+ this, &QWebChannelWebSocketTransport::textMessageReceived);
+}
+
+QWebChannelWebSocketTransport::~QWebChannelWebSocketTransport()
+{
- function waitForLoaded()
- {
- do {
- loadingSpy.wait(500);
- } while (loading);
- return lastLoadStatus == WebView.LoadSucceededStatus;
- }
+}
- function clear()
- {
- url = "";
- loadingSpy.clear()
- }
+void QWebChannelWebSocketTransport::sendTextMessage(const QString &message)
+{
+ d->socket->sendTextMessage(message);
}
+
+QT_END_NAMESPACE
diff --git a/src/webchannel/qwebchannelwebsockettransport.h b/src/webchannel/qwebchannelwebsockettransport.h
new file mode 100644
index 0000000..b718b9b
--- /dev/null
+++ b/src/webchannel/qwebchannelwebsockettransport.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebChannel module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWEBCHANNELWEBSOCKETTRANSPORT_H
+#define QWEBCHANNELWEBSOCKETTRANSPORT_H
+
+#include <QObject>
+#include <QtWebChannel/QWebChannelAbstractTransport>
+#include <QtWebChannel/qwebchannelglobal.h>
+#include <QtWebSockets/QWebSocket>
+
+QT_BEGIN_NAMESPACE
+
+struct QWebChannelWebSocketTransportPrivate;
+class Q_WEBCHANNEL_EXPORT QWebChannelWebSocketTransport : public QWebChannelAbstractTransport
+{
+ Q_OBJECT
+public:
+ explicit QWebChannelWebSocketTransport(QWebSocket *socket);
+ virtual ~QWebChannelWebSocketTransport();
+
+ void sendTextMessage(const QString &message) Q_DECL_OVERRIDE;
+
+private:
+ QScopedPointer<QWebChannelWebSocketTransportPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWEBCHANNELWEBSOCKETTRANSPORT_H
diff --git a/src/webchannel/qwebsockettransport.cpp b/src/webchannel/qwebsockettransport.cpp
deleted file mode 100644
index 8c25a9b..0000000
--- a/src/webchannel/qwebsockettransport.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtWebChannel module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwebsockettransport.h"
-#include "qwebsockettransport_p.h"
-
-#include <QUuid>
-
-#include <QtWebSockets/QWebSocket>
-
-QT_USE_NAMESPACE
-
-//BEGIN QWebSocketTransportPrivate
-
-QWebSocketTransportPrivate::QWebSocketTransportPrivate(QWebSocketTransport *transport, QObject *parent)
- : QWebSocketServer(QStringLiteral("QWebChannel Server"), NonSecureMode, parent)
- , m_messageHandler(Q_NULLPTR)
- , m_transport(transport)
- , m_useSecret(true)
- , m_starting(false)
-{
- connect(this, SIGNAL(acceptError(QAbstractSocket::SocketError)),
- SLOT(socketError()));
- connect(this, SIGNAL(newConnection()),
- SLOT(validateNewConnection()));
-}
-
-QWebSocketTransportPrivate::~QWebSocketTransportPrivate()
-{
- close();
- qDeleteAll(m_clients);
-}
-
-void QWebSocketTransportPrivate::initLater()
-{
- if (m_starting)
- return;
- metaObject()->invokeMethod(this, "init", Qt::QueuedConnection);
- m_starting = true;
-}
-
-void QWebSocketTransportPrivate::sendMessage(const QString &message, int clientId)
-{
- if (clientId == -1) {
- foreach (QWebSocket *client, m_clients) {
- client->sendTextMessage(message);
- }
- } else {
- m_clients.at(clientId)->sendTextMessage(message);
- }
-}
-
-void QWebSocketTransportPrivate::validateNewConnection()
-{
- QWebSocket *client = nextPendingConnection();
- // FIXME: client->protocol() != QStringLiteral("QWebChannel")
- // protocols are not supported in QtWebSockets yet...
- if (m_useSecret && client->requestUrl().path() != m_secret)
- {
- client->close(QWebSocketProtocol::CloseCodeBadOperation);
- client->deleteLater();
- } else {
- connect(client, SIGNAL(textMessageReceived(QString)),
- SLOT(messageReceived(QString)));
- connect(client, SIGNAL(disconnected()),
- SLOT(clientDisconnected()));
- m_clients << client;
- }
-}
-
-void QWebSocketTransportPrivate::init()
-{
- close();
-
- m_starting = false;
- if (m_useSecret) {
- m_secret = QUuid::createUuid().toString();
- // replace { by /
- m_secret[0] = QLatin1Char('/');
- // chop of trailing }
- m_secret.chop(1);
- }
-
- if (!listen(QHostAddress::LocalHost)) {
- emit failed(errorString());
- return;
- }
-
- m_baseUrl = QStringLiteral("127.0.0.1:%1%2").arg(serverPort()).arg(m_secret);
- emit initialized();
- emit baseUrlChanged(m_baseUrl);
-}
-
-void QWebSocketTransportPrivate::socketError()
-{
- emit failed(errorString());
-}
-
-void QWebSocketTransportPrivate::messageReceived(const QString &message)
-{
- if (m_messageHandler) {
- QWebSocket *client = qobject_cast<QWebSocket*>(sender());
- m_messageHandler->handleMessage(message, m_transport, m_clients.indexOf(client));
- }
- emit textDataReceived(message);
-}
-
-void QWebSocketTransportPrivate::clientDisconnected()
-{
- QWebSocket *client = qobject_cast<QWebSocket*>(sender());
- if (!client) {
- return;
- }
- const int idx = m_clients.indexOf(client);
- Q_ASSERT(idx != -1);
- m_clients.remove(idx);
- client->deleteLater();
-}
-
-//END QWebSocketTransportPrivate
-
-QWebSocketTransport::QWebSocketTransport(QObject *parent)
- : QObject(parent)
- , d(new QWebSocketTransportPrivate(this))
-{
- connect(d.data(), SIGNAL(textDataReceived(QString)),
- SIGNAL(messageReceived(QString)));
- connect(d.data(), SIGNAL(failed(QString)),
- SIGNAL(failed(QString)));
- connect(d.data(), SIGNAL(initialized()),
- SIGNAL(initialized()));
- connect(d.data(), SIGNAL(baseUrlChanged(QString)),
- SIGNAL(baseUrlChanged(QString)));
-
- d->initLater();
-}
-
-QWebSocketTransport::~QWebSocketTransport()
-{
-
-}
-
-void QWebSocketTransport::sendMessage(const QByteArray &message, int clientId) const
-{
- d->sendMessage(QString::fromUtf8(message), clientId);
-}
-
-void QWebSocketTransport::sendMessage(const QString &message, int clientId) const
-{
- d->sendMessage(message, clientId);
-}
-
-void QWebSocketTransport::setMessageHandler(QWebChannelMessageHandlerInterface *handler)
-{
- d->m_messageHandler = handler;
-}
-
-QString QWebSocketTransport::baseUrl() const
-{
- return d->m_baseUrl;
-}
-
-void QWebSocketTransport::setUseSecret(bool s)
-{
- if (d->m_useSecret == s)
- return;
- d->m_useSecret = s;
- d->initLater();
-}
-
-bool QWebSocketTransport::useSecret() const
-{
- return d->m_useSecret;
-}
diff --git a/src/webchannel/qwebsockettransport.h b/src/webchannel/qwebsockettransport.h
deleted file mode 100644
index b3e484f..0000000
--- a/src/webchannel/qwebsockettransport.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtWebChannel module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWEBSOCKETTRANSPORT_H
-#define QWEBSOCKETTRANSPORT_H
-
-#include "qwebchanneltransportinterface.h"
-
-QT_BEGIN_NAMESPACE
-
-class QWebSocketTransportPrivate;
-class Q_WEBCHANNEL_EXPORT QWebSocketTransport : public QObject, public QWebChannelTransportInterface
-{
- Q_OBJECT
- Q_INTERFACES(QWebChannelTransportInterface)
- Q_PROPERTY(QString baseUrl READ baseUrl NOTIFY baseUrlChanged)
- Q_PROPERTY(bool useSecret READ useSecret WRITE setUseSecret)
-public:
- explicit QWebSocketTransport(QObject *parent = 0);
- ~QWebSocketTransport() Q_DECL_OVERRIDE;
-
- void sendMessage(const QByteArray &message, int clientId = -1) const Q_DECL_OVERRIDE;
- void sendMessage(const QString &message, int clientId = -1) const Q_DECL_OVERRIDE;
- void setMessageHandler(QWebChannelMessageHandlerInterface *handler) Q_DECL_OVERRIDE;
-
- QString baseUrl() const;
-
- void setUseSecret(bool);
- bool useSecret() const;
-
-Q_SIGNALS:
- void baseUrlChanged(const QString &baseUrl);
- void failed(const QString &reason);
- void initialized();
- void messageReceived(const QString &message);
-
-private:
- QScopedPointer<QWebSocketTransportPrivate> d;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWEBSOCKETTRANSPORT_H
diff --git a/src/webchannel/webchannel.pro b/src/webchannel/webchannel.pro
index c6e6d69..a50beaa 100644
--- a/src/webchannel/webchannel.pro
+++ b/src/webchannel/webchannel.pro
@@ -12,20 +12,20 @@ OTHER_FILES = \
PUBLIC_HEADERS += \
qwebchannel.h \
- qwebchanneltransport.h \
- qwebsockettransport.h
+ qwebchannelabstracttransport.h \
+ qwebchannelwebsockettransport.h
PRIVATE_HEADERS += \
qwebchannel_p.h \
qmetaobjectpublisher_p.h \
- qwebsockettransport_p.h \
variantargument_p.h \
signalhandler_p.h
SOURCES += \
qwebchannel.cpp \
qmetaobjectpublisher.cpp \
- qwebsockettransport.cpp
+ qwebchannelabstracttransport.cpp \
+ qwebchannelwebsockettransport.cpp
qtHaveModule(qml) {
QT += qml
diff --git a/sync.profile b/sync.profile
index 5d7cd6b..f0e6c33 100644
--- a/sync.profile
+++ b/sync.profile
@@ -15,7 +15,4 @@
"qtwebsockets" => "refs/heads/dev",
# optional dependencies:
"qtdeclarative" => "refs/heads/dev",
- # TODO: disabled for now as it breaks CI builds on OSX
- # requires changes to qtqa scripts as discussed with sifalt, sahumada, tronical
- # "qtwebkit" => "",
);
diff --git a/tests/auto/qml/WebChannelTest.qml b/tests/auto/qml/Client.qml
index 9a0baa9..609fbac 100644
--- a/tests/auto/qml/WebChannelTest.qml
+++ b/tests/auto/qml/Client.qml
@@ -43,77 +43,86 @@ import QtQuick 2.0
import QtTest 1.0
import QtWebChannel 1.0
+import QtWebChannel.Tests 1.0
+import "qrc:///qwebchannel/qwebchannel.js" as Client
-TestCase {
- property var lastLoadStatus
- property bool useWebViewTransport: false
+Item {
+ TestTransport {
+ id: serverTransport
+ }
+ readonly property var serverTransport: serverTransport
- // only run after the webchannel has finished initialization
- when: webSocketTransport.baseUrl != ""
+ property var clientMessages: []
- WebViewTransport {
- id: webViewTransport
- webViewExperimental: defaultView.experimental
- }
- WebSocketTransport {
- id: webSocketTransport
- }
+ property bool debug: false
- TestWebView {
- id: defaultView
- }
+ QtObject {
+ id: clientTransport
+
+ property var send;
+ property var onmessage;
- WebChannel {
- id: webChannel
+ function postMessage(message)
+ {
+ if (debug) {
+ console.log("client posts message: ", message);
+ }
+ clientMessages.push(message);
+ serverTransport.textMessageReceived(message);
+ }
+
+ Component.onCompleted: {
+ serverTransport.sendTextMessageRequested.connect(function(message) {
+ if (debug) {
+ console.log("client received message: ", message);
+ }
+ onmessage({data:message});
+ });
+ }
}
- property var webChannel: webChannel
+ readonly property var clientTransport: clientTransport
+
+ Timer {
+ id: timer
+ running: false
+ repeat: false
- SignalSpy {
- id: rawMessageSpy
- target: useWebViewTransport ? webViewTransport : webSocketTransport;
- signalName: "onMessageReceived"
+ property var callback
+
+ onTriggered: {
+ callback();
+ }
}
- property var rawMessageSpy: rawMessageSpy
- property var rawMessageIdx: 0;
- function urlForFile(file)
+ function setTimeout(callback, delay)
{
- verify(useWebViewTransport || webSocketTransport.baseUrl != "", "webSocketTransport.baseUrl is empty");
- return "data/" + file + (!useWebViewTransport ? "?webChannelBaseUrl=" + webSocketTransport.baseUrl : "");
+ if (timer.running) {
+ console.error("nested calls to setTimeout are not supported!", JSON.stringify(callback), JSON.stringify(timer.callback));
+ return;
+ }
+ timer.callback = callback;
+ // note: an interval of 0 is directly triggered, so add a little padding
+ timer.interval = delay + 1;
+ timer.running = true;
}
- // load file in the given view or use the global one by default
- function loadUrl(file, view)
+ function createChannel(callback, raw)
{
- if (useWebViewTransport) {
- webChannel.disconnectFrom(webSocketTransport);
- webChannel.connectTo(webViewTransport);
- } else {
- webChannel.disconnectFrom(webViewTransport);
- webChannel.connectTo(webSocketTransport);
- }
- if (!view) {
- view = defaultView;
- }
- view.url = urlForFile(file);
- view.waitForLoaded();
+ return new Client.QWebChannel(clientTransport, callback, raw);
}
function cleanup()
{
- defaultView.clear();
- rawMessageSpy.clear();
- rawMessageIdx = 0;
+ clientMessages = [];
+ timer.running = false;
}
function awaitRawMessage()
{
- rawMessageSpy.wait(500);
- if (rawMessageSpy.signalArguments.length <= rawMessageIdx) {
- // still no message received, fail
- return null;
+ for (var i = 0; i < 10 && !clientMessages.length; ++i) {
+ wait(10);
}
- return rawMessageSpy.signalArguments[rawMessageIdx++][0];
+ return clientMessages.shift();
}
function awaitMessage()
@@ -131,7 +140,7 @@ TestCase {
verify(msg);
verify(msg.data);
verify(msg.data.type);
- compare(msg.data.type, qWebChannelMessageTypes.init);
+ compare(msg.data.type, Client.QWebChannelMessageTypes.init);
}
function awaitIdle()
@@ -139,19 +148,19 @@ TestCase {
var msg = awaitMessage();
verify(msg);
verify(msg.data);
- compare(msg.data.type, qWebChannelMessageTypes.idle);
+ compare(msg.data.type, Client.QWebChannelMessageTypes.idle);
verify(webChannel.test_clientIsIdle())
}
- property var qWebChannelMessageTypes: ({
- signal: 1,
- propertyUpdate: 2,
- init: 3,
- idle: 4,
- debug: 5,
- invokeMethod: 6,
- connectToSignal: 7,
- disconnectFromSignal: 8,
- setProperty: 9,
- });
+ function awaitMessageSkipIdle()
+ {
+ var msg;
+ do {
+ msg = awaitMessage();
+ verify(msg);
+ verify(msg.data);
+ } while (msg.data.type === Client.QWebChannelMessageTypes.idle);
+ return msg;
+ }
+
}
diff --git a/tests/auto/qml/data/bench_init.html b/tests/auto/qml/data/bench_init.html
deleted file mode 100644
index 7d3af5b..0000000
--- a/tests/auto/qml/data/bench_init.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<html>
- <head>
- <script type="text/javascript" src="qrc:///qwebchannel/qwebchannel.js"></script>
- <script type="text/javascript" src="testsetup.js"></script>
- <script type="text/javascript">
- //BEGIN SETUP
- createWebChannel(function(channel) {});
- //END SETUP
- </script>
- </head>
- <body>
- </body>
-</html>
diff --git a/tests/auto/qml/data/disconnect.html b/tests/auto/qml/data/disconnect.html
deleted file mode 100644
index a9a479c..0000000
--- a/tests/auto/qml/data/disconnect.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<html>
- <head>
- <script type="text/javascript" src="qrc:///qwebchannel/qwebchannel.js"></script>
- <script type="text/javascript" src="testsetup.js"></script>
- <script type="text/javascript">
- //BEGIN SETUP
- createWebChannel(function(channel) {
- myObj.mySignal.connect(function(arg) {
- channel.exec({label: "mySignalReceived", args: [arg]});
- myObj.mySignal.disconnect(this);
- });
- channel.subscribe("report", function() {
- channel.exec({label: "report"});
- });
- });
- //END SETUP
- </script>
- </head>
- <body>
- </body>
-</html>
diff --git a/tests/auto/qml/data/grouping.html b/tests/auto/qml/data/grouping.html
deleted file mode 100644
index f6bc33c..0000000
--- a/tests/auto/qml/data/grouping.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<html>
- <head>
- <script type="text/javascript" src="qrc:///qwebchannel/qwebchannel.js"></script>
- <script type="text/javascript" src="testsetup.js"></script>
- <script type="text/javascript">
- //BEGIN SETUP
- window.channel = createWebChannel(function(channel) {
- channel.subscribe(QWebChannelMessageTypes.propertyUpdate, function() {
- channel.exec({label: "gotPropertyUpdate", values: [myObj.myProperty, myOtherObj.foo, myOtherObj.bar]});
- });
- });
- //END SETUP
- </script>
- </head>
- <body>
- </body>
-</html>
diff --git a/tests/auto/qml/data/method.html b/tests/auto/qml/data/method.html
deleted file mode 100644
index 6dbaa90..0000000
--- a/tests/auto/qml/data/method.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<html>
- <head>
- <script type="text/javascript" src="qrc:///qwebchannel/qwebchannel.js"></script>
- <script type="text/javascript" src="testsetup.js"></script>
- <script type="text/javascript">
- //BEGIN SETUP
- createWebChannel(function(channel) {
- channel.subscribe("invokeMethod", function(arg) {
- myObj.myMethod(arg);
- });
- });
- //END SETUP
- </script>
- </head>
- <body>
- </body>
-</html>
diff --git a/tests/auto/qml/data/multiclient.html b/tests/auto/qml/data/multiclient.html
deleted file mode 100644
index 1573a1a..0000000
--- a/tests/auto/qml/data/multiclient.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<html>
- <head>
- <script type="text/javascript" src="qrc:///qwebchannel/qwebchannel.js"></script>
- <script type="text/javascript" src="testsetup.js"></script>
- <script type="text/javascript">
- //BEGIN SETUP
- createWebChannel(function(channel) {
- foo.ping.connect(function() {
- foo.pong(function(value) {
- channel.exec({pongAnswer: value});
- });
- });
- });
- //END SETUP
- </script>
- </head>
- <body>
- </body>
-</html>
diff --git a/tests/auto/qml/data/property.html b/tests/auto/qml/data/property.html
deleted file mode 100644
index 49b3811..0000000
--- a/tests/auto/qml/data/property.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<html>
- <head>
- <script type="text/javascript" src="qrc:///qwebchannel/qwebchannel.js"></script>
- <script type="text/javascript" src="testsetup.js"></script>
- <script type="text/javascript">
- //BEGIN SETUP
- createWebChannel(function(channel) {
- channel.exec({label: "init", value: myObj.myProperty});
- myObj.myPropertyChanged.connect(function() {
- channel.exec({label: "changed", value: myObj.myProperty});
- });
- channel.subscribe("setProperty", function(newValue) {
- myObj.myProperty = newValue;
- });
- });
- //END SETUP
- </script>
- </head>
- <body>
- </body>
-</html>
diff --git a/tests/auto/qml/data/receiveRaw.html b/tests/auto/qml/data/receiveRaw.html
deleted file mode 100644
index 139b2b1..0000000
--- a/tests/auto/qml/data/receiveRaw.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<html>
- <head>
- <script type="text/javascript" src="qrc:///qwebchannel/qwebchannel.js"></script>
- <script type="text/javascript" src="testsetup.js"></script>
- <script type="text/javascript">
- //BEGIN SETUP
- createWebChannel(function(channel) {
- channel.send("foobar");
- }, true /* raw */);
- //END SETUP
- </script>
- </head>
- <body>
- </body>
-</html>
diff --git a/tests/auto/qml/data/send.html b/tests/auto/qml/data/send.html
deleted file mode 100644
index c60fbf4..0000000
--- a/tests/auto/qml/data/send.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<html>
- <head>
- <script type="text/javascript" src="qrc:///qwebchannel/qwebchannel.js"></script>
- <script type="text/javascript" src="testsetup.js"></script>
- <script type="text/javascript">
- //BEGIN SETUP
- createWebChannel(function(channel) {
- channel.subscribe("myMessage", function(payload) {
- channel.send("myMessagePong:" + payload);
- });
- }, true /* raw */);
- //END SETUP
- </script>
- </head>
- <body>
- </body>
-</html>
diff --git a/tests/auto/qml/data/signal.html b/tests/auto/qml/data/signal.html
deleted file mode 100644
index bdce0c7..0000000
--- a/tests/auto/qml/data/signal.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<html>
- <head>
- <script type="text/javascript" src="qrc:///qwebchannel/qwebchannel.js"></script>
- <script type="text/javascript" src="testsetup.js"></script>
- <script type="text/javascript">
- //BEGIN SETUP
- createWebChannel(function(channel) {
- myObj.mySignal.connect(function(arg) {
- channel.exec({label: "signalReceived", value: arg});
- });
- });
- //END SETUP
- </script>
- </head>
- <body>
- </body>
-</html>
diff --git a/tests/auto/qml/data/wrapper.html b/tests/auto/qml/data/wrapper.html
deleted file mode 100644
index df368ee..0000000
--- a/tests/auto/qml/data/wrapper.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<html>
- <head>
- <script type="text/javascript" src="qrc:///qwebchannel/qwebchannel.js"></script>
- <script type="text/javascript" src="testsetup.js"></script>
- <script type="text/javascript">
- //BEGIN SETUP
- createWebChannel(function(channel) {
- myFactory.create("testObj", function(obj) {
- window[obj.objectName] = obj;
- obj.mySignal.connect(function(arg1, arg2) {
- channel.exec({label: "signalReceived", args: [arg1, arg2]});
- });
- obj.myProperty = 42;
- obj.myMethod("foobar");
- });
- channel.subscribe("triggerDelete", function() {
- testObj.deleteLater();
- });
- channel.subscribe("report", function() {
- channel.exec({label:"report", obj: testObj})
- });
- });
- //END SETUP
- </script>
- </head>
- <body>
- </body>
-</html>
diff --git a/tests/auto/qml/qml.cpp b/tests/auto/qml/qml.cpp
index 7267842..0612bdb 100644
--- a/tests/auto/qml/qml.cpp
+++ b/tests/auto/qml/qml.cpp
@@ -40,5 +40,17 @@
****************************************************************************/
#include <QtQuickTest/quicktest.h>
+#include <QtQml/qqml.h>
-QUICK_TEST_MAIN(qml)
+#ifndef QUICK_TEST_SOURCE_DIR
+#define QUICK_TEST_SOURCE_DIR Q_NULLPTR
+#endif
+
+#include "testtransport.h"
+
+int main(int argc, char **argv)
+{
+ qmlRegisterType<TestTransport>("QtWebChannel.Tests", 1, 0, "TestTransport");
+
+ return quick_test_main(argc, argv, "qml", QUICK_TEST_SOURCE_DIR);
+}
diff --git a/tests/auto/qml/qml.pro b/tests/auto/qml/qml.pro
index f86dc90..ddef2cb 100644
--- a/tests/auto/qml/qml.pro
+++ b/tests/auto/qml/qml.pro
@@ -8,7 +8,11 @@ CONFIG += warn_on qmltestcase
IMPORTPATH += $$OUT_PWD/../../../qml $$PWD
SOURCES += \
- qml.cpp
+ qml.cpp \
+ testtransport.cpp
+
+HEADERS += \
+ testtransport.h
OTHER_FILES += \
WebChannelTest.qml \
diff --git a/tests/auto/qml/testtransport.cpp b/tests/auto/qml/testtransport.cpp
new file mode 100644
index 0000000..a332955
--- /dev/null
+++ b/tests/auto/qml/testtransport.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebChannel module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "testtransport.h"
+
+QT_BEGIN_NAMESPACE
+
+TestTransport::TestTransport(QObject *parent)
+: QWebChannelAbstractTransport(parent)
+{
+
+}
+
+void TestTransport::sendTextMessage(const QString &message)
+{
+ emit sendTextMessageRequested(message);
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/webchannel/qmlwebviewtransport.h b/tests/auto/qml/testtransport.h
index 8fbfdd9..dd07832 100644
--- a/src/imports/webchannel/qmlwebviewtransport.h
+++ b/tests/auto/qml/testtransport.h
@@ -39,41 +39,25 @@
**
****************************************************************************/
-#ifndef QMLWEBVIEWTRANSPORT_H
-#define QMLWEBVIEWTRANSPORT_H
+#ifndef TESTTRANSPORT_H
+#define TESTTRANSPORT_H
-#include <qwebchanneltransportinterface.h>
+#include <QtWebChannel/QWebChannelAbstractTransport>
QT_BEGIN_NAMESPACE
-class QmlWebViewTransport : public QObject, public QWebChannelTransportInterface
+class TestTransport : public QWebChannelAbstractTransport
{
Q_OBJECT
- Q_INTERFACES(QWebChannelTransportInterface)
- Q_PROPERTY(QObject *webViewExperimental READ webViewExperimental WRITE setWebViewExperimental NOTIFY webViewChanged)
public:
- explicit QmlWebViewTransport(QObject *parent = 0);
- ~QmlWebViewTransport() Q_DECL_OVERRIDE;
+ explicit TestTransport(QObject *parent = 0);
- void sendMessage(const QString &message, int clientId) const Q_DECL_OVERRIDE;
- void sendMessage(const QByteArray &message, int clientId) const Q_DECL_OVERRIDE;
- void setMessageHandler(QWebChannelMessageHandlerInterface *handler) Q_DECL_OVERRIDE;
-
- void setWebViewExperimental(QObject *webViewExperimental);
- QObject *webViewExperimental() const;
+ virtual void sendTextMessage(const QString &message);
Q_SIGNALS:
- void webViewChanged(QObject *webViewExperimental);
- void messageReceived(const QString &message);
-
-private Q_SLOTS:
- void handleWebViewMessage(const QVariantMap &message);
-
-private:
- QObject *m_webViewExperimental;
- QWebChannelMessageHandlerInterface *m_handler;
+ void sendTextMessageRequested(const QString &message);
};
QT_END_NAMESPACE
-#endif // QMLWEBVIEWTRANSPORT_H
+#endif // TESTTRANSPORT_H
diff --git a/tests/auto/qml/tst_bench.qml b/tests/auto/qml/tst_bench.qml
index 056dda9..833720e 100644
--- a/tests/auto/qml/tst_bench.qml
+++ b/tests/auto/qml/tst_bench.qml
@@ -40,13 +40,24 @@
****************************************************************************/
import QtQuick 2.0
+import QtTest 1.0
import QtWebChannel 1.0
+import "qrc:///qwebchannel/qwebchannel.js" as Client
-WebChannelTest {
+TestCase {
name: "Bench"
id: test
+ Client {
+ id: client
+ }
+
+ WebChannel {
+ id: webChannel
+ transports: [client.serverTransport]
+ }
+
Component {
id: component
QtObject {
@@ -96,28 +107,15 @@ WebChannelTest {
webChannel.registerObjects(objects);
}
- function benchmark_init_baseline()
- {
- loadUrl("bench_init.html");
- }
-
- function benchmark_init_webview()
+ function cleanup()
{
- useWebViewTransport = true;
- loadUrl("bench_init.html");
- // init
- awaitMessage();
- // idle
- awaitMessage();
+ client.cleanup();
}
- function benchmark_init_websocket()
+ function benchmark_init()
{
- useWebViewTransport = false;
- loadUrl("bench_init.html");
- // init
- awaitMessage();
- // idle
- awaitMessage();
+ var channel = client.createChannel(function() {});
+ client.awaitInit();
+ client.awaitIdle();
}
}
diff --git a/tests/auto/qml/tst_metaobjectpublisher.qml b/tests/auto/qml/tst_metaobjectpublisher.qml
index e07f105..880b30d 100644
--- a/tests/auto/qml/tst_metaobjectpublisher.qml
+++ b/tests/auto/qml/tst_metaobjectpublisher.qml
@@ -40,12 +40,17 @@
****************************************************************************/
import QtQuick 2.0
+import QtTest 1.0
import QtWebChannel 1.0
+import "qrc:///qwebchannel/qwebchannel.js" as Client
-WebChannelTest {
+TestCase {
name: "MetaObjectPublisher"
- id: test
+
+ Client {
+ id: client
+ }
property var lastMethodArg
@@ -90,62 +95,71 @@ WebChannelTest {
}
}
- function initTestCase()
- {
- webChannel.registeredObjects = [myObj, myOtherObj, myFactory];
+ WebChannel {
+ id: webChannel
+ transports: [client.serverTransport]
+ registeredObjects: [myObj, myOtherObj, myFactory]
}
- function awaitMessageSkipIdle()
+ function init()
{
- var msg;
- do {
- msg = awaitMessage();
- verify(msg);
- verify(msg.data);
- } while (msg.data.type === qWebChannelMessageTypes.idle);
- return msg;
+ myObj.myProperty = 1
+ client.cleanup();
}
function test_property()
{
- myObj.myProperty = 1
- loadUrl("property.html");
- awaitInit();
- var msg = awaitMessageSkipIdle();
+ var channel = client.createChannel(function(channel) {
+ channel.exec({label: "init", value: channel.objects.myObj.myProperty});
+ channel.objects.myObj.myPropertyChanged.connect(function() {
+ channel.exec({label: "changed", value: channel.objects.myObj.myProperty});
+ });
+ channel.subscribe("setProperty", function(newValue) {
+ channel.objects.myObj.myProperty = newValue;
+ });
+ });
+
+ client.awaitInit();
+ var msg = client.awaitMessageSkipIdle();
compare(msg.data.label, "init");
compare(msg.data.value, 1);
compare(myObj.myProperty, 1);
// change property, should be propagated to HTML client and a message be send there
myObj.myProperty = 2;
- msg = awaitMessageSkipIdle();
+ msg = client.awaitMessageSkipIdle();
compare(msg.data.label, "changed");
compare(msg.data.value, 2);
compare(myObj.myProperty, 2);
// now trigger a write from the client side
webChannel.sendMessage("setProperty", 3);
- msg = awaitMessageSkipIdle();
+ msg = client.awaitMessageSkipIdle();
compare(myObj.myProperty, 3);
// the above write is also propagated to the HTML client
- msg = awaitMessageSkipIdle();
+ msg = client.awaitMessageSkipIdle();
compare(msg.data.label, "changed");
compare(msg.data.value, 3);
- awaitIdle();
+ client.awaitIdle();
}
function test_method()
{
- loadUrl("method.html");
- awaitInit();
- awaitIdle();
+ var channel = client.createChannel(function (channel) {
+ channel.subscribe("invokeMethod", function (arg) {
+ channel.objects.myObj.myMethod(arg);
+ });
+ });
+
+ client.awaitInit();
+ client.awaitIdle();
webChannel.sendMessage("invokeMethod", "test");
- var msg = awaitMessage();
- compare(msg.data.type, qWebChannelMessageTypes.invokeMethod);
+ var msg = client.awaitMessage();
+ compare(msg.data.type, Client.QWebChannelMessageTypes.invokeMethod);
compare(msg.data.object, "myObj");
compare(msg.data.args, ["test"]);
@@ -154,27 +168,35 @@ WebChannelTest {
function test_signal()
{
- loadUrl("signal.html");
- awaitInit();
-
- var msg = awaitMessage();
- compare(msg.data.type, qWebChannelMessageTypes.connectToSignal);
+ var channel = client.createChannel(function(channel) {
+ channel.objects.myObj.mySignal.connect(function(arg) {
+ channel.exec({label: "signalReceived", value: arg});
+ });
+ });
+ client.awaitInit();
+
+ var msg = client.awaitMessage();
+ compare(msg.data.type, Client.QWebChannelMessageTypes.connectToSignal);
compare(msg.data.object, "myObj");
- awaitIdle();
+ client.awaitIdle();
myObj.mySignal("test");
- msg = awaitMessage();
+ msg = client.awaitMessageSkipIdle();
compare(msg.data.label, "signalReceived");
compare(msg.data.value, "test");
}
function test_grouping()
{
- loadUrl("grouping.html");
- awaitInit();
- awaitIdle();
+ var channel = client.createChannel(function(channel) {
+ channel.subscribe(Client.QWebChannelMessageTypes.propertyUpdate, function() {
+ channel.exec({label: "gotPropertyUpdate", values: [channel.objects.myObj.myProperty, channel.objects.myOtherObj.foo, channel.objects.myOtherObj.bar]});
+ });
+ });
+ client.awaitInit();
+ client.awaitIdle();
// change properties a lot, we expect this to be grouped into a single update notification
for (var i = 0; i < 10; ++i) {
@@ -183,81 +205,106 @@ WebChannelTest {
myOtherObj.bar = i;
}
- var msg = awaitMessage();
+ var msg = client.awaitMessage();
verify(msg);
compare(msg.data.label, "gotPropertyUpdate");
compare(msg.data.values, [myObj.myProperty, myOtherObj.foo, myOtherObj.bar]);
- awaitIdle();
+ client.awaitIdle();
}
function test_wrapper()
{
- loadUrl("wrapper.html");
- awaitInit();
-
- var msg = awaitMessageSkipIdle();
- compare(msg.data.type, qWebChannelMessageTypes.invokeMethod);
+ var channel = client.createChannel(function(channel) {
+ channel.objects.myFactory.create("testObj", function(obj) {
+ channel.objects["testObj"] = obj;
+ obj.mySignal.connect(function(arg1, arg2) {
+ channel.exec({label: "signalReceived", args: [arg1, arg2]});
+ });
+ obj.myProperty = 42;
+ obj.myMethod("foobar");
+ });
+ channel.subscribe("triggerDelete", function() {
+ channel.objects.testObj.deleteLater();
+ });
+ channel.subscribe("report", function() {
+ channel.exec({label:"report", obj: channel.objects.testObj})
+ });
+ });
+ client.awaitInit();
+
+ var msg = client.awaitMessageSkipIdle();
+ compare(msg.data.type, Client.QWebChannelMessageTypes.invokeMethod);
compare(msg.data.object, "myFactory");
verify(myFactory.lastObj);
compare(myFactory.lastObj.objectName, "testObj");
- msg = awaitMessageSkipIdle();
- compare(msg.data.type, qWebChannelMessageTypes.connectToSignal);
+ msg = client.awaitMessageSkipIdle();
+ compare(msg.data.type, Client.QWebChannelMessageTypes.connectToSignal);
verify(msg.data.object);
var objId = msg.data.object;
- msg = awaitMessageSkipIdle();
- compare(msg.data.type, qWebChannelMessageTypes.connectToSignal);
+ msg = client.awaitMessageSkipIdle();
+ compare(msg.data.type, Client.QWebChannelMessageTypes.connectToSignal);
compare(msg.data.object, objId);
- msg = awaitMessageSkipIdle();
- compare(msg.data.type, qWebChannelMessageTypes.setProperty);
+ msg = client.awaitMessageSkipIdle();
+ compare(msg.data.type, Client.QWebChannelMessageTypes.setProperty);
compare(msg.data.object, objId);
compare(myFactory.lastObj.myProperty, 42);
- msg = awaitMessageSkipIdle();
- compare(msg.data.type, qWebChannelMessageTypes.invokeMethod);
+ msg = client.awaitMessageSkipIdle();
+ compare(msg.data.type, Client.QWebChannelMessageTypes.invokeMethod);
compare(msg.data.object, objId);
compare(msg.data.args, ["foobar"]);
- msg = awaitMessageSkipIdle();
+ msg = client.awaitMessageSkipIdle();
compare(msg.data.label, "signalReceived");
compare(msg.data.args, ["foobar", 42]);
// pass QObject* on the fly and trigger deleteLater from client side
webChannel.sendMessage("triggerDelete");
- msg = awaitMessageSkipIdle();
- compare(msg.data.type, qWebChannelMessageTypes.invokeMethod);
+ msg = client.awaitMessageSkipIdle();
+ compare(msg.data.type, Client.QWebChannelMessageTypes.invokeMethod);
compare(msg.data.object, objId);
+ client.awaitIdle();
+
webChannel.sendMessage("report");
- msg = awaitMessageSkipIdle();
+ msg = client.awaitMessageSkipIdle();
compare(msg.data.label, "report");
compare(msg.data.obj, {});
}
function test_disconnect()
{
- loadUrl("disconnect.html");
- awaitInit();
-
- var msg = awaitMessage();
- compare(msg.data.type, qWebChannelMessageTypes.connectToSignal);
+ var channel = client.createChannel(function(channel) {
+ channel.objects.myObj.mySignal.connect(function(arg) {
+ channel.exec({label: "mySignalReceived", args: [arg]});
+ channel.objects.myObj.mySignal.disconnect(this);
+ });
+ channel.subscribe("report", function() {
+ channel.exec({label: "report"});
+ });
+ });
+ client.awaitInit();
+
+ var msg = client.awaitMessage();
+ compare(msg.data.type, Client.QWebChannelMessageTypes.connectToSignal);
compare(msg.data.object, "myObj");
- awaitIdle();
+ client.awaitIdle();
myObj.mySignal(42);
- msg = awaitMessage();
+ msg = client.awaitMessage();
compare(msg.data.label, "mySignalReceived");
compare(msg.data.args, [42]);
- msg = awaitMessage();
- compare(msg.data.type, qWebChannelMessageTypes.disconnectFromSignal);
+ msg = client.awaitMessage();
+ compare(msg.data.type, Client.QWebChannelMessageTypes.disconnectFromSignal);
compare(msg.data.object, "myObj");
myObj.mySignal(0);
@@ -266,7 +313,7 @@ WebChannelTest {
// and verify no mySignalReceived was triggered by the above emission
webChannel.sendMessage("report");
- msg = awaitMessage();
+ msg = client.awaitMessage();
compare(msg.data.label, "report");
}
}
diff --git a/tests/auto/qml/tst_multiclient.qml b/tests/auto/qml/tst_multiclient.qml
index 519a63c..6c4b9b7 100644
--- a/tests/auto/qml/tst_multiclient.qml
+++ b/tests/auto/qml/tst_multiclient.qml
@@ -40,12 +40,21 @@
****************************************************************************/
import QtQuick 2.0
+import QtTest 1.0
import QtWebChannel 1.0
+import "qrc:///qwebchannel/qwebchannel.js" as Client
-WebChannelTest {
+TestCase {
name: "MultiClient"
- id: test
+
+ Client {
+ id: client1
+ }
+
+ Client {
+ id: client2
+ }
QtObject {
id: foo
@@ -61,39 +70,50 @@ WebChannelTest {
WebChannel.id: "foo"
}
- TestWebView {
- id: client1
+ WebChannel {
+ id: webChannel
+ transports: [client1.serverTransport, client2.serverTransport]
+ registeredObjects: [foo]
}
- TestWebView {
- id: client2
+
+ function init()
+ {
+ client1.cleanup();
+ client2.cleanup();
}
- function initTestCase()
+ function clientInitCallback(channel)
{
- webChannel.registeredObjects = [foo];
+ channel.objects.foo.ping.connect(function() {
+ channel.objects.foo.pong(function(value) {
+ channel.exec({pongAnswer: value});
+ });
+ });
}
function test_multiclient()
{
- loadUrl("multiclient.html", client1);
- loadUrl("multiclient.html", client2);
+ var c1 = client1.createChannel(clientInitCallback);
+ var c2 = client2.createChannel(clientInitCallback);
+
// init, connect & idle messages for two clients
- for (var i = 0; i < 3 * 2; ++i) {
- awaitMessage();
+ for (var i = 0; i < 3; ++i) {
+ client1.awaitMessage();
+ client2.awaitMessage();
}
foo.ping();
// invoke of pong method
- awaitMessage();
- awaitMessage();
+ client1.awaitMessage();
+ client2.awaitMessage();
- var msg = awaitMessage();
+ var msg = client1.awaitMessage();
compare(msg.data.pongAnswer, 1);
- msg = awaitMessage();
+ msg = client2.awaitMessage();
compare(msg.data.pongAnswer, 2);
- awaitIdle();
- awaitIdle();
+ client1.awaitIdle();
+ client2.awaitIdle();
}
}
diff --git a/tests/auto/qml/tst_webchannel.qml b/tests/auto/qml/tst_webchannel.qml
index dddba71..3c404d3 100644
--- a/tests/auto/qml/tst_webchannel.qml
+++ b/tests/auto/qml/tst_webchannel.qml
@@ -40,20 +40,47 @@
****************************************************************************/
import QtQuick 2.0
+import QtTest 1.0
-WebChannelTest {
+import QtWebChannel 1.0
+import "qrc:///qwebchannel/qwebchannel.js" as Client
+
+TestCase {
name: "WebChannel"
+ Client {
+ id: client
+ }
+
+ WebChannel {
+ id: webChannel
+ transports: [client.serverTransport]
+ }
+
+ function cleanup()
+ {
+ client.cleanup();
+ }
+
function test_receiveRawMessage()
{
- loadUrl("receiveRaw.html");
- compare(awaitRawMessage(), "foobar");
+ var channel = client.createChannel(function (channel) {
+ channel.send("foobar");
+ }, true /* raw */);
+ compare(client.awaitRawMessage(), "foobar");
}
function test_sendMessage()
{
- loadUrl("send.html");
+ var channel = client.createChannel(function (channel) {
+ channel.subscribe("myMessage", function(payload) {
+ channel.send("myMessagePong:" + payload);
+ });
+ channel.send("initialized");
+ }, true /* raw */);
+
+ compare(client.awaitRawMessage(), "initialized");
webChannel.sendMessage("myMessage", "foobar");
- compare(awaitRawMessage(), "myMessagePong:foobar");
+ compare(client.awaitRawMessage(), "myMessagePong:foobar");
}
}
diff --git a/tests/auto/webchannel/tst_webchannel.cpp b/tests/auto/webchannel/tst_webchannel.cpp
index ece02a8..10baaa3 100644
--- a/tests/auto/webchannel/tst_webchannel.cpp
+++ b/tests/auto/webchannel/tst_webchannel.cpp
@@ -44,7 +44,6 @@
#include <qwebchannel.h>
#include <qwebchannel_p.h>
#include <qmetaobjectpublisher_p.h>
-#include <qwebsockettransport.h>
#include <QtTest>
@@ -76,20 +75,6 @@ void TestWebChannel::setVariant(const QVariant &v)
m_lastVariant = v;
}
-void TestWebChannel::testInitWebSocketTransport()
-{
- QWebSocketTransport transport;
- QSignalSpy initSpy(&transport, SIGNAL(initialized()));
- QSignalSpy baseUrlSpy(&transport, SIGNAL(baseUrlChanged(QString)));
-
- QVERIFY(initSpy.wait());
- QCOMPARE(initSpy.size(), 1);
- QCOMPARE(baseUrlSpy.size(), 1);
- QCOMPARE(baseUrlSpy.first().size(), 1);
- QCOMPARE(transport.baseUrl(), baseUrlSpy.first().first().toString());
- QVERIFY(!transport.baseUrl().isEmpty());
-}
-
void TestWebChannel::testRegisterObjects()
{
QWebChannel channel;
diff --git a/tests/auto/webchannel/tst_webchannel.h b/tests/auto/webchannel/tst_webchannel.h
index 314fe99..4811a5c 100644
--- a/tests/auto/webchannel/tst_webchannel.h
+++ b/tests/auto/webchannel/tst_webchannel.h
@@ -44,24 +44,22 @@
#include <QObject>
#include <QVariant>
-#include <qwebchanneltransportinterface.h>
-class DummyTransport : public QObject, public QWebChannelTransportInterface
+#include <QtWebChannel/QWebChannelAbstractTransport>
+
+class DummyTransport : public QWebChannelAbstractTransport
{
Q_OBJECT
- Q_INTERFACES(QWebChannelTransportInterface)
public:
explicit DummyTransport(QObject *parent)
- : QObject(parent)
+ : QWebChannelAbstractTransport(parent)
{}
~DummyTransport() {};
- void sendMessage(const QString &/*message*/, int /*clientId*/) const Q_DECL_OVERRIDE
- {}
- void sendMessage(const QByteArray &/*message*/, int /*clientId*/) const Q_DECL_OVERRIDE
- {}
- void setMessageHandler(QWebChannelMessageHandlerInterface * /*handler*/) Q_DECL_OVERRIDE
- {}
+public slots:
+ void sendTextMessage(const QString &/*message*/) Q_DECL_OVERRIDE
+ {
+ }
};
class TestObject : public QObject
@@ -216,7 +214,6 @@ public:
Q_INVOKABLE void setVariant(const QVariant &v);
private slots:
- void testInitWebSocketTransport();
void testRegisterObjects();
void testInfoForObject();
void testInvokeMethodConversion();