custom-electronjs-titlebar
Version:
This is a library for electron.js to allow you to add custom titlebars!
1,121 lines (1,118 loc) • 41.4 kB
JavaScript
"use strict";
/* ---------------------------------------------------------------------------------------------
* Copyright (c) AlexTorresDev. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*-------------------------------------------------------------------------------------------- */
var __createBinding = this && this.__createBinding || (Object.create ? function (o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = {
enumerable: true,
get: function () {
return m[k];
}
};
}
Object.defineProperty(o, k2, desc);
} : function (o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
});
var __setModuleDefault = this && this.__setModuleDefault || (Object.create ? function (o, v) {
Object.defineProperty(o, "default", {
enumerable: true,
value: v
});
} : function (o, v) {
o["default"] = v;
});
var __importStar = this && this.__importStar || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) _get__("__createBinding")(result, mod, k);
_get__("__setModuleDefault")(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.MenuBar = void 0;
const electron_1 = require("electron");
const DOM = _get__("__importStar")(require("../base/common/dom"));
const event_1 = require("../base/common/event");
const lifecycle_1 = require("../base/common/lifecycle");
const platform_1 = require("../base/common/platform");
const keyboardEvent_1 = require("../base/browser/keyboardEvent");
const keyCodes_1 = require("../base/common/keyCodes");
const consts_1 = require("../consts");
const menu_1 = require("./menu");
const async_1 = require("../base/common/async");
const mouseEvent_1 = require("../base/browser/mouseEvent");
const touch_1 = require("../base/browser/touch");
const strings = _get__("__importStar")(require("../base/common/strings"));
const $ = _get__("DOM").$;
var MenubarState;
(function (MenubarState) {
MenubarState[MenubarState["HIDDEN"] = 0] = "HIDDEN";
MenubarState[MenubarState["VISIBLE"] = 1] = "VISIBLE";
MenubarState[MenubarState["FOCUSED"] = 2] = "FOCUSED";
MenubarState[MenubarState["OPEN"] = 3] = "OPEN";
})(_get__("MenubarState") || _assign__("MenubarState", {}));
class MenuBar extends _get__("lifecycle_1").Disposable {
constructor(container, menuIcons, currentOptions, options, closeMenu = () => {}) {
super();
this.container = container;
this.menuIcons = menuIcons;
this.currentOptions = currentOptions;
this.options = options;
this.closeMenu = closeMenu;
// Input-related
this._mnemonicsInUse = false;
this.openedViaKeyboard = false;
this.awaitingAltRelease = false;
this.ignoreNextMouseUp = false;
this.updatePending = false;
this.numMenusShown = 0;
this.overflowLayoutScheduled = undefined;
this.menuStyle = {};
this.container.setAttribute('role', 'menubar');
if (this.isCompact) {
this.container.classList.add('compact');
}
this.menus = [];
this.mnemonics = new Map();
this._focusState = _get__("MenubarState").VISIBLE;
this._onVisibilityChange = this._register(new (_get__("event_1").Emitter)());
this._onFocusStateChange = this._register(new (_get__("event_1").Emitter)());
this.createOverflowMenu();
this.menuUpdater = this._register(new (_get__("async_1").RunOnceScheduler)(() => this.update(), 200));
// this.actionRunner = this.options.actionRunner ?? this._register(new ActionRunner());
this.registerListeners();
this.setUnfocusedState();
}
registerListeners() {
/* this._register(this.actionRunner.onWillRun(() => {
this.setUnfocusedState();
})); */
if (!_get__("platform_1").isMacintosh) {
this._register(_get__("DOM").addDisposableListener(window, _get__("DOM").EventType.RESIZE, () => {
this.blur();
}));
}
this._register(_get__("DOM").ModifierKeyEmitter.getInstance().event(this.onModifierKeyToggled, this));
this._register(_get__("DOM").addDisposableListener(this.container, _get__("DOM").EventType.KEY_DOWN, e => {
const event = new (_get__("keyboardEvent_1").StandardKeyboardEvent)(e);
let eventHandled = true;
const key = !!e.key ? e.key.toLocaleLowerCase() : '';
const tabNav = _get__("platform_1").isMacintosh && !this.isCompact;
if (event.equals(15 /* KeyCode.LeftArrow */) || tabNav && event.equals(2 /* KeyCode.Tab */ | 1024 /* KeyMod.Shift */)) {
this.focusPrevious();
} else if (event.equals(17 /* KeyCode.RightArrow */) || tabNav && event.equals(2 /* KeyCode.Tab */)) {
this.focusNext();
} else if (event.equals(9 /* KeyCode.Escape */) && this.isFocused && !this.isOpen) {
this.setUnfocusedState();
} else if (!this.isOpen && !event.ctrlKey && this.options.enableMnemonics && this.mnemonicsInUse && this.mnemonics.has(key)) {
const menuIndex = this.mnemonics.get(key);
this.onMenuTriggered(menuIndex, false);
} else {
eventHandled = false;
}
// Never allow default tab behavior when not compact
if (!this.isCompact && (event.equals(2 /* KeyCode.Tab */ | 1024 /* KeyMod.Shift */) || event.equals(2 /* KeyCode.Tab */))) {
event.preventDefault();
}
if (eventHandled) {
event.preventDefault();
event.stopPropagation();
}
}));
this._register(_get__("DOM").addDisposableListener(window, _get__("DOM").EventType.MOUSE_DOWN, () => {
// This mouse event is outside the menubar so it counts as a focus out
if (this.isFocused) {
this.setUnfocusedState();
}
}));
this._register(_get__("DOM").addDisposableListener(this.container, _get__("DOM").EventType.FOCUS_IN, e => {
const event = e;
if (event.relatedTarget) {
if (!this.container.contains(event.relatedTarget)) {
this.focusToReturn = event.relatedTarget;
}
}
}));
this._register(_get__("DOM").addDisposableListener(this.container, _get__("DOM").EventType.FOCUS_OUT, e => {
const event = e;
// We are losing focus and there is a target, reset focusToReturn value as not to redirect
if (event.relatedTarget && !this.container.contains(event.relatedTarget)) {
this.focusToReturn = undefined;
this.setUnfocusedState();
}
}));
this._register(_get__("DOM").addDisposableListener(window, _get__("DOM").EventType.KEY_DOWN, e => {
if (!this.options.enableMnemonics || !e.altKey || e.ctrlKey || e.defaultPrevented) {
return;
}
const key = e.key.toLocaleLowerCase();
if (!this.mnemonics.has(key)) {
return;
}
this.mnemonicsInUse = true;
this.updateMnemonicVisibility(true);
const menuIndex = this.mnemonics.get(key);
this.onMenuTriggered(menuIndex, false);
}));
}
push(menu) {
const topLevelMenus = menu.items;
topLevelMenus.forEach(menuBarMenu => {
const menuIndex = this.menus.length;
const cleanMenuLabel = (0, _get__("consts_1").cleanMnemonic)(menuBarMenu.label);
const mnemonicMatches = _get__("consts_1").MENU_MNEMONIC_REGEX.exec(menuBarMenu.label);
// Register mnemonics
if (mnemonicMatches) {
const mnemonic = !!mnemonicMatches[1] ? mnemonicMatches[1] : mnemonicMatches[3];
this.registerMnemonic(this.menus.length, mnemonic);
}
if (this.isCompact) {
this.menus.push({
label: '',
actions: menuBarMenu.submenu
});
} else {
const buttonElement = _get__("$")('.cet-menubar-menu-button', {
role: 'menuitem',
tabindex: -1,
'aria-label': cleanMenuLabel,
'aria-haspopup': true
});
const titleElement = _get__("$")('.cet-menubar-menu-title', {
role: 'none',
'aria-hidden': true
});
buttonElement.appendChild(titleElement);
this.container.insertBefore(buttonElement, this.overflowMenu.buttonElement);
this.updateLabels(titleElement, buttonElement, menuBarMenu.label);
this._register(_get__("DOM").addDisposableListener(buttonElement, _get__("DOM").EventType.KEY_UP, e => {
const event = new (_get__("keyboardEvent_1").StandardKeyboardEvent)(e);
let eventHandled = true;
if ((event.equals(18 /* KeyCode.DownArrow */) || event.equals(3 /* KeyCode.Enter */)) && !this.isOpen) {
this.focusedMenu = {
index: menuIndex
};
this.openedViaKeyboard = true;
this.focusState = _get__("MenubarState").OPEN;
} else {
eventHandled = false;
}
if (eventHandled) {
event.preventDefault();
event.stopPropagation();
}
}));
this._register(_get__("touch_1").Gesture.addTarget(buttonElement));
this._register(_get__("DOM").addDisposableListener(buttonElement, _get__("touch_1").EventType.Tap, e => {
// Ignore this touch if the menu is touched
if (this.isOpen && this.focusedMenu && this.focusedMenu.holder && _get__("DOM").isAncestor(e.initialTarget, this.focusedMenu.holder)) {
return;
}
this.ignoreNextMouseUp = false;
this.onMenuTriggered(menuIndex, true);
e.preventDefault();
e.stopPropagation();
}));
this._register(_get__("DOM").addDisposableListener(buttonElement, _get__("DOM").EventType.MOUSE_DOWN, e => {
// Ignore non-left-click
const mouseEvent = new (_get__("mouseEvent_1").StandardMouseEvent)(e);
if (!mouseEvent.leftButton) {
e.preventDefault();
return;
}
if (!this.isOpen) {
// Open the menu with mouse down and ignore the following mouse up event
this.ignoreNextMouseUp = true;
this.onMenuTriggered(menuIndex, true);
} else {
this.ignoreNextMouseUp = false;
}
e.preventDefault();
e.stopPropagation();
}));
this._register(_get__("DOM").addDisposableListener(buttonElement, _get__("DOM").EventType.MOUSE_UP, e => {
if (e.defaultPrevented) {
return;
}
if (!this.ignoreNextMouseUp) {
if (this.isFocused) {
this.onMenuTriggered(menuIndex, true);
}
} else {
this.ignoreNextMouseUp = false;
}
}));
this._register(_get__("DOM").addDisposableListener(buttonElement, _get__("DOM").EventType.MOUSE_ENTER, () => {
if (this.isOpen && !this.isCurrentMenu(menuIndex)) {
buttonElement.focus();
this.cleanupMenu();
this.showMenu(menuIndex, false);
} else if (this.isFocused && !this.isOpen) {
this.focusedMenu = {
index: menuIndex
};
buttonElement.focus();
}
}));
this.menus.push({
label: menuBarMenu.label,
actions: menuBarMenu.submenu,
buttonElement,
titleElement
});
}
});
}
createOverflowMenu() {
const label = this.isCompact ? 'Compact' : 'More';
const buttonElement = _get__("$")('.cet-menubar-menu-button', {
role: 'menuitem',
tabindex: this.isCompact ? 0 : -1,
'aria-label': label,
'aria-haspopup': true
});
const titleElement = _get__("$")('.cet-menubar-menu-title.cet-toggle-more', {
role: 'none',
'aria-hidden': true
});
buttonElement.appendChild(titleElement);
this.container.appendChild(buttonElement);
buttonElement.style.visibility = 'hidden';
this._register(_get__("DOM").addDisposableListener(buttonElement, _get__("DOM").EventType.KEY_UP, e => {
const event = new (_get__("keyboardEvent_1").StandardKeyboardEvent)(e);
let eventHandled = true;
const triggerKeys = [3 /* KeyCode.Enter */];
if (!this.isCompact) {
triggerKeys.push(18 /* KeyCode.DownArrow */);
} else {
triggerKeys.push(10 /* KeyCode.Space */);
if (this.options.compactMode === _get__("menu_1").Direction.Right) {
triggerKeys.push(17 /* KeyCode.RightArrow */);
} else if (this.options.compactMode === _get__("menu_1").Direction.Left) {
triggerKeys.push(15 /* KeyCode.LeftArrow */);
}
}
if (triggerKeys.some(k => event.equals(k)) && !this.isOpen) {
this.focusedMenu = {
index: _get__("MenuBar").OVERFLOW_INDEX
};
this.openedViaKeyboard = true;
this.focusState = _get__("MenubarState").OPEN;
} else {
eventHandled = false;
}
if (eventHandled) {
event.preventDefault();
event.stopPropagation();
}
}));
this._register(_get__("touch_1").Gesture.addTarget(buttonElement));
this._register(_get__("DOM").addDisposableListener(buttonElement, _get__("touch_1").EventType.Tap, e => {
// Ignore this touch if the menu is touched
if (this.isOpen && this.focusedMenu && this.focusedMenu.holder && _get__("DOM").isAncestor(e.initialTarget, this.focusedMenu.holder)) {
return;
}
this.ignoreNextMouseUp = false;
this.onMenuTriggered(_get__("MenuBar").OVERFLOW_INDEX, true);
e.preventDefault();
e.stopPropagation();
}));
this._register(_get__("DOM").addDisposableListener(buttonElement, _get__("DOM").EventType.MOUSE_DOWN, e => {
// Ignore non-left-click
const mouseEvent = new (_get__("mouseEvent_1").StandardMouseEvent)(e);
if (!mouseEvent.leftButton) {
e.preventDefault();
return;
}
if (!this.isOpen) {
// Open the menu with mouse down and ignore the following mouse up event
this.ignoreNextMouseUp = true;
this.onMenuTriggered(_get__("MenuBar").OVERFLOW_INDEX, true);
} else {
this.ignoreNextMouseUp = false;
}
e.preventDefault();
e.stopPropagation();
}));
this._register(_get__("DOM").addDisposableListener(buttonElement, _get__("DOM").EventType.MOUSE_UP, e => {
if (e.defaultPrevented) {
return;
}
if (!this.ignoreNextMouseUp) {
if (this.isFocused) {
this.onMenuTriggered(_get__("MenuBar").OVERFLOW_INDEX, true);
}
} else {
this.ignoreNextMouseUp = false;
}
}));
this._register(_get__("DOM").addDisposableListener(buttonElement, _get__("DOM").EventType.MOUSE_ENTER, () => {
if (this.isOpen && !this.isCurrentMenu(_get__("MenuBar").OVERFLOW_INDEX)) {
this.overflowMenu.buttonElement.focus();
this.cleanupMenu();
this.showMenu(_get__("MenuBar").OVERFLOW_INDEX, false);
} else if (this.isFocused && !this.isOpen) {
this.focusedMenu = {
index: _get__("MenuBar").OVERFLOW_INDEX
};
buttonElement.focus();
}
}));
this.overflowMenu = {
buttonElement,
titleElement,
label: 'More'
};
}
setStyles(style) {
this.menuStyle = style;
}
updateMenu(menu) {
const menuToUpdate = this.menus.filter(menuBarMenu => menuBarMenu.label === menu.label);
if (menuToUpdate && menuToUpdate.length) {
// menuToUpdate[0].actions = menu.actions;
}
}
dispose() {
super.dispose();
this.menus.forEach(menuBarMenu => {
menuBarMenu.titleElement?.remove();
menuBarMenu.buttonElement?.remove();
});
this.overflowMenu.titleElement.remove();
this.overflowMenu.buttonElement.remove();
(0, _get__("lifecycle_1").dispose)(this.overflowLayoutScheduled);
this.overflowLayoutScheduled = undefined;
}
blur() {
this.setUnfocusedState();
}
getWidth() {
if (!this.isCompact && this.menus) {
const left = this.menus[0].buttonElement.getBoundingClientRect().left;
const right = this.hasOverflow ? this.overflowMenu.buttonElement.getBoundingClientRect().right : this.menus[this.menus.length - 1].buttonElement.getBoundingClientRect().right;
return right - left;
}
return 0;
}
getHeight() {
return this.container.clientHeight;
}
toggleFocus() {
if (!this.isFocused && this.options.visibility !== 'hidden') {
this.mnemonicsInUse = true;
this.focusedMenu = {
index: this.numMenusShown > 0 ? 0 : _get__("MenuBar").OVERFLOW_INDEX
};
this.focusState = _get__("MenubarState").FOCUSED;
} else if (!this.isOpen) {
this.setUnfocusedState();
}
}
updateOverflowAction() {
if (!this.menus || !this.menus.length) {
return;
}
const overflowMenuOnlyClass = 'overflow-menu-only';
// Remove overflow only restriction to allow the most space
this.container.classList.toggle(overflowMenuOnlyClass, false);
const sizeAvailable = this.container.offsetWidth;
let currentSize = 0;
let full = this.isCompact;
const prevNumMenusShown = this.numMenusShown;
this.numMenusShown = 0;
const showableMenus = this.menus.filter(menu => menu.buttonElement !== undefined && menu.titleElement !== undefined);
for (const menuBarMenu of showableMenus) {
if (!full) {
const size = menuBarMenu.buttonElement.offsetWidth;
if (currentSize + size > sizeAvailable) {
full = true;
} else {
currentSize += size;
this.numMenusShown++;
if (this.numMenusShown > prevNumMenusShown) {
menuBarMenu.buttonElement.style.visibility = 'visible';
}
}
}
if (full) {
menuBarMenu.buttonElement.style.visibility = 'hidden';
}
}
// If below minimium menu threshold, show the overflow menu only as hamburger menu
if (this.numMenusShown - 1 <= showableMenus.length / 2) {
for (const menuBarMenu of showableMenus) {
menuBarMenu.buttonElement.style.visibility = 'hidden';
}
full = true;
this.numMenusShown = 0;
currentSize = 0;
}
// Overflow
if (this.isCompact) {
// this.overflowMenu.actions = [];
for (let idx = this.numMenusShown; idx < this.menus.length; idx++) {
// this.overflowMenu.actions.push(new SubmenuAction(`menubar.submenu.${this.menus[idx].label}`, this.menus[idx].label, this.menus[idx].actions || []));
}
/* const compactMenuActions = this.options.getCompactMenuActions?.();
if (compactMenuActions && compactMenuActions.length) {
//this.overflowMenu.actions.push(new Separator());
this.overflowMenu.actions.push(...compactMenuActions);
} */
this.overflowMenu.buttonElement.style.visibility = 'visible';
} else if (full) {
// Can't fit the more button, need to remove more menus
while (currentSize + this.overflowMenu.buttonElement.offsetWidth > sizeAvailable && this.numMenusShown > 0) {
this.numMenusShown--;
const size = showableMenus[this.numMenusShown].buttonElement.offsetWidth;
showableMenus[this.numMenusShown].buttonElement.style.visibility = 'hidden';
currentSize -= size;
}
// this.overflowMenu.actions = [];
for (let idx = this.numMenusShown; idx < showableMenus.length; idx++) {
// this.overflowMenu.actions.push(new SubmenuAction(`menubar.submenu.${showableMenus[idx].label}`, showableMenus[idx].label, showableMenus[idx].actions || []));
}
if (this.overflowMenu.buttonElement.nextElementSibling !== showableMenus[this.numMenusShown].buttonElement) {
this.overflowMenu.buttonElement.remove();
this.container.insertBefore(this.overflowMenu.buttonElement, showableMenus[this.numMenusShown].buttonElement);
}
this.overflowMenu.buttonElement.style.visibility = 'visible';
} else {
this.overflowMenu.buttonElement.remove();
this.container.appendChild(this.overflowMenu.buttonElement);
this.overflowMenu.buttonElement.style.visibility = 'hidden';
}
// If we are only showing the overflow, add this class to avoid taking up space
this.container.classList.toggle(overflowMenuOnlyClass, this.numMenusShown === 0);
}
updateLabels(titleElement, buttonElement, label) {
const cleanMenuLabel = (0, _get__("consts_1").cleanMnemonic)(label);
// Update the button label to reflect mnemonics
if (this.options.enableMnemonics) {
const cleanLabel = _get__("strings").escape(label);
// This is global so reset it
_get__("consts_1").MENU_ESCAPED_MNEMONIC_REGEX.lastIndex = 0;
let escMatch = _get__("consts_1").MENU_ESCAPED_MNEMONIC_REGEX.exec(cleanLabel);
// We can't use negative lookbehind so we match our negative and skip
while (escMatch && escMatch[1]) {
escMatch = _get__("consts_1").MENU_ESCAPED_MNEMONIC_REGEX.exec(cleanLabel);
}
const replaceDoubleEscapes = str => str.replace(/&&/g, '&');
if (escMatch) {
titleElement.innerText = '';
titleElement.append(_get__("strings").ltrim(replaceDoubleEscapes(cleanLabel.substring(0, escMatch.index)), ' '), _get__("$")('mnemonic', {
'aria-hidden': 'true'
}, escMatch[3]), _get__("strings").rtrim(replaceDoubleEscapes(cleanLabel.substring(escMatch.index + escMatch[0].length)), ' '));
} else {
titleElement.innerText = replaceDoubleEscapes(cleanLabel).trim();
}
} else {
titleElement.innerText = cleanMenuLabel.replace(/&&/g, '&');
}
const mnemonicMatches = _get__("consts_1").MENU_MNEMONIC_REGEX.exec(label);
// Register mnemonics
if (mnemonicMatches) {
const mnemonic = !!mnemonicMatches[1] ? mnemonicMatches[1] : mnemonicMatches[3];
if (this.options.enableMnemonics) {
buttonElement.setAttribute('aria-keyshortcuts', 'Alt+' + mnemonic.toLocaleLowerCase());
} else {
buttonElement.removeAttribute('aria-keyshortcuts');
}
}
}
update(options) {
if (options) {
this.options = options;
}
// Don't update while using the menu
if (this.isFocused) {
this.updatePending = true;
return;
}
this.menus.forEach(menuBarMenu => {
if (!menuBarMenu.buttonElement || !menuBarMenu.titleElement) {
return;
}
this.updateLabels(menuBarMenu.titleElement, menuBarMenu.buttonElement, menuBarMenu.label);
});
if (!this.overflowLayoutScheduled) {
this.overflowLayoutScheduled = _get__("DOM").scheduleAtNextAnimationFrame(() => {
this.updateOverflowAction();
this.overflowLayoutScheduled = undefined;
});
}
this.setUnfocusedState();
}
registerMnemonic(menuIndex, mnemonic) {
this.mnemonics.set(mnemonic.toLocaleLowerCase(), menuIndex);
}
hideMenubar() {
if (this.container.style.display !== 'none') {
this.container.style.display = 'none';
this._onVisibilityChange.fire(false);
}
}
showMenubar() {
if (this.container.style.display !== 'flex') {
this.container.style.display = 'flex';
this._onVisibilityChange.fire(true);
this.updateOverflowAction();
}
}
get focusState() {
return this._focusState;
}
set focusState(value) {
if (this._focusState >= _get__("MenubarState").FOCUSED && value < _get__("MenubarState").FOCUSED) {
// Losing focus, update the menu if needed
if (this.updatePending) {
this.menuUpdater.schedule();
this.updatePending = false;
}
}
if (value === this._focusState) {
return;
}
const isVisible = this.isVisible;
const isOpen = this.isOpen;
const isFocused = this.isFocused;
this._focusState = value;
switch (value) {
case _get__("MenubarState").HIDDEN:
if (isVisible) {
this.hideMenubar();
}
if (isOpen) {
this.cleanupMenu();
}
if (isFocused) {
this.focusedMenu = undefined;
if (this.focusToReturn) {
this.focusToReturn.focus();
this.focusToReturn = undefined;
}
}
break;
case _get__("MenubarState").VISIBLE:
if (!isVisible) {
this.showMenubar();
}
if (isOpen) {
this.cleanupMenu();
}
if (isFocused) {
if (this.focusedMenu) {
if (this.focusedMenu.index === _get__("MenuBar").OVERFLOW_INDEX) {
this.overflowMenu.buttonElement.blur();
} else {
this.menus[this.focusedMenu.index].buttonElement?.blur();
}
}
this.focusedMenu = undefined;
if (this.focusToReturn) {
this.focusToReturn.focus();
this.focusToReturn = undefined;
}
}
break;
case _get__("MenubarState").FOCUSED:
if (!isVisible) {
this.showMenubar();
}
if (isOpen) {
this.cleanupMenu();
}
if (this.focusedMenu) {
if (this.focusedMenu.index === _get__("MenuBar").OVERFLOW_INDEX) {
this.overflowMenu.buttonElement.focus();
} else {
this.menus[this.focusedMenu.index].buttonElement?.focus();
}
}
break;
case _get__("MenubarState").OPEN:
if (!isVisible) {
this.showMenubar();
}
if (this.focusedMenu) {
this.showMenu(this.focusedMenu.index, this.openedViaKeyboard);
}
break;
}
this._focusState = value;
this._onFocusStateChange.fire(this.focusState >= _get__("MenubarState").FOCUSED);
}
get isVisible() {
return this.focusState >= _get__("MenubarState").VISIBLE;
}
get isFocused() {
return this.focusState >= _get__("MenubarState").FOCUSED;
}
get isOpen() {
return this.focusState >= _get__("MenubarState").OPEN;
}
get hasOverflow() {
return this.isCompact || this.numMenusShown < this.menus.length;
}
get isCompact() {
return this.options.compactMode !== undefined;
}
setUnfocusedState() {
if (this.options.visibility === 'toggle' || this.options.visibility === 'hidden') {
this.focusState = _get__("MenubarState").HIDDEN;
} else if (this.options.visibility === 'classic') {
this.focusState = _get__("MenubarState").HIDDEN;
} else {
this.focusState = _get__("MenubarState").VISIBLE;
}
this.ignoreNextMouseUp = false;
this.mnemonicsInUse = false;
this.updateMnemonicVisibility(false);
}
focusPrevious() {
if (!this.focusedMenu || this.numMenusShown === 0) {
return;
}
let newFocusedIndex = (this.focusedMenu.index - 1 + this.numMenusShown) % this.numMenusShown;
if (this.focusedMenu.index === _get__("MenuBar").OVERFLOW_INDEX) {
newFocusedIndex = this.numMenusShown - 1;
} else if (this.focusedMenu.index === 0 && this.hasOverflow) {
newFocusedIndex = _get__("MenuBar").OVERFLOW_INDEX;
}
if (newFocusedIndex === this.focusedMenu.index) {
return;
}
if (this.isOpen) {
this.cleanupMenu();
this.showMenu(newFocusedIndex);
} else if (this.isFocused) {
this.focusedMenu.index = newFocusedIndex;
if (newFocusedIndex === _get__("MenuBar").OVERFLOW_INDEX) {
this.overflowMenu.buttonElement.focus();
} else {
this.menus[newFocusedIndex].buttonElement?.focus();
}
}
}
focusNext() {
if (!this.focusedMenu || this.numMenusShown === 0) {
return;
}
let newFocusedIndex = (this.focusedMenu.index + 1) % this.numMenusShown;
if (this.focusedMenu.index === _get__("MenuBar").OVERFLOW_INDEX) {
newFocusedIndex = 0;
} else if (this.focusedMenu.index === this.numMenusShown - 1) {
newFocusedIndex = _get__("MenuBar").OVERFLOW_INDEX;
}
if (newFocusedIndex === this.focusedMenu.index) {
return;
}
if (this.isOpen) {
this.cleanupMenu();
this.showMenu(newFocusedIndex);
} else if (this.isFocused) {
this.focusedMenu.index = newFocusedIndex;
if (newFocusedIndex === _get__("MenuBar").OVERFLOW_INDEX) {
this.overflowMenu.buttonElement.focus();
} else {
this.menus[newFocusedIndex].buttonElement?.focus();
}
}
}
updateMnemonicVisibility(visible) {
if (this.menus) {
this.menus.forEach(menuBarMenu => {
if (menuBarMenu.titleElement && menuBarMenu.titleElement.children.length) {
const child = menuBarMenu.titleElement.children.item(0);
if (child) {
child.style.textDecoration = this.options.alwaysOnMnemonics || visible ? 'underline' : '';
}
}
});
}
}
get mnemonicsInUse() {
return this._mnemonicsInUse;
}
set mnemonicsInUse(value) {
this._mnemonicsInUse = value;
}
get shouldAltKeyFocus() {
if (_get__("platform_1").isMacintosh) {
return false;
}
if (!this.options.disableAltFocus) {
return true;
}
if (this.options.visibility === 'toggle') {
return true;
}
return false;
}
get onVisibilityChange() {
return this._onVisibilityChange.event;
}
get onFocusStateChange() {
return this._onFocusStateChange.event;
}
onMenuTriggered(menuIndex, clicked) {
if (!this.menus[menuIndex].actions) {
_get__("electron_1").ipcRenderer.send('menu-event', menuIndex + 1);
return;
}
if (this.isOpen) {
if (this.isCurrentMenu(menuIndex)) {
this.setUnfocusedState();
} else {
this.cleanupMenu();
this.showMenu(menuIndex, this.openedViaKeyboard);
}
} else {
this.focusedMenu = {
index: menuIndex
};
this.openedViaKeyboard = !clicked;
this.focusState = _get__("MenubarState").OPEN;
}
}
onModifierKeyToggled(modifierKeyStatus) {
const allModifiersReleased = !modifierKeyStatus.altKey && !modifierKeyStatus.ctrlKey && !modifierKeyStatus.shiftKey && !modifierKeyStatus.metaKey;
if (this.options.visibility === 'hidden') {
return;
}
// Prevent alt-key default if the menu is not hidden and we use alt to focus
if (modifierKeyStatus.event && this.shouldAltKeyFocus) {
if (_get__("keyCodes_1").ScanCodeUtils.toEnum(modifierKeyStatus.event.code) === 159 /* ScanCode.AltLeft */) {
modifierKeyStatus.event.preventDefault();
}
}
// Alt key pressed while menu is focused. This should return focus away from the menubar
if (this.isFocused && modifierKeyStatus.lastKeyPressed === 'alt' && modifierKeyStatus.altKey) {
this.setUnfocusedState();
this.mnemonicsInUse = false;
this.awaitingAltRelease = true;
}
// Clean alt key press and release
if (allModifiersReleased && modifierKeyStatus.lastKeyPressed === 'alt' && modifierKeyStatus.lastKeyReleased === 'alt') {
if (!this.awaitingAltRelease) {
if (!this.isFocused && this.shouldAltKeyFocus) {
this.mnemonicsInUse = true;
this.focusedMenu = {
index: this.numMenusShown > 0 ? 0 : _get__("MenuBar").OVERFLOW_INDEX
};
this.focusState = _get__("MenubarState").FOCUSED;
} else if (!this.isOpen) {
this.setUnfocusedState();
}
}
}
// Alt key released
if (!modifierKeyStatus.altKey && modifierKeyStatus.lastKeyReleased === 'alt') {
this.awaitingAltRelease = false;
}
if (this.options.enableMnemonics && this.menus && !this.isOpen) {
this.updateMnemonicVisibility(!this.awaitingAltRelease && modifierKeyStatus.altKey || this.mnemonicsInUse);
}
}
isCurrentMenu(menuIndex) {
if (!this.focusedMenu) {
return false;
}
return this.focusedMenu.index === menuIndex;
}
cleanupMenu() {
if (this.focusedMenu) {
// Remove focus from the menus first
if (this.focusedMenu.index === _get__("MenuBar").OVERFLOW_INDEX) {
this.overflowMenu.buttonElement.focus();
} else {
this.menus[this.focusedMenu.index].buttonElement?.focus();
}
if (this.focusedMenu.holder) {
this.focusedMenu.holder.parentElement?.classList.remove('open');
this.focusedMenu.holder.remove();
}
this.focusedMenu.widget?.dispose();
this.focusedMenu = {
index: this.focusedMenu.index
};
}
}
showMenu(menuIndex, selectFirst = true) {
const actualMenuIndex = menuIndex >= this.numMenusShown ? _get__("MenuBar").OVERFLOW_INDEX : menuIndex;
const customMenu = actualMenuIndex === _get__("MenuBar").OVERFLOW_INDEX ? this.overflowMenu : this.menus[actualMenuIndex];
if (!customMenu.actions || !customMenu.buttonElement || !customMenu.titleElement) {
return;
}
const menuHolder = _get__("$")('.cet-menubar-menu-container', {
title: ''
});
customMenu.buttonElement.classList.add('open');
const titleBoundingRect = customMenu.titleElement.getBoundingClientRect();
const titleBoundingRectZoom = _get__("DOM").getDomNodeZoomLevel(customMenu.titleElement);
if (this.options.compactMode === _get__("menu_1").Direction.Right) {
menuHolder.style.top = `${titleBoundingRect.top}px`;
menuHolder.style.left = `${titleBoundingRect.left + this.container.clientWidth}px`;
} else if (this.options.compactMode === _get__("menu_1").Direction.Left) {
menuHolder.style.top = `${titleBoundingRect.top}px`;
menuHolder.style.right = `${this.container.clientWidth}px`;
menuHolder.style.left = 'auto';
} else {
menuHolder.style.top = `${titleBoundingRect.bottom * titleBoundingRectZoom}px`;
menuHolder.style.left = `${titleBoundingRect.left * titleBoundingRectZoom}px`;
}
customMenu.buttonElement.appendChild(menuHolder);
const menuOptions = {
// getKeyBinding: this.options.getKeybinding,
// actionRunner: this.actionRunner,
enableMnemonics: this.options.alwaysOnMnemonics || this.mnemonicsInUse && this.options.enableMnemonics,
ariaLabel: customMenu.buttonElement.getAttribute('aria-label') ?? undefined
// expandDirection: this.isCompact ? this.options.compactMode : Direction.Right,
// useEventAsContext: true
};
const menuWidget = this._register(new (_get__("menu_1").CETMenu)(menuHolder, this.menuIcons, this.currentOptions, menuOptions, this.closeMenu));
menuWidget.createMenu(customMenu.actions?.items ?? []);
menuWidget.applyStyle(this.menuStyle);
this._register(menuWidget.onDidCancel(() => {
this.focusState = _get__("MenubarState").FOCUSED;
}));
if (actualMenuIndex !== menuIndex) {
menuWidget.trigger(menuIndex - this.numMenusShown);
} else {
menuWidget.focus(selectFirst);
}
this.focusedMenu = {
index: actualMenuIndex,
holder: menuHolder,
widget: menuWidget
};
}
}
exports.MenuBar = _get__("MenuBar");
_get__("MenuBar").OVERFLOW_INDEX = -1;
function _getGlobalObject() {
try {
if (!!global) {
return global;
}
} catch (e) {
try {
if (!!window) {
return window;
}
} catch (e) {
return this;
}
}
}
;
var _RewireModuleId__ = null;
function _getRewireModuleId__() {
if (_RewireModuleId__ === null) {
let globalVariable = _getGlobalObject();
if (!globalVariable.__$$GLOBAL_REWIRE_NEXT_MODULE_ID__) {
globalVariable.__$$GLOBAL_REWIRE_NEXT_MODULE_ID__ = 0;
}
_RewireModuleId__ = __$$GLOBAL_REWIRE_NEXT_MODULE_ID__++;
}
return _RewireModuleId__;
}
function _getRewireRegistry__() {
let theGlobalVariable = _getGlobalObject();
if (!theGlobalVariable.__$$GLOBAL_REWIRE_REGISTRY__) {
theGlobalVariable.__$$GLOBAL_REWIRE_REGISTRY__ = Object.create(null);
}
return theGlobalVariable.__$$GLOBAL_REWIRE_REGISTRY__;
}
function _getRewiredData__() {
let moduleId = _getRewireModuleId__();
let registry = _getRewireRegistry__();
let rewireData = registry[moduleId];
if (!rewireData) {
registry[moduleId] = Object.create(null);
rewireData = registry[moduleId];
}
return rewireData;
}
(function registerResetAll() {
let theGlobalVariable = _getGlobalObject();
if (!theGlobalVariable['__rewire_reset_all__']) {
theGlobalVariable['__rewire_reset_all__'] = function () {
theGlobalVariable.__$$GLOBAL_REWIRE_REGISTRY__ = Object.create(null);
};
}
})();
var INTENTIONAL_UNDEFINED = '__INTENTIONAL_UNDEFINED__';
let _RewireAPI__ = {};
(function () {
function addPropertyToAPIObject(name, value) {
Object.defineProperty(_RewireAPI__, name, {
value: value,
enumerable: false,
configurable: true
});
}
addPropertyToAPIObject('__get__', _get__);
addPropertyToAPIObject('__GetDependency__', _get__);
addPropertyToAPIObject('__Rewire__', _set__);
addPropertyToAPIObject('__set__', _set__);
addPropertyToAPIObject('__reset__', _reset__);
addPropertyToAPIObject('__ResetDependency__', _reset__);
addPropertyToAPIObject('__with__', _with__);
})();
function _get__(variableName) {
let rewireData = _getRewiredData__();
if (rewireData[variableName] === undefined) {
return _get_original__(variableName);
} else {
var value = rewireData[variableName];
if (value === INTENTIONAL_UNDEFINED) {
return undefined;
} else {
return value;
}
}
}
function _get_original__(variableName) {
switch (variableName) {
case "__createBinding":
return __createBinding;
case "__setModuleDefault":
return __setModuleDefault;
case "__importStar":
return __importStar;
case "DOM":
return DOM;
case "MenubarState":
return MenubarState;
case "event_1":
return event_1;
case "async_1":
return async_1;
case "platform_1":
return platform_1;
case "keyboardEvent_1":
return keyboardEvent_1;
case "consts_1":
return consts_1;
case "$":
return $;
case "touch_1":
return touch_1;
case "mouseEvent_1":
return mouseEvent_1;
case "menu_1":
return menu_1;
case "MenuBar":
return MenuBar;
case "lifecycle_1":
return lifecycle_1;
case "strings":
return strings;
case "electron_1":
return electron_1;
case "keyCodes_1":
return keyCodes_1;
}
return undefined;
}
function _assign__(variableName, value) {
let rewireData = _getRewiredData__();
if (rewireData[variableName] === undefined) {
return _set_original__(variableName, value);
} else {
return rewireData[variableName] = value;
}
}
function _set_original__(variableName, _value) {
switch (variableName) {
case "MenubarState":
return MenubarState = _value;
}
return undefined;
}
function _update_operation__(operation, variableName, prefix) {
var oldValue = _get__(variableName);
var newValue = operation === '++' ? oldValue + 1 : oldValue - 1;
_assign__(variableName, newValue);
return prefix ? newValue : oldValue;
}
function _set__(variableName, value) {
let rewireData = _getRewiredData__();
if (typeof variableName === 'object') {
Object.keys(variableName).forEach(function (name) {
rewireData[name] = variableName[name];
});
return function () {
Object.keys(variableName).forEach(function (name) {
_reset__(variableName);
});
};
} else {
if (value === undefined) {
rewireData[variableName] = INTENTIONAL_UNDEFINED;
} else {
rewireData[variableName] = value;
}
return function () {
_reset__(variableName);
};
}
}
function _reset__(variableName) {
let rewireData = _getRewiredData__();
delete rewireData[variableName];
if (Object.keys(rewireData).length == 0) {
delete _getRewireRegistry__()[_getRewireModuleId__];
}
;
}
function _with__(object) {
let rewireData = _getRewiredData__();
var rewiredVariableNames = Object.keys(object);
var previousValues = {};
function reset() {
rewiredVariableNames.forEach(function (variableName) {
rewireData[variableName] = previousValues[variableName];
});
}
return function (callback) {
rewiredVariableNames.forEach(function (variableName) {
previousValues[variableName] = rewireData[variableName];
rewireData[variableName] = object[variableName];
});
let result = callback();
if (!!result && typeof result.then == 'function') {
result.then(reset).catch(reset);
} else {
reset();
}
return result;
};
}
let _typeOfOriginalExport = typeof module.exports;
function addNonEnumerableProperty(name, value) {
Object.defineProperty(module.exports, name, {
value: value,
enumerable: false,
configurable: true
});
}
if ((_typeOfOriginalExport === 'object' || _typeOfOriginalExport === 'function') && Object.isExtensible(module.exports)) {
addNonEnumerableProperty('__get__', _get__);
addNonEnumerableProperty('__GetDependency__', _get__);
addNonEnumerableProperty('__Rewire__', _set__);
addNonEnumerableProperty('__set__', _set__);
addNonEnumerableProperty('__reset__', _reset__);
addNonEnumerableProperty('__ResetDependency__', _reset__);
addNonEnumerableProperty('__with__', _with__);
addNonEnumerableProperty('__RewireAPI__', _RewireAPI__);
}