Provide GM_functions in non-ScriptManager-environment
This script should not be not be installed directly. It is a library for other scripts to include with the meta directive // @require https://update.greasyfork.org/scripts/429613/975941/GM_Polyfill.js
/* eslint-disable no-multi-spaces */// ==UserScript==// @name GM_Polyfill// @namespace GM_Polyfill// @version 0.3// @description Provide GM_functions in non-ScriptManager-environment// @author PY-DNG// @match *// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADF0lEQVRYhe2XQU/bSBTHPbKRKtkmkpESbdVLcgwC4dtKjZDPFZgv0OTEN+h3gPNe+AIIBIccUeC0VrVa0khslDYgpSr1arUoPeaWxYz928OOaTY4hGVL2wMjvdu8937zxs/zf5r2vS1gBTgAhny5NQQOgdXbEj8BtgGCIOi5rtsyTXMghEDTtHuZEALTNAdLS0utIAh6CmYbeJIFsJ0kifR9/1gIkdw36S0wie/7x0mSSGA7q+z4vn/8pROPm+/7x6oSK6MAB0EQ9B7i5FmVUNdxMAowdF239dDJU3NdtwUMRwEwTXPwtQBM0xwA/Avg/3zt97gGbgB8reSpPQI8AjwC3BnAMIxLy7IGhmFc3TW4rutRLpcbGIbx170BSqXSu0aj0Y3jWAJEURTt7u62C4XC+0lB8/l8b39/vx1FUQQQx7E8Ojrqlkql9n8CqFarzSRJAN4Aa8AzoAacSSllpVJpjgesVCpNKaUEzoCXwFP1yv4CsL6+3roTQLlcPlHP5RagayNLiZa6lFLm8/le6lMoFN6r5PVxsQHowE8ACwsLJ1MBOp3OR+D1ePIxiLO9vb3fUp+dnZ0ToJepdD5D/Nztdn9P35xMANu2P6nTP88KNLL/ZRRFka7rkWEYV+rOa1N8fgSwbbs/EcBxnFP+EZCZpx/Z/wNALpcbWJY1UNDPpvjowHBubu40E0AIwezs7IUKtjgl2Focx3JmZubSMIxL1SlrU3wWASzL+iPzOU4VcBiGfaA+5SRvDg8Pu5r6BhqNRld1zMTKAfUwDPupUh4HuJZknuc1VRVeTUi+lSQJxWKxkwIUi8W3qm1vdI7yewXgeV5T07Il2bUoFUKwsbHRUhB1VTodeK66g1qtduM/UK1WU/DXaq+ufOsAm5ubLSHERFH6Aj7LciEEy8vLzfPz8z9V0CFAp9P5WC6XT8aTpzY/P99ut9sfRn3CMOx7ntdM2y9TliuIG4OJEALbti8cxzk1TbM/KfG4WZb1yXGcU9u2L9LEQohkdXX118zBRAE82Gjmuu700WwE5KGG0wNuG06/1fobtnrEdKhuQ44AAAAASUVORK5CYII=// @grant GM_setValue// @grant GM_getValue// @grant GM_deleteValue// @grant GM_listValues// @grant GM_xmlhttpRequest// @grant GM_openInTab// @grant GM_setClipboard// ==/UserScript==// GM_Polyfill By PY-DNG// 2021.07.18 - 2021.07.19// Simply provides the following GM_functions using localStorage, XMLHttpRequest and window.open:// Returns object GM_POLYFILLED which has the following properties that shows you which GM_functions are actually polyfilled:// GM_setValue, GM_getValue, GM_deleteValue, GM_listValues, GM_xmlhttpRequest, GM_openInTab, GM_setClipboard, unsafeWindow(object)// All polyfilled GM_functions are accessable in window object/Global_Scope(only without Tempermonkey Sandboxing environment)function GM_PolyFill(name = 'default') {const GM_POLYFILL_KEY_STORAGE = 'GM_STORAGE_POLYFILL';let GM_POLYFILL_storage;const GM_POLYFILLED = {GM_setValue: true,GM_getValue: true,GM_deleteValue: true,GM_listValues: true,GM_xmlhttpRequest: true,GM_openInTab: true,GM_setClipboard: true,unsafeWindow: true}// Ignore GM_PolyFill_Oncewindow.GM_POLYFILLED && window.GM_POLYFILLED.once && (window.unsafeWindow = window.GM_setClipboard = window.GM_openInTab = window.GM_xmlhttpRequest = window.GM_getValue = window.GM_setValue = window.GM_listValues = window.GM_deleteValue = undefined);GM_setValue_polyfill();GM_getValue_polyfill();GM_deleteValue_polyfill();GM_listValues_polyfill();GM_xmlhttpRequest_polyfill();GM_openInTab_polyfill();GM_setClipboard_polyfill();unsafeWindow_polyfill();function GM_POLYFILL_getStorage() {let gstorage = localStorage.getItem(GM_POLYFILL_KEY_STORAGE);gstorage = gstorage ? JSON.parse(gstorage) : {};let storage = gstorage[name] ? gstorage[name] : {};return storage;}function GM_POLYFILL_saveStorage() {let gstorage = localStorage.getItem(GM_POLYFILL_KEY_STORAGE);gstorage = gstorage ? JSON.parse(gstorage) : {};gstorage[name] = GM_POLYFILL_storage;localStorage.setItem(GM_POLYFILL_KEY_STORAGE, JSON.stringify(gstorage));}// GM_setValuefunction GM_setValue_polyfill() {typeof (GM_setValue) === 'function' ? GM_POLYFILLED.GM_setValue = false: window.GM_setValue = PF_GM_setValue;;function PF_GM_setValue(name, value) {GM_POLYFILL_storage = GM_POLYFILL_getStorage();name = String(name);GM_POLYFILL_storage[name] = value;GM_POLYFILL_saveStorage();}}// GM_getValuefunction GM_getValue_polyfill() {typeof (GM_getValue) === 'function' ? GM_POLYFILLED.GM_getValue = false: window.GM_getValue = PF_GM_getValue;function PF_GM_getValue(name, defaultValue) {GM_POLYFILL_storage = GM_POLYFILL_getStorage();name = String(name);if (GM_POLYFILL_storage.hasOwnProperty(name)) {return GM_POLYFILL_storage[name];} else {return defaultValue;}}}// GM_deleteValuefunction GM_deleteValue_polyfill() {typeof (GM_deleteValue) === 'function' ? GM_POLYFILLED.GM_deleteValue = false: window.GM_deleteValue = PF_GM_deleteValue;function PF_GM_deleteValue(name) {GM_POLYFILL_storage = GM_POLYFILL_getStorage();name = String(name);if (GM_POLYFILL_storage.hasOwnProperty(name)) {delete GM_POLYFILL_storage[name];GM_POLYFILL_saveStorage();}}}// GM_listValuesfunction GM_listValues_polyfill() {typeof (GM_listValues) === 'function' ? GM_POLYFILLED.GM_listValues = false: window.GM_listValues = PF_GM_listValues;function PF_GM_listValues() {GM_POLYFILL_storage = GM_POLYFILL_getStorage();return Object.keys(GM_POLYFILL_storage);}}// unsafeWindowfunction unsafeWindow_polyfill() {typeof (unsafeWindow) === 'object' ? GM_POLYFILLED.unsafeWindow = false: window.unsafeWindow = window;}// GM_xmlhttpRequest// not supported properties of details: synchronous binary nocache revalidate context fetch// not supported properties of response(onload arguments[0]): finalUrl// ---!IMPORTANT!--- DOES NOT SUPPORT CROSS-ORIGIN REQUESTS!!!!! ---!IMPORTANT!---function GM_xmlhttpRequest_polyfill() {typeof (GM_xmlhttpRequest) === 'function' ? GM_POLYFILLED.GM_xmlhttpRequest = false: window.GM_xmlhttpRequest = PF_GM_xmlhttpRequest;// details.synchronous is not supported as Tempermonkeyfunction PF_GM_xmlhttpRequest(details) {const xhr = new XMLHttpRequest();// open requestconst openArgs = [details.method, details.url, true];if (details.user && details.password) {openArgs.push(details.user);openArgs.push(details.password);}xhr.open.apply(xhr, openArgs);// set headersif (details.headers) {for (const key of Object.keys(details.headers)) {xhr.setRequestHeader(key, details.headers[key]);}}details.cookie ? xhr.setRequestHeader('cookie', details.cookie) : function () {};details.anonymous ? xhr.setRequestHeader('cookie', '') : function () {};// propertiesxhr.timeout = details.timeout;xhr.responseType = details.responseType;details.overrideMimeType ? xhr.overrideMimeType(details.overrideMimeType) : function () {};// eventsxhr.onabort = details.onabort;xhr.onerror = details.onerror;xhr.onloadstart = details.onloadstart;xhr.onprogress = details.onprogress;xhr.onreadystatechange = details.onreadystatechange;xhr.ontimeout = details.ontimeout;xhr.onload = function (e) {const response = {readyState: xhr.readyState,status: xhr.status,statusText: xhr.statusText,responseHeaders: xhr.getAllResponseHeaders(),response: xhr.response};(details.responseType === '' || details.responseType === 'text') ? (response.responseText = xhr.responseText) : function () {};(details.responseType === '' || details.responseType === 'document') ? (response.responseXML = xhr.responseXML) : function () {};details.onload(response);}// send requestdetails.data ? xhr.send(details.data) : xhr.send();return {abort: xhr.abort};}}// NOTE: options(arg2) is NOT SUPPORTED! if provided, then will just be skipped.function GM_openInTab_polyfill() {typeof (GM_openInTab) === 'function' ? GM_POLYFILLED.GM_openInTab = false: window.GM_openInTab = PF_GM_openInTab;function PF_GM_openInTab(url) {window.open(url);}}// NOTE: needs to be called in an event handler function, and info(arg2) is NOT SUPPORTED!function GM_setClipboard_polyfill() {typeof (GM_setClipboard) === 'function' ? GM_POLYFILLED.GM_setClipboard = false: window.GM_setClipboard = PF_GM_setClipboard;function PF_GM_setClipboard(text) {// Create a new textarea for copyingconst newInput = document.createElement('textarea');document.body.appendChild(newInput);newInput.value = text;newInput.select();document.execCommand('copy');document.body.removeChild(newInput);}}return GM_POLYFILLED;}