提交 a8461cf1 编写于 作者: S SteVen Batten

strictPropertyInit

refs #78168
上级 39b3e879
......@@ -113,7 +113,7 @@ export class Menu extends ActionBar {
const actions = this.mnemonics.get(key)!;
if (actions.length === 1) {
if (actions[0] instanceof SubmenuMenuActionViewItem) {
if (actions[0] instanceof SubmenuMenuActionViewItem && actions[0].container) {
this.focusItemByElement(actions[0].container);
}
......@@ -122,7 +122,7 @@ export class Menu extends ActionBar {
if (actions.length > 1) {
const action = actions.shift();
if (action) {
if (action && action.container) {
this.focusItemByElement(action.container);
actions.push(action);
}
......@@ -356,17 +356,17 @@ interface IMenuItemOptions extends IActionViewItemOptions {
class BaseMenuActionViewItem extends BaseActionViewItem {
public container: HTMLElement;
public container: HTMLElement | undefined;
protected options: IMenuItemOptions;
protected item: HTMLElement;
protected item: HTMLElement | undefined;
private runOnceToEnableMouseUp: RunOnceScheduler;
private label: HTMLElement;
private check: HTMLElement;
private mnemonic: string;
private label: HTMLElement | undefined;
private check: HTMLElement | undefined;
private mnemonic: string | undefined;
private cssClass: string;
protected menuStyle: IMenuStyles;
protected menuStyle: IMenuStyles | undefined;
constructor(ctx: any, action: IAction, options: IMenuItemOptions = {}) {
options.isMenu = true;
......@@ -449,13 +449,19 @@ class BaseMenuActionViewItem extends BaseActionViewItem {
focus(): void {
super.focus();
this.item.focus();
if (this.item) {
this.item.focus();
}
this.applyStyle();
}
updatePositionInSet(pos: number, setSize: number): void {
this.item.setAttribute('aria-posinset', `${pos}`);
this.item.setAttribute('aria-setsize', `${setSize}`);
if (this.item) {
this.item.setAttribute('aria-posinset', `${pos}`);
this.item.setAttribute('aria-setsize', `${setSize}`);
}
}
updateLabel(): void {
......@@ -467,7 +473,9 @@ class BaseMenuActionViewItem extends BaseActionViewItem {
label = cleanLabel;
}
this.label.setAttribute('aria-label', cleanLabel.replace(/&&/g, '&'));
if (this.label) {
this.label.setAttribute('aria-label', cleanLabel.replace(/&&/g, '&'));
}
const matches = MENU_MNEMONIC_REGEX.exec(label);
......@@ -488,13 +496,17 @@ class BaseMenuActionViewItem extends BaseActionViewItem {
}
label = label.replace(/&&/g, '&');
this.item.setAttribute('aria-keyshortcuts', (!!matches[1] ? matches[1] : matches[3]).toLocaleLowerCase());
if (this.item) {
this.item.setAttribute('aria-keyshortcuts', (!!matches[1] ? matches[1] : matches[3]).toLocaleLowerCase());
}
} else {
label = label.replace(/&&/g, '&');
}
}
this.label.innerHTML = label.trim();
if (this.label) {
this.label.innerHTML = label.trim();
}
}
}
......@@ -512,23 +524,23 @@ class BaseMenuActionViewItem extends BaseActionViewItem {
}
}
if (title) {
if (title && this.item) {
this.item.title = title;
}
}
updateClass(): void {
if (this.cssClass) {
if (this.cssClass && this.item) {
removeClasses(this.item, this.cssClass);
}
if (this.options.icon) {
if (this.options.icon && this.label) {
this.cssClass = this.getAction().class || '';
addClass(this.label, 'icon');
if (this.cssClass) {
addClasses(this.label, this.cssClass);
}
this.updateEnabled();
} else {
} else if (this.label) {
removeClass(this.label, 'icon');
}
}
......@@ -539,19 +551,27 @@ class BaseMenuActionViewItem extends BaseActionViewItem {
removeClass(this.element, 'disabled');
}
removeClass(this.item, 'disabled');
this.item.tabIndex = 0;
if (this.item) {
removeClass(this.item, 'disabled');
this.item.tabIndex = 0;
}
} else {
if (this.element) {
addClass(this.element, 'disabled');
}
addClass(this.item, 'disabled');
removeTabIndexAndUpdateFocus(this.item);
if (this.item) {
addClass(this.item, 'disabled');
removeTabIndexAndUpdateFocus(this.item);
}
}
}
updateChecked(): void {
if (!this.item) {
return;
}
if (this.getAction().checked) {
addClass(this.item, 'checked');
this.item.setAttribute('role', 'menuitemcheckbox');
......@@ -563,7 +583,7 @@ class BaseMenuActionViewItem extends BaseActionViewItem {
}
}
getMnemonic(): string {
getMnemonic(): string | undefined {
return this.mnemonic;
}
......@@ -577,10 +597,18 @@ class BaseMenuActionViewItem extends BaseActionViewItem {
const bgColor = isSelected && this.menuStyle.selectionBackgroundColor ? this.menuStyle.selectionBackgroundColor : this.menuStyle.backgroundColor;
const border = isSelected && this.menuStyle.selectionBorderColor ? `thin solid ${this.menuStyle.selectionBorderColor}` : '';
this.item.style.color = fgColor ? `${fgColor}` : null;
this.check.style.backgroundColor = fgColor ? `${fgColor}` : '';
this.item.style.backgroundColor = bgColor ? `${bgColor}` : '';
this.container.style.border = border;
if (this.item) {
this.item.style.color = fgColor ? `${fgColor}` : null;
this.item.style.backgroundColor = bgColor ? `${bgColor}` : '';
}
if (this.check) {
this.check.style.backgroundColor = fgColor ? `${fgColor}` : '';
}
if (this.container) {
this.container.style.border = border;
}
}
style(style: IMenuStyles): void {
......@@ -590,11 +618,11 @@ class BaseMenuActionViewItem extends BaseActionViewItem {
}
class SubmenuMenuActionViewItem extends BaseMenuActionViewItem {
private mysubmenu: Menu | null;
private mysubmenu: Menu | null = null;
private submenuContainer: HTMLElement | undefined;
private submenuIndicator: HTMLElement;
private submenuIndicator: HTMLElement | undefined;
private readonly submenuDisposables = this._register(new DisposableStore());
private mouseOver: boolean;
private mouseOver: boolean = false;
private showScheduler: RunOnceScheduler;
private hideScheduler: RunOnceScheduler;
private expandDirection: Direction;
......@@ -631,11 +659,13 @@ class SubmenuMenuActionViewItem extends BaseMenuActionViewItem {
return;
}
addClass(this.item, 'monaco-submenu-item');
this.item.setAttribute('aria-haspopup', 'true');
if (this.item) {
addClass(this.item, 'monaco-submenu-item');
this.item.setAttribute('aria-haspopup', 'true');
this.submenuIndicator = append(this.item, $('span.submenu-indicator'));
this.submenuIndicator.setAttribute('aria-hidden', 'true');
this.submenuIndicator = append(this.item, $('span.submenu-indicator'));
this.submenuIndicator.setAttribute('aria-hidden', 'true');
}
this._register(addDisposableListener(this.element, EventType.KEY_UP, e => {
let event = new StandardKeyboardEvent(e);
......@@ -793,7 +823,9 @@ class SubmenuMenuActionViewItem extends BaseMenuActionViewItem {
const isSelected = this.element && hasClass(this.element, 'focused');
const fgColor = isSelected && this.menuStyle.selectionForegroundColor ? this.menuStyle.selectionForegroundColor : this.menuStyle.foregroundColor;
this.submenuIndicator.style.backgroundColor = fgColor ? `${fgColor}` : '';
if (this.submenuIndicator) {
this.submenuIndicator.style.backgroundColor = fgColor ? `${fgColor}` : '';
}
if (this.parentData.submenu) {
this.parentData.submenu.style(this.menuStyle);
......
......@@ -56,7 +56,7 @@ export class MenuBar extends Disposable {
actions?: ReadonlyArray<IAction>;
}[];
private overflowMenu: {
private overflowMenu!: {
buttonElement: HTMLElement;
titleElement: HTMLElement;
label: string;
......@@ -73,22 +73,22 @@ export class MenuBar extends Disposable {
private menuUpdater: RunOnceScheduler;
// Input-related
private _mnemonicsInUse: boolean;
private openedViaKeyboard: boolean;
private awaitingAltRelease: boolean;
private ignoreNextMouseUp: boolean;
private _mnemonicsInUse: boolean = false;
private openedViaKeyboard: boolean = false;
private awaitingAltRelease: boolean = false;
private ignoreNextMouseUp: boolean = false;
private mnemonics: Map<string, number>;
private updatePending: boolean;
private updatePending: boolean = false;
private _focusState: MenubarState;
private actionRunner: IActionRunner;
private readonly _onVisibilityChange: Emitter<boolean>;
private readonly _onFocusStateChange: Emitter<boolean>;
private numMenusShown: number;
private menuStyle: IMenuStyles;
private overflowLayoutScheduled: IDisposable | null;
private numMenusShown: number = 0;
private menuStyle: IMenuStyles | undefined;
private overflowLayoutScheduled: IDisposable | null = null;
constructor(private container: HTMLElement, private options: IMenuBarOptions = {}) {
super();
......@@ -930,7 +930,9 @@ export class MenuBar extends Disposable {
};
let menuWidget = this._register(new Menu(menuHolder, customMenu.actions, menuOptions));
menuWidget.style(this.menuStyle);
if (this.menuStyle) {
menuWidget.style(this.menuStyle);
}
this._register(menuWidget.onDidCancel(() => {
this.focusState = MenubarState.FOCUSED;
......
......@@ -77,7 +77,7 @@ export abstract class MenubarControl extends Disposable {
'Help': nls.localize({ key: 'mHelp', comment: ['&& denotes a mnemonic'] }, "&&Help")
};
protected recentlyOpened: IRecentlyOpened;
protected recentlyOpened: IRecentlyOpened = { files: [], workspaces: [] };
protected menuUpdater: RunOnceScheduler;
......@@ -259,10 +259,10 @@ export abstract class MenubarControl extends Disposable {
}
export class CustomMenubarControl extends MenubarControl {
private menubar: MenuBar;
private container: HTMLElement;
private alwaysOnMnemonics: boolean;
private focusInsideMenubar: boolean;
private menubar: MenuBar | undefined;
private container: HTMLElement | undefined;
private alwaysOnMnemonics: boolean = false;
private focusInsideMenubar: boolean = false;
private readonly _onVisibilityChange: Emitter<boolean>;
private readonly _onFocusStateChange: Emitter<boolean>;
......@@ -518,6 +518,11 @@ export class CustomMenubarControl extends MenubarControl {
}
private setupCustomMenubar(firstTime: boolean): void {
// If there is no container, we cannot setup the menubar
if (!this.container) {
return;
}
if (firstTime) {
this.menubar = this._register(new MenuBar(
this.container, {
......@@ -526,12 +531,13 @@ export class CustomMenubarControl extends MenubarControl {
visibility: this.currentMenubarVisibility,
getKeybinding: (action) => this.keybindingService.lookupKeybinding(action.id),
compactMode: this.currentCompactMenuMode
}
));
}));
this.accessibilityService.alwaysUnderlineAccessKeys().then(val => {
this.alwaysOnMnemonics = val;
this.menubar.update({ enableMnemonics: this.currentEnableMenuBarMnemonics, disableAltFocus: this.currentDisableMenuBarAltFocus, visibility: this.currentMenubarVisibility, getKeybinding: (action) => this.keybindingService.lookupKeybinding(action.id), alwaysOnMnemonics: this.alwaysOnMnemonics, compactMode: this.currentCompactMenuMode });
if (this.menubar) {
this.menubar.update({ enableMnemonics: this.currentEnableMenuBarMnemonics, disableAltFocus: this.currentDisableMenuBarAltFocus, visibility: this.currentMenubarVisibility, getKeybinding: (action) => this.keybindingService.lookupKeybinding(action.id), alwaysOnMnemonics: this.alwaysOnMnemonics, compactMode: this.currentCompactMenuMode });
}
});
this._register(this.menubar.onFocusStateChange(focused => {
......@@ -557,7 +563,9 @@ export class CustomMenubarControl extends MenubarControl {
this._register(attachMenuStyler(this.menubar, this.themeService));
} else {
this.menubar.update({ enableMnemonics: this.currentEnableMenuBarMnemonics, disableAltFocus: this.currentDisableMenuBarAltFocus, visibility: this.currentMenubarVisibility, getKeybinding: (action) => this.keybindingService.lookupKeybinding(action.id), alwaysOnMnemonics: this.alwaysOnMnemonics, compactMode: this.currentCompactMenuMode });
if (this.menubar) {
this.menubar.update({ enableMnemonics: this.currentEnableMenuBarMnemonics, disableAltFocus: this.currentDisableMenuBarAltFocus, visibility: this.currentMenubarVisibility, getKeybinding: (action) => this.keybindingService.lookupKeybinding(action.id), alwaysOnMnemonics: this.alwaysOnMnemonics, compactMode: this.currentCompactMenuMode });
}
}
// Update the menu actions
......@@ -577,7 +585,9 @@ export class CustomMenubarControl extends MenubarControl {
if (!this.focusInsideMenubar) {
const actions: IAction[] = [];
updateActions(menu, actions, topLevelTitle);
this.menubar.updateMenu({ actions: actions, label: mnemonicMenuLabel(this.topLevelTitles[topLevelTitle]) });
if (this.menubar) {
this.menubar.updateMenu({ actions: actions, label: mnemonicMenuLabel(this.topLevelTitles[topLevelTitle]) });
}
}
}, this));
}
......@@ -604,7 +614,9 @@ export class CustomMenubarControl extends MenubarControl {
if (!this.focusInsideMenubar) {
const actions: IAction[] = [];
updateActions(menu, actions, title);
this.menubar.updateMenu({ actions: actions, label: mnemonicMenuLabel(this.topLevelTitles[title]) });
if (this.menubar) {
this.menubar.updateMenu({ actions: actions, label: mnemonicMenuLabel(this.topLevelTitles[title]) });
}
}
}));
}
......@@ -614,10 +626,12 @@ export class CustomMenubarControl extends MenubarControl {
updateActions(menu, actions, title);
}
if (!firstTime) {
this.menubar.updateMenu({ actions: actions, label: mnemonicMenuLabel(this.topLevelTitles[title]) });
} else {
this.menubar.push({ actions: actions, label: mnemonicMenuLabel(this.topLevelTitles[title]) });
if (this.menubar) {
if (!firstTime) {
this.menubar.updateMenu({ actions: actions, label: mnemonicMenuLabel(this.topLevelTitles[title]) });
} else {
this.menubar.push({ actions: actions, label: mnemonicMenuLabel(this.topLevelTitles[title]) });
}
}
}
}
......@@ -628,7 +642,9 @@ export class CustomMenubarControl extends MenubarControl {
DOM.removeClass(this.container, 'inactive');
} else {
DOM.addClass(this.container, 'inactive');
this.menubar.blur();
if (this.menubar) {
this.menubar.blur();
}
}
}
}
......@@ -648,7 +664,9 @@ export class CustomMenubarControl extends MenubarControl {
}
this._register(DOM.addDisposableListener(window, DOM.EventType.RESIZE, () => {
this.menubar.blur();
if (this.menubar) {
this.menubar.blur();
}
}));
// Mnemonics require fullscreen in web
......
......@@ -68,19 +68,19 @@ export class TitlebarPart extends Part implements ITitleService {
_serviceBrand: undefined;
private title: HTMLElement;
private dragRegion: HTMLElement;
private windowControls: HTMLElement;
private maxRestoreControl: HTMLElement;
private appIcon: HTMLElement;
private title!: HTMLElement;
private dragRegion: HTMLElement | undefined;
private windowControls: HTMLElement | undefined;
private maxRestoreControl: HTMLElement | undefined;
private appIcon: HTMLElement | undefined;
private customMenubar: CustomMenubarControl | undefined;
private menubar?: HTMLElement;
private resizer: HTMLElement;
private lastLayoutDimensions: Dimension;
private resizer: HTMLElement | undefined;
private lastLayoutDimensions: Dimension | undefined;
private pendingTitle: string;
private pendingTitle: string | undefined;
private isInactive: boolean;
private isInactive: boolean = false;
private readonly properties: ITitleProperties = { isPure: true, isAdmin: false };
private readonly activeEditorListeners = this._register(new DisposableStore());
......@@ -158,8 +158,10 @@ export class TitlebarPart extends Part implements ITitleService {
// Hide title when toggling menu bar
if (!isWeb && this.currentMenubarVisibility === 'toggle' && visible) {
// Hack to fix issue #52522 with layered webkit-app-region elements appearing under cursor
hide(this.dragRegion);
setTimeout(() => show(this.dragRegion), 50);
if (this.dragRegion) {
hide(this.dragRegion);
setTimeout(() => show(this.dragRegion!), 50);
}
}
this.adjustTitleMarginToCenter();
......@@ -169,7 +171,7 @@ export class TitlebarPart extends Part implements ITitleService {
}
private onMenubarFocusChanged(focused: boolean) {
if (!isWeb && (isWindows || isLinux) && this.currentMenubarVisibility === 'compact') {
if (!isWeb && (isWindows || isLinux) && this.currentMenubarVisibility === 'compact' && this.dragRegion) {
if (focused) {
hide(this.dragRegion);
} else {
......@@ -518,9 +520,9 @@ export class TitlebarPart extends Part implements ITitleService {
private onUpdateAppIconDragBehavior() {
const setting = this.configurationService.getValue('window.doubleClickIconToClose');
if (setting) {
if (setting && this.appIcon) {
(this.appIcon.style as any)['-webkit-app-region'] = 'no-drag';
} else {
} else if (this.appIcon) {
(this.appIcon.style as any)['-webkit-app-region'] = 'drag';
}
}
......@@ -576,14 +578,24 @@ export class TitlebarPart extends Part implements ITitleService {
if ((!isWeb && isMacintosh) || this.currentMenubarVisibility === 'hidden') {
this.title.style.zoom = `${1 / getZoomFactor()}`;
if (!isWeb && (isWindows || isLinux)) {
this.appIcon.style.zoom = `${1 / getZoomFactor()}`;
this.windowControls.style.zoom = `${1 / getZoomFactor()}`;
if (this.appIcon) {
this.appIcon.style.zoom = `${1 / getZoomFactor()}`;
}
if (this.windowControls) {
this.windowControls.style.zoom = `${1 / getZoomFactor()}`;
}
}
} else {
this.title.style.zoom = null;
if (!isWeb && (isWindows || isLinux)) {
this.appIcon.style.zoom = null;
this.windowControls.style.zoom = null;
if (this.appIcon) {
this.appIcon.style.zoom = null;
}
if (this.windowControls) {
this.windowControls.style.zoom = null;
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册