VS Code merge to df8fe74bd55313de0dd2303bc47a4aab0ca56b0e (#17979)

* Merge from vscode 504f934659740e9d41501cad9f162b54d7745ad9

* delete unused folders

* distro

* Bump build node version

* update chokidar

* FIx hygiene errors

* distro

* Fix extension lint issues

* Remove strict-vscode

* Add copyright header exemptions

* Bump vscode-extension-telemetry to fix webpacking issue with zone.js

* distro

* Fix failing tests (revert marked.js back to current one until we decide to update)

* Skip searchmodel test

* Fix mac build

* temp debug script loading

* Try disabling coverage

* log error too

* Revert "log error too"

This reverts commit af0183e5d4ab458fdf44b88fbfab9908d090526f.

* Revert "temp debug script loading"

This reverts commit 3d687d541c76db2c5b55626c78ae448d3c25089c.

* Add comments explaining coverage disabling

* Fix ansi_up loading issue

* Merge latest from ads

* Use newer option

* Fix compile

* add debug logging warn

* Always log stack

* log more

* undo debug

* Update to use correct base path (+cleanup)

* distro

* fix compile errors

* Remove strict-vscode

* Fix sql editors not showing

* Show db dropdown input & fix styling

* Fix more info in gallery

* Fix gallery asset requests

* Delete unused workflow

* Fix tapable resolutions for smoke test compile error

* Fix smoke compile

* Disable crash reporting

* Disable interactive

Co-authored-by: ADS Merger <karlb@microsoft.com>
This commit is contained in:
Charles Gagnon
2022-01-06 09:06:56 -08:00
committed by GitHub
parent fd2736b6a6
commit 2bc6a0cd01
2099 changed files with 79520 additions and 43813 deletions

View File

@@ -3,19 +3,19 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./actionbar';
import * as platform from 'vs/base/common/platform';
import * as nls from 'vs/nls';
import { Disposable } from 'vs/base/common/lifecycle';
import { SelectBox, ISelectOptionItem, ISelectBoxOptions } from 'vs/base/browser/ui/selectBox/selectBox';
import { IAction, IActionRunner, Action, IActionChangeEvent, ActionRunner, Separator } from 'vs/base/common/actions';
import * as types from 'vs/base/common/types';
import { EventType as TouchEventType, Gesture } from 'vs/base/browser/touch';
import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
import { DataTransfers } from 'vs/base/browser/dnd';
import { isFirefox } from 'vs/base/browser/browser';
import { DataTransfers } from 'vs/base/browser/dnd';
import { $, addDisposableListener, append, EventHelper, EventLike, EventType } from 'vs/base/browser/dom';
import { EventType as TouchEventType, Gesture } from 'vs/base/browser/touch';
import { IActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
import { ISelectBoxOptions, ISelectOptionItem, SelectBox } from 'vs/base/browser/ui/selectBox/selectBox';
import { Action, ActionRunner, IAction, IActionChangeEvent, IActionRunner, Separator } from 'vs/base/common/actions';
import { Disposable } from 'vs/base/common/lifecycle';
import * as platform from 'vs/base/common/platform';
import * as types from 'vs/base/common/types';
import 'vs/css!./actionbar';
import * as nls from 'vs/nls';
export interface IBaseActionViewItemOptions {
draggable?: boolean;
@@ -30,6 +30,10 @@ export class BaseActionViewItem extends Disposable implements IActionViewItem {
_context: unknown;
_action: IAction;
get action() {
return this._action;
}
private _actionRunner: IActionRunner | undefined;
constructor(context: unknown, action: IAction, protected options: IBaseActionViewItemOptions = {}) {
@@ -117,7 +121,7 @@ export class BaseActionViewItem extends Disposable implements IActionViewItem {
}
}
this._register(addDisposableListener(element, TouchEventType.Tap, e => this.onClick(e)));
this._register(addDisposableListener(element, TouchEventType.Tap, e => this.onClick(e, true))); // Preserve focus on tap #125470
this._register(addDisposableListener(element, EventType.MOUSE_DOWN, e => {
if (!enableDragging) {
@@ -162,10 +166,10 @@ export class BaseActionViewItem extends Disposable implements IActionViewItem {
});
}
onClick(event: EventLike): void {
onClick(event: EventLike, preserveFocus = false): void {
EventHelper.stop(event, true);
const context = types.isUndefinedOrNull(this._context) ? this.options?.useEventAsContext ? event : undefined : this._context;
const context = types.isUndefinedOrNull(this._context) ? this.options?.useEventAsContext ? event : { preserveFocus } : this._context;
this.actionRunner.run(this._action, context);
}

View File

@@ -3,17 +3,18 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./actionbar';
import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle';
import { IAction, IActionRunner, ActionRunner, IRunEvent, Separator } from 'vs/base/common/actions';
import * as DOM from 'vs/base/browser/dom';
import * as types from 'vs/base/common/types';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { ActionViewItem, BaseActionViewItem, IActionViewItemOptions } from 'vs/base/browser/ui/actionbar/actionViewItems';
import { ActionRunner, IAction, IActionRunner, IRunEvent, Separator } from 'vs/base/common/actions';
import { Emitter } from 'vs/base/common/event';
import { IActionViewItemOptions, ActionViewItem, BaseActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle';
import * as types from 'vs/base/common/types';
import 'vs/css!./actionbar';
export interface IActionViewItem extends IDisposable {
action: IAction;
actionRunner: IActionRunner;
setActionContext(context: unknown): void;
render(element: HTMLElement): void;
@@ -292,6 +293,10 @@ export class ActionBar extends Disposable implements IActionRunner {
return this._actionIds.includes(action.id);
}
getAction(index: number): IAction {
return this.viewItems[index].action;
}
push(arg: IAction | ReadonlyArray<IAction>, options: IActionOptions = {}): void {
const actions: ReadonlyArray<IAction> = Array.isArray(arg) ? arg : [arg];

View File

@@ -3,9 +3,9 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./aria';
import { isMacintosh } from 'vs/base/common/platform';
import * as dom from 'vs/base/browser/dom';
import { isMacintosh } from 'vs/base/common/platform';
import 'vs/css!./aria';
// Use a max length since we are inserting the whole msg in the DOM and that can cause browsers to freeze for long messages #94233
const MAX_MESSAGE_LENGTH = 20000;

View File

@@ -7,11 +7,11 @@ import * as dom from 'vs/base/browser/dom';
import { IMouseEvent } from 'vs/base/browser/mouseEvent';
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
import { commonPrefixLength } from 'vs/base/common/arrays';
import { Codicon, registerCodicon } from 'vs/base/common/codicons';
import { Color } from 'vs/base/common/color';
import { Emitter, Event } from 'vs/base/common/event';
import { dispose, IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { DisposableStore, dispose, IDisposable } from 'vs/base/common/lifecycle';
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
import { Codicon, registerCodicon } from 'vs/base/common/codicons';
import 'vs/css!./breadcrumbsWidget';
export abstract class BreadcrumbsItem {

View File

@@ -3,19 +3,19 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./button';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { Color } from 'vs/base/common/color';
import { mixin } from 'vs/base/common/objects';
import { Event as BaseEvent, Emitter } from 'vs/base/common/event';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { Gesture, EventType as TouchEventType } from 'vs/base/browser/touch';
import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels';
import { addDisposableListener, IFocusTracker, EventType, EventHelper, trackFocus, reset, removeTabIndexAndUpdateFocus } from 'vs/base/browser/dom'; // {{SQL CARBON EDIT}}
import { IContextMenuProvider } from 'vs/base/browser/contextmenu';
import { addDisposableListener, EventHelper, EventType, IFocusTracker, removeTabIndexAndUpdateFocus, reset, trackFocus } from 'vs/base/browser/dom'; // {{SQL CARBON EDIT}} Add removeTabIndexAndUpdateFocus
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { EventType as TouchEventType, Gesture } from 'vs/base/browser/touch';
import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels';
import { Action, IAction, IActionRunner } from 'vs/base/common/actions';
import { CSSIcon, Codicon } from 'vs/base/common/codicons';
import { Codicon, CSSIcon } from 'vs/base/common/codicons';
import { Color } from 'vs/base/common/color';
import { Emitter, Event as BaseEvent } from 'vs/base/common/event';
import { KeyCode } from 'vs/base/common/keyCodes';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { mixin } from 'vs/base/common/objects';
import 'vs/css!./button';
export interface IButtonOptions extends IButtonStyles {
readonly title?: boolean | string;

View File

@@ -3,13 +3,13 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { SplitView, Orientation, ISplitViewStyles, IView as ISplitViewView } from 'vs/base/browser/ui/splitview/splitview';
import { $ } from 'vs/base/browser/dom';
import { Event } from 'vs/base/common/event';
import { IView, IViewSize } from 'vs/base/browser/ui/grid/grid';
import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { Color } from 'vs/base/common/color';
import { IBoundarySashes } from 'vs/base/browser/ui/grid/gridview';
import { ISplitViewStyles, IView as ISplitViewView, Orientation, SplitView } from 'vs/base/browser/ui/splitview/splitview';
import { Color } from 'vs/base/common/color';
import { Event } from 'vs/base/common/event';
import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
export interface CenteredViewState {
leftMarginRatio: number;

View File

@@ -3,15 +3,15 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./checkbox';
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { BaseActionViewItem, IActionViewItemOptions } from 'vs/base/browser/ui/actionbar/actionViewItems';
import { Widget } from 'vs/base/browser/ui/widget';
import { IAction } from 'vs/base/common/actions';
import { Codicon, CSSIcon } from 'vs/base/common/codicons';
import { Color } from 'vs/base/common/color';
import { Emitter, Event } from 'vs/base/common/event';
import { KeyCode } from 'vs/base/common/keyCodes';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { Codicon, CSSIcon } from 'vs/base/common/codicons';
import { BaseActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
import 'vs/css!./checkbox';
export interface ICheckboxOpts extends ICheckboxStyles {
readonly actionClassName?: string;
@@ -41,21 +41,21 @@ const defaultOpts = {
export class CheckboxActionViewItem extends BaseActionViewItem {
protected checkbox: Checkbox | undefined;
protected readonly disposables = new DisposableStore();
protected readonly checkbox: Checkbox;
constructor(context: any, action: IAction, options: IActionViewItemOptions | undefined) {
super(context, action, options);
this.checkbox = this._register(new Checkbox({
actionClassName: this._action.class,
isChecked: this._action.checked,
title: (<IActionViewItemOptions>this.options).keybinding ? `${this._action.label} (${(<IActionViewItemOptions>this.options).keybinding})` : this._action.label,
notFocusable: true
}));
this._register(this.checkbox.onChange(() => this._action.checked = !!this.checkbox && this.checkbox.checked));
}
override render(container: HTMLElement): void {
this.element = container;
this.disposables.clear();
this.checkbox = new Checkbox({
actionClassName: this._action.class,
isChecked: this._action.checked,
title: this._action.label,
notFocusable: true
});
this.disposables.add(this.checkbox);
this.disposables.add(this.checkbox.onChange(() => this._action.checked = !!this.checkbox && this.checkbox.checked, this));
this.element.appendChild(this.checkbox.domNode);
}
@@ -70,35 +70,23 @@ export class CheckboxActionViewItem extends BaseActionViewItem {
}
override updateChecked(): void {
if (this.checkbox) {
this.checkbox.checked = this._action.checked;
}
this.checkbox.checked = this._action.checked;
}
override focus(): void {
if (this.checkbox) {
this.checkbox.domNode.tabIndex = 0;
this.checkbox.focus();
}
this.checkbox.domNode.tabIndex = 0;
this.checkbox.focus();
}
override blur(): void {
if (this.checkbox) {
this.checkbox.domNode.tabIndex = -1;
this.checkbox.domNode.blur();
}
this.checkbox.domNode.tabIndex = -1;
this.checkbox.domNode.blur();
}
override setFocusable(focusable: boolean): void {
if (this.checkbox) {
this.checkbox.domNode.tabIndex = focusable ? 0 : -1;
}
this.checkbox.domNode.tabIndex = focusable ? 0 : -1;
}
override dispose(): void {
this.disposables.dispose();
super.dispose();
}
}
export class Checkbox extends Widget {
@@ -185,7 +173,7 @@ export class Checkbox extends Widget {
}
width(): number {
return 2 /*marginleft*/ + 2 /*border*/ + 2 /*padding*/ + 16 /* icon width */;
return 2 /*margin left*/ + 2 /*border*/ + 2 /*padding*/ + 16 /* icon width */;
}
style(styles: ICheckboxStyles): void {
@@ -216,6 +204,7 @@ export class Checkbox extends Widget {
disable(): void {
this.domNode.setAttribute('aria-disabled', String(true));
}
}
export class SimpleCheckbox extends Widget {

View File

@@ -3,10 +3,10 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Codicon } from 'vs/base/common/codicons';
import 'vs/css!./codicon/codicon';
import 'vs/css!./codicon/codicon-modifiers';
import { Codicon } from 'vs/base/common/codicons';
export function formatRule(c: Codicon) {
let def = c.definition;

View File

@@ -3,12 +3,12 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./contextview';
import * as DOM from 'vs/base/browser/dom';
import * as platform from 'vs/base/common/platform';
import { IDisposable, toDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { Range } from 'vs/base/common/range';
import { BrowserFeatures } from 'vs/base/browser/canIUse';
import * as DOM from 'vs/base/browser/dom';
import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import * as platform from 'vs/base/common/platform';
import { Range } from 'vs/base/common/range';
import 'vs/css!./contextview';
export const enum ContextViewDOMPosition {
ABSOLUTE = 1,

View File

@@ -3,12 +3,12 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./countBadge';
import { $, append } from 'vs/base/browser/dom';
import { format } from 'vs/base/common/strings';
import { Color } from 'vs/base/common/color';
import { mixin } from 'vs/base/common/objects';
import { format } from 'vs/base/common/strings';
import { IThemable } from 'vs/base/common/styler';
import 'vs/css!./countBadge';
export interface ICountBadgeOptions extends ICountBadgetyles {
count?: number;

View File

@@ -118,6 +118,11 @@
flex: 1;
}
/** Dialog: File Path */
.monaco-dialog-box code {
font-family: var(--monaco-monospace-font);
}
/** Dialog: Buttons Row */
.monaco-dialog-box > .dialog-buttons-row {
display: flex;

View File

@@ -3,22 +3,21 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { $, addDisposableListener, clearNode, EventHelper, EventType, hide, isAncestor, show } from 'vs/base/browser/dom';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { ButtonBar, ButtonWithDescription, IButtonStyles } from 'vs/base/browser/ui/button/button';
import { ISimpleCheckboxStyles, SimpleCheckbox } from 'vs/base/browser/ui/checkbox/checkbox';
import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox';
import { Action } from 'vs/base/common/actions';
import { Codicon, registerCodicon } from 'vs/base/common/codicons';
import { Color } from 'vs/base/common/color';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { mnemonicButtonLabel } from 'vs/base/common/labels';
import { Disposable } from 'vs/base/common/lifecycle';
import { isLinux, isMacintosh } from 'vs/base/common/platform';
import 'vs/css!./dialog';
import * as nls from 'vs/nls';
import { Disposable } from 'vs/base/common/lifecycle';
import { $, hide, show, EventHelper, clearNode, isAncestor, addDisposableListener, EventType } from 'vs/base/browser/dom';
import { domEvent } from 'vs/base/browser/event';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { Color } from 'vs/base/common/color';
import { ButtonBar, ButtonWithDescription, IButtonStyles } from 'vs/base/browser/ui/button/button';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { Action } from 'vs/base/common/actions';
import { mnemonicButtonLabel } from 'vs/base/common/labels';
import { isMacintosh, isLinux } from 'vs/base/common/platform';
import { SimpleCheckbox, ISimpleCheckboxStyles } from 'vs/base/browser/ui/checkbox/checkbox';
import { Codicon, registerCodicon } from 'vs/base/common/codicons';
import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox';
export interface IDialogInputOptions {
readonly placeholder?: string;
@@ -94,6 +93,7 @@ export class Dialog extends Disposable {
this.shadowElement = this.modalElement.appendChild($('.dialog-shadow'));
this.element = this.shadowElement.appendChild($('.monaco-dialog-box'));
this.element.setAttribute('role', 'dialog');
this.element.tabIndex = -1;
hide(this.element);
this.buttons = Array.isArray(buttons) && buttons.length ? buttons : [nls.localize('ok', "OK")]; // If no button is provided, default to OK
@@ -219,8 +219,8 @@ export class Dialog extends Disposable {
}));
});
// Handle keyboard events gloably: Tab, Arrow-Left/Right
this._register(domEvent(window, 'keydown', true)((e: KeyboardEvent) => {
// Handle keyboard events globally: Tab, Arrow-Left/Right
this._register(addDisposableListener(window, 'keydown', e => {
const evt = new StandardKeyboardEvent(e);
if (evt.equals(KeyMod.Alt)) {
@@ -321,9 +321,9 @@ export class Dialog extends Disposable {
} else if (this.options.keyEventProcessor) {
this.options.keyEventProcessor(evt);
}
}));
}, true));
this._register(domEvent(window, 'keyup', true)((e: KeyboardEvent) => {
this._register(addDisposableListener(window, 'keyup', e => {
EventHelper.stop(e, true);
const evt = new StandardKeyboardEvent(e);
@@ -333,10 +333,10 @@ export class Dialog extends Disposable {
checkboxChecked: this.checkbox ? this.checkbox.checked : undefined
});
}
}));
}, true));
// Detect focus out
this._register(domEvent(this.element, 'focusout', false)((e: FocusEvent) => {
this._register(addDisposableListener(this.element, 'focusout', e => {
if (!!e.relatedTarget && !!this.element) {
if (!isAncestor(e.relatedTarget as HTMLElement, this.element)) {
this.focusToReturn = e.relatedTarget as HTMLElement;
@@ -347,7 +347,7 @@ export class Dialog extends Disposable {
}
}
}
}));
}, false));
const spinModifierClassName = 'codicon-modifier-spin';
@@ -391,7 +391,9 @@ export class Dialog extends Disposable {
this.applyStyles();
this.element.setAttribute('aria-labelledby', 'monaco-dialog-icon monaco-dialog-message-text monaco-dialog-message-detail monaco-dialog-message-body');
this.element.setAttribute('aria-modal', 'true');
this.element.setAttribute('aria-labelledby', 'monaco-dialog-icon monaco-dialog-message-text');
this.element.setAttribute('aria-describedby', 'monaco-dialog-icon monaco-dialog-message-text monaco-dialog-message-detail monaco-dialog-message-body');
show(this.element);
// Focus first element (input or button)
@@ -493,9 +495,9 @@ export class Dialog extends Disposable {
buttonMap.push({ label: button, index });
});
// macOS/linux: reverse button order
// macOS/linux: reverse button order if `cancelId` is defined
if (isMacintosh || isLinux) {
if (cancelId !== undefined) {
if (cancelId !== undefined && cancelId < buttons.length) {
const cancelButton = buttonMap.splice(cancelId, 1)[0];
buttonMap.reverse();
buttonMap.splice(buttonMap.length - 1, 0, cancelButton);

View File

@@ -35,7 +35,7 @@
padding-left: 0px;
padding-right: 0px;
line-height: 16px;
margin-left: -4px;
margin-left: -3px;
}
.monaco-dropdown-with-primary > .dropdown-action-container > .monaco-dropdown > .dropdown-label > .action-label {

View File

@@ -3,17 +3,17 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./dropdown';
import { Gesture, EventType as GestureEventType } from 'vs/base/browser/touch';
import { ActionRunner, IAction } from 'vs/base/common/actions';
import { IDisposable } from 'vs/base/common/lifecycle';
import { IContextViewProvider, IAnchor, AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
import { IMenuOptions } from 'vs/base/browser/ui/menu/menu';
import { KeyCode } from 'vs/base/common/keyCodes';
import { EventHelper, EventType, append, $, addDisposableListener, DOMEvent } from 'vs/base/browser/dom';
import { IContextMenuProvider } from 'vs/base/browser/contextmenu';
import { $, addDisposableListener, append, DOMEvent, EventHelper, EventType } from 'vs/base/browser/dom';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { EventType as GestureEventType, Gesture } from 'vs/base/browser/touch';
import { AnchorAlignment, IAnchor, IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
import { IMenuOptions } from 'vs/base/browser/ui/menu/menu';
import { ActionRunner, IAction } from 'vs/base/common/actions';
import { Emitter } from 'vs/base/common/event';
import { KeyCode } from 'vs/base/common/keyCodes';
import { IDisposable } from 'vs/base/common/lifecycle';
import 'vs/css!./dropdown';
export interface ILabelRenderer {
(container: HTMLElement): IDisposable | null;

View File

@@ -3,19 +3,19 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./dropdown';
import { Action, IAction, IActionRunner } from 'vs/base/common/actions';
import { IDisposable } from 'vs/base/common/lifecycle';
import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
import { KeyCode, ResolvedKeybinding } from 'vs/base/common/keyCodes';
import { append, $, addDisposableListener, EventType } from 'vs/base/browser/dom';
import { Emitter } from 'vs/base/common/event';
import { ActionViewItem, BaseActionViewItem, IActionViewItemOptions, IBaseActionViewItemOptions } from 'vs/base/browser/ui/actionbar/actionViewItems';
import { IActionProvider, DropdownMenu, IDropdownMenuOptions, ILabelRenderer } from 'vs/base/browser/ui/dropdown/dropdown';
import { IContextMenuProvider } from 'vs/base/browser/contextmenu';
import { Codicon } from 'vs/base/common/codicons';
import { IActionViewItemProvider } from 'vs/base/browser/ui/actionbar/actionbar';
import { $, addDisposableListener, append, EventType } from 'vs/base/browser/dom';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { IActionViewItemProvider } from 'vs/base/browser/ui/actionbar/actionbar';
import { ActionViewItem, BaseActionViewItem, IActionViewItemOptions, IBaseActionViewItemOptions } from 'vs/base/browser/ui/actionbar/actionViewItems';
import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
import { DropdownMenu, IActionProvider, IDropdownMenuOptions, ILabelRenderer } from 'vs/base/browser/ui/dropdown/dropdown';
import { Action, IAction, IActionRunner } from 'vs/base/common/actions';
import { Codicon } from 'vs/base/common/codicons';
import { Emitter } from 'vs/base/common/event';
import { KeyCode, ResolvedKeybinding } from 'vs/base/common/keyCodes';
import { IDisposable } from 'vs/base/common/lifecycle';
import 'vs/css!./dropdown';
export interface IKeybindingProvider {
(action: IAction): ResolvedKeybinding | undefined;

View File

@@ -3,20 +3,20 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./findInput';
import * as nls from 'vs/nls';
import * as dom from 'vs/base/browser/dom';
import { IMessage as InputBoxMessage, IInputValidator, IInputBoxStyles, HistoryInputBox } from 'vs/base/browser/ui/inputbox/inputBox';
import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
import { Widget } from 'vs/base/browser/ui/widget';
import { Event, Emitter } from 'vs/base/common/event';
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { IMouseEvent } from 'vs/base/browser/mouseEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { CaseSensitiveCheckbox, WholeWordsCheckbox, RegexCheckbox } from 'vs/base/browser/ui/findinput/findInputCheckboxes';
import { Color } from 'vs/base/common/color';
import { ICheckboxStyles } from 'vs/base/browser/ui/checkbox/checkbox';
import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
import { CaseSensitiveCheckbox, RegexCheckbox, WholeWordsCheckbox } from 'vs/base/browser/ui/findinput/findInputCheckboxes';
import { HistoryInputBox, IInputBoxStyles, IInputValidator, IMessage as InputBoxMessage } from 'vs/base/browser/ui/inputbox/inputBox';
import { Widget } from 'vs/base/browser/ui/widget';
import { Color } from 'vs/base/common/color';
import { Emitter, Event } from 'vs/base/common/event';
import { KeyCode } from 'vs/base/common/keyCodes';
import 'vs/css!./findInput';
import * as nls from 'vs/nls';
export interface IFindInputOptions extends IFindInputStyles {
readonly placeholder?: string;
@@ -50,6 +50,7 @@ export class FindInput extends Widget {
private validation?: IInputValidator;
private label: string;
private fixFocusOnOptionClickEnabled = true;
private imeSessionInProgress = false;
private inputActiveOptionBorder?: Color;
private inputActiveOptionForeground?: Color;
@@ -252,12 +253,24 @@ export class FindInput extends Widget {
parent.appendChild(this.domNode);
}
this._register(dom.addDisposableListener(this.inputBox.inputElement, 'compositionstart', (e: CompositionEvent) => {
this.imeSessionInProgress = true;
}));
this._register(dom.addDisposableListener(this.inputBox.inputElement, 'compositionend', (e: CompositionEvent) => {
this.imeSessionInProgress = false;
this._onInput.fire();
}));
this.onkeydown(this.inputBox.inputElement, (e) => this._onKeyDown.fire(e));
this.onkeyup(this.inputBox.inputElement, (e) => this._onKeyUp.fire(e));
this.oninput(this.inputBox.inputElement, (e) => this._onInput.fire());
this.onmousedown(this.inputBox.inputElement, (e) => this._onMouseDown.fire(e));
}
public get isImeSessionInProgress(): boolean {
return this.imeSessionInProgress;
}
public get onDidChange(): Event<string> {
return this.inputBox.onDidChange;
}

View File

@@ -4,9 +4,9 @@
*--------------------------------------------------------------------------------------------*/
import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox';
import { Codicon } from 'vs/base/common/codicons';
import { Color } from 'vs/base/common/color';
import * as nls from 'vs/nls';
import { Codicon } from 'vs/base/common/codicons';
export interface IFindInputCheckboxOpts {
readonly appendTitle: string;

View File

@@ -3,21 +3,21 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./findInput';
import * as nls from 'vs/nls';
import * as dom from 'vs/base/browser/dom';
import { IMessage as InputBoxMessage, IInputValidator, IInputBoxStyles, HistoryInputBox } from 'vs/base/browser/ui/inputbox/inputBox';
import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
import { Widget } from 'vs/base/browser/ui/widget';
import { Event, Emitter } from 'vs/base/common/event';
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { IMouseEvent } from 'vs/base/browser/mouseEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { Color } from 'vs/base/common/color';
import { ICheckboxStyles, Checkbox } from 'vs/base/browser/ui/checkbox/checkbox';
import { Checkbox, ICheckboxStyles } from 'vs/base/browser/ui/checkbox/checkbox';
import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
import { IFindInputCheckboxOpts } from 'vs/base/browser/ui/findinput/findInputCheckboxes';
import { HistoryInputBox, IInputBoxStyles, IInputValidator, IMessage as InputBoxMessage } from 'vs/base/browser/ui/inputbox/inputBox';
import { Widget } from 'vs/base/browser/ui/widget';
import { Codicon } from 'vs/base/common/codicons';
import { Color } from 'vs/base/common/color';
import { Emitter, Event } from 'vs/base/common/event';
import { KeyCode } from 'vs/base/common/keyCodes';
import 'vs/css!./findInput';
import * as nls from 'vs/nls';
export interface IReplaceInputOptions extends IReplaceInputStyles {
readonly placeholder?: string;

View File

@@ -3,14 +3,14 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./gridview';
import { Orientation } from 'vs/base/browser/ui/sash/sash';
import { Disposable } from 'vs/base/common/lifecycle';
import { tail2 as tail, equals } from 'vs/base/common/arrays';
import { orthogonal, IView as IGridViewView, GridView, Sizing as GridViewSizing, Box, IGridViewStyles, IViewSize, IGridViewOptions, IBoundarySashes } from './gridview';
import { equals, tail2 as tail } from 'vs/base/common/arrays';
import { Event } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import 'vs/css!./gridview';
import { Box, GridView, IBoundarySashes, IGridViewOptions, IGridViewStyles, IView as IGridViewView, IViewSize, orthogonal, Sizing as GridViewSizing } from './gridview';
export { Orientation, IViewSize, orthogonal, LayoutPriority } from './gridview';
export { IViewSize, LayoutPriority, Orientation, orthogonal } from './gridview';
export const enum Direction {
Up,

View File

@@ -3,19 +3,19 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./gridview';
import { Event, Emitter, Relay } from 'vs/base/common/event';
import { Orientation, Sash } from 'vs/base/browser/ui/sash/sash';
import { SplitView, IView as ISplitView, Sizing, LayoutPriority, ISplitViewStyles } from 'vs/base/browser/ui/splitview/splitview';
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { $ } from 'vs/base/browser/dom';
import { Orientation, Sash } from 'vs/base/browser/ui/sash/sash';
import { ISplitViewStyles, IView as ISplitView, LayoutPriority, Sizing, SplitView } from 'vs/base/browser/ui/splitview/splitview';
import { equals as arrayEquals, tail2 as tail } from 'vs/base/common/arrays';
import { Color } from 'vs/base/common/color';
import { Emitter, Event, Relay } from 'vs/base/common/event';
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { clamp } from 'vs/base/common/numbers';
import { isUndefined } from 'vs/base/common/types';
import 'vs/css!./gridview';
export { Sizing, LayoutPriority } from 'vs/base/browser/ui/splitview/splitview';
export { Orientation } from 'vs/base/browser/ui/sash/sash';
export { LayoutPriority, Sizing } from 'vs/base/browser/ui/splitview/splitview';
export interface IViewSize {
readonly width: number;

View File

@@ -3,9 +3,9 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as objects from 'vs/base/common/objects';
import * as dom from 'vs/base/browser/dom';
import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels';
import * as objects from 'vs/base/common/objects';
export interface IHighlight {
start: number;

View File

@@ -116,16 +116,19 @@
vertical-align: middle;
}
.monaco-hover .hover-contents a.code-link:hover,
.monaco-hover .hover-contents a.code-link {
color: inherit;
}
.monaco-hover .hover-contents a.code-link:before {
content: '(';
}
.monaco-hover .hover-contents a.code-link:after {
content: ')';
}
.monaco-hover .hover-contents a.code-link {
color: inherit;
}
.monaco-hover .hover-contents a.code-link > span {
text-decoration: underline;
/** Hack to force underline to show **/
@@ -143,3 +146,9 @@
-webkit-user-select: none;
user-select: none;
}
.monaco-hover-content .action-container.disabled {
pointer-events: none;
opacity: 0.4;
cursor: default;
}

View File

@@ -3,10 +3,10 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./hover';
import * as dom from 'vs/base/browser/dom';
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
import { Disposable } from 'vs/base/common/lifecycle';
import 'vs/css!./hover';
const $ = dom.$;
@@ -42,19 +42,43 @@ export class HoverWidget extends Disposable {
}
}
export function renderHoverAction(parent: HTMLElement, actionOptions: { label: string, iconClass?: string, run: (target: HTMLElement) => void, commandId: string }, keybindingLabel: string | null): IDisposable {
const actionContainer = dom.append(parent, $('div.action-container'));
const action = dom.append(actionContainer, $('a.action'));
action.setAttribute('href', '#');
action.setAttribute('role', 'button');
if (actionOptions.iconClass) {
dom.append(action, $(`span.icon.${actionOptions.iconClass}`));
export class HoverAction extends Disposable {
public static render(parent: HTMLElement, actionOptions: { label: string, iconClass?: string, run: (target: HTMLElement) => void, commandId: string }, keybindingLabel: string | null) {
return new HoverAction(parent, actionOptions, keybindingLabel);
}
private readonly actionContainer: HTMLElement;
private readonly action: HTMLElement;
private constructor(parent: HTMLElement, actionOptions: { label: string, iconClass?: string, run: (target: HTMLElement) => void, commandId: string }, keybindingLabel: string | null) {
super();
this.actionContainer = dom.append(parent, $('div.action-container'));
this.action = dom.append(this.actionContainer, $('a.action'));
this.action.setAttribute('href', '#');
this.action.setAttribute('role', 'button');
if (actionOptions.iconClass) {
dom.append(this.action, $(`span.icon.${actionOptions.iconClass}`));
}
const label = dom.append(this.action, $('span'));
label.textContent = keybindingLabel ? `${actionOptions.label} (${keybindingLabel})` : actionOptions.label;
this._register(dom.addDisposableListener(this.actionContainer, dom.EventType.CLICK, e => {
e.stopPropagation();
e.preventDefault();
actionOptions.run(this.actionContainer);
}));
this.setEnabled(true);
}
public setEnabled(enabled: boolean): void {
if (enabled) {
this.actionContainer.classList.remove('disabled');
this.actionContainer.removeAttribute('aria-disabled');
} else {
this.actionContainer.classList.add('disabled');
this.actionContainer.setAttribute('aria-disabled', 'true');
}
}
const label = dom.append(action, $('span'));
label.textContent = keybindingLabel ? `${actionOptions.label} (${keybindingLabel})` : actionOptions.label;
return dom.addDisposableListener(actionContainer, dom.EventType.CLICK, e => {
e.stopPropagation();
e.preventDefault();
actionOptions.run(actionContainer);
});
}

View File

@@ -13,7 +13,7 @@ export interface IHoverDelegateTarget extends IDisposable {
}
export interface IHoverDelegateOptions {
text: IMarkdownString | string;
content: IMarkdownString | string | HTMLElement;
target: IHoverDelegateTarget | HTMLElement;
hoverPosition?: HoverPosition;
showPointer?: boolean;

View File

@@ -3,17 +3,17 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./iconlabel';
import * as dom from 'vs/base/browser/dom';
import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
import { IMatch } from 'vs/base/common/filters';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { Range } from 'vs/base/common/range';
import { equals } from 'vs/base/common/objects';
import { IHoverDelegate } from 'vs/base/browser/ui/iconLabel/iconHoverDelegate';
import { IMarkdownString } from 'vs/base/common/htmlContent';
import { CancellationToken } from 'vs/base/common/cancellation';
import { setupCustomHover, setupNativeHover } from 'vs/base/browser/ui/iconLabel/iconLabelHover';
import { CancellationToken } from 'vs/base/common/cancellation';
import { IMatch } from 'vs/base/common/filters';
import { IMarkdownString } from 'vs/base/common/htmlContent';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { equals } from 'vs/base/common/objects';
import { Range } from 'vs/base/common/range';
import 'vs/css!./iconlabel';
export interface IIconLabelCreationOptions {
supportHighlights?: boolean;

View File

@@ -3,16 +3,16 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { isFunction, isString } from 'vs/base/common/types';
import * as dom from 'vs/base/browser/dom';
import { IIconLabelMarkdownString } from 'vs/base/browser/ui/iconLabel/iconLabel';
import { IHoverDelegate, IHoverDelegateOptions, IHoverDelegateTarget } from 'vs/base/browser/ui/iconLabel/iconHoverDelegate';
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
import { IDisposable } from 'vs/base/common/lifecycle';
import { DomEmitter } from 'vs/base/browser/event';
import { HoverPosition } from 'vs/base/browser/ui/hover/hoverWidget';
import { localize } from 'vs/nls';
import { IHoverDelegate, IHoverDelegateTarget } from 'vs/base/browser/ui/iconLabel/iconHoverDelegate';
import { IIconLabelMarkdownString } from 'vs/base/browser/ui/iconLabel/iconLabel';
import { RunOnceScheduler } from 'vs/base/common/async';
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
import { IMarkdownString } from 'vs/base/common/htmlContent';
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { isFunction, isString } from 'vs/base/common/types';
import { localize } from 'vs/nls';
export function setupNativeHover(htmlElement: HTMLElement, tooltip: string | IIconLabelMarkdownString | undefined): void {
@@ -32,79 +32,90 @@ export function setupCustomHover(hoverDelegate: IHoverDelegate, htmlElement: HTM
const tooltip = getTooltipForCustom(markdownTooltip);
let hoverOptions: IHoverDelegateOptions | undefined;
let mouseX: number | undefined;
let isHovering = false;
let tokenSource: CancellationTokenSource;
let hoverDisposable: IDisposable | undefined;
let hoverPreparation: IDisposable | undefined;
const mouseOverDomEmitter = new DomEmitter(htmlElement, dom.EventType.MOUSE_OVER, true);
mouseOverDomEmitter.event((e: MouseEvent) => {
if (isHovering) {
let hoverWidget: IDisposable | undefined;
const mouseEnter = (e: MouseEvent) => {
if (hoverPreparation) {
return;
}
tokenSource = new CancellationTokenSource();
function mouseLeaveOrDown(e: MouseEvent): void {
const tokenSource = new CancellationTokenSource();
const mouseLeaveOrDown = (e: MouseEvent) => {
const isMouseDown = e.type === dom.EventType.MOUSE_DOWN;
if (isMouseDown) {
hoverDisposable?.dispose();
hoverDisposable = undefined;
hoverWidget?.dispose();
hoverWidget = undefined;
}
if (isMouseDown || (<any>e).fromElement === htmlElement) {
isHovering = false;
hoverOptions = undefined;
tokenSource.dispose(true);
mouseLeaveDomEmitter.dispose();
mouseDownDomEmitter.dispose();
hoverPreparation?.dispose();
hoverPreparation = undefined;
}
}
const mouseLeaveDomEmitter = new DomEmitter(htmlElement, dom.EventType.MOUSE_LEAVE, true);
mouseLeaveDomEmitter.event(mouseLeaveOrDown);
const mouseDownDomEmitter = new DomEmitter(htmlElement, dom.EventType.MOUSE_DOWN, true);
mouseDownDomEmitter.event(mouseLeaveOrDown);
isHovering = true;
};
const mouseLeaveDomListener = dom.addDisposableListener(htmlElement, dom.EventType.MOUSE_LEAVE, mouseLeaveOrDown, true);
const mouseDownDownListener = dom.addDisposableListener(htmlElement, dom.EventType.MOUSE_DOWN, mouseLeaveOrDown, true);
function mouseMove(e: MouseEvent): void {
mouseX = e.x;
const target: IHoverDelegateTarget = {
targetElements: [htmlElement],
dispose: () => { }
};
let mouseMoveDomListener: IDisposable | undefined;
if (hoverDelegate.placement === undefined || hoverDelegate.placement === 'mouse') {
const mouseMove = (e: MouseEvent) => target.x = e.x + 10;
mouseMoveDomListener = dom.addDisposableListener(htmlElement, dom.EventType.MOUSE_MOVE, mouseMove, true);
}
const mouseMoveDomEmitter = new DomEmitter(htmlElement, dom.EventType.MOUSE_MOVE, true);
mouseMoveDomEmitter.event(mouseMove);
setTimeout(async () => {
if (isHovering && tooltip) {
// Re-use the already computed hover options if they exist.
if (!hoverOptions) {
const target: IHoverDelegateTarget = {
targetElements: [htmlElement],
dispose: () => { }
};
hoverOptions = {
text: localize('iconLabel.loading', "Loading..."),
const showHover = async () => {
if (hoverPreparation) {
const hoverOptions = {
content: localize('iconLabel.loading', "Loading..."),
target,
hoverPosition: HoverPosition.BELOW
};
hoverWidget?.dispose();
hoverWidget = hoverDelegate.showHover(hoverOptions);
const resolvedTooltip = (await tooltip(tokenSource.token)) ?? (!isString(markdownTooltip) ? markdownTooltip.markdownNotSupportedFallback : undefined);
hoverWidget?.dispose();
hoverWidget = undefined;
// awaiting the tooltip could take a while. Make sure we're still preparing to hover.
if (resolvedTooltip && hoverPreparation) {
const hoverOptions = {
content: resolvedTooltip,
target,
showPointer: hoverDelegate.placement === 'element',
hoverPosition: HoverPosition.BELOW
};
hoverDisposable = adjustXAndShowCustomHover(hoverOptions, mouseX, hoverDelegate, isHovering);
const resolvedTooltip = (await tooltip(tokenSource.token)) ?? (!isString(markdownTooltip) ? markdownTooltip.markdownNotSupportedFallback : undefined);
if (resolvedTooltip) {
hoverOptions = {
text: resolvedTooltip,
target,
showPointer: hoverDelegate.placement === 'element',
hoverPosition: HoverPosition.BELOW
};
// awaiting the tooltip could take a while. Make sure we're still hovering.
hoverDisposable = adjustXAndShowCustomHover(hoverOptions, mouseX, hoverDelegate, isHovering);
} else if (hoverDisposable) {
hoverDisposable.dispose();
hoverDisposable = undefined;
}
hoverWidget = hoverDelegate.showHover(hoverOptions);
}
}
mouseMoveDomEmitter.dispose();
}, hoverDelegate.delay);
mouseMoveDomListener?.dispose();
};
const timeout = new RunOnceScheduler(showHover, hoverDelegate.delay);
timeout.schedule();
hoverPreparation = toDisposable(() => {
timeout.dispose();
mouseMoveDomListener?.dispose();
mouseDownDownListener.dispose();
mouseLeaveDomListener.dispose();
tokenSource.dispose(true);
});
};
const mouseOverDomEmitter = dom.addDisposableListener(htmlElement, dom.EventType.MOUSE_OVER, mouseEnter, true);
return toDisposable(() => {
mouseOverDomEmitter.dispose();
hoverPreparation?.dispose();
hoverWidget?.dispose();
});
return mouseOverDomEmitter;
}
@@ -118,13 +129,3 @@ function getTooltipForCustom(markdownTooltip: string | IIconLabelMarkdownString)
return async () => markdown;
}
}
function adjustXAndShowCustomHover(hoverOptions: IHoverDelegateOptions | undefined, mouseX: number | undefined, hoverDelegate: IHoverDelegate, isHovering: boolean): IDisposable | undefined {
if (hoverOptions && isHovering) {
if (mouseX !== undefined && (hoverDelegate.placement === undefined || hoverDelegate.placement === 'mouse')) {
(<IHoverDelegateTarget>hoverOptions.target).x = mouseX + 10;
}
return hoverDelegate.showHover(hoverOptions);
}
return undefined;
}

View File

@@ -87,7 +87,7 @@
opacity: 0.75;
font-size: 90%;
font-weight: 600;
padding: 0 16px 0 5px;
margin: 0 16px 0 5px;
text-align: center;
}

View File

@@ -3,30 +3,31 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./inputBox';
import * as nls from 'vs/nls';
import * as dom from 'vs/base/browser/dom';
import { MarkdownRenderOptions } from 'vs/base/browser/markdownRenderer';
import { DomEmitter } from 'vs/base/browser/event';
import { renderFormattedText, renderText } from 'vs/base/browser/formattedTextRenderer';
import * as aria from 'vs/base/browser/ui/aria/aria';
import { IAction } from 'vs/base/common/actions';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { IContextViewProvider, AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
import { Event, Emitter } from 'vs/base/common/event';
import { Widget } from 'vs/base/browser/ui/widget';
import { Color } from 'vs/base/common/color';
import { mixin } from 'vs/base/common/objects';
import { HistoryNavigator } from 'vs/base/common/history';
import { IHistoryNavigationWidget } from 'vs/base/browser/history';
import { MarkdownRenderOptions } from 'vs/base/browser/markdownRenderer';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import * as aria from 'vs/base/browser/ui/aria/aria';
import { AnchorAlignment, IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
import { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
import { Widget } from 'vs/base/browser/ui/widget';
import { IAction } from 'vs/base/common/actions';
import { Color } from 'vs/base/common/color';
import { Emitter, Event } from 'vs/base/common/event';
import { HistoryNavigator } from 'vs/base/common/history';
import { mixin } from 'vs/base/common/objects';
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
import { domEvent } from 'vs/base/browser/event';
import 'vs/css!./inputBox';
import * as nls from 'vs/nls';
const $ = dom.$;
export interface IInputOptions extends IInputBoxStyles {
readonly placeholder?: string;
readonly showPlaceholderOnFocus?: boolean;
readonly tooltip?: string;
readonly ariaLabel?: string;
readonly type?: string;
@@ -201,13 +202,14 @@ export class InputBox extends Widget {
// from ScrollableElement to DOM
this._register(this.scrollableElement.onScroll(e => this.input.scrollTop = e.scrollTop));
const onSelectionChange = Event.filter(domEvent(document, 'selectionchange'), () => {
const onSelectionChange = this._register(new DomEmitter(document, 'selectionchange'));
const onAnchoredSelectionChange = Event.filter(onSelectionChange.event, () => {
const selection = document.getSelection();
return selection?.anchorNode === wrapper;
});
// from DOM to ScrollableElement
this._register(onSelectionChange(this.updateScrollDimensions, this));
this._register(onAnchoredSelectionChange(this.updateScrollDimensions, this));
this._register(this.onDidHeightChange(this.updateScrollDimensions, this));
} else {
this.input.type = this.options.type || 'text';
@@ -228,7 +230,7 @@ export class InputBox extends Widget {
this.input.setAttribute('aria-label', this.ariaLabel);
}
if (this.placeholder) {
if (this.placeholder && !this.options.showPlaceholderOnFocus) {
this.setPlaceHolder(this.placeholder);
}
@@ -257,10 +259,16 @@ export class InputBox extends Widget {
private onBlur(): void {
this._hideMessage();
if (this.options.showPlaceholderOnFocus) {
this.input.setAttribute('placeholder', '');
}
}
private onFocus(): void {
this._showMessage();
if (this.options.showPlaceholderOnFocus) {
this.input.setAttribute('placeholder', this.placeholder || '');
}
}
public setPlaceHolder(placeHolder: string): void {
@@ -571,7 +579,8 @@ export class InputBox extends Widget {
const value = this.value;
const lastCharCode = value.charCodeAt(value.length - 1);
const suffix = lastCharCode === 10 ? ' ' : '';
const mirrorTextContent = value + suffix;
const mirrorTextContent = (value + suffix)
.replace(/\u000c/g, ''); // Don't measure with the form feed character, which messes up sizing
if (mirrorTextContent) {
this.mirror.textContent = value + suffix;

View File

@@ -3,15 +3,15 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./keybindingLabel';
import * as dom from 'vs/base/browser/dom';
import { Color } from 'vs/base/common/color';
import { UILabelProvider } from 'vs/base/common/keybindingLabels';
import { ResolvedKeybinding, ResolvedKeybindingPart } from 'vs/base/common/keyCodes';
import { equals } from 'vs/base/common/objects';
import { OperatingSystem } from 'vs/base/common/platform';
import { ResolvedKeybinding, ResolvedKeybindingPart } from 'vs/base/common/keyCodes';
import { UILabelProvider } from 'vs/base/common/keybindingLabels';
import * as dom from 'vs/base/browser/dom';
import { localize } from 'vs/nls';
import { IThemable } from 'vs/base/common/styler';
import { Color } from 'vs/base/common/color';
import 'vs/css!./keybindingLabel';
import { localize } from 'vs/nls';
const $ = dom.$;

View File

@@ -55,10 +55,6 @@
outline: 0 !important;
}
.monaco-list:focus .monaco-list-row.selected .codicon {
color: inherit;
}
/* Dnd */
.monaco-drag-image {
display: inline-block;

View File

@@ -3,9 +3,9 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { GestureEvent } from 'vs/base/browser/touch';
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { IDragAndDropData } from 'vs/base/browser/dnd';
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { GestureEvent } from 'vs/base/browser/touch';
export interface IListVirtualDelegate<T> {
getHeight(element: T): number;
@@ -98,6 +98,7 @@ export interface IListDragAndDrop<T> {
getDragLabel?(elements: T[], originalEvent: DragEvent): string | undefined;
onDragStart?(data: IDragAndDropData, originalEvent: DragEvent): void;
onDragOver(data: IDragAndDropData, targetElement: T | undefined, targetIndex: number | undefined, originalEvent: DragEvent): boolean | IListDragOverReaction;
onDragLeave?(data: IDragAndDropData, targetElement: T | undefined, targetIndex: number | undefined, originalEvent: DragEvent): void;
drop(data: IDragAndDropData, targetElement: T | undefined, targetIndex: number | undefined, originalEvent: DragEvent): void;
onDragEnd?(originalEvent: DragEvent): void;
}

View File

@@ -3,16 +3,16 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./list';
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
import { range } from 'vs/base/common/arrays';
import { IListVirtualDelegate, IListRenderer, IListEvent, IListContextMenuEvent, IListMouseEvent } from './list';
import { List, IListStyles, IListOptions, IListAccessibilityProvider, IListOptionsUpdate } from './listWidget';
import { IPagedModel } from 'vs/base/common/paging';
import { Event } from 'vs/base/common/event';
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { Event } from 'vs/base/common/event';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { IPagedModel } from 'vs/base/common/paging';
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
import { IThemable } from 'vs/base/common/styler';
import 'vs/css!./list';
import { IListContextMenuEvent, IListEvent, IListMouseEvent, IListRenderer, IListVirtualDelegate } from './list';
import { IListAccessibilityProvider, IListOptions, IListOptionsUpdate, IListStyles, List } from './listWidget';
export interface IPagedRenderer<TElement, TTemplateData> extends IListRenderer<TElement, TTemplateData> {
renderPlaceholder(index: number, templateData: TTemplateData): void;

View File

@@ -3,25 +3,25 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { getOrDefault } from 'vs/base/common/objects';
import { IDisposable, dispose, Disposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { Gesture, EventType as TouchEventType, GestureEvent } from 'vs/base/browser/touch';
import { Event, Emitter } from 'vs/base/common/event';
import { domEvent } from 'vs/base/browser/event';
import { SmoothScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
import { ScrollEvent, ScrollbarVisibility, INewScrollDimensions, Scrollable } from 'vs/base/common/scrollable';
import { RangeMap, shift } from './rangeMap';
import { IListVirtualDelegate, IListRenderer, IListMouseEvent, IListTouchEvent, IListGestureEvent, IListDragEvent, IListDragAndDrop, ListDragOverEffect } from './list';
import { RowCache, IRow } from './rowCache';
import { ISpliceable } from 'vs/base/common/sequence';
import { memoize } from 'vs/base/common/decorators';
import { Range, IRange } from 'vs/base/common/range';
import { equals, distinct } from 'vs/base/common/arrays';
import { DataTransfers, StaticDND, IDragAndDropData } from 'vs/base/browser/dnd';
import { disposableTimeout, Delayer } from 'vs/base/common/async';
import { isFirefox } from 'vs/base/browser/browser';
import { DataTransfers, IDragAndDropData, StaticDND } from 'vs/base/browser/dnd';
import { $, addDisposableListener, animate, getContentHeight, getContentWidth, getTopLeftOffset, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
import { DomEmitter } from 'vs/base/browser/event';
import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
import { $, animate, getContentHeight, getContentWidth, getTopLeftOffset, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
import { EventType as TouchEventType, Gesture, GestureEvent } from 'vs/base/browser/touch';
import { SmoothScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
import { distinct, equals } from 'vs/base/common/arrays';
import { Delayer, disposableTimeout } from 'vs/base/common/async';
import { memoize } from 'vs/base/common/decorators';
import { Emitter, Event } from 'vs/base/common/event';
import { Disposable, DisposableStore, dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { getOrDefault } from 'vs/base/common/objects';
import { IRange, Range } from 'vs/base/common/range';
import { INewScrollDimensions, Scrollable, ScrollbarVisibility, ScrollEvent } from 'vs/base/common/scrollable';
import { ISpliceable } from 'vs/base/common/sequence';
import { IListDragAndDrop, IListDragEvent, IListGestureEvent, IListMouseEvent, IListRenderer, IListTouchEvent, IListVirtualDelegate, ListDragOverEffect } from './list';
import { RangeMap, shift } from './rangeMap';
import { IRow, RowCache } from './rowCache';
interface IItem<T> {
readonly id: string;
@@ -52,6 +52,8 @@ export interface IListViewOptionsUpdate {
readonly additionalScrollHeight?: number;
readonly smoothScrolling?: boolean;
readonly horizontalScrolling?: boolean;
readonly mouseWheelScrollSensitivity?: number;
readonly fastScrollSensitivity?: number;
}
export interface IListViewOptions<T> extends IListViewOptionsUpdate {
@@ -333,23 +335,24 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
horizontal: ScrollbarVisibility.Auto,
vertical: getOrDefault(options, o => o.verticalScrollMode, DefaultOptions.verticalScrollMode),
useShadows: getOrDefault(options, o => o.useShadows, DefaultOptions.useShadows),
mouseWheelScrollSensitivity: options.mouseWheelScrollSensitivity,
fastScrollSensitivity: options.fastScrollSensitivity
}, this.scrollable));
this.domNode.appendChild(this.scrollableElement.getDomNode());
container.appendChild(this.domNode);
this.scrollableElement.onScroll(this.onScroll, this, this.disposables);
domEvent(this.rowsContainer, TouchEventType.Change)(e => this.onTouchChange(e as GestureEvent), this, this.disposables);
this.disposables.add(addDisposableListener(this.rowsContainer, TouchEventType.Change, e => this.onTouchChange(e as GestureEvent)));
// Prevent the monaco-scrollable-element from scrolling
// https://github.com/microsoft/vscode/issues/44181
domEvent(this.scrollableElement.getDomNode(), 'scroll')
(e => (e.target as HTMLElement).scrollTop = 0, null, this.disposables);
this.disposables.add(addDisposableListener(this.scrollableElement.getDomNode(), 'scroll', e => (e.target as HTMLElement).scrollTop = 0));
Event.map(domEvent(this.domNode, 'dragover'), e => this.toDragEvent(e))(this.onDragOver, this, this.disposables);
Event.map(domEvent(this.domNode, 'drop'), e => this.toDragEvent(e))(this.onDrop, this, this.disposables);
domEvent(this.domNode, 'dragleave')(this.onDragLeave, this, this.disposables);
domEvent(window, 'dragend')(this.onDragEnd, this, this.disposables);
this.disposables.add(addDisposableListener(this.domNode, 'dragover', e => this.onDragOver(this.toDragEvent(e))));
this.disposables.add(addDisposableListener(this.domNode, 'drop', e => this.onDrop(this.toDragEvent(e))));
this.disposables.add(addDisposableListener(this.domNode, 'dragleave', e => this.onDragLeave(this.toDragEvent(e))));
this.disposables.add(addDisposableListener(this.domNode, 'dragend', e => this.onDragEnd(e)));
this.setRowLineHeight = getOrDefault(options, o => o.setRowLineHeight, DefaultOptions.setRowLineHeight);
this.setRowHeight = getOrDefault(options, o => o.setRowHeight, DefaultOptions.setRowHeight);
@@ -372,6 +375,14 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
if (options.horizontalScrolling !== undefined) {
this.horizontalScrolling = options.horizontalScrolling;
}
if (options.mouseWheelScrollSensitivity !== undefined) {
this.scrollableElement.updateOptions({ mouseWheelScrollSensitivity: options.mouseWheelScrollSensitivity });
}
if (options.fastScrollSensitivity !== undefined) {
this.scrollableElement.updateOptions({ fastScrollSensitivity: options.fastScrollSensitivity });
}
}
triggerScrollFromMouseWheelEvent(browserEvent: IMouseWheelEvent) {
@@ -397,7 +408,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
} else {
if (anchorIndex !== null && anchorIndex > index && anchorIndex <= lastRenderRange.end) {
// anchor in viewport
// resized elemnet in viewport and above the anchor
// resized element in viewport and above the anchor
heightDiff = size - this.items[index].size;
} else {
heightDiff = 0;
@@ -775,8 +786,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
item.row.domNode.draggable = !!uri;
if (uri) {
const onDragStart = domEvent(item.row.domNode, 'dragstart');
item.dragStartDisposable = onDragStart(event => this.onDragStart(item.element, uri, event));
item.dragStartDisposable = addDisposableListener(item.row.domNode, 'dragstart', event => this.onDragStart(item.element, uri, event));
}
if (this.horizontalScrolling) {
@@ -890,17 +900,17 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
// Events
@memoize get onMouseClick(): Event<IListMouseEvent<T>> { return Event.map(domEvent(this.domNode, 'click'), e => this.toMouseEvent(e)); }
@memoize get onMouseDblClick(): Event<IListMouseEvent<T>> { return Event.map(domEvent(this.domNode, 'dblclick'), e => this.toMouseEvent(e)); }
@memoize get onMouseMiddleClick(): Event<IListMouseEvent<T>> { return Event.filter(Event.map(domEvent(this.domNode, 'auxclick'), e => this.toMouseEvent(e as MouseEvent)), e => e.browserEvent.button === 1); }
@memoize get onMouseUp(): Event<IListMouseEvent<T>> { return Event.map(domEvent(this.domNode, 'mouseup'), e => this.toMouseEvent(e)); }
@memoize get onMouseDown(): Event<IListMouseEvent<T>> { return Event.map(domEvent(this.domNode, 'mousedown'), e => this.toMouseEvent(e)); }
@memoize get onMouseOver(): Event<IListMouseEvent<T>> { return Event.map(domEvent(this.domNode, 'mouseover'), e => this.toMouseEvent(e)); }
@memoize get onMouseMove(): Event<IListMouseEvent<T>> { return Event.map(domEvent(this.domNode, 'mousemove'), e => this.toMouseEvent(e)); }
@memoize get onMouseOut(): Event<IListMouseEvent<T>> { return Event.map(domEvent(this.domNode, 'mouseout'), e => this.toMouseEvent(e)); }
@memoize get onContextMenu(): Event<IListMouseEvent<T> | IListGestureEvent<T>> { return Event.any(Event.map(domEvent(this.domNode, 'contextmenu'), e => this.toMouseEvent(e)), Event.map(domEvent(this.domNode, TouchEventType.Contextmenu) as Event<GestureEvent>, e => this.toGestureEvent(e))); }
@memoize get onTouchStart(): Event<IListTouchEvent<T>> { return Event.map(domEvent(this.domNode, 'touchstart'), e => this.toTouchEvent(e)); }
@memoize get onTap(): Event<IListGestureEvent<T>> { return Event.map(domEvent(this.rowsContainer, TouchEventType.Tap), e => this.toGestureEvent(e as GestureEvent)); }
@memoize get onMouseClick(): Event<IListMouseEvent<T>> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'click')).event, e => this.toMouseEvent(e)); }
@memoize get onMouseDblClick(): Event<IListMouseEvent<T>> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'dblclick')).event, e => this.toMouseEvent(e)); }
@memoize get onMouseMiddleClick(): Event<IListMouseEvent<T>> { return Event.filter(Event.map(this.disposables.add(new DomEmitter(this.domNode, 'auxclick')).event, e => this.toMouseEvent(e as MouseEvent)), e => e.browserEvent.button === 1); }
@memoize get onMouseUp(): Event<IListMouseEvent<T>> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'mouseup')).event, e => this.toMouseEvent(e)); }
@memoize get onMouseDown(): Event<IListMouseEvent<T>> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'mousedown')).event, e => this.toMouseEvent(e)); }
@memoize get onMouseOver(): Event<IListMouseEvent<T>> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'mouseover')).event, e => this.toMouseEvent(e)); }
@memoize get onMouseMove(): Event<IListMouseEvent<T>> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'mousemove')).event, e => this.toMouseEvent(e)); }
@memoize get onMouseOut(): Event<IListMouseEvent<T>> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'mouseout')).event, e => this.toMouseEvent(e)); }
@memoize get onContextMenu(): Event<IListMouseEvent<T> | IListGestureEvent<T>> { return Event.any(Event.map(this.disposables.add(new DomEmitter(this.domNode, 'contextmenu')).event, e => this.toMouseEvent(e)), Event.map(this.disposables.add(new DomEmitter(this.domNode, TouchEventType.Contextmenu)).event as Event<GestureEvent>, e => this.toGestureEvent(e))); }
@memoize get onTouchStart(): Event<IListTouchEvent<T>> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'touchstart')).event, e => this.toTouchEvent(e)); }
@memoize get onTap(): Event<IListGestureEvent<T>> { return Event.map(this.disposables.add(new DomEmitter(this.rowsContainer, TouchEventType.Tap)).event, e => this.toGestureEvent(e as GestureEvent)); }
private toMouseEvent(browserEvent: MouseEvent): IListMouseEvent<T> {
const index = this.getItemIndexFromEventTarget(browserEvent.target || null);
@@ -961,7 +971,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
const elements = this.dnd.getDragElements(element);
event.dataTransfer.effectAllowed = 'copyMove';
event.dataTransfer.setData(DataTransfers.RESOURCES, JSON.stringify([uri]));
event.dataTransfer.setData(DataTransfers.TEXT, uri);
if (event.dataTransfer.setDragImage) {
let label: string | undefined;
@@ -1086,9 +1096,12 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
return true;
}
private onDragLeave(): void {
private onDragLeave(event: IListDragEvent<T>): void {
this.onDragLeaveTimeout.dispose();
this.onDragLeaveTimeout = disposableTimeout(() => this.clearDragOverFeedback(), 100);
if (this.currentDragData) {
this.dnd.onDragLeave?.(this.currentDragData, event.element, event.index, event.browserEvent);
}
}
private onDrop(event: IListDragEvent<T>): void {

View File

@@ -3,31 +3,32 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./list';
import { IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle';
import { isNumber } from 'vs/base/common/types';
import { range, binarySearch, firstOrDefault } from 'vs/base/common/arrays';
import { memoize } from 'vs/base/common/decorators';
import * as platform from 'vs/base/common/platform';
import { IDragAndDropData } from 'vs/base/browser/dnd';
import { createStyleSheet } from 'vs/base/browser/dom';
import { DomEmitter, stopEvent } from 'vs/base/browser/event';
import { IKeyboardEvent, StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { Gesture } from 'vs/base/browser/touch';
import { KeyCode } from 'vs/base/common/keyCodes';
import { StandardKeyboardEvent, IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { Event, Emitter, EventBufferer } from 'vs/base/common/event';
import { domEvent, stopEvent } from 'vs/base/browser/event';
import { IListVirtualDelegate, IListRenderer, IListEvent, IListContextMenuEvent, IListMouseEvent, IListTouchEvent, IListGestureEvent, IIdentityProvider, IKeyboardNavigationLabelProvider, IListDragAndDrop, IListDragOverReaction, ListError, IKeyboardNavigationDelegate } from './list';
import { ListView, IListViewOptions, IListViewDragAndDrop, IListViewAccessibilityProvider, IListViewOptionsUpdate } from './listView';
import { alert } from 'vs/base/browser/ui/aria/aria';
import { CombinedSpliceable } from 'vs/base/browser/ui/list/splice';
import { ScrollableElementChangeOptions } from 'vs/base/browser/ui/scrollbar/scrollableElementOptions';
import { binarySearch, firstOrDefault, range } from 'vs/base/common/arrays';
import { timeout } from 'vs/base/common/async';
import { Color } from 'vs/base/common/color';
import { memoize } from 'vs/base/common/decorators';
import { Emitter, Event, EventBufferer } from 'vs/base/common/event';
import { matchesPrefix } from 'vs/base/common/filters';
import { KeyCode } from 'vs/base/common/keyCodes';
import { DisposableStore, dispose, IDisposable } from 'vs/base/common/lifecycle';
import { clamp } from 'vs/base/common/numbers';
import { mixin } from 'vs/base/common/objects';
import * as platform from 'vs/base/common/platform';
import { ScrollbarVisibility, ScrollEvent } from 'vs/base/common/scrollable';
import { ISpliceable } from 'vs/base/common/sequence';
import { CombinedSpliceable } from 'vs/base/browser/ui/list/splice';
import { clamp } from 'vs/base/common/numbers';
import { matchesPrefix } from 'vs/base/common/filters';
import { IDragAndDropData } from 'vs/base/browser/dnd';
import { alert } from 'vs/base/browser/ui/aria/aria';
import { IThemable } from 'vs/base/common/styler';
import { createStyleSheet } from 'vs/base/browser/dom';
import { timeout } from 'vs/base/common/async';
import { isNumber } from 'vs/base/common/types';
import 'vs/css!./list';
import { IIdentityProvider, IKeyboardNavigationDelegate, IKeyboardNavigationLabelProvider, IListContextMenuEvent, IListDragAndDrop, IListDragOverReaction, IListEvent, IListGestureEvent, IListMouseEvent, IListRenderer, IListTouchEvent, IListVirtualDelegate, ListError } from './list';
import { IListViewAccessibilityProvider, IListViewDragAndDrop, IListViewOptions, IListViewOptionsUpdate, ListView } from './listView';
interface ITraitChangeEvent {
indexes: number[];
@@ -109,6 +110,7 @@ class TraitRenderer<T> implements IListRenderer<T, ITraitTemplateData>
class Trait<T> implements ISpliceable<boolean>, IDisposable {
private length = 0;
private indexes: number[] = [];
private sortedIndexes: number[] = [];
@@ -125,16 +127,26 @@ class Trait<T> implements ISpliceable<boolean>, IDisposable {
constructor(private _trait: string) { }
splice(start: number, deleteCount: number, elements: boolean[]): void {
deleteCount = Math.max(0, Math.min(deleteCount, this.length - start));
const diff = elements.length - deleteCount;
const end = start + deleteCount;
const indexes = [
const sortedIndexes = [
...this.sortedIndexes.filter(i => i < start),
...elements.map((hasTrait, i) => hasTrait ? i + start : -1).filter(i => i !== -1),
...this.sortedIndexes.filter(i => i >= end).map(i => i + diff)
];
const length = this.length + diff;
if (this.sortedIndexes.length > 0 && sortedIndexes.length === 0 && length > 0) {
const first = this.sortedIndexes.find(index => index >= start) ?? length - 1;
sortedIndexes.push(Math.min(first, length - 1));
}
this.renderer.splice(start, deleteCount, elements.length);
this._set(indexes, indexes);
this._set(sortedIndexes, sortedIndexes);
this.length = length;
}
renderIndex(index: number, container: HTMLElement): void {
@@ -249,27 +261,39 @@ export function isMonacoEditor(e: HTMLElement): boolean {
class KeyboardController<T> implements IDisposable {
private readonly disposables = new DisposableStore();
private readonly multipleSelectionDisposables = new DisposableStore();
@memoize
private get onKeyDown(): Event.IChainableEvent<StandardKeyboardEvent> {
return Event.chain(this.disposables.add(new DomEmitter(this.view.domNode, 'keydown')).event)
.filter(e => !isInputElement(e.target as HTMLElement))
.map(e => new StandardKeyboardEvent(e));
}
constructor(
private list: List<T>,
private view: ListView<T>,
options: IListOptions<T>
) {
const multipleSelectionSupport = options.multipleSelectionSupport !== false;
this.onKeyDown.filter(e => e.keyCode === KeyCode.Enter).on(this.onEnter, this, this.disposables);
this.onKeyDown.filter(e => e.keyCode === KeyCode.UpArrow).on(this.onUpArrow, this, this.disposables);
this.onKeyDown.filter(e => e.keyCode === KeyCode.DownArrow).on(this.onDownArrow, this, this.disposables);
this.onKeyDown.filter(e => e.keyCode === KeyCode.PageUp).on(this.onPageUpArrow, this, this.disposables);
this.onKeyDown.filter(e => e.keyCode === KeyCode.PageDown).on(this.onPageDownArrow, this, this.disposables);
this.onKeyDown.filter(e => e.keyCode === KeyCode.Escape).on(this.onEscape, this, this.disposables);
const onKeyDown = Event.chain(domEvent(view.domNode, 'keydown'))
.filter(e => !isInputElement(e.target as HTMLElement))
.map(e => new StandardKeyboardEvent(e));
if (options.multipleSelectionSupport !== false) {
this.onKeyDown.filter(e => (platform.isMacintosh ? e.metaKey : e.ctrlKey) && e.keyCode === KeyCode.KEY_A).on(this.onCtrlA, this, this.multipleSelectionDisposables);
}
}
onKeyDown.filter(e => e.keyCode === KeyCode.Enter).on(this.onEnter, this, this.disposables);
onKeyDown.filter(e => e.keyCode === KeyCode.UpArrow).on(this.onUpArrow, this, this.disposables);
onKeyDown.filter(e => e.keyCode === KeyCode.DownArrow).on(this.onDownArrow, this, this.disposables);
onKeyDown.filter(e => e.keyCode === KeyCode.PageUp).on(this.onPageUpArrow, this, this.disposables);
onKeyDown.filter(e => e.keyCode === KeyCode.PageDown).on(this.onPageDownArrow, this, this.disposables);
onKeyDown.filter(e => e.keyCode === KeyCode.Escape).on(this.onEscape, this, this.disposables);
updateOptions(optionsUpdate: IListOptionsUpdate): void {
if (optionsUpdate.multipleSelectionSupport !== undefined) {
this.multipleSelectionDisposables.clear();
if (multipleSelectionSupport) {
onKeyDown.filter(e => (platform.isMacintosh ? e.metaKey : e.ctrlKey) && e.keyCode === KeyCode.KEY_A).on(this.onCtrlA, this, this.disposables);
if (optionsUpdate.multipleSelectionSupport) {
this.onKeyDown.filter(e => (platform.isMacintosh ? e.metaKey : e.ctrlKey) && e.keyCode === KeyCode.KEY_A).on(this.onCtrlA, this, this.multipleSelectionDisposables);
}
}
}
@@ -329,6 +353,7 @@ class KeyboardController<T> implements IDisposable {
dispose() {
this.disposables.dispose();
this.multipleSelectionDisposables.dispose();
}
}
@@ -394,7 +419,7 @@ class TypeLabelController<T> implements IDisposable {
return;
}
const onChar = Event.chain(domEvent(this.view.domNode, 'keydown'))
const onChar = Event.chain(this.enabledDisposables.add(new DomEmitter(this.view.domNode, 'keydown')).event)
.filter(e => !isInputElement(e.target as HTMLElement))
.filter(() => this.automaticKeyboardNavigation || this.triggered)
.map(event => new StandardKeyboardEvent(event))
@@ -426,7 +451,7 @@ class TypeLabelController<T> implements IDisposable {
private onClear(): void {
const focus = this.list.getFocus();
if (focus.length > 0 && focus[0] === this.previouslyFocused) {
// List: re-anounce element on typing end since typed keys will interupt aria label of focused element
// List: re-announce element on typing end since typed keys will interrupt aria label of focused element
// Do not announce if there was a focus change at the end to prevent duplication https://github.com/microsoft/vscode/issues/95961
const ariaLabel = this.list.options.accessibilityProvider?.getAriaLabel(this.list.element(focus[0]));
if (ariaLabel) {
@@ -477,7 +502,7 @@ class DOMFocusController<T> implements IDisposable {
private list: List<T>,
private view: ListView<T>
) {
const onKeyDown = Event.chain(domEvent(view.domNode, 'keydown'))
const onKeyDown = Event.chain(this.disposables.add(new DomEmitter(view.domNode, 'keydown')).event)
.filter(e => !isInputElement(e.target as HTMLElement))
.map(e => new StandardKeyboardEvent(e));
@@ -542,8 +567,7 @@ const DefaultMultipleSelectionController = {
export class MouseController<T> implements IDisposable {
private multipleSelectionSupport: boolean;
readonly multipleSelectionController: IMultipleSelectionController<T> | undefined;
private multipleSelectionController: IMultipleSelectionController<T> | undefined;
private mouseSupport: boolean;
private readonly disposables = new DisposableStore();
@@ -551,10 +575,8 @@ export class MouseController<T> implements IDisposable {
readonly onPointer: Event<IListMouseEvent<T>> = this._onPointer.event;
constructor(protected list: List<T>) {
this.multipleSelectionSupport = !(list.options.multipleSelectionSupport === false);
if (this.multipleSelectionSupport) {
this.multipleSelectionController = list.options.multipleSelectionController || DefaultMultipleSelectionController;
if (list.options.multipleSelectionSupport !== false) {
this.multipleSelectionController = this.list.options.multipleSelectionController || DefaultMultipleSelectionController;
}
this.mouseSupport = typeof list.options.mouseSupport === 'undefined' || !!list.options.mouseSupport;
@@ -570,20 +592,30 @@ export class MouseController<T> implements IDisposable {
Event.any(list.onMouseClick, list.onMouseMiddleClick, list.onTap)(this.onViewPointer, this, this.disposables);
}
updateOptions(optionsUpdate: IListOptionsUpdate): void {
if (optionsUpdate.multipleSelectionSupport !== undefined) {
this.multipleSelectionController = undefined;
if (optionsUpdate.multipleSelectionSupport) {
this.multipleSelectionController = this.list.options.multipleSelectionController || DefaultMultipleSelectionController;
}
}
}
protected isSelectionSingleChangeEvent(event: IListMouseEvent<any> | IListTouchEvent<any>): boolean {
if (this.multipleSelectionController) {
return this.multipleSelectionController.isSelectionSingleChangeEvent(event);
if (!this.multipleSelectionController) {
return false;
}
return platform.isMacintosh ? event.browserEvent.metaKey : event.browserEvent.ctrlKey;
return this.multipleSelectionController.isSelectionSingleChangeEvent(event);
}
protected isSelectionRangeChangeEvent(event: IListMouseEvent<any> | IListTouchEvent<any>): boolean {
if (this.multipleSelectionController) {
return this.multipleSelectionController.isSelectionRangeChangeEvent(event);
if (!this.multipleSelectionController) {
return false;
}
return event.browserEvent.shiftKey;
return this.multipleSelectionController.isSelectionRangeChangeEvent(event);
}
private isSelectionChangeEvent(event: IListMouseEvent<any> | IListTouchEvent<any>): boolean {
@@ -627,11 +659,11 @@ export class MouseController<T> implements IDisposable {
return;
}
if (this.multipleSelectionSupport && this.isSelectionRangeChangeEvent(e)) {
if (this.isSelectionRangeChangeEvent(e)) {
return this.changeSelection(e);
}
if (this.multipleSelectionSupport && this.isSelectionChangeEvent(e)) {
if (this.isSelectionChangeEvent(e)) {
return this.changeSelection(e);
}
@@ -650,7 +682,7 @@ export class MouseController<T> implements IDisposable {
return;
}
if (this.multipleSelectionSupport && this.isSelectionChangeEvent(e)) {
if (this.isSelectionChangeEvent(e)) {
return;
}
@@ -755,6 +787,10 @@ export class DefaultStyleController implements IStyleController {
content.push(`.monaco-list${suffix}:focus .monaco-list-row.selected { color: ${styles.listActiveSelectionForeground}; }`);
}
if (styles.listActiveSelectionIconForeground) {
content.push(`.monaco-list${suffix}:focus .monaco-list-row.selected .codicon { color: ${styles.listActiveSelectionIconForeground}; }`);
}
if (styles.listFocusAndSelectionBackground) {
content.push(`
.monaco-drag-image,
@@ -774,6 +810,10 @@ export class DefaultStyleController implements IStyleController {
content.push(`.monaco-list${suffix} .monaco-list-row.focused:hover { color: ${styles.listInactiveFocusForeground}; }`); // overwrite :hover style in this case!
}
if (styles.listInactiveSelectionIconForeground) {
content.push(`.monaco-list${suffix} .monaco-list-row.focused .codicon { color: ${styles.listInactiveSelectionIconForeground}; }`);
}
if (styles.listInactiveFocusBackground) {
content.push(`.monaco-list${suffix} .monaco-list-row.focused { background-color: ${styles.listInactiveFocusBackground}; }`);
content.push(`.monaco-list${suffix} .monaco-list-row.focused:hover { background-color: ${styles.listInactiveFocusBackground}; }`); // overwrite :hover style in this case!
@@ -851,15 +891,18 @@ export class DefaultStyleController implements IStyleController {
}
}
export interface IListOptions<T> {
readonly identityProvider?: IIdentityProvider<T>;
readonly dnd?: IListDragAndDrop<T>;
export interface IListOptionsUpdate extends IListViewOptionsUpdate {
readonly enableKeyboardNavigation?: boolean;
readonly automaticKeyboardNavigation?: boolean;
readonly multipleSelectionSupport?: boolean;
}
export interface IListOptions<T> extends IListOptionsUpdate {
readonly identityProvider?: IIdentityProvider<T>;
readonly dnd?: IListDragAndDrop<T>;
readonly keyboardNavigationLabelProvider?: IKeyboardNavigationLabelProvider<T>;
readonly keyboardNavigationDelegate?: IKeyboardNavigationDelegate;
readonly keyboardSupport?: boolean;
readonly multipleSelectionSupport?: boolean;
readonly multipleSelectionController?: IMultipleSelectionController<T>;
readonly styleController?: (suffix: string) => IStyleController;
readonly accessibilityProvider?: IListAccessibilityProvider<T>;
@@ -875,6 +918,7 @@ export interface IListOptions<T> {
readonly additionalScrollHeight?: number;
readonly transformOptimization?: boolean;
readonly smoothScrolling?: boolean;
readonly scrollableElementChangeOptions?: ScrollableElementChangeOptions;
readonly alwaysConsumeMouseWheel?: boolean;
}
@@ -884,9 +928,11 @@ export interface IListStyles {
listFocusForeground?: Color;
listActiveSelectionBackground?: Color;
listActiveSelectionForeground?: Color;
listActiveSelectionIconForeground?: Color;
listFocusAndSelectionBackground?: Color;
listFocusAndSelectionForeground?: Color;
listInactiveSelectionBackground?: Color;
listInactiveSelectionIconForeground?: Color;
listInactiveSelectionForeground?: Color;
listInactiveFocusForeground?: Color;
listInactiveFocusBackground?: Color;
@@ -909,9 +955,11 @@ const defaultStyles: IListStyles = {
listFocusBackground: Color.fromHex('#7FB0D0'),
listActiveSelectionBackground: Color.fromHex('#0E639C'),
listActiveSelectionForeground: Color.fromHex('#FFFFFF'),
listActiveSelectionIconForeground: Color.fromHex('#FFFFFF'),
listFocusAndSelectionBackground: Color.fromHex('#094771'),
listFocusAndSelectionForeground: Color.fromHex('#FFFFFF'),
listInactiveSelectionBackground: Color.fromHex('#3F3F46'),
listInactiveSelectionIconForeground: Color.fromHex('#FFFFFF'),
listHoverBackground: Color.fromHex('#2A2D2E'),
listDropBackground: Color.fromHex('#383B3D'),
treeIndentGuidesStroke: Color.fromHex('#a9a9a9'),
@@ -1120,6 +1168,10 @@ class ListViewDragAndDrop<T> implements IListViewDragAndDrop<T> {
return this.dnd.onDragOver(data, targetElement, targetIndex, originalEvent);
}
onDragLeave(data: IDragAndDropData, targetElement: T, targetIndex: number, originalEvent: DragEvent): void {
this.dnd.onDragLeave?.(data, targetElement, targetIndex, originalEvent);
}
onDragEnd(originalEvent: DragEvent): void {
if (this.dnd.onDragEnd) {
this.dnd.onDragEnd(originalEvent);
@@ -1131,11 +1183,6 @@ class ListViewDragAndDrop<T> implements IListViewDragAndDrop<T> {
}
}
export interface IListOptionsUpdate extends IListViewOptionsUpdate {
readonly enableKeyboardNavigation?: boolean;
readonly automaticKeyboardNavigation?: boolean;
}
export class List<T> implements ISpliceable<T>, IThemable, IDisposable {
private focus = new Trait<T>('focused');
@@ -1147,6 +1194,7 @@ export class List<T> implements ISpliceable<T>, IThemable, IDisposable {
private styleController: IStyleController;
private typeLabelController?: TypeLabelController<T>;
private accessibilityProvider?: IListAccessibilityProvider<T>;
private keyboardController: KeyboardController<T> | undefined;
private mouseController: MouseController<T>;
private _ariaLabel: string = '';
@@ -1184,14 +1232,14 @@ export class List<T> implements ISpliceable<T>, IThemable, IDisposable {
@memoize get onContextMenu(): Event<IListContextMenuEvent<T>> {
let didJustPressContextMenuKey = false;
const fromKeyDown = Event.chain(domEvent(this.view.domNode, 'keydown'))
const fromKeyDown = Event.chain(this.disposables.add(new DomEmitter(this.view.domNode, 'keydown')).event)
.map(e => new StandardKeyboardEvent(e))
.filter(e => didJustPressContextMenuKey = e.keyCode === KeyCode.ContextMenu || (e.shiftKey && e.keyCode === KeyCode.F10))
.map(stopEvent)
.filter(() => false)
.event as Event<any>;
const fromKeyUp = Event.chain(domEvent(this.view.domNode, 'keyup'))
const fromKeyUp = Event.chain(this.disposables.add(new DomEmitter(this.view.domNode, 'keyup')).event)
.forEach(() => didJustPressContextMenuKey = false)
.map(e => new StandardKeyboardEvent(e))
.filter(e => e.keyCode === KeyCode.ContextMenu || (e.shiftKey && e.keyCode === KeyCode.F10))
@@ -1213,12 +1261,12 @@ export class List<T> implements ISpliceable<T>, IThemable, IDisposable {
return Event.any<IListContextMenuEvent<T>>(fromKeyDown, fromKeyUp, fromMouse);
}
get onKeyDown(): Event<KeyboardEvent> { return domEvent(this.view.domNode, 'keydown'); }
get onKeyUp(): Event<KeyboardEvent> { return domEvent(this.view.domNode, 'keyup'); }
get onKeyPress(): Event<KeyboardEvent> { return domEvent(this.view.domNode, 'keypress'); }
@memoize get onKeyDown(): Event<KeyboardEvent> { return this.disposables.add(new DomEmitter(this.view.domNode, 'keydown')).event; }
@memoize get onKeyUp(): Event<KeyboardEvent> { return this.disposables.add(new DomEmitter(this.view.domNode, 'keyup')).event; }
@memoize get onKeyPress(): Event<KeyboardEvent> { return this.disposables.add(new DomEmitter(this.view.domNode, 'keypress')).event; }
readonly onDidFocus: Event<void>;
readonly onDidBlur: Event<void>;
@memoize get onDidFocus(): Event<void> { return Event.signal(this.disposables.add(new DomEmitter(this.view.domNode, 'focus', true)).event); }
@memoize get onDidBlur(): Event<void> { return Event.signal(this.disposables.add(new DomEmitter(this.view.domNode, 'blur', true)).event); }
private readonly _onDidDispose = new Emitter<void>();
readonly onDidDispose: Event<void> = this._onDidDispose.event;
@@ -1277,14 +1325,11 @@ export class List<T> implements ISpliceable<T>, IThemable, IDisposable {
this.disposables.add(this.view);
this.disposables.add(this._onDidDispose);
this.onDidFocus = Event.map(domEvent(this.view.domNode, 'focus', true), () => null!);
this.onDidBlur = Event.map(domEvent(this.view.domNode, 'blur', true), () => null!);
this.disposables.add(new DOMFocusController(this, this.view));
if (typeof _options.keyboardSupport !== 'boolean' || _options.keyboardSupport) {
const controller = new KeyboardController(this, this.view, _options);
this.disposables.add(controller);
this.keyboardController = new KeyboardController(this, this.view, _options);
this.disposables.add(this.keyboardController);
}
if (_options.keyboardNavigationLabelProvider) {
@@ -1302,7 +1347,8 @@ export class List<T> implements ISpliceable<T>, IThemable, IDisposable {
if (this.accessibilityProvider) {
this.ariaLabel = this.accessibilityProvider.getWidgetAriaLabel();
}
if (_options.multipleSelectionSupport) {
if (this._options.multipleSelectionSupport !== false) {
this.view.domNode.setAttribute('aria-multiselectable', 'true');
}
}
@@ -1318,6 +1364,16 @@ export class List<T> implements ISpliceable<T>, IThemable, IDisposable {
this.typeLabelController.updateOptions(this._options);
}
if (this._options.multipleSelectionController !== undefined) {
if (this._options.multipleSelectionSupport) {
this.view.domNode.setAttribute('aria-multiselectable', 'true');
} else {
this.view.domNode.removeAttribute('aria-multiselectable');
}
}
this.mouseController.updateOptions(optionsUpdate);
this.keyboardController?.updateOptions(optionsUpdate);
this.view.updateOptions(optionsUpdate);
}
@@ -1463,6 +1519,11 @@ export class List<T> implements ISpliceable<T>, IThemable, IDisposable {
return firstOrDefault(this.anchor.get(), undefined);
}
getAnchorElement(): T | undefined {
const anchor = this.getAnchor();
return typeof anchor === 'undefined' ? undefined : this.element(anchor);
}
setFocus(indexes: number[], browserEvent?: UIEvent): void {
for (const index of indexes) {
if (index < 0 || index >= this.length) {

View File

@@ -3,9 +3,9 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IListRenderer } from './list';
import { IDisposable } from 'vs/base/common/lifecycle';
import { $ } from 'vs/base/browser/dom';
import { IDisposable } from 'vs/base/common/lifecycle';
import { IListRenderer } from './list';
export interface IRow {
domNode: HTMLElement;

View File

@@ -3,27 +3,27 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vs/nls';
import * as strings from 'vs/base/common/strings';
import { IActionRunner, IAction, SubmenuAction, Separator, EmptySubmenuAction } from 'vs/base/common/actions';
import { ActionBar, ActionsOrientation, IActionViewItemProvider } from 'vs/base/browser/ui/actionbar/actionbar';
import { ResolvedKeybinding, KeyCode } from 'vs/base/common/keyCodes';
import { EventType, EventHelper, EventLike, isAncestor, addDisposableListener, append, $, clearNode, createStyleSheet, isInShadowDOM, getActiveElement, Dimension, IDomNodePagePosition } from 'vs/base/browser/dom';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { RunOnceScheduler } from 'vs/base/common/async';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { Color } from 'vs/base/common/color';
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
import { ScrollbarVisibility, ScrollEvent } from 'vs/base/common/scrollable';
import { Event } from 'vs/base/common/event';
import { AnchorAlignment, layout, LayoutAnchorPosition } from 'vs/base/browser/ui/contextview/contextview';
import { isLinux, isMacintosh } from 'vs/base/common/platform';
import { Codicon, registerCodicon } from 'vs/base/common/codicons';
import { BaseActionViewItem, ActionViewItem, IActionViewItemOptions } from 'vs/base/browser/ui/actionbar/actionViewItems';
import { formatRule } from 'vs/base/browser/ui/codicons/codiconStyles';
import { isFirefox } from 'vs/base/browser/browser';
import { $, addDisposableListener, append, clearNode, createStyleSheet, Dimension, EventHelper, EventLike, EventType, getActiveElement, IDomNodePagePosition, isAncestor, isInShadowDOM } from 'vs/base/browser/dom';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { ActionBar, ActionsOrientation, IActionViewItemProvider } from 'vs/base/browser/ui/actionbar/actionbar';
import { ActionViewItem, BaseActionViewItem, IActionViewItemOptions } from 'vs/base/browser/ui/actionbar/actionViewItems';
import { formatRule } from 'vs/base/browser/ui/codicons/codiconStyles';
import { AnchorAlignment, layout, LayoutAnchorPosition } from 'vs/base/browser/ui/contextview/contextview';
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
import { EmptySubmenuAction, IAction, IActionRunner, Separator, SubmenuAction } from 'vs/base/common/actions';
import { RunOnceScheduler } from 'vs/base/common/async';
import { Codicon, registerCodicon } from 'vs/base/common/codicons';
import { Color } from 'vs/base/common/color';
import { Event } from 'vs/base/common/event';
import { stripIcons } from 'vs/base/common/iconLabels';
import { KeyCode, ResolvedKeybinding } from 'vs/base/common/keyCodes';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { isLinux, isMacintosh } from 'vs/base/common/platform';
import { ScrollbarVisibility, ScrollEvent } from 'vs/base/common/scrollable';
import * as strings from 'vs/base/common/strings';
import * as nls from 'vs/nls';
export const MENU_MNEMONIC_REGEX = /\(&([^\s&])\)|(^|[^&])&([^\s&])/;
export const MENU_ESCAPED_MNEMONIC_REGEX = /(&amp;)?(&amp;)([^\s&])/g;
@@ -447,7 +447,7 @@ class BaseMenuActionViewItem extends BaseActionViewItem {
this.onClick(e);
}
// In all other cases, set timout to allow context menu cancellation to trigger
// In all other cases, set timeout to allow context menu cancellation to trigger
// otherwise the action will destroy the menu and a second context menu
// will still trigger for right click.
else {

View File

@@ -3,25 +3,25 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./menubar';
import * as browser from 'vs/base/browser/browser';
import * as DOM from 'vs/base/browser/dom';
import * as strings from 'vs/base/common/strings';
import * as nls from 'vs/nls';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { EventType, Gesture, GestureEvent } from 'vs/base/browser/touch';
import { cleanMnemonic, IMenuOptions, Menu, MENU_ESCAPED_MNEMONIC_REGEX, MENU_MNEMONIC_REGEX, IMenuStyles, Direction } from 'vs/base/browser/ui/menu/menu';
import { ActionRunner, IAction, IActionRunner, SubmenuAction, Separator } from 'vs/base/common/actions';
import { RunOnceScheduler } from 'vs/base/common/async';
import { Event, Emitter } from 'vs/base/common/event';
import { KeyCode, ResolvedKeybinding, KeyMod } from 'vs/base/common/keyCodes';
import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle';
import { withNullAsUndefined } from 'vs/base/common/types';
import { asArray } from 'vs/base/common/arrays';
import { ScanCodeUtils, ScanCode } from 'vs/base/common/scanCode';
import { isMacintosh } from 'vs/base/common/platform';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { EventType, Gesture, GestureEvent } from 'vs/base/browser/touch';
import { cleanMnemonic, Direction, IMenuOptions, IMenuStyles, Menu, MENU_ESCAPED_MNEMONIC_REGEX, MENU_MNEMONIC_REGEX } from 'vs/base/browser/ui/menu/menu';
import { ActionRunner, IAction, IActionRunner, Separator, SubmenuAction } from 'vs/base/common/actions';
import { asArray } from 'vs/base/common/arrays';
import { RunOnceScheduler } from 'vs/base/common/async';
import { Codicon, registerCodicon } from 'vs/base/common/codicons';
import { Emitter, Event } from 'vs/base/common/event';
import { KeyCode, KeyMod, ResolvedKeybinding } from 'vs/base/common/keyCodes';
import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle';
import { isMacintosh } from 'vs/base/common/platform';
import { ScanCode, ScanCodeUtils } from 'vs/base/common/scanCode';
import * as strings from 'vs/base/common/strings';
import { withNullAsUndefined } from 'vs/base/common/types';
import 'vs/css!./menubar';
import * as nls from 'vs/nls';
const $ = DOM.$;

View File

@@ -3,13 +3,13 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./progressbar';
import { Disposable } from 'vs/base/common/lifecycle';
import { Color } from 'vs/base/common/color';
import { mixin } from 'vs/base/common/objects';
import { hide, show } from 'vs/base/browser/dom';
import { RunOnceScheduler } from 'vs/base/common/async';
import { Color } from 'vs/base/common/color';
import { Disposable } from 'vs/base/common/lifecycle';
import { mixin } from 'vs/base/common/objects';
import { isNumber } from 'vs/base/common/types';
import 'vs/css!./progressbar';
const CSS_DONE = 'done';
const CSS_ACTIVE = 'active';

View File

@@ -3,15 +3,15 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./sash';
import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
import { isMacintosh } from 'vs/base/common/platform';
import { EventType, Gesture, GestureEvent } from 'vs/base/browser/touch';
import { Event, Emitter } from 'vs/base/common/event';
import { getElementsByTagName, EventHelper, createStyleSheet, append, $, EventLike } from 'vs/base/browser/dom';
import { $, append, createStyleSheet, EventHelper, EventLike, getElementsByTagName } from 'vs/base/browser/dom';
import { DomEmitter } from 'vs/base/browser/event';
import { EventType, Gesture, GestureEvent } from 'vs/base/browser/touch';
import { Delayer } from 'vs/base/common/async';
import { memoize } from 'vs/base/common/decorators';
import { Emitter, Event } from 'vs/base/common/event';
import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
import { isMacintosh } from 'vs/base/common/platform';
import 'vs/css!./sash';
let DEBUG = false;
// DEBUG = Boolean("true"); // done "weirdly" so that a lint warning prevents you from pushing this
@@ -217,9 +217,9 @@ export class Sash extends Disposable {
if (state !== SashState.Disabled) {
this._orthogonalStartDragHandle = append(this.el, $('.orthogonal-drag-handle.start'));
this.orthogonalStartDragHandleDisposables.add(toDisposable(() => this._orthogonalStartDragHandle!.remove()));
this.orthogonalEndDragHandleDisposables.add(new DomEmitter(this._orthogonalStartDragHandle, 'mouseenter')).event
this.orthogonalStartDragHandleDisposables.add(new DomEmitter(this._orthogonalStartDragHandle, 'mouseenter')).event
(() => Sash.onMouseEnter(sash), undefined, this.orthogonalStartDragHandleDisposables);
this.orthogonalEndDragHandleDisposables.add(new DomEmitter(this._orthogonalStartDragHandle, 'mouseleave')).event
this.orthogonalStartDragHandleDisposables.add(new DomEmitter(this._orthogonalStartDragHandle, 'mouseleave')).event
(() => Sash.onMouseLeave(sash), undefined, this.orthogonalStartDragHandleDisposables);
}
};
@@ -362,13 +362,7 @@ export class Sash extends Disposable {
return;
}
// Select both iframes and webviews; internally Electron nests an iframe
// in its <webview> component, but this isn't queryable.
const iframes = [
...getElementsByTagName('iframe'),
...getElementsByTagName('webview'),
];
const iframes = getElementsByTagName('iframe');
for (const iframe of iframes) {
iframe.style.pointerEvents = 'none'; // disable mouse events on iframes as long as we drag the sash
}

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as dom from 'vs/base/browser/dom';
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
import { createFastDomNode, FastDomNode } from 'vs/base/browser/fastDomNode';
import { GlobalMouseMoveMonitor, IStandardMouseMoveEventData, standardMouseMoveMerger } from 'vs/base/browser/globalMouseMoveMonitor';
import { IMouseEvent, StandardWheelEvent } from 'vs/base/browser/mouseEvent';
import { ScrollbarArrow, ScrollbarArrowOptions } from 'vs/base/browser/ui/scrollbar/scrollbarArrow';
@@ -48,7 +48,7 @@ export abstract class AbstractScrollbar extends Widget {
protected _scrollByPage: boolean;
private _lazyRender: boolean;
protected _scrollbarState: ScrollbarState;
private _visibilityController: ScrollbarVisibilityController;
protected _visibilityController: ScrollbarVisibilityController;
private _mouseMoveMonitor: GlobalMouseMoveMonitor<IStandardMouseMoveEventData>;
public domNode: FastDomNode<HTMLElement>;

View File

@@ -8,8 +8,8 @@ import { AbstractScrollbar, ISimplifiedMouseEvent, ScrollbarHost } from 'vs/base
import { ScrollableElementResolvedOptions } from 'vs/base/browser/ui/scrollbar/scrollableElementOptions';
import { ARROW_IMG_SIZE } from 'vs/base/browser/ui/scrollbar/scrollbarArrow';
import { ScrollbarState } from 'vs/base/browser/ui/scrollbar/scrollbarState';
import { INewScrollPosition, ScrollEvent, Scrollable, ScrollbarVisibility } from 'vs/base/common/scrollable';
import { Codicon, registerCodicon } from 'vs/base/common/codicons';
import { INewScrollPosition, Scrollable, ScrollbarVisibility, ScrollEvent } from 'vs/base/common/scrollable';
const scrollbarButtonLeftIcon = registerCodicon('scrollbar-button-left', Codicon.triangleLeft);
@@ -107,4 +107,11 @@ export class HorizontalScrollbar extends AbstractScrollbar {
public writeScrollPosition(target: INewScrollPosition, scrollPosition: number): void {
target.scrollLeft = scrollPosition;
}
public updateOptions(options: ScrollableElementResolvedOptions): void {
this.updateScrollbarSize(options.horizontal === ScrollbarVisibility.Hidden ? 0 : options.horizontalScrollbarSize);
this._scrollbarState.setOppositeScrollbarSize(options.vertical === ScrollbarVisibility.Hidden ? 0 : options.verticalScrollbarSize);
this._visibilityController.setVisibility(options.horizontal);
this._scrollByPage = options.scrollByPage;
}
}

View File

@@ -3,10 +3,10 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./media/scrollbars';
import { getZoomFactor } from 'vs/base/browser/browser';
import * as dom from 'vs/base/browser/dom';
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
import { IMouseEvent, StandardWheelEvent, IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
import { createFastDomNode, FastDomNode } from 'vs/base/browser/fastDomNode';
import { IMouseEvent, IMouseWheelEvent, StandardWheelEvent } from 'vs/base/browser/mouseEvent';
import { ScrollbarHost } from 'vs/base/browser/ui/scrollbar/abstractScrollbar';
import { HorizontalScrollbar } from 'vs/base/browser/ui/scrollbar/horizontalScrollbar';
import { ScrollableElementChangeOptions, ScrollableElementCreationOptions, ScrollableElementResolvedOptions } from 'vs/base/browser/ui/scrollbar/scrollableElementOptions';
@@ -14,10 +14,10 @@ import { VerticalScrollbar } from 'vs/base/browser/ui/scrollbar/verticalScrollba
import { Widget } from 'vs/base/browser/ui/widget';
import { TimeoutTimer } from 'vs/base/common/async';
import { Emitter, Event } from 'vs/base/common/event';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import * as platform from 'vs/base/common/platform';
import { INewScrollDimensions, INewScrollPosition, IScrollDimensions, IScrollPosition, ScrollEvent, Scrollable, ScrollbarVisibility } from 'vs/base/common/scrollable';
import { getZoomFactor } from 'vs/base/browser/browser';
import { INewScrollDimensions, INewScrollPosition, IScrollDimensions, IScrollPosition, Scrollable, ScrollbarVisibility, ScrollEvent } from 'vs/base/common/scrollable';
import 'vs/css!./media/scrollbars';
const HIDE_TIMEOUT = 500;
const SCROLL_WHEEL_SENSITIVITY = 50;
@@ -288,8 +288,6 @@ export abstract class AbstractScrollableElement extends Widget {
/**
* Update configuration options for the scrollbar.
* Really this is Editor.IEditorScrollbarOptions, but base shouldn't
* depend on Editor.
*/
public updateOptions(newOptions: ScrollableElementChangeOptions): void {
if (typeof newOptions.handleMouseWheel !== 'undefined') {
@@ -305,9 +303,23 @@ export abstract class AbstractScrollableElement extends Widget {
if (typeof newOptions.scrollPredominantAxis !== 'undefined') {
this._options.scrollPredominantAxis = newOptions.scrollPredominantAxis;
}
if (typeof newOptions.horizontalScrollbarSize !== 'undefined') {
this._horizontalScrollbar.updateScrollbarSize(newOptions.horizontalScrollbarSize);
if (typeof newOptions.horizontal !== 'undefined') {
this._options.horizontal = newOptions.horizontal;
}
if (typeof newOptions.vertical !== 'undefined') {
this._options.vertical = newOptions.vertical;
}
if (typeof newOptions.horizontalScrollbarSize !== 'undefined') {
this._options.horizontalScrollbarSize = newOptions.horizontalScrollbarSize;
}
if (typeof newOptions.verticalScrollbarSize !== 'undefined') {
this._options.verticalScrollbarSize = newOptions.verticalScrollbarSize;
}
if (typeof newOptions.scrollByPage !== 'undefined') {
this._options.scrollByPage = newOptions.scrollByPage;
}
this._horizontalScrollbar.updateOptions(this._options);
this._verticalScrollbar.updateOptions(this._options);
if (!this._options.lazyRender) {
this._render();

View File

@@ -131,7 +131,11 @@ export interface ScrollableElementChangeOptions {
mouseWheelScrollSensitivity?: number;
fastScrollSensitivity?: number;
scrollPredominantAxis?: boolean;
horizontal?: ScrollbarVisibility;
horizontalScrollbarSize?: number;
vertical?: ScrollbarVisibility;
verticalScrollbarSize?: number;
scrollByPage?: boolean;
}
export interface ScrollableElementResolvedOptions {

View File

@@ -20,7 +20,7 @@ export class ScrollbarState {
* For the vertical scrollbar: the height of the pair horizontal scrollbar.
* For the horizontal scrollbar: the width of the pair vertical scrollbar.
*/
private readonly _oppositeScrollbarSize: number;
private _oppositeScrollbarSize: number;
/**
* For the vertical scrollbar: the height of the scrollbar's arrows.
@@ -115,7 +115,11 @@ export class ScrollbarState {
}
public setScrollbarSize(scrollbarSize: number): void {
this._scrollbarSize = scrollbarSize;
this._scrollbarSize = Math.round(scrollbarSize);
}
public setOppositeScrollbarSize(oppositeScrollbarSize: number): void {
this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize);
}
private static _computeValues(oppositeScrollbarSize: number, arrowSize: number, visibleSize: number, scrollSize: number, scrollPosition: number) {

View File

@@ -13,6 +13,7 @@ export class ScrollbarVisibilityController extends Disposable {
private _visibleClassName: string;
private _invisibleClassName: string;
private _domNode: FastDomNode<HTMLElement> | null;
private _rawShouldBeVisible: boolean;
private _shouldBeVisible: boolean;
private _isNeeded: boolean;
private _isVisible: boolean;
@@ -26,24 +27,37 @@ export class ScrollbarVisibilityController extends Disposable {
this._domNode = null;
this._isVisible = false;
this._isNeeded = false;
this._rawShouldBeVisible = false;
this._shouldBeVisible = false;
this._revealTimer = this._register(new TimeoutTimer());
}
public setVisibility(visibility: ScrollbarVisibility): void {
if (this._visibility !== visibility) {
this._visibility = visibility;
this._updateShouldBeVisible();
}
}
// ----------------- Hide / Reveal
private applyVisibilitySetting(shouldBeVisible: boolean): boolean {
public setShouldBeVisible(rawShouldBeVisible: boolean): void {
this._rawShouldBeVisible = rawShouldBeVisible;
this._updateShouldBeVisible();
}
private _applyVisibilitySetting(): boolean {
if (this._visibility === ScrollbarVisibility.Hidden) {
return false;
}
if (this._visibility === ScrollbarVisibility.Visible) {
return true;
}
return shouldBeVisible;
return this._rawShouldBeVisible;
}
public setShouldBeVisible(rawShouldBeVisible: boolean): void {
const shouldBeVisible = this.applyVisibilitySetting(rawShouldBeVisible);
private _updateShouldBeVisible(): void {
const shouldBeVisible = this._applyVisibilitySetting();
if (this._shouldBeVisible !== shouldBeVisible) {
this._shouldBeVisible = shouldBeVisible;

View File

@@ -8,8 +8,8 @@ import { AbstractScrollbar, ISimplifiedMouseEvent, ScrollbarHost } from 'vs/base
import { ScrollableElementResolvedOptions } from 'vs/base/browser/ui/scrollbar/scrollableElementOptions';
import { ARROW_IMG_SIZE } from 'vs/base/browser/ui/scrollbar/scrollbarArrow';
import { ScrollbarState } from 'vs/base/browser/ui/scrollbar/scrollbarState';
import { INewScrollPosition, ScrollEvent, Scrollable, ScrollbarVisibility } from 'vs/base/common/scrollable';
import { Codicon, registerCodicon } from 'vs/base/common/codicons';
import { INewScrollPosition, Scrollable, ScrollbarVisibility, ScrollEvent } from 'vs/base/common/scrollable';
const scrollbarButtonUpIcon = registerCodicon('scrollbar-button-up', Codicon.triangleUp);
const scrollbarButtonDownIcon = registerCodicon('scrollbar-button-down', Codicon.triangleDown);
@@ -107,4 +107,13 @@ export class VerticalScrollbar extends AbstractScrollbar {
public writeScrollPosition(target: INewScrollPosition, scrollPosition: number): void {
target.scrollTop = scrollPosition;
}
public updateOptions(options: ScrollableElementResolvedOptions): void {
this.updateScrollbarSize(options.vertical === ScrollbarVisibility.Hidden ? 0 : options.verticalScrollbarSize);
// give priority to vertical scroll bar over horizontal and let it scroll all the way to the bottom
this._scrollbarState.setOppositeScrollbarSize(0);
this._visibilityController.setVisibility(options.vertical);
this._scrollByPage = options.scrollByPage;
}
}

View File

@@ -3,19 +3,19 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./selectBox';
import { Event } from 'vs/base/common/event';
import { Widget } from 'vs/base/browser/ui/widget';
import { Color } from 'vs/base/common/color';
import { deepClone } from 'vs/base/common/objects';
import { IContentActionHandler } from 'vs/base/browser/formattedTextRenderer';
import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
import { IListStyles } from 'vs/base/browser/ui/list/listWidget';
import { SelectBoxNative } from 'vs/base/browser/ui/selectBox/selectBoxNative';
import { SelectBoxList } from 'vs/base/browser/ui/selectBox/selectBoxCustom';
import { isMacintosh } from 'vs/base/common/platform';
import { SelectBoxNative } from 'vs/base/browser/ui/selectBox/selectBoxNative';
import { Widget } from 'vs/base/browser/ui/widget';
import { Color } from 'vs/base/common/color';
import { Event } from 'vs/base/common/event';
import { IDisposable } from 'vs/base/common/lifecycle';
import { deepClone } from 'vs/base/common/objects';
import { isMacintosh } from 'vs/base/common/platform';
import 'vs/css!./selectBox';
// Public SelectBox interface - Calls routed to appropriate select implementation class

View File

@@ -3,25 +3,25 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./selectBoxCustom';
import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle';
import { Event, Emitter } from 'vs/base/common/event';
import { KeyCode, KeyCodeUtils } from 'vs/base/common/keyCodes';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import * as dom from 'vs/base/browser/dom';
import * as arrays from 'vs/base/common/arrays';
import { IContextViewProvider, AnchorPosition } from 'vs/base/browser/ui/contextview/contextview';
import { List } from 'vs/base/browser/ui/list/listWidget';
import { IListVirtualDelegate, IListRenderer, IListEvent } from 'vs/base/browser/ui/list/list';
import { domEvent } from 'vs/base/browser/event';
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
import { ISelectBoxDelegate, ISelectOptionItem, ISelectBoxOptions, ISelectBoxStyles, ISelectData } from 'vs/base/browser/ui/selectBox/selectBox';
import { isMacintosh } from 'vs/base/common/platform';
import { renderMarkdown } from 'vs/base/browser/markdownRenderer';
import { DomEmitter } from 'vs/base/browser/event';
import { IContentActionHandler } from 'vs/base/browser/formattedTextRenderer';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { renderMarkdown } from 'vs/base/browser/markdownRenderer';
import { AnchorPosition, IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
import { IListEvent, IListRenderer, IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { List } from 'vs/base/browser/ui/list/listWidget';
import { ISelectBoxDelegate, ISelectBoxOptions, ISelectBoxStyles, ISelectData, ISelectOptionItem } from 'vs/base/browser/ui/selectBox/selectBox';
import * as arrays from 'vs/base/common/arrays';
import { Emitter, Event } from 'vs/base/common/event';
import { KeyCode, KeyCodeUtils } from 'vs/base/common/keyCodes';
import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle';
import { isMacintosh } from 'vs/base/common/platform';
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
import 'vs/css!./selectBoxCustom';
import { localize } from 'vs/nls';
const $ = dom.$;
const SELECT_OPTION_ENTRY_TEMPLATE_ID = 'selectOption.entry.template';
@@ -334,7 +334,7 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
}
if (this.styles.decoratorRightForeground) {
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row .option-decorator-right { color: ${this.styles.decoratorRightForeground} !important; }`);
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row:not(.focused) .option-decorator-right { color: ${this.styles.decoratorRightForeground}; }`);
}
if (this.styles.selectBackground && this.styles.selectBorder && !this.styles.selectBorder.equals(this.styles.selectBackground)) {
@@ -350,14 +350,12 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
// Hover foreground - ignore for disabled options
if (this.styles.listHoverForeground) {
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row:hover { color: ${this.styles.listHoverForeground} !important; }`);
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.option-disabled:hover { background-color: ${this.styles.listActiveSelectionForeground} !important; }`);
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row:not(.option-disabled):not(.focused):hover { color: ${this.styles.listHoverForeground} !important; }`);
}
// Hover background - ignore for disabled options
if (this.styles.listHoverBackground) {
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row:not(.option-disabled):not(.focused):hover { background-color: ${this.styles.listHoverBackground} !important; }`);
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.option-disabled:hover { background-color: ${this.styles.selectBackground} !important; }`);
}
// Match quick input outline styles - ignore for disabled options
@@ -366,10 +364,13 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
}
if (this.styles.listHoverOutline) {
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row:hover:not(.focused) { outline: 1.6px dashed ${this.styles.listHoverOutline} !important; outline-offset: -1.6px !important; }`);
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.option-disabled:hover { outline: none !important; }`);
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row:not(.option-disabled):not(.focused):hover { outline: 1.6px dashed ${this.styles.listHoverOutline} !important; outline-offset: -1.6px !important; }`);
}
// Clear list styles on focus and on hover for disabled options
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.option-disabled.focused { background-color: transparent !important; color: inherit !important; outline: none !important; }`);
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.option-disabled:hover { background-color: transparent !important; color: inherit !important; outline: none !important; }`);
this.styleElement.textContent = content.join('\n');
this.applyStyles();
@@ -746,7 +747,8 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
}
// SetUp list keyboard controller - control navigation, disabled items, focus
const onSelectDropDownKeyDown = Event.chain(domEvent(this.selectDropDownListContainer, 'keydown'))
const onKeyDown = this._register(new DomEmitter(this.selectDropDownListContainer, 'keydown'));
const onSelectDropDownKeyDown = Event.chain(onKeyDown.event)
.filter(() => this.selectList.length > 0)
.map(e => new StandardKeyboardEvent(e));
@@ -762,7 +764,8 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
// SetUp list mouse controller - control navigation, disabled items, focus
this._register(Event.chain(domEvent(this.selectList.getHTMLElement(), 'mouseup'))
const onMouseUp = this._register(new DomEmitter(this.selectList.getHTMLElement(), 'mouseup'));
this._register(Event.chain(onMouseUp.event)
.filter(() => this.selectList.length > 0)
.on(e => this.onMouseUp(e), this));

View File

@@ -3,14 +3,14 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Disposable } from 'vs/base/common/lifecycle';
import { Event, Emitter } from 'vs/base/common/event';
import { KeyCode } from 'vs/base/common/keyCodes';
import * as dom from 'vs/base/browser/dom';
import { EventType, Gesture } from 'vs/base/browser/touch';
import { ISelectBoxDelegate, ISelectBoxOptions, ISelectBoxStyles, ISelectData, ISelectOptionItem } from 'vs/base/browser/ui/selectBox/selectBox';
import * as arrays from 'vs/base/common/arrays';
import { ISelectBoxDelegate, ISelectOptionItem, ISelectBoxOptions, ISelectBoxStyles, ISelectData } from 'vs/base/browser/ui/selectBox/selectBox';
import { Emitter, Event } from 'vs/base/common/event';
import { KeyCode } from 'vs/base/common/keyCodes';
import { Disposable } from 'vs/base/common/lifecycle';
import { isMacintosh } from 'vs/base/common/platform';
import { Gesture, EventType } from 'vs/base/browser/touch';
export class SelectBoxNative extends Disposable implements ISelectBoxDelegate {

View File

@@ -3,20 +3,20 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./paneview';
import { IDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { Event, Emitter } from 'vs/base/common/event';
import { domEvent } from 'vs/base/browser/event';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { $, append, trackFocus, EventHelper, clearNode } from 'vs/base/browser/dom';
import { Color, RGBA } from 'vs/base/common/color';
import { SplitView, IView } from './splitview';
import { isFirefox } from 'vs/base/browser/browser';
import { DataTransfers } from 'vs/base/browser/dnd';
import { $, addDisposableListener, append, clearNode, EventHelper, trackFocus } from 'vs/base/browser/dom';
import { DomEmitter } from 'vs/base/browser/event';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { Orientation } from 'vs/base/browser/ui/sash/sash';
import { localize } from 'vs/nls';
import { Color, RGBA } from 'vs/base/common/color';
import { Emitter, Event } from 'vs/base/common/event';
import { KeyCode } from 'vs/base/common/keyCodes';
import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
import { ScrollEvent } from 'vs/base/common/scrollable';
import 'vs/css!./paneview';
import { localize } from 'vs/nls';
import { IView, SplitView } from './splitview';
export interface IPaneOptions {
minimumBodySize?: number;
@@ -38,11 +38,11 @@ export interface IPaneStyles {
/**
* A Pane is a structured SplitView view.
*
* WARNING: You must call `render()` after you contruct it.
* WARNING: You must call `render()` after you construct it.
* It can't be done automatically at the end of the ctor
* because of the order of property initialization in TypeScript.
* Subclasses wouldn't be able to set own properties
* before the `render()` call, thus forbiding their use.
* before the `render()` call, thus forbidding their use.
*/
export abstract class Pane extends Disposable implements IView {
@@ -220,8 +220,8 @@ export abstract class Pane extends Disposable implements IView {
this.updateHeader();
const onHeaderKeyDown = Event.chain(domEvent(this.header, 'keydown'))
const onKeyDown = this._register(new DomEmitter(this.header, 'keydown'));
const onHeaderKeyDown = Event.chain(onKeyDown.event)
.map(e => new StandardKeyboardEvent(e));
this._register(onHeaderKeyDown.filter(e => e.keyCode === KeyCode.Enter || e.keyCode === KeyCode.Space)
@@ -233,12 +233,11 @@ export abstract class Pane extends Disposable implements IView {
this._register(onHeaderKeyDown.filter(e => e.keyCode === KeyCode.RightArrow)
.event(() => this.setExpanded(true), null));
this._register(domEvent(this.header, 'click')
(e => {
if (!e.defaultPrevented) {
this.setExpanded(!this.isExpanded());
}
}, null));
this._register(addDisposableListener(this.header, 'click', e => {
if (!e.defaultPrevented) {
this.setExpanded(!this.isExpanded());
}
}));
this.body = append(this.element, $('.pane-body'));
this.renderBody(this.body);
@@ -308,11 +307,11 @@ class PaneDraggable extends Disposable {
super();
pane.draggableElement.draggable = true;
this._register(domEvent(pane.draggableElement, 'dragstart')(this.onDragStart, this));
this._register(domEvent(pane.dropTargetElement, 'dragenter')(this.onDragEnter, this));
this._register(domEvent(pane.dropTargetElement, 'dragleave')(this.onDragLeave, this));
this._register(domEvent(pane.dropTargetElement, 'dragend')(this.onDragEnd, this));
this._register(domEvent(pane.dropTargetElement, 'drop')(this.onDrop, this));
this._register(addDisposableListener(pane.draggableElement, 'dragstart', e => this.onDragStart(e)));
this._register(addDisposableListener(pane.dropTargetElement, 'dragenter', e => this.onDragEnter(e)));
this._register(addDisposableListener(pane.dropTargetElement, 'dragleave', e => this.onDragLeave(e)));
this._register(addDisposableListener(pane.dropTargetElement, 'dragend', e => this.onDragEnd(e)));
this._register(addDisposableListener(pane.dropTargetElement, 'drop', e => this.onDrop(e)));
}
private onDragStart(e: DragEvent): void {

View File

@@ -3,18 +3,17 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./splitview';
import { IDisposable, toDisposable, Disposable, combinedDisposable } from 'vs/base/common/lifecycle';
import { Event, Emitter } from 'vs/base/common/event';
import * as types from 'vs/base/common/types';
import { clamp } from 'vs/base/common/numbers';
import { range, pushToStart, pushToEnd } from 'vs/base/common/arrays';
import { Sash, Orientation, ISashEvent as IBaseSashEvent, SashState } from 'vs/base/browser/ui/sash/sash';
import { Color } from 'vs/base/common/color';
import { domEvent } from 'vs/base/browser/event';
import { $, append, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
import { $, addDisposableListener, append, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
import { ISashEvent as IBaseSashEvent, Orientation, Sash, SashState } from 'vs/base/browser/ui/sash/sash';
import { SmoothScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
import { pushToEnd, pushToStart, range } from 'vs/base/common/arrays';
import { Color } from 'vs/base/common/color';
import { Emitter, Event } from 'vs/base/common/event';
import { combinedDisposable, Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { clamp } from 'vs/base/common/numbers';
import { Scrollable, ScrollbarVisibility, ScrollEvent } from 'vs/base/common/scrollable';
import * as types from 'vs/base/common/types';
import 'vs/css!./splitview';
export { Orientation } from 'vs/base/browser/ui/sash/sash';
export interface ISplitViewStyles {
@@ -488,8 +487,8 @@ export class SplitView<TLayoutContext = undefined> extends Disposable {
// This way, we can press Alt while we resize a sash, macOS style!
const disposable = combinedDisposable(
domEvent(document.body, 'keydown')(e => resetSashDragState(this.sashDragState!.current, e.altKey)),
domEvent(document.body, 'keyup')(() => resetSashDragState(this.sashDragState!.current, false))
addDisposableListener(document.body, 'keydown', e => resetSashDragState(this.sashDragState!.current, e.altKey)),
addDisposableListener(document.body, 'keyup', () => resetSashDragState(this.sashDragState!.current, false))
);
const resetSashDragState = (start: number, alt: boolean) => {

View File

@@ -3,17 +3,17 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./table';
import { $, append, clearNode, createStyleSheet, getContentHeight, getContentWidth } from 'vs/base/browser/dom';
import { IListRenderer, IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { IListOptions, IListOptionsUpdate, IListStyles, List } from 'vs/base/browser/ui/list/listWidget';
import { ISplitViewDescriptor, IView, Orientation, SplitView } from 'vs/base/browser/ui/splitview/splitview';
import { ITableColumn, ITableContextMenuEvent, ITableEvent, ITableGestureEvent, ITableMouseEvent, ITableRenderer, ITableTouchEvent, ITableVirtualDelegate } from 'vs/base/browser/ui/table/table';
import { Emitter, Event } from 'vs/base/common/event';
import { IDisposable } from 'vs/base/common/lifecycle';
import { ScrollbarVisibility, ScrollEvent } from 'vs/base/common/scrollable';
import { ISpliceable } from 'vs/base/common/sequence';
import { IThemable } from 'vs/base/common/styler';
import { IDisposable } from 'vs/base/common/lifecycle';
import { $, append, clearNode, createStyleSheet, getContentHeight, getContentWidth } from 'vs/base/browser/dom';
import { ISplitViewDescriptor, IView, Orientation, SplitView } from 'vs/base/browser/ui/splitview/splitview';
import { IListRenderer, IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { Emitter, Event } from 'vs/base/common/event';
import { ScrollbarVisibility, ScrollEvent } from 'vs/base/common/scrollable';
import 'vs/css!./table';
// TODO@joao
type TCell = any;

View File

@@ -3,18 +3,18 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./toolbar';
import * as nls from 'vs/nls';
import { Action, IActionRunner, IAction, SubmenuAction } from 'vs/base/common/actions';
import { IContextMenuProvider } from 'vs/base/browser/contextmenu';
import { ActionBar, ActionsOrientation, IActionViewItemProvider } from 'vs/base/browser/ui/actionbar/actionbar';
import { ResolvedKeybinding } from 'vs/base/common/keyCodes';
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
import { withNullAsUndefined } from 'vs/base/common/types';
import { DropdownMenuActionViewItem } from 'vs/base/browser/ui/dropdown/dropdownActionViewItem';
import { Action, IAction, IActionRunner, SubmenuAction } from 'vs/base/common/actions';
import { Codicon, CSSIcon, registerCodicon } from 'vs/base/common/codicons';
import { EventMultiplexer } from 'vs/base/common/event';
import { DropdownMenuActionViewItem } from 'vs/base/browser/ui/dropdown/dropdownActionViewItem';
import { IContextMenuProvider } from 'vs/base/browser/contextmenu';
import { ResolvedKeybinding } from 'vs/base/common/keyCodes';
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { withNullAsUndefined } from 'vs/base/common/types';
import 'vs/css!./toolbar';
import * as nls from 'vs/nls';
const toolBarMoreIcon = registerCodicon('toolbar-more', Codicon.more);
@@ -103,7 +103,7 @@ export class ToolBar extends Disposable {
keybindingProvider: this.options.getKeyBinding,
classNames: action.class,
anchorAlignmentProvider: this.options.anchorAlignmentProvider,
menuAsChild: true
menuAsChild: !!this.options.renderDropdownAsChildElement
}
);
result.setActionContext(this.actionBar.context);
@@ -148,6 +148,18 @@ export class ToolBar extends Disposable {
return itemsWidth;
}
getItemAction(index: number) {
return this.actionBar.getAction(index);
}
getItemWidth(index: number): number {
return this.actionBar.getWidth(index);
}
getItemsLength(): number {
return this.actionBar.length();
}
setAriaLabel(label: string): void {
this.actionBar.setAriaLabel(label);
}
@@ -187,7 +199,7 @@ export class ToolBar extends Disposable {
}
}
class ToggleMenuAction extends Action {
export class ToggleMenuAction extends Action {
static readonly ID = 'toolbar.toggle.more';

View File

@@ -3,29 +3,29 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./media/tree';
import { IDisposable, dispose, Disposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { IListOptions, List, IListStyles, MouseController, DefaultKeyboardNavigationDelegate, isInputElement, isMonacoEditor } from 'vs/base/browser/ui/list/listWidget';
import { IListVirtualDelegate, IListRenderer, IListMouseEvent, IListContextMenuEvent, IListDragAndDrop, IListDragOverReaction, IKeyboardNavigationLabelProvider, IIdentityProvider, IKeyboardNavigationDelegate } from 'vs/base/browser/ui/list/list';
import { append, $, getDomNodePagePosition, hasParentWithClass, createStyleSheet, clearNode } from 'vs/base/browser/dom';
import { Event, Relay, Emitter, EventBufferer } from 'vs/base/common/event';
import { DragAndDropData, IDragAndDropData, StaticDND } from 'vs/base/browser/dnd';
import { $, addDisposableListener, append, clearNode, createStyleSheet, getDomNodePagePosition, hasParentWithClass } from 'vs/base/browser/dom';
import { DomEmitter } from 'vs/base/browser/event';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { ITreeModel, ITreeNode, ITreeRenderer, ITreeEvent, ITreeMouseEvent, ITreeContextMenuEvent, ITreeFilter, ITreeNavigator, ICollapseStateChangeEvent, ITreeDragAndDrop, TreeDragOverBubble, TreeVisibility, TreeFilterResult, ITreeModelSpliceEvent, TreeMouseEventTarget } from 'vs/base/browser/ui/tree/tree';
import { ISpliceable } from 'vs/base/common/sequence';
import { IDragAndDropData, StaticDND, DragAndDropData } from 'vs/base/browser/dnd';
import { range, equals, distinctES6, firstOrDefault } from 'vs/base/common/arrays';
import { IIdentityProvider, IKeyboardNavigationDelegate, IKeyboardNavigationLabelProvider, IListContextMenuEvent, IListDragAndDrop, IListDragOverReaction, IListMouseEvent, IListRenderer, IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView';
import { domEvent } from 'vs/base/browser/event';
import { fuzzyScore, FuzzyScore } from 'vs/base/common/filters';
import { DefaultKeyboardNavigationDelegate, IListOptions, IListStyles, isInputElement, isMonacoEditor, List, MouseController } from 'vs/base/browser/ui/list/listWidget';
import { getVisibleState, isFilterResult } from 'vs/base/browser/ui/tree/indexTreeModel';
import { localize } from 'vs/nls';
import { ICollapseStateChangeEvent, ITreeContextMenuEvent, ITreeDragAndDrop, ITreeEvent, ITreeFilter, ITreeModel, ITreeModelSpliceEvent, ITreeMouseEvent, ITreeNavigator, ITreeNode, ITreeRenderer, TreeDragOverBubble, TreeFilterResult, TreeMouseEventTarget, TreeVisibility } from 'vs/base/browser/ui/tree/tree';
import { treeFilterClearIcon, treeFilterOnTypeOffIcon, treeFilterOnTypeOnIcon, treeItemExpandedIcon } from 'vs/base/browser/ui/tree/treeIcons';
import { distinctES6, equals, firstOrDefault, range } from 'vs/base/common/arrays';
import { disposableTimeout } from 'vs/base/common/async';
import { isMacintosh } from 'vs/base/common/platform';
import { clamp } from 'vs/base/common/numbers';
import { ScrollEvent } from 'vs/base/common/scrollable';
import { SetMap } from 'vs/base/common/collections';
import { treeItemExpandedIcon, treeFilterOnTypeOnIcon, treeFilterOnTypeOffIcon, treeFilterClearIcon } from 'vs/base/browser/ui/tree/treeIcons';
import { Emitter, Event, EventBufferer, Relay } from 'vs/base/common/event';
import { fuzzyScore, FuzzyScore } from 'vs/base/common/filters';
import { KeyCode } from 'vs/base/common/keyCodes';
import { Disposable, DisposableStore, dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { clamp } from 'vs/base/common/numbers';
import { isMacintosh } from 'vs/base/common/platform';
import { ScrollEvent } from 'vs/base/common/scrollable';
import { ISpliceable } from 'vs/base/common/sequence';
import 'vs/css!./media/tree';
import { localize } from 'vs/nls';
class TreeElementsDragAndDropData<T, TFilterData, TContext> extends ElementsDragAndDropData<T, TContext> {
@@ -648,7 +648,7 @@ class TypeFilterController<T, TFilterData> implements IDisposable {
) {
this.domNode = $(`.monaco-list-type-filter.${this.positionClassName}`);
this.domNode.draggable = true;
domEvent(this.domNode, 'dragstart')(this.onDragStart, this, this.disposables);
this.disposables.add(addDisposableListener(this.domNode, 'dragstart', () => this.onDragStart()));
this.messageDomNode = append(view.getHTMLElement(), $(`.monaco-list-type-filter-message`));
@@ -661,7 +661,7 @@ class TypeFilterController<T, TFilterData> implements IDisposable {
this.filterOnTypeDomNode.checked = this._filterOnType;
this.filterOnTypeDomNode.tabIndex = -1;
this.updateFilterOnTypeTitleAndIcon();
domEvent(this.filterOnTypeDomNode, 'input')(this.onDidChangeFilterOnType, this, this.disposables);
this.disposables.add(addDisposableListener(this.filterOnTypeDomNode, 'input', () => this.onDidChangeFilterOnType()));
this.clearDomNode = append(controls, $<HTMLInputElement>('button.clear' + treeFilterClearIcon.cssSelector));
this.clearDomNode.tabIndex = -1;
@@ -711,7 +711,8 @@ class TypeFilterController<T, TFilterData> implements IDisposable {
return;
}
const onKeyDown = Event.chain(domEvent(this.view.getHTMLElement(), 'keydown'))
const onRawKeyDown = this.enabledDisposables.add(new DomEmitter(this.view.getHTMLElement(), 'keydown'));
const onKeyDown = Event.chain(onRawKeyDown.event)
.filter(e => !isInputElement(e.target as HTMLElement) || e.target === this.filterOnTypeDomNode)
.filter(e => e.key !== 'Dead' && !/^Media/.test(e.key))
.map(e => new StandardKeyboardEvent(e))
@@ -721,9 +722,9 @@ class TypeFilterController<T, TFilterData> implements IDisposable {
.forEach(e => { e.stopPropagation(); e.preventDefault(); })
.event;
const onClear = domEvent(this.clearDomNode, 'click');
const onClearClick = this.enabledDisposables.add(new DomEmitter(this.clearDomNode, 'click'));
Event.chain(Event.any<MouseEvent | StandardKeyboardEvent>(onKeyDown, onClear))
Event.chain(Event.any<MouseEvent | StandardKeyboardEvent>(onKeyDown, onClearClick.event))
.event(this.onEventOrInput, this, this.enabledDisposables);
this.filter.pattern = '';
@@ -849,8 +850,8 @@ class TypeFilterController<T, TFilterData> implements IDisposable {
this.domNode.classList.add('dragging');
disposables.add(toDisposable(() => this.domNode.classList.remove('dragging')));
domEvent(document, 'dragover')(onDragOver, null, disposables);
domEvent(this.domNode, 'dragend')(onDragEnd, null, disposables);
disposables.add(addDisposableListener(document, 'dragover', e => onDragOver(e)));
disposables.add(addDisposableListener(this.domNode, 'dragend', () => onDragEnd()));
StaticDND.CurrentDragAndDropData = new DragAndDropData('vscode-ui');
disposables.add(toDisposable(() => StaticDND.CurrentDragAndDropData = undefined));
@@ -957,11 +958,14 @@ export interface IKeyboardNavigationEventFilter {
}
export interface IAbstractTreeOptionsUpdate extends ITreeRendererOptions {
readonly multipleSelectionSupport?: boolean;
readonly automaticKeyboardNavigation?: boolean;
readonly simpleKeyboardNavigation?: boolean;
readonly filterOnType?: boolean;
readonly smoothScrolling?: boolean;
readonly horizontalScrolling?: boolean;
readonly mouseWheelScrollSensitivity?: number;
readonly fastScrollSensitivity?: number;
readonly expandOnDoubleClick?: boolean;
readonly expandOnlyOnTwistieClick?: boolean | ((e: any) => boolean); // e is T
}
@@ -1000,7 +1004,10 @@ class Trait<T> {
return this._nodeSet;
}
constructor(private identityProvider?: IIdentityProvider<T>) { }
constructor(
private getFirstViewElementWithTrait: () => ITreeNode<T, any> | undefined,
private identityProvider?: IIdentityProvider<T>
) { }
set(nodes: ITreeNode<T, any>[], browserEvent?: UIEvent): void {
if (!(browserEvent as any)?.__forceEvent && equals(this.nodes, nodes)) {
@@ -1071,6 +1078,14 @@ class Trait<T> {
}
}
if (this.nodes.length > 0 && nodes.length === 0) {
const node = this.getFirstViewElementWithTrait();
if (node) {
nodes.push(node);
}
}
this._set(nodes, true);
}
@@ -1320,9 +1335,9 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
this.disposables.add(filter);
}
this.focus = new Trait(_options.identityProvider);
this.selection = new Trait(_options.identityProvider);
this.anchor = new Trait(_options.identityProvider);
this.focus = new Trait(() => this.view.getFocusedElements()[0], _options.identityProvider);
this.selection = new Trait(() => this.view.getSelectedElements()[0], _options.identityProvider);
this.anchor = new Trait(() => this.view.getAnchorElement(), _options.identityProvider);
this.view = new TreeNodeList(user, container, treeDelegate, this.renderers, this.focus, this.selection, this.anchor, { ...asListOptions(() => this.model, _options), tree: this });
this.model = this.createModel(user, this.view, _options);
@@ -1387,10 +1402,8 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
}
this.view.updateOptions({
...this._options,
enableKeyboardNavigation: this._options.simpleKeyboardNavigation,
automaticKeyboardNavigation: this._options.automaticKeyboardNavigation,
smoothScrolling: this._options.smoothScrolling,
horizontalScrolling: this._options.horizontalScrolling
});
if (this.typeFilterController) {

View File

@@ -3,23 +3,23 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ComposedTreeDelegate, IAbstractTreeOptions, IAbstractTreeOptionsUpdate } from 'vs/base/browser/ui/tree/abstractTree';
import { ObjectTree, IObjectTreeOptions, CompressibleObjectTree, ICompressibleTreeRenderer, ICompressibleKeyboardNavigationLabelProvider, ICompressibleObjectTreeOptions, IObjectTreeSetChildrenOptions } from 'vs/base/browser/ui/tree/objectTree';
import { IListVirtualDelegate, IIdentityProvider, IListDragAndDrop, IListDragOverReaction } from 'vs/base/browser/ui/list/list';
import { ITreeElement, ITreeNode, ITreeRenderer, ITreeEvent, ITreeMouseEvent, ITreeContextMenuEvent, ITreeSorter, ICollapseStateChangeEvent, IAsyncDataSource, ITreeDragAndDrop, TreeError, WeakMapper, ITreeFilter, TreeVisibility, TreeFilterResult } from 'vs/base/browser/ui/tree/tree';
import { IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle';
import { Emitter, Event } from 'vs/base/common/event';
import { timeout, CancelablePromise, createCancelablePromise, Promises } from 'vs/base/common/async';
import { IListStyles } from 'vs/base/browser/ui/list/listWidget';
import { Iterable } from 'vs/base/common/iterator';
import { IDragAndDropData } from 'vs/base/browser/dnd';
import { IIdentityProvider, IListDragAndDrop, IListDragOverReaction, IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView';
import { isPromiseCanceledError, onUnexpectedError } from 'vs/base/common/errors';
import { ScrollEvent } from 'vs/base/common/scrollable';
import { ICompressedTreeNode, ICompressedTreeElement } from 'vs/base/browser/ui/tree/compressedObjectTreeModel';
import { IThemable } from 'vs/base/common/styler';
import { isFilterResult, getVisibleState } from 'vs/base/browser/ui/tree/indexTreeModel';
import { IListStyles } from 'vs/base/browser/ui/list/listWidget';
import { ComposedTreeDelegate, IAbstractTreeOptions, IAbstractTreeOptionsUpdate } from 'vs/base/browser/ui/tree/abstractTree';
import { ICompressedTreeElement, ICompressedTreeNode } from 'vs/base/browser/ui/tree/compressedObjectTreeModel';
import { getVisibleState, isFilterResult } from 'vs/base/browser/ui/tree/indexTreeModel';
import { CompressibleObjectTree, ICompressibleKeyboardNavigationLabelProvider, ICompressibleObjectTreeOptions, ICompressibleTreeRenderer, IObjectTreeOptions, IObjectTreeSetChildrenOptions, ObjectTree } from 'vs/base/browser/ui/tree/objectTree';
import { IAsyncDataSource, ICollapseStateChangeEvent, ITreeContextMenuEvent, ITreeDragAndDrop, ITreeElement, ITreeEvent, ITreeFilter, ITreeMouseEvent, ITreeNode, ITreeRenderer, ITreeSorter, TreeError, TreeFilterResult, TreeVisibility, WeakMapper } from 'vs/base/browser/ui/tree/tree';
import { treeItemLoadingIcon } from 'vs/base/browser/ui/tree/treeIcons';
import { CancelablePromise, createCancelablePromise, Promises, timeout } from 'vs/base/common/async';
import { isPromiseCanceledError, onUnexpectedError } from 'vs/base/common/errors';
import { Emitter, Event } from 'vs/base/common/event';
import { Iterable } from 'vs/base/common/iterator';
import { DisposableStore, dispose, IDisposable } from 'vs/base/common/lifecycle';
import { ScrollEvent } from 'vs/base/common/scrollable';
import { IThemable } from 'vs/base/common/styler';
interface IAsyncDataTreeNode<TInput, T> {
element: TInput | T;

View File

@@ -3,12 +3,12 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Iterable } from 'vs/base/common/iterator';
import { Event } from 'vs/base/common/event';
import { ITreeModel, ITreeNode, ITreeElement, ICollapseStateChangeEvent, ITreeModelSpliceEvent, TreeError, TreeFilterResult, TreeVisibility, WeakMapper } from 'vs/base/browser/ui/tree/tree';
import { IObjectTreeModelOptions, ObjectTreeModel, IObjectTreeModel, IObjectTreeModelSetChildrenOptions } from 'vs/base/browser/ui/tree/objectTreeModel';
import { IIndexTreeModelSpliceOptions, IList } from 'vs/base/browser/ui/tree/indexTreeModel';
import { IIdentityProvider } from 'vs/base/browser/ui/list/list';
import { IIndexTreeModelSpliceOptions, IList } from 'vs/base/browser/ui/tree/indexTreeModel';
import { IObjectTreeModel, IObjectTreeModelOptions, IObjectTreeModelSetChildrenOptions, ObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel';
import { ICollapseStateChangeEvent, ITreeElement, ITreeModel, ITreeModelSpliceEvent, ITreeNode, TreeError, TreeFilterResult, TreeVisibility, WeakMapper } from 'vs/base/browser/ui/tree/tree';
import { Event } from 'vs/base/common/event';
import { Iterable } from 'vs/base/common/iterator';
// Exported only for test reasons, do not use directly
export interface ICompressedTreeElement<T> extends ITreeElement<T> {

View File

@@ -3,12 +3,12 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IIdentityProvider, IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { AbstractTree, IAbstractTreeOptions } from 'vs/base/browser/ui/tree/abstractTree';
import { ITreeNode, ITreeModel, ITreeElement, ITreeRenderer, ITreeSorter, IDataSource, TreeError } from 'vs/base/browser/ui/tree/tree';
import { ObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel';
import { IListVirtualDelegate, IIdentityProvider } from 'vs/base/browser/ui/list/list';
import { Iterable } from 'vs/base/common/iterator';
import { IList } from 'vs/base/browser/ui/tree/indexTreeModel';
import { ObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel';
import { IDataSource, ITreeElement, ITreeModel, ITreeNode, ITreeRenderer, ITreeSorter, TreeError } from 'vs/base/browser/ui/tree/tree';
import { Iterable } from 'vs/base/common/iterator';
export interface IDataTreeOptions<T, TFilterData = void> extends IAbstractTreeOptions<T, TFilterData> {
readonly sorter?: ITreeSorter<T>;

View File

@@ -3,12 +3,12 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./media/tree';
import { Iterable } from 'vs/base/common/iterator';
import { AbstractTree, IAbstractTreeOptions } from 'vs/base/browser/ui/tree/abstractTree';
import { IndexTreeModel, IList } from 'vs/base/browser/ui/tree/indexTreeModel';
import { ITreeElement, ITreeModel, ITreeNode, ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { AbstractTree, IAbstractTreeOptions } from 'vs/base/browser/ui/tree/abstractTree';
import { IList, IndexTreeModel } from 'vs/base/browser/ui/tree/indexTreeModel';
import { ITreeElement, ITreeModel, ITreeNode, ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
import { Iterable } from 'vs/base/common/iterator';
import 'vs/css!./media/tree';
export interface IIndexTreeOptions<T, TFilterData = void> extends IAbstractTreeOptions<T, TFilterData> { }

View File

@@ -4,8 +4,8 @@
*--------------------------------------------------------------------------------------------*/
import { IIdentityProvider } from 'vs/base/browser/ui/list/list';
import { ICollapseStateChangeEvent, ITreeElement, ITreeFilter, ITreeFilterDataResult, ITreeModel, ITreeNode, TreeVisibility, ITreeModelSpliceEvent, TreeError } from 'vs/base/browser/ui/tree/tree';
import { tail2 } from 'vs/base/common/arrays';
import { ICollapseStateChangeEvent, ITreeElement, ITreeFilter, ITreeFilterDataResult, ITreeModel, ITreeModelSpliceEvent, ITreeNode, TreeError, TreeVisibility } from 'vs/base/browser/ui/tree/tree';
import { splice, tail2 } from 'vs/base/common/arrays';
import { LcsDiff } from 'vs/base/common/diff/diff';
import { Emitter, Event, EventBufferer } from 'vs/base/common/event';
import { Iterable } from 'vs/base/common/iterator';
@@ -256,7 +256,7 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
}
}
const deletedNodes = parentNode.children.splice(lastIndex, deleteCount, ...nodesToInsert);
const deletedNodes = splice(parentNode.children, lastIndex, deleteCount, nodesToInsert);
// figure out what is the count of deleted visible children
let deletedVisibleChildrenCount = 0;

View File

@@ -47,7 +47,6 @@
display: flex !important;
align-items: center;
justify-content: center;
color: inherit !important;
transform: translateX(3px);
}

View File

@@ -3,15 +3,15 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Iterable } from 'vs/base/common/iterator';
import { IIdentityProvider, IKeyboardNavigationLabelProvider, IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { AbstractTree, IAbstractTreeOptions, IAbstractTreeOptionsUpdate } from 'vs/base/browser/ui/tree/abstractTree';
import { ITreeNode, ITreeModel, ITreeElement, ITreeRenderer, ITreeSorter, ICollapseStateChangeEvent } from 'vs/base/browser/ui/tree/tree';
import { ObjectTreeModel, IObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel';
import { IListVirtualDelegate, IKeyboardNavigationLabelProvider, IIdentityProvider } from 'vs/base/browser/ui/list/list';
import { Event } from 'vs/base/common/event';
import { CompressibleObjectTreeModel, ElementMapper, ICompressedTreeNode, ICompressedTreeElement } from 'vs/base/browser/ui/tree/compressedObjectTreeModel';
import { memoize } from 'vs/base/common/decorators';
import { CompressibleObjectTreeModel, ElementMapper, ICompressedTreeElement, ICompressedTreeNode } from 'vs/base/browser/ui/tree/compressedObjectTreeModel';
import { IList } from 'vs/base/browser/ui/tree/indexTreeModel';
import { IObjectTreeModel, ObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel';
import { ICollapseStateChangeEvent, ITreeElement, ITreeModel, ITreeNode, ITreeRenderer, ITreeSorter } from 'vs/base/browser/ui/tree/tree';
import { memoize } from 'vs/base/common/decorators';
import { Event } from 'vs/base/common/event';
import { Iterable } from 'vs/base/common/iterator';
export interface IObjectTreeOptions<T, TFilterData = void> extends IAbstractTreeOptions<T, TFilterData> {
readonly sorter?: ITreeSorter<T>;

View File

@@ -3,11 +3,11 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Iterable } from 'vs/base/common/iterator';
import { IndexTreeModel, IIndexTreeModelOptions, IList, IIndexTreeModelSpliceOptions } from 'vs/base/browser/ui/tree/indexTreeModel';
import { Event } from 'vs/base/common/event';
import { ITreeModel, ITreeNode, ITreeElement, ITreeSorter, ICollapseStateChangeEvent, ITreeModelSpliceEvent, TreeError } from 'vs/base/browser/ui/tree/tree';
import { IIdentityProvider } from 'vs/base/browser/ui/list/list';
import { IIndexTreeModelOptions, IIndexTreeModelSpliceOptions, IList, IndexTreeModel } from 'vs/base/browser/ui/tree/indexTreeModel';
import { ICollapseStateChangeEvent, ITreeElement, ITreeModel, ITreeModelSpliceEvent, ITreeNode, ITreeSorter, TreeError } from 'vs/base/browser/ui/tree/tree';
import { Event } from 'vs/base/common/event';
import { Iterable } from 'vs/base/common/iterator';
export type ITreeNodeCallback<T, TFilterData> = (node: ITreeNode<T, TFilterData>) => void;

View File

@@ -3,9 +3,9 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Event } from 'vs/base/common/event';
import { IListRenderer, IListDragOverReaction, IListDragAndDrop, ListDragOverEffect } from 'vs/base/browser/ui/list/list';
import { IDragAndDropData } from 'vs/base/browser/dnd';
import { IListDragAndDrop, IListDragOverReaction, IListRenderer, ListDragOverEffect } from 'vs/base/browser/ui/list/list';
import { Event } from 'vs/base/common/event';
export const enum TreeVisibility {

View File

@@ -3,9 +3,9 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vs/nls';
import { Action } from 'vs/base/common/actions';
import { AsyncDataTree } from 'vs/base/browser/ui/tree/asyncDataTree';
import { Action } from 'vs/base/common/actions';
import * as nls from 'vs/nls';
export class CollapseAllAction<TInput, T, TFilterData = void> extends Action {

View File

@@ -6,8 +6,8 @@
import * as dom from 'vs/base/browser/dom';
import { IKeyboardEvent, StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { IMouseEvent, StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { Disposable } from 'vs/base/common/lifecycle';
import { Gesture } from 'vs/base/browser/touch';
import { Disposable } from 'vs/base/common/lifecycle';
export abstract class Widget extends Disposable {