Greasy Fork is available in English.
load wenku8+ temporarily
Ce script ne doit pas être installé directement. C'est une librairie destinée à être incluse dans d'autres scripts avec la méta-directive // @require https://update.greasyfork.org/scripts/437461/1001439/wenku8%2B%20loader.js
// 源代码 (function () { const KEY_LOCALCDN = 'LOCAL-CDN'; const KEY_LOCALCDN_VERSION = 'version'; const VALUE_LOCALCDN_VERSION = '0.1'; const KEY_POLYFILL = 'wenku8-plus-injecter'; GM_PolyFill(KEY_POLYFILL); DoLog(); DoLog(LogLevel.Success, 'wenku8+ loader loaded successfully on this page'); const main_url = 'https://greasyfork.org/scripts/416310/code/script.user.js'; const loader_url = 'https://greasyfork.org/scripts/437461/code/script.js'; dealDocument(); function dealDocument(oDom=document) { // Hook window.open const open = window.open; window.open = openWithInjector; function openWithInjector(strUrl, strWindowName, strWindowFeatures) { const newTab = open(strUrl, strWindowName, strWindowFeatures); const oDom = newTab.document; const oWin = newTab.window; oWin.addEventListener('load', function() { const script = oDom.createElement('script'); script.src = loader_url; oWin.document.head.appendChild(script); }); return newTab; } // Hook <a> hooklinks(); setInterval(hooklinks, 200); // Load wenku8+ const script = oDom.createElement('script'); script.src = main_url; document.head.appendChild(script); function hooklinks() { // Hook <a> for (const a of document.querySelectorAll('a')) { !a.wenku8_loader_hooked && a.addEventListener('click', onclick); a.wenku8_loader_hooked = true; } function onclick(e) { const a = e.currentTarget; const href = a.href;; if (!a.href.match(/^https?:\/\//)) {return;} destroyEvent(e); window.open(href); } } } // Just stopPropagation and preventDefault function destroyEvent(e) { if (!e) {return false;}; if (!e instanceof Event) {return false;}; e.stopPropagation(); e.preventDefault(); } // Load/Read and Save javascript from given url // Auto reties when xhr fails. // If load success then callback(true), else callback(false) function loadJSPlus(url, callback, oDoc=document, maxRetry=3, retried=0) { const fn = callback || function () {}; const localCDN = GM_getValue(KEY_LOCALCDN, {}); if (localCDN[url]) { DoLog(LogLevel.Info, 'Loading js from localCDN: ' + url); const js = localCDN[url]; appendScript(js); fn(true); return; } DoLog(LogLevel.Info, 'Loading js from web: ' + url); GM_xmlhttpRequest({ method : 'GET', url : url, responseType : 'text', onload : function(e) { if (e.status === 200) { const js = e.responseText; localCDN[url] = js; localCDN[KEY_LOCALCDN_VERSION] = VALUE_LOCALCDN_VERSION; GM_setValue(KEY_LOCALCDN, localCDN); appendScript(js); fn(true); } else { retry(); } }, onerror : retry }) function appendScript(code) { const script = oDoc.createElement('script'); script.type = 'text/javascript'; script.innerHTML = code; oDoc.head.appendChild(script); } function retry() { retried++; if (retried <= maxRetry) { loadJSPlus(url, callback, oDoc, maxRetry, retried); } else { fn(false); } } } // GM_Polyfill By PY-DNG // 2021.07.18 // 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 function GM_PolyFill(name='default') { const GM_POLYFILL_KEY_STORAGE = 'GM_STORAGE_POLYFILL'; const GM_POLYFILL_storage = GM_POLYFILL_getStorage(); const GM_POLYFILLED = { GM_setValue: true, GM_getValue: true, GM_deleteValue: true, GM_listValues: true, GM_xmlhttpRequest: true, GM_openInTab: true, GM_setClipboard: true, }; GM_setValue_polyfill(); GM_getValue_polyfill(); GM_deleteValue_polyfill(); GM_listValues_polyfill(); GM_xmlhttpRequest_polyfill(); GM_openInTab_polyfill(); GM_setClipboard_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_setValue function GM_setValue_polyfill() { typeof (GM_setValue) === 'function' ? GM_POLYFILLED.GM_setValue = false: window.GM_setValue = PF_GM_setValue;; function PF_GM_setValue(name, value) { name = String(name); GM_POLYFILL_storage[name] = value; GM_POLYFILL_saveStorage(); }; }; // GM_getValue function GM_getValue_polyfill() { typeof (GM_getValue) === 'function' ? GM_POLYFILLED.GM_getValue = false: window.GM_getValue = PF_GM_getValue; function PF_GM_getValue(name, defaultValue) { name = String(name); if (GM_POLYFILL_storage.hasOwnProperty(name)) { return GM_POLYFILL_storage[name]; } else { return defaultValue; }; }; }; // GM_deleteValue function GM_deleteValue_polyfill() { typeof (GM_deleteValue) === 'function' ? GM_POLYFILLED.GM_deleteValue = false: window.GM_deleteValue = PF_GM_deleteValue; function PF_GM_deleteValue(name) { name = String(name); if (GM_POLYFILL_storage.hasOwnProperty(name)) { delete GM_POLYFILL_storage[name]; GM_POLYFILL_saveStorage(); }; }; }; // GM_listValues function GM_listValues_polyfill() { typeof (GM_listValues) === 'function' ? GM_POLYFILLED.GM_listValues = false: window.GM_listValues = PF_GM_listValues; function PF_GM_listValues() { return Object.keys(GM_POLYFILL_storage); }; }; // 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 Tempermonkey function PF_GM_xmlhttpRequest(details) { const xhr = new XMLHttpRequest(); // open request const 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 headers if (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 () {}; // properties xhr.timeout = details.timeout; xhr.responseType = details.responseType; details.overrideMimeType ? xhr.overrideMimeType(details.overrideMimeType) : function () {}; // events xhr.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 request details.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 copying const newInput = document.createElement('textarea'); document.body.appendChild(newInput); newInput.value = text; newInput.select(); document.execCommand('copy'); document.body.removeChild(newInput); }; }; return GM_POLYFILLED; }; // Arguments: level=LogLevel.Info, logContent, asObject=false // Needs one call "DoLog();" to get it initialized before using it! function DoLog() { // Global log levels set window.LogLevel = { None: 0, Error: 1, Success: 2, Warning: 3, Info: 4, } window.LogLevelMap = {}; window.LogLevelMap[LogLevel.None] = {prefix: '' , color: 'color:#ffffff'} window.LogLevelMap[LogLevel.Error] = {prefix: '[Error]' , color: 'color:#ff0000'} window.LogLevelMap[LogLevel.Success] = {prefix: '[Success]' , color: 'color:#00aa00'} window.LogLevelMap[LogLevel.Warning] = {prefix: '[Warning]' , color: 'color:#ffa500'} window.LogLevelMap[LogLevel.Info] = {prefix: '[Info]' , color: 'color:#888888'} window.LogLevelMap[LogLevel.Elements] = {prefix: '[Elements]', color: 'color:#000000'} // Current log level DoLog.logLevel = window.isPY_DNG ? LogLevel.Info : LogLevel.Warning; // Info Warning Success Error // Log counter DoLog.logCount === undefined && (DoLog.logCount = 0); if (++DoLog.logCount > 512) { console.clear(); DoLog.logCount = 0; } // Get args let level, logContent, asObject; switch (arguments.length) { case 1: level = LogLevel.Info; logContent = arguments[0]; asObject = false; break; case 2: level = arguments[0]; logContent = arguments[1]; asObject = false; break; case 3: level = arguments[0]; logContent = arguments[1]; asObject = arguments[2]; break; default: level = LogLevel.Info; logContent = 'DoLog initialized.'; asObject = false; break; } // Log when log level permits if (level <= DoLog.logLevel) { let msg = '%c' + LogLevelMap[level].prefix; let subst = LogLevelMap[level].color; if (asObject) { msg += ' %o'; } else { switch(typeof(logContent)) { case 'string': msg += ' %s'; break; case 'number': msg += ' %d'; break; case 'object': msg += ' %o'; break; } } console.log(msg, subst, logContent); } } })();