diff options
Diffstat (limited to 'src/core/api/qwebengineframe.cpp')
-rw-r--r-- | src/core/api/qwebengineframe.cpp | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/src/core/api/qwebengineframe.cpp b/src/core/api/qwebengineframe.cpp new file mode 100644 index 000000000..1eedc4b92 --- /dev/null +++ b/src/core/api/qwebengineframe.cpp @@ -0,0 +1,192 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qwebengineframe.h" + +#include "qwebenginescript.h" +#include <QtQml/qqmlengine.h> + +#include "web_contents_adapter_client.h" +#include "web_contents_adapter.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QWebEngineFrame + \brief The QWebEngineFrame class gives information about and control over a page frame. + \since 6.8 + + \inmodule QtWebEngineCore + + A web engine frame represents a single frame within a web page, such as those created by + \c <frame> or \c <iframe> HTML elements. + An active QWebEnginePage has one or more frames arranged in a tree structure. The top-level + frame, the root of this tree, can be accessed through the mainFrame() method, and + children() provides a frame's direct descendants. + + A frame's lifetime is, at most, as long as the QWebEnginePage object that produced it. + However, frames may be created and deleted spontaneously and dynamically, for example through + navigation and script execution. Because of this, many QWebEngineFrame methods return + optional values, which will be \c std::nullopt if the frame no longer exists. +*/ + +/*! \internal + */ +QWebEngineFrame::QWebEngineFrame(QtWebEngineCore::WebContentsAdapterClient *adapter, quint64 id) + : m_adapterClient(adapter), m_id(id) +{ +} + +/*! + Returns \c{true} if this object represents an existing frame; \c{false} otherwise. + + Once a frame is invalid, it never becomes valid again. +*/ +bool QWebEngineFrame::isValid() const +{ + return m_adapterClient->webContentsAdapter()->hasFrame(m_id); +} + +/*! + Returns the frame name; that is, what would be returned by \c window.name in JavaScript. + + If the frame could not be found, returns a null QString. + + \sa htmlName +*/ +QString QWebEngineFrame::name() const +{ + return m_adapterClient->webContentsAdapter()->frameName(m_id); +} + +/*! + Returns the value of the frame's \c name HTML attribute, or an empty string if it has none. + + If the frame could not be found, returns a null QString. + + \sa name +*/ +QString QWebEngineFrame::htmlName() const +{ + return m_adapterClient->webContentsAdapter()->frameHtmlName(m_id); +} + +/*! + Returns a list of the frame's children in an arbitrary order. + + If the frame could not be found, returns an empty list. + */ +QList<QWebEngineFrame> QWebEngineFrame::children() const +{ + QList<QWebEngineFrame> result; + for (auto childId : m_adapterClient->webContentsAdapter()->frameChildren(m_id)) + result.push_back(QWebEngineFrame{ m_adapterClient, childId }); + return result; +} + +/*! + Returns the URL of the content currently loaded in this frame. + + If the frame could not be found, returns an empty QUrl. + */ +QUrl QWebEngineFrame::url() const +{ + return m_adapterClient->webContentsAdapter()->frameUrl(m_id); +} + +/*! + Returns the size of the frame within the viewport. + + If the frame could not be found, returns QSizeF(). + */ +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, + otherwise \c{false}. + */ + +/*! \fn bool QWebEngineFrame::operator!=(const QWebEngineFrame &left, const QWebEngineFrame &right) noexcept + + Returns \c{true} if \a left and \a right represent different frames in the same web page, + otherwise \c{false}. + */ + +QT_END_NAMESPACE + +#include "moc_qwebengineframe.cpp" |