// ==UserScript== // @namespace https://greasyfork.org/zh-CN/users/30310-adan1 // @name 自定预加载JS库 // @description 尽可能地使依赖JS库的页面能正常呈现 // @icon http://jquery.com/favicon.ico // @author Adan1 // @include http://* // @include https://* /// @connect * // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant GM_listValues // @grant GM_xmlhttpRequest // @grant GM_getResourceText // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @require http://cdn.staticfile.org/jquery/1.8.3/jquery.min.js // @require https://cdn.jsdelivr.net/jquery.blockui/2.70.0/jquery.blockUI.min.js /// @require https://cdn.jsdelivr.net/crypto-js/3.1.2/rollups/md5.js /// @resource ohoho http://cdn.staticfile.org/jquery/1.8.3/jquery.min.js /// @resource mask https://cdn.jsdelivr.net/jquery.blockui/2.70.0/jquery.blockUI.min.js // @run-at document-start // @date 2016-02-20 // @version 1.0 // @modified 2016-03-10 // @downloadURL https://update.greasyfork.icu/scripts/17881/%E8%87%AA%E5%AE%9A%E9%A2%84%E5%8A%A0%E8%BD%BDJS%E5%BA%93.user.js // @updateURL https://update.greasyfork.icu/scripts/17881/%E8%87%AA%E5%AE%9A%E9%A2%84%E5%8A%A0%E8%BD%BDJS%E5%BA%93.meta.js // ==/UserScript== //eval(GM_getResourceText("ohoho")); (function(gmWindow, jQuery, $){ //eval(GM_getResourceText("mask")); var Storage = (function(dis){ dis.gm = { get: function(key){ return GM_getValue(key); //不存在的映射项返回undefined }, put: function(key, value){ //验证过可以直接存取Object对象,还有必要JSON? if(value===undefined){ value = null; } GM_setValue(key, value); //value=undefined时会被强制转成字符串'undefined',value=null时不会被转换。 }, isExist: function(key){ return GM_getValue(key)!==undefined; }, remove: function(key){ GM_deleteValue(key); }, getJSON: function(key){ var j = this.get(key); if(j!==undefined){ j = JSON.parse(j); } return j; }, putJSON: function(key, jsonObj){ if(jsonObj==undefined){ jsonObj = null; }else{ jsonObj = JSON.stringify(jsonObj); } GM_setValue(key, jsonObj); }, size: function(){ return GM_listValues().length; }, clear: function(){ GM_listValues().forEach(GM_deleteValue); /* for(var i=GM_listValues().length-1; i>-1; i--){ var key = GM_listValues()[i]; this.remove(key); } */ }, list: function(callback){ if(!($.type(callback) === "function")){return;} //return Object.prototype.toString.call(fn)==='[object Function]'; var readOnlyKeys = GM_listValues(); for(var i=0; i=array.length){ return; } var offs = index + 1; if(isLeft===true){ if(index===0){ return; } //必须的 offs = index - 1; } array.splice(offs, 0, array.splice(index, 1)[0]); } function isRookieNoob(){ //return Storage.gm.get("version")!==GM_info.script.version; return Storage.gm.get("version")===undefined; } for(;;){ if(isRookieNoob()===true){ Storage.gm.put("version", GM_info.script.version); Storage.gm.put("setting", "{}"); //本脚本的选项 console.log("["+GM_info.script.name+" v"+GM_info.script.version+"] 初始化") }else{ console.log("["+GM_info.script.name+" v"+GM_info.script.version+"] 确认载入"); if(false){ // === TEST ONLY === Storage.gm.clear(); DataService.dao.setting.hosts.update({'www.baidu.com':true, 'greasyfork.org':true, 'mahouka.jp':true }); DataService.dao.setting.hostMeta.update('www.baidu.com', {active:true, 'xq-seq':null}); DataService.dao.setting.blackWildcardMeta.update('www.baidu.com', {'match-seq':[0,2,1], 'wildcard-list':['//*/**/','/s?*']}); DataService.dao.setting.whitePathnames.update('www.baidu.com', {'/b':false, '/duty/':true, '/s':true}); DataService.dao.setting.whitePathnameInfo.update('www.baidu.com', '/duty/', {'xq-seq':[2,1,0], 'js-list':[ 'http://ajax.useso.com/ajax/libs/jquery/2.1.0/jquery.min.js', //'https://greasyfork.org/scripts/17346-just-a-test/code/just-a-test.js' 'http://libs.baidu.com/jquerytools/1.2.7/jquery.tools.min.js' ]}); DataService.dao.setting.whitePathnameInfo.update('www.baidu.com', '/s', {'xq-seq':[1,0,2], 'js-list':[ 'http://libs.baidu.com/jquerytools/1.2.7/jquery.tools.min.js', 'http://ajax.useso.com/ajax/libs/jquery/2.1.0/jquery.min.js' ]}); DataService.dao.setting.whiteWildcardMeta.update('www.baidu.com', {'match-seq':[2,0,1], 'wildcard-list':['//*/**/','/duty/*', '/s/*']}); DataService.dao.setting.whiteWildcardInfo.update('www.baidu.com', '/duty/*', {'xq-seq':[1,0], 'js-list':[ //'https://greasyfork.org/scripts/17346-just-a-test/code/just-a-test.js', 'http://libs.baidu.com/jquerytools/1.2.7/jquery.tools.min.js' ]}); } if(DataService.model.setting.hosts()[location.host] === undefined){ break; } var hostMeta = DataService.model.setting.hostMeta(location.host); if(hostMeta['active']!==true){ break; } if(hostMeta['protocol'].indexOf(location.protocol) < 0){ break; } var xqSeqMap = { '4': function(){ var bwm = DataService.model.setting.blackWildcardMeta(location.host); return bwm['match-seq'].some(function(cv){ var bw = bwm['wildcard-list'][cv]; if(bw==undefined){ return; } //next if(PathMatcher.matchWildcard(bw)===true){ console.log("黑名单:通配 %s 已拦截 %s", bw, location.href); return true; } //return PathMatcher.matchWildcard(bw);//quick quit forEach }); }, '2': function(){ var wps = DataService.model.setting.whitePathnames(location.host); for(var wp in wps){ if(wps[wp]!==true){ continue; } if(PathMatcher.match(wp)){ console.log("白名单:个例 %s 已匹配 %s", wp, location.href); var wpi = DataService.model.setting.whitePathnameInfo(location.host, wp); var scptInjt = new ScriptInjector(); wpi['xq-seq'].forEach(function(element){ var link = wpi['js-list'][element]; if(link==undefined){ return; } //next console.log("尝试加载JS资源 %s 到 %s", link, location.href); if(link.charAt(0)==='@'){ scptInjt.injectContent(DataService.model.resource.scriptTxt(link.substring(1))); }else{ scptInjt.injectUrlContent(link); } }); return true; } } }, '1': function(){ var wwm = DataService.model.setting.whiteWildcardMeta(location.host); return wwm['match-seq'].some(function(cv){ var ww = wwm['wildcard-list'][cv]; if(ww==undefined){ return; } //next if(PathMatcher.matchWildcard(ww)){ console.log("白名单:通配 %s 已匹配 %s", ww, location.href); var wwi = DataService.model.setting.whiteWildcardInfo(location.host, ww); var scptInjt = new ScriptInjector(); wwi['xq-seq'].forEach(function(element){ var link = wwi['js-list'][element]; if(link==undefined){ return; } //next console.log("尝试加载JS资源 %s 到 %s", link, location.href); if(link.charAt(0)==='@'){ scptInjt.injectContent(DataService.model.resource.scriptTxt(link.substring(1))); }else{ scptInjt.injectUrlContent(link); } }); return true;//quick quit forEach } }); } }; var seq; hostMeta['xq-seq'].some(function(element, index, array){ //本应使用find方法,但Chrome没实现。 //console.log(element); if(xqSeqMap[element]()==true){ seq = element; return true; //quick quit forEach } }); //Storage.gm.listToLog(); } break;} function isNotIframe(){ // check and fix for menu UI and the blockUI return window.self === window.top; }; if(isNotIframe()===true){ //GM_registerMenuCommand("结束当前页面JS链接加载", function(){alert("JS加载等待过久才好使用此功能。");}); $(function(){ // NEW BUG: 当注入的脚本中含有破坏整个网页结构的,$将无法访问,导致没有触发document event。 $.blockUI.defaults.centerX = true $.blockUI.defaults.centerY = true $.blockUI.defaults.fadeIn = 500; $.blockUI.defaults.fadeOut = 500; $.blockUI.defaults.timeout = 0; //指定时间后消失 $.blockUI.defaults.css.border = "0 solid"; //$.blockUI.defaults.css.top = '30px'; //$.blockUI.defaults.css.left = '40%'; $.blockUI.defaults.css.cursor = null; $.blockUI.defaults.baseZ = 2147483647; // MAX $.blockUI.defaults.overlayCSS.cursor = "wait"; $.blockUI.defaults.showOverlay = true; //遮罩层 //$.growlUI('Notification Title', 'Notification Content...'); //通知信息 var menu1 = function(){ if($("style#preloadjs-simple-style").size()===0){ // GM_addStyle $("").appendTo(document.body).text([ "#preloadjs-simple{ background-color:white; margin:initial; padding:initial; }", "#preloadjs-simple{ width:550px; height:480px; -height:495px; border:1px solid white; color:black; padding-top:20px; }", "#preloadjs-simple>div{ MARGIN-LEFT:auto; MARGIN-RIGHT:auto; margin-bottom:10px; text-align:center; width:520px; height:190px; border:1px solid white; }", "#preloadjs-simple input{ font:normal 14px 宋体; }", "#preloadjs-simple select{ width:514px; border:1px solid gray; -line-height:normal; }", "#preloadjs-simple .title{ font:normal 14px 宋体; margin:0px 0 5px 0; }", "#preloadjs-simple>p{ margin:10px 0 0px 18px; width:510px; height:18px; font:normal 14px arial; color:gray; text-align:left; float:left; }", "#preloadjs-simple>p{ white-space:nowrap; overflow-x:hidden; overflow-y:auto; -text-overflow:ellipsis; }", "#preloadjs-simple-cdnlist{ display:none; }", "#preloadjs-simple-cdnlist-bt-add{ float:left; }", "#preloadjs-simple-cdnlist-bt-addall{ float:right; }", "#preloadjs-simple-jslist{ display:none; }", "#preloadjs-simple-jslist.solo{ height:390px; }", "#preloadjs-simple-jslist-show{ -height:341px; }", "#preloadjs-simple-jslist-bt-add{ float:left; }", "#preloadjs-simple-jslist-bt-delete{ float:right; }", "div#preloadjs-simple-bottom{ width:auto; height:45px; border-top:1px solid gray; margin-top:1px; }", "#preloadjs-simple-bottom input{ margin:10px 17px; }", "#preloadjs-simple-bt-apply{ float:left; }", "#preloadjs-simple-bt-applysite{ float:left; }", "#preloadjs-simple-bt-close{ float:right; }" ].join("\n")); } var ui_simple = $("
"); $(["
", "

检查到当前页面引入Google平台下相关的JS库资源,推荐使用360公共CDN提取资源。

", "", "", "", "
"].join("")).appendTo(ui_simple).each(function(){ var colle = $("script[src][injected!=true]").map(function(){ var url = this.src.trim(); var reg = /^(\w+):\/\/([^\/:]*)(?::(\d+))?\/(.*)/; var result = reg.exec(url); //alert(RegExp.$1 + ',' + RegExp.$2 + '' + RegExp.$3 + ',' + RegExp.$4+ ',' + RegExp.$5); if(["ajax.googleapis.com"].indexOf(RegExp.$2 + RegExp.$3)>-1){ return url; } }); var p = $(this); if(colle.length===0){ p.prop("google-not-found", true); return; } p.find("#preloadjs-simple-cdnlist-show").each(function(){ Array.prototype.forEach.call(colle, function(e){ //seems not array that no method this.add(new Option(e, e)); }, this); }); var transfer = function(url){ var si = 0; si = url.indexOf("//", si); si = url.indexOf("/", si+2); return "//ajax.useso.com" + url.substring(si); } p.find("#preloadjs-simple-cdnlist-bt-add").click(function(){ $("#preloadjs-simple-cdnlist-show").each(function(){ if(this.selectedIndex===-1){ alert("没有选中项"); return; } var lnk = this.selectedOptions[0].text; lnk = transfer(lnk); $("#preloadjs-simple-jslist-show").append(new Option(lnk, lnk)); }); }); p.find("#preloadjs-simple-cdnlist-bt-addall").click(function(){ $("#preloadjs-simple-cdnlist-show").each(function(){ Array.prototype.forEach.call(this.options, function(e){ var lnk = e.text; lnk = transfer(lnk); $("#preloadjs-simple-jslist-show").append(new Option(lnk, lnk)); }); }); }); p.fadeIn("slow"); }); $(["
", "

需要加载的JS库资源

", "", "", "", "", "", "
"].join("")).appendTo(ui_simple).each(function(){ var p = $(this); if(ui_simple.find("#preloadjs-simple-cdnlist").prop("google-not-found")===true){ p.addClass("solo").find("#preloadjs-simple-jslist-show").attr("size", 20); p.find("#preloadjs-simple-jslist-show").css("height", "341px"); // UI BUG } p.find("#preloadjs-simple-jslist-bt-add").click(function(){ var input = prompt("请输入需要加载JS的URL:", null); if(input==null){ return; } input = input.trim(); if(/^( |\S)+$/g.test(input)){ $("#preloadjs-simple-jslist-show").append(new Option(input, input)); } }); p.find("#preloadjs-simple-jslist-bt-delete").click(function(){ $("#preloadjs-simple-jslist-show").each(function(){ if(this.selectedIndex===-1){ alert("没有选中项"); return; } var op = this.selectedOptions[0]; if(confirm("确认删除项:\n"+op.text)===true){ op.outerHTML = ""; } }); }); p.find("#preloadjs-simple-jslist-bt-up").click(function(){ $("#preloadjs-simple-jslist-show").each(function(){ if(this.selectedIndex===-1){ alert("没有选中项"); return; } $(this.selectedOptions[0]).after(this.options[this.selectedIndex-1]); }); }); p.find("#preloadjs-simple-jslist-bt-down").click(function(){ $("#preloadjs-simple-jslist-show").each(function(){ if(this.selectedIndex===-1){ alert("没有选中项"); return; } $(this.selectedOptions[0]).before(this.options[this.selectedIndex+1]); }); }); p.fadeIn("slow"); }); $("

").appendTo(ui_simple).text(location.href); $("
").appendTo(ui_simple); $(["
", "", "", "", "
"].join("")).appendTo(ui_simple).each(function(){ var p = $(this); p.find("#preloadjs-simple-bt-apply").click(function(){ var hosts = DataService.model.setting.hosts(); hosts[location.host] = true; DataService.dao.setting.hosts.update(location.host, hosts); var pathname = location.href.substring(location.origin.length); var hostDump = DataService.dump.setting.host(location.host); DataService.dao.setting.hostMeta.update(location.host, hostDump.hostMeta); hostDump.whitePathnames[pathname] = true; DataService.dao.setting.whitePathnames.update(location.host, hostDump.whitePathnames); var wpi = DataService.model.setting.whitePathnameInfo(location.host, pathname); var incr = $.map($("#preloadjs-simple-jslist-show").children(), function(e){ return e.text; }); Array.prototype.push.apply(wpi["js-list"], incr); Array.prototype.push.apply(wpi["xq-seq"], incr.map(function(v, i){ return wpi["xq-seq"].length+i; })); DataService.dao.setting.whitePathnameInfo.update(location.host, pathname, wpi); alert("已应用保存数据"); }); p.find("#preloadjs-simple-bt-applysite").click(function(){ var hosts = DataService.model.setting.hosts(); hosts[location.host] = true; DataService.dao.setting.hosts.update(location.host, hosts); var wildcard = "/*"; var hostDump = DataService.dump.setting.host(location.host); DataService.dao.setting.hostMeta.update(location.host, hostDump.hostMeta); if(hostDump.whiteWildcardMeta["wildcard-list"].indexOf(wildcard)<0){ //这边不重复算了 hostDump.whiteWildcardMeta["wildcard-list"].push(wildcard); hostDump.whiteWildcardMeta["match-seq"].push(hostDump.whiteWildcardMeta["match-seq"].length); DataService.dao.setting.whiteWildcardMeta.update(location.host, hostDump.whiteWildcardMeta); }; var wwi = DataService.model.setting.whiteWildcardInfo(location.host, wildcard); var incr = $.map($("#preloadjs-simple-jslist-show").children(), function(e){ return e.text; }); Array.prototype.push.apply(wwi["js-list"], incr); Array.prototype.push.apply(wwi["xq-seq"], incr.map(function(v, i){ return wwi["xq-seq"].length+i; })); DataService.dao.setting.whiteWildcardInfo.update(location.host, wildcard, wwi); alert("已应用保存数据"); }); p.find("#preloadjs-simple-bt-close").click(function(){ if(!confirm("确定关闭?关闭意味着之前没有应用(保存)的数据将会丢失。")){ return; } $.unblockUI(); }); }); $.blockUI({ message: ui_simple, css: { top: '30px', left: '55%' } }); }; var menu2 = function(){ // chrome://about/?preloadjs if($("style#preloadjs-advanced-style").size()===0){ // GM_addStyle $("").appendTo(document.body).text([ //"*{ all:default; } *{ all:initial; }", //重置默认值,可惜目前浏览器均不完整支持。 "#preloadjs-advanced{ background-color:white; margin:initial; padding:initial; }", "#preloadjs-advanced{ width:550px; height:550px; border:0px solid black; color:black; }", "#preloadjs-advanced>div{ MARGIN-LEFT:auto; MARGIN-RIGHT:auto; text-align:center; width:520px; height:500px; border:1px solid white; }", "#preloadjs-advanced input{ font:normal 14px 宋体; }", "#preloadjs-advanced .title{ font:normal 20px 宋体; margin:15px 0 5px 0; }", "#preloadjs-advanced .annotation{ font:normal 13px 宋体; color:gray; }", "#preloadjs-advanced-hostlist{ display:none; }", "#preloadjs-advanced-hostlist ul{ overflow-y:auto; height:430px; list-style:none; padding:0; border:0px solid black; }", "#preloadjs-advanced-hostlist ul li{ border:0px solid black; }", "#preloadjs-advanced-hostlist ul li input{ margin-top:10px; font:normal 20px cursive; }", "#preloadjs-advanced-matchlist{ display:none; }", "#preloadjs-advanced-matchlist>label{ display:inline; }", // UI BUG "#preloadjs-advanced-matchlist select{ width:514px; border:1px solid gray; }", "#preloadjs-advanced-matchlist-show{ height:158px; }", // UI BUG "#preloadjs-advanced-matchlist-bt-add{ float:left; }", "#preloadjs-advanced-matchlist-bt-delete{ float:right; }", "#preloadjs-advanced-matchlist-loadjs-show{ height:103px; }", // UI BUG "#preloadjs-advanced-matchlist-loadjs-bt-add{ float:left; }", "#preloadjs-advanced-matchlist-loadjs-bt-delete{ float:right; }", "#preloadjs-advanced-matchlist p{ float:left; margin:20px 4px 5px 4px; }", "#preloadjs-advanced-resource{ display:none; }", "#preloadjs-advanced-resource-bt-add{ float:left; }", "#preloadjs-advanced-resource-bt-delete{ float:right; }", "#preloadjs-advanced-resource select{ width:514px; border:1px solid gray; }", "#preloadjs-advanced-resource textarea{ resize:none; overflow:auto; width:508px; border:1px solid gray; height:230px; margin-top:10px; }", "div#preloadjs-advanced-bottom{ width:auto; height:45px; border-top:1px solid gray; }", "#preloadjs-advanced-bottom input{ margin:10px 16px; }", "#preloadjs-advanced-bt-resource{ float:left; display:none; }", "#preloadjs-advanced-bt-return{ float:left; display:none; }", "#preloadjs-advanced-bt-apply{ float:right; display:none; }", "#preloadjs-advanced-bt-close{ float:right; }" ].join("\n")); } var ui_advanced = $("
"); $(["
", "

已建立的域名档案

", "", "
"].join("")).appendTo(ui_advanced).each(function(){ var p = $(this); p.bind("ui-setup", function(){ var hosts = DataService.model.setting.hosts(); var list = p.children("ul"); list.empty(); //clear for(var h in hosts){ $("").val(h).appendTo(list).wrap("
  • ").one("click", function(){ p.triggerHandler("ui-unsetup"); $("#preloadjs-advanced-matchlist").triggerHandler("ui-setup", this.value); }); } p.slideDown("slow"); ui_advanced.find("#preloadjs-advanced-bt-resource").show("slow"); }).bind("ui-unsetup", function(){ p.slideUp("slow"); ui_advanced.find("#preloadjs-advanced-bt-resource").hide("slow"); }); return false; }); $(["
    ", "", "

    名单优先级: 黑名单:通配 > 白名单:个例 > 白名单:通配

    ", "
    ", "
    ", "", "", "", "", "
    ", "

    加载的JS资源 可以通过“@资源名”方式添加已存储的资源,方便跨域和提升速度。

    ", "
    ", "", "", "", "", "
    ", "

    以上所有列表中的优先级暂时由高到低,通过上移下移调整匹配执行顺序。

    ", "
    "].join("")).appendTo(ui_advanced).each(function(){ var p = $(this); var hostDump = null, changeRecord = null; //CACHE p.find("#preloadjs-advanced-matchlist-active").bind("change", function(evt, data){ if(this.checked==true){ hostDump.hostMeta['active'] = true; }else{ hostDump.hostMeta['active'] = false; } }); p.find("#preloadjs-advanced-matchlist-class").each(function(){ this.add(new Option("白名单:通配", "1")); this.add(new Option("白名单:个例", "2")); this.add(new Option("黑名单:通配", "4")); $(this).bind("change", { '1': function(){ $("#preloadjs-advanced-matchlist-show").trigger("list-load", { "list": function(){ hostDump.whiteWildcardMeta['wildcard-list'].forEach(function(w){ this.add(new Option(w, w)); }, this); }, "add": function(){ var input = prompt("请输入需要匹配的通配路径(不包含域名),以“/”开头:\n(目前暂时只支持第一个*之后的匹配)", null); if(input==null){ return; } input = input.trim(); if(/^\/( |\S)*$/g.test(input)){ if(input.indexOf("*")===-1){ input += "*";} if(hostDump.whiteWildcardMeta["wildcard-list"].indexOf(input)>-1){ alert("不能添加已存在的项目"); return; } hostDump.whiteWildcardMeta["wildcard-list"].push(input); this.add(new Option(input, input)); hostDump.whiteWildcardInfo[input] = { 'xq-seq': [], 'js-list': [] };//rebuild changeRecord.whiteWildcardInfo[input] = "update"; //overmark } }, "delete": function(){ if(this.selectedIndex===-1){ alert("没有选中项"); return; } var op = this.selectedOptions[0]; if(confirm("确认删除项:\n"+op.text)===true){ hostDump.whiteWildcardMeta["wildcard-list"].splice(this.selectedIndex, 1); op.outerHTML = ""; changeRecord.whiteWildcardInfo[op.text] = "delete"; //overmark $("#preloadjs-advanced-matchlist-loadjs-show").removeData("actions").empty(); } }, "up": function(){ if(this.selectedIndex===-1){ alert("没有选中项"); return; } arrayElementSwap(hostDump.whiteWildcardMeta["wildcard-list"], this.selectedIndex, true); $(this.selectedOptions[0]).after(this.options[this.selectedIndex-1]); }, "down": function(){ if(this.selectedIndex===-1){ alert("没有选中项"); return; } arrayElementSwap(hostDump.whiteWildcardMeta["wildcard-list"], this.selectedIndex); $(this.selectedOptions[0]).before(this.options[this.selectedIndex+1]); } }); }, '2': function(){ $("#preloadjs-advanced-matchlist-show").trigger("list-load", { "list": function(){ for(var p in hostDump.whitePathnames){ this.add(new Option(p, p)); } }, "add": function(){ var input = prompt("请输入需要匹配的完整路径(不包含域名),以“/”开头:", null); if(input==null){ return; } input = input.trim(); if(/^\/( |\S)*$/g.test(input)){ if(input in hostDump.whitePathnames){ alert("不能添加已存在的项目"); return; } hostDump.whitePathnames[input] = true; this.add(new Option(input, input)); hostDump.whitePathnameInfo[input] = { 'xq-seq': [], 'js-list': [] };//rebuild changeRecord.whitePathnameInfo[input] = "update"; //overmark } }, "delete": function(){ if(this.selectedIndex===-1){ alert("没有选中项"); return; } var op = this.selectedOptions[0]; if(confirm("确认删除项:\n"+op.text)===true){ delete hostDump.whitePathnames[op.text]; op.outerHTML = ""; delete hostDump.whitePathnameInfo[op.text]; changeRecord.whitePathnameInfo[op.text] = "delete"; //overmark $("#preloadjs-advanced-matchlist-loadjs-show").removeData("actions").empty(); } } }); }, '4': function(){ $("#preloadjs-advanced-matchlist-show").trigger("list-load", { "list": function(){ hostDump.blackWildcardMeta['wildcard-list'].forEach(function(w){ this.add(new Option(w, w)); }, this); }, "add": function(){ var input = prompt("请输入需要匹配的通配路径(不包含域名),以“/”开头:\n(目前暂时只支持第一个*之后的匹配)", null); if(input==null){ return; } input = input.trim(); if(/^\/( |\S)*$/g.test(input)){ if(input.indexOf("*")===-1){ input += "*";} hostDump.blackWildcardMeta["wildcard-list"].push(input); this.add(new Option(input, input)); } }, "delete": function(){ if(this.selectedIndex===-1){ alert("没有选中项"); return; } var op = this.selectedOptions[0]; if(confirm("确认删除项:\n"+op.text)===true){ hostDump.blackWildcardMeta["wildcard-list"].splice(this.selectedIndex, 1); op.outerHTML = ""; } }, "up": function(){ if(this.selectedIndex===-1){ alert("没有选中项"); return; } arrayElementSwap(hostDump.blackWildcardMeta["wildcard-list"], this.selectedIndex, true); $(this.selectedOptions[0]).after(this.options[this.selectedIndex-1]); }, "down": function(){ if(this.selectedIndex===-1){ alert("没有选中项"); return; } arrayElementSwap(hostDump.blackWildcardMeta["wildcard-list"], this.selectedIndex); $(this.selectedOptions[0]).before(this.options[this.selectedIndex+1]); } }); } }, function(evt, data){ evt.data[this.value](); }); }); p.find("#preloadjs-advanced-matchlist-show").bind("list-load", function(evt, data){ $(this).removeData("actions"); $("#preloadjs-advanced-matchlist-loadjs-show").removeData("actions").empty(); this.innerHTML = null; data["list"].call(this); // with 'select' $(this).data("actions", data); }).bind("change", { '1': function(wildcard){ $("#preloadjs-advanced-matchlist-loadjs-show").trigger("list-load", { "wildcard": wildcard, "list": function(actions){ hostDump.whiteWildcardInfo[actions.wildcard]['js-list'].forEach(function(js){ this.add(new Option(js, js)); }, this); }, "add": function(actions){ var input = prompt("请输入需要加载JS的URL:", null); if(input==null){ return; } input = input.trim(); if(/^( |\S)+$/g.test(input)){ hostDump.whiteWildcardInfo[actions.wildcard]['js-list'].push(input); this.add(new Option(input, input)); changeRecord.whiteWildcardInfo[actions.wildcard] = "update"; //overmark } }, "delete": function(actions){ if(this.selectedIndex===-1){ alert("没有选中项"); return; } var op = this.selectedOptions[0]; if(confirm("确认删除项:\n"+op.text)===true){ hostDump.whiteWildcardInfo[actions.wildcard]['js-list'].splice(this.selectedIndex, 1); op.outerHTML = ""; changeRecord.whiteWildcardInfo[actions.wildcard] = "update"; //overmark } }, "up": function(actions){ if(this.selectedIndex===-1){ alert("没有选中项"); return; } arrayElementSwap(hostDump.whiteWildcardInfo[actions.wildcard]['js-list'], this.selectedIndex, true); $(this.selectedOptions[0]).after(this.options[this.selectedIndex-1]); changeRecord.whiteWildcardInfo[actions.wildcard] = "update"; //overmark }, "down": function(actions){ if(this.selectedIndex===-1){ alert("没有选中项"); return; } arrayElementSwap(hostDump.whiteWildcardInfo[actions.wildcard]['js-list'], this.selectedIndex); $(this.selectedOptions[0]).before(this.options[this.selectedIndex+1]); changeRecord.whiteWildcardInfo[actions.wildcard] = "update"; //overmark } }); }, '2': function(pathname){ $("#preloadjs-advanced-matchlist-loadjs-show").trigger("list-load", { "pathname": pathname, "list": function(actions){ hostDump.whitePathnameInfo[actions.pathname]['js-list'].forEach(function(js){ this.add(new Option(js, js)); }, this); }, "add": function(actions){ var input = prompt("请输入需要加载JS的URL:", null); if(input==null){ return; } input = input.trim(); if(/^( |\S)+$/g.test(input)){ hostDump.whitePathnameInfo[actions.pathname]['js-list'].push(input); this.add(new Option(input, input)); changeRecord.whitePathnameInfo[actions.pathname] = "update"; //overmark } }, "delete": function(actions){ if(this.selectedIndex===-1){ alert("没有选中项"); return; } var op = this.selectedOptions[0]; if(confirm("确认删除项:\n"+op.text)===true){ hostDump.whitePathnameInfo[actions.pathname]['js-list'].splice(this.selectedIndex, 1); op.outerHTML = ""; changeRecord.whitePathnameInfo[actions.pathname] = "update"; //overmark } }, "up": function(actions){ if(this.selectedIndex===-1){ alert("没有选中项"); return; } arrayElementSwap(hostDump.whitePathnameInfo[actions.pathname]['js-list'], this.selectedIndex, true); $(this.selectedOptions[0]).after(this.options[this.selectedIndex-1]); changeRecord.whitePathnameInfo[actions.pathname] = "update"; //overmark }, "down": function(actions){ if(this.selectedIndex===-1){ alert("没有选中项"); return; } arrayElementSwap(hostDump.whitePathnameInfo[actions.pathname]['js-list'], this.selectedIndex); $(this.selectedOptions[0]).before(this.options[this.selectedIndex+1]); changeRecord.whitePathnameInfo[actions.pathname] = "update"; //overmark } }); }, '4': function(){ } // not support for black list }, function(evt, data){//选择对应名单的操作发送对应的actions data吗 if(this.selectedIndex===-1){ return; } //修复这奇葩未选中BUG evt.data[$("#preloadjs-advanced-matchlist-class").val()](this.selectedOptions[0].text); }); ["add", "delete", "up", "down"].forEach(function(e){ var show = p.find("#preloadjs-advanced-matchlist-show"); p.find("#preloadjs-advanced-matchlist-bt-"+e).click(function(){ var act = show.data("actions")[e]; if(act == undefined){ alert("sorry not support"); return; } act.call(show.get(0)); //console.dir(changeRecord); }); }); p.find("#preloadjs-advanced-matchlist-loadjs-show").bind("list-load", function(evt, data){ $(this).removeData("actions"); this.innerHTML = null; data['list'].call(this, data); // with 'select' $(this).data("actions", data); }); ["add", "delete", "up", "down"].forEach(function(e){ var show = p.find("#preloadjs-advanced-matchlist-loadjs-show"); p.find("#preloadjs-advanced-matchlist-loadjs-bt-"+e).click(function(){ var acts = show.data("actions"); if(acts == undefined){ alert("sorry no selected item or not support"); return; } var act = acts[e]; //if(act == undefined){ alert("sorry not support"); return; } act.call(show.get(0), acts); //console.dir(changeRecord); }); }); p.bind("ui-setup", function(event, data){ //data from triggerHandler hostDump = DataService.dump.setting.hostAll(data); // load data to share changeRecord = { whiteWildcardInfo: {}, whitePathnameInfo: {} }; p.find("label>span>b").text(data); p.find("#preloadjs-advanced-matchlist-active").get(0).checked = hostDump.hostMeta['active']==true?true:false; p.find("#preloadjs-advanced-matchlist-class").each(function(){ this.selectedIndex = -1; //必须放到显示时才有效 }).val(2).trigger("change"); ui_advanced.find("#preloadjs-advanced-bt-apply").click(function(){ hostDump.hostMeta['xq-seq'] = [4,2,1]; DataService.dao.setting.hostMeta.update(data, hostDump.hostMeta); var v2i = function(currentValue, index, array){ return index; }; hostDump.blackWildcardMeta['match-seq'] = hostDump.blackWildcardMeta['wildcard-list'].map(v2i); DataService.dao.setting.blackWildcardMeta.update(data, hostDump.blackWildcardMeta); Object.keys(hostDump.whitePathnames).forEach(function(p){ hostDump.whitePathnames[p]=true }); DataService.dao.setting.whitePathnames.update(data, hostDump.whitePathnames); for(var p in changeRecord.whitePathnameInfo){ ({ "update": function(){ hostDump.whitePathnameInfo[p]['xq-seq'] = hostDump.whitePathnameInfo[p]['js-list'].map(v2i); DataService.dao.setting.whitePathnameInfo.update(data, p, hostDump.whitePathnameInfo[p]); }, "delete": function(){ DataService.dao.setting.whitePathnameInfo.remove(data, p); } })[changeRecord.whitePathnameInfo[p]](); } hostDump.whiteWildcardMeta['match-seq'] = hostDump.whiteWildcardMeta['wildcard-list'].map(v2i); DataService.dao.setting.whiteWildcardMeta.update(data, hostDump.whiteWildcardMeta); for(var w in changeRecord.whiteWildcardInfo){ ({ "update":function(){ hostDump.whiteWildcardInfo[w]['xq-seq'] = hostDump.whiteWildcardInfo[w]['js-list'].map(v2i); DataService.dao.setting.whiteWildcardInfo.update(data, w, hostDump.whiteWildcardInfo[w]); }, "delete":function(){ DataService.dao.setting.whiteWildcardInfo.remove(data, w); } })[changeRecord.whiteWildcardInfo[w]](); } alert("已应用保存数据"); }); p.slideDown("slow"); $("#preloadjs-advanced-bt-return").show("slow").click(function(){ $(this).unbind("click"); p.triggerHandler("ui-unsetup"); $("#preloadjs-advanced-hostlist").triggerHandler("ui-setup"); }); $("#preloadjs-advanced-bt-apply").show("slow"); }).bind("ui-unsetup", function(){ $("#preloadjs-advanced-bt-apply").unbind("click").hide("slow"); $("#preloadjs-advanced-bt-return").hide("slow"); p.slideUp("slow"); }); return false; }); $(["
    ", "

    资源列表

    ", "", "", "
    ", "", "", "
    "].join("")).appendTo(ui_advanced).each(function(){ var p = $(this); var resourceSets = null, resourceTxt = null; var changeRecord = null; p.find("#preloadjs-advanced-resource-list").bind("change", function(evt, data){ if(this.selectedIndex===-1){ return;} // debug var rid = this.selectedOptions[0].text; for(; !(rid in resourceTxt); ){ resourceTxt[rid] = DataService.model.resource.scriptTxt(rid); //cache } $("#preloadjs-advanced-resource-jscontent").val(resourceTxt[rid]).trigger("js-edit", rid); }); p.find("#preloadjs-advanced-resource-bt-add").click(function(){ var input = prompt("请输入唯一的资源名(默认以日期时间命名):", null); if(input==null){ return; } input = input.trim(); if(input===""){ input = new Date().toLocaleString("ja-JP", {hour12:false}); } if(input in resourceSets){ alert("已存在的资源名"); return; } resourceSets[input] = "default"; resourceTxt[input] = ""; $("#preloadjs-advanced-resource-list").get(0).add(new Option(input, input)); changeRecord[input] = "update"; }); p.find("#preloadjs-advanced-resource-bt-delete").click(function(){ var list = $("#preloadjs-advanced-resource-list").get(0); if(list.selectedIndex===-1){ alert("没有选中项"); return; } var rid = list.selectedOptions[0].text; if(confirm("确认删除项:\n"+rid)!==true){ return; } $("#preloadjs-advanced-resource-jscontent").removeData("sync-to").attr("disabled", true).val(""); delete resourceSets[rid]; delete resourceTxt[rid]; list.selectedOptions[0].outerHTML = ""; changeRecord[rid] = "delete"; }); p.find("#preloadjs-advanced-resource-jscontent").bind("js-edit", function(evt, data){ $(this).removeData("sync-to").data("sync-to", data).attr("disabled", false); }).bind("blur", function(){ var rid = $(this).data("sync-to"); if(rid==undefined){ return; } if(this.value!==resourceTxt[rid] && confirm("内容已被修改,点击[取消/否]恢复。")===true){ resourceTxt[rid] = this.value; changeRecord[rid] = "update"; }else{ this.value = resourceTxt[rid]; //recover } }); p.bind("ui-setup", function(){ resourceSets = DataService.model.resource.sets(); resourceTxt = {}; changeRecord = {}; $("#preloadjs-advanced-resource-jscontent").attr("disabled", true).val(""); //clear $("#preloadjs-advanced-resource-list").empty().each(function(){ for(var r in resourceSets){ this.add(new Option(r, r)); } }); $("#preloadjs-advanced-bt-apply").click(function(){ //console.log("%d %o %o %o", Date.now(), resourceSets, resourceTxt, changeRecord); DataService.dao.resource.sets.update(resourceSets); for(var rid in changeRecord){ ({ "update": function(){ //alert(CryptoJS.MD5("Message").toString().length); DataService.dao.resource.scriptTxt.update(rid, resourceTxt[rid]); }, "delete": function(){ DataService.dao.resource.scriptTxt.remove(rid); } })[changeRecord[rid]](); } alert("已应用保存数据"); }); p.slideDown("slow"); $("#preloadjs-advanced-bt-return").show("slow").click(function(){ $(this).unbind("click"); p.triggerHandler("ui-unsetup"); $("#preloadjs-advanced-hostlist").triggerHandler("ui-setup"); }); $("#preloadjs-advanced-bt-apply").show("slow"); }).bind("ui-unsetup", function(){ $("#preloadjs-advanced-bt-apply").unbind("click").hide("slow"); $("#preloadjs-advanced-bt-return").hide("slow"); p.slideUp("slow"); }); return false; }); $(["
    ", "", "", "", "", "
    "].join("")).appendTo(ui_advanced).each(function(){ var p = $(this); p.find("#preloadjs-advanced-bt-resource").click(function(){ $("#preloadjs-advanced-hostlist").triggerHandler("ui-unsetup"); $("#preloadjs-advanced-resource").triggerHandler("ui-setup"); }); p.find("#preloadjs-advanced-bt-close").click(function(){ if(!confirm("确定关闭?关闭意味着之前没有应用(保存)的数据将会丢失。")){ return; } $.unblockUI(); }); return false; //stop the loop }); ui_advanced.find("#preloadjs-advanced-hostlist").trigger("ui-setup"); // init $.blockUI({ message: ui_advanced, css: { top: '30px', left: '55%' } }); }; var MenuHelper = function(){ var regIds = {}; var reregSeq = []; this.register = function(name, fn, accessKey){ this.unregister(name); regIds[name] = [GM_registerMenuCommand(name, fn, accessKey), fn, accessKey]; reregSeq.push(name); }; this.unregister = function(name){ if(name in regIds){ GM_unregisterMenuCommand(regIds[name][0]); reregSeq.splice(reregSeq.indexOf(name), 1); delete regIds[name]; } }; this.unregisterAll = function(){ reregSeq = []; for(var name in regIds){ GM_unregisterMenuCommand(regIds[name][0]); delete regIds[name]; } }; this.reregisterAll = function(){ reregSeq.forEach(function(name){ GM_unregisterMenuCommand(regIds[name][0]); var fn = regIds[name][1], accessKey = regIds[name][2]; regIds[name][0] = GM_registerMenuCommand(name, fn, accessKey);//update id }); }; }; var menus = new MenuHelper(); menus.register("[快捷]"+GM_info.script.name, function(){ menu1(); menus.reregisterAll(); }, 'j'); menus.register("[高级]"+GM_info.script.name, function(){ menu2(); menus.reregisterAll(); }, 's'); if(location.href==='https://www.baidu.com/duty/'){ //TEST ONLY //menu1(); menu2(); } }) }; })(window, jQuery, jQuery.noConflict(true));