From a769848dc6ce004ed4cac9e569766003046824fc Mon Sep 17 00:00:00 2001 From: trlkly Date: Fri, 12 Jan 2018 20:45:33 -0600 Subject: [PATCH 01/17] switch to node 4.7.0 per error --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 45c926f..53b5036 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: - - "4.5.0" + - "4.7.0" before_install: - npm install -g grunt-cli - rvm install 2.4.1 From d35b0736b598d6b81b2d8739312a1d54ea6d39cb Mon Sep 17 00:00:00 2001 From: trlkly Date: Fri, 12 Jan 2018 21:02:01 -0600 Subject: [PATCH 02/17] add shim to support GM 4.0 This shim has been tested on the release, but not on source. --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index dd8259f..a8230d9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "questionable-content-spa", - "version": "0.5.1", + "version": "0.5.2", "author": "Alexander Krivács Schrøder", "devDependencies": { "grunt": "~1.0.1", @@ -15,5 +15,5 @@ "load-grunt-tasks": "~3.5" }, "licenseBanner": "/* \n * Copyright (C) 2016 Alexander Krivács Schrøder \n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see .\n */\n", - "userscriptBanner": "// ==UserScript==\n// @name Questionable Content Single-Page Application with Extra Features\n// @namespace https://questionablextensions.net/\n// @version <%= pkg.version %>\n// @author Alexander Krivács Schrøder\n// @description Converts questionablecontent.net into a single-page application and adds extra features, such as character, location and storyline navigation.\n// @homepage https://questionablextensions.net/\n// @icon https://questionablextensions.net/images/icon.png\n// @icon64 https://questionablextensions.net/images/icon64.png\n// @updateURL https://questionablextensions.net/releases/qc-ext.latest.meta.js\n// @downloadURL https://questionablextensions.net/releases/qc-ext.latest.user.js\n// @supportURL https://github.com/Questionable-Content-Extensions/client/issues\n// @match *://*.questionablecontent.net/\n// @match *://*.questionablecontent.net/index.php\n// @match *://*.questionablecontent.net/view.php*\n// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.js\n// @require https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js\n// @require https://questionablextensions.net/scripts/angular.custom.js\n// @require https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.min.js\n// @connect questionablextensions.net\n// @connect localhost\n// @grant GM_getValue\n// @grant GM_setValue\n// @grant GM_xmlhttpRequest\n// @noframes\n// ==/UserScript==\n" + "userscriptBanner": "// ==UserScript==\n// @name Questionable Content Single-Page Application with Extra Features\n// @namespace https://questionablextensions.net/\n// @version <%= pkg.version %>\n// @author Alexander Krivács Schrøder\n// @description Converts questionablecontent.net into a single-page application and adds extra features, such as character, location and storyline navigation.\n// @homepage https://questionablextensions.net/\n// @icon https://questionablextensions.net/images/icon.png\n// @icon64 https://questionablextensions.net/images/icon64.png\n// @updateURL https://questionablextensions.net/releases/qc-ext.latest.meta.js\n// @downloadURL https://questionablextensions.net/releases/qc-ext.latest.user.js\n// @supportURL https://github.com/Questionable-Content-Extensions/client/issues\n// @match *://*.questionablecontent.net/\n// @match *://*.questionablecontent.net/index.php\n// @match *://*.questionablecontent.net/view.php*\n// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.js\n// @require https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js\n// @require https://questionablextensions.net/scripts/angular.custom.js\n// @require https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.min.js\n// @connect questionablextensions.net\n// @connect localhost\n// @grant GM_getValue\n// @grant GM_setValue\n// @grant GM_xmlhttpRequest\n// @grant GM.xmlHttpRequest\n// @require https://gist.githubusercontent.com/arantius/3123124/raw/grant-none-shim.js\n// @noframes\n// ==/UserScript==\nif (GM.xmlHttpRequest) GM_xmlhttpRequest = GM_xmlHttpRequest;\n" } From ba64ccdb2c981a6375fec8afcfec02cc0b42a584 Mon Sep 17 00:00:00 2001 From: trlkly Date: Fri, 12 Jan 2018 22:56:17 -0600 Subject: [PATCH 03/17] modified grant-none-shim Modified the grant-none shim to not take effect if GM_ functions still exist. --- assets/js/grant-none-shim.js | 164 +++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 assets/js/grant-none-shim.js diff --git a/assets/js/grant-none-shim.js b/assets/js/grant-none-shim.js new file mode 100644 index 0000000..0322639 --- /dev/null +++ b/assets/js/grant-none-shim.js @@ -0,0 +1,164 @@ +/* +The MIT License (MIT) + +Copyright (c) 2014 Anthony Lieuallen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +This script is intended to be used with @require, for Greasemonkey scripts +using "@grant none". It emulates the GM_ APIs as closely as possible, using +modern browser features like DOM storage. + +Scripts should plan to remove usage of GM_ APIs, but this shim offers a +short-term workaround to gain the benefits of running in the security +restriction free "@grant none" mode before that is completed. + +Read the comments on each function to learn if its emulation is good enough +for your purposes. + +NOT IMPLEMENTED: + * GM_getResourceText + * GM_openInTab + * GM_registerMenuCommand +*/ + +if ('undefined' == typeof GM_addStyle) var GM_addStyle = function (aCss) { + 'use strict'; + let head = document.getElementsByTagName('head')[0]; + if (!head) head = document.documentElement; + if (head) { + let style = document.createElement('style'); + style.setAttribute('type', 'text/css'); + style.textContent = aCss; + head.appendChild(style); + return style; + } + return null; +}; + +if ('undefined' == typeof GM_log) var GM_log = console.log; + +// This naive implementation will simply fail to do cross-domain requests, +// just like any javascript in any page would. +if ('undefined' == typeof GM_xmlhttpRequest) var GM_xmlhttpRequest = function(aOpts) { + 'use strict'; + let req = new XMLHttpRequest(); + + __setupRequestEvent(aOpts, req, 'abort'); + __setupRequestEvent(aOpts, req, 'error'); + __setupRequestEvent(aOpts, req, 'load'); + __setupRequestEvent(aOpts, req, 'progress'); + __setupRequestEvent(aOpts, req, 'readystatechange'); + + req.open(aOpts.method, aOpts.url, !aOpts.synchronous, + aOpts.user || '', aOpts.password || ''); + if (aOpts.overrideMimeType) { + req.overrideMimeType(aOpts.overrideMimeType); + } + if (aOpts.headers) { + for (let prop in aOpts.headers) { + if (Object.prototype.hasOwnProperty.call(aOpts.headers, prop)) { + req.setRequestHeader(prop, aOpts.headers[prop]); + } + } + } + let body = aOpts.data ? aOpts.data : null; + if (aOpts.binary) { + return req.sendAsBinary(body); + } else { + return req.send(body); + } +}; + +function __setupRequestEvent(aOpts, aReq, aEventName) { + 'use strict'; + if (!aOpts['on' + aEventName]) return; + + aReq.addEventListener(aEventName, function(aEvent) { + let responseState = { + responseText: aReq.responseText, + responseXML: aReq.responseXML, + readyState: aReq.readyState, + responseHeaders: null, + status: null, + statusText: null, + finalUrl: null + }; + switch (aEventName) { + case "progress": + responseState.lengthComputable = aEvent.lengthComputable; + responseState.loaded = aEvent.loaded; + responseState.total = aEvent.total; + break; + case "error": + break; + default: + if (4 != aReq.readyState) break; + responseState.responseHeaders = aReq.getAllResponseHeaders(); + responseState.status = aReq.status; + responseState.statusText = aReq.statusText; + break; + } + aOpts['on' + aEventName](responseState); + }); +} + +const __GM_STORAGE_PREFIX = [ + '', GM_info.script.namespace, GM_info.script.name, ''].join('***'); + +// All of the GM_*Value methods rely on DOM Storage's localStorage facility. +// They work like always, but the values are scoped to a domain, unlike the +// original functions. The content page's scripts can access, set, and +// remove these values. +if ('undefined' == typeof GM_deleteValue) var GM_deleteValue = function (aKey) { + 'use strict'; + localStorage.removeItem(__GM_STORAGE_PREFIX + aKey); +}; + +if ('undefined' == typeof GM_getValue) var GM_getValue = function (aKey, aDefault) { + 'use strict'; + let val = localStorage.getItem(__GM_STORAGE_PREFIX + aKey); + if (null === val && 'undefined' != typeof aDefault) return aDefault; + return val; +}; + +if ('undefined' == typeof GM_listValues) var GM_listValues = function () { + 'use strict'; + let prefixLen = __GM_STORAGE_PREFIX.length; + let values = []; + let i = 0; + for (let i = 0; i < localStorage.length; i++) { + let k = localStorage.key(i); + if (k.substr(0, prefixLen) === __GM_STORAGE_PREFIX) { + values.push(k.substr(prefixLen)); + } + } + return values; +}; + +if ('undefined' == typeof GM_setValue) var GM_setValue = function (aKey, aVal) { + 'use strict'; + localStorage.setItem(__GM_STORAGE_PREFIX + aKey, aVal); +}; + +if ('undefined' == typeof GM_getResourceURL) var GM_getResourceURL = function (aName) { + 'use strict'; + return 'greasemonkey-script:' + GM_info.uuid + '/' + aName; +}; From 3fd9c435ee3062851d8aeab9e2733862084663f9 Mon Sep 17 00:00:00 2001 From: trlkly Date: Fri, 12 Jan 2018 23:01:49 -0600 Subject: [PATCH 04/17] Deleting file and moving to new repo. --- assets/js/grant-none-shim.js | 164 ----------------------------------- 1 file changed, 164 deletions(-) delete mode 100644 assets/js/grant-none-shim.js diff --git a/assets/js/grant-none-shim.js b/assets/js/grant-none-shim.js deleted file mode 100644 index 0322639..0000000 --- a/assets/js/grant-none-shim.js +++ /dev/null @@ -1,164 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2014 Anthony Lieuallen - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - -This script is intended to be used with @require, for Greasemonkey scripts -using "@grant none". It emulates the GM_ APIs as closely as possible, using -modern browser features like DOM storage. - -Scripts should plan to remove usage of GM_ APIs, but this shim offers a -short-term workaround to gain the benefits of running in the security -restriction free "@grant none" mode before that is completed. - -Read the comments on each function to learn if its emulation is good enough -for your purposes. - -NOT IMPLEMENTED: - * GM_getResourceText - * GM_openInTab - * GM_registerMenuCommand -*/ - -if ('undefined' == typeof GM_addStyle) var GM_addStyle = function (aCss) { - 'use strict'; - let head = document.getElementsByTagName('head')[0]; - if (!head) head = document.documentElement; - if (head) { - let style = document.createElement('style'); - style.setAttribute('type', 'text/css'); - style.textContent = aCss; - head.appendChild(style); - return style; - } - return null; -}; - -if ('undefined' == typeof GM_log) var GM_log = console.log; - -// This naive implementation will simply fail to do cross-domain requests, -// just like any javascript in any page would. -if ('undefined' == typeof GM_xmlhttpRequest) var GM_xmlhttpRequest = function(aOpts) { - 'use strict'; - let req = new XMLHttpRequest(); - - __setupRequestEvent(aOpts, req, 'abort'); - __setupRequestEvent(aOpts, req, 'error'); - __setupRequestEvent(aOpts, req, 'load'); - __setupRequestEvent(aOpts, req, 'progress'); - __setupRequestEvent(aOpts, req, 'readystatechange'); - - req.open(aOpts.method, aOpts.url, !aOpts.synchronous, - aOpts.user || '', aOpts.password || ''); - if (aOpts.overrideMimeType) { - req.overrideMimeType(aOpts.overrideMimeType); - } - if (aOpts.headers) { - for (let prop in aOpts.headers) { - if (Object.prototype.hasOwnProperty.call(aOpts.headers, prop)) { - req.setRequestHeader(prop, aOpts.headers[prop]); - } - } - } - let body = aOpts.data ? aOpts.data : null; - if (aOpts.binary) { - return req.sendAsBinary(body); - } else { - return req.send(body); - } -}; - -function __setupRequestEvent(aOpts, aReq, aEventName) { - 'use strict'; - if (!aOpts['on' + aEventName]) return; - - aReq.addEventListener(aEventName, function(aEvent) { - let responseState = { - responseText: aReq.responseText, - responseXML: aReq.responseXML, - readyState: aReq.readyState, - responseHeaders: null, - status: null, - statusText: null, - finalUrl: null - }; - switch (aEventName) { - case "progress": - responseState.lengthComputable = aEvent.lengthComputable; - responseState.loaded = aEvent.loaded; - responseState.total = aEvent.total; - break; - case "error": - break; - default: - if (4 != aReq.readyState) break; - responseState.responseHeaders = aReq.getAllResponseHeaders(); - responseState.status = aReq.status; - responseState.statusText = aReq.statusText; - break; - } - aOpts['on' + aEventName](responseState); - }); -} - -const __GM_STORAGE_PREFIX = [ - '', GM_info.script.namespace, GM_info.script.name, ''].join('***'); - -// All of the GM_*Value methods rely on DOM Storage's localStorage facility. -// They work like always, but the values are scoped to a domain, unlike the -// original functions. The content page's scripts can access, set, and -// remove these values. -if ('undefined' == typeof GM_deleteValue) var GM_deleteValue = function (aKey) { - 'use strict'; - localStorage.removeItem(__GM_STORAGE_PREFIX + aKey); -}; - -if ('undefined' == typeof GM_getValue) var GM_getValue = function (aKey, aDefault) { - 'use strict'; - let val = localStorage.getItem(__GM_STORAGE_PREFIX + aKey); - if (null === val && 'undefined' != typeof aDefault) return aDefault; - return val; -}; - -if ('undefined' == typeof GM_listValues) var GM_listValues = function () { - 'use strict'; - let prefixLen = __GM_STORAGE_PREFIX.length; - let values = []; - let i = 0; - for (let i = 0; i < localStorage.length; i++) { - let k = localStorage.key(i); - if (k.substr(0, prefixLen) === __GM_STORAGE_PREFIX) { - values.push(k.substr(prefixLen)); - } - } - return values; -}; - -if ('undefined' == typeof GM_setValue) var GM_setValue = function (aKey, aVal) { - 'use strict'; - localStorage.setItem(__GM_STORAGE_PREFIX + aKey, aVal); -}; - -if ('undefined' == typeof GM_getResourceURL) var GM_getResourceURL = function (aName) { - 'use strict'; - return 'greasemonkey-script:' + GM_info.uuid + '/' + aName; -}; From 39dfac31f0f1351a1de0a77cfdfc0c9d5b3e5e72 Mon Sep 17 00:00:00 2001 From: trlkly Date: Fri, 12 Jan 2018 23:12:31 -0600 Subject: [PATCH 05/17] switch to modified grant-none-shim.js The original grant-none-shim.js would run even on GM versions that include the GM_ functions. This could cause breakage. Fixed to only create new functions if they don't already exist. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a8230d9..2826be7 100644 --- a/package.json +++ b/package.json @@ -15,5 +15,5 @@ "load-grunt-tasks": "~3.5" }, "licenseBanner": "/* \n * Copyright (C) 2016 Alexander Krivács Schrøder \n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see .\n */\n", - "userscriptBanner": "// ==UserScript==\n// @name Questionable Content Single-Page Application with Extra Features\n// @namespace https://questionablextensions.net/\n// @version <%= pkg.version %>\n// @author Alexander Krivács Schrøder\n// @description Converts questionablecontent.net into a single-page application and adds extra features, such as character, location and storyline navigation.\n// @homepage https://questionablextensions.net/\n// @icon https://questionablextensions.net/images/icon.png\n// @icon64 https://questionablextensions.net/images/icon64.png\n// @updateURL https://questionablextensions.net/releases/qc-ext.latest.meta.js\n// @downloadURL https://questionablextensions.net/releases/qc-ext.latest.user.js\n// @supportURL https://github.com/Questionable-Content-Extensions/client/issues\n// @match *://*.questionablecontent.net/\n// @match *://*.questionablecontent.net/index.php\n// @match *://*.questionablecontent.net/view.php*\n// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.js\n// @require https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js\n// @require https://questionablextensions.net/scripts/angular.custom.js\n// @require https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.min.js\n// @connect questionablextensions.net\n// @connect localhost\n// @grant GM_getValue\n// @grant GM_setValue\n// @grant GM_xmlhttpRequest\n// @grant GM.xmlHttpRequest\n// @require https://gist.githubusercontent.com/arantius/3123124/raw/grant-none-shim.js\n// @noframes\n// ==/UserScript==\nif (GM.xmlHttpRequest) GM_xmlhttpRequest = GM_xmlHttpRequest;\n" + "userscriptBanner": "// ==UserScript==\n// @name Questionable Content Single-Page Application with Extra Features\n// @namespace https://questionablextensions.net/\n// @version <%= pkg.version %>\n// @author Alexander Krivács Schrøder\n// @description Converts questionablecontent.net into a single-page application and adds extra features, such as character, location and storyline navigation.\n// @homepage https://questionablextensions.net/\n// @icon https://questionablextensions.net/images/icon.png\n// @icon64 https://questionablextensions.net/images/icon64.png\n// @updateURL https://questionablextensions.net/releases/qc-ext.latest.meta.js\n// @downloadURL https://questionablextensions.net/releases/qc-ext.latest.user.js\n// @supportURL https://github.com/Questionable-Content-Extensions/client/issues\n// @match *://*.questionablecontent.net/\n// @match *://*.questionablecontent.net/index.php\n// @match *://*.questionablecontent.net/view.php*\n// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.js\n// @require https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js\n// @require https://questionablextensions.net/scripts/angular.custom.js\n// @require https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.min.js\n// @connect questionablextensions.net\n// @connect localhost\n// @grant GM_getValue\n// @grant GM_setValue\n// @grant GM_xmlhttpRequest\n// @grant GM.xmlHttpRequest\n// @require https://gist.githubusercontent.com/trlkly/c1c97d07fdc0210adeed4c6a436e885d/raw/c62c7319b5adabf2a8d6986337c690bed93f69b7/grant-none-shim.js\n// @noframes\n// ==/UserScript==\nif (GM.xmlHttpRequest) GM_xmlhttpRequest = GM_xmlHttpRequest;\n" } From e9b2876d1aa42b972cc00b4a72f8350fbc678bd7 Mon Sep 17 00:00:00 2001 From: trlkly Date: Fri, 12 Jan 2018 23:31:19 -0600 Subject: [PATCH 06/17] logic fix --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2826be7..f200c9a 100644 --- a/package.json +++ b/package.json @@ -15,5 +15,5 @@ "load-grunt-tasks": "~3.5" }, "licenseBanner": "/* \n * Copyright (C) 2016 Alexander Krivács Schrøder \n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see .\n */\n", - "userscriptBanner": "// ==UserScript==\n// @name Questionable Content Single-Page Application with Extra Features\n// @namespace https://questionablextensions.net/\n// @version <%= pkg.version %>\n// @author Alexander Krivács Schrøder\n// @description Converts questionablecontent.net into a single-page application and adds extra features, such as character, location and storyline navigation.\n// @homepage https://questionablextensions.net/\n// @icon https://questionablextensions.net/images/icon.png\n// @icon64 https://questionablextensions.net/images/icon64.png\n// @updateURL https://questionablextensions.net/releases/qc-ext.latest.meta.js\n// @downloadURL https://questionablextensions.net/releases/qc-ext.latest.user.js\n// @supportURL https://github.com/Questionable-Content-Extensions/client/issues\n// @match *://*.questionablecontent.net/\n// @match *://*.questionablecontent.net/index.php\n// @match *://*.questionablecontent.net/view.php*\n// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.js\n// @require https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js\n// @require https://questionablextensions.net/scripts/angular.custom.js\n// @require https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.min.js\n// @connect questionablextensions.net\n// @connect localhost\n// @grant GM_getValue\n// @grant GM_setValue\n// @grant GM_xmlhttpRequest\n// @grant GM.xmlHttpRequest\n// @require https://gist.githubusercontent.com/trlkly/c1c97d07fdc0210adeed4c6a436e885d/raw/c62c7319b5adabf2a8d6986337c690bed93f69b7/grant-none-shim.js\n// @noframes\n// ==/UserScript==\nif (GM.xmlHttpRequest) GM_xmlhttpRequest = GM_xmlHttpRequest;\n" + "userscriptBanner": "// ==UserScript==\n// @name Questionable Content Single-Page Application with Extra Features\n// @namespace https://questionablextensions.net/\n// @version <%= pkg.version %>\n// @author Alexander Krivács Schrøder\n// @description Converts questionablecontent.net into a single-page application and adds extra features, such as character, location and storyline navigation.\n// @homepage https://questionablextensions.net/\n// @icon https://questionablextensions.net/images/icon.png\n// @icon64 https://questionablextensions.net/images/icon64.png\n// @updateURL https://questionablextensions.net/releases/qc-ext.latest.meta.js\n// @downloadURL https://questionablextensions.net/releases/qc-ext.latest.user.js\n// @supportURL https://github.com/Questionable-Content-Extensions/client/issues\n// @match *://*.questionablecontent.net/\n// @match *://*.questionablecontent.net/index.php\n// @match *://*.questionablecontent.net/view.php*\n// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.js\n// @require https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js\n// @require https://questionablextensions.net/scripts/angular.custom.js\n// @require https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.min.js\n// @connect questionablextensions.net\n// @connect localhost\n// @grant GM_getValue\n// @grant GM_setValue\n// @grant GM_xmlhttpRequest\n// @grant GM.xmlHttpRequest\n// @require https://gist.githubusercontent.com/trlkly/c1c97d07fdc0210adeed4c6a436e885d/raw/c62c7319b5adabf2a8d6986337c690bed93f69b7/grant-none-shim.js\n// @noframes\n// ==/UserScript==\nif (typeof GM !== 'undefined') GM_xmlhttpRequest = GM.xmlHttpRequest; //shim for GM 4.0\n" } From 6318e7c0f9278a1d2c95fef7e10475edb721b3e9 Mon Sep 17 00:00:00 2001 From: trlkly Date: Sat, 13 Jan 2018 03:01:44 -0600 Subject: [PATCH 07/17] Simplified GM4 script Hopefully possible to inline and made pre-ES6 compatible --- assets/js/gm4-shim.js | 50 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 assets/js/gm4-shim.js diff --git a/assets/js/gm4-shim.js b/assets/js/gm4-shim.js new file mode 100644 index 0000000..8e7a5d2 --- /dev/null +++ b/assets/js/gm4-shim.js @@ -0,0 +1,50 @@ +/* +Functions copied from https://gist.github.com/arantius/3123124 +The MIT License (MIT) + +Copyright (c) 2014 Anthony Lieuallen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. +*/ + +if (typeof GM !== 'undefined') { + var GM_xmlhttpRequest = GM.xmlHttpRequest; + var storagePrefix = GM.info.script.namespace + '?'; + + // The following functions all use local storage, and thus could be accessed + // by the host. They are also restricted to a single domain. + + var GM_deleteValue = function (aKey) { + localStorage.removeItem(storagePrefix + aKey); + }; + + var GM_getValue = function (aKey, aDefault) { + var aValue = localStorage.getItem(storagePrefix + aKey); + if (null === aValue && 'undefined' !== typeof aDefault) return aDefault; + return aValue; + }; + + var GM_listValues = function () { + var prefixLen = storagePrefix.length; + var values = []; + for (var i = 0; i < localStorage.length; i++) { + var k = localStorage.key(i); + if (k.substr(0, prefixLen) === storagePrefix) { + values.push(k.substr(prefixLen)); + } + } + return values; + }; + + var GM_setValue = function (aKey, aVal) { + localStorage.setItem(storagePrefix + aKey, aVal); + }; +} From 60b9534553836362d963e4831986579bcfd2669a Mon Sep 17 00:00:00 2001 From: trlkly Date: Sat, 13 Jan 2018 03:08:16 -0600 Subject: [PATCH 08/17] add new global --- .jshintrc | 1 + 1 file changed, 1 insertion(+) diff --git a/.jshintrc b/.jshintrc index efcdba3..b4f307e 100644 --- a/.jshintrc +++ b/.jshintrc @@ -12,6 +12,7 @@ "GM_getValue": true, "GM_setValue": true, "unsafeWindow": true + "GM": true }, "latedef": true, "nocomma": true, From 3d5b8365f10390f66b00dccee48e1ac4d5ebb590 Mon Sep 17 00:00:00 2001 From: trlkly Date: Sat, 13 Jan 2018 03:10:11 -0600 Subject: [PATCH 09/17] forgot comma --- .jshintrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.jshintrc b/.jshintrc index b4f307e..f24af91 100644 --- a/.jshintrc +++ b/.jshintrc @@ -11,7 +11,7 @@ "GM_xmlhttpRequest": true, "GM_getValue": true, "GM_setValue": true, - "unsafeWindow": true + "unsafeWindow": true, "GM": true }, "latedef": true, From 382cf20f3a55f2b9a0c338f482f340fdd37ee381 Mon Sep 17 00:00:00 2001 From: trlkly Date: Sat, 13 Jan 2018 03:11:23 -0600 Subject: [PATCH 10/17] add back 'use strict' Thought it was causing problems, but apparently not. --- assets/js/gm4-shim.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/assets/js/gm4-shim.js b/assets/js/gm4-shim.js index 8e7a5d2..8c77901 100644 --- a/assets/js/gm4-shim.js +++ b/assets/js/gm4-shim.js @@ -23,16 +23,19 @@ if (typeof GM !== 'undefined') { // by the host. They are also restricted to a single domain. var GM_deleteValue = function (aKey) { + 'use strict'; localStorage.removeItem(storagePrefix + aKey); }; var GM_getValue = function (aKey, aDefault) { + 'use strict'; var aValue = localStorage.getItem(storagePrefix + aKey); if (null === aValue && 'undefined' !== typeof aDefault) return aDefault; return aValue; }; var GM_listValues = function () { + 'use strict'; var prefixLen = storagePrefix.length; var values = []; for (var i = 0; i < localStorage.length; i++) { @@ -45,6 +48,7 @@ if (typeof GM !== 'undefined') { }; var GM_setValue = function (aKey, aVal) { + 'use strict'; localStorage.setItem(storagePrefix + aKey, aVal); }; } From da11aef3c813eca5420c9f5111d16083bed0d5b9 Mon Sep 17 00:00:00 2001 From: trlkly Date: Sat, 13 Jan 2018 03:15:47 -0600 Subject: [PATCH 11/17] JSHint "fixes" --- assets/js/gm4-shim.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/assets/js/gm4-shim.js b/assets/js/gm4-shim.js index 8c77901..623edbf 100644 --- a/assets/js/gm4-shim.js +++ b/assets/js/gm4-shim.js @@ -16,7 +16,9 @@ all copies or substantial portions of the Software. */ if (typeof GM !== 'undefined') { - var GM_xmlhttpRequest = GM.xmlHttpRequest; + /*jshint unused:false*/ + + var GM_xmlhttpRequest = GM.xmlHttpRequest; var storagePrefix = GM.info.script.namespace + '?'; // The following functions all use local storage, and thus could be accessed @@ -30,7 +32,7 @@ if (typeof GM !== 'undefined') { var GM_getValue = function (aKey, aDefault) { 'use strict'; var aValue = localStorage.getItem(storagePrefix + aKey); - if (null === aValue && 'undefined' !== typeof aDefault) return aDefault; + if (null === aValue && 'undefined' !== typeof aDefault) { return aDefault; } return aValue; }; From 69c97bf7becd61b33e180e6bace04ae7a06fa26c Mon Sep 17 00:00:00 2001 From: trlkly Date: Sat, 13 Jan 2018 03:23:31 -0600 Subject: [PATCH 12/17] hopefully fix tabs for JSCS --- assets/js/gm4-shim.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/assets/js/gm4-shim.js b/assets/js/gm4-shim.js index 623edbf..a18953f 100644 --- a/assets/js/gm4-shim.js +++ b/assets/js/gm4-shim.js @@ -16,28 +16,28 @@ all copies or substantial portions of the Software. */ if (typeof GM !== 'undefined') { - /*jshint unused:false*/ + /*jshint unused:false*/ - var GM_xmlhttpRequest = GM.xmlHttpRequest; - var storagePrefix = GM.info.script.namespace + '?'; + var GM_xmlhttpRequest = GM.xmlHttpRequest; + var storagePrefix = GM.info.script.namespace + '?'; // The following functions all use local storage, and thus could be accessed // by the host. They are also restricted to a single domain. var GM_deleteValue = function (aKey) { - 'use strict'; + 'use strict'; localStorage.removeItem(storagePrefix + aKey); }; var GM_getValue = function (aKey, aDefault) { - 'use strict'; + 'use strict'; var aValue = localStorage.getItem(storagePrefix + aKey); if (null === aValue && 'undefined' !== typeof aDefault) { return aDefault; } return aValue; }; var GM_listValues = function () { - 'use strict'; + 'use strict'; var prefixLen = storagePrefix.length; var values = []; for (var i = 0; i < localStorage.length; i++) { @@ -50,7 +50,7 @@ if (typeof GM !== 'undefined') { }; var GM_setValue = function (aKey, aVal) { - 'use strict'; + 'use strict'; localStorage.setItem(storagePrefix + aKey, aVal); }; } From 03827227d4d140fdcdcef195484b592b3f26457c Mon Sep 17 00:00:00 2001 From: trlkly Date: Sat, 13 Jan 2018 03:28:43 -0600 Subject: [PATCH 13/17] hopefully all the other JSCS complaints --- assets/js/gm4-shim.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/assets/js/gm4-shim.js b/assets/js/gm4-shim.js index a18953f..2e6b6e9 100644 --- a/assets/js/gm4-shim.js +++ b/assets/js/gm4-shim.js @@ -24,20 +24,23 @@ if (typeof GM !== 'undefined') { // The following functions all use local storage, and thus could be accessed // by the host. They are also restricted to a single domain. - var GM_deleteValue = function (aKey) { + var GM_deleteValue = function(aKey) { 'use strict'; + localStorage.removeItem(storagePrefix + aKey); }; - var GM_getValue = function (aKey, aDefault) { + var GM_getValue = function(aKey, aDefault) { 'use strict'; + var aValue = localStorage.getItem(storagePrefix + aKey); if (null === aValue && 'undefined' !== typeof aDefault) { return aDefault; } return aValue; }; - var GM_listValues = function () { + var GM_listValues = function() { 'use strict'; + var prefixLen = storagePrefix.length; var values = []; for (var i = 0; i < localStorage.length; i++) { @@ -49,8 +52,9 @@ if (typeof GM !== 'undefined') { return values; }; - var GM_setValue = function (aKey, aVal) { + var GM_setValue = function(aKey, aVal) { 'use strict'; + localStorage.setItem(storagePrefix + aKey, aVal); }; } From 5b72c9d10791885780533a02e17152c601ffd002 Mon Sep 17 00:00:00 2001 From: trlkly Date: Sat, 13 Jan 2018 03:59:23 -0600 Subject: [PATCH 14/17] Add gm4-shim to beginning of concat: source --- Gruntfile.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Gruntfile.js b/Gruntfile.js index 6fce414..7813203 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -86,6 +86,7 @@ module.exports = function (grunt) { banner: '<%= pkg.licenseBanner %>\n<%= pkg.userscriptBanner %>' }, src: [ + 'assets/js/gm4-shim.js', 'assets/js/constants.js', 'assets/generated/variables.pass2.js', 'assets/js/settings.js', From 08995bbdae7fbfd95fff181e1484fd5747e92612 Mon Sep 17 00:00:00 2001 From: trlkly Date: Sat, 13 Jan 2018 04:01:21 -0600 Subject: [PATCH 15/17] remove code and requires from metablock --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f200c9a..101768e 100644 --- a/package.json +++ b/package.json @@ -15,5 +15,5 @@ "load-grunt-tasks": "~3.5" }, "licenseBanner": "/* \n * Copyright (C) 2016 Alexander Krivács Schrøder \n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see .\n */\n", - "userscriptBanner": "// ==UserScript==\n// @name Questionable Content Single-Page Application with Extra Features\n// @namespace https://questionablextensions.net/\n// @version <%= pkg.version %>\n// @author Alexander Krivács Schrøder\n// @description Converts questionablecontent.net into a single-page application and adds extra features, such as character, location and storyline navigation.\n// @homepage https://questionablextensions.net/\n// @icon https://questionablextensions.net/images/icon.png\n// @icon64 https://questionablextensions.net/images/icon64.png\n// @updateURL https://questionablextensions.net/releases/qc-ext.latest.meta.js\n// @downloadURL https://questionablextensions.net/releases/qc-ext.latest.user.js\n// @supportURL https://github.com/Questionable-Content-Extensions/client/issues\n// @match *://*.questionablecontent.net/\n// @match *://*.questionablecontent.net/index.php\n// @match *://*.questionablecontent.net/view.php*\n// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.js\n// @require https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js\n// @require https://questionablextensions.net/scripts/angular.custom.js\n// @require https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.min.js\n// @connect questionablextensions.net\n// @connect localhost\n// @grant GM_getValue\n// @grant GM_setValue\n// @grant GM_xmlhttpRequest\n// @grant GM.xmlHttpRequest\n// @require https://gist.githubusercontent.com/trlkly/c1c97d07fdc0210adeed4c6a436e885d/raw/c62c7319b5adabf2a8d6986337c690bed93f69b7/grant-none-shim.js\n// @noframes\n// ==/UserScript==\nif (typeof GM !== 'undefined') GM_xmlhttpRequest = GM.xmlHttpRequest; //shim for GM 4.0\n" + "userscriptBanner": "// ==UserScript==\n// @name Questionable Content Single-Page Application with Extra Features\n// @namespace https://questionablextensions.net/\n// @version <%= pkg.version %>\n// @author Alexander Krivács Schrøder\n// @description Converts questionablecontent.net into a single-page application and adds extra features, such as character, location and storyline navigation.\n// @homepage https://questionablextensions.net/\n// @icon https://questionablextensions.net/images/icon.png\n// @icon64 https://questionablextensions.net/images/icon64.png\n// @updateURL https://questionablextensions.net/releases/qc-ext.latest.meta.js\n// @downloadURL https://questionablextensions.net/releases/qc-ext.latest.user.js\n// @supportURL https://github.com/Questionable-Content-Extensions/client/issues\n// @match *://*.questionablecontent.net/\n// @match *://*.questionablecontent.net/index.php\n// @match *://*.questionablecontent.net/view.php*\n// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.js\n// @require https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js\n// @require https://questionablextensions.net/scripts/angular.custom.js\n// @require https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.min.js\n// @connect questionablextensions.net\n// @connect localhost\n// @grant GM_getValue\n// @grant GM_setValue\n// @grant GM_xmlhttpRequest\n// @grant GM.xmlHttpRequest\n// @noframes\n// ==/UserScript==\n" } From 1d6451e14e3c6e9b0bc8cb190bc9aa11121729de Mon Sep 17 00:00:00 2001 From: trlkly Date: Mon, 15 Jan 2018 08:55:12 -0600 Subject: [PATCH 16/17] better storage naming; use GM_ storage if possible I decided that using the namespace as a name was a bad idea if you ever write another script, so I now use the initials from the script name. And since I was already updating anyways, I thought to reverse my previous decision and continue to use GM_ storage if possible, so settings won't be lost unless necessary. I also added a shim for GM_info, which I neglected before. It currently exists in GM 4, but it may be removed in the future, hence the weird testing. Not sure how many edits I should do in one commit, but this one is tested (as much as the rest). --- assets/js/gm4-shim.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/js/gm4-shim.js b/assets/js/gm4-shim.js index 2e6b6e9..bc54be9 100644 --- a/assets/js/gm4-shim.js +++ b/assets/js/gm4-shim.js @@ -15,11 +15,12 @@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. */ -if (typeof GM !== 'undefined') { +if (typeof GM !== 'undefined' && typeof GM_getValue === 'undefined') { /*jshint unused:false*/ + if (typeof GM_info === 'undefined') { const GM_info = GM.info; } var GM_xmlhttpRequest = GM.xmlHttpRequest; - var storagePrefix = GM.info.script.namespace + '?'; + var storagePrefix = GM.info.script.name.replace(/[^A-Z]*/g, '') + '-'; // The following functions all use local storage, and thus could be accessed // by the host. They are also restricted to a single domain. From 5f934a0dda6987cd19095ba84fc741af46a86d1d Mon Sep 17 00:00:00 2001 From: trlkly Date: Mon, 15 Jan 2018 09:12:14 -0600 Subject: [PATCH 17/17] jshint overrides --- assets/js/gm4-shim.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/js/gm4-shim.js b/assets/js/gm4-shim.js index bc54be9..9226e0d 100644 --- a/assets/js/gm4-shim.js +++ b/assets/js/gm4-shim.js @@ -15,9 +15,9 @@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. */ -if (typeof GM !== 'undefined' && typeof GM_getValue === 'undefined') { - /*jshint unused:false*/ +/*jshint unused:false, esversion: 6, latedef: false*/ +if (typeof GM !== 'undefined' && typeof GM_getValue === 'undefined') { if (typeof GM_info === 'undefined') { const GM_info = GM.info; } var GM_xmlhttpRequest = GM.xmlHttpRequest; var storagePrefix = GM.info.script.name.replace(/[^A-Z]*/g, '') + '-';