diff --git a/src/plugins/GreaseMonkey/CMakeLists.txt b/src/plugins/GreaseMonkey/CMakeLists.txt index cc81ca322..15a7bfd6f 100644 --- a/src/plugins/GreaseMonkey/CMakeLists.txt +++ b/src/plugins/GreaseMonkey/CMakeLists.txt @@ -7,11 +7,12 @@ set( GreaseMonkey_SRCS gm_downloader.cpp gm_addscriptdialog.cpp gm_notification.cpp + gm_icon.cpp + gm_jsobject.cpp settings/gm_settings.cpp settings/gm_settingslistdelegate.cpp settings/gm_settingsscriptinfo.cpp settings/gm_settingslistwidget.cpp - gm_icon.cpp ) set( GreaseMonkey_UIS diff --git a/src/plugins/GreaseMonkey/data/bootstrap.js b/src/plugins/GreaseMonkey/data/bootstrap.js index fe3f6957c..ec9db158e 100644 --- a/src/plugins/GreaseMonkey/data/bootstrap.js +++ b/src/plugins/GreaseMonkey/data/bootstrap.js @@ -1,73 +1,87 @@ -if (typeof GM_xmlhttpRequest === "undefined") { - GM_xmlhttpRequest = function(/* object */ details) { - details.method = details.method.toUpperCase() || "GET"; - - if (!details.url) { - throw("GM_xmlhttpRequest requires an URL."); - } - - // build XMLHttpRequest object - var oXhr = new XMLHttpRequest; - // run it - if("onreadystatechange" in details) - oXhr.onreadystatechange = function() { details.onreadystatechange(oXhr) }; - if("onload" in details) - oXhr.onload = function() { details.onload(oXhr) }; - if("onerror" in details) - oXhr.onerror = function() { details.onerror(oXhr) }; - - oXhr.open(details.method, details.url, true); - - if("headers" in details) - for(var header in details.headers) - oXhr.setRequestHeader(header, details.headers[header]); - - if("data" in details) - oXhr.send(details.data); - else - oXhr.send(); +var GM = { + info: { + script: { + description: "", + excludes: [], + includes: [], + matches: [], + name: "", + namespace: "", + resources: {}, + 'run-at': "document-end", + version: "" + }, + scriptMetaStr: "", + scriptHandler: "QupZilla GreaseMonkey", + version: "4.0" } +}; +window.GM = GM; + +function GM_info() { + return GM.info; } -if (typeof GM_addStyle === "undefined") { - function GM_addStyle(/* string */ styles) { - var head = document.getElementsByTagName("head")[0]; - if (head === undefined) { - document.onreadystatechange = function() { - if (document.readyState == "interactive") { - var oStyle = document.createElement("style"); - oStyle.setAttribute("type", "text/css"); - oStyle.appendChild(document.createTextNode(styles)); - document.getElementsByTagName("head")[0].appendChild(oStyle); - } +function GM_xmlhttpRequest(/* object */ details) { + details.method = details.method.toUpperCase() || "GET"; + + if (!details.url) { + throw("GM_xmlhttpRequest requires an URL."); + } + + // build XMLHttpRequest object + var oXhr = new XMLHttpRequest; + // run it + if("onreadystatechange" in details) + oXhr.onreadystatechange = function() { details.onreadystatechange(oXhr) }; + if("onload" in details) + oXhr.onload = function() { details.onload(oXhr) }; + if("onerror" in details) + oXhr.onerror = function() { details.onerror(oXhr) }; + + oXhr.open(details.method, details.url, true); + + if("headers" in details) + for(var header in details.headers) + oXhr.setRequestHeader(header, details.headers[header]); + + if("data" in details) + oXhr.send(details.data); + else + oXhr.send(); +} + +function GM_addStyle(/* string */ styles) { + var head = document.getElementsByTagName("head")[0]; + if (head === undefined) { + document.onreadystatechange = function() { + if (document.readyState == "interactive") { + var oStyle = document.createElement("style"); + oStyle.setAttribute("type", "text/css"); + oStyle.appendChild(document.createTextNode(styles)); + document.getElementsByTagName("head")[0].appendChild(oStyle); } } - else { - var oStyle = document.createElement("style"); - oStyle.setAttribute("type", "text/css"); - oStyle.appendChild(document.createTextNode(styles)); - head.appendChild(oStyle); - } + } + else { + var oStyle = document.createElement("style"); + oStyle.setAttribute("type", "text/css"); + oStyle.appendChild(document.createTextNode(styles)); + head.appendChild(oStyle); } } -if (typeof GM_log === "undefined") { - function GM_log(log) { - if(console) - console.log(log); - } +function GM_log(log) { + if(console) + console.log(log); } -if (typeof GM_openInTab === "undefined") { - function GM_openInTab(url) { - return window.open(url); - } +function GM_openInTab(url) { + return window.open(url); } -if (typeof GM_setClipboard === "undefined") { - function GM_setClipboard(text) { - //window._qz_greasemonkey.setClipboard(text); - } +function GM_setClipboard(text) { + window.external.extra.greasemonkey.setClipboard(text); } // Define unsafe window @@ -75,6 +89,19 @@ var unsafeWindow = window; window.wrappedJSObject = unsafeWindow; // GM_registerMenuCommand not supported -if (typeof GM_registerMenuCommand === "undefined") { - function GM_registerMenuCommand(caption, commandFunc, accessKey) { } -} +function GM_registerMenuCommand(caption, commandFunc, accessKey) { } + +// GM_getResourceUrl not supported +function GM_getResourceUrl(resourceName) { } + +// GreaseMonkey 4.0 support +GM.openInTab = GM_openInTab; +GM.setClipboard = GM_setClipboard; +GM.xmlhttpRequest = GM_xmlhttpRequest; + +// GM_getResourceUrl not supported +GM.getResourceUrl = function(resourceName) { + return new Promise((resolve, reject) => { + reject(); + }); +}; diff --git a/src/plugins/GreaseMonkey/data/bootstrap.min.js b/src/plugins/GreaseMonkey/data/bootstrap.min.js index 7ea61f3bc..c453f20f1 100644 --- a/src/plugins/GreaseMonkey/data/bootstrap.min.js +++ b/src/plugins/GreaseMonkey/data/bootstrap.min.js @@ -1 +1,4 @@ -"undefined"===typeof GM_xmlhttpRequest&&(GM_xmlhttpRequest=function(a){a.method=a.method.toUpperCase()||"GET";if(!a.url)throw"GM_xmlhttpRequest requires an URL.";var b=new XMLHttpRequest;"onreadystatechange"in a&&(b.onreadystatechange=function(){a.onreadystatechange(b)});"onload"in a&&(b.onload=function(){a.onload(b)});"onerror"in a&&(b.onerror=function(){a.onerror(b)});b.open(a.method,a.url,!0);if("headers"in a)for(var c in a.headers)b.setRequestHeader(c,a.headers[c]);"data"in a?b.send(a.data):b.send()});if("undefined"===typeof GM_addStyle)var GM_addStyle=function(a){var b=document.getElementsByTagName("head")[0];if(void 0===b)document.onreadystatechange=function(){if("interactive"==document.readyState){var b=document.createElement("style");b.setAttribute("type","text/css");b.appendChild(document.createTextNode(a));document.getElementsByTagName("head")[0].appendChild(b)}};else{var c=document.createElement("style");c.setAttribute("type","text/css");c.appendChild(document.createTextNode(a));b.appendChild(c)}};if("undefined"===typeof GM_log)var GM_log=function(a){console&&console.log(a)};if("undefined"===typeof GM_openInTab)var GM_openInTab=function(a){return window.open(a)};if("undefined"===typeof GM_setClipboard)var GM_setClipboard=function(a){};var unsafeWindow=window;window.wrappedJSObject=unsafeWindow;if("undefined"===typeof GM_registerMenuCommand)var GM_registerMenuCommand=function(a,b,c){}; \ No newline at end of file +var GM={info:{script:{description:"",excludes:[],includes:[],matches:[],name:"",namespace:"",resources:{},"run-at":"document-end",version:""},scriptMetaStr:"",scriptHandler:"QupZilla GreaseMonkey",version:"4.0"}};window.GM=GM;function GM_info(){return GM.info} +function GM_xmlhttpRequest(a){a.method=a.method.toUpperCase()||"GET";if(!a.url)throw"GM_xmlhttpRequest requires an URL.";var b=new XMLHttpRequest;"onreadystatechange"in a&&(b.onreadystatechange=function(){a.onreadystatechange(b)});"onload"in a&&(b.onload=function(){a.onload(b)});"onerror"in a&&(b.onerror=function(){a.onerror(b)});b.open(a.method,a.url,!0);if("headers"in a)for(var c in a.headers)b.setRequestHeader(c,a.headers[c]);"data"in a?b.send(a.data):b.send()} +function GM_addStyle(a){var b=document.getElementsByTagName("head")[0];if(void 0===b)document.onreadystatechange=function(){if("interactive"==document.readyState){var b=document.createElement("style");b.setAttribute("type","text/css");b.appendChild(document.createTextNode(a));document.getElementsByTagName("head")[0].appendChild(b)}};else{var c=document.createElement("style");c.setAttribute("type","text/css");c.appendChild(document.createTextNode(a));b.appendChild(c)}} +function GM_log(a){console&&console.log(a)}function GM_openInTab(a){return window.open(a)}function GM_setClipboard(a){window.external.extra.greasemonkey.setClipboard(a)}var unsafeWindow=window;window.wrappedJSObject=unsafeWindow;function GM_registerMenuCommand(a,b,c){}function GM_getResourceUrl(a){}GM.openInTab=GM_openInTab;GM.setClipboard=GM_setClipboard;GM.xmlhttpRequest=GM_xmlhttpRequest;GM.getResourceUrl=function(a){return new Promise(function(a,c){c()})}; diff --git a/src/plugins/GreaseMonkey/data/values.js b/src/plugins/GreaseMonkey/data/values.js index e7e6d70b2..fffc49b9b 100644 --- a/src/plugins/GreaseMonkey/data/values.js +++ b/src/plugins/GreaseMonkey/data/values.js @@ -26,3 +26,56 @@ function GM_listValues() { function GM_setValue(aKey, aVal) { localStorage.setItem("%1" + aKey, aVal); } + +// GreaseMonkey 4.0 support +var asyncCall = (func) => { + if (window.external.extra) { + func(); + } else { + document.addEventListener("_qupzilla_external_created", func); + } +}; + +GM.deleteValue = function(name) { + return new Promise((resolve, reject) => { + asyncCall(() => { + window.external.extra.greasemonkey.deleteValue("%1", name, (res) => { + if (res) { + resolve(); + } else { + reject(); + } + }); + }); + }); +}; + +GM.getValue = function(name, value) { + return new Promise((resolve) => { + asyncCall(() => { + window.external.extra.greasemonkey.getValue("%1", name, value, resolve); + }); + }); +}; + +GM.setValue = function(name, value) { + return new Promise((resolve, reject) => { + asyncCall(() => { + window.external.extra.greasemonkey.setValue("%1", name, value, (res) => { + if (res) { + resolve(); + } else { + reject(); + } + }); + }); + }); +}; + +GM.listValues = function() { + return new Promise((resolve) => { + asyncCall(() => { + window.external.extra.greasemonkey.listValues("%1", resolve); + }); + }); +}; diff --git a/src/plugins/GreaseMonkey/data/values.min.js b/src/plugins/GreaseMonkey/data/values.min.js index 2ebaffbcd..66e2b32d6 100644 --- a/src/plugins/GreaseMonkey/data/values.min.js +++ b/src/plugins/GreaseMonkey/data/values.min.js @@ -1 +1,3 @@ -function GM_deleteValue(a){localStorage.removeItem("%1"+a)}function GM_getValue(a,b){var c=localStorage.getItem("%1"+a);return null===c&&"undefined"!=typeof b?b:c}function GM_listValues(){for(var a=[],b=0;b +* Copyright (C) 2013-2018 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -70,7 +70,7 @@ QVariant GM_JSObject::getValue(const QString &nspace, const QString &name, const return dValue; } -void GM_JSObject::setValue(const QString &nspace, const QString &name, const QVariant &value) +bool GM_JSObject::setValue(const QString &nspace, const QString &name, const QVariant &value) { QString savedValue; @@ -92,17 +92,19 @@ void GM_JSObject::setValue(const QString &nspace, const QString &name, const QVa break; default: - break; + return false; } QString valueName = QString("GreaseMonkey-%1/%2").arg(nspace, name); m_settings->setValue(valueName, savedValue); + return true; } -void GM_JSObject::deleteValue(const QString &nspace, const QString &name) +bool GM_JSObject::deleteValue(const QString &nspace, const QString &name) { QString valueName = QString("GreaseMonkey-%1/%2").arg(nspace, name); m_settings->remove(valueName); + return true; } QStringList GM_JSObject::listValues(const QString &nspace) diff --git a/src/plugins/GreaseMonkey/gm_jsobject.h b/src/plugins/GreaseMonkey/gm_jsobject.h index 16221ff2f..3b5599679 100644 --- a/src/plugins/GreaseMonkey/gm_jsobject.h +++ b/src/plugins/GreaseMonkey/gm_jsobject.h @@ -1,6 +1,6 @@ /* ============================================================ * GreaseMonkey plugin for Falkon -* Copyright (C) 2013-2014 David Rosca +* Copyright (C) 2013-2018 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,8 +34,8 @@ public: public slots: QVariant getValue(const QString &nspace, const QString &name, const QVariant &dValue); - void setValue(const QString &nspace, const QString &name, const QVariant &value); - void deleteValue(const QString &nspace, const QString &name); + bool setValue(const QString &nspace, const QString &name, const QVariant &value); + bool deleteValue(const QString &nspace, const QString &name); QStringList listValues(const QString &nspace); void setClipboard(const QString &text); diff --git a/src/plugins/GreaseMonkey/gm_manager.cpp b/src/plugins/GreaseMonkey/gm_manager.cpp index 338fb4ffd..0d88104bf 100644 --- a/src/plugins/GreaseMonkey/gm_manager.cpp +++ b/src/plugins/GreaseMonkey/gm_manager.cpp @@ -1,6 +1,6 @@ /* ============================================================ * GreaseMonkey plugin for Falkon -* Copyright (C) 2012-2017 David Rosca +* Copyright (C) 2012-2018 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,6 +18,7 @@ #include "gm_manager.h" #include "gm_script.h" #include "gm_downloader.h" +#include "gm_jsobject.h" #include "gm_icon.h" #include "gm_addscriptdialog.h" #include "settings/gm_settings.h" @@ -28,6 +29,7 @@ #include "mainapplication.h" #include "networkmanager.h" #include "desktopnotificationsfactory.h" +#include "javascript/externaljsobject.h" #include #include @@ -39,8 +41,14 @@ GM_Manager::GM_Manager(const QString &sPath, QObject* parent) : QObject(parent) , m_settingsPath(sPath) + , m_jsObject(new GM_JSObject(this)) { - QTimer::singleShot(0, this, SLOT(load())); + load(); +} + +GM_Manager::~GM_Manager() +{ + ExternalJsObject::unregisterExtraObject(QSL("greasemonkey")); } void GM_Manager::showSettings(QWidget* parent) @@ -239,6 +247,9 @@ void GM_Manager::load() mApp->webProfile()->scripts()->insert(script->webScript()); } } + + m_jsObject->setSettingsFile(m_settingsPath + QSL("/greasemonkey/values.ini")); + ExternalJsObject::registerExtraObject(QSL("greasemonkey"), m_jsObject); } void GM_Manager::scriptChanged() diff --git a/src/plugins/GreaseMonkey/gm_manager.h b/src/plugins/GreaseMonkey/gm_manager.h index bed11ae22..959040dcc 100644 --- a/src/plugins/GreaseMonkey/gm_manager.h +++ b/src/plugins/GreaseMonkey/gm_manager.h @@ -1,6 +1,6 @@ /* ============================================================ * GreaseMonkey plugin for Falkon -* Copyright (C) 2013-2017 David Rosca +* Copyright (C) 2013-2018 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,6 +28,7 @@ class QWebFrame; class BrowserWindow; class GM_Script; +class GM_JSObject; class GM_Settings; class GM_Icon; @@ -36,6 +37,7 @@ class GM_Manager : public QObject Q_OBJECT public: explicit GM_Manager(const QString &sPath, QObject* parent = 0); + ~GM_Manager(); void showSettings(QWidget* parent); void downloadScript(const QUrl &url); @@ -80,7 +82,7 @@ private: QPointer m_settings; QStringList m_disabledScripts; - //GM_JSObject* m_jsObject; + GM_JSObject *m_jsObject; QList m_scripts; QHash m_windows; diff --git a/src/plugins/GreaseMonkey/gm_plugin.cpp b/src/plugins/GreaseMonkey/gm_plugin.cpp index 1a0aa87fc..ab046f536 100644 --- a/src/plugins/GreaseMonkey/gm_plugin.cpp +++ b/src/plugins/GreaseMonkey/gm_plugin.cpp @@ -1,6 +1,6 @@ /* ============================================================ * GreaseMonkey plugin for Falkon -* Copyright (C) 2012-2017 David Rosca +* Copyright (C) 2012-2018 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -40,7 +40,7 @@ PluginSpec GM_Plugin::pluginSpec() spec.name = "GreaseMonkey"; spec.info = "Userscripts for Falkon"; spec.description = "Provides support for userscripts"; - spec.version = "0.8.0"; + spec.version = "0.9.0"; spec.author = "David Rosca "; spec.icon = QIcon(":gm/data/icon.svg").pixmap(32); spec.hasSettings = true;