summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/common/qt_messages.h4
-rw-r--r--src/core/core_common.pri8
-rw-r--r--src/core/core_gyp_generator.pro11
-rw-r--r--src/core/core_module.pro6
-rw-r--r--src/core/renderer/content_renderer_client_qt.cpp8
-rw-r--r--src/core/renderer/web_channel_ipc_transport.cpp175
-rw-r--r--src/core/renderer/web_channel_ipc_transport.h59
-rw-r--r--src/core/web_channel_ipc_transport_host.cpp80
-rw-r--r--src/core/web_channel_ipc_transport_host.h65
-rw-r--r--src/core/web_contents_adapter.cpp28
-rw-r--r--src/core/web_contents_adapter.h8
-rw-r--r--src/core/web_contents_adapter_p.h4
-rw-r--r--src/webengine/api/qquickwebengineview.cpp18
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h5
-rw-r--r--sync.profile1
-rw-r--r--tests/auto/quick/qmltests/data/tst_webchannel.qml114
-rw-r--r--tests/auto/quick/qmltests/data/webchannel-test.html21
17 files changed, 601 insertions, 14 deletions
diff --git a/src/core/common/qt_messages.h b/src/core/common/qt_messages.h
index 315987cd..5ae5fef7 100644
--- a/src/core/common/qt_messages.h
+++ b/src/core/common/qt_messages.h
@@ -29,6 +29,8 @@ IPC_MESSAGE_ROUTED1(QtRenderViewObserver_FetchDocumentMarkup,
IPC_MESSAGE_ROUTED1(QtRenderViewObserver_FetchDocumentInnerText,
uint64 /* requestId */)
+IPC_MESSAGE_ROUTED1(WebChannelIPCTransport_Message, std::vector<char> /*binaryJSON*/)
+
//-----------------------------------------------------------------------------
// WebContents messages
// These are messages sent from the renderer back to the browser process.
@@ -42,3 +44,5 @@ IPC_MESSAGE_ROUTED2(QtRenderViewObserverHost_DidFetchDocumentInnerText,
base::string16 /* innerText */)
IPC_MESSAGE_ROUTED0(QtRenderViewObserverHost_DidFirstVisuallyNonEmptyLayout)
+
+IPC_MESSAGE_ROUTED1(WebChannelIPCTransportHost_SendMessage, std::vector<char> /*binaryJSON*/)
diff --git a/src/core/core_common.pri b/src/core/core_common.pri
new file mode 100644
index 00000000..2e9ee419
--- /dev/null
+++ b/src/core/core_common.pri
@@ -0,0 +1,8 @@
+# NOTE: The TARGET, QT, QT_PRIVATE variables are used in both core_module.pro and core_gyp_generator.pro
+# gyp/ninja will take care of the compilation, qmake/make will finish with linking and install.
+
+TARGET = QtWebEngineCore
+QT += qml quick webchannel
+QT_PRIVATE += quick-private gui-private core-private
+
+qtHaveModule(positioning):QT += positioning
diff --git a/src/core/core_gyp_generator.pro b/src/core/core_gyp_generator.pro
index 2ec2816c..3980dcc5 100644
--- a/src/core/core_gyp_generator.pro
+++ b/src/core/core_gyp_generator.pro
@@ -7,11 +7,7 @@ GYPINCLUDES += qtwebengine.gypi
TEMPLATE = lib
-# NOTE: The TARGET, QT, QT_PRIVATE variables must match those in core_module.pro.
-# gyp/ninja will take care of the compilation, qmake/make will finish with linking and install.
-TARGET = QtWebEngineCore
-QT += qml quick
-QT_PRIVATE += quick-private gui-private core-private
+include(core_common.pri)
# Defining keywords such as 'signal' clashes with the chromium code base.
DEFINES += QT_NO_KEYWORDS \
@@ -63,6 +59,7 @@ SOURCES = \
render_widget_host_view_qt.cpp \
renderer/content_renderer_client_qt.cpp \
renderer/qt_render_view_observer.cpp \
+ renderer/web_channel_ipc_transport.cpp \
resource_bundle_qt.cpp \
resource_context_qt.cpp \
resource_dispatcher_host_delegate_qt.cpp \
@@ -70,6 +67,7 @@ SOURCES = \
surface_factory_qt.cpp \
url_request_context_getter_qt.cpp \
url_request_qrc_job_qt.cpp \
+ web_channel_ipc_transport_host.cpp \
web_contents_adapter.cpp \
web_contents_delegate_qt.cpp \
web_contents_view_qt.cpp \
@@ -116,6 +114,7 @@ HEADERS = \
render_widget_host_view_qt_delegate.h \
renderer/content_renderer_client_qt.h \
renderer/qt_render_view_observer.h \
+ renderer/web_channel_ipc_transport.h \
resource_context_qt.h \
resource_dispatcher_host_delegate_qt.h \
stream_video_node.h \
@@ -123,6 +122,7 @@ HEADERS = \
type_conversion.h \
url_request_context_getter_qt.h \
url_request_qrc_job_qt.h \
+ web_channel_ipc_transport_host.h \
web_contents_adapter.h \
web_contents_adapter_client.h \
web_contents_adapter_p.h \
@@ -140,5 +140,4 @@ qtHaveModule(positioning) {
SOURCES += location_provider_qt.cpp
HEADERS += location_provider_qt.h
DEFINES += QT_USE_POSITIONING=1
- QT += positioning
}
diff --git a/src/core/core_module.pro b/src/core/core_module.pro
index e6933cc4..afa11d31 100644
--- a/src/core/core_module.pro
+++ b/src/core/core_module.pro
@@ -1,10 +1,6 @@
MODULE = webenginecore
-TARGET = QtWebEngineCore
-
-qtHaveModule(positioning):QT += positioning
-QT += qml quick
-QT_PRIVATE += quick-private gui-private core-private
+include(core_common.pri)
# Needed to set a CFBundleIdentifier
QMAKE_INFO_PLIST = Info_mac.plist
diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp
index a13a7999..f8970e7a 100644
--- a/src/core/renderer/content_renderer_client_qt.cpp
+++ b/src/core/renderer/content_renderer_client_qt.cpp
@@ -50,6 +50,7 @@
#include "ui/base/webui/jstemplate_builder.h"
#include "content/public/common/web_preferences.h"
+#include "renderer/web_channel_ipc_transport.h"
#include "renderer/qt_render_view_observer.h"
#include "grit/renderer_resources.h"
@@ -66,14 +67,17 @@ ContentRendererClientQt::~ContentRendererClientQt()
void ContentRendererClientQt::RenderThreadStarted()
{
+ content::RenderThread *renderThread = content::RenderThread::Get();
+ renderThread->RegisterExtension(WebChannelIPCTransport::getV8Extension());
m_visitedLinkSlave.reset(new visitedlink::VisitedLinkSlave);
- content::RenderThread::Get()->AddObserver(m_visitedLinkSlave.data());
+ renderThread->AddObserver(m_visitedLinkSlave.data());
}
void ContentRendererClientQt::RenderViewCreated(content::RenderView* render_view)
{
- // RenderViewObserver destroys itself with its RenderView.
+ // RenderViewObservers destroy themselves with their RenderView.
new QtRenderViewObserver(render_view);
+ new WebChannelIPCTransport(render_view);
}
bool ContentRendererClientQt::HasErrorPage(int httpStatusCode, std::string *errorDomain)
diff --git a/src/core/renderer/web_channel_ipc_transport.cpp b/src/core/renderer/web_channel_ipc_transport.cpp
new file mode 100644
index 00000000..0491a610
--- /dev/null
+++ b/src/core/renderer/web_channel_ipc_transport.cpp
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine 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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later 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 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "renderer/web_channel_ipc_transport.h"
+
+#include "common/qt_messages.h"
+
+#include "content/public/renderer/render_view.h"
+#include "third_party/WebKit/public/web/WebLocalFrame.h"
+#include "third_party/WebKit/public/web/WebView.h"
+#include "v8/include/v8.h"
+
+#include <QJsonDocument>
+
+static const char kWebChannelTransportExtensionName[] = "v8/WebChannelTransport";
+
+static const char kWebChannelTransportApi[] =
+ "if (typeof(navigator) === 'undefined')" \
+ " navigator = {};" \
+ "if (typeof(navigator.qtWebChannelTransport) === 'undefined')" \
+ " navigator.qtWebChannelTransport = {};" \
+ "navigator.qtWebChannelTransport.send = function(message) {" \
+ " native function NativeQtSendMessage();" \
+ " NativeQtSendMessage(message);" \
+ "};";
+
+class WebChannelTransportExtension : public v8::Extension {
+public:
+ static content::RenderView *GetRenderView();
+
+ WebChannelTransportExtension() : v8::Extension(kWebChannelTransportExtensionName, kWebChannelTransportApi)
+ {
+ }
+
+ virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate(v8::Isolate* isolate, v8::Handle<v8::String> name) Q_DECL_OVERRIDE;
+
+ static void NativeQtSendMessage(const v8::FunctionCallbackInfo<v8::Value>& args)
+ {
+ content::RenderView *renderView = GetRenderView();
+ if (!renderView || args.Length() != 1)
+ return;
+ v8::Handle<v8::Value> val = args[0];
+ if (!val->IsString() && !val->IsStringObject())
+ return;
+ v8::String::Utf8Value utf8(val->ToString());
+
+ QByteArray valueData(*utf8, utf8.length());
+ QJsonParseError error;
+ QJsonDocument doc = QJsonDocument::fromJson(valueData, &error);
+ if (error.error != QJsonParseError::NoError)
+ qWarning("%s %d: Parsing error: %s",__FILE__, __LINE__, qPrintable(error.errorString()));
+ int size = 0;
+ const char *rawData = doc.rawData(&size);
+ renderView->Send(new WebChannelIPCTransportHost_SendMessage(renderView->GetRoutingID(), std::vector<char>(rawData, rawData + size)));
+ }
+};
+
+content::RenderView *WebChannelTransportExtension::GetRenderView()
+{
+ blink::WebLocalFrame *webframe = blink::WebLocalFrame::frameForCurrentContext();
+ DCHECK(webframe) << "There should be an active frame since we just got a native function called.";
+ if (!webframe)
+ return 0;
+
+ blink::WebView *webview = webframe->view();
+ if (!webview)
+ return 0; // can happen during closing
+
+ return content::RenderView::FromWebView(webview);
+}
+
+v8::Handle<v8::FunctionTemplate> WebChannelTransportExtension::GetNativeFunctionTemplate(v8::Isolate *isolate, v8::Handle<v8::String> name)
+{
+ if (name->Equals(v8::String::NewFromUtf8(isolate, "NativeQtSendMessage")))
+ return v8::FunctionTemplate::New(isolate, NativeQtSendMessage);
+
+ return v8::Handle<v8::FunctionTemplate>();
+}
+
+WebChannelIPCTransport::WebChannelIPCTransport(content::RenderView *renderView)
+ : content::RenderViewObserver(renderView)
+{
+}
+
+void WebChannelIPCTransport::dispatchWebChannelMessage(const std::vector<char> &binaryJSON)
+{
+ blink::WebView *webView = render_view()->GetWebView();
+ if (!webView)
+ return;
+
+ QJsonDocument doc = QJsonDocument::fromRawData(binaryJSON.data(), binaryJSON.size(), QJsonDocument::BypassValidation);
+ Q_ASSERT(doc.isObject());
+ QByteArray json = doc.toJson(QJsonDocument::Compact);
+
+ v8::Isolate *isolate = v8::Isolate::GetCurrent();
+ v8::HandleScope handleScope(isolate);
+ blink::WebFrame *frame = webView->mainFrame();
+ v8::Handle<v8::Context> context = frame->mainWorldScriptContext();
+ v8::Context::Scope contextScope(context);
+
+ v8::Handle<v8::Object> global(context->Global());
+ v8::Handle<v8::Value> navigatorValue(global->Get(v8::String::NewFromUtf8(isolate, "navigator")));
+ if (!navigatorValue->IsObject())
+ return;
+ v8::Handle<v8::Value> navigatorQtValue(navigatorValue->ToObject()->Get(v8::String::NewFromUtf8(isolate, "qtWebChannelTransport")));
+ if (!navigatorQtValue->IsObject())
+ return;
+ v8::Handle<v8::Value> onmessageCallbackValue(navigatorQtValue->ToObject()->Get(v8::String::NewFromUtf8(isolate, "onmessage")));
+ if (!onmessageCallbackValue->IsFunction()) {
+ qWarning("onmessage is not a callable property of navigator.qtWebChannelTransport. Some things might not work as expected.");
+ return;
+ }
+
+ v8::Handle<v8::Object> messageObject(v8::Object::New(isolate));
+ messageObject->ForceSet(v8::String::NewFromUtf8(isolate, "data")
+ , v8::String::NewFromUtf8(isolate, json.constData(), v8::String::kNormalString, json.size())
+ , v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete));
+
+ v8::Handle<v8::Function> callback = v8::Handle<v8::Function>::Cast(onmessageCallbackValue);
+ const int argc = 1;
+ v8::Handle<v8::Value> argv[argc];
+ argv[0] = messageObject;
+ frame->callFunctionEvenIfScriptDisabled(callback, navigatorQtValue->ToObject(), argc, argv);
+}
+
+v8::Extension *WebChannelIPCTransport::getV8Extension()
+{
+ return new WebChannelTransportExtension;
+}
+
+bool WebChannelIPCTransport::OnMessageReceived(const IPC::Message &message)
+{
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(WebChannelIPCTransport, message)
+ IPC_MESSAGE_HANDLER(WebChannelIPCTransport_Message, dispatchWebChannelMessage)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
diff --git a/src/core/renderer/web_channel_ipc_transport.h b/src/core/renderer/web_channel_ipc_transport.h
new file mode 100644
index 00000000..29e819e9
--- /dev/null
+++ b/src/core/renderer/web_channel_ipc_transport.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine 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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later 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 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef NAVIGATOR_QT_EXTENSION_H
+#define NAVIGATOR_QT_EXTENSION_H
+
+#include "base/values.h"
+#include "content/public/renderer/render_view_observer.h"
+#include <QtCore/qcompilerdetection.h>
+
+namespace v8 {
+class Extension;
+}
+
+class WebChannelIPCTransport : public content::RenderViewObserver {
+public:
+ static v8::Extension* getV8Extension();
+
+ WebChannelIPCTransport(content::RenderView *);
+
+private:
+ void dispatchWebChannelMessage(const std::vector<char> &binaryJSON);
+ virtual bool OnMessageReceived(const IPC::Message &message) Q_DECL_OVERRIDE;
+};
+
+#endif // NAVIGATOR_QT_EXTENSION_H
diff --git a/src/core/web_channel_ipc_transport_host.cpp b/src/core/web_channel_ipc_transport_host.cpp
new file mode 100644
index 00000000..d940aeab
--- /dev/null
+++ b/src/core/web_channel_ipc_transport_host.cpp
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine 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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later 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 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "web_channel_ipc_transport_host.h"
+
+#include "base/strings/string16.h"
+
+#include "common/qt_messages.h"
+#include "type_conversion.h"
+
+#include <QJsonDocument>
+#include <QJsonObject>
+
+WebChannelIPCTransportHost::WebChannelIPCTransportHost(content::WebContents *contents, QObject *parent)
+ : QWebChannelAbstractTransport(parent)
+ , content::WebContentsObserver(contents)
+{
+}
+
+WebChannelIPCTransportHost::~WebChannelIPCTransportHost()
+{
+}
+
+void WebChannelIPCTransportHost::sendMessage(const QJsonObject &message)
+{
+ QJsonDocument doc(message);
+ int size = 0;
+ const char *rawData = doc.rawData(&size);
+ Send(new WebChannelIPCTransport_Message(routing_id(), std::vector<char>(rawData, rawData + size)));
+}
+
+void WebChannelIPCTransportHost::onWebChannelMessage(const std::vector<char> &message)
+{
+ QJsonDocument doc = QJsonDocument::fromRawData(message.data(), message.size(), QJsonDocument::BypassValidation);
+ Q_ASSERT(doc.isObject());
+ Q_EMIT messageReceived(doc.object(), this);
+}
+
+bool WebChannelIPCTransportHost::OnMessageReceived(const IPC::Message &message)
+{
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(WebChannelIPCTransportHost, message)
+ IPC_MESSAGE_HANDLER(WebChannelIPCTransportHost_SendMessage, onWebChannelMessage)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
diff --git a/src/core/web_channel_ipc_transport_host.h b/src/core/web_channel_ipc_transport_host.h
new file mode 100644
index 00000000..d51ebba2
--- /dev/null
+++ b/src/core/web_channel_ipc_transport_host.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine 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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later 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 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WEB_CHANNEL_IPC_TRANSPORT_H
+#define WEB_CHANNEL_IPC_TRANSPORT_H
+
+
+#include <QtWebChannel/QWebChannelAbstractTransport>
+#include "content/public/browser/web_contents_observer.h"
+
+#include "qtwebenginecoreglobal.h"
+#include <QtCore/QObject>
+
+
+QT_FORWARD_DECLARE_CLASS(QString)
+
+class WebChannelIPCTransportHost : public QWebChannelAbstractTransport
+ , public content::WebContentsObserver
+{
+public:
+ WebChannelIPCTransportHost(content::WebContents *, QObject *parent = 0);
+ virtual ~WebChannelIPCTransportHost();
+
+ // QWebChannelAbstractTransport
+ virtual void sendMessage(const QJsonObject &message) Q_DECL_OVERRIDE;
+
+private:
+ bool OnMessageReceived(const IPC::Message& message) Q_DECL_OVERRIDE;
+ void onWebChannelMessage(const std::vector<char> &message);
+};
+
+#endif // WEB_CHANNEL_IPC_TRANSPORT_H
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 249f9204..306de1a4 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -49,6 +49,7 @@
#include "media_capture_devices_dispatcher.h"
#include "qt_render_view_observer_host.h"
#include "type_conversion.h"
+#include "web_channel_ipc_transport_host.h"
#include "web_contents_adapter_client.h"
#include "web_contents_view_qt.h"
#include "web_engine_context.h"
@@ -77,6 +78,7 @@
#include <QStyleHints>
#include <QVariant>
#include <QtGui/qaccessible.h>
+#include <QtWebChannel/QWebChannel>
static const int kTestWindowWidth = 800;
static const int kTestWindowHeight = 600;
@@ -320,6 +322,8 @@ class LoadRecursionGuard {
WebContentsAdapterPrivate::WebContentsAdapterPrivate()
// This has to be the first thing we create, and the last we destroy.
: engineContext(WebEngineContext::current())
+ , webChannel(0)
+ , adapterClient(0)
, nextRequestId(1)
, lastFindRequestId(0)
{
@@ -830,3 +834,27 @@ content::WebContents *WebContentsAdapter::webContents() const
Q_D(const WebContentsAdapter);
return d->webContents.get();
}
+
+QWebChannel *WebContentsAdapter::webChannel() const
+{
+ Q_D(const WebContentsAdapter);
+ return d->webChannel;
+}
+
+void WebContentsAdapter::setWebChannel(QWebChannel *channel)
+{
+ Q_D(WebContentsAdapter);
+ if (d->webChannel == channel)
+ return;
+ if (!d->webChannelTransport.get())
+ d->webChannelTransport.reset(new WebChannelIPCTransportHost(d->webContents.get()));
+ else
+ d->webChannel->disconnectFrom(d->webChannelTransport.get());
+
+ d->webChannel = channel;
+ if (!channel) {
+ d->webChannelTransport.reset();
+ return;
+ }
+ channel->connectTo(d->webChannelTransport.get());
+}
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index 3c4ad997..6ba7c4b0 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -50,9 +50,13 @@ class WebContents;
struct WebPreferences;
}
class BrowserContextQt;
+class MessagePassingInterface;
class WebContentsAdapterPrivate;
-QT_FORWARD_DECLARE_CLASS(QAccessibleInterface);
+QT_BEGIN_NAMESPACE
+class QAccessibleInterface;
+class QWebChannel;
+QT_END_NAMESPACE
class QWEBENGINE_EXPORT WebContentsAdapter : public QSharedData {
public:
@@ -115,6 +119,8 @@ public:
QAccessibleInterface *browserAccessible();
BrowserContextQt* browserContext();
BrowserContextAdapter* browserContextAdapter();
+ QWebChannel *webChannel() const;
+ void setWebChannel(QWebChannel *);
// meant to be used within WebEngineCore only
content::WebContents *webContents() const;
diff --git a/src/core/web_contents_adapter_p.h b/src/core/web_contents_adapter_p.h
index f47c05de..dcdf97f2 100644
--- a/src/core/web_contents_adapter_p.h
+++ b/src/core/web_contents_adapter_p.h
@@ -46,9 +46,11 @@
class BrowserContextAdapter;
class QtRenderViewObserverHost;
+class WebChannelIPCTransportHost;
class WebContentsAdapterClient;
class WebContentsDelegateQt;
class WebEngineContext;
+QT_FORWARD_DECLARE_CLASS(QWebChannel)
class WebContentsAdapterPrivate {
public:
@@ -59,6 +61,8 @@ public:
scoped_ptr<content::WebContents> webContents;
scoped_ptr<WebContentsDelegateQt> webContentsDelegate;
scoped_ptr<QtRenderViewObserverHost> renderViewObserverHost;
+ scoped_ptr<WebChannelIPCTransportHost> webChannelTransport;
+ QWebChannel *webChannel;
WebContentsAdapterClient *adapterClient;
quint64 nextRequestId;
int lastFindRequestId;
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index c6c67ff0..a47defb7 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -61,6 +61,7 @@
#include <QQmlContext>
#include <QQmlEngine>
#include <QQmlProperty>
+#include <QQmlWebChannel>
#include <QScreen>
#include <QStringBuilder>
#include <QUrl>
@@ -811,6 +812,23 @@ QQuickWebEngineHistory *QQuickWebEngineViewExperimental::navigationHistory() con
return d_ptr->m_history.data();
}
+QQmlWebChannel *QQuickWebEngineViewExperimental::webChannel() const
+{
+ d_ptr->ensureContentsAdapter();
+ QQmlWebChannel *qmlWebChannel = qobject_cast<QQmlWebChannel *>(d_ptr->adapter->webChannel());
+ Q_ASSERT(!d_ptr->adapter->webChannel() || qmlWebChannel);
+ if (!qmlWebChannel) {
+ qmlWebChannel = new QQmlWebChannel;
+ d_ptr->adapter->setWebChannel(qmlWebChannel);
+ }
+ return qmlWebChannel;
+}
+
+void QQuickWebEngineViewExperimental::setWebChannel(QQmlWebChannel *webChannel)
+{
+ d_ptr->adapter->setWebChannel(webChannel);
+}
+
void QQuickWebEngineViewExperimental::grantFeaturePermission(const QUrl &securityOrigin, QQuickWebEngineViewExperimental::Feature feature, bool granted)
{
if (!d_ptr->adapter)
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index 48eb25cb..d7785092 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -55,6 +55,7 @@ class QQuickWebEngineView;
class QQmlComponent;
class QQmlContext;
class QQuickWebEngineSettings;
+class QQmlWebChannel;
class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineViewport : public QObject {
Q_OBJECT
@@ -80,6 +81,7 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineViewExperimental : public QObjec
Q_PROPERTY(QQmlComponent *extraContextMenuEntriesComponent READ extraContextMenuEntriesComponent WRITE setExtraContextMenuEntriesComponent NOTIFY extraContextMenuEntriesComponentChanged)
Q_PROPERTY(bool isFullScreen READ isFullScreen WRITE setIsFullScreen NOTIFY isFullScreenChanged)
Q_PROPERTY(QQuickWebEngineHistory *navigationHistory READ navigationHistory CONSTANT FINAL)
+ Q_PROPERTY(QQmlWebChannel *webChannel READ webChannel WRITE setWebChannel)
Q_ENUMS(Feature)
Q_FLAGS(FindFlags)
@@ -103,6 +105,9 @@ public:
void setExtraContextMenuEntriesComponent(QQmlComponent *);
QQmlComponent *extraContextMenuEntriesComponent() const;
QQuickWebEngineHistory *navigationHistory() const;
+ QQuickWebEngineSettings *settings() const;
+ QQmlWebChannel *webChannel() const;
+ void setWebChannel(QQmlWebChannel *);
public Q_SLOTS:
void goBackTo(int index);
diff --git a/sync.profile b/sync.profile
index 1e9519fe..774941d5 100644
--- a/sync.profile
+++ b/sync.profile
@@ -21,4 +21,5 @@
"qtxmlpatterns" => "",
# FIXME: take examples out into their own module to avoid a potential circular dependency later ?
"qtquickcontrols" => "",
+ "qtwebchannel" => "",
);
diff --git a/tests/auto/quick/qmltests/data/tst_webchannel.qml b/tests/auto/quick/qmltests/data/tst_webchannel.qml
new file mode 100644
index 00000000..1abb191e
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_webchannel.qml
@@ -0,0 +1,114 @@
+/*********************************************************************
+** 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.0
+import QtTest 1.0
+import QtWebEngine 1.0
+import QtWebEngine.experimental 1.0
+
+import QtWebChannel 1.0
+
+Item {
+ id: test
+ signal barCalled(var arg)
+ signal clientInitializedCalled(var arg)
+
+ QtObject {
+ id: testObject
+ WebChannel.id: "testObject"
+
+ property var foo: 42
+
+ function clientInitialized(arg)
+ {
+ clientInitializedCalled(arg);
+ }
+
+ function bar(arg) {
+ barCalled(arg);
+ }
+
+ signal runTest(var foo)
+ }
+
+ TestWebEngineView {
+ id: webView
+ experimental.webChannel.registeredObjects: [testObject]
+ }
+
+ SignalSpy {
+ id: initializedSpy
+ target: test
+ signalName: "clientInitializedCalled"
+ }
+
+ SignalSpy {
+ id: barSpy
+ target: test
+ signalName: "barCalled"
+ }
+
+ TestCase {
+ name: "WebViewWebChannel"
+ property url testUrl: Qt.resolvedUrl("./webchannel-test.html")
+
+ function init() {
+ initializedSpy.clear();
+ barSpy.clear();
+ }
+
+ function test_basic() {
+ webView.url = testUrl;
+ verify(webView.waitForLoadSucceeded());
+
+ initializedSpy.wait();
+ compare(initializedSpy.signalArguments.length, 1);
+ compare(initializedSpy.signalArguments[0][0], 42);
+
+ var newValue = "roundtrip";
+ testObject.runTest(newValue);
+ barSpy.wait();
+ compare(barSpy.signalArguments.length, 1);
+ compare(barSpy.signalArguments[0][0], newValue);
+
+ compare(testObject.foo, newValue);
+ }
+ }
+}
diff --git a/tests/auto/quick/qmltests/data/webchannel-test.html b/tests/auto/quick/qmltests/data/webchannel-test.html
new file mode 100644
index 00000000..94082120
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/webchannel-test.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script>
+ <script type="text/javascript">
+ //BEGIN SETUP
+ var channel = new QWebChannel(navigator.qtWebChannelTransport, function(channel) {
+ window.testObject = channel.objects.testObject;
+ testObject.runTest.connect(function(foo) {
+ testObject.foo = foo;
+ testObject.bar(foo);
+ });
+ testObject.clientInitialized(testObject.foo);
+ });
+ //END SETUP
+ </script>
+ </head>
+ <body>
+ </body>
+</html>