summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/android/qandroidwebview.cpp31
-rw-r--r--src/plugins/android/qandroidwebview_p.h11
-rw-r--r--src/plugins/darwin/qdarwinwebview.mm11
-rw-r--r--src/plugins/darwin/qdarwinwebview_p.h5
-rw-r--r--src/plugins/wasm/qwasmwebview.cpp7
-rw-r--r--src/plugins/wasm/qwasmwebview_p.h5
-rw-r--r--src/plugins/webengine/qwebenginewebview.cpp6
-rw-r--r--src/plugins/webengine/qwebenginewebview_p.h10
-rw-r--r--src/plugins/windows/qwebview2webview.cpp22
-rw-r--r--src/plugins/windows/qwebview2webview_p.h5
-rw-r--r--src/quick/qquickwebview.cpp51
-rw-r--r--src/quick/qquickwebview_p.h6
-rw-r--r--src/webview/qwebview.cpp6
-rw-r--r--src/webview/qwebview.h7
-rw-r--r--src/webview/qwebview_p.h3
-rw-r--r--tests/auto/webview/qwebview/tst_qwebview.cpp19
16 files changed, 101 insertions, 104 deletions
diff --git a/src/plugins/android/qandroidwebview.cpp b/src/plugins/android/qandroidwebview.cpp
index ee33e2c..42cddc0 100644
--- a/src/plugins/android/qandroidwebview.cpp
+++ b/src/plugins/android/qandroidwebview.cpp
@@ -190,19 +190,19 @@ QString QAndroidWebViewPrivate::title() const
return m_viewController.callMethod<QString>("getTitle");
}
-void QAndroidWebViewPrivate::runJavaScriptPrivate(const QString &script,
- int callbackId)
+void QAndroidWebViewPrivate::runJavaScript(
+ const QString &script, const std::function<void(const QVariant &)> &resultCallback)
{
if (QtAndroidPrivate::androidSdkVersion() < 19) {
qWarning("runJavaScript() requires API level 19 or higher.");
- if (callbackId == -1)
- return;
-
- // Emit signal here to remove the callback.
- emit q_ptr->javaScriptResult(callbackId, QVariant());
+ if (resultCallback)
+ resultCallback(QVariant());
+ return;
}
- m_viewController.callMethod<void>("runJavaScript", script, jlong(callbackId));
+ m_callbacks.insert(m_callbackId, resultCallback);
+ m_viewController.callMethod<void>("runJavaScript", script, jlong(m_callbackId));
+ ++m_callbackId;
}
QWebViewSettingsPrivate *QAndroidWebViewPrivate::settings() const
@@ -259,6 +259,17 @@ void QAndroidWebViewPrivate::onApplicationStateChanged(Qt::ApplicationState stat
m_viewController.callMethod<void>("onPause");
}
+void QAndroidWebViewPrivate::javaScriptResult(int id, const QVariant &result)
+{
+ auto it = m_callbacks.find(id);
+ if (it != m_callbacks.end()) {
+ auto callback = it.value();
+ if (callback)
+ callback(result);
+ m_callbacks.erase(it);
+ }
+}
+
static void c_onRunJavaScriptResult(JNIEnv *env,
jobject thiz,
jlong id,
@@ -285,8 +296,8 @@ static void c_onRunJavaScriptResult(JNIEnv *env,
jsonValue = object.value(QStringLiteral("data"));
}
- emit wc->q_ptr->javaScriptResult(int(callbackId),
- jsonValue.isNull() ? resultString : jsonValue.toVariant());
+ wc->javaScriptResult(int(callbackId),
+ jsonValue.isNull() ? resultString : jsonValue.toVariant());
}
Q_DECLARE_JNI_NATIVE_METHOD(c_onRunJavaScriptResult)
diff --git a/src/plugins/android/qandroidwebview_p.h b/src/plugins/android/qandroidwebview_p.h
index 1cacd19..5a8d229 100644
--- a/src/plugins/android/qandroidwebview_p.h
+++ b/src/plugins/android/qandroidwebview_p.h
@@ -80,16 +80,21 @@ public:
void deleteCookie(const QString &domain, const QString &name) override;
void deleteAllCookies() override;
+ void runJavaScript(const QString &script,
+ const std::function<void(const QVariant &)> &resultCallback) override;
+
+ void javaScriptResult(int id, const QVariant &result);
+
protected:
- void runJavaScriptPrivate(const QString& script,
- int callbackId) override;
QWebViewSettingsPrivate *settings() const override;
private Q_SLOTS:
void onApplicationStateChanged(Qt::ApplicationState state);
private:
- quint64 m_callbackId;
+ int m_callbackId;
+ QMap<int, std::function<void(const QVariant &)>> m_callbacks;
+
QWindow *m_window;
QtJniTypes::WebViewController m_viewController;
QtJniTypes::WebView m_webView;
diff --git a/src/plugins/darwin/qdarwinwebview.mm b/src/plugins/darwin/qdarwinwebview.mm
index 967eaa0..0727768 100644
--- a/src/plugins/darwin/qdarwinwebview.mm
+++ b/src/plugins/darwin/qdarwinwebview.mm
@@ -460,13 +460,16 @@ QVariant fromJSValue(id result)
return QVariant();
}
-void QDarwinWebViewPrivate::runJavaScriptPrivate(const QString &script, int callbackId)
+void QDarwinWebViewPrivate::runJavaScript(
+ const QString &script, const std::function<void(const QVariant &)> &resultCallback)
{
+ std::function<void(const QVariant &)> callbackCopy = resultCallback;
QPointer<QDarwinWebViewPrivate> observer(this);
[wkWebView evaluateJavaScript:script.toNSString()
- completionHandler:^(id result, NSError *) {
- if (callbackId != -1 && observer)
- emit q_ptr->javaScriptResult(callbackId, fromJSValue(result));
+ completionHandler:^(id result, NSError *error) {
+ QVariant r = error ? QVariant() : fromJSValue(result);
+ if (callbackCopy && observer)
+ callbackCopy(r);
}];
}
diff --git a/src/plugins/darwin/qdarwinwebview_p.h b/src/plugins/darwin/qdarwinwebview_p.h
index a7d8b83..a23e12c 100644
--- a/src/plugins/darwin/qdarwinwebview_p.h
+++ b/src/plugins/darwin/qdarwinwebview_p.h
@@ -82,9 +82,8 @@ public:
void deleteCookie(const QString &domain, const QString &name) override;
void deleteAllCookies() override;
-protected:
- void runJavaScriptPrivate(const QString& script,
- int callbackId) override;
+ void runJavaScript(const QString &script,
+ const std::function<void(const QVariant &)> &resultCallback) override;
public:
WKWebView *wkWebView;
diff --git a/src/plugins/wasm/qwasmwebview.cpp b/src/plugins/wasm/qwasmwebview.cpp
index ca93c5e..31a7579 100644
--- a/src/plugins/wasm/qwasmwebview.cpp
+++ b/src/plugins/wasm/qwasmwebview.cpp
@@ -195,11 +195,12 @@ void QWasmWebViewPrivate::deleteAllCookies()
qWarning("deleteAllCookies() not supported on this platform");
}
-void QWasmWebViewPrivate::runJavaScriptPrivate(const QString &script, int callbackId)
+void QWasmWebViewPrivate::runJavaScript(const QString &script,
+ const std::function<void(const QVariant &)> &resultCallback)
{
Q_UNUSED(script);
- Q_UNUSED(callbackId);
- qWarning("runJavaScriptPrivate() not supported on this platform");
+ Q_UNUSED(resultCallback);
+ qWarning("runJavaScript() not supported on this platform");
}
QWebViewSettingsPrivate *QWasmWebViewPrivate::settings() const
diff --git a/src/plugins/wasm/qwasmwebview_p.h b/src/plugins/wasm/qwasmwebview_p.h
index 6695f66..bb251ed 100644
--- a/src/plugins/wasm/qwasmwebview_p.h
+++ b/src/plugins/wasm/qwasmwebview_p.h
@@ -76,9 +76,10 @@ public:
void deleteCookie(const QString &domain, const QString &name) final;
void deleteAllCookies() final;
+ void runJavaScript(const QString &script,
+ const std::function<void(const QVariant &)> &resultCallback) final;
+
protected:
- void runJavaScriptPrivate(const QString& script,
- int callbackId) final;
QWebViewSettingsPrivate *settings() const final;
private:
diff --git a/src/plugins/webengine/qwebenginewebview.cpp b/src/plugins/webengine/qwebenginewebview.cpp
index 8dd3421..2c58a2f 100644
--- a/src/plugins/webengine/qwebenginewebview.cpp
+++ b/src/plugins/webengine/qwebenginewebview.cpp
@@ -121,10 +121,10 @@ QString QWebEngineWebViewPrivate::title() const
return m_webEngineView->title();
}
-void QWebEngineWebViewPrivate::runJavaScriptPrivate(const QString &script,
- int callbackId)
+void QWebEngineWebViewPrivate::runJavaScript(
+ const QString &script, const std::function<void(const QVariant &)> &resultCallback)
{
- m_webEngineView->runJavaScript(script, QQuickWebView::takeCallback(callbackId));
+ m_webEngineView->runJavaScript(script, resultCallback);
}
void QWebEngineWebViewPrivate::setCookie(const QString &domain, const QString &name, const QString &value)
diff --git a/src/plugins/webengine/qwebenginewebview_p.h b/src/plugins/webengine/qwebenginewebview_p.h
index 4681f16..a73c712 100644
--- a/src/plugins/webengine/qwebenginewebview_p.h
+++ b/src/plugins/webengine/qwebenginewebview_p.h
@@ -22,12 +22,12 @@
#include <QtQml/qqmlcomponent.h>
-#include <private/qwebview_p.h>
+#include <QtWebView/private/qwebview_p.h>
#include <QtWebEngineQuick/QQuickWebEngineProfile>
#include <QtWebEngineQuick/private/qquickwebenginesettings_p.h>
#include <QtCore/qpointer.h>
-
+#include <QVariant>
QT_BEGIN_NAMESPACE
class QQuickItem;
@@ -84,7 +84,6 @@ public:
QWebViewSettingsPrivate *settings() const override;
QWindow *nativeWindow() const override { return nullptr; }
-public Q_SLOTS:
void goBack() override;
void goForward() override;
void reload() override;
@@ -94,6 +93,8 @@ public Q_SLOTS:
const QString &value) override;
void deleteCookie(const QString &domain, const QString &name) override;
void deleteAllCookies() override;
+ void runJavaScript(const QString &script,
+ const std::function<void(const QVariant &)> &resultCallback) override;
private Q_SLOTS:
void q_urlChanged();
@@ -105,9 +106,6 @@ private Q_SLOTS:
void q_cookieAdded(const QNetworkCookie &cookie);
void q_cookieRemoved(const QNetworkCookie &cookie);
-protected:
- void runJavaScriptPrivate(const QString& script,
- int callbackId) override;
private:
friend class QWebEngineWebViewSettingsPrivate;
diff --git a/src/plugins/windows/qwebview2webview.cpp b/src/plugins/windows/qwebview2webview.cpp
index 204d9d8..205f7bb 100644
--- a/src/plugins/windows/qwebview2webview.cpp
+++ b/src/plugins/windows/qwebview2webview.cpp
@@ -637,14 +637,15 @@ void QWebView2WebViewPrivate::updateWindowGeometry()
}
}
-void QWebView2WebViewPrivate::runJavaScriptPrivate(const QString &script, int callbackId)
+void QWebView2WebViewPrivate::runJavaScript(
+ const QString &script, const std::function<void(const QVariant &)> &resultCallback)
{
if (m_webview) {
- const HRESULT hr = m_webview->ExecuteScript(
+ m_webview->ExecuteScript(
(wchar_t *)script.utf16(),
Microsoft::WRL::Callback<ICoreWebView2ExecuteScriptCompletedHandler>(
- [this, callbackId](HRESULT errorCode,
- LPCWSTR resultObjectAsJson) -> HRESULT {
+ [this, resultCallback](HRESULT errorCode,
+ LPCWSTR resultObjectAsJson) -> HRESULT {
QString resultStr = QString::fromWCharArray(resultObjectAsJson);
QJsonParseError parseError;
@@ -664,15 +665,16 @@ void QWebView2WebViewPrivate::runJavaScriptPrivate(const QString &script, int ca
resultVariant = val.toVariant();
}
}
- if (errorCode != S_OK)
- emit q_ptr->javaScriptResult(callbackId,
- qt_error_string(errorCode));
- else
- emit q_ptr->javaScriptResult(callbackId, resultVariant);
+ QVariant r =
+ errorCode == S_OK ? resultVariant : qt_error_string(errorCode);
+ if (resultCallback)
+ resultCallback(r);
return errorCode;
})
.Get());
- Q_ASSERT_SUCCEEDED(hr);
+ } else {
+ if (resultCallback)
+ resultCallback(QVariant());
}
}
diff --git a/src/plugins/windows/qwebview2webview_p.h b/src/plugins/windows/qwebview2webview_p.h
index 60201f0..2b00277 100644
--- a/src/plugins/windows/qwebview2webview_p.h
+++ b/src/plugins/windows/qwebview2webview_p.h
@@ -86,8 +86,10 @@ public:
void setCookie(const QString &domain, const QString &name, const QString &value) override;
void deleteCookie(const QString &domain, const QString &name) override;
void deleteAllCookies() override;
+ void runJavaScript(const QString &script,
+ const std::function<void(const QVariant &)> &resultCallback) override;
-private Q_SLOTS:
+private:
HRESULT onNavigationStarting(ICoreWebView2* webview, ICoreWebView2NavigationStartingEventArgs* args);
HRESULT onNavigationCompleted(ICoreWebView2* webview, ICoreWebView2NavigationCompletedEventArgs* args);
HRESULT onWebResourceRequested(ICoreWebView2* sender, ICoreWebView2WebResourceRequestedEventArgs* args);
@@ -97,7 +99,6 @@ private Q_SLOTS:
void initialize(HWND hWnd);
protected:
- void runJavaScriptPrivate(const QString &script, int callbackId) override;
QWebViewSettingsPrivate *settings() const override;
private:
diff --git a/src/quick/qquickwebview.cpp b/src/quick/qquickwebview.cpp
index 2d67df6..3dc1ed8 100644
--- a/src/quick/qquickwebview.cpp
+++ b/src/quick/qquickwebview.cpp
@@ -72,7 +72,6 @@ QQuickWebView::QQuickWebView(QQuickItem *parent)
connect(m_webView, &QWebView::urlChanged, this, &QQuickWebView::urlChanged);
connect(m_webView, &QWebView::loadProgressChanged, this, &QQuickWebView::loadProgressChanged);
connect(m_webView, &QWebView::loadingChanged, this, &QQuickWebView::onLoadingChanged);
- connect(m_webView, &QWebView::javaScriptResult, this, &QQuickWebView::onRunJavaScriptResult);
connect(m_webView, &QWebView::httpUserAgentChanged, this, &QQuickWebView::httpUserAgentChanged);
connect(m_webView, &QWebView::cookieAdded, this, &QQuickWebView::cookieAdded);
connect(m_webView, &QWebView::cookieRemoved, this, &QQuickWebView::cookieRemoved);
@@ -272,13 +271,24 @@ void QQuickWebView::loadHtml(const QString &html, const QUrl &baseUrl)
*/
void QQuickWebView::runJavaScript(const QString &script, const QJSValue &callback)
{
- const int callbackId = callback.isCallable() ? callbacks->insertCallback(callback) : -1;
- runJavaScriptPrivate(script, callbackId);
-}
-
-void QQuickWebView::runJavaScriptPrivate(const QString &script, int callbackId)
-{
- m_webView->runJavaScriptPrivate(script, callbackId);
+ if (callback.isCallable()) {
+ int callbackId = callbacks->insertCallback(callback);
+ QPointer<QQmlEngine> weakEngine = qmlEngine(this);
+ m_webView->runJavaScript(script, [callbackId, weakEngine](const QVariant &result) {
+ QJSValue callback = callbacks->takeCallback(callbackId);
+ if (!weakEngine) {
+ qWarning("No JavaScript engine, unable to handle JavaScript callback!");
+ return;
+ }
+
+ Q_ASSERT(callback.isCallable());
+ QJSValueList args;
+ args.append(weakEngine->toScriptValue(result));
+ callback.call(args);
+ });
+ } else {
+ m_webView->runJavaScript(script);
+ }
}
/*!
@@ -333,37 +343,12 @@ void QQuickWebView::deleteAllCookies()
m_webView->deleteAllCookies();
}
-void QQuickWebView::onRunJavaScriptResult(int id, const QVariant &variant)
-{
- if (id == -1)
- return;
-
- QJSValue callback = callbacks->takeCallback(id);
- if (callback.isUndefined())
- return;
-
- QQmlEngine *engine = qmlEngine(this);
- if (engine == 0) {
- qWarning("No JavaScript engine, unable to handle JavaScript callback!");
- return;
- }
-
- QJSValueList args;
- args.append(engine->toScriptValue(variant));
- callback.call(args);
-}
-
void QQuickWebView::onLoadingChanged(const QWebViewLoadRequest &loadRequest)
{
QQuickWebViewLoadRequest qqLoadRequest(loadRequest);
Q_EMIT loadingChanged(&qqLoadRequest);
}
-QJSValue QQuickWebView::takeCallback(int id)
-{
- return callbacks->takeCallback(id);
-}
-
/*!
\qmlproperty WebViewSettings WebView::settings
\readonly
diff --git a/src/quick/qquickwebview_p.h b/src/quick/qquickwebview_p.h
index 4e8d5c7..8cd9752 100644
--- a/src/quick/qquickwebview_p.h
+++ b/src/quick/qquickwebview_p.h
@@ -93,17 +93,11 @@ Q_SIGNALS:
Q_REVISION(6, 3) void cookieAdded(const QString &domain, const QString &name);
Q_REVISION(6, 3) void cookieRemoved(const QString &domain, const QString &name);
-protected:
- void runJavaScriptPrivate(const QString &script, int callbackId);
-
private Q_SLOTS:
- void onRunJavaScriptResult(int id, const QVariant &variant);
void onLoadingChanged(const QWebViewLoadRequest &loadRequest);
private:
friend class QWebEngineWebViewPrivate;
- static QJSValue takeCallback(int id);
-
QWebView *m_webView;
QQuickWebViewSettings *m_settings;
};
diff --git a/src/webview/qwebview.cpp b/src/webview/qwebview.cpp
index 8ba9662..75ab2f9 100644
--- a/src/webview/qwebview.cpp
+++ b/src/webview/qwebview.cpp
@@ -102,10 +102,10 @@ void QWebView::loadHtml(const QString &html, const QUrl &baseUrl)
d->loadHtml(html, baseUrl);
}
-void QWebView::runJavaScriptPrivate(const QString &script,
- int callbackId)
+void QWebView::runJavaScript(const QString &script,
+ const std::function<void(const QVariant &)> &resultCallback)
{
- d->runJavaScriptPrivate(script, callbackId);
+ return d->runJavaScript(script, resultCallback);
}
void QWebView::setCookie(const QString &domain, const QString &name, const QString &value)
diff --git a/src/webview/qwebview.h b/src/webview/qwebview.h
index 94681b1..1e3a160 100644
--- a/src/webview/qwebview.h
+++ b/src/webview/qwebview.h
@@ -61,21 +61,18 @@ public:
Q_INVOKABLE void deleteCookie(const QString &domain, const QString &name);
Q_INVOKABLE void deleteAllCookies();
- // FIXME runjavascript
+ void runJavaScript(const QString &script,
+ const std::function<void(const QVariant &)> &resultCallback = {});
Q_SIGNALS:
void titleChanged(QString title);
void urlChanged(QUrl url);
void loadingChanged(const QWebViewLoadRequest &loadRequest);
void loadProgressChanged(int loadProgress);
- void javaScriptResult(int id, const QVariant &result);
void httpUserAgentChanged(QString userAgent);
void cookieAdded(const QString &domain, const QString &name);
void cookieRemoved(const QString &domain, const QString &name);
-protected:
- void runJavaScriptPrivate(const QString &script, int callbackId);
-
private:
Q_DISABLE_COPY(QWebView)
diff --git a/src/webview/qwebview_p.h b/src/webview/qwebview_p.h
index 4134f2a..ea7869d 100644
--- a/src/webview/qwebview_p.h
+++ b/src/webview/qwebview_p.h
@@ -65,11 +65,12 @@ public:
virtual void stop() = 0;
virtual void reload() = 0;
virtual void loadHtml(const QString &html, const QUrl &baseUrl) = 0;
- virtual void runJavaScriptPrivate(const QString &script, int callbackId) = 0;
virtual void setCookie(const QString &domain, const QString &name, const QString &value) = 0;
virtual void deleteCookie(const QString &domain, const QString &name) = 0;
virtual void deleteAllCookies() = 0;
virtual QWindow *nativeWindow() const = 0;
+ virtual void runJavaScript(const QString &script,
+ const std::function<void(const QVariant &)> &resultCallback) = 0;
protected:
explicit QWebViewPrivate(QWebView *view) : q_ptr(view) { };
diff --git a/tests/auto/webview/qwebview/tst_qwebview.cpp b/tests/auto/webview/qwebview/tst_qwebview.cpp
index 85108e7..4360aaa 100644
--- a/tests/auto/webview/qwebview/tst_qwebview.cpp
+++ b/tests/auto/webview/qwebview/tst_qwebview.cpp
@@ -142,7 +142,6 @@ void tst_QWebView::loadHtml()
QWebView view;
QCOMPARE(view.loadProgress(), 0);
QSignalSpy loadChangedSingalSpy(&view, SIGNAL(loadingChanged(QWebViewLoadRequest)));
- QSignalSpy javaScriptResultSpy(&view, SIGNAL(javaScriptResult(int, QVariant)));
view.loadHtml(content, loadUrl);
QTRY_COMPARE(view.loadProgress(), 100);
QTRY_VERIFY(!view.isLoading());
@@ -151,15 +150,15 @@ void tst_QWebView::loadHtml()
// take load finished
const QWebViewLoadRequest &lr = loadChangedSingalSpy.at(1).at(0).value<QWebViewLoadRequest>();
QCOMPARE(lr.status(), QWebViewLoadRequest::LoadStatus::LoadSucceededStatus);
- if (QWebViewFactory::loadedPluginHasKey("android_view")) {
- // WebEngine javascript calls work only with qmlengine, however here we use
- // c++ interface
- int callback = 1;
- view.runJavaScriptPrivate("document.baseURI", callback);
- QTRY_COMPARE(javaScriptResultSpy.size(), 1);
- QCOMPARE(javaScriptResultSpy.at(0).at(0), callback);
- QCOMPARE(javaScriptResultSpy.at(0).at(1).value<QUrl>(), resultUrl);
- }
+ bool called = false;
+ QUrl url;
+ auto callback = [&](const QVariant &result) {
+ called = true;
+ url = result.value<QUrl>();
+ };
+ view.runJavaScript("document.baseURI", callback);
+ QTRY_COMPARE(called, true);
+ QCOMPARE(url, resultUrl);
QVERIFY(view.url().isValid());
QCOMPARE(view.url(), resultUrl);