electron/lib/browser/api/menu-item.ts

100 lines
3.4 KiB
TypeScript
Raw Normal View History

import * as roles from '@electron/internal/browser/api/menu-item-roles';
2023-02-13 21:39:18 +00:00
import { Menu, BrowserWindow, WebContents, KeyboardEvent } from 'electron/main';
2020-03-20 20:28:31 +00:00
let nextCommandId = 0;
2016-01-12 02:40:23 +00:00
2020-07-06 20:24:54 +00:00
const MenuItem = function (this: any, options: any) {
// Preserve extra fields specified by user
for (const key in options) {
2020-03-20 20:28:31 +00:00
if (!(key in this)) this[key] = options[key];
}
2017-12-31 18:23:32 +00:00
if (typeof this.role === 'string' || this.role instanceof String) {
2020-03-20 20:28:31 +00:00
this.role = this.role.toLowerCase();
2017-12-31 18:23:32 +00:00
}
2020-03-20 20:28:31 +00:00
this.submenu = this.submenu || roles.getDefaultSubmenu(this.role);
2016-06-21 22:41:37 +00:00
if (this.submenu != null && this.submenu.constructor !== Menu) {
this.submenu = Menu.buildFromTemplate(this.submenu);
2016-06-21 22:41:37 +00:00
}
if (this.type == null && this.submenu != null) {
2020-03-20 20:28:31 +00:00
this.type = 'submenu';
2016-06-21 22:41:37 +00:00
}
if (this.type === 'submenu' && (this.submenu == null || this.submenu.constructor !== Menu)) {
2020-03-20 20:28:31 +00:00
throw new Error('Invalid submenu');
2016-01-12 02:40:23 +00:00
}
this.overrideReadOnlyProperty('type', roles.getDefaultType(this.role));
2020-03-20 20:28:31 +00:00
this.overrideReadOnlyProperty('role');
this.overrideReadOnlyProperty('accelerator');
this.overrideReadOnlyProperty('icon');
this.overrideReadOnlyProperty('submenu');
2020-03-20 20:28:31 +00:00
this.overrideProperty('label', roles.getDefaultLabel(this.role));
this.overrideProperty('sublabel', '');
this.overrideProperty('toolTip', '');
this.overrideProperty('enabled', true);
this.overrideProperty('visible', true);
this.overrideProperty('checked', false);
this.overrideProperty('acceleratorWorksWhenHidden', true);
this.overrideProperty('registerAccelerator', roles.shouldRegisterAccelerator(this.role));
2016-06-21 22:41:37 +00:00
if (!MenuItem.types.includes(this.type)) {
2020-03-20 20:28:31 +00:00
throw new Error(`Unknown menu item type: ${this.type}`);
}
2016-01-12 02:40:23 +00:00
2020-03-20 20:28:31 +00:00
this.overrideReadOnlyProperty('commandId', ++nextCommandId);
2016-06-21 22:41:37 +00:00
Object.defineProperty(this, 'userAccelerator', {
get: () => {
if (process.platform !== 'darwin') return null;
if (!this.menu) return null;
return this.menu._getUserAcceleratorAt(this.commandId);
},
enumerable: true
});
2020-03-20 20:28:31 +00:00
const click = options.click;
2023-02-13 21:39:18 +00:00
this.click = (event: KeyboardEvent, focusedWindow: BrowserWindow, focusedWebContents: WebContents) => {
2016-06-21 22:41:37 +00:00
// Manually flip the checked flags when clicked.
if (!roles.shouldOverrideCheckStatus(this.role) &&
(this.type === 'checkbox' || this.type === 'radio')) {
2020-03-20 20:28:31 +00:00
this.checked = !this.checked;
2016-01-12 02:40:23 +00:00
}
2016-06-21 22:41:37 +00:00
if (!roles.execute(this.role, focusedWindow, focusedWebContents)) {
2016-06-22 20:48:26 +00:00
if (typeof click === 'function') {
2020-03-20 20:28:31 +00:00
click(this, focusedWindow, event);
2016-06-22 20:48:26 +00:00
} else if (typeof this.selector === 'string' && process.platform === 'darwin') {
2020-03-20 20:28:31 +00:00
Menu.sendActionToFirstResponder(this.selector);
2016-06-21 22:41:37 +00:00
}
2016-01-12 02:40:23 +00:00
}
2020-03-20 20:28:31 +00:00
};
};
2016-06-21 22:41:37 +00:00
2020-03-20 20:28:31 +00:00
MenuItem.types = ['normal', 'separator', 'submenu', 'checkbox', 'radio'];
2016-01-12 02:40:23 +00:00
MenuItem.prototype.getDefaultRoleAccelerator = function () {
2020-03-20 20:28:31 +00:00
return roles.getDefaultAccelerator(this.role);
};
MenuItem.prototype.getCheckStatus = function () {
if (!roles.shouldOverrideCheckStatus(this.role)) return this.checked;
return roles.getCheckStatus(this.role);
};
2020-07-06 20:24:54 +00:00
MenuItem.prototype.overrideProperty = function (name: string, defaultValue: any = null) {
2016-06-21 22:41:37 +00:00
if (this[name] == null) {
2020-03-20 20:28:31 +00:00
this[name] = defaultValue;
2016-06-21 22:41:37 +00:00
}
2020-03-20 20:28:31 +00:00
};
2016-06-21 22:41:37 +00:00
2020-07-06 20:24:54 +00:00
MenuItem.prototype.overrideReadOnlyProperty = function (name: string, defaultValue: any) {
2020-03-20 20:28:31 +00:00
this.overrideProperty(name, defaultValue);
2016-06-21 22:41:37 +00:00
Object.defineProperty(this, name, {
enumerable: true,
writable: false,
value: this[name]
2020-03-20 20:28:31 +00:00
});
};
2016-01-12 02:40:23 +00:00
2020-03-20 20:28:31 +00:00
module.exports = MenuItem;