Ability to Toggle Context Menu Items On and Off


(Matthew G. Saroff) #1

Trying to recreate bbCodeXtra functionality, an one of the program’s features is the ability to turn on and off menus, so if, for example, you do not use VBulletin, you could turn that sub-menu off.

Is there a way to set a variable, and then use that variable to determine whether or not the menu is to be shown or not?

Basically, I want to be able to have a setup page like this:

And I want to avoid a potential forest of nested if statements.


(Matthew G. Saroff) #2

Update: According to the docs, I can set the “visible” parameter to false so that the menu will not show:

browser.contextMenus.create({
            parentId: "bbcode",
            id: "Vbulletincode",
            title: browser.i18n.getMessage("bbcodewebex.menu_vbulletin"),
            visible: false,
            contexts: ["all"]
        }, onCreated);

But that gets me the following error:

Error: Type error for parameter createProperties (Unexpected property "visible") for contextMenus.create.

Is there something wrong in this menu statement, or is this a FF bug?


(Martin Giger) #3

visible was introduced in Firefox 63, before that it’s not supported.


(Niklas Gollenstede) #4

In one of my extension, I have this options definition:

const optionsModel = {
	// ...
	menus: {
		title: 'Menus',
		default: true,
		children: {
			unloadOtherTabs: {
				default: 'tab tools_menu',
				restrict: { type: 'string', },
				input: { type: 'menulist', options: [
					{ value: 'tools_menu', label: `only in the Tools menu`, },
					{ value: 'tab tools_menu', label: `also in the Tab context menu`, },
				], prefix: `Show <b>Unload Other Tabs</b>`, },
			},
			unloadAllTabs: {
				default: 'tools_menu',
				restrict: { type: 'string', },
				input: { type: 'menulist', options: [
					{ value: 'tools_menu', label: `only in the Tools menu`, },
					{ value: 'tab tools_menu', label: `also in the Tab context menu`, },
				], prefix: `Show <b>Unload in All Windows</b>`, },
			},
		},
	},
	// ...
};

(It shouldn’t really matter how they are wrapped in getters/update events/UI, the API should be self-explining.)
And use it like this:

const menus = {
	// ...
	unloadOtherTabs: {
		title: 'Unload Other Tabs',
		icons: { 32: 'many.png', },
		contexts: options.menus.children.unloadOtherTabs.value.split(' '),
	},
	unloadAllTabs: {
		title: 'Unload in All Windows',
		contexts: options.menus.children.unloadAllTabs.value.split(' '),
	},
}; Object.keys(menus).forEach(id => (menus[id].id = id));
Object.values(menus).forEach(menu => Menus.create(menu));
options.menus.children.unloadOtherTabs.onChange(updateMenu);
options.menus.children.unloadAllTabs.onChange(updateMenu);
function updateMenu([ value, ], _, { name, }) {
	menus[name].contexts = value.split(' ');
	Menus.update(name, { contexts: value.split(' '), });
}

Works like a charm.
I am not sure though what happens if you set contextx to an empty array. Might just always leave it in the tools menu.


(Matthew G. Saroff) #5

Because visible is not yet supported on the released version (62), I did this:

if (vbulletinon === false){
 console.log("vbulletin off");
 var removing = browser.contextMenus.remove("Vbulletincode");
} 

It’s only 6 menus so 6 if statements are fine.