NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @namespace https://openuserjs.org/users/wishingking // @exclude * // ==UserLibrary== // @name GM_createMenu // @description GM_createMenu, A library, support batch add, for you to solve batch add and switch menu trouble. // @copyright 2020, wishingking (https://openuserjs.org/users/wishingking) // @license MIT // @version 0.1.10 // ==/UserScript== // ==/UserLibrary== // ==OpenUserJS== // @author wishingking // ==/OpenUserJS== /** * * When you write a plug-in, you suddenly find that you need a switch button or need to batch add menu. What should I do? Call the underlying API to implement? It may not be too much trouble, and after deleting the menu, the new menu will change its position up and down. In short, dig the pit slowly. Well, there is a GM_createMenu library packaged today, which perfectly solves the problem of adding switch menu and batch adding menu. OK, have a good time! * * The following permissions must be granted * //@grant GM_registerMenuCommand * //@grant GM_unregisterMenuCommand * //@grant GM_setValue If you want to remember the menu switch status, you need to turn it on * //@grant GM_getValue If you want to remember the menu switch status, you need to turn it on */ var GM_createMenu = { list : [], //menu lists ids : {}, //menu ids storage : false, isSwitch:function(item){ return item && item.on && item.off; }, //stored menus store : function(data){ GM_setValue("__GM_createMenu_list", data||this.list); }, //get stored menus getStore : function(key){ return GM_getValue(key||"__GM_createMenu_list"); }, mergeList : function(list, store){ if(!store || store.length===0) return list; //array map var storeMap = {}; for(var i in store){ var itemstore = store[i]; if(!itemstore || typeof itemstore !== "object") continue; var itemstorename = itemstore["name"] || (itemstore["on"]["name"] + itemstore["off"]["name"]); storeMap[itemstorename] = itemstore; } //merge array for(var n in list){ var item = list[n]; if(!item || typeof item !== "object") continue; var itemname = item["name"] || (item["on"]["name"] + item["off"]["name"]); var storeitem = storeMap[itemname]; if(this.isSwitch(storeitem)){ item.curr = storeitem.curr; item.uncurr = storeitem.uncurr; item.on.default = storeitem.on.default; item.off.default = storeitem.off.default; list[n] = item; } } return list; }, //create menu,from contains page, menu create : function(option, from){ var _this = this; if(_this.list.length===0) return; from = from || 'page'; if(typeof option !== 'undefined' && typeof option.storage !== 'undefined'){ _this.storage = option.storage; } //delete old menu for(var i in _this.ids){ GM_unregisterMenuCommand(_this.ids[i]); } //merge data var list = _this.list; if(_this.storage){ list = _this.mergeList(list, _this.getStore()); } else { if(GM_setValue) _this.store([]); } //begin create menu list.forEach(function(item, i){ if(!item || typeof item !== "object") return true; var currMenu = _this.isSwitch(item) ? item[item.curr] : item; _this.ids[currMenu.name] = GM_registerMenuCommand(currMenu.name, function(){ //call user callback currMenu.callback(); if(_this.isSwitch(item)){ //Reverse switch item[item.curr].default = false; item[item.uncurr].default = true; var item_curr = item.curr; item.curr=item.uncurr; item.uncurr=item_curr; if(_this.storage){ _this.store(); } _this.create(option, 'menu'); } }, currMenu.accessKey||null); if(item.load && from === 'page') item.load(item.uncurr||null); }); }, //Add menu configuration add:function(conf){ //Compatible array configuration if(Object.prototype.toString.call(conf) === "[object Array]"){ for(var i in conf){ this.add(conf[i]); } return this; } //switch menu if(conf.on && conf.off){ //check configuration if((!conf.on.name||!conf.off.name) && typeof conf === 'object'){ alert("GM_createMenu Item name is need."); return this; } if(!conf.on.callback){ conf.on.callback = function(){}; } if(!conf.off.callback){ conf.off.callback = function(){}; } if(conf.off.default){ conf.curr="off" conf.uncurr="on" conf.on.default=false; conf.off.default=true; } else if(conf.on.default){ conf.curr="on" conf.uncurr="off"; conf.on.default=true; conf.off.default=false; } else{ conf.curr="on" conf.uncurr="off"; conf.on.default=true; conf.off.default=false; } } else { //common menu //check configuration if(!conf.name && typeof conf === 'object'){ alert("GM_createMenu Item name is need."); return this; } } this.list.push(conf); return this; }, }; /** Demoļ¼ GM_createMenu.add([ //switch menu { load : function(menuStatus){ if(menuStatus==="on") alert("loaded"); }, on : { default : true, name : "Open", callback : function(){ alert("I'm Open."); } }, off : { name : "Close", callback : function(){ alert("I'm Close."); } } }, { on : { name : "Edit", accessKey: 'E', callback : function(){ alert("I am editing"); } }, off : { default : true, name : "Exit Edit", accessKey: 'X', callback : function(){ alert("I'm exit."); } } }, //common menu { name : "Common menu 1", callback : function(){ alert("I'm Common menu 1"); } }, { name : "Common menu 2", callback : function(){ alert("I am Common menu 2"); }, load : function(){ alert("loaded common menu2"); } } ]); GM_createMenu.create({storage:true}); Or: GM_createMenu.add({ on : { default : true, name : "Open", callback : function(){ alert("I'm Open."); } }, off : { name : "Close", callback : function(){ alert("I'm Close."); } } }); GM_createMenu.add({ on : { name : "Edit", accessKey: 'E', callback : function(){ alert("I am editing"); } }, off : { default : true, name : "Exit Edit", accessKey: 'X', callback : function(){ alert("I'm exit."); } } }); GM_createMenu.create(); */