diff options
| author | Moss Heim <moss.heim@qt.io> | 2024-03-26 11:01:34 +0100 |
|---|---|---|
| committer | Moss Heim <moss.heim@qt.io> | 2024-05-22 10:46:26 +0200 |
| commit | 8a610f99b9f6eaf48438e41660e6b4b35e02f2bb (patch) | |
| tree | 44ec26fcc20d6430e98763127a8b23c8309eb28a /src/core/api/qwebengineframe.cpp | |
| parent | 2e6f7bb1ec5cf6dbbdd27b416660bfa4f385fe85 (diff) | |
Add QWebEngineFrame::runJavaScript
Run JavaScript code on a specific frame, optionally executing a callback
when done. Uses the enclosing page's callback system.
There are two sets of overloads, matching the API of QQuickWebEngineView
and QWebEnginePage.
Also adds QQuickWebEngineFrame::runJavaScript()
Change-Id: I48746bd83d0f19644157548483a94637fc70c20f
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/core/api/qwebengineframe.cpp')
| -rw-r--r-- | src/core/api/qwebengineframe.cpp | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/core/api/qwebengineframe.cpp b/src/core/api/qwebengineframe.cpp index edd89d663..1eedc4b92 100644 --- a/src/core/api/qwebengineframe.cpp +++ b/src/core/api/qwebengineframe.cpp @@ -3,6 +3,9 @@ #include "qwebengineframe.h" +#include "qwebenginescript.h" +#include <QtQml/qqmlengine.h> + #include "web_contents_adapter_client.h" #include "web_contents_adapter.h" @@ -101,6 +104,77 @@ QSizeF QWebEngineFrame::size() const return m_adapterClient->webContentsAdapter()->frameSize(m_id); } +/*! \fn void QWebEngineFrame::runJavaScript(const QString &script, const std::function<void(const QVariant &)> &callback) + \fn void QWebEngineFrame::runJavaScript(const QString &script, quint32 worldId) + \fn void QWebEngineFrame::runJavaScript(const QString &script, quint32 worldId, const + std::function<void(const QVariant &)> &callback) + + Runs the JavaScript code contained in \a script on this frame, without checking + whether the DOM of the page has been constructed. + To avoid conflicts with other scripts executed on the page, the world in + which the script is run is specified by \a worldId. The world ID values are + the same as provided by QWebEngineScript::ScriptWorldId, and between \c 0 + and \c 256. If you leave out the \c world ID, the script is run in the + \c MainWorld. + When the script has been executed, \a callback is called with the result of the last + executed statement. \c callback can be any of a function pointer, a functor or a lambda, + and it is expected to take a QVariant parameter. For example: + \code + page.runJavaScript("document.title", [](const QVariant &v) { qDebug() << v.toString(); }); + \endcode + Only plain data can be returned from JavaScript as the result value. + Supported data types include all of the JSON data types as well as, for + example, \c{Date} and \c{ArrayBuffer}. Unsupported data types include, for + example, \c{Function} and \c{Promise}. + \warning Do not execute lengthy routines in the callback function, because it might block the + rendering of the web engine page. + \warning We guarantee that the \a callback is always called, but it might be + done during page destruction. When QWebEnginePage is deleted, the callback is triggered with an + invalid value and it is not safe to use the corresponding QWebEnginePage or QWebEngineView + instance inside it. + \sa QWebEngineScript::ScriptWorldId, QWebEnginePage::runJavaScript, {Script Injection} + */ +void QWebEngineFrame::runJavaScript(const QString &script, + const std::function<void(const QVariant &)> &callback) +{ + runJavaScript(script, QWebEngineScript::MainWorld, callback); +} + +void QWebEngineFrame::runJavaScript(const QString &script, quint32 worldId, + const std::function<void(const QVariant &)> &callback) +{ + m_adapterClient->runJavaScript(script, worldId, m_id, callback); +} + +void QWebEngineFrame::runJavaScript(const QString &script, quint32 worldId) +{ + runJavaScript(script, worldId, std::function<void(const QVariant &)>{}); +} + +void QWebEngineFrame::runJavaScript(const QString &script, const QJSValue &callback) +{ + runJavaScript(script, QWebEngineScript::MainWorld, callback); +} + +void QWebEngineFrame::runJavaScript(const QString &script, quint32 worldId, + const QJSValue &callback) +{ + std::function<void(const QVariant &)> wrappedCallback; + if (!callback.isUndefined()) { + const QObject *holdingObject = m_adapterClient->holdingQObject(); + wrappedCallback = [holdingObject, callback](const QVariant &result) { + if (auto engine = qmlEngine(holdingObject)) { + QJSValueList args; + args.append(engine->toScriptValue(result)); + callback.call(args); + } else { + qWarning("No QML engine found to execute runJavaScript() callback"); + } + }; + } + runJavaScript(script, worldId, wrappedCallback); +} + /*! \fn bool QWebEngineFrame::operator==(const QWebEngineFrame &left, const QWebEngineFrame &right) noexcept Returns \c{true} if \a left and \a right represent the same frame in the same web page, |
