Merge from vscode a5cf1da01d5db3d2557132be8d30f89c38019f6c (#8525)

* Merge from vscode a5cf1da01d5db3d2557132be8d30f89c38019f6c

* remove files we don't want

* fix hygiene

* update distro

* update distro

* fix hygiene

* fix strict nulls

* distro

* distro

* fix tests

* fix tests

* add another edit

* fix viewlet icon

* fix azure dialog

* fix some padding

* fix more padding issues
This commit is contained in:
Anthony Dresser
2019-12-04 19:28:22 -08:00
committed by GitHub
parent a8818ab0df
commit f5ce7fb2a5
1507 changed files with 42813 additions and 27370 deletions

View File

@@ -16,6 +16,7 @@ import { ICommandAction, IMenu, IMenuActionOptions, MenuItemAction, SubmenuItemA
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
// The alternative key on all platforms is alt. On windows we also support shift as an alternative key #44136
class AlternativeKeyEmitter extends Emitter<boolean> {
@@ -148,7 +149,7 @@ export class MenuEntryActionViewItem extends ActionViewItem {
@INotificationService protected _notificationService: INotificationService,
@IContextMenuService _contextMenuService: IContextMenuService
) {
super(undefined, _action, { icon: !!(_action.class || _action.item.iconLocation), label: !_action.class && !_action.item.iconLocation });
super(undefined, _action, { icon: !!(_action.class || _action.item.icon), label: !_action.class && !_action.item.icon });
this._altKey = AlternativeKeyEmitter.getInstance(_contextMenuService);
}
@@ -237,28 +238,45 @@ export class MenuEntryActionViewItem extends ActionViewItem {
_updateItemClass(item: ICommandAction): void {
this._itemClassDispose.value = undefined;
if (item.iconLocation) {
let iconClass: string;
const iconPathMapKey = item.iconLocation.dark.toString();
if (MenuEntryActionViewItem.ICON_PATH_TO_CSS_RULES.has(iconPathMapKey)) {
iconClass = MenuEntryActionViewItem.ICON_PATH_TO_CSS_RULES.get(iconPathMapKey)!;
} else {
iconClass = ids.nextId();
createCSSRule(`.icon.${iconClass}`, `background-image: ${asCSSUrl(item.iconLocation.light || item.iconLocation.dark)}`);
createCSSRule(`.vs-dark .icon.${iconClass}, .hc-black .icon.${iconClass}`, `background-image: ${asCSSUrl(item.iconLocation.dark)}`);
MenuEntryActionViewItem.ICON_PATH_TO_CSS_RULES.set(iconPathMapKey, iconClass);
}
if (this.label) {
addClasses(this.label, 'icon', iconClass);
if (ThemeIcon.isThemeIcon(item.icon)) {
// theme icons
const iconClass = ThemeIcon.asClassName(item.icon);
if (this.label && iconClass) {
addClasses(this.label, iconClass);
this._itemClassDispose.value = toDisposable(() => {
if (this.label) {
removeClasses(this.label, 'icon', iconClass);
removeClasses(this.label, iconClass);
}
});
}
} else if (item.icon) {
// icon path
let iconClass: string;
if (item.icon?.dark?.scheme) {
const iconPathMapKey = item.icon.dark.toString();
if (MenuEntryActionViewItem.ICON_PATH_TO_CSS_RULES.has(iconPathMapKey)) {
iconClass = MenuEntryActionViewItem.ICON_PATH_TO_CSS_RULES.get(iconPathMapKey)!;
} else {
iconClass = ids.nextId();
createCSSRule(`.icon.${iconClass}`, `background-image: ${asCSSUrl(item.icon.light || item.icon.dark)}`);
createCSSRule(`.vs-dark .icon.${iconClass}, .hc-black .icon.${iconClass}`, `background-image: ${asCSSUrl(item.icon.dark)}`);
MenuEntryActionViewItem.ICON_PATH_TO_CSS_RULES.set(iconPathMapKey, iconClass);
}
if (this.label) {
addClasses(this.label, 'icon', iconClass);
this._itemClassDispose.value = toDisposable(() => {
if (this.label) {
removeClasses(this.label, 'icon', iconClass);
}
});
}
}
}
}
}
@@ -304,17 +322,19 @@ export class LabeledMenuItemActionItem extends MenuEntryActionViewItem {
dispose(this._labeledItemClassDispose);
this._labeledItemClassDispose = undefined;
if (item.iconLocation) {
if (ThemeIcon.isThemeIcon(item.icon)) {
// TODO
} else if (item.icon) {
let iconClass: string;
const iconPathMapKey = item.iconLocation.dark.toString();
const iconPathMapKey = item.icon.dark.toString();
if (MenuEntryActionViewItem.ICON_PATH_TO_CSS_RULES.has(iconPathMapKey)) {
iconClass = MenuEntryActionViewItem.ICON_PATH_TO_CSS_RULES.get(iconPathMapKey)!;
} else {
iconClass = ids.nextId();
createCSSRule(`.icon.${iconClass}`, `background-image: ${asCSSUrl(item.iconLocation.light || item.iconLocation.dark)}`);
createCSSRule(`.vs-dark .icon.${iconClass}, .hc-black .icon.${iconClass}`, `background-image: ${asCSSUrl(item.iconLocation.dark)}`);
createCSSRule(`.icon.${iconClass}`, `background-image: ${asCSSUrl(item.icon.light || item.icon.dark)}`);
createCSSRule(`.vs-dark .icon.${iconClass}, .hc-black .icon.${iconClass}`, `background-image: ${asCSSUrl(item.icon.dark)}`);
MenuEntryActionViewItem.ICON_PATH_TO_CSS_RULES.set(iconPathMapKey, iconClass);
}

View File

@@ -5,13 +5,14 @@
import { Action } from 'vs/base/common/actions';
import { SyncDescriptor0, createSyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { IConstructorSignature2, createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IConstructorSignature2, createDecorator, BrandedService } from 'vs/platform/instantiation/common/instantiation';
import { IKeybindings, KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { ICommandService, ICommandHandler, CommandsRegistry } from 'vs/platform/commands/common/commands';
import { IDisposable } from 'vs/base/common/lifecycle';
import { Event, Emitter } from 'vs/base/common/event';
import { URI, UriComponents } from 'vs/base/common/uri';
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
export interface ILocalizedString {
value: string;
@@ -22,7 +23,7 @@ export interface ICommandAction {
id: string;
title: string | ILocalizedString;
category?: string | ILocalizedString;
iconLocation?: { dark: URI; light?: URI; };
icon?: { dark?: URI; light?: URI; } | ThemeIcon;
precondition?: ContextKeyExpr;
toggled?: ContextKeyExpr;
}
@@ -64,6 +65,7 @@ export const enum MenuId {
DebugWatchContext,
DebugToolBar,
EditorContext,
EditorContextPeek,
EditorTitle,
EditorTitleContext,
EmptyEditorGroupContext,
@@ -95,6 +97,9 @@ export const enum MenuId {
StatusBarWindowIndicatorMenu,
TouchBarContext,
TitleBarContext,
TunnelContext,
TunnelInline,
TunnelTitle,
ViewItemContext,
ViewTitle,
ObjectExplorerItemContext, // {{SQL CARBON EDIT}}
@@ -300,7 +305,13 @@ export class SyncActionDescriptor {
private readonly _keybindingContext: ContextKeyExpr | undefined;
private readonly _keybindingWeight: number | undefined;
constructor(ctor: IConstructorSignature2<string, string, Action>,
public static create<Services extends BrandedService[]>(ctor: { new(id: string, label: string, ...services: Services): Action },
id: string, label: string | undefined, keybindings?: IKeybindings, keybindingContext?: ContextKeyExpr, keybindingWeight?: number
): SyncActionDescriptor {
return new SyncActionDescriptor(ctor as IConstructorSignature2<string, string, Action>, id, label, keybindings, keybindingContext, keybindingWeight);
}
private constructor(ctor: IConstructorSignature2<string, string, Action>,
id: string, label: string | undefined, keybindings?: IKeybindings, keybindingContext?: ContextKeyExpr, keybindingWeight?: number
) {
this._id = id;

View File

@@ -4,8 +4,8 @@
*--------------------------------------------------------------------------------------------*/
import { Emitter, Event } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { IMenu, IMenuActionOptions, IMenuItem, IMenuService, isIMenuItem, ISubmenuItem, MenuId, MenuItemAction, MenuRegistry, SubmenuItemAction } from 'vs/platform/actions/common/actions';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { IMenu, IMenuActionOptions, IMenuItem, IMenuService, isIMenuItem, ISubmenuItem, MenuId, MenuItemAction, MenuRegistry, SubmenuItemAction, ILocalizedString } from 'vs/platform/actions/common/actions';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { ContextKeyExpr, IContextKeyService, IContextKeyChangeEvent } from 'vs/platform/contextkey/common/contextkey';
@@ -27,24 +27,24 @@ export class MenuService implements IMenuService {
type MenuItemGroup = [string, Array<IMenuItem | ISubmenuItem>];
class Menu extends Disposable implements IMenu {
class Menu implements IMenu {
private readonly _onDidChange = this._register(new Emitter<IMenu | undefined>());
private readonly _onDidChange = new Emitter<IMenu | undefined>();
private readonly _dispoables = new DisposableStore();
private _menuGroups!: MenuItemGroup[];
private _contextKeys!: Set<string>;
private _menuGroups: MenuItemGroup[] = [];
private _contextKeys: Set<string> = new Set();
constructor(
private readonly _id: MenuId,
@ICommandService private readonly _commandService: ICommandService,
@IContextKeyService private readonly _contextKeyService: IContextKeyService
) {
super();
this._build();
// rebuild this menu whenever the menu registry reports an
// event for this MenuId
this._register(Event.debounce(
this._dispoables.add(Event.debounce(
Event.filter(MenuRegistry.onDidChangeMenu, menuId => menuId === this._id),
() => { },
50
@@ -52,18 +52,23 @@ class Menu extends Disposable implements IMenu {
// when context keys change we need to check if the menu also
// has changed
this._register(Event.debounce<IContextKeyChangeEvent, boolean>(
this._dispoables.add(Event.debounce<IContextKeyChangeEvent, boolean>(
this._contextKeyService.onDidChangeContext,
(last, event) => last || event.affectsSome(this._contextKeys),
50
)(e => e && this._onDidChange.fire(undefined), this));
}
dispose(): void {
this._dispoables.dispose();
this._onDidChange.dispose();
}
private _build(): void {
// reset
this._menuGroups = [];
this._contextKeys = new Set();
this._menuGroups.length = 0;
this._contextKeys.clear();
const menuItems = MenuRegistry.getMenuItems(this._id);
@@ -106,7 +111,10 @@ class Menu extends Disposable implements IMenu {
const activeActions: Array<MenuItemAction | SubmenuItemAction> = [];
for (const item of items) {
if (this._contextKeyService.contextMatchesRules(item.when)) {
const action = isIMenuItem(item) ? new MenuItemAction(item.command, item.alt, options, this._contextKeyService, this._commandService) : new SubmenuItemAction(item);
const action = isIMenuItem(item)
? new MenuItemAction(item.command, item.alt, options, this._contextKeyService, this._commandService)
: new SubmenuItemAction(item);
activeActions.push(action);
}
}
@@ -125,7 +133,7 @@ class Menu extends Disposable implements IMenu {
}
}
private static _compareMenuItems(a: IMenuItem, b: IMenuItem): number {
private static _compareMenuItems(a: IMenuItem | ISubmenuItem, b: IMenuItem | ISubmenuItem): number {
let aGroup = a.group;
let bGroup = b.group;
@@ -163,8 +171,15 @@ class Menu extends Disposable implements IMenu {
}
// sort on titles
const aTitle = typeof a.command.title === 'string' ? a.command.title : a.command.title.value;
const bTitle = typeof b.command.title === 'string' ? b.command.title : b.command.title.value;
return aTitle.localeCompare(bTitle);
return Menu._compareTitles(
isIMenuItem(a) ? a.command.title : a.title,
isIMenuItem(b) ? b.command.title : b.title
);
}
private static _compareTitles(a: string | ILocalizedString, b: string | ILocalizedString) {
const aStr = typeof a === 'string' ? a : a.value;
const bStr = typeof b === 'string' ? b : b.value;
return aStr.localeCompare(bStr);
}
}