Merge VS Code 1.31.1 (#4283)

This commit is contained in:
Matt Irvine
2019-03-15 13:09:45 -07:00
committed by GitHub
parent 7d31575149
commit 86bac90001
1716 changed files with 53308 additions and 48375 deletions

View File

@@ -117,7 +117,7 @@
/* Context Menu */
.context-view.monaco-menu-container {
font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Ubuntu", "Droid Sans", sans-serif;
font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif;
outline: 0;
border: none;
-webkit-animation: fadeIn 0.083s linear;
@@ -154,7 +154,6 @@
flex-shrink: 1;
box-sizing: border-box;
height: 30px;
-webkit-app-region: no-drag;
overflow: hidden;
flex-wrap: wrap;
}
@@ -183,7 +182,7 @@
}
.menubar .menubar-menu-items-holder.monaco-menu-container {
font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Ubuntu", "Droid Sans", sans-serif;
font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif;
outline: 0;
border: none;
}

View File

@@ -15,9 +15,10 @@ import { RunOnceScheduler } from 'vs/base/common/async';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Color } from 'vs/base/common/color';
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
import { ScrollbarVisibility, ScrollEvent } from 'vs/base/common/scrollable';
import { Event, Emitter } from 'vs/base/common/event';
import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
import { isLinux } from 'vs/base/common/platform';
export const MENU_MNEMONIC_REGEX: RegExp = /\(&{1,2}(.)\)|&{1,2}(.)/;
export const MENU_ESCAPED_MNEMONIC_REGEX: RegExp = /(?:&){1,2}(.)/;
@@ -26,7 +27,7 @@ export interface IMenuOptions {
context?: any;
actionItemProvider?: IActionItemProvider;
actionRunner?: IActionRunner;
getKeyBinding?: (action: IAction) => ResolvedKeybinding;
getKeyBinding?: (action: IAction) => ResolvedKeybinding | undefined;
ariaLabel?: string;
enableMnemonics?: boolean;
anchorAlignment?: AnchorAlignment;
@@ -44,7 +45,7 @@ export interface IMenuStyles {
}
export class SubmenuAction extends Action {
constructor(label: string, public entries: (SubmenuAction | IAction)[], cssClass?: string) {
constructor(label: string, public entries: Array<SubmenuAction | IAction>, cssClass?: string) {
super(!!cssClass ? cssClass : 'submenu', label, '', true);
}
}
@@ -59,6 +60,7 @@ export class Menu extends ActionBar {
private menuDisposables: IDisposable[];
private scrollableElement: DomScrollableElement;
private menuElement: HTMLElement;
private scrollTopHold: number | undefined;
private readonly _onScroll: Emitter<void>;
@@ -94,48 +96,73 @@ export class Menu extends ActionBar {
const key = KeyCodeUtils.fromString(e.key);
if (this.mnemonics.has(key)) {
EventHelper.stop(e, true);
const actions = this.mnemonics.get(key);
const actions = this.mnemonics.get(key)!;
if (actions.length === 1) {
if (actions[0] instanceof SubmenuActionItem) {
this.focusItemByElement(actions[0].container);
}
actions[0].onClick(event);
actions[0].onClick(e);
}
if (actions.length > 1) {
const action = actions.shift();
this.focusItemByElement(action.container);
if (action) {
this.focusItemByElement(action.container);
actions.push(action);
}
actions.push(action);
this.mnemonics.set(key, actions);
}
}
}));
}
if (isLinux) {
this._register(addDisposableListener(menuElement, EventType.KEY_DOWN, e => {
const event = new StandardKeyboardEvent(e);
if (event.equals(KeyCode.Home) || event.equals(KeyCode.PageUp)) {
this.focusedItem = this.items.length - 1;
this.focusNext();
EventHelper.stop(e, true);
} else if (event.equals(KeyCode.End) || event.equals(KeyCode.PageDown)) {
this.focusedItem = 0;
this.focusPrevious();
EventHelper.stop(e, true);
}
}));
}
this._register(addDisposableListener(this.domNode, EventType.MOUSE_OUT, e => {
let relatedTarget = e.relatedTarget as HTMLElement;
if (!isAncestor(relatedTarget, this.domNode)) {
this.focusedItem = undefined;
this.scrollTopHold = this.menuElement.scrollTop;
this.updateFocus();
e.stopPropagation();
}
}));
this._register(addDisposableListener(this.domNode, EventType.MOUSE_UP, e => {
// Absorb clicks in menu dead space https://github.com/Microsoft/vscode/issues/63575
EventHelper.stop(e, true);
}));
this._register(addDisposableListener(this.actionsList, EventType.MOUSE_OVER, e => {
let target = e.target as HTMLElement;
if (!target || !isAncestor(target, this.actionsList) || target === this.actionsList) {
return;
}
while (target.parentElement !== this.actionsList) {
while (target.parentElement !== this.actionsList && target.parentElement !== null) {
target = target.parentElement;
}
if (hasClass(target, 'action-item')) {
const lastFocusedItem = this.focusedItem;
this.scrollTopHold = this.menuElement.scrollTop;
this.setFocusedItem(target);
if (lastFocusedItem !== this.focusedItem) {
@@ -171,7 +198,11 @@ export class Menu extends ActionBar {
this._onScroll.fire();
}, this, this.menuDisposables);
this._register(addDisposableListener(this.menuElement, EventType.SCROLL, (e) => {
this._register(addDisposableListener(this.menuElement, EventType.SCROLL, (e: ScrollEvent) => {
if (this.scrollTopHold !== undefined) {
this.menuElement.scrollTop = this.scrollTopHold;
this.scrollTopHold = undefined;
}
this.scrollableElement.scanDomNode();
}));
@@ -261,7 +292,7 @@ export class Menu extends ActionBar {
if (mnemonic && menuActionItem.isEnabled()) {
let actionItems: MenuActionItem[] = [];
if (this.mnemonics.has(mnemonic)) {
actionItems = this.mnemonics.get(mnemonic);
actionItems = this.mnemonics.get(mnemonic)!;
}
actionItems.push(menuActionItem);
@@ -276,7 +307,11 @@ export class Menu extends ActionBar {
if (options.getKeyBinding) {
const keybinding = options.getKeyBinding(action);
if (keybinding) {
menuItemOptions.keybinding = keybinding.getLabel();
const keybindingLabel = keybinding.getLabel();
if (keybindingLabel) {
menuItemOptions.keybinding = keybindingLabel;
}
}
}
@@ -287,7 +322,7 @@ export class Menu extends ActionBar {
if (mnemonic && menuActionItem.isEnabled()) {
let actionItems: MenuActionItem[] = [];
if (this.mnemonics.has(mnemonic)) {
actionItems = this.mnemonics.get(mnemonic);
actionItems = this.mnemonics.get(mnemonic)!;
}
actionItems.push(menuActionItem);
@@ -342,6 +377,10 @@ class MenuActionItem extends BaseActionItem {
render(container: HTMLElement): void {
super.render(container);
if (!this.element) {
return;
}
this.container = container;
this.item = append(this.element, $('a.action-menu-item'));
@@ -439,7 +478,7 @@ class MenuActionItem extends BaseActionItem {
removeClasses(this.item, this.cssClass);
}
if (this.options.icon) {
this.cssClass = this.getAction().class;
this.cssClass = this.getAction().class || '';
addClass(this.label, 'icon');
if (this.cssClass) {
addClasses(this.label, this.cssClass);
@@ -452,11 +491,17 @@ class MenuActionItem extends BaseActionItem {
updateEnabled(): void {
if (this.getAction().enabled) {
removeClass(this.element, 'disabled');
if (this.element) {
removeClass(this.element, 'disabled');
}
removeClass(this.item, 'disabled');
this.item.tabIndex = 0;
} else {
addClass(this.element, 'disabled');
if (this.element) {
addClass(this.element, 'disabled');
}
addClass(this.item, 'disabled');
removeTabIndexAndUpdateFocus(this.item);
}
@@ -483,7 +528,7 @@ class MenuActionItem extends BaseActionItem {
return;
}
const isSelected = hasClass(this.element, 'focused');
const isSelected = this.element && hasClass(this.element, 'focused');
const fgColor = isSelected && this.menuStyle.selectionForegroundColor ? this.menuStyle.selectionForegroundColor : this.menuStyle.foregroundColor;
const bgColor = isSelected && this.menuStyle.selectionBackgroundColor ? this.menuStyle.selectionBackgroundColor : this.menuStyle.backgroundColor;
const border = isSelected && this.menuStyle.selectionBorderColor ? `1px solid ${this.menuStyle.selectionBorderColor}` : null;
@@ -501,8 +546,8 @@ class MenuActionItem extends BaseActionItem {
}
class SubmenuActionItem extends MenuActionItem {
private mysubmenu: Menu;
private submenuContainer: HTMLElement;
private mysubmenu: Menu | null;
private submenuContainer: HTMLElement | undefined;
private submenuIndicator: HTMLElement;
private submenuDisposables: IDisposable[] = [];
private mouseOver: boolean;
@@ -525,7 +570,7 @@ class SubmenuActionItem extends MenuActionItem {
}, 250);
this.hideScheduler = new RunOnceScheduler(() => {
if ((!isAncestor(document.activeElement, this.element) && this.parentData.submenu === this.mysubmenu)) {
if (this.element && (!isAncestor(document.activeElement, this.element) && this.parentData.submenu === this.mysubmenu)) {
this.parentData.parent.focus(false);
this.cleanupExistingSubmenu(true);
}
@@ -535,6 +580,10 @@ class SubmenuActionItem extends MenuActionItem {
render(container: HTMLElement): void {
super.render(container);
if (!this.element) {
return;
}
addClass(this.item, 'monaco-submenu-item');
this.item.setAttribute('aria-haspopup', 'true');
@@ -570,7 +619,7 @@ class SubmenuActionItem extends MenuActionItem {
}));
this._register(addDisposableListener(this.element, EventType.FOCUS_OUT, e => {
if (!isAncestor(document.activeElement, this.element)) {
if (this.element && !isAncestor(document.activeElement, this.element)) {
this.hideScheduler.schedule();
}
}));
@@ -597,16 +646,20 @@ class SubmenuActionItem extends MenuActionItem {
private cleanupExistingSubmenu(force: boolean): void {
if (this.parentData.submenu && (force || (this.parentData.submenu !== this.mysubmenu))) {
this.parentData.submenu.dispose();
this.parentData.submenu = null;
this.parentData.submenu = undefined;
if (this.submenuContainer) {
this.submenuDisposables = dispose(this.submenuDisposables);
this.submenuContainer = null;
this.submenuContainer = undefined;
}
}
}
private createSubmenu(selectFirstItem = true): void {
if (!this.element) {
return;
}
if (!this.parentData.submenu) {
this.submenuContainer = append(this.element, $('div.monaco-submenu'));
addClasses(this.submenuContainer, 'menubar-menu-items-holder', 'context-view');
@@ -618,13 +671,15 @@ class SubmenuActionItem extends MenuActionItem {
const boundingRect = this.element.getBoundingClientRect();
const childBoundingRect = this.submenuContainer.getBoundingClientRect();
const computedStyles = getComputedStyle(this.parentData.parent.domNode);
const paddingTop = parseFloat(computedStyles.paddingTop || '0') || 0;
if (window.innerWidth <= boundingRect.right + childBoundingRect.width) {
this.submenuContainer.style.left = '10px';
this.submenuContainer.style.top = `${this.element.offsetTop - this.parentData.parent.scrollOffset + boundingRect.height}px`;
} else {
this.submenuContainer.style.left = `${this.element.offsetWidth}px`;
this.submenuContainer.style.top = `${this.element.offsetTop - this.parentData.parent.scrollOffset}px`;
this.submenuContainer.style.top = `${this.element.offsetTop - this.parentData.parent.scrollOffset - paddingTop}px`;
}
this.submenuDisposables.push(addDisposableListener(this.submenuContainer, EventType.KEY_UP, e => {
@@ -633,11 +688,14 @@ class SubmenuActionItem extends MenuActionItem {
EventHelper.stop(e, true);
this.parentData.parent.focus();
this.parentData.submenu.dispose();
this.parentData.submenu = null;
if (this.parentData.submenu) {
this.parentData.submenu.dispose();
this.parentData.submenu = undefined;
}
this.submenuDisposables = dispose(this.submenuDisposables);
this.submenuContainer = null;
this.submenuContainer = undefined;
}
}));
@@ -651,11 +709,14 @@ class SubmenuActionItem extends MenuActionItem {
this.submenuDisposables.push(this.parentData.submenu.onDidCancel(() => {
this.parentData.parent.focus();
this.parentData.submenu.dispose();
this.parentData.submenu = null;
if (this.parentData.submenu) {
this.parentData.submenu.dispose();
this.parentData.submenu = undefined;
}
this.submenuDisposables = dispose(this.submenuDisposables);
this.submenuContainer = null;
this.submenuContainer = undefined;
}));
this.parentData.submenu.focus(selectFirstItem);
@@ -673,7 +734,7 @@ class SubmenuActionItem extends MenuActionItem {
return;
}
const isSelected = hasClass(this.element, 'focused');
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}` : null;
@@ -695,7 +756,7 @@ class SubmenuActionItem extends MenuActionItem {
if (this.submenuContainer) {
this.submenuDisposables = dispose(this.submenuDisposables);
this.submenuContainer = null;
this.submenuContainer = undefined;
}
}
}

View File

@@ -59,9 +59,9 @@ export class MenuBar extends Disposable {
index: number;
holder?: HTMLElement;
widget?: Menu;
};
} | undefined;
private focusToReturn: HTMLElement;
private focusToReturn: HTMLElement | undefined;
private menuUpdater: RunOnceScheduler;
// Input-related
@@ -80,7 +80,7 @@ export class MenuBar extends Disposable {
private numMenusShown: number;
private menuStyle: IMenuStyles;
private overflowLayoutScheduled: IDisposable;
private overflowLayoutScheduled: IDisposable | null;
constructor(private container: HTMLElement, private options: IMenuBarOptions = {}) {
super();
@@ -118,7 +118,7 @@ export class MenuBar extends Disposable {
} else if (event.equals(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);
const menuIndex = this.mnemonics.get(key)!;
this.onMenuTriggered(menuIndex, false);
} else {
eventHandled = false;
@@ -152,7 +152,7 @@ export class MenuBar extends Disposable {
if (event.relatedTarget) {
if (!this.container.contains(event.relatedTarget as HTMLElement)) {
this.focusToReturn = null;
this.focusToReturn = undefined;
this.setUnfocusedState();
}
}
@@ -171,7 +171,7 @@ export class MenuBar extends Disposable {
this.mnemonicsInUse = true;
this.updateMnemonicVisibility(true);
const menuIndex = this.mnemonics.get(key);
const menuIndex = this.mnemonics.get(key)!;
this.onMenuTriggered(menuIndex, false);
}));
@@ -223,7 +223,7 @@ export class MenuBar extends Disposable {
Gesture.addTarget(buttonElement);
this._register(DOM.addDisposableListener(buttonElement, EventType.Tap, (e: GestureEvent) => {
// Ignore this touch if the menu is touched
if (this.isOpen && this.focusedMenu.holder && DOM.isAncestor(e.initialTarget as HTMLElement, this.focusedMenu.holder)) {
if (this.isOpen && this.focusedMenu && this.focusedMenu.holder && DOM.isAncestor(e.initialTarget as HTMLElement, this.focusedMenu.holder)) {
return;
}
@@ -307,7 +307,7 @@ export class MenuBar extends Disposable {
Gesture.addTarget(buttonElement);
this._register(DOM.addDisposableListener(buttonElement, EventType.Tap, (e: GestureEvent) => {
// Ignore this touch if the menu is touched
if (this.isOpen && this.focusedMenu.holder && DOM.isAncestor(e.initialTarget as HTMLElement, this.focusedMenu.holder)) {
if (this.isOpen && this.focusedMenu && this.focusedMenu.holder && DOM.isAncestor(e.initialTarget as HTMLElement, this.focusedMenu.holder)) {
return;
}
@@ -377,7 +377,9 @@ export class MenuBar extends Disposable {
DOM.removeNode(this.overflowMenu.titleElement);
DOM.removeNode(this.overflowMenu.buttonElement);
this.overflowLayoutScheduled = dispose(this.overflowLayoutScheduled);
if (this.overflowLayoutScheduled) {
this.overflowLayoutScheduled = dispose(this.overflowLayoutScheduled);
}
}
blur(): void {
@@ -439,7 +441,7 @@ export class MenuBar extends Disposable {
this.overflowMenu.actions = [];
for (let idx = this.numMenusShown; idx < this.menuCache.length; idx++) {
this.overflowMenu.actions.push(new SubmenuAction(this.menuCache[idx].label, this.menuCache[idx].actions));
this.overflowMenu.actions.push(new SubmenuAction(this.menuCache[idx].label, this.menuCache[idx].actions || []));
}
DOM.removeNode(this.overflowMenu.buttonElement);
@@ -496,7 +498,7 @@ export class MenuBar extends Disposable {
if (!this.overflowLayoutScheduled) {
this.overflowLayoutScheduled = DOM.scheduleAtNextAnimationFrame(() => {
this.updateOverflowAction();
this.overflowLayoutScheduled = void 0;
this.overflowLayoutScheduled = null;
});
}
@@ -518,6 +520,8 @@ export class MenuBar extends Disposable {
if (this.container.style.display !== 'flex') {
this.container.style.display = 'flex';
this._onVisibilityChange.fire(true);
this.updateOverflowAction();
}
}
@@ -556,11 +560,11 @@ export class MenuBar extends Disposable {
}
if (isFocused) {
this.focusedMenu = null;
this.focusedMenu = undefined;
if (this.focusToReturn) {
this.focusToReturn.focus();
this.focusToReturn = null;
this.focusToReturn = undefined;
}
}
@@ -584,11 +588,11 @@ export class MenuBar extends Disposable {
}
}
this.focusedMenu = null;
this.focusedMenu = undefined;
if (this.focusToReturn) {
this.focusToReturn.focus();
this.focusToReturn = null;
this.focusToReturn = undefined;
}
}
@@ -814,7 +818,10 @@ export class MenuBar extends Disposable {
}
if (this.focusedMenu.holder) {
DOM.removeClass(this.focusedMenu.holder.parentElement, 'open');
if (this.focusedMenu.holder.parentElement) {
DOM.removeClass(this.focusedMenu.holder.parentElement, 'open');
}
this.focusedMenu.holder.remove();
}
@@ -829,6 +836,11 @@ export class MenuBar extends Disposable {
private showCustomMenu(menuIndex: number, selectFirst = true): void {
const actualMenuIndex = menuIndex >= this.numMenusShown ? MenuBar.OVERFLOW_INDEX : menuIndex;
const customMenu = actualMenuIndex === MenuBar.OVERFLOW_INDEX ? this.overflowMenu : this.menuCache[actualMenuIndex];
if (!customMenu.actions) {
return;
}
const menuHolder = $('div.menubar-menu-items-holder');
DOM.addClass(customMenu.buttonElement, 'open');
@@ -851,12 +863,6 @@ export class MenuBar extends Disposable {
this.focusState = MenubarState.FOCUSED;
}));
this._register(menuWidget.onDidBlur(() => {
setTimeout(() => {
this.cleanupCustomMenu();
}, 100);
}));
if (actualMenuIndex !== menuIndex) {
menuWidget.trigger(menuIndex - this.numMenusShown);
} else {
@@ -897,7 +903,7 @@ class ModifierKeyEmitter extends Emitter<IModifierKeyStatus> {
ctrlKey: false
};
this._subscriptions.push(domEvent(document.body, 'keydown')(e => {
this._subscriptions.push(domEvent(document.body, 'keydown', true)(e => {
const event = new StandardKeyboardEvent(e);
if (e.altKey && !this._keyStatus.altKey) {
@@ -920,7 +926,8 @@ class ModifierKeyEmitter extends Emitter<IModifierKeyStatus> {
this.fire(this._keyStatus);
}
}));
this._subscriptions.push(domEvent(document.body, 'keyup')(e => {
this._subscriptions.push(domEvent(document.body, 'keyup', true)(e => {
if (!e.altKey && this._keyStatus.altKey) {
this._keyStatus.lastKeyReleased = 'alt';
} else if (!e.ctrlKey && this._keyStatus.ctrlKey) {
@@ -943,11 +950,11 @@ class ModifierKeyEmitter extends Emitter<IModifierKeyStatus> {
this.fire(this._keyStatus);
}
}));
this._subscriptions.push(domEvent(document.body, 'mousedown')(e => {
this._subscriptions.push(domEvent(document.body, 'mousedown', true)(e => {
this._keyStatus.lastKeyPressed = undefined;
}));
this._subscriptions.push(domEvent(window, 'blur')(e => {
this._keyStatus.lastKeyPressed = undefined;
this._keyStatus.lastKeyReleased = undefined;