// ==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();
*/
Donate for the site OpenUserJS
Are you sure you want to go to an external site to donate a monetary value?
WARNING: Some countries laws may supersede the payment processors policy such as the GDPR and PayPal. While it is highly appreciated to donate, please check with your countries privacy and identity laws regarding privacy of information first. Use at your utmost discretion.