diff --git a/src/lib/plugins/pluginproxy.h b/src/lib/plugins/pluginproxy.h index 3d0aae45a..9d81cc7d3 100644 --- a/src/lib/plugins/pluginproxy.h +++ b/src/lib/plugins/pluginproxy.h @@ -21,8 +21,10 @@ #include "plugins.h" #include "qzcommon.h" -class BrowserWindow; +#include + class WebPage; +class BrowserWindow; class QUPZILLA_EXPORT PluginProxy : public Plugins { diff --git a/src/plugins.pri b/src/plugins.pri index 7dd7c8c8b..d235ba230 100644 --- a/src/plugins.pri +++ b/src/plugins.pri @@ -35,6 +35,8 @@ DESTDIR = $$QZ_DESTDIR/plugins/ QT *= webenginewidgets network +CONFIG += c++11 + OBJECTS_DIR = build MOC_DIR = build RCC_DIR = build diff --git a/src/plugins/GreaseMonkey/gm_addscriptdialog.h b/src/plugins/GreaseMonkey/gm_addscriptdialog.h index 97192254a..8f2a1b0db 100644 --- a/src/plugins/GreaseMonkey/gm_addscriptdialog.h +++ b/src/plugins/GreaseMonkey/gm_addscriptdialog.h @@ -33,7 +33,7 @@ class GM_AddScriptDialog : public QDialog Q_OBJECT public: - explicit GM_AddScriptDialog(GM_Manager* manager, GM_Script* script, QWidget* parent); + explicit GM_AddScriptDialog(GM_Manager *manager, GM_Script *script, QWidget *parent = Q_NULLPTR); ~GM_AddScriptDialog(); private slots: diff --git a/src/plugins/GreaseMonkey/gm_downloader.cpp b/src/plugins/GreaseMonkey/gm_downloader.cpp index 616e31968..b202c8eaf 100644 --- a/src/plugins/GreaseMonkey/gm_downloader.cpp +++ b/src/plugins/GreaseMonkey/gm_downloader.cpp @@ -30,20 +30,12 @@ #include #include "qzregexp.h" -GM_Downloader::GM_Downloader(const QNetworkRequest &request, GM_Manager* manager) +GM_Downloader::GM_Downloader(const QUrl &url, GM_Manager* manager) : QObject() , m_manager(manager) - , m_widget(0) { - m_reply = new FollowRedirectReply(request.url(), mApp->networkManager()); + m_reply = new FollowRedirectReply(url, mApp->networkManager()); connect(m_reply, SIGNAL(finished()), this, SLOT(scriptDownloaded())); - - QVariant v = request.attribute((QNetworkRequest::Attribute)(QNetworkRequest::User + 100)); - WebPage* webPage = static_cast(v.value()); - - if (WebPage::isPointerSafeToUse(webPage)) { - m_widget = webPage->view(); - } } void GM_Downloader::scriptDownloaded() @@ -148,7 +140,7 @@ void GM_Downloader::downloadRequires() if (script->isValid()) { if (!m_manager->containsScript(script->fullName())) { - GM_AddScriptDialog dialog(m_manager, script, m_widget); + GM_AddScriptDialog dialog(m_manager, script); deleteScript = dialog.exec() != QDialog::Accepted; } else { diff --git a/src/plugins/GreaseMonkey/gm_downloader.h b/src/plugins/GreaseMonkey/gm_downloader.h index a4bbf40de..19eba794d 100644 --- a/src/plugins/GreaseMonkey/gm_downloader.h +++ b/src/plugins/GreaseMonkey/gm_downloader.h @@ -32,7 +32,7 @@ class GM_Downloader : public QObject { Q_OBJECT public: - explicit GM_Downloader(const QNetworkRequest &request, GM_Manager* manager); + explicit GM_Downloader(const QUrl &url, GM_Manager* manager); private slots: void scriptDownloaded(); @@ -43,7 +43,6 @@ private: GM_Manager* m_manager; FollowRedirectReply* m_reply; - QWidget* m_widget; QString m_fileName; QList m_requireUrls; diff --git a/src/plugins/GreaseMonkey/gm_manager.cpp b/src/plugins/GreaseMonkey/gm_manager.cpp index 2ef377668..27662c8bd 100644 --- a/src/plugins/GreaseMonkey/gm_manager.cpp +++ b/src/plugins/GreaseMonkey/gm_manager.cpp @@ -30,9 +30,10 @@ #include #include -#include #include #include +#include +#include GM_Manager::GM_Manager(const QString &sPath, QObject* parent) : QObject(parent) @@ -52,9 +53,9 @@ void GM_Manager::showSettings(QWidget* parent) m_settings.data()->raise(); } -void GM_Manager::downloadScript(const QNetworkRequest &request) +void GM_Manager::downloadScript(const QUrl &url) { - new GM_Downloader(request, this); + new GM_Downloader(url, this); } QString GM_Manager::settinsPath() const @@ -109,41 +110,34 @@ void GM_Manager::unloadPlugin() QList GM_Manager::allScripts() const { - QList list; - list.append(m_startScripts); - list.append(m_endScripts); - - return list; + return m_scripts; } bool GM_Manager::containsScript(const QString &fullName) const { - foreach (GM_Script* script, m_startScripts) { - if (fullName == script->fullName()) { - return true; - } - } - - foreach (GM_Script* script, m_endScripts) { + foreach (GM_Script* script, m_scripts) { if (fullName == script->fullName()) { return true; } } return false; - } void GM_Manager::enableScript(GM_Script* script) { script->setEnabled(true); m_disabledScripts.removeOne(script->fullName()); + + mApp->webProfile()->scripts().insert(script->webScript()); } void GM_Manager::disableScript(GM_Script* script) { script->setEnabled(false); m_disabledScripts.append(script->fullName()); + + mApp->webProfile()->scripts().remove(script->webScript()); } bool GM_Manager::addScript(GM_Script* script) @@ -152,12 +146,8 @@ bool GM_Manager::addScript(GM_Script* script) return false; } - if (script->startAt() == GM_Script::DocumentStart) { - m_startScripts.append(script); - } - else { - m_endScripts.append(script); - } + m_scripts.append(script); + mApp->webProfile()->scripts().insert(script->webScript()); emit scriptsChanged(); return true; @@ -169,12 +159,8 @@ bool GM_Manager::removeScript(GM_Script* script, bool removeFile) return false; } - if (script->startAt() == GM_Script::DocumentStart) { - m_startScripts.removeOne(script); - } - else { - m_endScripts.removeOne(script); - } + m_scripts.removeOne(script); + mApp->webProfile()->scripts().insert(script->webScript()); m_disabledScripts.removeOne(script->fullName()); @@ -194,51 +180,6 @@ void GM_Manager::showNotification(const QString &message, const QString &title) mApp->desktopNotifications()->showNotification(icon, title.isEmpty() ? tr("GreaseMonkey") : title, message); } -void GM_Manager::frameLoadStart() -{ - QWebFrame* frame = qobject_cast(sender()); - if (!frame) { - return; - } - - const QUrl url = QzTools::frameUrl(frame); - const QString urlScheme = url.scheme(); - const QString urlString = url.toEncoded(); - - if (!canRunOnScheme(urlScheme)) { - return; - } - - const QString readyState = frame->evaluateJavaScript(QSL("document.readyState")).toString(); - - frame->addToJavaScriptWindowObject(QSL("_qz_greasemonkey"), m_jsObject); - - foreach (GM_Script* script, m_startScripts) { - if (script->match(urlString)) { - frame->evaluateJavaScript(m_bootstrap + script->script()); - } - } - - foreach (GM_Script* script, m_endScripts) { - if (script->match(urlString)) { - // If DOMContentLoaded already fired - if (readyState == QL1S("complete")) { - frame->evaluateJavaScript(m_bootstrap + script->script()); - } - else { - const QString jscript = QString(QSL("window.addEventListener(\"DOMContentLoaded\",function(e) { \n%1\n }, true);")) - .arg(m_bootstrap + script->script()); - frame->evaluateJavaScript(jscript); - } - } - } -} - -void GM_Manager::frameCreated(QWebFrame *frame) -{ - connect(frame, SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(frameLoadStart())); -} - void GM_Manager::load() { QDir gmDir(m_settingsPath + QL1S("/greasemonkey")); @@ -263,15 +204,13 @@ void GM_Manager::load() continue; } + m_scripts.append(script); + if (m_disabledScripts.contains(script->fullName())) { script->setEnabled(false); } - - if (script->startAt() == GM_Script::DocumentStart) { - m_startScripts.append(script); - } else { - m_endScripts.append(script); + mApp->webProfile()->scripts().insert(script->webScript()); } } diff --git a/src/plugins/GreaseMonkey/gm_manager.h b/src/plugins/GreaseMonkey/gm_manager.h index 9e87774e2..3f47b657b 100644 --- a/src/plugins/GreaseMonkey/gm_manager.h +++ b/src/plugins/GreaseMonkey/gm_manager.h @@ -40,7 +40,7 @@ public: explicit GM_Manager(const QString &sPath, QObject* parent = 0); void showSettings(QWidget* parent); - void downloadScript(const QNetworkRequest &request); + void downloadScript(const QUrl &url); QString settinsPath() const; QString scriptsDirectory() const; @@ -68,9 +68,6 @@ public slots: void mainWindowCreated(BrowserWindow* window); void mainWindowDeleted(BrowserWindow* window); - void frameLoadStart(); - void frameCreated(QWebFrame* frame); - private slots: void load(); @@ -81,8 +78,7 @@ private: QStringList m_disabledScripts; GM_JSObject* m_jsObject; - QList m_endScripts; - QList m_startScripts; + QList m_scripts; QHash m_windows; }; diff --git a/src/plugins/GreaseMonkey/gm_plugin.cpp b/src/plugins/GreaseMonkey/gm_plugin.cpp index 8d1fb2a8c..01914be9e 100644 --- a/src/plugins/GreaseMonkey/gm_plugin.cpp +++ b/src/plugins/GreaseMonkey/gm_plugin.cpp @@ -53,21 +53,13 @@ void GM_Plugin::init(InitState state, const QString &settingsPath) { m_manager = new GM_Manager(settingsPath, this); - connect(mApp->plugins(), SIGNAL(webPageCreated(WebPage*)), this, SLOT(webPageCreated(WebPage*))); connect(mApp->plugins(), SIGNAL(mainWindowCreated(BrowserWindow*)), m_manager, SLOT(mainWindowCreated(BrowserWindow*))); connect(mApp->plugins(), SIGNAL(mainWindowDeleted(BrowserWindow*)), m_manager, SLOT(mainWindowDeleted(BrowserWindow*))); // Make sure userscripts works also with already created WebPages if (state == LateInitState) { - foreach (BrowserWindow* window, mApp->windows()) { + for (BrowserWindow *window : mApp->windows()) { m_manager->mainWindowCreated(window); - - for (int i = 0; i < window->tabWidget()->count(); ++i) { - WebTab* tab = qobject_cast(window->tabWidget()->widget(i)); - if (tab) { - webPageCreated(tab->webView()->page()); - } - } } } } @@ -96,26 +88,18 @@ void GM_Plugin::showSettings(QWidget* parent) m_manager->showSettings(parent); } -QNetworkReply* GM_Plugin::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice* outgoingData) +bool GM_Plugin::acceptNavigationRequest(WebPage *page, const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame) { - Q_UNUSED(outgoingData) + Q_UNUSED(page) + Q_UNUSED(type) + Q_UNUSED(isMainFrame) - if (op == QNetworkAccessManager::GetOperation && request.rawHeader("X-QupZilla-UserLoadAction") == QByteArray("1")) { - const QString urlString = request.url().toString(QUrl::RemoveFragment | QUrl::RemoveQuery); - - if (urlString.endsWith(QLatin1String(".user.js"))) { - m_manager->downloadScript(request); - return new EmptyNetworkReply; - } + if (url.toString().endsWith(QL1S(".user.js"))) { + m_manager->downloadScript(url); + return false; } - return 0; -} - -void GM_Plugin::webPageCreated(WebPage* page) -{ - m_manager->frameCreated(page->mainFrame()); - connect(page, SIGNAL(frameCreated(QWebFrame*)), m_manager, SLOT(frameCreated(QWebFrame*))); + return true; } #if QT_VERSION < 0x050000 diff --git a/src/plugins/GreaseMonkey/gm_plugin.h b/src/plugins/GreaseMonkey/gm_plugin.h index e7d80a57b..ba89d8ece 100644 --- a/src/plugins/GreaseMonkey/gm_plugin.h +++ b/src/plugins/GreaseMonkey/gm_plugin.h @@ -43,10 +43,7 @@ public: QTranslator* getTranslator(const QString &locale); void showSettings(QWidget* parent = 0); - QNetworkReply* createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice* outgoingData); - -private slots: - void webPageCreated(WebPage* page); + bool acceptNavigationRequest(WebPage *page, const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame); private: GM_Manager* m_manager; diff --git a/src/plugins/GreaseMonkey/gm_script.cpp b/src/plugins/GreaseMonkey/gm_script.cpp index 94d05f348..10571599d 100644 --- a/src/plugins/GreaseMonkey/gm_script.cpp +++ b/src/plugins/GreaseMonkey/gm_script.cpp @@ -23,7 +23,6 @@ #include #include -#include #include GM_Script::GM_Script(GM_Manager* manager, const QString &filePath) @@ -32,6 +31,7 @@ GM_Script::GM_Script(GM_Manager* manager, const QString &filePath) , m_fileWatcher(new DelayedFileWatcher(this)) , m_namespace("GreaseMonkeyNS") , m_startAt(DocumentEnd) + , m_noframes(false) , m_fileName(filePath) , m_enabled(true) , m_valid(false) @@ -81,6 +81,11 @@ GM_Script::StartAt GM_Script::startAt() const return m_startAt; } +bool GM_Script::noFrames() const +{ + return m_noframes; +} + bool GM_Script::isEnabled() const { return m_valid && m_enabled; @@ -118,11 +123,21 @@ QString GM_Script::script() const return m_script; } +QString GM_Script::metaData() const +{ + return m_metadata; +} + QString GM_Script::fileName() const { return m_fileName; } +QWebEngineScript GM_Script::webScript() const +{ + return m_webScript; +} + bool GM_Script::match(const QString &urlString) { if (!isEnabled()) { @@ -258,8 +273,14 @@ void GM_Script::parseScript() } int index = fileData.indexOf(QLatin1String("// ==/UserScript==")) + 18; - QString script = fileData.mid(index).trimmed(); + m_metadata = fileData.mid(0, index); + QString script = fileData.mid(index).trimmed(); + m_valid = !script.isEmpty(); + + m_script = QSL("(function(){%1\n%2\n})();").arg(m_manager->requireScripts(requireList), script); + +#if QTWEBENGINE_DISABLED QString jscript("(function(){" "function GM_getValue(name,val){return GM_getValueImpl('%1',name,val);}" "function GM_setValue(name,val){return GM_setValueImpl('%1',name,val);}" @@ -267,10 +288,12 @@ void GM_Script::parseScript() "function GM_listValues(){return GM_listValuesImpl('%1');}" "\n%2\n})();"); QString nspace = QCryptographicHash::hash(fullName().toUtf8(), QCryptographicHash::Md4).toHex(); +#endif - script.prepend(m_manager->requireScripts(requireList)); - script = jscript.arg(nspace, script); - - m_script = script; - m_valid = !script.isEmpty(); + // Create QWebEngineScript + m_webScript.setName(fullName()); + m_webScript.setInjectionPoint(startAt() == DocumentStart ? QWebEngineScript::DocumentCreation : QWebEngineScript::DocumentReady); + m_webScript.setWorldId(QWebEngineScript::MainWorld); + m_webScript.setRunsOnSubFrames(!m_noframes); + m_webScript.setSourceCode(QSL("%1\n%2").arg(m_metadata, m_script)); } diff --git a/src/plugins/GreaseMonkey/gm_script.h b/src/plugins/GreaseMonkey/gm_script.h index f0ec7868b..953d31fe0 100644 --- a/src/plugins/GreaseMonkey/gm_script.h +++ b/src/plugins/GreaseMonkey/gm_script.h @@ -23,6 +23,7 @@ #include #include #include +#include class QWebFrame; @@ -49,6 +50,7 @@ public: QUrl downloadUrl() const; StartAt startAt() const; + bool noFrames() const; bool isEnabled() const; void setEnabled(bool enable); @@ -57,8 +59,11 @@ public: QStringList exclude() const; QString script() const; + QString metaData() const; QString fileName() const; + QWebEngineScript webScript() const; + bool match(const QString &urlString); signals: @@ -83,11 +88,15 @@ private: QUrl m_downloadUrl; StartAt m_startAt; + bool m_noframes; QString m_script; + QString m_metadata; QString m_fileName; bool m_enabled; bool m_valid; + + QWebEngineScript m_webScript; }; #endif // GM_SCRIPT_H diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 459f1e588..02d1a3d9f 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -44,7 +44,6 @@ isEqual(QT_MAJOR_VERSION, 5): !qtHaveModule(KWallet): disablePlugin(KWalletPassw disablePlugin(AccessKeysNavigation) disablePlugin(AutoScroll) disablePlugin(CopyTitle) -disablePlugin(GreaseMonkey) disablePlugin(MailHandle) disablePlugin(MouseGestures) disablePlugin(PIM)