1
mirror of https://invent.kde.org/network/falkon.git synced 2024-11-14 02:52:12 +01:00

Bring back GreaseMonkey

Everything seems to work just fine. The only thing that doesn't
work now are GM_setValue and GM_getValue functions.
This commit is contained in:
David Rosca 2015-05-24 23:16:01 +02:00
parent 1387dbef64
commit e825f0268b
12 changed files with 78 additions and 136 deletions

View File

@ -21,8 +21,10 @@
#include "plugins.h" #include "plugins.h"
#include "qzcommon.h" #include "qzcommon.h"
class BrowserWindow; #include <QWebEnginePage>
class WebPage; class WebPage;
class BrowserWindow;
class QUPZILLA_EXPORT PluginProxy : public Plugins class QUPZILLA_EXPORT PluginProxy : public Plugins
{ {

View File

@ -35,6 +35,8 @@ DESTDIR = $$QZ_DESTDIR/plugins/
QT *= webenginewidgets network QT *= webenginewidgets network
CONFIG += c++11
OBJECTS_DIR = build OBJECTS_DIR = build
MOC_DIR = build MOC_DIR = build
RCC_DIR = build RCC_DIR = build

View File

@ -33,7 +33,7 @@ class GM_AddScriptDialog : public QDialog
Q_OBJECT Q_OBJECT
public: 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(); ~GM_AddScriptDialog();
private slots: private slots:

View File

@ -30,20 +30,12 @@
#include <QSettings> #include <QSettings>
#include "qzregexp.h" #include "qzregexp.h"
GM_Downloader::GM_Downloader(const QNetworkRequest &request, GM_Manager* manager) GM_Downloader::GM_Downloader(const QUrl &url, GM_Manager* manager)
: QObject() : QObject()
, m_manager(manager) , 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())); connect(m_reply, SIGNAL(finished()), this, SLOT(scriptDownloaded()));
QVariant v = request.attribute((QNetworkRequest::Attribute)(QNetworkRequest::User + 100));
WebPage* webPage = static_cast<WebPage*>(v.value<void*>());
if (WebPage::isPointerSafeToUse(webPage)) {
m_widget = webPage->view();
}
} }
void GM_Downloader::scriptDownloaded() void GM_Downloader::scriptDownloaded()
@ -148,7 +140,7 @@ void GM_Downloader::downloadRequires()
if (script->isValid()) { if (script->isValid()) {
if (!m_manager->containsScript(script->fullName())) { 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; deleteScript = dialog.exec() != QDialog::Accepted;
} }
else { else {

View File

@ -32,7 +32,7 @@ class GM_Downloader : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit GM_Downloader(const QNetworkRequest &request, GM_Manager* manager); explicit GM_Downloader(const QUrl &url, GM_Manager* manager);
private slots: private slots:
void scriptDownloaded(); void scriptDownloaded();
@ -43,7 +43,6 @@ private:
GM_Manager* m_manager; GM_Manager* m_manager;
FollowRedirectReply* m_reply; FollowRedirectReply* m_reply;
QWidget* m_widget;
QString m_fileName; QString m_fileName;
QList<QUrl> m_requireUrls; QList<QUrl> m_requireUrls;

View File

@ -30,9 +30,10 @@
#include <QTimer> #include <QTimer>
#include <QDir> #include <QDir>
#include <QWebFrame>
#include <QSettings> #include <QSettings>
#include <QStatusBar> #include <QStatusBar>
#include <QWebEngineProfile>
#include <QWebEngineScriptCollection>
GM_Manager::GM_Manager(const QString &sPath, QObject* parent) GM_Manager::GM_Manager(const QString &sPath, QObject* parent)
: QObject(parent) : QObject(parent)
@ -52,9 +53,9 @@ void GM_Manager::showSettings(QWidget* parent)
m_settings.data()->raise(); 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 QString GM_Manager::settinsPath() const
@ -109,41 +110,34 @@ void GM_Manager::unloadPlugin()
QList<GM_Script*> GM_Manager::allScripts() const QList<GM_Script*> GM_Manager::allScripts() const
{ {
QList<GM_Script*> list; return m_scripts;
list.append(m_startScripts);
list.append(m_endScripts);
return list;
} }
bool GM_Manager::containsScript(const QString &fullName) const bool GM_Manager::containsScript(const QString &fullName) const
{ {
foreach (GM_Script* script, m_startScripts) { foreach (GM_Script* script, m_scripts) {
if (fullName == script->fullName()) {
return true;
}
}
foreach (GM_Script* script, m_endScripts) {
if (fullName == script->fullName()) { if (fullName == script->fullName()) {
return true; return true;
} }
} }
return false; return false;
} }
void GM_Manager::enableScript(GM_Script* script) void GM_Manager::enableScript(GM_Script* script)
{ {
script->setEnabled(true); script->setEnabled(true);
m_disabledScripts.removeOne(script->fullName()); m_disabledScripts.removeOne(script->fullName());
mApp->webProfile()->scripts().insert(script->webScript());
} }
void GM_Manager::disableScript(GM_Script* script) void GM_Manager::disableScript(GM_Script* script)
{ {
script->setEnabled(false); script->setEnabled(false);
m_disabledScripts.append(script->fullName()); m_disabledScripts.append(script->fullName());
mApp->webProfile()->scripts().remove(script->webScript());
} }
bool GM_Manager::addScript(GM_Script* script) bool GM_Manager::addScript(GM_Script* script)
@ -152,12 +146,8 @@ bool GM_Manager::addScript(GM_Script* script)
return false; return false;
} }
if (script->startAt() == GM_Script::DocumentStart) { m_scripts.append(script);
m_startScripts.append(script); mApp->webProfile()->scripts().insert(script->webScript());
}
else {
m_endScripts.append(script);
}
emit scriptsChanged(); emit scriptsChanged();
return true; return true;
@ -169,12 +159,8 @@ bool GM_Manager::removeScript(GM_Script* script, bool removeFile)
return false; return false;
} }
if (script->startAt() == GM_Script::DocumentStart) { m_scripts.removeOne(script);
m_startScripts.removeOne(script); mApp->webProfile()->scripts().insert(script->webScript());
}
else {
m_endScripts.removeOne(script);
}
m_disabledScripts.removeOne(script->fullName()); 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); mApp->desktopNotifications()->showNotification(icon, title.isEmpty() ? tr("GreaseMonkey") : title, message);
} }
void GM_Manager::frameLoadStart()
{
QWebFrame* frame = qobject_cast<QWebFrame*>(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() void GM_Manager::load()
{ {
QDir gmDir(m_settingsPath + QL1S("/greasemonkey")); QDir gmDir(m_settingsPath + QL1S("/greasemonkey"));
@ -263,15 +204,13 @@ void GM_Manager::load()
continue; continue;
} }
m_scripts.append(script);
if (m_disabledScripts.contains(script->fullName())) { if (m_disabledScripts.contains(script->fullName())) {
script->setEnabled(false); script->setEnabled(false);
} }
if (script->startAt() == GM_Script::DocumentStart) {
m_startScripts.append(script);
}
else { else {
m_endScripts.append(script); mApp->webProfile()->scripts().insert(script->webScript());
} }
} }

View File

@ -40,7 +40,7 @@ public:
explicit GM_Manager(const QString &sPath, QObject* parent = 0); explicit GM_Manager(const QString &sPath, QObject* parent = 0);
void showSettings(QWidget* parent); void showSettings(QWidget* parent);
void downloadScript(const QNetworkRequest &request); void downloadScript(const QUrl &url);
QString settinsPath() const; QString settinsPath() const;
QString scriptsDirectory() const; QString scriptsDirectory() const;
@ -68,9 +68,6 @@ public slots:
void mainWindowCreated(BrowserWindow* window); void mainWindowCreated(BrowserWindow* window);
void mainWindowDeleted(BrowserWindow* window); void mainWindowDeleted(BrowserWindow* window);
void frameLoadStart();
void frameCreated(QWebFrame* frame);
private slots: private slots:
void load(); void load();
@ -81,8 +78,7 @@ private:
QStringList m_disabledScripts; QStringList m_disabledScripts;
GM_JSObject* m_jsObject; GM_JSObject* m_jsObject;
QList<GM_Script*> m_endScripts; QList<GM_Script*> m_scripts;
QList<GM_Script*> m_startScripts;
QHash<BrowserWindow*, GM_Icon*> m_windows; QHash<BrowserWindow*, GM_Icon*> m_windows;
}; };

View File

@ -53,21 +53,13 @@ void GM_Plugin::init(InitState state, const QString &settingsPath)
{ {
m_manager = new GM_Manager(settingsPath, this); 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(mainWindowCreated(BrowserWindow*)), m_manager, SLOT(mainWindowCreated(BrowserWindow*)));
connect(mApp->plugins(), SIGNAL(mainWindowDeleted(BrowserWindow*)), m_manager, SLOT(mainWindowDeleted(BrowserWindow*))); connect(mApp->plugins(), SIGNAL(mainWindowDeleted(BrowserWindow*)), m_manager, SLOT(mainWindowDeleted(BrowserWindow*)));
// Make sure userscripts works also with already created WebPages // Make sure userscripts works also with already created WebPages
if (state == LateInitState) { if (state == LateInitState) {
foreach (BrowserWindow* window, mApp->windows()) { for (BrowserWindow *window : mApp->windows()) {
m_manager->mainWindowCreated(window); m_manager->mainWindowCreated(window);
for (int i = 0; i < window->tabWidget()->count(); ++i) {
WebTab* tab = qobject_cast<WebTab*>(window->tabWidget()->widget(i));
if (tab) {
webPageCreated(tab->webView()->page());
}
}
} }
} }
} }
@ -96,26 +88,18 @@ void GM_Plugin::showSettings(QWidget* parent)
m_manager->showSettings(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")) { if (url.toString().endsWith(QL1S(".user.js"))) {
const QString urlString = request.url().toString(QUrl::RemoveFragment | QUrl::RemoveQuery); m_manager->downloadScript(url);
return false;
if (urlString.endsWith(QLatin1String(".user.js"))) {
m_manager->downloadScript(request);
return new EmptyNetworkReply;
}
} }
return 0; return true;
}
void GM_Plugin::webPageCreated(WebPage* page)
{
m_manager->frameCreated(page->mainFrame());
connect(page, SIGNAL(frameCreated(QWebFrame*)), m_manager, SLOT(frameCreated(QWebFrame*)));
} }
#if QT_VERSION < 0x050000 #if QT_VERSION < 0x050000

View File

@ -43,10 +43,7 @@ public:
QTranslator* getTranslator(const QString &locale); QTranslator* getTranslator(const QString &locale);
void showSettings(QWidget* parent = 0); void showSettings(QWidget* parent = 0);
QNetworkReply* createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice* outgoingData); bool acceptNavigationRequest(WebPage *page, const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame);
private slots:
void webPageCreated(WebPage* page);
private: private:
GM_Manager* m_manager; GM_Manager* m_manager;

View File

@ -23,7 +23,6 @@
#include <QFile> #include <QFile>
#include <QStringList> #include <QStringList>
#include <QWebFrame>
#include <QCryptographicHash> #include <QCryptographicHash>
GM_Script::GM_Script(GM_Manager* manager, const QString &filePath) 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_fileWatcher(new DelayedFileWatcher(this))
, m_namespace("GreaseMonkeyNS") , m_namespace("GreaseMonkeyNS")
, m_startAt(DocumentEnd) , m_startAt(DocumentEnd)
, m_noframes(false)
, m_fileName(filePath) , m_fileName(filePath)
, m_enabled(true) , m_enabled(true)
, m_valid(false) , m_valid(false)
@ -81,6 +81,11 @@ GM_Script::StartAt GM_Script::startAt() const
return m_startAt; return m_startAt;
} }
bool GM_Script::noFrames() const
{
return m_noframes;
}
bool GM_Script::isEnabled() const bool GM_Script::isEnabled() const
{ {
return m_valid && m_enabled; return m_valid && m_enabled;
@ -118,11 +123,21 @@ QString GM_Script::script() const
return m_script; return m_script;
} }
QString GM_Script::metaData() const
{
return m_metadata;
}
QString GM_Script::fileName() const QString GM_Script::fileName() const
{ {
return m_fileName; return m_fileName;
} }
QWebEngineScript GM_Script::webScript() const
{
return m_webScript;
}
bool GM_Script::match(const QString &urlString) bool GM_Script::match(const QString &urlString)
{ {
if (!isEnabled()) { if (!isEnabled()) {
@ -258,8 +273,14 @@ void GM_Script::parseScript()
} }
int index = fileData.indexOf(QLatin1String("// ==/UserScript==")) + 18; 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(){" QString jscript("(function(){"
"function GM_getValue(name,val){return GM_getValueImpl('%1',name,val);}" "function GM_getValue(name,val){return GM_getValueImpl('%1',name,val);}"
"function GM_setValue(name,val){return GM_setValueImpl('%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');}" "function GM_listValues(){return GM_listValuesImpl('%1');}"
"\n%2\n})();"); "\n%2\n})();");
QString nspace = QCryptographicHash::hash(fullName().toUtf8(), QCryptographicHash::Md4).toHex(); QString nspace = QCryptographicHash::hash(fullName().toUtf8(), QCryptographicHash::Md4).toHex();
#endif
script.prepend(m_manager->requireScripts(requireList)); // Create QWebEngineScript
script = jscript.arg(nspace, script); m_webScript.setName(fullName());
m_webScript.setInjectionPoint(startAt() == DocumentStart ? QWebEngineScript::DocumentCreation : QWebEngineScript::DocumentReady);
m_script = script; m_webScript.setWorldId(QWebEngineScript::MainWorld);
m_valid = !script.isEmpty(); m_webScript.setRunsOnSubFrames(!m_noframes);
m_webScript.setSourceCode(QSL("%1\n%2").arg(m_metadata, m_script));
} }

View File

@ -23,6 +23,7 @@
#include <QObject> #include <QObject>
#include <QVector> #include <QVector>
#include <QUrl> #include <QUrl>
#include <QWebEngineScript>
class QWebFrame; class QWebFrame;
@ -49,6 +50,7 @@ public:
QUrl downloadUrl() const; QUrl downloadUrl() const;
StartAt startAt() const; StartAt startAt() const;
bool noFrames() const;
bool isEnabled() const; bool isEnabled() const;
void setEnabled(bool enable); void setEnabled(bool enable);
@ -57,8 +59,11 @@ public:
QStringList exclude() const; QStringList exclude() const;
QString script() const; QString script() const;
QString metaData() const;
QString fileName() const; QString fileName() const;
QWebEngineScript webScript() const;
bool match(const QString &urlString); bool match(const QString &urlString);
signals: signals:
@ -83,11 +88,15 @@ private:
QUrl m_downloadUrl; QUrl m_downloadUrl;
StartAt m_startAt; StartAt m_startAt;
bool m_noframes;
QString m_script; QString m_script;
QString m_metadata;
QString m_fileName; QString m_fileName;
bool m_enabled; bool m_enabled;
bool m_valid; bool m_valid;
QWebEngineScript m_webScript;
}; };
#endif // GM_SCRIPT_H #endif // GM_SCRIPT_H

View File

@ -44,7 +44,6 @@ isEqual(QT_MAJOR_VERSION, 5): !qtHaveModule(KWallet): disablePlugin(KWalletPassw
disablePlugin(AccessKeysNavigation) disablePlugin(AccessKeysNavigation)
disablePlugin(AutoScroll) disablePlugin(AutoScroll)
disablePlugin(CopyTitle) disablePlugin(CopyTitle)
disablePlugin(GreaseMonkey)
disablePlugin(MailHandle) disablePlugin(MailHandle)
disablePlugin(MouseGestures) disablePlugin(MouseGestures)
disablePlugin(PIM) disablePlugin(PIM)