diff options
20 files changed, 548 insertions, 321 deletions
diff --git a/src/core/user_script.cpp b/src/core/user_script.cpp index 912b204b7..6f5828cbf 100644 --- a/src/core/user_script.cpp +++ b/src/core/user_script.cpp @@ -81,6 +81,7 @@ UserScript::UserScript(const UserScript &other) return; scriptData.reset(new UserScriptData(*other.scriptData)); m_name = other.m_name; + m_url = other.m_url; } UserScript::~UserScript() @@ -96,6 +97,7 @@ UserScript &UserScript::operator=(const UserScript &other) } scriptData.reset(new UserScriptData(*other.scriptData)); m_name = other.m_name; + m_url = other.m_url; return *this; } @@ -125,6 +127,16 @@ void UserScript::setSourceCode(const QString &source) parseMetadataHeader(); } +QUrl UserScript::sourceUrl() const +{ + return m_url; +} + +void UserScript::setSourceUrl(const QUrl &url) +{ + m_url = url; +} + UserScript::InjectionPoint UserScript::injectionPoint() const { if (isNull()) @@ -173,7 +185,9 @@ bool UserScript::operator==(const UserScript &other) const return worldId() == other.worldId() && runsOnSubFrames() == other.runsOnSubFrames() && injectionPoint() == other.injectionPoint() - && name() == other.name() && sourceCode() == other.sourceCode(); + && name() == other.name() + && sourceCode() == other.sourceCode() + && sourceUrl() == other.sourceUrl(); } void UserScript::initData() diff --git a/src/core/user_script.h b/src/core/user_script.h index 8f65f4b74..07fba90f4 100644 --- a/src/core/user_script.h +++ b/src/core/user_script.h @@ -56,6 +56,7 @@ #include <QtCore/QScopedPointer> #include <QtCore/QSharedData> #include <QtCore/QString> +#include <QtCore/QUrl> struct UserScriptData; @@ -84,6 +85,9 @@ public: QString sourceCode() const; void setSourceCode(const QString &); + QUrl sourceUrl() const; + void setSourceUrl(const QUrl &); + InjectionPoint injectionPoint() const; void setInjectionPoint(InjectionPoint); @@ -103,6 +107,7 @@ private: QScopedPointer<UserScriptData> scriptData; QString m_name; + QUrl m_url; }; } // namespace QtWebEngineCore diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp index 2bea21115..7c0454e53 100644 --- a/src/webengine/api/qquickwebengineprofile.cpp +++ b/src/webengine/api/qquickwebengineprofile.cpp @@ -40,18 +40,18 @@ #include "qquickwebengineprofile.h" #include "qquickwebengineprofile_p.h" -#include "qquickwebenginescript_p.h" #include "qquickwebenginesettings_p.h" +#include "qquickwebenginescriptcollection.h" +#include "qquickwebenginescriptcollection_p.h" #include "qquickwebengineview_p_p.h" #include "qwebenginecookiestore.h" #include "qwebenginenotification.h" - #include <QFileInfo> #include <QDir> #include <QQmlEngine> +#include <QtQml/QQmlInfo> #include "profile_adapter.h" -#include "renderer_host/user_resource_controller_host.h" #include "web_engine_settings.h" #include <QtWebEngineCore/private/qwebenginedownloadrequest_p.h> @@ -158,8 +158,10 @@ QT_BEGIN_NAMESPACE */ QQuickWebEngineProfilePrivate::QQuickWebEngineProfilePrivate(ProfileAdapter *profileAdapter) - : m_settings(new QQuickWebEngineSettings()) - , m_profileAdapter(profileAdapter) + : m_settings(new QQuickWebEngineSettings()) + , m_profileAdapter(profileAdapter) + , m_scriptCollection(new QQuickWebEngineScriptCollection( + new QQuickWebEngineScriptCollectionPrivate(profileAdapter->userResourceController()))) { profileAdapter->addClient(this); // Fullscreen API was implemented before the supported setting, so we must @@ -308,38 +310,6 @@ void QQuickWebEngineProfilePrivate::showNotification(QSharedPointer<QtWebEngineC Q_EMIT q->presentNotification(notification); } -void QQuickWebEngineProfilePrivate::userScripts_append(QQmlListProperty<QQuickWebEngineScript> *p, QQuickWebEngineScript *script) -{ - Q_ASSERT(p && p->data); - QQuickWebEngineProfilePrivate *d = static_cast<QQuickWebEngineProfilePrivate *>(p->data); - QtWebEngineCore::UserResourceControllerHost *resourceController = d->profileAdapter()->userResourceController(); - d->m_userScripts.append(script); - script->d_func()->bind(resourceController); -} - -int QQuickWebEngineProfilePrivate::userScripts_count(QQmlListProperty<QQuickWebEngineScript> *p) -{ - Q_ASSERT(p && p->data); - QQuickWebEngineProfilePrivate *d = static_cast<QQuickWebEngineProfilePrivate *>(p->data); - return d->m_userScripts.count(); -} - -QQuickWebEngineScript *QQuickWebEngineProfilePrivate::userScripts_at(QQmlListProperty<QQuickWebEngineScript> *p, int idx) -{ - Q_ASSERT(p && p->data); - QQuickWebEngineProfilePrivate *d = static_cast<QQuickWebEngineProfilePrivate *>(p->data); - return d->m_userScripts.at(idx); -} - -void QQuickWebEngineProfilePrivate::userScripts_clear(QQmlListProperty<QQuickWebEngineScript> *p) -{ - Q_ASSERT(p && p->data); - QQuickWebEngineProfilePrivate *d = static_cast<QQuickWebEngineProfilePrivate *>(p->data); - QtWebEngineCore::UserResourceControllerHost *resourceController = d->profileAdapter()->userResourceController(); - resourceController->clearAllScripts(NULL); - d->m_userScripts.clear(); -} - /*! \qmltype WebEngineProfile \instantiates QQuickWebEngineProfile @@ -1062,23 +1032,10 @@ QQuickWebEngineSettings *QQuickWebEngineProfile::settings() const \sa WebEngineScript */ -/*! - \property QQuickWebEngineProfile::userScripts - \since 5.9 - - \brief The collection of scripts that are injected into all pages that share - this profile. - - \sa QQuickWebEngineScript, QQmlListReference -*/ -QQmlListProperty<QQuickWebEngineScript> QQuickWebEngineProfile::userScripts() +QQuickWebEngineScriptCollection *QQuickWebEngineProfile::userScripts() const { - Q_D(QQuickWebEngineProfile); - return QQmlListProperty<QQuickWebEngineScript>(this, d, - d->userScripts_append, - d->userScripts_count, - d->userScripts_at, - d->userScripts_clear); + const Q_D(QQuickWebEngineProfile); + return d->m_scriptCollection.data(); } /*! @@ -1097,3 +1054,5 @@ QWebEngineClientCertificateStore *QQuickWebEngineProfile::clientCertificateStore } QT_END_NAMESPACE + +#include "moc_qquickwebengineprofile.cpp" diff --git a/src/webengine/api/qquickwebengineprofile.h b/src/webengine/api/qquickwebengineprofile.h index ca90d7ae8..ccc5a9098 100644 --- a/src/webengine/api/qquickwebengineprofile.h +++ b/src/webengine/api/qquickwebengineprofile.h @@ -42,23 +42,22 @@ #include <QtWebEngine/qtwebengineglobal.h> - #include <QtCore/QObject> #include <QtCore/QScopedPointer> #include <QtCore/QString> -#include <QtQml/QQmlListProperty> QT_BEGIN_NAMESPACE class QWebEngineDownloadRequest; -class QQuickWebEngineProfilePrivate; -class QQuickWebEngineScript; +class QWebEngineScript; class QQuickWebEngineSettings; class QWebEngineClientCertificateStore; class QWebEngineCookieStore; class QWebEngineNotification; class QWebEngineUrlRequestInterceptor; class QWebEngineUrlSchemeHandler; +class QQuickWebEngineScriptCollection; +class QQuickWebEngineProfilePrivate; class Q_WEBENGINE_EXPORT QQuickWebEngineProfile : public QObject { Q_OBJECT @@ -73,7 +72,7 @@ class Q_WEBENGINE_EXPORT QQuickWebEngineProfile : public QObject { Q_PROPERTY(int httpCacheMaximumSize READ httpCacheMaximumSize WRITE setHttpCacheMaximumSize NOTIFY httpCacheMaximumSizeChanged FINAL) Q_PROPERTY(QStringList spellCheckLanguages READ spellCheckLanguages WRITE setSpellCheckLanguages NOTIFY spellCheckLanguagesChanged FINAL REVISION 3) Q_PROPERTY(bool spellCheckEnabled READ isSpellCheckEnabled WRITE setSpellCheckEnabled NOTIFY spellCheckEnabledChanged FINAL REVISION 3) - Q_PROPERTY(QQmlListProperty<QQuickWebEngineScript> userScripts READ userScripts FINAL REVISION 4) + Q_PROPERTY(QQuickWebEngineScriptCollection *userScripts READ userScripts) Q_PROPERTY(bool useForGlobalCertificateVerification READ isUsedForGlobalCertificateVerification WRITE setUseForGlobalCertificateVerification @@ -146,7 +145,7 @@ public: void setSpellCheckEnabled(bool enabled); bool isSpellCheckEnabled() const; - QQmlListProperty<QQuickWebEngineScript> userScripts(); + QQuickWebEngineScriptCollection *userScripts() const; void setUseForGlobalCertificateVerification(bool b); bool isUsedForGlobalCertificateVerification() const; @@ -172,7 +171,6 @@ Q_SIGNALS: Q_REVISION(3) void spellCheckEnabledChanged(); Q_REVISION(5) void useForGlobalCertificateVerificationChanged(); Q_REVISION(5) void downloadPathChanged(); - void downloadRequested(QWebEngineDownloadRequest *download); void downloadFinished(QWebEngineDownloadRequest *download); diff --git a/src/webengine/api/qquickwebengineprofile_p.h b/src/webengine/api/qquickwebengineprofile_p.h index f1fd93543..b9b52a693 100644 --- a/src/webengine/api/qquickwebengineprofile_p.h +++ b/src/webengine/api/qquickwebengineprofile_p.h @@ -65,6 +65,7 @@ QT_BEGIN_NAMESPACE class QWebEngineDownloadRequest; class QQuickWebEngineSettings; class QQuickWebEngineViewPrivate; +class QQuickWebEngineScriptCollection; class QQuickWebEngineProfilePrivate : public QtWebEngineCore::ProfileAdapterClient { public: @@ -89,19 +90,13 @@ public: void showNotification(QSharedPointer<QtWebEngineCore::UserNotificationController> &controller) override; - // QQmlListPropertyHelpers - static void userScripts_append(QQmlListProperty<QQuickWebEngineScript> *p, QQuickWebEngineScript *script); - static int userScripts_count(QQmlListProperty<QQuickWebEngineScript> *p); - static QQuickWebEngineScript *userScripts_at(QQmlListProperty<QQuickWebEngineScript> *p, int idx); - static void userScripts_clear(QQmlListProperty<QQuickWebEngineScript> *p); - private: friend class QQuickWebEngineView; QQuickWebEngineProfile *q_ptr; QScopedPointer<QQuickWebEngineSettings> m_settings; QPointer<QtWebEngineCore::ProfileAdapter> m_profileAdapter; QMap<quint32, QPointer<QWebEngineDownloadRequest> > m_ongoingDownloads; - QList<QQuickWebEngineScript *> m_userScripts; + QScopedPointer<QQuickWebEngineScriptCollection> m_scriptCollection; }; QT_END_NAMESPACE diff --git a/src/webengine/api/qquickwebenginescript.cpp b/src/webengine/api/qquickwebenginescript.cpp index ab7aee4cb..81fd0b925 100644 --- a/src/webengine/api/qquickwebenginescript.cpp +++ b/src/webengine/api/qquickwebenginescript.cpp @@ -38,7 +38,6 @@ ****************************************************************************/ #include "qquickwebenginescript.h" -#include "qquickwebenginescript_p.h" #include <QQmlFile> #include <QtCore/QDebug> @@ -128,12 +127,7 @@ QT_BEGIN_NAMESPACE /*! Constructs a new QQuickWebEngineScript with the parent \a parent. */ -QQuickWebEngineScript::QQuickWebEngineScript(QObject *parent) - : QObject(parent) - , d_ptr(new QQuickWebEngineScriptPrivate) -{ - d_ptr->q_ptr = this; -} +QQuickWebEngineScript::QQuickWebEngineScript() : d(new QtWebEngineCore::UserScript) { } /*! \internal @@ -142,16 +136,28 @@ QQuickWebEngineScript::~QQuickWebEngineScript() { } +QQuickWebEngineScript::QQuickWebEngineScript(const QQuickWebEngineScript &other) : d(other.d) { } + +QQuickWebEngineScript &QQuickWebEngineScript::operator=(const QQuickWebEngineScript &other) +{ + d = other.d; + return *this; +} + +bool QQuickWebEngineScript::operator==(const QQuickWebEngineScript &other) const +{ + return d == other.d || *d == *(other.d); +} + /*! Returns the script object as string. */ QString QQuickWebEngineScript::toString() const { - Q_D(const QQuickWebEngineScript); - if (d->coreScript.isNull()) + if (d->isNull()) return QStringLiteral("QWebEngineScript()"); - QString ret = QStringLiteral("QWebEngineScript(") % d->coreScript.name() % QStringLiteral(", "); - switch (d->coreScript.injectionPoint()) { + QString ret = QStringLiteral("QWebEngineScript(") % d->name() % QStringLiteral(", "); + switch (d->injectionPoint()) { case UserScript::DocumentElementCreation: ret.append(QStringLiteral("WebEngineScript::DocumentCreation, ")); break; @@ -162,9 +168,9 @@ QString QQuickWebEngineScript::toString() const ret.append(QStringLiteral("WebEngineScript::Deferred, ")); break; } - ret.append(QString::number(d->coreScript.worldId()) % QStringLiteral(", ") - % (d->coreScript.runsOnSubFrames() ? QStringLiteral("true") : QStringLiteral("false")) - % QStringLiteral(", ") % d->coreScript.sourceCode() % QLatin1Char(')')); + ret.append(QString::number(d->worldId()) % QStringLiteral(", ") + % (d->runsOnSubFrames() ? QStringLiteral("true") : QStringLiteral("false")) + % QStringLiteral(", ") % d->sourceCode() % QLatin1Char(')')); return ret; } @@ -184,8 +190,7 @@ QString QQuickWebEngineScript::toString() const */ QString QQuickWebEngineScript::name() const { - Q_D(const QQuickWebEngineScript); - return d->coreScript.name(); + return d->name(); } /*! @@ -218,8 +223,7 @@ QString QQuickWebEngineScript::name() const */ QUrl QQuickWebEngineScript::sourceUrl() const { - Q_D(const QQuickWebEngineScript); - return d->m_sourceUrl; + return d->sourceUrl(); } /*! @@ -238,8 +242,7 @@ QUrl QQuickWebEngineScript::sourceUrl() const */ QString QQuickWebEngineScript::sourceCode() const { - Q_D(const QQuickWebEngineScript); - return d->coreScript.sourceCode(); + return d->sourceCode(); } ASSERT_ENUMS_MATCH(QQuickWebEngineScript::Deferred, UserScript::AfterLoad) @@ -271,8 +274,7 @@ ASSERT_ENUMS_MATCH(QQuickWebEngineScript::DocumentCreation, UserScript::Document */ QQuickWebEngineScript::InjectionPoint QQuickWebEngineScript::injectionPoint() const { - Q_D(const QQuickWebEngineScript); - return static_cast<QQuickWebEngineScript::InjectionPoint>(d->coreScript.injectionPoint()); + return static_cast<QQuickWebEngineScript::InjectionPoint>(d->injectionPoint()); } /*! @@ -298,8 +300,7 @@ QQuickWebEngineScript::InjectionPoint QQuickWebEngineScript::injectionPoint() co */ QQuickWebEngineScript::ScriptWorldId QQuickWebEngineScript::worldId() const { - Q_D(const QQuickWebEngineScript); - return static_cast<QQuickWebEngineScript::ScriptWorldId>(d->coreScript.worldId()); + return static_cast<QQuickWebEngineScript::ScriptWorldId>(d->worldId()); } /*! @@ -320,45 +321,35 @@ QQuickWebEngineScript::ScriptWorldId QQuickWebEngineScript::worldId() const */ bool QQuickWebEngineScript::runOnSubframes() const { - Q_D(const QQuickWebEngineScript); - return d->coreScript.runsOnSubFrames(); + return d->runsOnSubFrames(); } void QQuickWebEngineScript::setName(const QString &name) { - Q_D(QQuickWebEngineScript); if (name == QQuickWebEngineScript::name()) return; - d->aboutToUpdateUnderlyingScript(); - d->coreScript.setName(name); - Q_EMIT nameChanged(name); + d->setName(name); } void QQuickWebEngineScript::setSourceCode(const QString &code) { - Q_D(QQuickWebEngineScript); if (code == sourceCode()) return; // setting the source directly resets the sourceUrl - if (d->m_sourceUrl != QUrl()) { - d->m_sourceUrl = QUrl(); - Q_EMIT sourceUrlChanged(d->m_sourceUrl); + if (d->sourceUrl() != QUrl()) { + d->setSourceUrl(QUrl()); } - d->aboutToUpdateUnderlyingScript(); - d->coreScript.setSourceCode(code); - Q_EMIT sourceCodeChanged(code); + d->setSourceCode(code); } void QQuickWebEngineScript::setSourceUrl(const QUrl &url) { - Q_D(QQuickWebEngineScript); if (url == sourceUrl()) return; - d->m_sourceUrl = url; - Q_EMIT sourceUrlChanged(d->m_sourceUrl); + d->setSourceUrl(url); QFile f(QQmlFile::urlToLocalFileOrQrc(url)); if (!f.open(QIODevice::ReadOnly)) { @@ -366,81 +357,31 @@ void QQuickWebEngineScript::setSourceUrl(const QUrl &url) return; } - d->aboutToUpdateUnderlyingScript(); QString source = QString::fromUtf8(f.readAll()); - d->coreScript.setSourceCode(source); - Q_EMIT sourceCodeChanged(source); + d->setSourceCode(source); } void QQuickWebEngineScript::setInjectionPoint(QQuickWebEngineScript::InjectionPoint injectionPoint) { - Q_D(QQuickWebEngineScript); if (injectionPoint == QQuickWebEngineScript::injectionPoint()) return; - d->aboutToUpdateUnderlyingScript(); - d->coreScript.setInjectionPoint(static_cast<UserScript::InjectionPoint>(injectionPoint)); - Q_EMIT injectionPointChanged(injectionPoint); + d->setInjectionPoint(static_cast<UserScript::InjectionPoint>(injectionPoint)); } void QQuickWebEngineScript::setWorldId(QQuickWebEngineScript::ScriptWorldId scriptWorldId) { - Q_D(QQuickWebEngineScript); if (scriptWorldId == worldId()) return; - d->aboutToUpdateUnderlyingScript(); - d->coreScript.setWorldId(scriptWorldId); - Q_EMIT worldIdChanged(scriptWorldId); + d->setWorldId(scriptWorldId); } void QQuickWebEngineScript::setRunOnSubframes(bool on) { - Q_D(QQuickWebEngineScript); if (on == runOnSubframes()) return; - d->aboutToUpdateUnderlyingScript(); - d->coreScript.setRunsOnSubFrames(on); - Q_EMIT runOnSubframesChanged(on); -} - -/*! - \internal -*/ -void QQuickWebEngineScript::timerEvent(QTimerEvent *e) -{ - Q_D(QQuickWebEngineScript); - if (e->timerId() != d->m_basicTimer.timerId()) { - QObject::timerEvent(e); - return; - } - if (!d->m_controllerHost) - return; - d->m_basicTimer.stop(); - d->m_controllerHost->addUserScript(d->coreScript, d->m_adapter); -} - -void QQuickWebEngineScriptPrivate::bind(QtWebEngineCore::UserResourceControllerHost *resourceController, QtWebEngineCore::WebContentsAdapter *adapter) -{ - aboutToUpdateUnderlyingScript(); - m_adapter = adapter; - m_controllerHost = resourceController; -} - -QQuickWebEngineScriptPrivate::QQuickWebEngineScriptPrivate() - :m_controllerHost(0) - , m_adapter(0) - -{ -} - -void QQuickWebEngineScriptPrivate::aboutToUpdateUnderlyingScript() -{ - Q_Q(QQuickWebEngineScript); - if (m_controllerHost) - m_controllerHost->removeUserScript(coreScript, m_adapter); - // Defer updates to the next event loop - m_basicTimer.start(0, q); + d->setRunsOnSubFrames(on); } QT_END_NAMESPACE diff --git a/src/webengine/api/qquickwebenginescript.h b/src/webengine/api/qquickwebenginescript.h index d5c4310db..a5f20bc50 100644 --- a/src/webengine/api/qquickwebenginescript.h +++ b/src/webengine/api/qquickwebenginescript.h @@ -40,24 +40,26 @@ #ifndef QQUICKWEBENGINESCRIPT_H #define QQUICKWEBENGINESCRIPT_H -#include <QtCore/qobject.h> #include <QtCore/qurl.h> +#include <QtCore/QSharedDataPointer> #include <QtWebEngine/qtwebengineglobal.h> +namespace QtWebEngineCore { +class UserScript; +} // namespace + QT_BEGIN_NAMESPACE -class QQuickWebEngineScriptPrivate; class QQuickWebEngineView; -class Q_WEBENGINE_EXPORT QQuickWebEngineScript : public QObject +class Q_WEBENGINE_EXPORT QQuickWebEngineScript { - Q_OBJECT - Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged FINAL) - Q_PROPERTY(QUrl sourceUrl READ sourceUrl WRITE setSourceUrl NOTIFY sourceUrlChanged FINAL) - Q_PROPERTY(QString sourceCode READ sourceCode WRITE setSourceCode NOTIFY sourceCodeChanged FINAL) - Q_PROPERTY(InjectionPoint injectionPoint READ injectionPoint WRITE setInjectionPoint NOTIFY injectionPointChanged FINAL) - Q_PROPERTY(ScriptWorldId worldId READ worldId WRITE setWorldId NOTIFY worldIdChanged FINAL) - Q_PROPERTY(bool runOnSubframes READ runOnSubframes WRITE setRunOnSubframes NOTIFY runOnSubframesChanged FINAL) - + Q_GADGET + Q_PROPERTY(QString name READ name WRITE setName FINAL) + Q_PROPERTY(QUrl sourceUrl READ sourceUrl WRITE setSourceUrl FINAL) + Q_PROPERTY(QString sourceCode READ sourceCode WRITE setSourceCode FINAL) + Q_PROPERTY(InjectionPoint injectionPoint READ injectionPoint WRITE setInjectionPoint FINAL) + Q_PROPERTY(ScriptWorldId worldId READ worldId WRITE setWorldId FINAL) + Q_PROPERTY(bool runOnSubframes READ runOnSubframes WRITE setRunOnSubframes FINAL) public: enum InjectionPoint { @@ -74,9 +76,12 @@ public: }; Q_ENUM(ScriptWorldId) - explicit QQuickWebEngineScript(QObject *parent = Q_NULLPTR); + explicit QQuickWebEngineScript(); ~QQuickWebEngineScript(); - Q_INVOKABLE QString toString() const; + QQuickWebEngineScript(const QQuickWebEngineScript &other); + QQuickWebEngineScript &operator=(const QQuickWebEngineScript &other); + bool operator==(const QQuickWebEngineScript &other) const; + inline bool operator!=(const QQuickWebEngineScript &other) const { return !operator==(other); } QString name() const; QUrl sourceUrl() const; @@ -85,6 +90,7 @@ public: ScriptWorldId worldId() const; bool runOnSubframes() const; + Q_INVOKABLE QString toString() const; Q_INVOKABLE void setName(const QString &name); Q_INVOKABLE void setSourceUrl(const QUrl &url); Q_INVOKABLE void setSourceCode(const QString &code); @@ -92,22 +98,13 @@ public: Q_INVOKABLE void setWorldId(ScriptWorldId scriptWorldId); Q_INVOKABLE void setRunOnSubframes(bool on); -Q_SIGNALS: - void nameChanged(const QString &name); - void sourceUrlChanged(const QUrl &url); - void sourceCodeChanged(const QString &code); - void injectionPointChanged(InjectionPoint injectionPoint); - void worldIdChanged(ScriptWorldId scriptWorldId); - void runOnSubframesChanged(bool on); - -protected: - void timerEvent(QTimerEvent *e) override; private: + QQuickWebEngineScript(const QtWebEngineCore::UserScript &); + QSharedDataPointer<QtWebEngineCore::UserScript> d; friend class QQuickWebEngineProfilePrivate; friend class QQuickWebEngineViewPrivate; - Q_DECLARE_PRIVATE(QQuickWebEngineScript) - QScopedPointer<QQuickWebEngineScriptPrivate> d_ptr; + friend class QQuickWebEngineScriptCollectionPrivate; }; QT_END_NAMESPACE diff --git a/src/webengine/api/qquickwebenginescriptcollection.cpp b/src/webengine/api/qquickwebenginescriptcollection.cpp new file mode 100644 index 000000000..b02e9f84d --- /dev/null +++ b/src/webengine/api/qquickwebenginescriptcollection.cpp @@ -0,0 +1,248 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** 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 The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickwebenginescriptcollection.h" +#include "qquickwebenginescriptcollection_p.h" +#include "renderer_host/user_resource_controller_host.h" +#include <QtQml/QQmlInfo> +#include <QtQml/private/qqmlengine_p.h> +#include <QtQml/private/qv4scopedvalue_p.h> +#include <QtQml/private/qv4arrayobject_p.h> + +QQuickWebEngineScript parseScript(const QJSValue &value, bool *ok) +{ + QQuickWebEngineScript s; + if (ok) + *ok = false; + + if (value.isObject()) { + + if (value.hasProperty(QStringLiteral("name"))) + s.setName(value.property(QStringLiteral("name")).toString()); + + if (value.hasProperty(QStringLiteral("sourceUrl"))) + s.setSourceUrl(value.property(QStringLiteral("sourceUrl")).toString()); + + if (value.hasProperty(QStringLiteral("injectionPoint"))) + s.setInjectionPoint(QQuickWebEngineScript::InjectionPoint( + value.property(QStringLiteral("injectionPoint")).toUInt())); + + if (value.hasProperty(QStringLiteral("sourceCode"))) + s.setSourceCode(value.property(QStringLiteral("sourceCode")).toString()); + + if (value.hasProperty(QStringLiteral("worldId"))) + s.setWorldId(QQuickWebEngineScript::ScriptWorldId( + value.property(QStringLiteral("worldId")).toUInt())); + + if (value.hasProperty(QStringLiteral("runOnSubframes"))) + s.setRunOnSubframes(value.property(QStringLiteral("runOnSubframes")).toBool()); + + if (ok) + *ok = true; + } + return s; +} + +QQuickWebEngineScriptCollection::QQuickWebEngineScriptCollection( + QQuickWebEngineScriptCollectionPrivate *collectionPrivate) + : d(collectionPrivate) +{ +} + +QQuickWebEngineScriptCollection::~QQuickWebEngineScriptCollection() { } + +int QQuickWebEngineScriptCollection::count() const +{ + return d->count(); +} + +bool QQuickWebEngineScriptCollection::contains(const QQuickWebEngineScript &value) const +{ + return d->contains(value); +} + +QQuickWebEngineScript QQuickWebEngineScriptCollection::findScript(const QString &name) const +{ + return d->find(name); +} + +QList<QQuickWebEngineScript> QQuickWebEngineScriptCollection::findScripts(const QString &name) const +{ + return d->toList(name); +} + +void QQuickWebEngineScriptCollection::insert(const QQuickWebEngineScript &s) +{ + d->insert(s); +} + +void QQuickWebEngineScriptCollection::insert(const QList<QQuickWebEngineScript> &list) +{ + d->reserve(list.size()); + for (const QQuickWebEngineScript &s : list) + d->insert(s); +} + +bool QQuickWebEngineScriptCollection::remove(const QQuickWebEngineScript &script) +{ + return d->remove(script); +} + +void QQuickWebEngineScriptCollection::clear() +{ + d->clear(); +} + +QList<QQuickWebEngineScript> QQuickWebEngineScriptCollection::toList() const +{ + return d->toList(); +} + +QQuickWebEngineScriptCollectionPrivate::QQuickWebEngineScriptCollectionPrivate( + QtWebEngineCore::UserResourceControllerHost *controller, + QSharedPointer<QtWebEngineCore::WebContentsAdapter> webContents) + : m_scriptController(controller), m_contents(webContents) +{ +} + +int QQuickWebEngineScriptCollectionPrivate::count() const +{ + return m_scripts.count(); +} + +bool QQuickWebEngineScriptCollectionPrivate::contains(const QQuickWebEngineScript &s) const +{ + return m_scripts.contains(s); +} + +void QQuickWebEngineScriptCollectionPrivate::insert(const QQuickWebEngineScript &script) +{ + m_scripts.append(script); + if (!m_contents || m_contents->isInitialized()) + m_scriptController->addUserScript(*script.d, m_contents.data()); +} + +bool QQuickWebEngineScriptCollectionPrivate::remove(const QQuickWebEngineScript &script) +{ + if (!m_contents || m_contents->isInitialized()) + m_scriptController->removeUserScript(*script.d, m_contents.data()); + return m_scripts.removeAll(script); +} + +QList<QQuickWebEngineScript> +QQuickWebEngineScriptCollectionPrivate::toList(const QString &scriptName) const +{ + QList<QQuickWebEngineScript> ret; + for (const QQuickWebEngineScript &script : qAsConst(m_scripts)) + if (scriptName == script.name()) + ret.append(script); + return ret; +} + +QQuickWebEngineScript QQuickWebEngineScriptCollectionPrivate::find(const QString &name) const +{ + for (const QQuickWebEngineScript &script : qAsConst(m_scripts)) + if (name == script.name()) + return script; + return QQuickWebEngineScript(); +} + +void QQuickWebEngineScriptCollectionPrivate::clear() +{ + m_scripts.clear(); + if (!m_contents || m_contents->isInitialized()) + m_scriptController->clearAllScripts(m_contents.data()); +} + +void QQuickWebEngineScriptCollectionPrivate::reserve(int capacity) +{ + m_scripts.reserve(capacity); + if (!m_contents || m_contents->isInitialized()) + m_scriptController->reserve(m_contents.data(), capacity); +} + +void QQuickWebEngineScriptCollectionPrivate::initializationFinished( + QSharedPointer<QtWebEngineCore::WebContentsAdapter> contents) +{ + Q_ASSERT(m_contents); + Q_ASSERT(contents); + + for (const QQuickWebEngineScript &script : qAsConst(m_scripts)) + m_scriptController->addUserScript(*script.d, contents.data()); + m_contents = contents; +} + +QJSValue QQuickWebEngineScriptCollection::collection() const +{ + const QList<QQuickWebEngineScript> &list = d->m_scripts; + QQmlContext *context = QQmlEngine::contextForObject(this); + QQmlEngine *engine = context->engine(); + QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine); + QV4::Scope scope(v4); + QV4::Scoped<QV4::ArrayObject> scriptArray(scope, v4->newArrayObject(list.length())); + int i = 0; + for (const auto &val : list) { + QV4::ScopedValue sv(scope, v4->fromVariant(QVariant::fromValue(val))); + scriptArray->put(i++, sv); + } + return QJSValuePrivate::fromReturnedValue(scriptArray.asReturnedValue()); +} + +void QQuickWebEngineScriptCollection::setCollection(const QJSValue &scripts) +{ + if (!scripts.isArray()) + return; + + QList<QQuickWebEngineScript> scriptList; + quint32 length = scripts.property(QStringLiteral("length")).toUInt(); + for (quint32 i = 0; i < length; ++i) { + bool ok; + QQuickWebEngineScript s = parseScript(scripts.property(i), &ok); + if (!ok) { + qmlWarning(this) << "Unsupported script type"; + return; + } + scriptList.append(s); + } + if (scriptList != d->m_scripts) { + clear(); + insert(scriptList); + Q_EMIT collectionChanged(); + } +} diff --git a/src/webengine/api/qquickwebenginescriptcollection.h b/src/webengine/api/qquickwebenginescriptcollection.h new file mode 100644 index 000000000..e2fd8488d --- /dev/null +++ b/src/webengine/api/qquickwebenginescriptcollection.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** 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 The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKWEBENGINESCRIPTCOLLECTION_H +#define QQUICKWEBENGINESCRIPTCOLLECTION_H + +#include <QtWebEngine/qtwebengineglobal.h> +#include "qquickwebenginescript.h" +#include <QtCore/qscopedpointer.h> +#include <QtCore/qlist.h> +#include <QtCore/qset.h> +#include <QtCore/QObject> +#include <QtQml/QJSValue> + +QT_BEGIN_NAMESPACE +class QQuickWebEngineScriptCollectionPrivate; + +class Q_WEBENGINE_EXPORT QQuickWebEngineScriptCollection : public QObject +{ + Q_OBJECT +public: + Q_PROPERTY(QJSValue collection READ collection WRITE setCollection NOTIFY collectionChanged) + ~QQuickWebEngineScriptCollection(); + bool isEmpty() const { return !count(); } + int count() const; + inline int size() const { return count(); } + bool contains(const QQuickWebEngineScript &value) const; + + Q_INVOKABLE QQuickWebEngineScript findScript(const QString &name) const; + Q_INVOKABLE QList<QQuickWebEngineScript> findScripts(const QString &name) const; + + Q_INVOKABLE void insert(const QQuickWebEngineScript &); + Q_INVOKABLE void insert(const QList<QQuickWebEngineScript> &list); + + Q_INVOKABLE bool remove(const QQuickWebEngineScript &); + Q_INVOKABLE void clear(); + + QJSValue collection() const; + void setCollection(const QJSValue &scripts); + + QList<QQuickWebEngineScript> toList() const; +Q_SIGNALS: + void collectionChanged(); + +private: + Q_DISABLE_COPY(QQuickWebEngineScriptCollection) + QQuickWebEngineScriptCollection(QQuickWebEngineScriptCollectionPrivate *); + QScopedPointer<QQuickWebEngineScriptCollectionPrivate> d; + friend class QQuickWebEngineProfilePrivate; + friend class QQuickWebEngineViewPrivate; +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QQuickWebEngineScriptCollection *) + +#endif // QWEBENGINESCRIPTCOLLECTION_H diff --git a/src/webengine/api/qquickwebenginescript_p.h b/src/webengine/api/qquickwebenginescriptcollection_p.h index 30b47a654..79c70f928 100644 --- a/src/webengine/api/qquickwebenginescript_p.h +++ b/src/webengine/api/qquickwebenginescriptcollection_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtWebEngine module of the Qt Toolkit. @@ -37,8 +37,8 @@ ** ****************************************************************************/ -#ifndef QQUICKWEBENGINESCRIPT_P_H -#define QQUICKWEBENGINESCRIPT_P_H +#ifndef QQUICKWEBENGINESCRIPTCOLLECTION_P_H +#define QQUICKWEBENGINESCRIPTCOLLECTION_P_H // // W A R N I N G @@ -51,37 +51,46 @@ // We mean it. // -#include "qquickwebenginescript.h" +#include "qtwebenginecoreglobal.h" -#include <QtCore/QBasicTimer> -#include "user_script.h" +#include "qquickwebenginescript.h" #include "web_contents_adapter.h" +#include <QtCore/QSet> +#include <QtCore/QSharedPointer> + namespace QtWebEngineCore { class UserResourceControllerHost; -class WebContentsAdapter; } // namespace QT_BEGIN_NAMESPACE - -class QQuickWebEngineScriptPrivate { +class QQuickWebEngineScriptCollectionPrivate +{ public: - Q_DECLARE_PUBLIC(QQuickWebEngineScript) - QQuickWebEngineScriptPrivate(); - void aboutToUpdateUnderlyingScript(); - void bind(QtWebEngineCore::UserResourceControllerHost *, QtWebEngineCore::WebContentsAdapter * = 0); + QQuickWebEngineScriptCollectionPrivate( + QtWebEngineCore::UserResourceControllerHost *, + QSharedPointer<QtWebEngineCore::WebContentsAdapter> = + QSharedPointer<QtWebEngineCore::WebContentsAdapter>()); - QtWebEngineCore::UserScript coreScript; - QBasicTimer m_basicTimer; - QtWebEngineCore::UserResourceControllerHost *m_controllerHost; - QtWebEngineCore::WebContentsAdapter *m_adapter; - QUrl m_sourceUrl; + int count() const; + bool contains(const QQuickWebEngineScript &) const; + QList<QQuickWebEngineScript> toList(const QString &scriptName = QString()) const; + QQuickWebEngineScript find(const QString &name) const; -private: - QQuickWebEngineScript *q_ptr; + void initializationFinished(QSharedPointer<QtWebEngineCore::WebContentsAdapter> contents); + + void insert(const QQuickWebEngineScript &); + bool remove(const QQuickWebEngineScript &); + void clear(); + void reserve(int); +private: + QtWebEngineCore::UserResourceControllerHost *m_scriptController; + QSharedPointer<QtWebEngineCore::WebContentsAdapter> m_contents; + QList<QQuickWebEngineScript> m_scripts; + friend class QQuickWebEngineScriptCollection; }; QT_END_NAMESPACE -#endif // QQUICKWEBENGINESCRIPT_P_H +#endif // QWEBENGINESCRIPTCOLLECTION__PH diff --git a/src/webengine/api/qquickwebenginesingleton.cpp b/src/webengine/api/qquickwebenginesingleton.cpp index 2fbc95c32..e61c4e5bf 100644 --- a/src/webengine/api/qquickwebenginesingleton.cpp +++ b/src/webengine/api/qquickwebenginesingleton.cpp @@ -91,6 +91,11 @@ QQuickWebEngineProfile *QQuickWebEngineSingleton::defaultProfile() const return QQuickWebEngineProfile::defaultProfile(); } +QQuickWebEngineScript QQuickWebEngineSingleton::script() const +{ + return QQuickWebEngineScript(); +} + #include "moc_qquickwebenginesingleton_p.cpp" QT_END_NAMESPACE diff --git a/src/webengine/api/qquickwebenginesingleton_p.h b/src/webengine/api/qquickwebenginesingleton_p.h index eb33cc06d..ec1b779f8 100644 --- a/src/webengine/api/qquickwebenginesingleton_p.h +++ b/src/webengine/api/qquickwebenginesingleton_p.h @@ -53,6 +53,7 @@ #include <QtWebEngine/private/qtwebengineglobal_p.h> #include <QObject> +#include "qquickwebenginescript.h" QT_BEGIN_NAMESPACE @@ -63,10 +64,10 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineSingleton : public QObject { Q_OBJECT Q_PROPERTY(QQuickWebEngineSettings* settings READ settings CONSTANT FINAL) Q_PROPERTY(QQuickWebEngineProfile* defaultProfile READ defaultProfile CONSTANT FINAL REVISION 1) - public: QQuickWebEngineSettings *settings() const; QQuickWebEngineProfile *defaultProfile() const; + Q_INVOKABLE QQuickWebEngineScript script() const; }; QT_END_NAMESPACE diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index 8086b7d1d..01f604736 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -57,21 +57,19 @@ #include "qquickwebenginenewviewrequest_p.h" #include "qquickwebengineprofile_p.h" #include "qquickwebenginesettings_p.h" -#include "qquickwebenginescript_p.h" #include "qquickwebenginetouchhandleprovider_p_p.h" #include "qwebenginecertificateerror.h" #include "qwebenginefindtextresult.h" #include "qwebenginefullscreenrequest.h" #include "qwebenginequotarequest.h" #include "qwebengineregisterprotocolhandlerrequest.h" - +#include "qquickwebenginescriptcollection_p.h" #if QT_CONFIG(webengine_testsupport) #include "qquickwebenginetestsupport_p.h" #endif #include "render_widget_host_view_qt_delegate_quick.h" #include "render_widget_host_view_qt_delegate_quickwindow.h" -#include "renderer_host/user_resource_controller_host.h" #include "ui_delegates_manager.h" #include "web_contents_adapter.h" #include "web_engine_error.h" @@ -183,6 +181,9 @@ void QQuickWebEngineViewPrivate::initializeProfile() m_profile->d_ptr->addWebContentsAdapterClient(this); m_settings.reset(new QQuickWebEngineSettings(m_profile->settings())); adapter->setClient(this); + m_scriptCollection.reset( + new QQuickWebEngineScriptCollection(new QQuickWebEngineScriptCollectionPrivate( + profileAdapter()->userResourceController(), adapter))); } } @@ -928,8 +929,7 @@ void QQuickWebEngineViewPrivate::initializationFinished() if (devToolsView && devToolsView->d_ptr->adapter) adapter->openDevToolsFrontend(devToolsView->d_ptr->adapter); - for (QQuickWebEngineScript *script : qAsConst(m_userScripts)) - script->d_func()->bind(profileAdapter()->userResourceController(), adapter.data()); + m_scriptCollection->d->initializationFinished(adapter); if (q->window()) adapter->setVisible(q->isVisible()); @@ -1195,14 +1195,10 @@ QQuickWebEngineSettings *QQuickWebEngineView::settings() return d->m_settings.data(); } -QQmlListProperty<QQuickWebEngineScript> QQuickWebEngineView::userScripts() +QQuickWebEngineScriptCollection *QQuickWebEngineView::userScripts() { Q_D(QQuickWebEngineView); - return QQmlListProperty<QQuickWebEngineScript>(this, d, - d->userScripts_append, - d->userScripts_count, - d->userScripts_at, - d->userScripts_clear); + return d->m_scriptCollection.data(); } void QQuickWebEngineViewPrivate::updateAdapter() @@ -2209,43 +2205,6 @@ QPointF QQuickWebEngineView::scrollPosition() const return d->adapter->lastScrollOffset(); } -void QQuickWebEngineViewPrivate::userScripts_append(QQmlListProperty<QQuickWebEngineScript> *p, QQuickWebEngineScript *script) -{ - Q_ASSERT(p && p->data); - QQuickWebEngineViewPrivate *d = static_cast<QQuickWebEngineViewPrivate*>(p->data); - d->m_userScripts.append(script); - // If the adapter hasn't been initialized, we'll bind the scripts in initializationFinished() - if (!d->adapter->isInitialized()) - return; - UserResourceControllerHost *resourceController = d->profileAdapter()->userResourceController(); - script->d_func()->bind(resourceController, d->adapter.data()); -} - -int QQuickWebEngineViewPrivate::userScripts_count(QQmlListProperty<QQuickWebEngineScript> *p) -{ - Q_ASSERT(p && p->data); - QQuickWebEngineViewPrivate *d = static_cast<QQuickWebEngineViewPrivate*>(p->data); - return d->m_userScripts.count(); -} - -QQuickWebEngineScript *QQuickWebEngineViewPrivate::userScripts_at(QQmlListProperty<QQuickWebEngineScript> *p, int idx) -{ - Q_ASSERT(p && p->data); - QQuickWebEngineViewPrivate *d = static_cast<QQuickWebEngineViewPrivate*>(p->data); - return d->m_userScripts.at(idx); -} - -void QQuickWebEngineViewPrivate::userScripts_clear(QQmlListProperty<QQuickWebEngineScript> *p) -{ - Q_ASSERT(p && p->data); - QQuickWebEngineViewPrivate *d = static_cast<QQuickWebEngineViewPrivate*>(p->data); - d->m_userScripts.clear(); - if (!d->adapter->isInitialized()) - return; - UserResourceControllerHost *resourceController = d->profileAdapter()->userResourceController(); - resourceController->clearAllScripts(d->adapter.data()); -} - void QQuickWebEngineView::componentComplete() { QQuickItem::componentComplete(); diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h index 68c40616d..bf058c4d3 100644 --- a/src/webengine/api/qquickwebengineview_p.h +++ b/src/webengine/api/qquickwebengineview_p.h @@ -88,6 +88,7 @@ class QWebEngineFullScreenRequest; class QWebEngineQuotaRequest; class QWebEngineRegisterProtocolHandlerRequest; class QWebEngineContextMenuRequest; +class QQuickWebEngineScriptCollection; #if QT_CONFIG(webengine_testsupport) class QQuickWebEngineTestSupport; @@ -113,7 +114,7 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem { #if QT_CONFIG(webengine_webchannel) Q_PROPERTY(QQmlWebChannel *webChannel READ webChannel WRITE setWebChannel NOTIFY webChannelChanged REVISION 1 FINAL) #endif - Q_PROPERTY(QQmlListProperty<QQuickWebEngineScript> userScripts READ userScripts FINAL REVISION 1) + Q_PROPERTY(QQuickWebEngineScriptCollection *userScripts READ userScripts FINAL REVISION 1) Q_PROPERTY(bool activeFocusOnPress READ activeFocusOnPress WRITE setActiveFocusOnPress NOTIFY activeFocusOnPressChanged REVISION 2 FINAL) Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged REVISION 2 FINAL) Q_PROPERTY(QSizeF contentsSize READ contentsSize NOTIFY contentsSizeChanged FINAL REVISION 3) @@ -470,7 +471,7 @@ public: QQuickWebEngineProfile *profile(); void setProfile(QQuickWebEngineProfile *); - QQmlListProperty<QQuickWebEngineScript> userScripts(); + QQuickWebEngineScriptCollection *userScripts(); QQuickWebEngineSettings *settings(); QQmlWebChannel *webChannel(); diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index d8219751e..b16263d5f 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -52,6 +52,7 @@ // #include "qquickwebengineview_p.h" +#include "qquickwebenginescriptcollection.h" #include "render_view_context_menu_qt.h" #include "touch_handle_drawable_client.h" #include "web_contents_adapter_client.h" @@ -187,12 +188,6 @@ public: void widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegateQuick *oldWidget, QtWebEngineCore::RenderWidgetHostViewQtDelegateQuick *newWidget); - // QQmlListPropertyHelpers - static void userScripts_append(QQmlListProperty<QQuickWebEngineScript> *p, QQuickWebEngineScript *script); - static int userScripts_count(QQmlListProperty<QQuickWebEngineScript> *p); - static QQuickWebEngineScript *userScripts_at(QQmlListProperty<QQuickWebEngineScript> *p, int idx); - static void userScripts_clear(QQmlListProperty<QQuickWebEngineScript> *p); - QQuickWebEngineProfile *m_profile; QSharedPointer<QtWebEngineCore::WebContentsAdapter> adapter; QScopedPointer<QQuickWebEngineHistory> m_history; @@ -231,13 +226,13 @@ private: }; QScopedPointer<QtWebEngineCore::UIDelegatesManager> m_uIDelegatesManager; - QList<QQuickWebEngineScript *> m_userScripts; QColor m_backgroundColor; qreal m_zoomFactor; bool m_ui2Enabled; bool m_profileInitialized; QWebEngineContextMenuRequest *m_contextMenuRequest; LoadVisuallyCommittedState m_loadVisuallyCommittedState = NotCommitted; + QScopedPointer<QQuickWebEngineScriptCollection> m_scriptCollection; }; #ifndef QT_NO_ACCESSIBILITY diff --git a/src/webengine/module.pro b/src/webengine/module.pro index 8b1cab596..b796c3d97 100644 --- a/src/webengine/module.pro +++ b/src/webengine/module.pro @@ -24,12 +24,13 @@ SOURCES = \ api/qquickwebenginenavigationrequest.cpp \ api/qquickwebenginenewviewrequest.cpp \ api/qquickwebengineprofile.cpp \ - api/qquickwebenginescript.cpp \ api/qquickwebenginesettings.cpp \ api/qquickwebenginesingleton.cpp \ api/qquickwebenginetouchhandleprovider.cpp \ api/qquickwebengineview.cpp \ api/qtwebengineglobal.cpp \ + api/qquickwebenginescript.cpp \ + api/qquickwebenginescriptcollection.cpp \ render_widget_host_view_qt_delegate_quick.cpp \ render_widget_host_view_qt_delegate_quickwindow.cpp \ ui_delegates_manager.cpp @@ -48,13 +49,14 @@ HEADERS = \ api/qquickwebenginenewviewrequest_p.h \ api/qquickwebengineprofile.h \ api/qquickwebengineprofile_p.h \ - api/qquickwebenginescript.h \ - api/qquickwebenginescript_p.h \ api/qquickwebenginesettings_p.h \ api/qquickwebenginesingleton_p.h \ api/qquickwebenginetouchhandleprovider_p_p.h \ api/qquickwebengineview_p.h \ api/qquickwebengineview_p_p.h \ + api/qquickwebenginescript.h \ + api/qquickwebenginescriptcollection.h \ + api/qquickwebenginescriptcollection_p.h \ render_widget_host_view_qt_delegate_quick.h \ render_widget_host_view_qt_delegate_quickwindow.h \ ui_delegates_manager.h diff --git a/src/webengine/plugin/plugin.cpp b/src/webengine/plugin/plugin.cpp index 72ff597eb..d92ee59ec 100644 --- a/src/webengine/plugin/plugin.cpp +++ b/src/webengine/plugin/plugin.cpp @@ -105,7 +105,9 @@ public: qmlRegisterType<QQuickWebEngineProfile, 3>(uri, 1, 4, "WebEngineProfile"); qmlRegisterType<QQuickWebEngineProfile, 4>(uri, 1, 5, "WebEngineProfile"); qmlRegisterType<QQuickWebEngineProfile, 5>(uri, 1, 9, "WebEngineProfile"); - qmlRegisterType<QQuickWebEngineScript>(uri, 1, 1, "WebEngineScript"); + qRegisterMetaType<QQuickWebEngineScript>(); + qmlRegisterUncreatableType<QQuickWebEngineScript>( + uri, 1, 1, "WebEngineScript", msgUncreatableType("WebEngineScript")); // for enums qRegisterMetaType<QWebEngineCertificateError>(); qmlRegisterUncreatableType<QWebEngineCertificateError>(uri, 1, 1, "WebEngineCertificateError", msgUncreatableType("WebEngineCertificateError")); qmlRegisterUncreatableType<QWebEngineDownloadRequest>(uri, 1, 1, "WebEngineDownloadRequest", diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp index dc6f9c7c3..091b24469 100644 --- a/tests/auto/quick/publicapi/tst_publicapi.cpp +++ b/tests/auto/quick/publicapi/tst_publicapi.cpp @@ -104,7 +104,7 @@ static const QStringList hardcodedTypes = QStringList() << "const QQuickWebEngineContextMenuData*" << "QWebEngineCookieStore*" << "Qt::LayoutDirection" - ; + << "QQuickWebEngineScriptCollection*"; static const QStringList expectedAPI = QStringList() << "QQuickWebEngineAction.text --> QString" @@ -361,7 +361,7 @@ static const QStringList expectedAPI = QStringList() << "QQuickWebEngineProfile.storageNameChanged() --> void" << "QQuickWebEngineProfile.useForGlobalCertificateVerification --> bool" << "QQuickWebEngineProfile.useForGlobalCertificateVerificationChanged() --> void" - << "QQuickWebEngineProfile.userScripts --> QQmlListProperty<QQuickWebEngineScript>" + << "QQuickWebEngineProfile.userScripts --> QQuickWebEngineScriptCollection*" << "QQuickWebEngineScript.ApplicationWorld --> ScriptWorldId" << "QQuickWebEngineScript.Deferred --> InjectionPoint" << "QQuickWebEngineScript.DocumentCreation --> InjectionPoint" @@ -369,11 +369,8 @@ static const QStringList expectedAPI = QStringList() << "QQuickWebEngineScript.MainWorld --> ScriptWorldId" << "QQuickWebEngineScript.UserWorld --> ScriptWorldId" << "QQuickWebEngineScript.injectionPoint --> InjectionPoint" - << "QQuickWebEngineScript.injectionPointChanged(InjectionPoint) --> void" << "QQuickWebEngineScript.name --> QString" - << "QQuickWebEngineScript.nameChanged(QString) --> void" << "QQuickWebEngineScript.runOnSubframes --> bool" - << "QQuickWebEngineScript.runOnSubframesChanged(bool) --> void" << "QQuickWebEngineScript.setInjectionPoint(InjectionPoint) --> void" << "QQuickWebEngineScript.setName(QString) --> void" << "QQuickWebEngineScript.setRunOnSubframes(bool) --> void" @@ -381,12 +378,9 @@ static const QStringList expectedAPI = QStringList() << "QQuickWebEngineScript.setSourceUrl(QUrl) --> void" << "QQuickWebEngineScript.setWorldId(ScriptWorldId) --> void" << "QQuickWebEngineScript.sourceCode --> QString" - << "QQuickWebEngineScript.sourceCodeChanged(QString) --> void" << "QQuickWebEngineScript.sourceUrl --> QUrl" - << "QQuickWebEngineScript.sourceUrlChanged(QUrl) --> void" << "QQuickWebEngineScript.toString() --> QString" << "QQuickWebEngineScript.worldId --> ScriptWorldId" - << "QQuickWebEngineScript.worldIdChanged(ScriptWorldId) --> void" << "QQuickWebEngineSettings.AllowAllUnknownUrlSchemes --> UnknownUrlSchemePolicy" << "QQuickWebEngineSettings.AllowUnknownUrlSchemesFromUserInteraction --> UnknownUrlSchemePolicy" << "QQuickWebEngineSettings.DisallowUnknownUrlSchemes --> UnknownUrlSchemePolicy" @@ -454,6 +448,7 @@ static const QStringList expectedAPI = QStringList() << "QQuickWebEngineSettings.webRTCPublicInterfacesOnlyChanged() --> void" << "QQuickWebEngineSingleton.defaultProfile --> QQuickWebEngineProfile*" << "QQuickWebEngineSingleton.settings --> QQuickWebEngineSettings*" + << "QQuickWebEngineSingleton.script() --> QQuickWebEngineScript" << "QQuickWebEngineView.action(WebAction) --> QQuickWebEngineAction*" << "QQuickWebEngineView.A0 --> PrintedPageSizeId" << "QQuickWebEngineView.A1 --> PrintedPageSizeId" @@ -765,7 +760,7 @@ static const QStringList expectedAPI = QStringList() << "QQuickWebEngineView.triggerWebAction(WebAction) --> void" << "QQuickWebEngineView.url --> QUrl" << "QQuickWebEngineView.urlChanged() --> void" - << "QQuickWebEngineView.userScripts --> QQmlListProperty<QQuickWebEngineScript>" + << "QQuickWebEngineView.userScripts --> QQuickWebEngineScriptCollection*" #if QT_CONFIG(webengine_webchannel) << "QQuickWebEngineView.webChannel --> QQmlWebChannel*" #endif diff --git a/tests/auto/quick/qmltests/data/tst_userScripts.qml b/tests/auto/quick/qmltests/data/tst_userScripts.qml index f4fcc30ab..4d0bd28bf 100644 --- a/tests/auto/quick/qmltests/data/tst_userScripts.qml +++ b/tests/auto/quick/qmltests/data/tst_userScripts.qml @@ -31,32 +31,33 @@ import QtTest 1.0 import QtWebEngine 1.2 Item { - WebEngineScript { - id: changeDocumentTitleScript - sourceUrl: Qt.resolvedUrl("change-document-title.js") - injectionPoint: WebEngineScript.DocumentReady + + function changeDocumentTitleScript() { + return { name: "changeDocumentTitleScript", + sourceUrl: Qt.resolvedUrl("change-document-title.js"), + injectionPoint: WebEngineScript.DocumentReady } } - WebEngineScript { - id: appendDocumentTitleScript - sourceUrl: Qt.resolvedUrl("append-document-title.js") - injectionPoint: WebEngineScript.DocumentReady + function appendDocumentTitleScript() { + return { sourceUrl: Qt.resolvedUrl("append-document-title.js"), + injectionPoint: WebEngineScript.DocumentReady } } - WebEngineScript { - id: bigUserScript - sourceUrl: Qt.resolvedUrl("big-user-script.js") - injectionPoint: WebEngineScript.DocumentReady + function bigUserScript() { + return { sourceUrl: Qt.resolvedUrl("big-user-script.js"), + injectionPoint: WebEngineScript.DocumentReady } } - WebEngineScript { - id: scriptWithMetadata - sourceUrl: Qt.resolvedUrl("script-with-metadata.js") + function scriptWithMetadata() { + var script = WebEngine.script() + script.sourceUrl = Qt.resolvedUrl("script-with-metadata.js") + return script } - WebEngineScript { - id: scriptWithBadMatchMetadata - sourceUrl: Qt.resolvedUrl("script-with-bad-match-metadata.js") + function scriptWithBadMatchMetadata() { + var script = WebEngine.script() + script.sourceUrl = Qt.resolvedUrl("script-with-bad-match-metadata.js") + return script } TestWebEngineView { @@ -79,21 +80,22 @@ Item { onNavigationRequested: { var urlString = request.url.toString(); if (urlString.indexOf("test1.html") !== -1) - userScripts = [ changeDocumentTitleScript ]; + userScripts.collection = [ changeDocumentTitleScript() ]; else if (urlString.indexOf("test2.html") !== -1) - userScripts = [ appendDocumentTitleScript ]; + userScripts.collection = [ appendDocumentTitleScript() ]; else - userScripts = []; + userScripts.collection = []; } } TestCase { name: "WebEngineViewUserScripts" + function init() { webEngineView.url = ""; - webEngineView.userScripts = []; - webEngineView.profile.userScripts = []; + webEngineView.userScripts.collection = []; + webEngineView.profile.userScripts.collection = []; } function test_oneScript() { @@ -101,7 +103,8 @@ Item { webEngineView.waitForLoadSucceeded(); tryCompare(webEngineView, "title", "Test page 1"); - webEngineView.userScripts = [ changeDocumentTitleScript ]; + webEngineView.userScripts.collection = [ changeDocumentTitleScript() ] + compare(webEngineView.title, "Test page 1"); webEngineView.reload(); @@ -112,7 +115,7 @@ Item { webEngineView.waitForLoadSucceeded(); tryCompare(webEngineView, "title", "New title"); - webEngineView.userScripts = []; + webEngineView.userScripts.collection = []; compare(webEngineView.title, "New title"); webEngineView.reload(); @@ -124,23 +127,25 @@ Item { webEngineView.url = Qt.resolvedUrl("test1.html"); webEngineView.waitForLoadSucceeded(); tryCompare(webEngineView, "title", "Test page 1"); - - webEngineView.userScripts = [ changeDocumentTitleScript, appendDocumentTitleScript ]; + var script1 = changeDocumentTitleScript(); + var script2 = appendDocumentTitleScript(); + script2.injectionPoint = WebEngineScript.Deferred; + webEngineView.userScripts.collection = [ script1, script2 ]; // Make sure the scripts are loaded in order. - appendDocumentTitleScript.injectionPoint = WebEngineScript.Deferred webEngineView.reload(); webEngineView.waitForLoadSucceeded(); tryCompare(webEngineView, "title", "New title with appendix"); - appendDocumentTitleScript.injectionPoint = WebEngineScript.DocumentReady - changeDocumentTitleScript.injectionPoint = WebEngineScript.Deferred + script2.injectionPoint = WebEngineScript.DocumentReady + script1.injectionPoint = WebEngineScript.Deferred + webEngineView.userScripts.collection = [ script1, script2 ]; webEngineView.reload(); webEngineView.waitForLoadSucceeded(); tryCompare(webEngineView, "title", "New title"); // Make sure we can remove scripts from the preload list. - webEngineView.userScripts = [ appendDocumentTitleScript ]; + webEngineView.userScripts.collection = [ script2 ]; webEngineView.reload(); webEngineView.waitForLoadSucceeded(); tryCompare(webEngineView, "title", "Test page 1 with appendix"); @@ -163,17 +168,18 @@ Item { } function test_bigScript() { - webEngineView.userScripts = [ bigUserScript ]; + webEngineView.userScripts.collection = [ bigUserScript() ]; webEngineView.url = Qt.resolvedUrl("test1.html"); webEngineView.waitForLoadSucceeded(); tryCompare(webEngineView , "title", "Big user script changed title"); } function test_parseMetadataHeader() { - compare(scriptWithMetadata.name, "Test script"); - compare(scriptWithMetadata.injectionPoint, WebEngineScript.DocumentReady); + var script = scriptWithMetadata() + compare(script.name, "Test script"); + compare(script.injectionPoint, WebEngineScript.DocumentReady); - webEngineView.userScripts = [ scriptWithMetadata ]; + webEngineView.userScripts.collection = [ script ]; // @include *data/test*.html webEngineView.url = Qt.resolvedUrl("test1.html"); @@ -197,10 +203,11 @@ Item { } function test_dontInjectBadUrlPatternsEverywhere() { - compare(scriptWithBadMatchMetadata.name, "Test bad match script"); - compare(scriptWithBadMatchMetadata.injectionPoint, WebEngineScript.DocumentReady); + var script = scriptWithBadMatchMetadata(); + compare(script.name, "Test bad match script"); + compare(script.injectionPoint, WebEngineScript.DocumentReady); - webEngineView.userScripts = [ scriptWithBadMatchMetadata ]; + webEngineView.userScripts.collection = [ script ]; // @match some:junk webEngineView.url = Qt.resolvedUrl("test2.html"); @@ -209,7 +216,7 @@ Item { } function test_profileWideScript() { - webEngineView.profile.userScripts = [ changeDocumentTitleScript ]; + webEngineView.profile.userScripts.collection = [ changeDocumentTitleScript() ]; webEngineView.url = Qt.resolvedUrl("test1.html"); webEngineView.waitForLoadSucceeded(); diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp index a95c231a1..d0dcd0fcc 100644 --- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp +++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp @@ -38,6 +38,7 @@ #include <QtQml/QQmlEngine> #include <QtTest/QtTest> #include <QtWebEngine/QQuickWebEngineProfile> +#include <QtWebEngine/QQuickWebEngineScriptCollection> #include <QtGui/private/qinputmethod_p.h> #include <QtWebEngine/private/qquickwebengineview_p.h> #include <QtWebEngine/private/qquickwebenginesettings_p.h> @@ -1035,10 +1036,10 @@ void tst_QQuickWebEngineView::userScripts() QScopedPointer<QQuickWebEngineView> webEngineView2(newWebEngineView()); webEngineView2->setParentItem(m_window->contentItem()); - QQmlListReference list(webEngineView1->profile(), "userScripts"); + QQuickWebEngineScriptCollection *collection = webEngineView1->profile()->userScripts(); QQuickWebEngineScript script; script.setSourceCode("document.title = 'New title';"); - list.append(&script); + collection->insert(script); webEngineView1->setUrl(urlFromTestPath("html/basic_page.html")); QVERIFY(waitForLoadSucceeded(webEngineView1.data())); @@ -1048,7 +1049,7 @@ void tst_QQuickWebEngineView::userScripts() QVERIFY(waitForLoadSucceeded(webEngineView2.data())); QTRY_COMPARE(webEngineView2->title(), QStringLiteral("New title")); - list.clear(); + collection->clear(); } void tst_QQuickWebEngineView::javascriptClipboard_data() |