chore(vscode): update to 1.56.0
This commit is contained in:
@ -20,7 +20,7 @@ export interface IContextMenuDelegate {
|
||||
getActions(): readonly IAction[];
|
||||
getCheckedActionsRepresentation?(action: IAction): 'radio' | 'checkbox';
|
||||
getActionViewItem?(action: IAction): IActionViewItem | undefined;
|
||||
getActionsContext?(event?: IContextMenuEvent): any;
|
||||
getActionsContext?(event?: IContextMenuEvent): unknown;
|
||||
getKeyBinding?(action: IAction): ResolvedKeybinding | undefined;
|
||||
getMenuClassName?(): string;
|
||||
onHide?(didCancel: boolean): void;
|
||||
|
@ -42,7 +42,7 @@ export class DelayedDragHandler extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
override dispose(): void {
|
||||
super.dispose();
|
||||
|
||||
this.clearDragTimeout();
|
||||
@ -89,7 +89,7 @@ export function applyDragImage(event: DragEvent, label: string | null, clazz: st
|
||||
|
||||
export interface IDragAndDropData {
|
||||
update(dataTransfer: DataTransfer): void;
|
||||
getData(): any;
|
||||
getData(): unknown;
|
||||
}
|
||||
|
||||
export class DragAndDropData<T> implements IDragAndDropData {
|
||||
|
@ -1193,18 +1193,21 @@ export function computeScreenAwareSize(cssPx: number): number {
|
||||
* to change the location of the current page.
|
||||
* See https://mathiasbynens.github.io/rel-noopener/
|
||||
*/
|
||||
export function windowOpenNoOpener(url: string): void {
|
||||
export function windowOpenNoOpener(url: string): boolean {
|
||||
if (browser.isElectron || browser.isEdgeLegacyWebView) {
|
||||
// In VSCode, window.open() always returns null...
|
||||
// The same is true for a WebView (see https://github.com/microsoft/monaco-editor/issues/628)
|
||||
// Also call directly window.open in sandboxed Electron (see https://github.com/microsoft/monaco-editor/issues/2220)
|
||||
window.open(url);
|
||||
return true;
|
||||
} else {
|
||||
let newTab = window.open();
|
||||
if (newTab) {
|
||||
(newTab as any).opener = null;
|
||||
newTab.location.href = url;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1409,37 +1412,8 @@ export function multibyteAwareBtoa(str: string): string {
|
||||
*/
|
||||
export namespace WebFileSystemAccess {
|
||||
|
||||
// https://wicg.github.io/file-system-access/#dom-window-showdirectorypicker
|
||||
export interface FileSystemAccess {
|
||||
showDirectoryPicker: () => Promise<FileSystemDirectoryHandle>;
|
||||
}
|
||||
|
||||
// https://wicg.github.io/file-system-access/#api-filesystemdirectoryhandle
|
||||
export interface FileSystemDirectoryHandle {
|
||||
readonly kind: 'directory',
|
||||
readonly name: string,
|
||||
|
||||
getFileHandle: (name: string, options?: { create?: boolean }) => Promise<FileSystemFileHandle>;
|
||||
getDirectoryHandle: (name: string, options?: { create?: boolean }) => Promise<FileSystemDirectoryHandle>;
|
||||
}
|
||||
|
||||
// https://wicg.github.io/file-system-access/#api-filesystemfilehandle
|
||||
export interface FileSystemFileHandle {
|
||||
readonly kind: 'file',
|
||||
readonly name: string,
|
||||
|
||||
createWritable: (options?: { keepExistingData?: boolean }) => Promise<FileSystemWritableFileStream>;
|
||||
}
|
||||
|
||||
// https://wicg.github.io/file-system-access/#api-filesystemwritablefilestream
|
||||
export interface FileSystemWritableFileStream {
|
||||
write: (buffer: Uint8Array) => Promise<void>;
|
||||
close: () => Promise<void>;
|
||||
}
|
||||
|
||||
export function supported(obj: any & Window): obj is FileSystemAccess {
|
||||
const candidate = obj as FileSystemAccess | undefined;
|
||||
if (typeof candidate?.showDirectoryPicker === 'function') {
|
||||
export function supported(obj: any & Window): boolean {
|
||||
if (typeof obj?.showDirectoryPicker === 'function') {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1589,7 +1563,7 @@ export class ModifierKeyEmitter extends Emitter<IModifierKeyStatus> {
|
||||
return ModifierKeyEmitter.instance;
|
||||
}
|
||||
|
||||
dispose() {
|
||||
override dispose() {
|
||||
super.dispose();
|
||||
this._subscriptions.dispose();
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ export type EventHandler = HTMLElement | HTMLDocument | Window;
|
||||
|
||||
export interface IDomEvent {
|
||||
<K extends keyof HTMLElementEventMap>(element: EventHandler, type: K, useCapture?: boolean): BaseEvent<HTMLElementEventMap[K]>;
|
||||
(element: EventHandler, type: string, useCapture?: boolean): BaseEvent<any>;
|
||||
(element: EventHandler, type: string, useCapture?: boolean): BaseEvent<unknown>;
|
||||
}
|
||||
|
||||
export const domEvent: IDomEvent = (element: EventHandler, type: string, useCapture?: boolean) => {
|
||||
|
@ -16,6 +16,7 @@ export interface FormattedTextRenderOptions {
|
||||
readonly className?: string;
|
||||
readonly inline?: boolean;
|
||||
readonly actionHandler?: IContentActionHandler;
|
||||
readonly renderCodeSegements?: boolean;
|
||||
}
|
||||
|
||||
export function renderText(text: string, options: FormattedTextRenderOptions = {}): HTMLElement {
|
||||
@ -26,7 +27,7 @@ export function renderText(text: string, options: FormattedTextRenderOptions = {
|
||||
|
||||
export function renderFormattedText(formattedText: string, options: FormattedTextRenderOptions = {}): HTMLElement {
|
||||
const element = createElement(options);
|
||||
_renderFormattedText(element, parseFormattedText(formattedText), options.actionHandler);
|
||||
_renderFormattedText(element, parseFormattedText(formattedText, !!options.renderCodeSegements), options.actionHandler, options.renderCodeSegements);
|
||||
return element;
|
||||
}
|
||||
|
||||
@ -75,6 +76,7 @@ const enum FormatType {
|
||||
Italics,
|
||||
Action,
|
||||
ActionClose,
|
||||
Code,
|
||||
NewLine
|
||||
}
|
||||
|
||||
@ -85,7 +87,7 @@ interface IFormatParseTree {
|
||||
children?: IFormatParseTree[];
|
||||
}
|
||||
|
||||
function _renderFormattedText(element: Node, treeNode: IFormatParseTree, actionHandler?: IContentActionHandler) {
|
||||
function _renderFormattedText(element: Node, treeNode: IFormatParseTree, actionHandler?: IContentActionHandler, renderCodeSegements?: boolean) {
|
||||
let child: Node | undefined;
|
||||
|
||||
if (treeNode.type === FormatType.Text) {
|
||||
@ -94,6 +96,8 @@ function _renderFormattedText(element: Node, treeNode: IFormatParseTree, actionH
|
||||
child = document.createElement('b');
|
||||
} else if (treeNode.type === FormatType.Italics) {
|
||||
child = document.createElement('i');
|
||||
} else if (treeNode.type === FormatType.Code && renderCodeSegements) {
|
||||
child = document.createElement('code');
|
||||
} else if (treeNode.type === FormatType.Action && actionHandler) {
|
||||
const a = document.createElement('a');
|
||||
a.href = '#';
|
||||
@ -114,12 +118,12 @@ function _renderFormattedText(element: Node, treeNode: IFormatParseTree, actionH
|
||||
|
||||
if (child && Array.isArray(treeNode.children)) {
|
||||
treeNode.children.forEach((nodeChild) => {
|
||||
_renderFormattedText(child!, nodeChild, actionHandler);
|
||||
_renderFormattedText(child!, nodeChild, actionHandler, renderCodeSegements);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function parseFormattedText(content: string): IFormatParseTree {
|
||||
function parseFormattedText(content: string, parseCodeSegments: boolean): IFormatParseTree {
|
||||
|
||||
const root: IFormatParseTree = {
|
||||
type: FormatType.Root,
|
||||
@ -134,19 +138,19 @@ function parseFormattedText(content: string): IFormatParseTree {
|
||||
while (!stream.eos()) {
|
||||
let next = stream.next();
|
||||
|
||||
const isEscapedFormatType = (next === '\\' && formatTagType(stream.peek()) !== FormatType.Invalid);
|
||||
const isEscapedFormatType = (next === '\\' && formatTagType(stream.peek(), parseCodeSegments) !== FormatType.Invalid);
|
||||
if (isEscapedFormatType) {
|
||||
next = stream.next(); // unread the backslash if it escapes a format tag type
|
||||
}
|
||||
|
||||
if (!isEscapedFormatType && isFormatTag(next) && next === stream.peek()) {
|
||||
if (!isEscapedFormatType && isFormatTag(next, parseCodeSegments) && next === stream.peek()) {
|
||||
stream.advance();
|
||||
|
||||
if (current.type === FormatType.Text) {
|
||||
current = stack.pop()!;
|
||||
}
|
||||
|
||||
const type = formatTagType(next);
|
||||
const type = formatTagType(next, parseCodeSegments);
|
||||
if (current.type === type || (current.type === FormatType.Action && type === FormatType.ActionClose)) {
|
||||
current = stack.pop()!;
|
||||
} else {
|
||||
@ -200,11 +204,11 @@ function parseFormattedText(content: string): IFormatParseTree {
|
||||
return root;
|
||||
}
|
||||
|
||||
function isFormatTag(char: string): boolean {
|
||||
return formatTagType(char) !== FormatType.Invalid;
|
||||
function isFormatTag(char: string, supportCodeSegments: boolean): boolean {
|
||||
return formatTagType(char, supportCodeSegments) !== FormatType.Invalid;
|
||||
}
|
||||
|
||||
function formatTagType(char: string): FormatType {
|
||||
function formatTagType(char: string, supportCodeSegments: boolean): FormatType {
|
||||
switch (char) {
|
||||
case '*':
|
||||
return FormatType.Bold;
|
||||
@ -214,6 +218,8 @@ function formatTagType(char: string): FormatType {
|
||||
return FormatType.Action;
|
||||
case ']':
|
||||
return FormatType.ActionClose;
|
||||
case '`':
|
||||
return supportCodeSegments ? FormatType.Code : FormatType.Invalid;
|
||||
default:
|
||||
return FormatType.Invalid;
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ export class Gesture extends Disposable {
|
||||
return 'ontouchstart' in window || navigator.maxTouchPoints > 0 || (window as Window).navigator.msMaxTouchPoints > 0;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
public override dispose(): void {
|
||||
if (this.handle) {
|
||||
this.handle.dispose();
|
||||
this.handle = null;
|
||||
|
@ -27,12 +27,12 @@ export class BaseActionViewItem extends Disposable implements IActionViewItem {
|
||||
|
||||
element: HTMLElement | undefined;
|
||||
|
||||
_context: any;
|
||||
_context: unknown;
|
||||
_action: IAction;
|
||||
|
||||
private _actionRunner: IActionRunner | undefined;
|
||||
|
||||
constructor(context: any, action: IAction, protected options: IBaseActionViewItemOptions = {}) {
|
||||
constructor(context: unknown, action: IAction, protected options: IBaseActionViewItemOptions = {}) {
|
||||
super();
|
||||
|
||||
this._context = context || this;
|
||||
@ -174,6 +174,10 @@ export class BaseActionViewItem extends Disposable implements IActionViewItem {
|
||||
}
|
||||
}
|
||||
|
||||
isFocused(): boolean {
|
||||
return !!this.element?.classList.contains('focused');
|
||||
}
|
||||
|
||||
blur(): void {
|
||||
if (this.element) {
|
||||
this.element.blur();
|
||||
@ -212,7 +216,7 @@ export class BaseActionViewItem extends Disposable implements IActionViewItem {
|
||||
// implement in subclass
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
override dispose(): void {
|
||||
if (this.element) {
|
||||
this.element.remove();
|
||||
this.element = undefined;
|
||||
@ -231,7 +235,7 @@ export interface IActionViewItemOptions extends IBaseActionViewItemOptions {
|
||||
export class ActionViewItem extends BaseActionViewItem {
|
||||
|
||||
protected label: HTMLElement | undefined;
|
||||
protected options: IActionViewItemOptions;
|
||||
protected override options: IActionViewItemOptions;
|
||||
|
||||
private cssClass?: string;
|
||||
|
||||
@ -244,7 +248,7 @@ export class ActionViewItem extends BaseActionViewItem {
|
||||
this.cssClass = '';
|
||||
}
|
||||
|
||||
render(container: HTMLElement): void {
|
||||
override render(container: HTMLElement): void {
|
||||
super.render(container);
|
||||
|
||||
if (this.element) {
|
||||
@ -276,32 +280,36 @@ export class ActionViewItem extends BaseActionViewItem {
|
||||
|
||||
// Only set the tabIndex on the element once it is about to get focused
|
||||
// That way this element wont be a tab stop when it is not needed #106441
|
||||
focus(): void {
|
||||
override focus(): void {
|
||||
if (this.label) {
|
||||
this.label.tabIndex = 0;
|
||||
this.label.focus();
|
||||
}
|
||||
}
|
||||
|
||||
blur(): void {
|
||||
override isFocused(): boolean {
|
||||
return !!this.label && this.label?.tabIndex === 0;
|
||||
}
|
||||
|
||||
override blur(): void {
|
||||
if (this.label) {
|
||||
this.label.tabIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
setFocusable(focusable: boolean): void {
|
||||
override setFocusable(focusable: boolean): void {
|
||||
if (this.label) {
|
||||
this.label.tabIndex = focusable ? 0 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
updateLabel(): void {
|
||||
override updateLabel(): void {
|
||||
if (this.options.label && this.label) {
|
||||
this.label.textContent = this.getAction().label;
|
||||
}
|
||||
}
|
||||
|
||||
updateTooltip(): void {
|
||||
override updateTooltip(): void {
|
||||
let title: string | null = null;
|
||||
|
||||
if (this.getAction().tooltip) {
|
||||
@ -320,7 +328,7 @@ export class ActionViewItem extends BaseActionViewItem {
|
||||
}
|
||||
}
|
||||
|
||||
updateClass(): void {
|
||||
override updateClass(): void {
|
||||
if (this.cssClass && this.label) {
|
||||
this.label.classList.remove(...this.cssClass.split(' '));
|
||||
}
|
||||
@ -343,7 +351,7 @@ export class ActionViewItem extends BaseActionViewItem {
|
||||
}
|
||||
}
|
||||
|
||||
updateEnabled(): void {
|
||||
override updateEnabled(): void {
|
||||
if (this.getAction().enabled) {
|
||||
if (this.label) {
|
||||
this.label.removeAttribute('aria-disabled');
|
||||
@ -365,7 +373,7 @@ export class ActionViewItem extends BaseActionViewItem {
|
||||
}
|
||||
}
|
||||
|
||||
updateChecked(): void {
|
||||
override updateChecked(): void {
|
||||
if (this.label) {
|
||||
if (this.getAction().checked) {
|
||||
this.label.classList.add('checked');
|
||||
@ -407,23 +415,23 @@ export class SelectActionViewItem extends BaseActionViewItem {
|
||||
return option;
|
||||
}
|
||||
|
||||
setFocusable(focusable: boolean): void {
|
||||
override setFocusable(focusable: boolean): void {
|
||||
this.selectBox.setFocusable(focusable);
|
||||
}
|
||||
|
||||
focus(): void {
|
||||
override focus(): void {
|
||||
if (this.selectBox) {
|
||||
this.selectBox.focus();
|
||||
}
|
||||
}
|
||||
|
||||
blur(): void {
|
||||
override blur(): void {
|
||||
if (this.selectBox) {
|
||||
this.selectBox.blur();
|
||||
}
|
||||
}
|
||||
|
||||
render(container: HTMLElement): void {
|
||||
override render(container: HTMLElement): void {
|
||||
this.selectBox.render(container);
|
||||
}
|
||||
}
|
||||
|
@ -4,16 +4,17 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-action-bar {
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.monaco-action-bar .actions-container {
|
||||
display: flex;
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.monaco-action-bar.vertical .actions-container {
|
||||
@ -21,9 +22,10 @@
|
||||
}
|
||||
|
||||
.monaco-action-bar .action-item {
|
||||
display: block;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
transition: transform 50ms ease;
|
||||
position: relative; /* DO NOT REMOVE - this is the key to preventing the ghosting icon bug in Chrome 42 */
|
||||
}
|
||||
|
||||
@ -31,23 +33,22 @@
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.monaco-action-bar.animated .action-item.active {
|
||||
transform: scale(1.272019649, 1.272019649); /* 1.272019649 = √φ */
|
||||
}
|
||||
|
||||
.monaco-action-bar .action-item .icon,
|
||||
.monaco-action-bar .action-item .codicon {
|
||||
display: inline-block;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.monaco-action-bar .action-item .codicon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.monaco-action-bar .action-label {
|
||||
font-size: 11px;
|
||||
margin-right: 4px;
|
||||
padding: 3px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.monaco-action-bar .action-item.disabled .action-label,
|
||||
@ -74,10 +75,6 @@
|
||||
margin-right: .8em;
|
||||
}
|
||||
|
||||
.monaco-action-bar.animated.vertical .action-item.active {
|
||||
transform: translate(5px, 0);
|
||||
}
|
||||
|
||||
.secondary-actions .monaco-action-bar .action-label {
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import { IActionViewItemOptions, ActionViewItem, BaseActionViewItem } from 'vs/b
|
||||
|
||||
export interface IActionViewItem extends IDisposable {
|
||||
actionRunner: IActionRunner;
|
||||
setActionContext(context: any): void;
|
||||
setActionContext(context: unknown): void;
|
||||
render(element: HTMLElement): void;
|
||||
isEnabled(): boolean;
|
||||
focus(fromRight?: boolean): void; // TODO@isidorn what is this?
|
||||
@ -38,7 +38,7 @@ export interface ActionTrigger {
|
||||
|
||||
export interface IActionBarOptions {
|
||||
readonly orientation?: ActionsOrientation;
|
||||
readonly context?: any;
|
||||
readonly context?: unknown;
|
||||
readonly actionViewItemProvider?: IActionViewItemProvider;
|
||||
readonly actionRunner?: IActionRunner;
|
||||
readonly ariaLabel?: string;
|
||||
@ -264,11 +264,11 @@ export class ActionBar extends Disposable implements IActionRunner {
|
||||
}
|
||||
}
|
||||
|
||||
get context(): any {
|
||||
get context(): unknown {
|
||||
return this._context;
|
||||
}
|
||||
|
||||
set context(context: any) {
|
||||
set context(context: unknown) {
|
||||
this._context = context;
|
||||
this.viewItems.forEach(i => i.setActionContext(context));
|
||||
}
|
||||
@ -525,11 +525,11 @@ export class ActionBar extends Disposable implements IActionRunner {
|
||||
}
|
||||
}
|
||||
|
||||
run(action: IAction, context?: unknown): Promise<void> {
|
||||
return this._actionRunner.run(action, context);
|
||||
async run(action: IAction, context?: unknown): Promise<void> {
|
||||
await this._actionRunner.run(action, context);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
override dispose(): void {
|
||||
dispose(this.viewItems);
|
||||
this.viewItems = [];
|
||||
|
||||
|
@ -24,6 +24,9 @@
|
||||
height: 100%;
|
||||
outline: none;
|
||||
}
|
||||
.monaco-breadcrumbs.disabled .monaco-breadcrumb-item {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.monaco-breadcrumbs .monaco-breadcrumb-item .codicon-breadcrumb-separator {
|
||||
color: inherit;
|
||||
|
@ -56,6 +56,7 @@ export class BreadcrumbsWidget {
|
||||
private readonly _nodes = new Array<HTMLDivElement>();
|
||||
private readonly _freeNodes = new Array<HTMLDivElement>();
|
||||
|
||||
private _enabled: boolean = true;
|
||||
private _focusedItemIdx: number = -1;
|
||||
private _selectedItemIdx: number = -1;
|
||||
|
||||
@ -155,13 +156,18 @@ export class BreadcrumbsWidget {
|
||||
content += `.monaco-breadcrumbs .monaco-breadcrumb-item.focused.selected { color: ${style.breadcrumbsFocusAndSelectionForeground}}\n`;
|
||||
}
|
||||
if (style.breadcrumbsHoverForeground) {
|
||||
content += `.monaco-breadcrumbs .monaco-breadcrumb-item:hover:not(.focused):not(.selected) { color: ${style.breadcrumbsHoverForeground}}\n`;
|
||||
content += `.monaco-breadcrumbs:not(.disabled ) .monaco-breadcrumb-item:hover:not(.focused):not(.selected) { color: ${style.breadcrumbsHoverForeground}}\n`;
|
||||
}
|
||||
if (this._styleElement.innerText !== content) {
|
||||
this._styleElement.innerText = content;
|
||||
}
|
||||
}
|
||||
|
||||
setEnabled(value: boolean) {
|
||||
this._enabled = value;
|
||||
this._domNode.classList.toggle('disabled', !this._enabled);
|
||||
}
|
||||
|
||||
domFocus(): void {
|
||||
let idx = this._focusedItemIdx >= 0 ? this._focusedItemIdx : this._items.length - 1;
|
||||
if (idx >= 0 && idx < this._items.length) {
|
||||
@ -326,6 +332,9 @@ export class BreadcrumbsWidget {
|
||||
}
|
||||
|
||||
private _onClick(event: IMouseEvent): void {
|
||||
if (!this._enabled) {
|
||||
return;
|
||||
}
|
||||
for (let el: HTMLElement | null = event.target; el; el = el.parentElement) {
|
||||
let idx = this._nodes.indexOf(el as HTMLDivElement);
|
||||
if (idx >= 0) {
|
||||
|
@ -22,8 +22,9 @@
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
.monaco-button.disabled:focus,
|
||||
.monaco-button.disabled {
|
||||
opacity: 0.4;
|
||||
opacity: 0.4 !important;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
@ -39,3 +40,15 @@
|
||||
.monaco-button-dropdown > .monaco-dropdown-button {
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
.monaco-description-button {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.monaco-description-button .monaco-button-label {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.monaco-description-button .monaco-button-description {
|
||||
font-style: italic;
|
||||
}
|
||||
|
@ -50,6 +50,10 @@ export interface IButton extends IDisposable {
|
||||
hasFocus(): boolean;
|
||||
}
|
||||
|
||||
export interface IButtonWithDescription extends IButton {
|
||||
description: string;
|
||||
}
|
||||
|
||||
export class Button extends Disposable implements IButton {
|
||||
|
||||
private _element: HTMLElement;
|
||||
@ -303,6 +307,207 @@ export class ButtonWithDropdown extends Disposable implements IButton {
|
||||
}
|
||||
}
|
||||
|
||||
export class ButtonWithDescription extends Disposable implements IButtonWithDescription {
|
||||
|
||||
private _element: HTMLElement;
|
||||
private _labelElement: HTMLElement;
|
||||
private _descriptionElement: HTMLElement;
|
||||
private options: IButtonOptions;
|
||||
|
||||
private buttonBackground: Color | undefined;
|
||||
private buttonHoverBackground: Color | undefined;
|
||||
private buttonForeground: Color | undefined;
|
||||
private buttonSecondaryBackground: Color | undefined;
|
||||
private buttonSecondaryHoverBackground: Color | undefined;
|
||||
private buttonSecondaryForeground: Color | undefined;
|
||||
private buttonBorder: Color | undefined;
|
||||
|
||||
private _onDidClick = this._register(new Emitter<Event>());
|
||||
get onDidClick(): BaseEvent<Event> { return this._onDidClick.event; }
|
||||
|
||||
private focusTracker: IFocusTracker;
|
||||
|
||||
constructor(container: HTMLElement, options?: IButtonOptions) {
|
||||
super();
|
||||
|
||||
this.options = options || Object.create(null);
|
||||
mixin(this.options, defaultOptions, false);
|
||||
|
||||
this.buttonForeground = this.options.buttonForeground;
|
||||
this.buttonBackground = this.options.buttonBackground;
|
||||
this.buttonHoverBackground = this.options.buttonHoverBackground;
|
||||
|
||||
this.buttonSecondaryForeground = this.options.buttonSecondaryForeground;
|
||||
this.buttonSecondaryBackground = this.options.buttonSecondaryBackground;
|
||||
this.buttonSecondaryHoverBackground = this.options.buttonSecondaryHoverBackground;
|
||||
|
||||
this.buttonBorder = this.options.buttonBorder;
|
||||
|
||||
this._element = document.createElement('a');
|
||||
this._element.classList.add('monaco-button');
|
||||
this._element.classList.add('monaco-description-button');
|
||||
this._element.tabIndex = 0;
|
||||
this._element.setAttribute('role', 'button');
|
||||
|
||||
this._labelElement = document.createElement('div');
|
||||
this._labelElement.classList.add('monaco-button-label');
|
||||
this._labelElement.tabIndex = -1;
|
||||
this._element.appendChild(this._labelElement);
|
||||
|
||||
this._descriptionElement = document.createElement('div');
|
||||
this._descriptionElement.classList.add('monaco-button-description');
|
||||
this._descriptionElement.tabIndex = -1;
|
||||
this._element.appendChild(this._descriptionElement);
|
||||
|
||||
container.appendChild(this._element);
|
||||
|
||||
this._register(Gesture.addTarget(this._element));
|
||||
|
||||
[EventType.CLICK, TouchEventType.Tap].forEach(eventType => {
|
||||
this._register(addDisposableListener(this._element, eventType, e => {
|
||||
if (!this.enabled) {
|
||||
EventHelper.stop(e);
|
||||
return;
|
||||
}
|
||||
|
||||
this._onDidClick.fire(e);
|
||||
}));
|
||||
});
|
||||
|
||||
this._register(addDisposableListener(this._element, EventType.KEY_DOWN, e => {
|
||||
const event = new StandardKeyboardEvent(e);
|
||||
let eventHandled = false;
|
||||
if (this.enabled && (event.equals(KeyCode.Enter) || event.equals(KeyCode.Space))) {
|
||||
this._onDidClick.fire(e);
|
||||
eventHandled = true;
|
||||
} else if (event.equals(KeyCode.Escape)) {
|
||||
this._element.blur();
|
||||
eventHandled = true;
|
||||
}
|
||||
|
||||
if (eventHandled) {
|
||||
EventHelper.stop(event, true);
|
||||
}
|
||||
}));
|
||||
|
||||
this._register(addDisposableListener(this._element, EventType.MOUSE_OVER, e => {
|
||||
if (!this._element.classList.contains('disabled')) {
|
||||
this.setHoverBackground();
|
||||
}
|
||||
}));
|
||||
|
||||
this._register(addDisposableListener(this._element, EventType.MOUSE_OUT, e => {
|
||||
this.applyStyles(); // restore standard styles
|
||||
}));
|
||||
|
||||
// Also set hover background when button is focused for feedback
|
||||
this.focusTracker = this._register(trackFocus(this._element));
|
||||
this._register(this.focusTracker.onDidFocus(() => this.setHoverBackground()));
|
||||
this._register(this.focusTracker.onDidBlur(() => this.applyStyles())); // restore standard styles
|
||||
|
||||
this.applyStyles();
|
||||
}
|
||||
|
||||
private setHoverBackground(): void {
|
||||
let hoverBackground;
|
||||
if (this.options.secondary) {
|
||||
hoverBackground = this.buttonSecondaryHoverBackground ? this.buttonSecondaryHoverBackground.toString() : null;
|
||||
} else {
|
||||
hoverBackground = this.buttonHoverBackground ? this.buttonHoverBackground.toString() : null;
|
||||
}
|
||||
if (hoverBackground) {
|
||||
this._element.style.backgroundColor = hoverBackground;
|
||||
}
|
||||
}
|
||||
|
||||
style(styles: IButtonStyles): void {
|
||||
this.buttonForeground = styles.buttonForeground;
|
||||
this.buttonBackground = styles.buttonBackground;
|
||||
this.buttonHoverBackground = styles.buttonHoverBackground;
|
||||
this.buttonSecondaryForeground = styles.buttonSecondaryForeground;
|
||||
this.buttonSecondaryBackground = styles.buttonSecondaryBackground;
|
||||
this.buttonSecondaryHoverBackground = styles.buttonSecondaryHoverBackground;
|
||||
this.buttonBorder = styles.buttonBorder;
|
||||
|
||||
this.applyStyles();
|
||||
}
|
||||
|
||||
private applyStyles(): void {
|
||||
if (this._element) {
|
||||
let background, foreground;
|
||||
if (this.options.secondary) {
|
||||
foreground = this.buttonSecondaryForeground ? this.buttonSecondaryForeground.toString() : '';
|
||||
background = this.buttonSecondaryBackground ? this.buttonSecondaryBackground.toString() : '';
|
||||
} else {
|
||||
foreground = this.buttonForeground ? this.buttonForeground.toString() : '';
|
||||
background = this.buttonBackground ? this.buttonBackground.toString() : '';
|
||||
}
|
||||
|
||||
const border = this.buttonBorder ? this.buttonBorder.toString() : '';
|
||||
|
||||
this._element.style.color = foreground;
|
||||
this._element.style.backgroundColor = background;
|
||||
|
||||
this._element.style.borderWidth = border ? '1px' : '';
|
||||
this._element.style.borderStyle = border ? 'solid' : '';
|
||||
this._element.style.borderColor = border;
|
||||
}
|
||||
}
|
||||
|
||||
get element(): HTMLElement {
|
||||
return this._element;
|
||||
}
|
||||
|
||||
set label(value: string) {
|
||||
this._element.classList.add('monaco-text-button');
|
||||
if (this.options.supportIcons) {
|
||||
reset(this._labelElement, ...renderLabelWithIcons(value));
|
||||
} else {
|
||||
this._labelElement.textContent = value;
|
||||
}
|
||||
if (typeof this.options.title === 'string') {
|
||||
this._element.title = this.options.title;
|
||||
} else if (this.options.title) {
|
||||
this._element.title = value;
|
||||
}
|
||||
}
|
||||
|
||||
set description(value: string) {
|
||||
if (this.options.supportIcons) {
|
||||
reset(this._descriptionElement, ...renderLabelWithIcons(value));
|
||||
} else {
|
||||
this._descriptionElement.textContent = value;
|
||||
}
|
||||
}
|
||||
|
||||
set icon(icon: CSSIcon) {
|
||||
this._element.classList.add(...CSSIcon.asClassNameArray(icon));
|
||||
}
|
||||
|
||||
set enabled(value: boolean) {
|
||||
if (value) {
|
||||
this._element.classList.remove('disabled');
|
||||
this._element.setAttribute('aria-disabled', String(false));
|
||||
this._element.tabIndex = 0;
|
||||
} else {
|
||||
this._element.classList.add('disabled');
|
||||
this._element.setAttribute('aria-disabled', String(true));
|
||||
}
|
||||
}
|
||||
|
||||
get enabled() {
|
||||
return !this._element.classList.contains('disabled');
|
||||
}
|
||||
|
||||
focus(): void {
|
||||
this._element.focus();
|
||||
}
|
||||
|
||||
hasFocus(): boolean {
|
||||
return this._element === document.activeElement;
|
||||
}
|
||||
}
|
||||
|
||||
export class ButtonBar extends Disposable {
|
||||
|
||||
private _buttons: IButton[] = [];
|
||||
@ -321,6 +526,12 @@ export class ButtonBar extends Disposable {
|
||||
return button;
|
||||
}
|
||||
|
||||
addButtonWithDescription(options?: IButtonOptions): IButtonWithDescription {
|
||||
const button = this._register(new ButtonWithDescription(this.container, options));
|
||||
this.pushButton(button);
|
||||
return button;
|
||||
}
|
||||
|
||||
addButtonWithDropdown(options: IButtonWithDropdownOptions): IButton {
|
||||
const button = this._register(new ButtonWithDropdown(this.container, options));
|
||||
this.pushButton(button);
|
||||
|
@ -44,7 +44,7 @@ export class CheckboxActionViewItem extends BaseActionViewItem {
|
||||
protected checkbox: Checkbox | undefined;
|
||||
protected readonly disposables = new DisposableStore();
|
||||
|
||||
render(container: HTMLElement): void {
|
||||
override render(container: HTMLElement): void {
|
||||
this.element = container;
|
||||
|
||||
this.disposables.clear();
|
||||
@ -59,7 +59,7 @@ export class CheckboxActionViewItem extends BaseActionViewItem {
|
||||
this.element.appendChild(this.checkbox.domNode);
|
||||
}
|
||||
|
||||
updateEnabled(): void {
|
||||
override updateEnabled(): void {
|
||||
if (this.checkbox) {
|
||||
if (this.isEnabled()) {
|
||||
this.checkbox.enable();
|
||||
@ -69,33 +69,33 @@ export class CheckboxActionViewItem extends BaseActionViewItem {
|
||||
}
|
||||
}
|
||||
|
||||
updateChecked(): void {
|
||||
override updateChecked(): void {
|
||||
if (this.checkbox) {
|
||||
this.checkbox.checked = this._action.checked;
|
||||
}
|
||||
}
|
||||
|
||||
focus(): void {
|
||||
override focus(): void {
|
||||
if (this.checkbox) {
|
||||
this.checkbox.domNode.tabIndex = 0;
|
||||
this.checkbox.focus();
|
||||
}
|
||||
}
|
||||
|
||||
blur(): void {
|
||||
override blur(): void {
|
||||
if (this.checkbox) {
|
||||
this.checkbox.domNode.tabIndex = -1;
|
||||
this.checkbox.domNode.blur();
|
||||
}
|
||||
}
|
||||
|
||||
setFocusable(focusable: boolean): void {
|
||||
override setFocusable(focusable: boolean): void {
|
||||
if (this.checkbox) {
|
||||
this.checkbox.domNode.tabIndex = focusable ? 0 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
override dispose(): void {
|
||||
this.disposables.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
@ -13,7 +13,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.codicon-sync.codicon-modifier-spin, .codicon-loading.codicon-modifier-spin, .codicon-gear.codicon-modifier-spin {
|
||||
.codicon-sync.codicon-modifier-spin,
|
||||
.codicon-loading.codicon-modifier-spin,
|
||||
.codicon-gear.codicon-modifier-spin,
|
||||
.codicon-notebook-state-executing.codicon-modifier-spin {
|
||||
/* Use steps to throttle FPS to reduce CPU usage */
|
||||
animation: codicon-spin 1.5s steps(30) infinite;
|
||||
}
|
||||
|
Binary file not shown.
@ -45,7 +45,7 @@ export interface IDelegate {
|
||||
anchorAxisAlignment?: AnchorAxisAlignment; // default: vertical
|
||||
canRelayout?: boolean; // default: true
|
||||
onDOMEvent?(e: Event, activeElement: HTMLElement): void;
|
||||
onHide?(data?: any): void;
|
||||
onHide?(data?: unknown): void;
|
||||
}
|
||||
|
||||
export interface IContextViewProvider {
|
||||
@ -324,7 +324,7 @@ export class ContextView extends Disposable {
|
||||
this.view.style.width = 'initial';
|
||||
}
|
||||
|
||||
hide(data?: any): void {
|
||||
hide(data?: unknown): void {
|
||||
const delegate = this.delegate;
|
||||
this.delegate = null;
|
||||
|
||||
@ -351,7 +351,7 @@ export class ContextView extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
override dispose(): void {
|
||||
this.hide();
|
||||
|
||||
super.dispose();
|
||||
|
@ -10,7 +10,7 @@
|
||||
width: 100%;
|
||||
left:0;
|
||||
top:0;
|
||||
z-index: 2000;
|
||||
z-index: 2600;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
@ -34,17 +34,12 @@
|
||||
|
||||
/** Dialog: Title Actions Row */
|
||||
.monaco-dialog-box .dialog-toolbar-row {
|
||||
height: 22px;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.monaco-dialog-box .action-label {
|
||||
height: 16px;
|
||||
min-width: 16px;
|
||||
background-size: 16px;
|
||||
background-position: 50%;
|
||||
background-repeat: no-repeat;
|
||||
margin: 0px;
|
||||
margin-left: 4px;
|
||||
.monaco-dialog-box .dialog-toolbar-row .actions-container {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
/** Dialog: Message Row */
|
||||
@ -144,6 +139,10 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.monaco-dialog-box > .dialog-buttons-row > .dialog-buttons.centered {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.monaco-dialog-box > .dialog-buttons-row > .dialog-buttons > .monaco-button {
|
||||
width: fit-content;
|
||||
width: -moz-fit-content;
|
||||
|
@ -11,7 +11,7 @@ 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, IButtonStyles } from 'vs/base/browser/ui/button/button';
|
||||
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';
|
||||
@ -34,6 +34,10 @@ export interface IDialogOptions {
|
||||
readonly type?: 'none' | 'info' | 'error' | 'question' | 'warning' | 'pending';
|
||||
readonly inputs?: IDialogInputOptions[];
|
||||
readonly keyEventProcessor?: (event: StandardKeyboardEvent) => void;
|
||||
readonly renderBody?: (container: HTMLElement) => void;
|
||||
readonly icon?: Codicon;
|
||||
readonly buttonDetails?: string[];
|
||||
readonly disableCloseAction?: boolean;
|
||||
}
|
||||
|
||||
export interface IDialogResult {
|
||||
@ -53,6 +57,8 @@ export interface IDialogStyles extends IButtonStyles, ISimpleCheckboxStyles {
|
||||
readonly inputBackground?: Color;
|
||||
readonly inputForeground?: Color;
|
||||
readonly inputBorder?: Color;
|
||||
readonly textLinkForeground?: Color;
|
||||
|
||||
}
|
||||
|
||||
interface ButtonMapEntry {
|
||||
@ -71,6 +77,7 @@ export class Dialog extends Disposable {
|
||||
private modalElement: HTMLElement | undefined;
|
||||
private readonly buttonsContainer: HTMLElement;
|
||||
private readonly messageDetailElement: HTMLElement;
|
||||
private readonly messageContainer: HTMLElement;
|
||||
private readonly iconElement: HTMLElement;
|
||||
private readonly checkbox: SimpleCheckbox | undefined;
|
||||
private readonly toolbarContainer: HTMLElement;
|
||||
@ -83,7 +90,7 @@ export class Dialog extends Disposable {
|
||||
constructor(private container: HTMLElement, private message: string, buttons: string[], private options: IDialogOptions) {
|
||||
super();
|
||||
|
||||
this.modalElement = this.container.appendChild($(`.monaco-dialog-modal-block${options.type === 'pending' ? '.dimmed' : ''}`));
|
||||
this.modalElement = this.container.appendChild($(`.monaco-dialog-modal-block.dimmed`));
|
||||
this.shadowElement = this.modalElement.appendChild($('.dialog-shadow'));
|
||||
this.element = this.shadowElement.appendChild($('.monaco-dialog-box'));
|
||||
this.element.setAttribute('role', 'dialog');
|
||||
@ -95,20 +102,29 @@ export class Dialog extends Disposable {
|
||||
|
||||
const messageRowElement = this.element.appendChild($('.dialog-message-row'));
|
||||
this.iconElement = messageRowElement.appendChild($('.dialog-icon'));
|
||||
const messageContainer = messageRowElement.appendChild($('.dialog-message-container'));
|
||||
this.messageContainer = messageRowElement.appendChild($('.dialog-message-container'));
|
||||
|
||||
if (this.options.detail) {
|
||||
const messageElement = messageContainer.appendChild($('.dialog-message'));
|
||||
if (this.options.detail || this.options.renderBody) {
|
||||
const messageElement = this.messageContainer.appendChild($('.dialog-message'));
|
||||
const messageTextElement = messageElement.appendChild($('.dialog-message-text'));
|
||||
messageTextElement.innerText = this.message;
|
||||
}
|
||||
|
||||
this.messageDetailElement = messageContainer.appendChild($('.dialog-message-detail'));
|
||||
this.messageDetailElement.innerText = this.options.detail ? this.options.detail : message;
|
||||
this.messageDetailElement = this.messageContainer.appendChild($('.dialog-message-detail'));
|
||||
if (this.options.detail || !this.options.renderBody) {
|
||||
this.messageDetailElement.innerText = this.options.detail ? this.options.detail : message;
|
||||
} else {
|
||||
this.messageDetailElement.style.display = 'none';
|
||||
}
|
||||
|
||||
if (this.options.renderBody) {
|
||||
const customBody = this.messageContainer.appendChild($('.dialog-message-body'));
|
||||
this.options.renderBody(customBody);
|
||||
}
|
||||
|
||||
if (this.options.inputs) {
|
||||
this.inputs = this.options.inputs.map(input => {
|
||||
const inputRowElement = messageContainer.appendChild($('.dialog-message-input'));
|
||||
const inputRowElement = this.messageContainer.appendChild($('.dialog-message-input'));
|
||||
|
||||
const inputBox = this._register(new InputBox(inputRowElement, undefined, {
|
||||
placeholder: input.placeholder,
|
||||
@ -126,7 +142,7 @@ export class Dialog extends Disposable {
|
||||
}
|
||||
|
||||
if (this.options.checkboxLabel) {
|
||||
const checkboxRowElement = messageContainer.appendChild($('.dialog-checkbox-row'));
|
||||
const checkboxRowElement = this.messageContainer.appendChild($('.dialog-checkbox-row'));
|
||||
|
||||
const checkbox = this.checkbox = this._register(new SimpleCheckbox(this.options.checkboxLabel, !!this.options.checkboxChecked));
|
||||
|
||||
@ -175,12 +191,16 @@ export class Dialog extends Disposable {
|
||||
|
||||
const buttonBar = this.buttonBar = this._register(new ButtonBar(this.buttonsContainer));
|
||||
const buttonMap = this.rearrangeButtons(this.buttons, this.options.cancelId);
|
||||
this.buttonsContainer.classList.toggle('centered');
|
||||
|
||||
// Handle button clicks
|
||||
buttonMap.forEach((entry, index) => {
|
||||
const button = this._register(buttonBar.addButton({ title: true }));
|
||||
const primary = buttonMap[index].index === 0;
|
||||
const button = this.options.buttonDetails ? this._register(buttonBar.addButtonWithDescription({ title: true, secondary: !primary })) : this._register(buttonBar.addButton({ title: true, secondary: !primary }));
|
||||
button.label = mnemonicButtonLabel(buttonMap[index].label, true);
|
||||
|
||||
if (button instanceof ButtonWithDescription) {
|
||||
button.description = this.options.buttonDetails![buttonMap[index].index];
|
||||
}
|
||||
this._register(button.onDidClick(e => {
|
||||
if (e) {
|
||||
EventHelper.stop(e);
|
||||
@ -287,7 +307,7 @@ export class Dialog extends Disposable {
|
||||
EventHelper.stop(e, true);
|
||||
const evt = new StandardKeyboardEvent(e);
|
||||
|
||||
if (evt.equals(KeyCode.Escape)) {
|
||||
if (!this.options.disableCloseAction && evt.equals(KeyCode.Escape)) {
|
||||
resolve({
|
||||
button: this.options.cancelId || 0,
|
||||
checkboxChecked: this.checkbox ? this.checkbox.checked : undefined
|
||||
@ -313,34 +333,41 @@ export class Dialog extends Disposable {
|
||||
|
||||
this.iconElement.classList.remove(...dialogErrorIcon.classNamesArray, ...dialogWarningIcon.classNamesArray, ...dialogInfoIcon.classNamesArray, ...Codicon.loading.classNamesArray, spinModifierClassName);
|
||||
|
||||
switch (this.options.type) {
|
||||
case 'error':
|
||||
this.iconElement.classList.add(...dialogErrorIcon.classNamesArray);
|
||||
break;
|
||||
case 'warning':
|
||||
this.iconElement.classList.add(...dialogWarningIcon.classNamesArray);
|
||||
break;
|
||||
case 'pending':
|
||||
this.iconElement.classList.add(...Codicon.loading.classNamesArray, spinModifierClassName);
|
||||
break;
|
||||
case 'none':
|
||||
case 'info':
|
||||
case 'question':
|
||||
default:
|
||||
this.iconElement.classList.add(...dialogInfoIcon.classNamesArray);
|
||||
break;
|
||||
if (this.options.icon) {
|
||||
this.iconElement.classList.add(...this.options.icon.classNamesArray);
|
||||
} else {
|
||||
switch (this.options.type) {
|
||||
case 'error':
|
||||
this.iconElement.classList.add(...dialogErrorIcon.classNamesArray);
|
||||
break;
|
||||
case 'warning':
|
||||
this.iconElement.classList.add(...dialogWarningIcon.classNamesArray);
|
||||
break;
|
||||
case 'pending':
|
||||
this.iconElement.classList.add(...Codicon.loading.classNamesArray, spinModifierClassName);
|
||||
break;
|
||||
case 'none':
|
||||
case 'info':
|
||||
case 'question':
|
||||
default:
|
||||
this.iconElement.classList.add(...dialogInfoIcon.classNamesArray);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const actionBar = this._register(new ActionBar(this.toolbarContainer, {}));
|
||||
|
||||
const action = this._register(new Action('dialog.close', nls.localize('dialogClose', "Close Dialog"), dialogCloseIcon.classNames, true, async () => {
|
||||
resolve({
|
||||
button: this.options.cancelId || 0,
|
||||
checkboxChecked: this.checkbox ? this.checkbox.checked : undefined
|
||||
});
|
||||
}));
|
||||
if (!this.options.disableCloseAction) {
|
||||
const actionBar = this._register(new ActionBar(this.toolbarContainer, {}));
|
||||
|
||||
actionBar.push(action, { icon: true, label: false, });
|
||||
const action = this._register(new Action('dialog.close', nls.localize('dialogClose', "Close Dialog"), dialogCloseIcon.classNames, true, async () => {
|
||||
resolve({
|
||||
button: this.options.cancelId || 0,
|
||||
checkboxChecked: this.checkbox ? this.checkbox.checked : undefined
|
||||
});
|
||||
}));
|
||||
|
||||
actionBar.push(action, { icon: true, label: false, });
|
||||
}
|
||||
|
||||
this.applyStyles();
|
||||
|
||||
@ -369,6 +396,7 @@ export class Dialog extends Disposable {
|
||||
const bgColor = style.dialogBackground;
|
||||
const shadowColor = style.dialogShadow ? `0 0px 8px ${style.dialogShadow}` : '';
|
||||
const border = style.dialogBorder ? `1px solid ${style.dialogBorder}` : '';
|
||||
const linkFgColor = style.textLinkForeground;
|
||||
|
||||
this.shadowElement.style.boxShadow = shadowColor;
|
||||
|
||||
@ -389,6 +417,12 @@ export class Dialog extends Disposable {
|
||||
this.messageDetailElement.style.color = messageDetailColor.makeOpaque(bgColor).toString();
|
||||
}
|
||||
|
||||
if (linkFgColor) {
|
||||
for (const el of this.messageContainer.getElementsByTagName('a')) {
|
||||
el.style.color = linkFgColor.toString();
|
||||
}
|
||||
}
|
||||
|
||||
let color;
|
||||
switch (this.options.type) {
|
||||
case 'error':
|
||||
@ -417,7 +451,7 @@ export class Dialog extends Disposable {
|
||||
this.applyStyles();
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
override dispose(): void {
|
||||
super.dispose();
|
||||
|
||||
if (this.modalElement) {
|
||||
|
@ -11,8 +11,29 @@
|
||||
.monaco-dropdown > .dropdown-label {
|
||||
cursor: pointer;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.monaco-dropdown > .dropdown-label > .action-label.disabled {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.monaco-dropdown-with-primary {
|
||||
display: flex !important;
|
||||
flex-direction: row;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.monaco-dropdown-with-primary > .action-container > .action-label {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.monaco-dropdown-with-primary > .dropdown-action-container > .monaco-dropdown > .dropdown-label .codicon[class*='codicon-'] {
|
||||
font-size: 12px;
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
line-height: 16px;
|
||||
margin-left: -4px;
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ export class BaseDropdown extends ActionRunner {
|
||||
this.hide();
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
override dispose(): void {
|
||||
super.dispose();
|
||||
this.hide();
|
||||
|
||||
@ -159,7 +159,7 @@ export class Dropdown extends BaseDropdown {
|
||||
this.contextViewProvider = options.contextViewProvider;
|
||||
}
|
||||
|
||||
show(): void {
|
||||
override show(): void {
|
||||
super.show();
|
||||
|
||||
this.element.classList.add('active');
|
||||
@ -187,7 +187,7 @@ export class Dropdown extends BaseDropdown {
|
||||
this.element.classList.remove('active');
|
||||
}
|
||||
|
||||
hide(): void {
|
||||
override hide(): void {
|
||||
super.hide();
|
||||
|
||||
if (this.contextViewProvider) {
|
||||
@ -250,7 +250,7 @@ export class DropdownMenu extends BaseDropdown {
|
||||
this._actions = actions;
|
||||
}
|
||||
|
||||
show(): void {
|
||||
override show(): void {
|
||||
super.show();
|
||||
|
||||
this.element.classList.add('active');
|
||||
@ -269,7 +269,7 @@ export class DropdownMenu extends BaseDropdown {
|
||||
});
|
||||
}
|
||||
|
||||
hide(): void {
|
||||
override hide(): void {
|
||||
super.hide();
|
||||
}
|
||||
|
||||
|
@ -7,14 +7,15 @@ 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 { ResolvedKeybinding } from 'vs/base/common/keyCodes';
|
||||
import { append, $ } from 'vs/base/browser/dom';
|
||||
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 { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
|
||||
export interface IKeybindingProvider {
|
||||
(action: IAction): ResolvedKeybinding | undefined;
|
||||
@ -42,23 +43,26 @@ export class DropdownMenuActionViewItem extends BaseActionViewItem {
|
||||
private _onDidChangeVisibility = this._register(new Emitter<boolean>());
|
||||
readonly onDidChangeVisibility = this._onDidChangeVisibility.event;
|
||||
|
||||
protected override readonly options: IDropdownMenuActionViewItemOptions;
|
||||
|
||||
constructor(
|
||||
action: IAction,
|
||||
menuActionsOrProvider: readonly IAction[] | IActionProvider,
|
||||
contextMenuProvider: IContextMenuProvider,
|
||||
protected options: IDropdownMenuActionViewItemOptions = {}
|
||||
options: IDropdownMenuActionViewItemOptions = Object.create(null)
|
||||
) {
|
||||
super(null, action, options);
|
||||
|
||||
this.menuActionsOrProvider = menuActionsOrProvider;
|
||||
this.contextMenuProvider = contextMenuProvider;
|
||||
this.options = options;
|
||||
|
||||
if (this.options.actionRunner) {
|
||||
this.actionRunner = this.options.actionRunner;
|
||||
}
|
||||
}
|
||||
|
||||
render(container: HTMLElement): void {
|
||||
override render(container: HTMLElement): void {
|
||||
this.actionItem = container;
|
||||
|
||||
const labelRenderer: ILabelRenderer = (el: HTMLElement): IDisposable | null => {
|
||||
@ -123,7 +127,7 @@ export class DropdownMenuActionViewItem extends BaseActionViewItem {
|
||||
this.updateEnabled();
|
||||
}
|
||||
|
||||
setActionContext(newContext: unknown): void {
|
||||
override setActionContext(newContext: unknown): void {
|
||||
super.setActionContext(newContext);
|
||||
|
||||
if (this.dropdownMenu) {
|
||||
@ -141,7 +145,7 @@ export class DropdownMenuActionViewItem extends BaseActionViewItem {
|
||||
}
|
||||
}
|
||||
|
||||
protected updateEnabled(): void {
|
||||
protected override updateEnabled(): void {
|
||||
const disabled = !this.getAction().enabled;
|
||||
this.actionItem?.classList.toggle('disabled', disabled);
|
||||
this.element?.classList.toggle('disabled', disabled);
|
||||
@ -166,7 +170,7 @@ export class ActionWithDropdownActionViewItem extends ActionViewItem {
|
||||
super(context, action, options);
|
||||
}
|
||||
|
||||
render(container: HTMLElement): void {
|
||||
override render(container: HTMLElement): void {
|
||||
super.render(container);
|
||||
if (this.element) {
|
||||
this.element.classList.add('action-dropdown-item');
|
||||
@ -181,6 +185,36 @@ export class ActionWithDropdownActionViewItem extends ActionViewItem {
|
||||
};
|
||||
this.dropdownMenuActionViewItem = new DropdownMenuActionViewItem(this._register(new Action('dropdownAction', undefined)), menuActionsProvider, this.contextMenuProvider, { classNames: ['dropdown', ...Codicon.dropDownButton.classNamesArray, ...(<IActionWithDropdownActionViewItemOptions>this.options).menuActionClassNames || []] });
|
||||
this.dropdownMenuActionViewItem.render(this.element);
|
||||
|
||||
this._register(addDisposableListener(this.element, EventType.KEY_DOWN, e => {
|
||||
const event = new StandardKeyboardEvent(e);
|
||||
let handled: boolean = false;
|
||||
if (this.dropdownMenuActionViewItem?.isFocused() && event.equals(KeyCode.LeftArrow)) {
|
||||
handled = true;
|
||||
this.dropdownMenuActionViewItem?.blur();
|
||||
this.focus();
|
||||
} else if (this.isFocused() && event.equals(KeyCode.RightArrow)) {
|
||||
handled = true;
|
||||
this.blur();
|
||||
this.dropdownMenuActionViewItem?.focus();
|
||||
}
|
||||
if (handled) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
override blur(): void {
|
||||
super.blur();
|
||||
this.dropdownMenuActionViewItem?.blur();
|
||||
}
|
||||
|
||||
override setFocusable(focusable: boolean): void {
|
||||
super.setFocusable(focusable);
|
||||
this.dropdownMenuActionViewItem?.setFocusable(focusable);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,106 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IContextMenuProvider } from 'vs/base/browser/contextmenu';
|
||||
import { ActionViewItem, BaseActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
|
||||
import { DropdownMenuActionViewItem } from 'vs/base/browser/ui/dropdown/dropdownActionViewItem';
|
||||
import { IAction } from 'vs/base/common/actions';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
export class DropdownWithPrimaryActionViewItem extends BaseActionViewItem {
|
||||
private _primaryAction: ActionViewItem;
|
||||
private _dropdown: DropdownMenuActionViewItem;
|
||||
private _container: HTMLElement | null = null;
|
||||
private toDispose: IDisposable[];
|
||||
|
||||
constructor(
|
||||
primaryAction: IAction,
|
||||
dropdownAction: IAction,
|
||||
dropdownMenuActions: IAction[],
|
||||
_className: string,
|
||||
private readonly _contextMenuProvider: IContextMenuProvider,
|
||||
dropdownIcon?: string
|
||||
) {
|
||||
super(null, primaryAction);
|
||||
this._primaryAction = new ActionViewItem(undefined, primaryAction, {
|
||||
icon: true,
|
||||
label: false
|
||||
});
|
||||
this._dropdown = new DropdownMenuActionViewItem(dropdownAction, dropdownMenuActions, this._contextMenuProvider, {
|
||||
menuAsChild: true
|
||||
});
|
||||
this.toDispose = [];
|
||||
}
|
||||
|
||||
override render(container: HTMLElement): void {
|
||||
this._container = container;
|
||||
super.render(this._container);
|
||||
this._container.classList.add('monaco-dropdown-with-primary');
|
||||
const primaryContainer = DOM.$('.action-container');
|
||||
this._primaryAction.render(DOM.append(this._container, primaryContainer));
|
||||
const dropdownContainer = DOM.$('.dropdown-action-container');
|
||||
this._dropdown.render(DOM.append(this._container, dropdownContainer));
|
||||
|
||||
this.toDispose.push(DOM.addDisposableListener(primaryContainer, DOM.EventType.KEY_DOWN, (e: KeyboardEvent) => {
|
||||
const event = new StandardKeyboardEvent(e);
|
||||
if (event.equals(KeyCode.RightArrow)) {
|
||||
this._primaryAction.element!.tabIndex = -1;
|
||||
this._dropdown.focus();
|
||||
event.stopPropagation();
|
||||
}
|
||||
}));
|
||||
this.toDispose.push(DOM.addDisposableListener(dropdownContainer, DOM.EventType.KEY_DOWN, (e: KeyboardEvent) => {
|
||||
const event = new StandardKeyboardEvent(e);
|
||||
if (event.equals(KeyCode.LeftArrow)) {
|
||||
this._primaryAction.element!.tabIndex = 0;
|
||||
this._dropdown.setFocusable(false);
|
||||
this._primaryAction.element?.focus();
|
||||
event.stopPropagation();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
override focus(fromRight?: boolean): void {
|
||||
if (fromRight) {
|
||||
this._dropdown.focus();
|
||||
} else {
|
||||
this._primaryAction.element!.tabIndex = 0;
|
||||
this._primaryAction.element!.focus();
|
||||
}
|
||||
}
|
||||
|
||||
override blur(): void {
|
||||
this._primaryAction.element!.tabIndex = -1;
|
||||
this._dropdown.blur();
|
||||
this._container!.blur();
|
||||
}
|
||||
|
||||
override setFocusable(focusable: boolean): void {
|
||||
if (focusable) {
|
||||
this._primaryAction.element!.tabIndex = 0;
|
||||
} else {
|
||||
this._primaryAction.element!.tabIndex = -1;
|
||||
this._dropdown.setFocusable(false);
|
||||
}
|
||||
}
|
||||
|
||||
override dispose(): void {
|
||||
this.toDispose = dispose(this.toDispose);
|
||||
}
|
||||
|
||||
update(dropdownAction: IAction, dropdownMenuActions: IAction[], dropdownIcon?: string): void {
|
||||
this._dropdown?.dispose();
|
||||
this._dropdown = new DropdownMenuActionViewItem(dropdownAction, dropdownMenuActions, this._contextMenuProvider, {
|
||||
menuAsChild: true,
|
||||
classNames: ['codicon', dropdownIcon || 'codicon-chevron-down']
|
||||
});
|
||||
if (this.element) {
|
||||
this._dropdown.render(this.element);
|
||||
}
|
||||
}
|
||||
}
|
@ -382,7 +382,7 @@ export class ReplaceInput extends Widget {
|
||||
this.domNode.style.width = newWidth + 'px';
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
public override dispose(): void {
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
@ -521,51 +521,6 @@ export class SerializableGrid<T extends ISerializableView> extends Grid<T> {
|
||||
return { type: 'branch', data: node.children.map(c => SerializableGrid.serializeNode(c, orthogonal(orientation))), size };
|
||||
}
|
||||
|
||||
private static deserializeNode<T extends ISerializableView>(json: ISerializedNode, orientation: Orientation, box: Box, deserializer: IViewDeserializer<T>): GridNode<T> {
|
||||
if (!json || typeof json !== 'object') {
|
||||
throw new Error('Invalid JSON');
|
||||
}
|
||||
|
||||
if (json.type === 'branch') {
|
||||
if (!Array.isArray(json.data)) {
|
||||
throw new Error('Invalid JSON: \'data\' property of branch must be an array.');
|
||||
}
|
||||
|
||||
const children: GridNode<T>[] = [];
|
||||
let offset = 0;
|
||||
|
||||
for (const child of json.data) {
|
||||
if (typeof child.size !== 'number') {
|
||||
throw new Error('Invalid JSON: \'size\' property of node must be a number.');
|
||||
}
|
||||
|
||||
const childSize = child.type === 'leaf' && child.visible === false ? 0 : child.size;
|
||||
const childBox: Box = orientation === Orientation.HORIZONTAL
|
||||
? { top: box.top, left: box.left + offset, width: childSize, height: box.height }
|
||||
: { top: box.top + offset, left: box.left, width: box.width, height: childSize };
|
||||
|
||||
children.push(SerializableGrid.deserializeNode(child, orthogonal(orientation), childBox, deserializer));
|
||||
offset += childSize;
|
||||
}
|
||||
|
||||
return { children, box };
|
||||
|
||||
} else if (json.type === 'leaf') {
|
||||
const view: T = deserializer.fromJSON(json.data);
|
||||
return { view, box, cachedVisibleSize: json.visible === false ? json.size : undefined };
|
||||
}
|
||||
|
||||
throw new Error('Invalid JSON: \'type\' property must be either \'branch\' or \'leaf\'.');
|
||||
}
|
||||
|
||||
private static getFirstLeaf<T extends IView>(node: GridNode<T>): GridLeafNode<T> {
|
||||
if (!isGridBranchNode(node)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
return SerializableGrid.getFirstLeaf(node.children[0]);
|
||||
}
|
||||
|
||||
static deserialize<T extends ISerializableView>(json: ISerializedGrid, deserializer: IViewDeserializer<T>, options: IGridOptions = {}): SerializableGrid<T> {
|
||||
if (typeof json.orientation !== 'number') {
|
||||
throw new Error('Invalid JSON: \'orientation\' property must be a number.');
|
||||
@ -596,7 +551,7 @@ export class SerializableGrid<T extends ISerializableView> extends Grid<T> {
|
||||
};
|
||||
}
|
||||
|
||||
layout(width: number, height: number): void {
|
||||
override layout(width: number, height: number): void {
|
||||
super.layout(width, height);
|
||||
|
||||
if (this.initialLayoutContext) {
|
||||
|
@ -30,8 +30,7 @@
|
||||
}
|
||||
|
||||
.monaco-hover .markdown-hover > .hover-contents:not(.code-hover-contents) hr {
|
||||
/* This is a strange rule but it avoids https://github.com/microsoft/vscode/issues/96795, just 100vw on its own caused the actual hover width to increase */
|
||||
min-width: calc(100% + 100vw);
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.monaco-hover p,
|
||||
|
@ -10,6 +10,10 @@ import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableEle
|
||||
|
||||
const $ = dom.$;
|
||||
|
||||
export const enum HoverPosition {
|
||||
LEFT, RIGHT, BELOW, ABOVE
|
||||
}
|
||||
|
||||
export class HoverWidget extends Disposable {
|
||||
|
||||
public readonly containerDomNode: HTMLElement;
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { AnchorPosition } from 'vs/base/browser/ui/contextview/contextview';
|
||||
import { HoverPosition } from 'vs/base/browser/ui/hover/hoverWidget';
|
||||
import { IMarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
@ -15,7 +15,7 @@ export interface IHoverDelegateTarget extends IDisposable {
|
||||
export interface IHoverDelegateOptions {
|
||||
text: IMarkdownString | string;
|
||||
target: IHoverDelegateTarget | HTMLElement;
|
||||
anchorPosition?: AnchorPosition;
|
||||
hoverPosition?: HoverPosition;
|
||||
}
|
||||
|
||||
export interface IHoverDelegate {
|
||||
|
@ -11,12 +11,12 @@ import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Range } from 'vs/base/common/range';
|
||||
import { equals } from 'vs/base/common/objects';
|
||||
import { IHoverDelegate, IHoverDelegateOptions, IHoverDelegateTarget } from 'vs/base/browser/ui/iconLabel/iconHoverDelegate';
|
||||
import { AnchorPosition } from 'vs/base/browser/ui/contextview/contextview';
|
||||
import { IMarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { isFunction, isString } from 'vs/base/common/types';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { localize } from 'vs/nls';
|
||||
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import { HoverPosition } from 'vs/base/browser/ui/hover/hoverWidget';
|
||||
|
||||
export interface IIconLabelCreationOptions {
|
||||
supportHighlights?: boolean;
|
||||
@ -222,12 +222,12 @@ export class IconLabel extends Disposable {
|
||||
let isHovering = false;
|
||||
let tokenSource: CancellationTokenSource;
|
||||
let hoverDisposable: IDisposable | undefined;
|
||||
function mouseOver(this: HTMLElement, e: MouseEvent): any {
|
||||
function mouseOver(this: HTMLElement, e: MouseEvent): void {
|
||||
if (isHovering) {
|
||||
return;
|
||||
}
|
||||
tokenSource = new CancellationTokenSource();
|
||||
function mouseLeaveOrDown(this: HTMLElement, e: MouseEvent): any {
|
||||
function mouseLeaveOrDown(this: HTMLElement, e: MouseEvent): void {
|
||||
const isMouseDown = e.type === dom.EventType.MOUSE_DOWN;
|
||||
if (isMouseDown) {
|
||||
hoverDisposable?.dispose();
|
||||
@ -245,7 +245,7 @@ export class IconLabel extends Disposable {
|
||||
const mouseDownDisposable = domEvent(htmlElement, dom.EventType.MOUSE_DOWN, true)(mouseLeaveOrDown.bind(htmlElement));
|
||||
isHovering = true;
|
||||
|
||||
function mouseMove(this: HTMLElement, e: MouseEvent): any {
|
||||
function mouseMove(this: HTMLElement, e: MouseEvent): void {
|
||||
mouseX = e.x;
|
||||
}
|
||||
const mouseMoveDisposable = domEvent(htmlElement, dom.EventType.MOUSE_MOVE, true)(mouseMove.bind(htmlElement));
|
||||
@ -260,7 +260,7 @@ export class IconLabel extends Disposable {
|
||||
hoverOptions = {
|
||||
text: localize('iconLabel.loading', "Loading..."),
|
||||
target,
|
||||
anchorPosition: AnchorPosition.BELOW
|
||||
hoverPosition: HoverPosition.BELOW
|
||||
};
|
||||
hoverDisposable = IconLabel.adjustXAndShowCustomHover(hoverOptions, mouseX, hoverDelegate, isHovering);
|
||||
|
||||
@ -269,7 +269,7 @@ export class IconLabel extends Disposable {
|
||||
hoverOptions = {
|
||||
text: resolvedTooltip,
|
||||
target,
|
||||
anchorPosition: AnchorPosition.BELOW
|
||||
hoverPosition: HoverPosition.BELOW
|
||||
};
|
||||
// awaiting the tooltip could take a while. Make sure we're still hovering.
|
||||
hoverDisposable = IconLabel.adjustXAndShowCustomHover(hoverOptions, mouseX, hoverDelegate, isHovering);
|
||||
|
@ -610,7 +610,7 @@ export class InputBox extends Widget {
|
||||
}
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
public override dispose(): void {
|
||||
this._hideMessage();
|
||||
|
||||
this.message = null;
|
||||
|
@ -11,13 +11,10 @@
|
||||
|
||||
.monaco-keybinding > .monaco-keybinding-key {
|
||||
display: inline-block;
|
||||
border: solid 1px rgba(204, 204, 204, 0.4);
|
||||
border-bottom-color: rgba(187, 187, 187, 0.4);
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-radius: 3px;
|
||||
box-shadow: inset 0 -1px 0 rgba(187, 187, 187, 0.4);
|
||||
background-color: rgba(221, 221, 221, 0.4);
|
||||
vertical-align: middle;
|
||||
color: #555;
|
||||
font-size: 11px;
|
||||
padding: 3px 5px;
|
||||
margin: 0 2px;
|
||||
@ -31,19 +28,10 @@
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.hc-black .monaco-keybinding > .monaco-keybinding-key,
|
||||
.vs-dark .monaco-keybinding > .monaco-keybinding-key {
|
||||
background-color: rgba(128, 128, 128, 0.17);
|
||||
color: #ccc;
|
||||
border: solid 1px rgba(51, 51, 51, 0.6);
|
||||
border-bottom-color: rgba(68, 68, 68, 0.6);
|
||||
box-shadow: inset 0 -1px 0 rgba(68, 68, 68, 0.6);
|
||||
}
|
||||
|
||||
.monaco-keybinding > .monaco-keybinding-key-separator {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.monaco-keybinding > .monaco-keybinding-key-chord-separator {
|
||||
width: 6px;
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ import { ResolvedKeybinding, ResolvedKeybindingPart } from 'vs/base/common/keyCo
|
||||
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';
|
||||
|
||||
const $ = dom.$;
|
||||
|
||||
@ -26,18 +28,44 @@ export interface Matches {
|
||||
chordPart: PartMatches;
|
||||
}
|
||||
|
||||
export interface KeybindingLabelOptions {
|
||||
renderUnboundKeybindings: boolean;
|
||||
export interface KeybindingLabelOptions extends IKeybindingLabelStyles {
|
||||
renderUnboundKeybindings?: boolean;
|
||||
}
|
||||
|
||||
export class KeybindingLabel {
|
||||
export interface IKeybindingLabelStyles {
|
||||
keybindingLabelBackground?: Color;
|
||||
keybindingLabelForeground?: Color;
|
||||
keybindingLabelBorder?: Color;
|
||||
keybindingLabelBottomBorder?: Color;
|
||||
keybindingLabelShadow?: Color;
|
||||
}
|
||||
|
||||
export class KeybindingLabel implements IThemable {
|
||||
|
||||
private domNode: HTMLElement;
|
||||
private options: KeybindingLabelOptions;
|
||||
|
||||
private readonly keyElements = new Set<HTMLSpanElement>();
|
||||
|
||||
private keybinding: ResolvedKeybinding | undefined;
|
||||
private matches: Matches | undefined;
|
||||
private didEverRender: boolean;
|
||||
|
||||
constructor(container: HTMLElement, private os: OperatingSystem, private options?: KeybindingLabelOptions) {
|
||||
private labelBackground: Color | undefined;
|
||||
private labelForeground: Color | undefined;
|
||||
private labelBorder: Color | undefined;
|
||||
private labelBottomBorder: Color | undefined;
|
||||
private labelShadow: Color | undefined;
|
||||
|
||||
constructor(container: HTMLElement, private os: OperatingSystem, options?: KeybindingLabelOptions) {
|
||||
this.options = options || Object.create(null);
|
||||
|
||||
this.labelBackground = this.options.keybindingLabelBackground;
|
||||
this.labelForeground = this.options.keybindingLabelForeground;
|
||||
this.labelBorder = this.options.keybindingLabelBorder;
|
||||
this.labelBottomBorder = this.options.keybindingLabelBottomBorder;
|
||||
this.labelShadow = this.options.keybindingLabelShadow;
|
||||
|
||||
this.domNode = dom.append(container, $('.monaco-keybinding'));
|
||||
this.didEverRender = false;
|
||||
container.appendChild(this.domNode);
|
||||
@ -58,7 +86,7 @@ export class KeybindingLabel {
|
||||
}
|
||||
|
||||
private render() {
|
||||
dom.clearNode(this.domNode);
|
||||
this.clear();
|
||||
|
||||
if (this.keybinding) {
|
||||
let [firstPart, chordPart] = this.keybinding.getParts();
|
||||
@ -74,9 +102,16 @@ export class KeybindingLabel {
|
||||
this.renderUnbound(this.domNode);
|
||||
}
|
||||
|
||||
this.applyStyles();
|
||||
|
||||
this.didEverRender = true;
|
||||
}
|
||||
|
||||
private clear(): void {
|
||||
dom.clearNode(this.domNode);
|
||||
this.keyElements.clear();
|
||||
}
|
||||
|
||||
private renderPart(parent: HTMLElement, part: ResolvedKeybindingPart, match: PartMatches | null) {
|
||||
const modifierLabels = UILabelProvider.modifierLabels[this.os];
|
||||
if (part.ctrlKey) {
|
||||
@ -98,14 +133,54 @@ export class KeybindingLabel {
|
||||
}
|
||||
|
||||
private renderKey(parent: HTMLElement, label: string, highlight: boolean, separator: string): void {
|
||||
dom.append(parent, $('span.monaco-keybinding-key' + (highlight ? '.highlight' : ''), undefined, label));
|
||||
dom.append(parent, this.createKeyElement(label, highlight ? '.highlight' : ''));
|
||||
if (separator) {
|
||||
dom.append(parent, $('span.monaco-keybinding-key-separator', undefined, separator));
|
||||
}
|
||||
}
|
||||
|
||||
private renderUnbound(parent: HTMLElement): void {
|
||||
dom.append(parent, $('span.monaco-keybinding-key', undefined, localize('unbound', "Unbound")));
|
||||
dom.append(parent, this.createKeyElement(localize('unbound', "Unbound")));
|
||||
}
|
||||
|
||||
private createKeyElement(label: string, extraClass = ''): HTMLElement {
|
||||
const keyElement = $('span.monaco-keybinding-key' + extraClass, undefined, label);
|
||||
this.keyElements.add(keyElement);
|
||||
|
||||
return keyElement;
|
||||
}
|
||||
|
||||
style(styles: IKeybindingLabelStyles): void {
|
||||
this.labelBackground = styles.keybindingLabelBackground;
|
||||
this.labelForeground = styles.keybindingLabelForeground;
|
||||
this.labelBorder = styles.keybindingLabelBorder;
|
||||
this.labelBottomBorder = styles.keybindingLabelBottomBorder;
|
||||
this.labelShadow = styles.keybindingLabelShadow;
|
||||
|
||||
this.applyStyles();
|
||||
}
|
||||
|
||||
private applyStyles() {
|
||||
if (this.element) {
|
||||
for (const keyElement of this.keyElements) {
|
||||
if (this.labelBackground) {
|
||||
keyElement.style.backgroundColor = this.labelBackground?.toString();
|
||||
}
|
||||
if (this.labelBorder) {
|
||||
keyElement.style.borderColor = this.labelBorder.toString();
|
||||
}
|
||||
if (this.labelBottomBorder) {
|
||||
keyElement.style.borderBottomColor = this.labelBottomBorder.toString();
|
||||
}
|
||||
if (this.labelShadow) {
|
||||
keyElement.style.boxShadow = `inset 0 -1px 0 ${this.labelShadow}`;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.labelForeground) {
|
||||
this.element.style.color = this.labelForeground.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static areSame(a: Matches | undefined, b: Matches | undefined): boolean {
|
||||
|
@ -339,7 +339,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
container.appendChild(this.domNode);
|
||||
|
||||
this.scrollableElement.onScroll(this.onScroll, this, this.disposables);
|
||||
domEvent(this.rowsContainer, TouchEventType.Change)(this.onTouchChange, this, this.disposables);
|
||||
domEvent(this.rowsContainer, TouchEventType.Change)(e => this.onTouchChange(e as GestureEvent), this, this.disposables);
|
||||
|
||||
// Prevent the monaco-scrollable-element from scrolling
|
||||
// https://github.com/microsoft/vscode/issues/44181
|
||||
@ -362,6 +362,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
updateOptions(options: IListViewOptionsUpdate) {
|
||||
if (options.additionalScrollHeight !== undefined) {
|
||||
this.additionalScrollHeight = options.additionalScrollHeight;
|
||||
this.scrollableElement.setScrollDimensions({ scrollHeight: this.scrollHeight });
|
||||
}
|
||||
|
||||
if (options.smoothScrolling !== undefined) {
|
||||
@ -407,6 +408,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
this.items[index].size = size;
|
||||
|
||||
this.render(lastRenderRange, Math.max(0, this.lastRenderTop + heightDiff), this.lastRenderHeight, undefined, undefined, true);
|
||||
this.setScrollTop(this.lastRenderTop);
|
||||
|
||||
this.eventuallyUpdateScrollDimensions();
|
||||
|
||||
@ -679,12 +681,12 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
if (this.supportDynamicHeights) {
|
||||
this._rerender(this.scrollTop, this.renderHeight);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.horizontalScrolling) {
|
||||
this.scrollableElement.setScrollDimensions({
|
||||
width: typeof width === 'number' ? width : getContentWidth(this.domNode)
|
||||
});
|
||||
}
|
||||
if (this.horizontalScrolling) {
|
||||
this.scrollableElement.setScrollDimensions({
|
||||
width: typeof width === 'number' ? width : getContentWidth(this.domNode)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -898,7 +900,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
@memoize get onMouseOut(): Event<IListMouseEvent<T>> { return Event.map(domEvent(this.domNode, 'mouseout'), e => this.toMouseEvent(e)); }
|
||||
@memoize get onContextMenu(): Event<IListMouseEvent<T>> { return Event.map(domEvent(this.domNode, 'contextmenu'), e => this.toMouseEvent(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)); }
|
||||
@memoize get onTap(): Event<IListGestureEvent<T>> { return Event.map(domEvent(this.rowsContainer, TouchEventType.Tap), e => this.toGestureEvent(e as GestureEvent)); }
|
||||
|
||||
private toMouseEvent(browserEvent: MouseEvent): IListMouseEvent<T> {
|
||||
const index = this.getItemIndexFromEventTarget(browserEvent.target || null);
|
||||
|
@ -188,7 +188,7 @@ class SelectionTrait<T> extends Trait<T> {
|
||||
super('selected');
|
||||
}
|
||||
|
||||
renderIndex(index: number, container: HTMLElement): void {
|
||||
override renderIndex(index: number, container: HTMLElement): void {
|
||||
super.renderIndex(index, container);
|
||||
|
||||
if (this.setAriaSelected) {
|
||||
@ -1635,13 +1635,13 @@ export class List<T> implements ISpliceable<T>, IThemable, IDisposable {
|
||||
this.view.setScrollTop(m * clamp(relativeTop, 0, 1) + elementTop);
|
||||
} else {
|
||||
const viewItemBottom = elementTop + elementHeight;
|
||||
const wrapperBottom = scrollTop + this.view.renderHeight;
|
||||
const scrollBottom = scrollTop + this.view.renderHeight;
|
||||
|
||||
if (elementTop < scrollTop && viewItemBottom >= wrapperBottom) {
|
||||
if (elementTop < scrollTop && viewItemBottom >= scrollBottom) {
|
||||
// The element is already overflowing the viewport, no-op
|
||||
} else if (elementTop < scrollTop) {
|
||||
} else if (elementTop < scrollTop || (viewItemBottom >= scrollBottom && elementHeight >= this.view.renderHeight)) {
|
||||
this.view.setScrollTop(elementTop);
|
||||
} else if (viewItemBottom >= wrapperBottom) {
|
||||
} else if (viewItemBottom >= scrollBottom) {
|
||||
this.view.setScrollTop(viewItemBottom - this.view.renderHeight);
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ export enum Direction {
|
||||
}
|
||||
|
||||
export interface IMenuOptions {
|
||||
context?: any;
|
||||
context?: unknown;
|
||||
actionViewItemProvider?: IActionViewItemProvider;
|
||||
actionRunner?: IActionRunner;
|
||||
getKeyBinding?: (action: IAction) => ResolvedKeybinding | undefined;
|
||||
@ -264,7 +264,7 @@ export class Menu extends ActionBar {
|
||||
}
|
||||
}
|
||||
|
||||
getContainer(): HTMLElement {
|
||||
override getContainer(): HTMLElement {
|
||||
return this.scrollableElement.getDomNode();
|
||||
}
|
||||
|
||||
@ -309,7 +309,7 @@ export class Menu extends ActionBar {
|
||||
}
|
||||
}
|
||||
|
||||
protected updateFocus(fromRight?: boolean): void {
|
||||
protected override updateFocus(fromRight?: boolean): void {
|
||||
super.updateFocus(fromRight, true);
|
||||
|
||||
if (typeof this.focusedItem !== 'undefined') {
|
||||
@ -385,7 +385,7 @@ class BaseMenuActionViewItem extends BaseActionViewItem {
|
||||
|
||||
public container: HTMLElement | undefined;
|
||||
|
||||
protected options: IMenuItemOptions;
|
||||
protected override options: IMenuItemOptions;
|
||||
protected item: HTMLElement | undefined;
|
||||
|
||||
private runOnceToEnableMouseUp: RunOnceScheduler;
|
||||
@ -465,7 +465,7 @@ class BaseMenuActionViewItem extends BaseActionViewItem {
|
||||
this._register(this.runOnceToEnableMouseUp);
|
||||
}
|
||||
|
||||
render(container: HTMLElement): void {
|
||||
override render(container: HTMLElement): void {
|
||||
super.render(container);
|
||||
|
||||
if (!this.element) {
|
||||
@ -504,12 +504,12 @@ class BaseMenuActionViewItem extends BaseActionViewItem {
|
||||
this.updateChecked();
|
||||
}
|
||||
|
||||
blur(): void {
|
||||
override blur(): void {
|
||||
super.blur();
|
||||
this.applyStyle();
|
||||
}
|
||||
|
||||
focus(): void {
|
||||
override focus(): void {
|
||||
super.focus();
|
||||
|
||||
if (this.item) {
|
||||
@ -526,7 +526,7 @@ class BaseMenuActionViewItem extends BaseActionViewItem {
|
||||
}
|
||||
}
|
||||
|
||||
updateLabel(): void {
|
||||
override updateLabel(): void {
|
||||
if (!this.label) {
|
||||
return;
|
||||
}
|
||||
@ -579,7 +579,7 @@ class BaseMenuActionViewItem extends BaseActionViewItem {
|
||||
}
|
||||
}
|
||||
|
||||
updateTooltip(): void {
|
||||
override updateTooltip(): void {
|
||||
let title: string | null = null;
|
||||
|
||||
if (this.getAction().tooltip) {
|
||||
@ -598,7 +598,7 @@ class BaseMenuActionViewItem extends BaseActionViewItem {
|
||||
}
|
||||
}
|
||||
|
||||
updateClass(): void {
|
||||
override updateClass(): void {
|
||||
if (this.cssClass && this.item) {
|
||||
this.item.classList.remove(...this.cssClass.split(' '));
|
||||
}
|
||||
@ -614,7 +614,7 @@ class BaseMenuActionViewItem extends BaseActionViewItem {
|
||||
}
|
||||
}
|
||||
|
||||
updateEnabled(): void {
|
||||
override updateEnabled(): void {
|
||||
if (this.getAction().enabled) {
|
||||
if (this.element) {
|
||||
this.element.classList.remove('disabled');
|
||||
@ -639,7 +639,7 @@ class BaseMenuActionViewItem extends BaseActionViewItem {
|
||||
}
|
||||
}
|
||||
|
||||
updateChecked(): void {
|
||||
override updateChecked(): void {
|
||||
if (!this.item) {
|
||||
return;
|
||||
}
|
||||
@ -724,7 +724,7 @@ class SubmenuMenuActionViewItem extends BaseMenuActionViewItem {
|
||||
}, 750);
|
||||
}
|
||||
|
||||
render(container: HTMLElement): void {
|
||||
override render(container: HTMLElement): void {
|
||||
super.render(container);
|
||||
|
||||
if (!this.element) {
|
||||
@ -783,7 +783,7 @@ class SubmenuMenuActionViewItem extends BaseMenuActionViewItem {
|
||||
}));
|
||||
}
|
||||
|
||||
updateEnabled(): void {
|
||||
override updateEnabled(): void {
|
||||
// override on submenu entry
|
||||
// native menus do not observe enablement on sumbenus
|
||||
// we mimic that behavior
|
||||
@ -794,7 +794,7 @@ class SubmenuMenuActionViewItem extends BaseMenuActionViewItem {
|
||||
this.createSubmenu(selectFirst);
|
||||
}
|
||||
|
||||
onClick(e: EventLike): void {
|
||||
override onClick(e: EventLike): void {
|
||||
// stop clicking from trying to run an action
|
||||
EventHelper.stop(e, true);
|
||||
|
||||
@ -925,7 +925,7 @@ class SubmenuMenuActionViewItem extends BaseMenuActionViewItem {
|
||||
}
|
||||
}
|
||||
|
||||
protected applyStyle(): void {
|
||||
protected override applyStyle(): void {
|
||||
super.applyStyle();
|
||||
|
||||
if (!this.menuStyle) {
|
||||
@ -944,7 +944,7 @@ class SubmenuMenuActionViewItem extends BaseMenuActionViewItem {
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
override dispose(): void {
|
||||
super.dispose();
|
||||
|
||||
this.hideScheduler.dispose();
|
||||
|
@ -422,7 +422,7 @@ export class MenuBar extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
override dispose(): void {
|
||||
super.dispose();
|
||||
|
||||
this.menuCache.forEach(menuBarMenu => {
|
||||
|
@ -211,7 +211,7 @@ export class Sash extends Disposable {
|
||||
this._register(domEvent(this.el, 'mouseleave')(() => Sash.onMouseLeave(this)));
|
||||
|
||||
this._register(Gesture.addTarget(this.el));
|
||||
this._register(domEvent(this.el, EventType.Start)(this.onTouchStart, this));
|
||||
this._register(domEvent(this.el, EventType.Start)(e => this.onTouchStart(e as GestureEvent), this));
|
||||
|
||||
if (typeof options.size === 'number') {
|
||||
this.size = options.size;
|
||||
@ -430,6 +430,10 @@ export class Sash extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
clearSashHoverState(): void {
|
||||
Sash.onMouseLeave(this);
|
||||
}
|
||||
|
||||
layout(): void {
|
||||
if (this.orientation === Orientation.VERTICAL) {
|
||||
const verticalProvider = (<IVerticalSashLayoutProvider>this.layoutProvider);
|
||||
@ -484,7 +488,7 @@ export class Sash extends Disposable {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
override dispose(): void {
|
||||
super.dispose();
|
||||
this.el.remove();
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ export abstract class AbstractScrollableElement extends Widget {
|
||||
this._domNode.appendChild(this._topShadowDomNode.domNode);
|
||||
|
||||
this._topLeftShadowDomNode = createFastDomNode(document.createElement('div'));
|
||||
this._topLeftShadowDomNode.setClassName('shadow top-left-corner');
|
||||
this._topLeftShadowDomNode.setClassName('shadow');
|
||||
this._domNode.appendChild(this._topLeftShadowDomNode.domNode);
|
||||
} else {
|
||||
this._leftShadowDomNode = null;
|
||||
@ -239,7 +239,7 @@ export abstract class AbstractScrollableElement extends Widget {
|
||||
this._revealOnScroll = true;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
public override dispose(): void {
|
||||
this._mouseWheelToDispose = dispose(this._mouseWheelToDispose);
|
||||
super.dispose();
|
||||
}
|
||||
@ -484,9 +484,12 @@ export abstract class AbstractScrollableElement extends Widget {
|
||||
const enableTop = scrollState.scrollTop > 0;
|
||||
const enableLeft = scrollState.scrollLeft > 0;
|
||||
|
||||
this._leftShadowDomNode!.setClassName('shadow' + (enableLeft ? ' left' : ''));
|
||||
this._topShadowDomNode!.setClassName('shadow' + (enableTop ? ' top' : ''));
|
||||
this._topLeftShadowDomNode!.setClassName('shadow top-left-corner' + (enableTop ? ' top' : '') + (enableLeft ? ' left' : ''));
|
||||
const leftClassName = (enableLeft ? ' left' : '');
|
||||
const topClassName = (enableTop ? ' top' : '');
|
||||
const topLeftClassName = (enableLeft || enableTop ? ' top-left-corner' : '');
|
||||
this._leftShadowDomNode!.setClassName(`shadow${leftClassName}`);
|
||||
this._topShadowDomNode!.setClassName(`shadow${topClassName}`);
|
||||
this._topLeftShadowDomNode!.setClassName(`shadow${topLeftClassName}${topClassName}${leftClassName}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1046,7 +1046,7 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
|
||||
}
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
public override dispose(): void {
|
||||
this.hideSelectDropDown(false);
|
||||
super.dispose();
|
||||
}
|
||||
|
@ -52,6 +52,14 @@
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.monaco-pane-view .pane > .pane-header > .actions .action-item {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.monaco-pane-view .pane > .pane-header > .actions .action-label {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
/* TODO: actions should be part of the pane, but they aren't yet */
|
||||
.monaco-pane-view .pane:hover > .pane-header.expanded > .actions,
|
||||
.monaco-pane-view .pane:focus-within > .pane-header.expanded > .actions,
|
||||
@ -60,22 +68,6 @@
|
||||
display: initial;
|
||||
}
|
||||
|
||||
/* TODO: actions should be part of the pane, but they aren't yet */
|
||||
.monaco-pane-view .pane > .pane-header > .actions .action-label.icon,
|
||||
.monaco-pane-view .pane > .pane-header > .actions .action-label.codicon {
|
||||
width: 28px;
|
||||
height: 22px;
|
||||
background-size: 16px;
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
margin-right: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: inherit;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
.monaco-pane-view .pane > .pane-header .monaco-action-bar .action-item.select-container {
|
||||
cursor: default;
|
||||
}
|
||||
|
@ -568,7 +568,7 @@ export class PaneView extends Disposable {
|
||||
}, 200);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
override dispose(): void {
|
||||
super.dispose();
|
||||
|
||||
this.paneItems.forEach(i => i.disposable.dispose());
|
||||
|
@ -1022,7 +1022,7 @@ export class SplitView<TLayoutContext = undefined> extends Disposable {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
override dispose(): void {
|
||||
super.dispose();
|
||||
|
||||
this.viewItems.forEach(i => i.dispose());
|
||||
|
@ -3,6 +3,10 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-toolbar {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.monaco-toolbar .toolbar-toggle-more {
|
||||
display: inline-block;
|
||||
padding: 0;
|
||||
|
@ -181,7 +181,7 @@ export class ToolBar extends Disposable {
|
||||
this.actionBar.clear();
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
override dispose(): void {
|
||||
this.clear();
|
||||
super.dispose();
|
||||
}
|
||||
@ -202,7 +202,7 @@ class ToggleMenuAction extends Action {
|
||||
this.toggleDropdownMenu = toggleDropdownMenu;
|
||||
}
|
||||
|
||||
async run(): Promise<void> {
|
||||
override async run(): Promise<void> {
|
||||
this.toggleDropdownMenu();
|
||||
}
|
||||
|
||||
|
@ -29,11 +29,11 @@ import { treeItemExpandedIcon, treeFilterOnTypeOnIcon, treeFilterOnTypeOffIcon,
|
||||
|
||||
class TreeElementsDragAndDropData<T, TFilterData, TContext> extends ElementsDragAndDropData<T, TContext> {
|
||||
|
||||
set context(context: TContext | undefined) {
|
||||
override set context(context: TContext | undefined) {
|
||||
this.data.context = context;
|
||||
}
|
||||
|
||||
get context(): TContext | undefined {
|
||||
override get context(): TContext | undefined {
|
||||
return this.data.context;
|
||||
}
|
||||
|
||||
@ -1091,7 +1091,7 @@ class TreeNodeListMouseController<T, TFilterData, TRef> extends MouseController<
|
||||
super(list);
|
||||
}
|
||||
|
||||
protected onViewPointer(e: IListMouseEvent<ITreeNode<T, TFilterData>>): void {
|
||||
protected override onViewPointer(e: IListMouseEvent<ITreeNode<T, TFilterData>>): void {
|
||||
if (isInputElement(e.browserEvent.target as HTMLElement) || isMonacoEditor(e.browserEvent.target as HTMLElement)) {
|
||||
return;
|
||||
}
|
||||
@ -1141,7 +1141,7 @@ class TreeNodeListMouseController<T, TFilterData, TRef> extends MouseController<
|
||||
super.onViewPointer(e);
|
||||
}
|
||||
|
||||
protected onDoubleClick(e: IListMouseEvent<ITreeNode<T, TFilterData>>): void {
|
||||
protected override onDoubleClick(e: IListMouseEvent<ITreeNode<T, TFilterData>>): void {
|
||||
const onTwistie = (e.browserEvent.target as HTMLElement).classList.contains('monaco-tl-twistie');
|
||||
|
||||
if (onTwistie || !this.tree.expandOnDoubleClick) {
|
||||
@ -1175,11 +1175,11 @@ class TreeNodeList<T, TFilterData, TRef> extends List<ITreeNode<T, TFilterData>>
|
||||
super(user, container, virtualDelegate, renderers, options);
|
||||
}
|
||||
|
||||
protected createMouseController(options: ITreeNodeListOptions<T, TFilterData, TRef>): MouseController<ITreeNode<T, TFilterData>> {
|
||||
protected override createMouseController(options: ITreeNodeListOptions<T, TFilterData, TRef>): MouseController<ITreeNode<T, TFilterData>> {
|
||||
return new TreeNodeListMouseController(this, options.tree);
|
||||
}
|
||||
|
||||
splice(start: number, deleteCount: number, elements: ITreeNode<T, TFilterData>[] = []): void {
|
||||
override splice(start: number, deleteCount: number, elements: ITreeNode<T, TFilterData>[] = []): void {
|
||||
super.splice(start, deleteCount, elements);
|
||||
|
||||
if (elements.length === 0) {
|
||||
@ -1217,7 +1217,7 @@ class TreeNodeList<T, TFilterData, TRef> extends List<ITreeNode<T, TFilterData>>
|
||||
}
|
||||
}
|
||||
|
||||
setFocus(indexes: number[], browserEvent?: UIEvent, fromAPI = false): void {
|
||||
override setFocus(indexes: number[], browserEvent?: UIEvent, fromAPI = false): void {
|
||||
super.setFocus(indexes, browserEvent);
|
||||
|
||||
if (!fromAPI) {
|
||||
@ -1225,7 +1225,7 @@ class TreeNodeList<T, TFilterData, TRef> extends List<ITreeNode<T, TFilterData>>
|
||||
}
|
||||
}
|
||||
|
||||
setSelection(indexes: number[], browserEvent?: UIEvent, fromAPI = false): void {
|
||||
override setSelection(indexes: number[], browserEvent?: UIEvent, fromAPI = false): void {
|
||||
super.setSelection(indexes, browserEvent);
|
||||
|
||||
if (!fromAPI) {
|
||||
@ -1233,7 +1233,7 @@ class TreeNodeList<T, TFilterData, TRef> extends List<ITreeNode<T, TFilterData>>
|
||||
}
|
||||
}
|
||||
|
||||
setAnchor(index: number | undefined, fromAPI = false): void {
|
||||
override setAnchor(index: number | undefined, fromAPI = false): void {
|
||||
super.setAnchor(index);
|
||||
|
||||
if (!fromAPI) {
|
||||
|
@ -157,11 +157,11 @@ function asTreeContextMenuEvent<TInput, T>(e: ITreeContextMenuEvent<IAsyncDataTr
|
||||
|
||||
class AsyncDataTreeElementsDragAndDropData<TInput, T, TContext> extends ElementsDragAndDropData<T, TContext> {
|
||||
|
||||
set context(context: TContext | undefined) {
|
||||
override set context(context: TContext | undefined) {
|
||||
this.data.context = context;
|
||||
}
|
||||
|
||||
get context(): TContext | undefined {
|
||||
override get context(): TContext | undefined {
|
||||
return this.data.context;
|
||||
}
|
||||
|
||||
@ -1131,7 +1131,7 @@ export interface ICompressibleAsyncDataTreeOptionsUpdate extends IAsyncDataTreeO
|
||||
|
||||
export class CompressibleAsyncDataTree<TInput, T, TFilterData = void> extends AsyncDataTree<TInput, T, TFilterData> {
|
||||
|
||||
protected readonly tree!: CompressibleObjectTree<IAsyncDataTreeNode<TInput, T>, TFilterData>;
|
||||
protected override readonly tree!: CompressibleObjectTree<IAsyncDataTreeNode<TInput, T>, TFilterData>;
|
||||
protected readonly compressibleNodeMapper: CompressibleAsyncDataTreeNodeMapper<TInput, T, TFilterData> = new WeakMapper(node => new CompressibleAsyncDataTreeNodeWrapper(node));
|
||||
private filter?: ITreeFilter<T, TFilterData>;
|
||||
|
||||
@ -1148,7 +1148,7 @@ export class CompressibleAsyncDataTree<TInput, T, TFilterData = void> extends As
|
||||
this.filter = options.filter;
|
||||
}
|
||||
|
||||
protected createTree(
|
||||
protected override createTree(
|
||||
user: string,
|
||||
container: HTMLElement,
|
||||
delegate: IListVirtualDelegate<T>,
|
||||
@ -1162,18 +1162,18 @@ export class CompressibleAsyncDataTree<TInput, T, TFilterData = void> extends As
|
||||
return new CompressibleObjectTree(user, container, objectTreeDelegate, objectTreeRenderers, objectTreeOptions);
|
||||
}
|
||||
|
||||
protected asTreeElement(node: IAsyncDataTreeNode<TInput, T>, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>): ICompressedTreeElement<IAsyncDataTreeNode<TInput, T>> {
|
||||
protected override asTreeElement(node: IAsyncDataTreeNode<TInput, T>, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>): ICompressedTreeElement<IAsyncDataTreeNode<TInput, T>> {
|
||||
return {
|
||||
incompressible: this.compressionDelegate.isIncompressible(node.element as T),
|
||||
...super.asTreeElement(node, viewStateContext)
|
||||
};
|
||||
}
|
||||
|
||||
updateOptions(options: ICompressibleAsyncDataTreeOptionsUpdate = {}): void {
|
||||
override updateOptions(options: ICompressibleAsyncDataTreeOptionsUpdate = {}): void {
|
||||
this.tree.updateOptions(options);
|
||||
}
|
||||
|
||||
getViewState(): IAsyncDataTreeViewState {
|
||||
override getViewState(): IAsyncDataTreeViewState {
|
||||
if (!this.identityProvider) {
|
||||
throw new TreeError(this.user, 'Can\'t get tree view state without an identity provider');
|
||||
}
|
||||
@ -1201,7 +1201,7 @@ export class CompressibleAsyncDataTree<TInput, T, TFilterData = void> extends As
|
||||
return { focus, selection, expanded, scrollTop: this.scrollTop };
|
||||
}
|
||||
|
||||
protected render(node: IAsyncDataTreeNode<TInput, T>, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>): void {
|
||||
protected override render(node: IAsyncDataTreeNode<TInput, T>, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>): void {
|
||||
if (!this.identityProvider) {
|
||||
return super.render(node, viewStateContext);
|
||||
}
|
||||
@ -1277,7 +1277,7 @@ export class CompressibleAsyncDataTree<TInput, T, TFilterData = void> extends As
|
||||
// For compressed async data trees, `TreeVisibility.Recurse` doesn't currently work
|
||||
// and we have to filter everything beforehand
|
||||
// Related to #85193 and #85835
|
||||
protected processChildren(children: Iterable<T>): Iterable<T> {
|
||||
protected override processChildren(children: Iterable<T>): Iterable<T> {
|
||||
if (this.filter) {
|
||||
children = Iterable.filter(children, e => {
|
||||
const result = this.filter!.filter(e, TreeVisibility.Visible);
|
||||
|
@ -23,7 +23,7 @@ export interface IDataTreeViewState {
|
||||
|
||||
export class DataTree<TInput, T, TFilterData = void> extends AbstractTree<T | null, TFilterData, T | null> {
|
||||
|
||||
protected model!: ObjectTreeModel<T, TFilterData>;
|
||||
protected override model!: ObjectTreeModel<T, TFilterData>;
|
||||
private input: TInput | undefined;
|
||||
|
||||
private identityProvider: IIdentityProvider<T> | undefined;
|
||||
|
@ -14,7 +14,7 @@ export interface IIndexTreeOptions<T, TFilterData = void> extends IAbstractTreeO
|
||||
|
||||
export class IndexTree<T, TFilterData = void> extends AbstractTree<T, TFilterData, number[]> {
|
||||
|
||||
protected model!: IndexTreeModel<T, TFilterData>;
|
||||
protected override model!: IndexTreeModel<T, TFilterData>;
|
||||
|
||||
constructor(
|
||||
user: string,
|
||||
|
@ -38,9 +38,9 @@ export interface IObjectTreeSetChildrenOptions<T> {
|
||||
|
||||
export class ObjectTree<T extends NonNullable<any>, TFilterData = void> extends AbstractTree<T | null, TFilterData, T | null> {
|
||||
|
||||
protected model!: IObjectTreeModel<T, TFilterData>;
|
||||
protected override model!: IObjectTreeModel<T, TFilterData>;
|
||||
|
||||
get onDidChangeCollapseState(): Event<ICollapseStateChangeEvent<T | null, TFilterData>> { return this.model.onDidChangeCollapseState; }
|
||||
override get onDidChangeCollapseState(): Event<ICollapseStateChangeEvent<T | null, TFilterData>> { return this.model.onDidChangeCollapseState; }
|
||||
|
||||
constructor(
|
||||
user: string,
|
||||
@ -194,7 +194,7 @@ export interface ICompressibleObjectTreeOptionsUpdate extends IAbstractTreeOptio
|
||||
|
||||
export class CompressibleObjectTree<T extends NonNullable<any>, TFilterData = void> extends ObjectTree<T, TFilterData> implements ICompressedTreeNodeProvider<T, TFilterData> {
|
||||
|
||||
protected model!: CompressibleObjectTreeModel<T, TFilterData>;
|
||||
protected override model!: CompressibleObjectTreeModel<T, TFilterData>;
|
||||
|
||||
constructor(
|
||||
user: string,
|
||||
@ -208,15 +208,15 @@ export class CompressibleObjectTree<T extends NonNullable<any>, TFilterData = vo
|
||||
super(user, container, delegate, compressibleRenderers, asObjectTreeOptions<T, TFilterData>(compressedTreeNodeProvider, options));
|
||||
}
|
||||
|
||||
setChildren(element: T | null, children: Iterable<ICompressedTreeElement<T>> = Iterable.empty(), options?: IObjectTreeSetChildrenOptions<T>): void {
|
||||
override setChildren(element: T | null, children: Iterable<ICompressedTreeElement<T>> = Iterable.empty(), options?: IObjectTreeSetChildrenOptions<T>): void {
|
||||
this.model.setChildren(element, children, options);
|
||||
}
|
||||
|
||||
protected createModel(user: string, view: IList<ITreeNode<T, TFilterData>>, options: ICompressibleObjectTreeOptions<T, TFilterData>): ITreeModel<T | null, TFilterData, T | null> {
|
||||
protected override createModel(user: string, view: IList<ITreeNode<T, TFilterData>>, options: ICompressibleObjectTreeOptions<T, TFilterData>): ITreeModel<T | null, TFilterData, T | null> {
|
||||
return new CompressibleObjectTreeModel(user, view, options);
|
||||
}
|
||||
|
||||
updateOptions(optionsUpdate: ICompressibleObjectTreeOptionsUpdate = {}): void {
|
||||
override updateOptions(optionsUpdate: ICompressibleObjectTreeOptionsUpdate = {}): void {
|
||||
super.updateOptions(optionsUpdate);
|
||||
|
||||
if (typeof optionsUpdate.compressionEnabled !== 'undefined') {
|
||||
|
@ -13,11 +13,9 @@ export class CollapseAllAction<TInput, T, TFilterData = void> extends Action {
|
||||
super('vs.tree.collapse', nls.localize('collapse all', "Collapse All"), 'collapse-all', enabled);
|
||||
}
|
||||
|
||||
async run(): Promise<any> {
|
||||
override async run(): Promise<any> {
|
||||
this.viewer.collapseAll();
|
||||
this.viewer.setSelection([]);
|
||||
this.viewer.setFocus([]);
|
||||
this.viewer.domFocus();
|
||||
this.viewer.focusFirst();
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import { Event, Emitter } from 'vs/base/common/event';
|
||||
export interface ITelemetryData {
|
||||
readonly from?: string;
|
||||
readonly target?: string;
|
||||
[key: string]: any;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
export type WorkbenchActionExecutedClassification = {
|
||||
@ -30,13 +30,14 @@ export interface IAction extends IDisposable {
|
||||
class: string | undefined;
|
||||
enabled: boolean;
|
||||
checked: boolean;
|
||||
run(event?: any): Promise<any>;
|
||||
run(event?: unknown): Promise<unknown>;
|
||||
}
|
||||
|
||||
export interface IActionRunner extends IDisposable {
|
||||
run(action: IAction, context?: any): Promise<any>;
|
||||
readonly onDidRun: Event<IRunEvent>;
|
||||
readonly onBeforeRun: Event<IRunEvent>;
|
||||
|
||||
run(action: IAction, context?: unknown): Promise<unknown>;
|
||||
}
|
||||
|
||||
export interface IActionChangeEvent {
|
||||
@ -58,9 +59,9 @@ export class Action extends Disposable implements IAction {
|
||||
protected _cssClass: string | undefined;
|
||||
protected _enabled: boolean = true;
|
||||
protected _checked: boolean = false;
|
||||
protected readonly _actionCallback?: (event?: any) => Promise<any>;
|
||||
protected readonly _actionCallback?: (event?: unknown) => Promise<unknown>;
|
||||
|
||||
constructor(id: string, label: string = '', cssClass: string = '', enabled: boolean = true, actionCallback?: (event?: any) => Promise<any>) {
|
||||
constructor(id: string, label: string = '', cssClass: string = '', enabled: boolean = true, actionCallback?: (event?: unknown) => Promise<unknown>) {
|
||||
super();
|
||||
this._id = id;
|
||||
this._label = label;
|
||||
@ -148,19 +149,16 @@ export class Action extends Disposable implements IAction {
|
||||
}
|
||||
}
|
||||
|
||||
run(event?: any, _data?: ITelemetryData): Promise<any> {
|
||||
async run(event?: unknown, data?: ITelemetryData): Promise<void> {
|
||||
if (this._actionCallback) {
|
||||
return this._actionCallback(event);
|
||||
await this._actionCallback(event);
|
||||
}
|
||||
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
}
|
||||
|
||||
export interface IRunEvent {
|
||||
readonly action: IAction;
|
||||
readonly result?: any;
|
||||
readonly error?: any;
|
||||
readonly error?: Error;
|
||||
}
|
||||
|
||||
export class ActionRunner extends Disposable implements IActionRunner {
|
||||
@ -171,24 +169,25 @@ export class ActionRunner extends Disposable implements IActionRunner {
|
||||
private _onDidRun = this._register(new Emitter<IRunEvent>());
|
||||
readonly onDidRun = this._onDidRun.event;
|
||||
|
||||
async run(action: IAction, context?: any): Promise<any> {
|
||||
async run(action: IAction, context?: unknown): Promise<void> {
|
||||
if (!action.enabled) {
|
||||
return Promise.resolve(null);
|
||||
return;
|
||||
}
|
||||
|
||||
this._onBeforeRun.fire({ action: action });
|
||||
this._onBeforeRun.fire({ action });
|
||||
|
||||
let error: Error | undefined = undefined;
|
||||
try {
|
||||
const result = await this.runAction(action, context);
|
||||
this._onDidRun.fire({ action: action, result: result });
|
||||
} catch (error) {
|
||||
this._onDidRun.fire({ action: action, error: error });
|
||||
await this.runAction(action, context);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
|
||||
this._onDidRun.fire({ action, error });
|
||||
}
|
||||
|
||||
protected runAction(action: IAction, context?: any): Promise<any> {
|
||||
const res = context ? action.run(context) : action.run();
|
||||
return Promise.resolve(res);
|
||||
protected async runAction(action: IAction, context?: unknown): Promise<void> {
|
||||
await action.run(context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,6 +197,7 @@ export class Separator extends Action {
|
||||
|
||||
constructor(label?: string) {
|
||||
super(Separator.ID, label, label ? 'separator text' : 'separator');
|
||||
|
||||
this.checked = false;
|
||||
this.enabled = false;
|
||||
}
|
||||
@ -213,6 +213,7 @@ export class SubmenuAction implements IAction {
|
||||
readonly checked: boolean = false;
|
||||
|
||||
private readonly _actions: readonly IAction[];
|
||||
get actions(): readonly IAction[] { return this._actions; }
|
||||
|
||||
constructor(id: string, label: string, actions: readonly IAction[], cssClass?: string) {
|
||||
this.id = id;
|
||||
@ -227,15 +228,13 @@ export class SubmenuAction implements IAction {
|
||||
// to bridge into the rendering world.
|
||||
}
|
||||
|
||||
get actions(): readonly IAction[] {
|
||||
return this._actions;
|
||||
}
|
||||
|
||||
async run(): Promise<any> { }
|
||||
async run(): Promise<void> { }
|
||||
}
|
||||
|
||||
export class EmptySubmenuAction extends Action {
|
||||
|
||||
static readonly ID = 'vs.actions.empty';
|
||||
|
||||
constructor() {
|
||||
super(EmptySubmenuAction.ID, nls.localize('submenu.empty', '(empty)'), undefined, false);
|
||||
}
|
||||
|
@ -381,7 +381,7 @@ export class AutoOpenBarrier extends Barrier {
|
||||
this._timeout = setTimeout(() => this.open(), autoOpenTimeMs);
|
||||
}
|
||||
|
||||
open(): void {
|
||||
override open(): void {
|
||||
clearTimeout(this._timeout);
|
||||
super.open();
|
||||
}
|
||||
@ -772,7 +772,7 @@ export class RunOnceWorker<T> extends RunOnceScheduler {
|
||||
}
|
||||
}
|
||||
|
||||
protected doRun(): void {
|
||||
protected override doRun(): void {
|
||||
const units = this.units;
|
||||
this.units = [];
|
||||
|
||||
@ -781,7 +781,7 @@ export class RunOnceWorker<T> extends RunOnceScheduler {
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
override dispose(): void {
|
||||
this.units = [];
|
||||
|
||||
super.dispose();
|
||||
@ -942,7 +942,7 @@ export class TaskSequentializer {
|
||||
}
|
||||
|
||||
setPending(taskId: number, promise: Promise<void>, onCancel?: () => void,): Promise<void> {
|
||||
this._pending = { taskId: taskId, cancel: () => onCancel?.(), promise };
|
||||
this._pending = { taskId, cancel: () => onCancel?.(), promise };
|
||||
|
||||
promise.then(() => this.donePending(taskId), () => this.donePending(taskId));
|
||||
|
||||
@ -1179,7 +1179,7 @@ export namespace Promises {
|
||||
* Interface of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled
|
||||
*/
|
||||
interface PromiseWithAllSettled<T> {
|
||||
allSettled<T>(promises: Promise<T>[]): Promise<ReadonlyArray<IResolvedPromise<T> | IRejectedPromise>>;
|
||||
allSettled<T>(promises: Promise<T>[]): Promise<readonly (IResolvedPromise<T> | IRejectedPromise)[]>;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1188,7 +1188,7 @@ export namespace Promises {
|
||||
* in the order of the original passed in promises array.
|
||||
* See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled
|
||||
*/
|
||||
export async function allSettled<T>(promises: Promise<T>[]): Promise<ReadonlyArray<IResolvedPromise<T> | IRejectedPromise>> {
|
||||
export async function allSettled<T>(promises: Promise<T>[]): Promise<readonly (IResolvedPromise<T> | IRejectedPromise)[]> {
|
||||
if (typeof (Promise as unknown as PromiseWithAllSettled<T>).allSettled === 'function') {
|
||||
return allSettledNative(promises); // in some environments we can benefit from native implementation
|
||||
}
|
||||
@ -1196,11 +1196,11 @@ export namespace Promises {
|
||||
return allSettledShim(promises);
|
||||
}
|
||||
|
||||
async function allSettledNative<T>(promises: Promise<T>[]): Promise<ReadonlyArray<IResolvedPromise<T> | IRejectedPromise>> {
|
||||
async function allSettledNative<T>(promises: Promise<T>[]): Promise<readonly (IResolvedPromise<T> | IRejectedPromise)[]> {
|
||||
return (Promise as unknown as PromiseWithAllSettled<T>).allSettled(promises);
|
||||
}
|
||||
|
||||
async function allSettledShim<T>(promises: Promise<T>[]): Promise<ReadonlyArray<IResolvedPromise<T> | IRejectedPromise>> {
|
||||
async function allSettledShim<T>(promises: Promise<T>[]): Promise<readonly (IResolvedPromise<T> | IRejectedPromise)[]> {
|
||||
return Promise.all(promises.map(promise => (promise.then(value => {
|
||||
const fulfilled: IResolvedPromise<T> = { status: 'fulfilled', value };
|
||||
|
||||
|
@ -235,3 +235,11 @@ export function streamToBufferReadableStream(stream: streams.ReadableStreamEvent
|
||||
export function newWriteableBufferStream(options?: streams.WriteableStreamOptions): streams.WriteableStream<VSBuffer> {
|
||||
return streams.newWriteableStream<VSBuffer>(chunks => VSBuffer.concat(chunks), options);
|
||||
}
|
||||
|
||||
export function prefixedBufferReadable(prefix: VSBuffer, readable: VSBufferReadable): VSBufferReadable {
|
||||
return streams.prefixedReadable(prefix, readable, chunks => VSBuffer.concat(chunks));
|
||||
}
|
||||
|
||||
export function prefixedBufferStream(prefix: VSBuffer, stream: VSBufferReadableStream): VSBufferReadableStream {
|
||||
return streams.prefixedStream(prefix, stream, chunks => VSBuffer.concat(chunks));
|
||||
}
|
||||
|
@ -49,6 +49,16 @@ export function registerCodicon(id: string, def: Codicon): Codicon {
|
||||
return new Codicon(id, def);
|
||||
}
|
||||
|
||||
// Selects all codicon names encapsulated in the `$()` syntax and wraps the
|
||||
// results with spaces so that screen readers can read the text better.
|
||||
export function getCodiconAriaLabel(text: string | undefined) {
|
||||
if (!text) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return text.replace(/\$\((.*?)\)/g, (_match, codiconName) => ` ${codiconName} `).trim();
|
||||
}
|
||||
|
||||
export class Codicon implements CSSIcon {
|
||||
constructor(public readonly id: string, public readonly definition: Codicon | IconDefinition, public description?: string) {
|
||||
_registry.add(this);
|
||||
@ -131,7 +141,6 @@ export namespace Codicon {
|
||||
export const tagAdd = new Codicon('tag-add', { fontCharacter: '\\ea66' });
|
||||
export const tagRemove = new Codicon('tag-remove', { fontCharacter: '\\ea66' });
|
||||
export const person = new Codicon('person', { fontCharacter: '\\ea67' });
|
||||
export const personAdd = new Codicon('person-add', { fontCharacter: '\\ea67' });
|
||||
export const personFollow = new Codicon('person-follow', { fontCharacter: '\\ea67' });
|
||||
export const personOutline = new Codicon('person-outline', { fontCharacter: '\\ea67' });
|
||||
export const personFilled = new Codicon('person-filled', { fontCharacter: '\\ea67' });
|
||||
@ -550,7 +559,20 @@ export namespace Codicon {
|
||||
export const debugRerun = new Codicon('debug-rerun', { fontCharacter: '\\ebc0' });
|
||||
export const workspaceTrusted = new Codicon('workspace-trusted', { fontCharacter: '\\ebc1' });
|
||||
export const workspaceUntrusted = new Codicon('workspace-untrusted', { fontCharacter: '\\ebc2' });
|
||||
export const workspaceUnknown = new Codicon('workspace-unknown', { fontCharacter: '\\ebc3' });
|
||||
export const workspaceUnspecified = new Codicon('workspace-unspecified', { fontCharacter: '\\ebc3' });
|
||||
export const terminalCmd = new Codicon('terminal-cmd', { fontCharacter: '\\ebc4' });
|
||||
export const terminalDebian = new Codicon('terminal-debian', { fontCharacter: '\\ebc5' });
|
||||
export const terminalLinux = new Codicon('terminal-linux', { fontCharacter: '\\ebc6' });
|
||||
export const terminalPowershell = new Codicon('terminal-powershell', { fontCharacter: '\\ebc7' });
|
||||
export const terminalTmux = new Codicon('terminal-tmux', { fontCharacter: '\\ebc8' });
|
||||
export const terminalUbuntu = new Codicon('terminal-ubuntu', { fontCharacter: '\\ebc9' });
|
||||
export const terminalBash = new Codicon('terminal-bash', { fontCharacter: '\\ebca' });
|
||||
export const arrowSwap = new Codicon('arrow-swap', { fontCharacter: '\\ebcb' });
|
||||
export const copy = new Codicon('copy', { fontCharacter: '\\ebcc' });
|
||||
export const personAdd = new Codicon('person-add', { fontCharacter: '\\ebcd' });
|
||||
export const filterFilled = new Codicon('filter-filled', { fontCharacter: '\\ebce' });
|
||||
export const wand = new Codicon('wand', { fontCharacter: '\\ebcf' });
|
||||
export const debugLineByLine = new Codicon('debug-line-by-line', { fontCharacter: '\\ebd0' });
|
||||
|
||||
export const dropDownButton = new Codicon('drop-down-button', Codicon.chevronDown.definition);
|
||||
}
|
||||
|
@ -66,6 +66,24 @@ export function groupBy<T>(data: T[], groupFn: (element: T) => string): IStringD
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Groups the collection into a dictionary based on the provided
|
||||
* group function.
|
||||
*/
|
||||
export function groupByNumber<T>(data: T[], groupFn: (element: T) => number): Map<number, T[]> {
|
||||
const result = new Map<number, T[]>();
|
||||
for (const element of data) {
|
||||
const key = groupFn(element);
|
||||
let target = result.get(key);
|
||||
if (!target) {
|
||||
target = [];
|
||||
result.set(key, target);
|
||||
}
|
||||
target.push(element);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function fromMap<T>(original: Map<string, T>): IStringDictionary<T> {
|
||||
const result: IStringDictionary<T> = Object.create(null);
|
||||
if (original) {
|
||||
|
@ -229,11 +229,11 @@ export class ExpectedError extends Error {
|
||||
}
|
||||
|
||||
export interface IErrorOptions {
|
||||
actions?: ReadonlyArray<IAction>;
|
||||
actions?: readonly IAction[];
|
||||
}
|
||||
|
||||
export interface IErrorWithActions {
|
||||
actions?: ReadonlyArray<IAction>;
|
||||
actions?: readonly IAction[];
|
||||
}
|
||||
|
||||
export function isErrorWithActions(obj: unknown): obj is IErrorWithActions {
|
||||
|
@ -674,7 +674,7 @@ export class PauseableEmitter<T> extends Emitter<T> {
|
||||
}
|
||||
}
|
||||
|
||||
fire(event: T): void {
|
||||
override fire(event: T): void {
|
||||
if (this._listeners) {
|
||||
if (this._isPaused !== 0) {
|
||||
this._eventQueue.push(event);
|
||||
|
@ -12,6 +12,8 @@ import { illegalArgument } from 'vs/base/common/errors';
|
||||
* But these are "more general", as they should work across browsers & OS`s.
|
||||
*/
|
||||
export const enum KeyCode {
|
||||
DependsOnKbLayout = -1,
|
||||
|
||||
/**
|
||||
* Placed first to cover the 0 value of the enum.
|
||||
*/
|
||||
|
@ -887,7 +887,7 @@ export class LinkedMap<K, V> implements Map<K, V> {
|
||||
this._tail = undefined;
|
||||
}
|
||||
else if (item === this._head) {
|
||||
// This can only happend if size === 1 which is handle
|
||||
// This can only happen if size === 1 which is handled
|
||||
// by the case above.
|
||||
if (!item.next) {
|
||||
throw new Error('Invalid list');
|
||||
@ -896,7 +896,7 @@ export class LinkedMap<K, V> implements Map<K, V> {
|
||||
this._head = item.next;
|
||||
}
|
||||
else if (item === this._tail) {
|
||||
// This can only happend if size === 1 which is handle
|
||||
// This can only happen if size === 1 which is handled
|
||||
// by the case above.
|
||||
if (!item.previous) {
|
||||
throw new Error('Invalid list');
|
||||
@ -1028,7 +1028,7 @@ export class LRUCache<K, V> extends LinkedMap<K, V> {
|
||||
this.checkTrim();
|
||||
}
|
||||
|
||||
get(key: K, touch: Touch = Touch.AsNew): V | undefined {
|
||||
override get(key: K, touch: Touch = Touch.AsNew): V | undefined {
|
||||
return super.get(key, touch);
|
||||
}
|
||||
|
||||
@ -1036,7 +1036,7 @@ export class LRUCache<K, V> extends LinkedMap<K, V> {
|
||||
return super.get(key, Touch.None);
|
||||
}
|
||||
|
||||
set(key: K, value: V): this {
|
||||
override set(key: K, value: V): this {
|
||||
super.set(key, value, Touch.AsNew);
|
||||
this.checkTrim();
|
||||
return this;
|
||||
@ -1048,3 +1048,47 @@ export class LRUCache<K, V> extends LinkedMap<K, V> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the map in type that only implements readonly properties. Useful
|
||||
* in the extension host to prevent the consumer from making any mutations.
|
||||
*/
|
||||
export class ReadonlyMapView<K, V> implements ReadonlyMap<K, V>{
|
||||
readonly #source: ReadonlyMap<K, V>;
|
||||
|
||||
public get size() {
|
||||
return this.#source.size;
|
||||
}
|
||||
|
||||
constructor(source: ReadonlyMap<K, V>) {
|
||||
this.#source = source;
|
||||
}
|
||||
|
||||
forEach(callbackfn: (value: V, key: K, map: ReadonlyMap<K, V>) => void, thisArg?: any): void {
|
||||
this.#source.forEach(callbackfn, thisArg);
|
||||
}
|
||||
|
||||
get(key: K): V | undefined {
|
||||
return this.#source.get(key);
|
||||
}
|
||||
|
||||
has(key: K): boolean {
|
||||
return this.#source.has(key);
|
||||
}
|
||||
|
||||
entries(): IterableIterator<[K, V]> {
|
||||
return this.#source.entries();
|
||||
}
|
||||
|
||||
keys(): IterableIterator<K> {
|
||||
return this.#source.keys();
|
||||
}
|
||||
|
||||
values(): IterableIterator<V> {
|
||||
return this.#source.values();
|
||||
}
|
||||
|
||||
[Symbol.iterator](): IterableIterator<[K, V]> {
|
||||
return this.#source.entries();
|
||||
}
|
||||
}
|
||||
|
@ -66,6 +66,8 @@ export namespace Schemas {
|
||||
|
||||
export const vscodeWorkspaceTrust = 'vscode-workspace-trust';
|
||||
|
||||
export const vscodeTerminal = 'vscode-terminal';
|
||||
|
||||
export const webviewPanel = 'webview-panel';
|
||||
|
||||
/**
|
||||
@ -73,11 +75,6 @@ export namespace Schemas {
|
||||
*/
|
||||
export const vscodeWebview = 'vscode-webview';
|
||||
|
||||
/**
|
||||
* Scheme used for loading resources inside of webviews.
|
||||
*/
|
||||
export const vscodeWebviewResource = 'vscode-webview-resource';
|
||||
|
||||
/**
|
||||
* Scheme used for extension pages
|
||||
*/
|
||||
@ -88,6 +85,11 @@ export namespace Schemas {
|
||||
* files with our custom protocol handler (desktop only).
|
||||
*/
|
||||
export const vscodeFileResource = 'vscode-file';
|
||||
|
||||
/**
|
||||
* Scheme used for temporary resources
|
||||
*/
|
||||
export const tmp = 'tmp';
|
||||
}
|
||||
|
||||
class RemoteAuthoritiesImpl {
|
||||
@ -162,7 +164,7 @@ class FileAccessImpl {
|
||||
}
|
||||
|
||||
// Only convert the URI if we are in a native context and it has `file:` scheme
|
||||
// and we have explicitly enabled the conversion (sandbox, or ENABLE_VSCODE_BROWSER_CODE_LOADING)
|
||||
// and we have explicitly enabled the conversion (sandbox, or VSCODE_BROWSER_CODE_LOADING)
|
||||
if (platform.isNative && (__forceCodeFileUri || platform.isPreferringBrowserCodeLoad) && uri.scheme === Schemas.file) {
|
||||
return uri.with({
|
||||
scheme: Schemas.vscodeFileResource,
|
||||
|
@ -24,7 +24,7 @@ interface NLSConfig {
|
||||
}
|
||||
|
||||
export interface IProcessEnvironment {
|
||||
[key: string]: string;
|
||||
[key: string]: string | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -53,12 +53,12 @@ declare const self: unknown;
|
||||
export const globals: any = (typeof self === 'object' ? self : typeof global === 'object' ? global : {});
|
||||
|
||||
let nodeProcess: INodeProcess | undefined = undefined;
|
||||
if (typeof process !== 'undefined') {
|
||||
// Native environment (non-sandboxed)
|
||||
nodeProcess = process;
|
||||
} else if (typeof globals.vscode !== 'undefined') {
|
||||
if (typeof globals.vscode !== 'undefined') {
|
||||
// Native environment (sandboxed)
|
||||
nodeProcess = globals.vscode.process;
|
||||
} else if (typeof process !== 'undefined') {
|
||||
// Native environment (non-sandboxed)
|
||||
nodeProcess = process;
|
||||
}
|
||||
|
||||
const isElectronRenderer = typeof nodeProcess?.versions?.electron === 'string' && nodeProcess.type === 'renderer';
|
||||
@ -71,7 +71,7 @@ export const browserCodeLoadingCacheStrategy: 'none' | 'code' | 'bypassHeatCheck
|
||||
}
|
||||
|
||||
// Otherwise, only enabled conditionally
|
||||
const env = nodeProcess?.env['ENABLE_VSCODE_BROWSER_CODE_LOADING'];
|
||||
const env = nodeProcess?.env['VSCODE_BROWSER_CODE_LOADING'];
|
||||
if (typeof env === 'string') {
|
||||
if (env === 'none' || env === 'code' || env === 'bypassHeatCheck' || env === 'bypassHeatCheckAndEagerCompile') {
|
||||
return env;
|
||||
|
@ -6,20 +6,10 @@
|
||||
import { isWindows, isMacintosh, setImmediate, globals, INodeProcess } from 'vs/base/common/platform';
|
||||
|
||||
let safeProcess: INodeProcess & { nextTick: (callback: (...args: any[]) => void) => void; };
|
||||
|
||||
// Native node.js environment
|
||||
declare const process: INodeProcess;
|
||||
if (typeof process !== 'undefined') {
|
||||
safeProcess = {
|
||||
get platform() { return process.platform; },
|
||||
get env() { return process.env; },
|
||||
cwd() { return process.env['VSCODE_CWD'] || process.cwd(); },
|
||||
nextTick(callback: (...args: any[]) => void): void { return process.nextTick!(callback); }
|
||||
};
|
||||
}
|
||||
|
||||
// Native sandbox environment
|
||||
else if (typeof globals.vscode !== 'undefined') {
|
||||
if (typeof globals.vscode !== 'undefined') {
|
||||
const sandboxProcess: INodeProcess = globals.vscode.process;
|
||||
safeProcess = {
|
||||
get platform() { return sandboxProcess.platform; },
|
||||
@ -29,6 +19,16 @@ else if (typeof globals.vscode !== 'undefined') {
|
||||
};
|
||||
}
|
||||
|
||||
// Native node.js environment
|
||||
else if (typeof process !== 'undefined') {
|
||||
safeProcess = {
|
||||
get platform() { return process.platform; },
|
||||
get env() { return process.env; },
|
||||
cwd() { return process.env['VSCODE_CWD'] || process.cwd(); },
|
||||
nextTick(callback: (...args: any[]) => void): void { return process.nextTick!(callback); }
|
||||
};
|
||||
}
|
||||
|
||||
// Web environment
|
||||
else {
|
||||
safeProcess = {
|
||||
|
168
lib/vscode/src/vs/base/common/product.ts
Normal file
168
lib/vscode/src/vs/base/common/product.ts
Normal file
@ -0,0 +1,168 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IStringDictionary } from 'vs/base/common/collections';
|
||||
|
||||
export interface IBuiltInExtension {
|
||||
readonly name: string;
|
||||
readonly version: string;
|
||||
readonly repo: string;
|
||||
readonly metadata: any;
|
||||
}
|
||||
|
||||
export type ConfigurationSyncStore = {
|
||||
url: string,
|
||||
insidersUrl: string,
|
||||
stableUrl: string,
|
||||
canSwitch: boolean,
|
||||
authenticationProviders: IStringDictionary<{ scopes: string[] }>
|
||||
};
|
||||
|
||||
export type ExtensionUntrustedWorkspaceSupport = {
|
||||
readonly default?: boolean | 'limited',
|
||||
readonly override?: boolean | 'limited'
|
||||
};
|
||||
|
||||
export interface IProductConfiguration {
|
||||
readonly version: string;
|
||||
readonly date?: string;
|
||||
readonly quality?: string;
|
||||
readonly commit?: string;
|
||||
|
||||
readonly nameShort: string;
|
||||
readonly nameLong: string;
|
||||
|
||||
readonly win32AppUserModelId?: string;
|
||||
readonly win32MutexName?: string;
|
||||
readonly applicationName: string;
|
||||
|
||||
readonly urlProtocol: string;
|
||||
readonly dataFolderName: string; // location for extensions (e.g. ~/.vscode-insiders)
|
||||
|
||||
readonly builtInExtensions?: IBuiltInExtension[];
|
||||
|
||||
readonly downloadUrl?: string;
|
||||
readonly updateUrl?: string;
|
||||
readonly webEndpointUrl?: string;
|
||||
readonly target?: string;
|
||||
|
||||
readonly settingsSearchBuildId?: number;
|
||||
readonly settingsSearchUrl?: string;
|
||||
|
||||
readonly tasConfig?: {
|
||||
endpoint: string;
|
||||
telemetryEventName: string;
|
||||
featuresTelemetryPropertyName: string;
|
||||
assignmentContextTelemetryPropertyName: string;
|
||||
};
|
||||
|
||||
readonly experimentsUrl?: string;
|
||||
|
||||
readonly extensionsGallery?: {
|
||||
readonly serviceUrl: string;
|
||||
readonly itemUrl: string;
|
||||
readonly controlUrl: string;
|
||||
readonly recommendationsUrl: string;
|
||||
};
|
||||
|
||||
readonly extensionTips?: { [id: string]: string; };
|
||||
readonly extensionImportantTips?: IStringDictionary<ImportantExtensionTip>;
|
||||
readonly configBasedExtensionTips?: { [id: string]: IConfigBasedExtensionTip; };
|
||||
readonly exeBasedExtensionTips?: { [id: string]: IExeBasedExtensionTip; };
|
||||
readonly remoteExtensionTips?: { [remoteName: string]: IRemoteExtensionTip; };
|
||||
readonly extensionKeywords?: { [extension: string]: readonly string[]; };
|
||||
readonly keymapExtensionTips?: readonly string[];
|
||||
readonly trustedExtensionUrlPublicKeys?: { [id: string]: string[]; };
|
||||
|
||||
readonly crashReporter?: {
|
||||
readonly companyName: string;
|
||||
readonly productName: string;
|
||||
};
|
||||
|
||||
readonly enableTelemetry?: boolean;
|
||||
readonly aiConfig?: {
|
||||
readonly asimovKey: string;
|
||||
};
|
||||
|
||||
readonly sendASmile?: {
|
||||
readonly reportIssueUrl: string,
|
||||
readonly requestFeatureUrl: string
|
||||
};
|
||||
|
||||
readonly documentationUrl?: string;
|
||||
readonly releaseNotesUrl?: string;
|
||||
readonly keyboardShortcutsUrlMac?: string;
|
||||
readonly keyboardShortcutsUrlLinux?: string;
|
||||
readonly keyboardShortcutsUrlWin?: string;
|
||||
readonly introductoryVideosUrl?: string;
|
||||
readonly tipsAndTricksUrl?: string;
|
||||
readonly newsletterSignupUrl?: string;
|
||||
readonly twitterUrl?: string;
|
||||
readonly requestFeatureUrl?: string;
|
||||
readonly reportIssueUrl?: string;
|
||||
readonly reportMarketplaceIssueUrl?: string;
|
||||
readonly licenseUrl?: string;
|
||||
readonly privacyStatementUrl?: string;
|
||||
readonly telemetryOptOutUrl?: string;
|
||||
|
||||
readonly npsSurveyUrl?: string;
|
||||
readonly cesSurveyUrl?: string;
|
||||
readonly surveys?: readonly ISurveyData[];
|
||||
|
||||
readonly checksums?: { [path: string]: string; };
|
||||
readonly checksumFailMoreInfoUrl?: string;
|
||||
|
||||
readonly appCenter?: IAppCenterConfiguration;
|
||||
|
||||
readonly portable?: string;
|
||||
|
||||
readonly extensionKind?: { readonly [extensionId: string]: ('ui' | 'workspace' | 'web')[]; };
|
||||
readonly extensionSyncedKeys?: { readonly [extensionId: string]: string[]; };
|
||||
readonly extensionAllowedProposedApi?: readonly string[];
|
||||
readonly extensionUntrustedWorkspaceSupport?: { readonly [extensionId: string]: ExtensionUntrustedWorkspaceSupport };
|
||||
readonly extensionVirtualWorkspacesSupport?: { readonly [extensionId: string]: { default?: boolean, override?: boolean } };
|
||||
|
||||
readonly msftInternalDomains?: string[];
|
||||
readonly linkProtectionTrustedDomains?: readonly string[];
|
||||
|
||||
readonly 'configurationSync.store'?: ConfigurationSyncStore;
|
||||
|
||||
readonly darwinUniversalAssetId?: string;
|
||||
}
|
||||
|
||||
export type ImportantExtensionTip = { name: string; languages?: string[]; pattern?: string; isExtensionPack?: boolean };
|
||||
|
||||
export interface IAppCenterConfiguration {
|
||||
readonly 'win32-ia32': string;
|
||||
readonly 'win32-x64': string;
|
||||
readonly 'linux-x64': string;
|
||||
readonly 'darwin': string;
|
||||
}
|
||||
|
||||
export interface IConfigBasedExtensionTip {
|
||||
configPath: string;
|
||||
configName: string;
|
||||
recommendations: IStringDictionary<{ name: string, remotes?: string[], important?: boolean, isExtensionPack?: boolean }>;
|
||||
}
|
||||
|
||||
export interface IExeBasedExtensionTip {
|
||||
friendlyName: string;
|
||||
windowsPath?: string;
|
||||
important?: boolean;
|
||||
recommendations: IStringDictionary<{ name: string, important?: boolean, isExtensionPack?: boolean }>;
|
||||
}
|
||||
|
||||
export interface IRemoteExtensionTip {
|
||||
friendlyName: string;
|
||||
extensionId: string;
|
||||
}
|
||||
|
||||
export interface ISurveyData {
|
||||
surveyId: string;
|
||||
surveyUrl: string;
|
||||
languageId: string;
|
||||
editCount: number;
|
||||
userProbability: number;
|
||||
}
|
@ -9,6 +9,7 @@ import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
* keyboardEvent.code
|
||||
*/
|
||||
export const enum ScanCode {
|
||||
DependsOnKbLayout = -1,
|
||||
None,
|
||||
|
||||
Hyper,
|
||||
@ -468,11 +469,11 @@ export class ScanCodeBinding {
|
||||
|
||||
(function () {
|
||||
for (let i = 0; i <= ScanCode.MAX_VALUE; i++) {
|
||||
IMMUTABLE_CODE_TO_KEY_CODE[i] = -1;
|
||||
IMMUTABLE_CODE_TO_KEY_CODE[i] = KeyCode.DependsOnKbLayout;
|
||||
}
|
||||
|
||||
for (let i = 0; i <= KeyCode.MAX_VALUE; i++) {
|
||||
IMMUTABLE_KEY_CODE_TO_CODE[i] = -1;
|
||||
IMMUTABLE_KEY_CODE_TO_CODE[i] = ScanCode.DependsOnKbLayout;
|
||||
}
|
||||
|
||||
function define(code: ScanCode, keyCode: KeyCode): void {
|
||||
|
@ -223,7 +223,7 @@ export class Scrollable extends Disposable {
|
||||
this._smoothScrolling = null;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
public override dispose(): void {
|
||||
if (this._smoothScrolling) {
|
||||
this._smoothScrolling.dispose();
|
||||
this._smoothScrolling = null;
|
||||
|
@ -18,6 +18,7 @@ namespace Severity {
|
||||
const _warning = 'warning';
|
||||
const _warn = 'warn';
|
||||
const _info = 'info';
|
||||
const _ignore = 'ignore';
|
||||
|
||||
/**
|
||||
* Parses 'error', 'warning', 'warn', 'info' in call casings
|
||||
@ -41,6 +42,15 @@ namespace Severity {
|
||||
}
|
||||
return Severity.Ignore;
|
||||
}
|
||||
|
||||
export function toString(severity: Severity): string {
|
||||
switch (severity) {
|
||||
case Severity.Error: return _error;
|
||||
case Severity.Warning: return _warning;
|
||||
case Severity.Info: return _info;
|
||||
default: return _ignore;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Severity;
|
||||
|
@ -142,15 +142,21 @@ export interface ReadableBufferedStream<T> {
|
||||
}
|
||||
|
||||
export function isReadableStream<T>(obj: unknown): obj is ReadableStream<T> {
|
||||
const candidate = obj as ReadableStream<T>;
|
||||
const candidate = obj as ReadableStream<T> | undefined;
|
||||
if (!candidate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return candidate && [candidate.on, candidate.pause, candidate.resume, candidate.destroy].every(fn => typeof fn === 'function');
|
||||
return [candidate.on, candidate.pause, candidate.resume, candidate.destroy].every(fn => typeof fn === 'function');
|
||||
}
|
||||
|
||||
export function isReadableBufferedStream<T>(obj: unknown): obj is ReadableBufferedStream<T> {
|
||||
const candidate = obj as ReadableBufferedStream<T>;
|
||||
const candidate = obj as ReadableBufferedStream<T> | undefined;
|
||||
if (!candidate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return candidate && isReadableStream(candidate.stream) && Array.isArray(candidate.buffer) && typeof candidate.ended === 'boolean';
|
||||
return isReadableStream(candidate.stream) && Array.isArray(candidate.buffer) && typeof candidate.ended === 'boolean';
|
||||
}
|
||||
|
||||
export interface IReducer<T> {
|
||||
@ -625,6 +631,16 @@ export function toStream<T>(t: T, reducer: IReducer<T>): ReadableStream<T> {
|
||||
return stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to create an empty stream
|
||||
*/
|
||||
export function emptyStream(): ReadableStream<never> {
|
||||
const stream = newWriteableStream<never>(() => { throw new Error('not supported'); });
|
||||
stream.end();
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to convert a T into a Readable<T>.
|
||||
*/
|
||||
@ -658,3 +674,71 @@ export function transform<Original, Transformed>(stream: ReadableStreamEvents<Or
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to take an existing readable that will
|
||||
* have a prefix injected to the beginning.
|
||||
*/
|
||||
export function prefixedReadable<T>(prefix: T, readable: Readable<T>, reducer: IReducer<T>): Readable<T> {
|
||||
let prefixHandled = false;
|
||||
|
||||
return {
|
||||
read: () => {
|
||||
const chunk = readable.read();
|
||||
|
||||
// Handle prefix only once
|
||||
if (!prefixHandled) {
|
||||
prefixHandled = true;
|
||||
|
||||
// If we have also a read-result, make
|
||||
// sure to reduce it to a single result
|
||||
if (chunk !== null) {
|
||||
return reducer([prefix, chunk]);
|
||||
}
|
||||
|
||||
// Otherwise, just return prefix directly
|
||||
return prefix;
|
||||
}
|
||||
|
||||
return chunk;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to take an existing stream that will
|
||||
* have a prefix injected to the beginning.
|
||||
*/
|
||||
export function prefixedStream<T>(prefix: T, stream: ReadableStream<T>, reducer: IReducer<T>): ReadableStream<T> {
|
||||
let prefixHandled = false;
|
||||
|
||||
const target = newWriteableStream<T>(reducer);
|
||||
|
||||
listenStream(stream, {
|
||||
onData: data => {
|
||||
|
||||
// Handle prefix only once
|
||||
if (!prefixHandled) {
|
||||
prefixHandled = true;
|
||||
|
||||
return target.write(reducer([prefix, data]));
|
||||
}
|
||||
|
||||
return target.write(data);
|
||||
},
|
||||
onError: error => target.error(error),
|
||||
onEnd: () => {
|
||||
|
||||
// Handle prefix only once
|
||||
if (!prefixHandled) {
|
||||
prefixHandled = true;
|
||||
|
||||
target.write(prefix);
|
||||
}
|
||||
|
||||
target.end();
|
||||
}
|
||||
});
|
||||
|
||||
return target;
|
||||
}
|
||||
|
@ -240,19 +240,19 @@ export function withUndefinedAsNull<T>(x: T | undefined): T | null {
|
||||
return typeof x === 'undefined' ? null : x;
|
||||
}
|
||||
|
||||
type AddFirstParameterToFunction<T, TargetFunctionsReturnType, FirstParameter> = T extends (...args: any[]) => TargetFunctionsReturnType ?
|
||||
// Function: add param to function
|
||||
(firstArg: FirstParameter, ...args: Parameters<T>) => ReturnType<T> :
|
||||
|
||||
// Else: just leave as is
|
||||
T;
|
||||
|
||||
/**
|
||||
* Allows to add a first parameter to functions of a type.
|
||||
*/
|
||||
export type AddFirstParameterToFunctions<Target, TargetFunctionsReturnType, FirstParameter> = {
|
||||
|
||||
// For every property
|
||||
[K in keyof Target]:
|
||||
|
||||
// Function: add param to function
|
||||
Target[K] extends (...args: any[]) => TargetFunctionsReturnType ? (firstArg: FirstParameter, ...args: Parameters<Target[K]>) => ReturnType<Target[K]> :
|
||||
|
||||
// Else: just leave as is
|
||||
Target[K]
|
||||
// For every property
|
||||
[K in keyof Target]: AddFirstParameterToFunction<Target[K], TargetFunctionsReturnType, FirstParameter>;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -286,3 +286,7 @@ export function NotImplementedProxy<T>(name: string): { new(): T } {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function assertNever(value: never) {
|
||||
throw new Error('Unreachable');
|
||||
}
|
||||
|
@ -418,14 +418,14 @@ class Uri extends URI {
|
||||
_formatted: string | null = null;
|
||||
_fsPath: string | null = null;
|
||||
|
||||
get fsPath(): string {
|
||||
override get fsPath(): string {
|
||||
if (!this._fsPath) {
|
||||
this._fsPath = uriToFsPath(this, false);
|
||||
}
|
||||
return this._fsPath;
|
||||
}
|
||||
|
||||
toString(skipEncoding: boolean = false): string {
|
||||
override toString(skipEncoding: boolean = false): string {
|
||||
if (!skipEncoding) {
|
||||
if (!this._formatted) {
|
||||
this._formatted = _asFormatted(this, false);
|
||||
@ -437,7 +437,7 @@ class Uri extends URI {
|
||||
}
|
||||
}
|
||||
|
||||
toJSON(): UriComponents {
|
||||
override toJSON(): UriComponents {
|
||||
const res = <UriState>{
|
||||
$mid: 1
|
||||
};
|
||||
|
@ -18,7 +18,7 @@ export class LineDecoder {
|
||||
private stringDecoder: sd.StringDecoder;
|
||||
private remaining: string | null;
|
||||
|
||||
constructor(encoding: string = 'utf8') {
|
||||
constructor(encoding: BufferEncoding = 'utf8') {
|
||||
this.stringDecoder = new sd.StringDecoder(encoding);
|
||||
this.remaining = null;
|
||||
}
|
||||
|
@ -56,8 +56,9 @@ export const virtualMachineHint: { value(): number } = new class {
|
||||
|
||||
const interfaces = networkInterfaces();
|
||||
for (let name in interfaces) {
|
||||
if (Object.prototype.hasOwnProperty.call(interfaces, name)) {
|
||||
for (const { mac, internal } of interfaces[name]) {
|
||||
const networkInterface = interfaces[name];
|
||||
if (networkInterface) {
|
||||
for (const { mac, internal } of networkInterface) {
|
||||
if (!internal) {
|
||||
interfaceCount += 1;
|
||||
if (this._isVirtualMachineMacAdress(mac.toUpperCase())) {
|
||||
|
@ -34,10 +34,13 @@ function doGetMac(): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const ifaces = networkInterfaces();
|
||||
for (const [, infos] of Object.entries(ifaces)) {
|
||||
for (const info of infos) {
|
||||
if (validateMacAddress(info.mac)) {
|
||||
return resolve(info.mac);
|
||||
for (let name in ifaces) {
|
||||
const networkInterface = ifaces[name];
|
||||
if (networkInterface) {
|
||||
for (const { mac } of networkInterface) {
|
||||
if (validateMacAddress(mac)) {
|
||||
return resolve(mac);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -379,7 +379,7 @@ export class LineProcess extends AbstractProcess<LineData> {
|
||||
this.stderrLineDecoder = stderrLineDecoder;
|
||||
}
|
||||
|
||||
protected handleClose(data: any, cc: ValueCallback<SuccessData>, pp: ProgressCallback<LineData>, ee: ErrorCallback): void {
|
||||
protected override handleClose(data: any, cc: ValueCallback<SuccessData>, pp: ProgressCallback<LineData>, ee: ErrorCallback): void {
|
||||
const stdoutLine = this.stdoutLineDecoder ? this.stdoutLineDecoder.end() : null;
|
||||
if (stdoutLine) {
|
||||
pp({ line: stdoutLine, source: Source.stdout });
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as os from 'os';
|
||||
import { release, userInfo } from 'os';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { getFirstAvailablePowerShellInstallation } from 'vs/base/node/powershell';
|
||||
import * as processes from 'vs/base/node/processes';
|
||||
@ -11,10 +11,10 @@ import * as processes from 'vs/base/node/processes';
|
||||
/**
|
||||
* Gets the detected default shell for the _system_, not to be confused with VS Code's _default_
|
||||
* shell that the terminal uses by default.
|
||||
* @param p The platform to detect the shell of.
|
||||
* @param os The platform to detect the shell of.
|
||||
*/
|
||||
export async function getSystemShell(p: platform.Platform, env: platform.IProcessEnvironment): Promise<string> {
|
||||
if (p === platform.Platform.Windows) {
|
||||
export async function getSystemShell(os: platform.OperatingSystem, env: platform.IProcessEnvironment): Promise<string> {
|
||||
if (os === platform.OperatingSystem.Windows) {
|
||||
if (platform.isWindows) {
|
||||
return getSystemShellWindows();
|
||||
}
|
||||
@ -22,11 +22,11 @@ export async function getSystemShell(p: platform.Platform, env: platform.IProces
|
||||
return processes.getWindowsShell(env);
|
||||
}
|
||||
|
||||
return getSystemShellUnixLike(p, env);
|
||||
return getSystemShellUnixLike(os, env);
|
||||
}
|
||||
|
||||
export function getSystemShellSync(p: platform.Platform, env: platform.IProcessEnvironment): string {
|
||||
if (p === platform.Platform.Windows) {
|
||||
export function getSystemShellSync(os: platform.OperatingSystem, env: platform.IProcessEnvironment): string {
|
||||
if (os === platform.OperatingSystem.Windows) {
|
||||
if (platform.isWindows) {
|
||||
return getSystemShellWindowsSync(env);
|
||||
}
|
||||
@ -34,13 +34,13 @@ export function getSystemShellSync(p: platform.Platform, env: platform.IProcessE
|
||||
return processes.getWindowsShell(env);
|
||||
}
|
||||
|
||||
return getSystemShellUnixLike(p, env);
|
||||
return getSystemShellUnixLike(os, env);
|
||||
}
|
||||
|
||||
let _TERMINAL_DEFAULT_SHELL_UNIX_LIKE: string | null = null;
|
||||
function getSystemShellUnixLike(p: platform.Platform, env: platform.IProcessEnvironment): string {
|
||||
function getSystemShellUnixLike(os: platform.OperatingSystem, env: platform.IProcessEnvironment): string {
|
||||
// Only use $SHELL for the current OS
|
||||
if (platform.isLinux && p === platform.Platform.Mac || platform.isMacintosh && p === platform.Platform.Linux) {
|
||||
if (platform.isLinux && os === platform.OperatingSystem.Macintosh || platform.isMacintosh && os === platform.OperatingSystem.Linux) {
|
||||
return '/bin/bash';
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ function getSystemShellUnixLike(p: platform.Platform, env: platform.IProcessEnvi
|
||||
try {
|
||||
// It's possible for $SHELL to be unset, this API reads /etc/passwd. See https://github.com/github/codespaces/issues/1639
|
||||
// Node docs: "Throws a SystemError if a user has no username or homedir."
|
||||
unixLikeTerminal = os.userInfo().shell;
|
||||
unixLikeTerminal = userInfo().shell;
|
||||
} catch (err) { }
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ function getSystemShellWindowsSync(env: platform.IProcessEnvironment): string {
|
||||
return _TERMINAL_DEFAULT_SHELL_WINDOWS;
|
||||
}
|
||||
|
||||
const isAtLeastWindows10 = platform.isWindows && parseFloat(os.release()) >= 10;
|
||||
const isAtLeastWindows10 = platform.isWindows && parseFloat(release()) >= 10;
|
||||
const is32ProcessOn64Windows = env.hasOwnProperty('PROCESSOR_ARCHITEW6432');
|
||||
const powerShellPath = `${env['windir']}\\${is32ProcessOn64Windows ? 'Sysnative' : 'System32'}\\WindowsPowerShell\\v1.0\\powershell.exe`;
|
||||
return isAtLeastWindows10 ? powerShellPath : processes.getWindowsShell(env);
|
||||
|
@ -72,7 +72,7 @@ export class Client extends IPCClient implements IDisposable {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
override dispose(): void {
|
||||
this.protocol.disconnect();
|
||||
}
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ class ProtocolReader extends Disposable {
|
||||
return this._incomingData.read(this._incomingData.byteLength);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
public override dispose(): void {
|
||||
this._isDisposed = true;
|
||||
super.dispose();
|
||||
}
|
||||
@ -412,7 +412,7 @@ export class Client<TContext = string> extends IPCClient<TContext> {
|
||||
super(protocol, id, ipcLogger);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
override dispose(): void {
|
||||
super.dispose();
|
||||
const socket = this.protocol.getSocket();
|
||||
this.protocol.sendDisconnect();
|
||||
|
@ -32,7 +32,7 @@ export class Client extends IPCClient implements IDisposable {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
override dispose(): void {
|
||||
this.protocol.disconnect();
|
||||
}
|
||||
}
|
||||
|
@ -266,7 +266,7 @@ export class WebSocketNodeSocket extends Disposable implements ISocket {
|
||||
this._register(this.socket.onClose(() => this._onClose.fire()));
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
public override dispose(): void {
|
||||
if (this._zlibDeflateFlushWaitingCount > 0) {
|
||||
// Wait for any outstanding writes to finish before disposing
|
||||
this._register(this._onDidZlibFlush.event(() => {
|
||||
@ -581,7 +581,7 @@ export class Server extends IPCServer {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
override dispose(): void {
|
||||
super.dispose();
|
||||
if (this.server) {
|
||||
this.server.close();
|
||||
|
@ -66,7 +66,7 @@ class TestIPCClient extends IPCClient<string> {
|
||||
super(protocol, id);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
override dispose(): void {
|
||||
this._onDidDisconnect.fire();
|
||||
super.dispose();
|
||||
}
|
||||
@ -253,7 +253,7 @@ suite('Base IPC', function () {
|
||||
|
||||
test('call success', async function () {
|
||||
const r = await ipcService.marco();
|
||||
return assert.equal(r, 'polo');
|
||||
return assert.strictEqual(r, 'polo');
|
||||
});
|
||||
|
||||
test('call error', async function () {
|
||||
@ -261,7 +261,7 @@ suite('Base IPC', function () {
|
||||
await ipcService.error('nice error');
|
||||
return assert.fail('should not reach here');
|
||||
} catch (err) {
|
||||
return assert.equal(err.message, 'nice error');
|
||||
return assert.strictEqual(err.message, 'nice error');
|
||||
}
|
||||
});
|
||||
|
||||
@ -304,20 +304,20 @@ suite('Base IPC', function () {
|
||||
ipcService.onPong(msg => messages.push(msg));
|
||||
await timeout(0);
|
||||
|
||||
assert.deepEqual(messages, []);
|
||||
assert.deepStrictEqual(messages, []);
|
||||
service.ping('hello');
|
||||
await timeout(0);
|
||||
|
||||
assert.deepEqual(messages, ['hello']);
|
||||
assert.deepStrictEqual(messages, ['hello']);
|
||||
service.ping('world');
|
||||
await timeout(0);
|
||||
|
||||
assert.deepEqual(messages, ['hello', 'world']);
|
||||
assert.deepStrictEqual(messages, ['hello', 'world']);
|
||||
});
|
||||
|
||||
test('buffers in arrays', async function () {
|
||||
const r = await ipcService.buffersLength([VSBuffer.alloc(2), VSBuffer.alloc(3)]);
|
||||
return assert.equal(r, 5);
|
||||
return assert.strictEqual(r, 5);
|
||||
});
|
||||
});
|
||||
|
||||
@ -345,7 +345,7 @@ suite('Base IPC', function () {
|
||||
|
||||
test('call success', async function () {
|
||||
const r = await ipcService.marco();
|
||||
return assert.equal(r, 'polo');
|
||||
return assert.strictEqual(r, 'polo');
|
||||
});
|
||||
|
||||
test('call error', async function () {
|
||||
@ -353,7 +353,7 @@ suite('Base IPC', function () {
|
||||
await ipcService.error('nice error');
|
||||
return assert.fail('should not reach here');
|
||||
} catch (err) {
|
||||
return assert.equal(err.message, 'nice error');
|
||||
return assert.strictEqual(err.message, 'nice error');
|
||||
}
|
||||
});
|
||||
|
||||
@ -363,15 +363,15 @@ suite('Base IPC', function () {
|
||||
ipcService.onPong(msg => messages.push(msg));
|
||||
await timeout(0);
|
||||
|
||||
assert.deepEqual(messages, []);
|
||||
assert.deepStrictEqual(messages, []);
|
||||
service.ping('hello');
|
||||
await timeout(0);
|
||||
|
||||
assert.deepEqual(messages, ['hello']);
|
||||
assert.deepStrictEqual(messages, ['hello']);
|
||||
service.ping('world');
|
||||
await timeout(0);
|
||||
|
||||
assert.deepEqual(messages, ['hello', 'world']);
|
||||
assert.deepStrictEqual(messages, ['hello', 'world']);
|
||||
});
|
||||
|
||||
test('marshalling uri', async function () {
|
||||
@ -383,7 +383,7 @@ suite('Base IPC', function () {
|
||||
|
||||
test('buffers in arrays', async function () {
|
||||
const r = await ipcService.buffersLength([VSBuffer.alloc(2), VSBuffer.alloc(3)]);
|
||||
return assert.equal(r, 5);
|
||||
return assert.strictEqual(r, 5);
|
||||
});
|
||||
});
|
||||
|
||||
@ -411,7 +411,7 @@ suite('Base IPC', function () {
|
||||
|
||||
test('call extra context', async function () {
|
||||
const r = await ipcService.context();
|
||||
return assert.equal(r, 'Super Context');
|
||||
return assert.strictEqual(r, 'Super Context');
|
||||
});
|
||||
});
|
||||
|
||||
@ -461,7 +461,7 @@ suite('Base IPC', function () {
|
||||
clientService1.ping('hello 1');
|
||||
|
||||
await timeout(1);
|
||||
assert.deepEqual(pings, ['hello 1']);
|
||||
assert.deepStrictEqual(pings, ['hello 1']);
|
||||
|
||||
const client2 = server.createConnection('client2');
|
||||
const clientService2 = new TestService();
|
||||
@ -472,19 +472,19 @@ suite('Base IPC', function () {
|
||||
clientService2.ping('hello 2');
|
||||
|
||||
await timeout(1);
|
||||
assert.deepEqual(pings, ['hello 1', 'hello 2']);
|
||||
assert.deepStrictEqual(pings, ['hello 1', 'hello 2']);
|
||||
|
||||
client1.dispose();
|
||||
clientService1.ping('hello 1');
|
||||
|
||||
await timeout(1);
|
||||
assert.deepEqual(pings, ['hello 1', 'hello 2']);
|
||||
assert.deepStrictEqual(pings, ['hello 1', 'hello 2']);
|
||||
|
||||
await timeout(1);
|
||||
clientService2.ping('hello again 2');
|
||||
|
||||
await timeout(1);
|
||||
assert.deepEqual(pings, ['hello 1', 'hello 2', 'hello again 2']);
|
||||
assert.deepStrictEqual(pings, ['hello 1', 'hello 2', 'hello again 2']);
|
||||
|
||||
client2.dispose();
|
||||
server.dispose();
|
||||
|
@ -22,8 +22,8 @@ suite('IPC, Child Process', () => {
|
||||
const service = new TestServiceClient(channel);
|
||||
|
||||
const result = service.pong('ping').then(r => {
|
||||
assert.equal(r.incoming, 'ping');
|
||||
assert.equal(r.outgoing, 'pong');
|
||||
assert.strictEqual(r.incoming, 'ping');
|
||||
assert.strictEqual(r.outgoing, 'pong');
|
||||
});
|
||||
|
||||
return result.finally(() => client.dispose());
|
||||
@ -37,7 +37,7 @@ suite('IPC, Child Process', () => {
|
||||
const event = new Promise((c, e) => {
|
||||
service.onMarco(({ answer }) => {
|
||||
try {
|
||||
assert.equal(answer, 'polo');
|
||||
assert.strictEqual(answer, 'polo');
|
||||
c(undefined);
|
||||
} catch (err) {
|
||||
e(err);
|
||||
@ -60,17 +60,17 @@ suite('IPC, Child Process', () => {
|
||||
const disposable = service.onMarco(() => count++);
|
||||
|
||||
const result = service.marco().then(async answer => {
|
||||
assert.equal(answer, 'polo');
|
||||
assert.equal(count, 1);
|
||||
assert.strictEqual(answer, 'polo');
|
||||
assert.strictEqual(count, 1);
|
||||
|
||||
const answer_1 = await service.marco();
|
||||
assert.equal(answer_1, 'polo');
|
||||
assert.equal(count, 2);
|
||||
assert.strictEqual(answer_1, 'polo');
|
||||
assert.strictEqual(count, 2);
|
||||
disposable.dispose();
|
||||
|
||||
const answer_2 = await service.marco();
|
||||
assert.equal(answer_2, 'polo');
|
||||
assert.equal(count, 2);
|
||||
assert.strictEqual(answer_2, 'polo');
|
||||
assert.strictEqual(count, 2);
|
||||
});
|
||||
|
||||
return result.finally(() => client.dispose());
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
.quick-input-titlebar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.quick-input-left-action-bar {
|
||||
@ -22,10 +23,6 @@
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.quick-input-left-action-bar.monaco-action-bar .actions-container {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.quick-input-title {
|
||||
padding: 3px 0px;
|
||||
text-align: center;
|
||||
@ -37,12 +34,14 @@
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.quick-input-right-action-bar > .actions-container {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.quick-input-titlebar .monaco-action-bar .action-label.codicon {
|
||||
margin: 0;
|
||||
width: 19px;
|
||||
height: 100%;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.quick-input-description {
|
||||
@ -260,10 +259,8 @@
|
||||
}
|
||||
|
||||
.quick-input-list .quick-input-list-entry-action-bar .action-label.codicon {
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
padding: 0 2px;
|
||||
vertical-align: middle;
|
||||
margin-right: 4px;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.quick-input-list .quick-input-list-entry-action-bar {
|
||||
@ -274,10 +271,6 @@
|
||||
margin-right: 4px; /* separate from scrollbar */
|
||||
}
|
||||
|
||||
.quick-input-list .quick-input-list-entry-action-bar .action-label.codicon {
|
||||
margin-right: 4px; /* separate actions */
|
||||
}
|
||||
|
||||
.quick-input-list .quick-input-list-entry .quick-input-list-entry-action-bar .action-label.always-visible,
|
||||
.quick-input-list .quick-input-list-entry:hover .quick-input-list-entry-action-bar .action-label,
|
||||
.quick-input-list .monaco-list-row.focused .quick-input-list-entry-action-bar .action-label {
|
||||
|
@ -32,6 +32,7 @@ import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
|
||||
import { escape } from 'vs/base/common/strings';
|
||||
import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels';
|
||||
import { isString } from 'vs/base/common/types';
|
||||
import { IKeybindingLabelStyles } from 'vs/base/browser/ui/keybindingLabel/keybindingLabel';
|
||||
|
||||
export interface IQuickInputOptions {
|
||||
idPrefix: string;
|
||||
@ -57,6 +58,7 @@ export interface IQuickInputStyles {
|
||||
countBadge: ICountBadgetyles;
|
||||
button: IButtonStyles;
|
||||
progressBar: IProgressBarStyles;
|
||||
keybindingLabel: IKeybindingLabelStyles;
|
||||
list: IListStyles & { pickerGroupBorder?: Color; pickerGroupForeground?: Color; };
|
||||
}
|
||||
|
||||
@ -410,7 +412,7 @@ class QuickInput extends Disposable implements IQuickInput {
|
||||
|
||||
readonly onDispose = this.onDisposeEmitter.event;
|
||||
|
||||
dispose(): void {
|
||||
override dispose(): void {
|
||||
this.hide();
|
||||
this.onDisposeEmitter.fire();
|
||||
|
||||
@ -694,7 +696,7 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
|
||||
}
|
||||
}
|
||||
|
||||
show() {
|
||||
override show() {
|
||||
if (!this.visible) {
|
||||
this.visibleDisposables.add(
|
||||
this.ui.inputBox.onDidChange(value => {
|
||||
@ -884,20 +886,11 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
|
||||
});
|
||||
}
|
||||
|
||||
protected update() {
|
||||
protected override update() {
|
||||
if (!this.visible) {
|
||||
return;
|
||||
}
|
||||
let hideInput = false;
|
||||
let inputShownJustForScreenReader = false;
|
||||
if (!!this._hideInput && this._items.length > 0) {
|
||||
if (this.ui.isScreenReaderOptimized()) {
|
||||
// Always show input if screen reader attached https://github.com/microsoft/vscode/issues/94360
|
||||
inputShownJustForScreenReader = true;
|
||||
} else {
|
||||
hideInput = true;
|
||||
}
|
||||
}
|
||||
const hideInput = !!this._hideInput && this._items.length > 0;
|
||||
this.ui.container.classList.toggle('hidden-input', hideInput && !this.description);
|
||||
const visibilities: Visibilities = {
|
||||
title: !!this.title || !!this.step || !!this.buttons.length,
|
||||
@ -925,13 +918,9 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
|
||||
if (this.ui.inputBox.placeholder !== (this.placeholder || '')) {
|
||||
this.ui.inputBox.placeholder = (this.placeholder || '');
|
||||
}
|
||||
if (inputShownJustForScreenReader) {
|
||||
this.ui.inputBox.ariaLabel = '';
|
||||
} else {
|
||||
const ariaLabel = this.ariaLabel || this.placeholder || QuickPick.DEFAULT_ARIA_LABEL;
|
||||
if (this.ui.inputBox.ariaLabel !== ariaLabel) {
|
||||
this.ui.inputBox.ariaLabel = ariaLabel;
|
||||
}
|
||||
const ariaLabel = this.ariaLabel || this.placeholder || QuickPick.DEFAULT_ARIA_LABEL;
|
||||
if (this.ui.inputBox.ariaLabel !== ariaLabel) {
|
||||
this.ui.inputBox.ariaLabel = ariaLabel;
|
||||
}
|
||||
this.ui.list.matchOnDescription = this.matchOnDescription;
|
||||
this.ui.list.matchOnDetail = this.matchOnDetail;
|
||||
@ -1063,7 +1052,7 @@ class InputBox extends QuickInput implements IInputBox {
|
||||
|
||||
readonly onDidAccept = this.onDidAcceptEmitter.event;
|
||||
|
||||
show() {
|
||||
override show() {
|
||||
if (!this.visible) {
|
||||
this.visibleDisposables.add(
|
||||
this.ui.inputBox.onDidChange(value => {
|
||||
@ -1079,7 +1068,7 @@ class InputBox extends QuickInput implements IInputBox {
|
||||
super.show();
|
||||
}
|
||||
|
||||
protected update() {
|
||||
protected override update() {
|
||||
if (!this.visible) {
|
||||
return;
|
||||
}
|
||||
@ -1388,8 +1377,12 @@ export class QuickInputController extends Disposable {
|
||||
const index = input.items.indexOf(event.item);
|
||||
if (index !== -1) {
|
||||
const items = input.items.slice();
|
||||
items.splice(index, 1);
|
||||
const removed = items.splice(index, 1);
|
||||
const activeItems = input.activeItems.filter((ai) => ai !== removed[0]);
|
||||
input.items = items;
|
||||
if (activeItems) {
|
||||
input.activeItems = activeItems;
|
||||
}
|
||||
}
|
||||
}
|
||||
})),
|
||||
@ -1729,6 +1722,34 @@ export class QuickInputController extends Disposable {
|
||||
if (this.styles.list.pickerGroupForeground) {
|
||||
content.push(`.quick-input-list .quick-input-list-separator { color: ${this.styles.list.pickerGroupForeground}; }`);
|
||||
}
|
||||
|
||||
if (
|
||||
this.styles.keybindingLabel.keybindingLabelBackground ||
|
||||
this.styles.keybindingLabel.keybindingLabelBorder ||
|
||||
this.styles.keybindingLabel.keybindingLabelBottomBorder ||
|
||||
this.styles.keybindingLabel.keybindingLabelShadow ||
|
||||
this.styles.keybindingLabel.keybindingLabelForeground
|
||||
) {
|
||||
content.push('.quick-input-list .monaco-keybinding > .monaco-keybinding-key {');
|
||||
if (this.styles.keybindingLabel.keybindingLabelBackground) {
|
||||
content.push(`background-color: ${this.styles.keybindingLabel.keybindingLabelBackground};`);
|
||||
}
|
||||
if (this.styles.keybindingLabel.keybindingLabelBorder) {
|
||||
// Order matters here. `border-color` must come before `border-bottom-color`.
|
||||
content.push(`border-color: ${this.styles.keybindingLabel.keybindingLabelBorder};`);
|
||||
}
|
||||
if (this.styles.keybindingLabel.keybindingLabelBottomBorder) {
|
||||
content.push(`border-bottom-color: ${this.styles.keybindingLabel.keybindingLabelBottomBorder};`);
|
||||
}
|
||||
if (this.styles.keybindingLabel.keybindingLabelShadow) {
|
||||
content.push(`box-shadow: inset 0 -1px 0 ${this.styles.keybindingLabel.keybindingLabelShadow};`);
|
||||
}
|
||||
if (this.styles.keybindingLabel.keybindingLabelForeground) {
|
||||
content.push(`color: ${this.styles.keybindingLabel.keybindingLabelForeground};`);
|
||||
}
|
||||
content.push('}');
|
||||
}
|
||||
|
||||
const newStyles = content.join('\n');
|
||||
if (newStyles !== this.ui.styleSheet.textContent) {
|
||||
this.ui.styleSheet.textContent = newStyles;
|
||||
|
@ -27,6 +27,7 @@ import { IQuickInputOptions } from 'vs/base/parts/quickinput/browser/quickInput'
|
||||
import { IListOptions, List, IListStyles, IListAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget';
|
||||
import { KeybindingLabel } from 'vs/base/browser/ui/keybindingLabel/keybindingLabel';
|
||||
import { localize } from 'vs/nls';
|
||||
import { getCodiconAriaLabel } from 'vs/base/common/codicons';
|
||||
|
||||
const $ = dom.$;
|
||||
|
||||
@ -427,7 +428,7 @@ export class QuickInputList {
|
||||
const saneDescription = item.description && item.description.replace(/\r?\n/g, ' ');
|
||||
const saneDetail = item.detail && item.detail.replace(/\r?\n/g, ' ');
|
||||
const saneAriaLabel = item.ariaLabel || [saneLabel, saneDescription, saneDetail]
|
||||
.map(s => s && parseLabelWithIcons(s).text)
|
||||
.map(s => getCodiconAriaLabel(s))
|
||||
.filter(s => !!s)
|
||||
.join(', ');
|
||||
|
||||
@ -603,6 +604,7 @@ export class QuickInputList {
|
||||
|
||||
// Filter by value (since we support icons in labels, use $(..) aware fuzzy matching)
|
||||
else {
|
||||
let currentSeparator: IQuickPickSeparator | undefined;
|
||||
this.elements.forEach(element => {
|
||||
const labelHighlights = this.matchOnLabel ? withNullAsUndefined(matchesFuzzyIconAware(query, parseLabelWithIcons(element.saneLabel))) : undefined;
|
||||
const descriptionHighlights = this.matchOnDescription ? withNullAsUndefined(matchesFuzzyIconAware(query, parseLabelWithIcons(element.saneDescription || ''))) : undefined;
|
||||
@ -621,6 +623,16 @@ export class QuickInputList {
|
||||
element.hidden = !element.item.alwaysShow;
|
||||
}
|
||||
element.separator = undefined;
|
||||
|
||||
// we can show the separator unless the list gets sorted by match
|
||||
if (!this.sortByLabel) {
|
||||
const previous = element.index && this.inputElements[element.index - 1];
|
||||
currentSeparator = previous && previous.type === 'separator' ? previous : currentSeparator;
|
||||
if (currentSeparator && !element.hidden) {
|
||||
element.separator = currentSeparator;
|
||||
currentSeparator = undefined;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -363,7 +363,7 @@ export interface IQuickPickItemButtonContext<T extends IQuickPickItem> extends I
|
||||
export type QuickPickInput<T = IQuickPickItem> = T | IQuickPickSeparator;
|
||||
|
||||
|
||||
//region Fuzzy Scorer Support
|
||||
//#region Fuzzy Scorer Support
|
||||
|
||||
export type IQuickPickItemWithResource = IQuickPickItem & { resource?: URI };
|
||||
|
||||
|
52
lib/vscode/src/vs/base/parts/sandbox/common/sandboxTypes.ts
Normal file
52
lib/vscode/src/vs/base/parts/sandbox/common/sandboxTypes.ts
Normal file
@ -0,0 +1,52 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IProcessEnvironment } from 'vs/base/common/platform';
|
||||
import { IProductConfiguration } from 'vs/base/common/product';
|
||||
|
||||
|
||||
// #######################################################################
|
||||
// ### ###
|
||||
// ### Types we need in a common layer for reuse ###
|
||||
// ### ###
|
||||
// #######################################################################
|
||||
|
||||
|
||||
/**
|
||||
* The common properties required for any sandboxed
|
||||
* renderer to function.
|
||||
*/
|
||||
export interface ISandboxConfiguration {
|
||||
|
||||
/**
|
||||
* Identifier of the sandboxed renderer.
|
||||
*/
|
||||
windowId: number;
|
||||
|
||||
/**
|
||||
* Absolute installation path.
|
||||
*/
|
||||
appRoot: string;
|
||||
|
||||
/**
|
||||
* Per window process environment.
|
||||
*/
|
||||
userEnv: IProcessEnvironment;
|
||||
|
||||
/**
|
||||
* Product configuration.
|
||||
*/
|
||||
product: IProductConfiguration;
|
||||
|
||||
/**
|
||||
* Configured zoom level.
|
||||
*/
|
||||
zoomLevel?: number;
|
||||
|
||||
/**
|
||||
* @deprecated to be removed soon
|
||||
*/
|
||||
nodeCachedDataDir?: string;
|
||||
}
|
@ -9,6 +9,122 @@
|
||||
|
||||
const { ipcRenderer, webFrame, crashReporter, contextBridge } = require('electron');
|
||||
|
||||
//#region Utilities
|
||||
|
||||
/**
|
||||
* @param {string} channel
|
||||
* @returns {true | never}
|
||||
*/
|
||||
function validateIPC(channel) {
|
||||
if (!channel || !channel.startsWith('vscode:')) {
|
||||
throw new Error(`Unsupported event IPC channel '${channel}'`);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} type
|
||||
* @returns {type is 'uncaughtException'}
|
||||
*/
|
||||
function validateProcessEventType(type) {
|
||||
if (type !== 'uncaughtException') {
|
||||
throw new Error(`Unsupported process event '${type}'`);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} key the name of the process argument to parse
|
||||
* @returns {string | undefined}
|
||||
*/
|
||||
function parseArgv(key) {
|
||||
for (const arg of process.argv) {
|
||||
if (arg.indexOf(`--${key}=`) === 0) {
|
||||
return arg.split('=')[1];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Resolve Configuration
|
||||
|
||||
/**
|
||||
* @typedef {import('../common/sandboxTypes').ISandboxConfiguration} ISandboxConfiguration
|
||||
*/
|
||||
|
||||
/** @type {ISandboxConfiguration | undefined} */
|
||||
let configuration = undefined;
|
||||
|
||||
/** @type {Promise<ISandboxConfiguration>} */
|
||||
const resolveConfiguration = (async () => {
|
||||
const windowConfigIpcChannel = parseArgv('vscode-window-config');
|
||||
if (!windowConfigIpcChannel) {
|
||||
throw new Error('Preload: did not find expected vscode-window-config in renderer process arguments list.');
|
||||
}
|
||||
|
||||
try {
|
||||
if (validateIPC(windowConfigIpcChannel)) {
|
||||
|
||||
// Resolve configuration from electron-main
|
||||
configuration = await ipcRenderer.invoke(windowConfigIpcChannel);
|
||||
|
||||
// Apply `userEnv` directly
|
||||
Object.assign(process.env, configuration.userEnv);
|
||||
|
||||
// Apply zoom level early before even building the
|
||||
// window DOM elements to avoid UI flicker. We always
|
||||
// have to set the zoom level from within the window
|
||||
// because Chrome has it's own way of remembering zoom
|
||||
// settings per origin (if vscode-file:// is used) and
|
||||
// we want to ensure that the user configuration wins.
|
||||
webFrame.setZoomLevel(configuration.zoomLevel ?? 0);
|
||||
|
||||
return configuration;
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(`Preload: unable to fetch vscode-window-config: ${error}`);
|
||||
}
|
||||
})();
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Resolve Shell Environment
|
||||
|
||||
/**
|
||||
* If VSCode is not run from a terminal, we should resolve additional
|
||||
* shell specific environment from the OS shell to ensure we are seeing
|
||||
* all development related environment variables. We do this from the
|
||||
* main process because it may involve spawning a shell.
|
||||
*
|
||||
* @type {Promise<typeof process.env>}
|
||||
*/
|
||||
const resolveShellEnv = (async () => {
|
||||
|
||||
// Resolve `userEnv` from configuration and
|
||||
// `shellEnv` from the main side
|
||||
const [userEnv, shellEnv] = await Promise.all([
|
||||
(async () => (await resolveConfiguration).userEnv)(),
|
||||
ipcRenderer.invoke('vscode:fetchShellEnv')
|
||||
]);
|
||||
|
||||
if (!process.env['VSCODE_SKIP_PROCESS_ENV_PATCHING'] /* TODO@bpasero for https://github.com/microsoft/vscode/issues/108804 */) {
|
||||
// Assign all keys of the shell environment to our process environment
|
||||
// But make sure that the user environment wins in the end over shell environment
|
||||
Object.assign(process.env, shellEnv, userEnv);
|
||||
}
|
||||
|
||||
return { ...process.env, ...shellEnv, ...userEnv };
|
||||
})();
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Globals Definition
|
||||
|
||||
// #######################################################################
|
||||
// ### ###
|
||||
// ### !!! DO NOT USE GET/SET PROPERTIES ANYWHERE HERE !!! ###
|
||||
@ -17,14 +133,21 @@
|
||||
// ### ###
|
||||
// #######################################################################
|
||||
|
||||
/**
|
||||
* @type {import('../electron-sandbox/globals')}
|
||||
*/
|
||||
const globals = {
|
||||
|
||||
/**
|
||||
* A minimal set of methods exposed from Electron's `ipcRenderer`
|
||||
* to support communication to main process.
|
||||
*
|
||||
* @type {import('../electron-sandbox/electronTypes').IpcRenderer}
|
||||
* @typedef {import('../electron-sandbox/electronTypes').IpcRenderer} IpcRenderer
|
||||
* @typedef {import('electron').IpcRendererEvent} IpcRendererEvent
|
||||
*
|
||||
* @type {IpcRenderer}
|
||||
*/
|
||||
|
||||
ipcRenderer: {
|
||||
|
||||
/**
|
||||
@ -50,8 +173,8 @@
|
||||
|
||||
/**
|
||||
* @param {string} channel
|
||||
* @param {(event: import('electron').IpcRendererEvent, ...args: any[]) => void} listener
|
||||
* @returns {import('../electron-sandbox/electronTypes').IpcRenderer}
|
||||
* @param {(event: IpcRendererEvent, ...args: any[]) => void} listener
|
||||
* @returns {IpcRenderer}
|
||||
*/
|
||||
on(channel, listener) {
|
||||
if (validateIPC(channel)) {
|
||||
@ -63,8 +186,8 @@
|
||||
|
||||
/**
|
||||
* @param {string} channel
|
||||
* @param {(event: import('electron').IpcRendererEvent, ...args: any[]) => void} listener
|
||||
* @returns {import('../electron-sandbox/electronTypes').IpcRenderer}
|
||||
* @param {(event: IpcRendererEvent, ...args: any[]) => void} listener
|
||||
* @returns {IpcRenderer}
|
||||
*/
|
||||
once(channel, listener) {
|
||||
if (validateIPC(channel)) {
|
||||
@ -76,8 +199,8 @@
|
||||
|
||||
/**
|
||||
* @param {string} channel
|
||||
* @param {(event: import('electron').IpcRendererEvent, ...args: any[]) => void} listener
|
||||
* @returns {import('../electron-sandbox/electronTypes').IpcRenderer}
|
||||
* @param {(event: IpcRendererEvent, ...args: any[]) => void} listener
|
||||
* @returns {IpcRenderer}
|
||||
*/
|
||||
removeListener(channel, listener) {
|
||||
if (validateIPC(channel)) {
|
||||
@ -100,7 +223,7 @@
|
||||
*/
|
||||
connect(channelRequest, channelResponse, requestNonce) {
|
||||
if (validateIPC(channelRequest) && validateIPC(channelResponse)) {
|
||||
const responseListener = (/** @type {import('electron').IpcRendererEvent} */ e, /** @type {string} */ responseNonce) => {
|
||||
const responseListener = (/** @type {IpcRendererEvent} */ e, /** @type {string} */ responseNonce) => {
|
||||
// validate that the nonce from the response is the same
|
||||
// as when requested. and if so, use `postMessage` to
|
||||
// send the `MessagePort` safely over, even when context
|
||||
@ -157,7 +280,9 @@
|
||||
* Note: when `sandbox` is enabled, the only properties available
|
||||
* are https://github.com/electron/electron/blob/master/docs/api/process.md#sandbox
|
||||
*
|
||||
* @type {import('../electron-sandbox/globals').ISandboxNodeProcess}
|
||||
* @typedef {import('../electron-sandbox/globals').ISandboxNodeProcess} ISandboxNodeProcess
|
||||
*
|
||||
* @type {ISandboxNodeProcess}
|
||||
*/
|
||||
process: {
|
||||
get platform() { return process.platform; },
|
||||
@ -178,16 +303,8 @@
|
||||
/**
|
||||
* @returns {Promise<typeof process.env>}
|
||||
*/
|
||||
getShellEnv() {
|
||||
return shellEnv;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {{[key: string]: string}} userEnv
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
resolveEnv(userEnv) {
|
||||
return resolveEnv(userEnv);
|
||||
shellEnv() {
|
||||
return resolveShellEnv;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -200,7 +317,7 @@
|
||||
/**
|
||||
* @param {string} type
|
||||
* @param {Function} callback
|
||||
* @returns {import('../electron-sandbox/globals').ISandboxNodeProcess}
|
||||
* @returns {ISandboxNodeProcess}
|
||||
*/
|
||||
on(type, callback) {
|
||||
if (validateProcessEventType(type)) {
|
||||
@ -210,6 +327,37 @@
|
||||
return this;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Some information about the context we are running in.
|
||||
*
|
||||
* @type {import('../electron-sandbox/globals').ISandboxContext}
|
||||
*/
|
||||
context: {
|
||||
|
||||
/**
|
||||
* A configuration object made accessible from the main side
|
||||
* to configure the sandbox browser window.
|
||||
*
|
||||
* Note: intentionally not using a getter here because the
|
||||
* actual value will be set after `resolveConfiguration`
|
||||
* has finished.
|
||||
*
|
||||
* @returns {ISandboxConfiguration | undefined}
|
||||
*/
|
||||
configuration() {
|
||||
return configuration;
|
||||
},
|
||||
|
||||
/**
|
||||
* Allows to await the resolution of the configuration object.
|
||||
*
|
||||
* @returns {Promise<ISandboxConfiguration>}
|
||||
*/
|
||||
async resolveConfiguration() {
|
||||
return resolveConfiguration;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -231,69 +379,4 @@
|
||||
// @ts-ignore
|
||||
window.vscode = globals;
|
||||
}
|
||||
|
||||
//#region Utilities
|
||||
|
||||
/**
|
||||
* @param {string} channel
|
||||
* @returns {true | never}
|
||||
*/
|
||||
function validateIPC(channel) {
|
||||
if (!channel || !channel.startsWith('vscode:')) {
|
||||
throw new Error(`Unsupported event IPC channel '${channel}'`);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} type
|
||||
* @returns {type is 'uncaughtException'}
|
||||
*/
|
||||
function validateProcessEventType(type) {
|
||||
if (type !== 'uncaughtException') {
|
||||
throw new Error(`Unsupported process event '${type}'`);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @type {Promise<typeof process.env> | undefined} */
|
||||
let shellEnv = undefined;
|
||||
|
||||
/**
|
||||
* If VSCode is not run from a terminal, we should resolve additional
|
||||
* shell specific environment from the OS shell to ensure we are seeing
|
||||
* all development related environment variables. We do this from the
|
||||
* main process because it may involve spawning a shell.
|
||||
*
|
||||
* @param {{[key: string]: string}} userEnv
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function resolveEnv(userEnv) {
|
||||
if (!shellEnv) {
|
||||
|
||||
// Apply `userEnv` directly
|
||||
Object.assign(process.env, userEnv);
|
||||
|
||||
// Resolve `shellEnv` from the main side
|
||||
shellEnv = new Promise(function (resolve) {
|
||||
ipcRenderer.once('vscode:acceptShellEnv', function (event, shellEnvResult) {
|
||||
if (!process.env['VSCODE_SKIP_PROCESS_ENV_PATCHING'] /* TODO@bpasero for https://github.com/microsoft/vscode/issues/108804 */) {
|
||||
// Assign all keys of the shell environment to our process environment
|
||||
// But make sure that the user environment wins in the end over shell environment
|
||||
Object.assign(process.env, shellEnvResult, userEnv);
|
||||
}
|
||||
|
||||
resolve({ ...process.env, ...shellEnvResult, ...userEnv });
|
||||
});
|
||||
|
||||
ipcRenderer.send('vscode:fetchShellEnv');
|
||||
});
|
||||
}
|
||||
|
||||
await shellEnv;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
}());
|
||||
|
@ -4,6 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { globals, INodeProcess, IProcessEnvironment } from 'vs/base/common/platform';
|
||||
import { ISandboxConfiguration } from 'vs/base/parts/sandbox/common/sandboxTypes';
|
||||
import { ProcessMemoryInfo, CrashReporter, IpcRenderer, WebFrame } from 'vs/base/parts/sandbox/electron-sandbox/electronTypes';
|
||||
|
||||
/**
|
||||
@ -74,8 +75,8 @@ export interface ISandboxNodeProcess extends INodeProcess {
|
||||
getProcessMemoryInfo: () => Promise<ProcessMemoryInfo>;
|
||||
|
||||
/**
|
||||
* A custom method we add to `process`: Resolve the true process environment to use and
|
||||
* apply it to `process.env`.
|
||||
* Returns a process environment that includes all shell environment variables even if
|
||||
* the application was not started from a shell / terminal / console.
|
||||
*
|
||||
* There are different layers of environment that will apply:
|
||||
* - `process.env`: this is the actual environment of the process before this method
|
||||
@ -86,17 +87,8 @@ export interface ISandboxNodeProcess extends INodeProcess {
|
||||
* from a terminal and changed certain variables
|
||||
*
|
||||
* The order of overwrites is `process.env` < `shellEnv` < `userEnv`.
|
||||
*
|
||||
* It is critical that every process awaits this method early on startup to get the right
|
||||
* set of environment in `process.env`.
|
||||
*/
|
||||
resolveEnv(userEnv: IProcessEnvironment): Promise<void>;
|
||||
|
||||
/**
|
||||
* Returns a process environment that includes any shell environment even if the application
|
||||
* was not started from a shell / terminal / console.
|
||||
*/
|
||||
getShellEnv(): Promise<IProcessEnvironment>;
|
||||
shellEnv(): Promise<IProcessEnvironment>;
|
||||
}
|
||||
|
||||
export interface IpcMessagePort {
|
||||
@ -114,8 +106,24 @@ export interface IpcMessagePort {
|
||||
connect(channelRequest: string, channelResponse: string, requestNonce: string): void;
|
||||
}
|
||||
|
||||
export interface ISandboxContext {
|
||||
|
||||
/**
|
||||
* A configuration object made accessible from the main side
|
||||
* to configure the sandbox browser window. Will be `undefined`
|
||||
* for as long as `resolveConfiguration` is not awaited.
|
||||
*/
|
||||
configuration(): ISandboxConfiguration | undefined;
|
||||
|
||||
/**
|
||||
* Allows to await the resolution of the configuration object.
|
||||
*/
|
||||
resolveConfiguration(): Promise<ISandboxConfiguration>;
|
||||
}
|
||||
|
||||
export const ipcRenderer: IpcRenderer = globals.vscode.ipcRenderer;
|
||||
export const ipcMessagePort: IpcMessagePort = globals.vscode.ipcMessagePort;
|
||||
export const webFrame: WebFrame = globals.vscode.webFrame;
|
||||
export const crashReporter: CrashReporter = globals.vscode.crashReporter;
|
||||
export const process: ISandboxNodeProcess = globals.vscode.process;
|
||||
export const context: ISandboxContext = globals.vscode.context;
|
||||
|
@ -4,13 +4,17 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { ipcRenderer, crashReporter, webFrame, process } from 'vs/base/parts/sandbox/electron-sandbox/globals';
|
||||
import { ipcRenderer, crashReporter, webFrame, context, process } from 'vs/base/parts/sandbox/electron-sandbox/globals';
|
||||
|
||||
suite('Sandbox', () => {
|
||||
test('globals', () => {
|
||||
test('globals', async () => {
|
||||
assert.ok(typeof ipcRenderer.send === 'function');
|
||||
assert.ok(typeof crashReporter.addExtraParameter === 'function');
|
||||
assert.ok(typeof webFrame.setZoomLevel === 'function');
|
||||
assert.ok(typeof process.platform === 'string');
|
||||
|
||||
const config = await context.resolveConfiguration();
|
||||
assert.ok(config);
|
||||
assert.ok(context.configuration());
|
||||
});
|
||||
});
|
||||
|
@ -320,7 +320,7 @@ export class Storage extends Disposable implements IStorage {
|
||||
return new Promise(resolve => this.whenFlushedCallbacks.push(resolve));
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
override dispose(): void {
|
||||
this.flushDelayer.cancel(); // workaround https://github.com/microsoft/vscode/issues/116777
|
||||
this.flushDelayer.dispose();
|
||||
|
||||
|
@ -111,7 +111,7 @@ flakySuite('Storage Library', function () {
|
||||
|
||||
class TestSQLiteStorageDatabase extends SQLiteStorageDatabase {
|
||||
private readonly _onDidChangeItemsExternal = new Emitter<IStorageItemsChangeEvent>();
|
||||
get onDidChangeItemsExternal(): Event<IStorageItemsChangeEvent> { return this._onDidChangeItemsExternal.event; }
|
||||
override get onDidChangeItemsExternal(): Event<IStorageItemsChangeEvent> { return this._onDidChangeItemsExternal.event; }
|
||||
|
||||
fireDidChangeItemsExternal(event: IStorageItemsChangeEvent): void {
|
||||
this._onDidChangeItemsExternal.fire(event);
|
||||
|
@ -59,8 +59,8 @@ suite('Comparers', () => {
|
||||
// name-only comparisons
|
||||
assert(compareFileNames('a', 'A') !== compareLocale('a', 'A'), 'the same letter does not sort by locale');
|
||||
assert(compareFileNames('â', 'Â') !== compareLocale('â', 'Â'), 'the same accented letter does not sort by locale');
|
||||
assert.notDeepEqual(['artichoke', 'Artichoke', 'art', 'Art'].sort(compareFileNames), ['artichoke', 'Artichoke', 'art', 'Art'].sort(compareLocale), 'words with the same root and different cases do not sort in locale order');
|
||||
assert.notDeepEqual(['email', 'Email', 'émail', 'Émail'].sort(compareFileNames), ['email', 'Email', 'émail', 'Émail'].sort(compareLocale), 'the same base characters with different case or accents do not sort in locale order');
|
||||
assert.notDeepStrictEqual(['artichoke', 'Artichoke', 'art', 'Art'].sort(compareFileNames), ['artichoke', 'Artichoke', 'art', 'Art'].sort(compareLocale), 'words with the same root and different cases do not sort in locale order');
|
||||
assert.notDeepStrictEqual(['email', 'Email', 'émail', 'Émail'].sort(compareFileNames), ['email', 'Email', 'émail', 'Émail'].sort(compareLocale), 'the same base characters with different case or accents do not sort in locale order');
|
||||
|
||||
// numeric comparisons
|
||||
assert(compareFileNames('abc02.txt', 'abc002.txt') > 0, 'filenames with equivalent numbers and leading zeros sort in unicode order');
|
||||
|
@ -44,8 +44,14 @@ suite('FormattedTextRenderer', () => {
|
||||
result = renderFormattedText('__italics__');
|
||||
assert.strictEqual(result.innerHTML, '<i>italics</i>');
|
||||
|
||||
result = renderFormattedText('this string has **bold** and __italics__');
|
||||
assert.strictEqual(result.innerHTML, 'this string has <b>bold</b> and <i>italics</i>');
|
||||
result = renderFormattedText('``code``');
|
||||
assert.strictEqual(result.innerHTML, '``code``');
|
||||
|
||||
result = renderFormattedText('``code``', { renderCodeSegements: true });
|
||||
assert.strictEqual(result.innerHTML, '<code>code</code>');
|
||||
|
||||
result = renderFormattedText('this string has **bold**, __italics__, and ``code``!!', { renderCodeSegements: true });
|
||||
assert.strictEqual(result.innerHTML, 'this string has <b>bold</b>, <i>italics</i>, and <code>code</code>!!');
|
||||
});
|
||||
|
||||
test('no formatting', () => {
|
||||
@ -96,6 +102,26 @@ suite('FormattedTextRenderer', () => {
|
||||
assert.strictEqual(callbackCalled, true);
|
||||
});
|
||||
|
||||
test('fancier action', () => {
|
||||
let callbackCalled = false;
|
||||
let result: HTMLElement = renderFormattedText('``__**[[action]]**__``', {
|
||||
renderCodeSegements: true,
|
||||
actionHandler: {
|
||||
callback(content) {
|
||||
assert.strictEqual(content, '0');
|
||||
callbackCalled = true;
|
||||
},
|
||||
disposeables: store
|
||||
}
|
||||
});
|
||||
assert.strictEqual(result.innerHTML, '<code><i><b><a href="#">action</a></b></i></code>');
|
||||
|
||||
let event: MouseEvent = <any>document.createEvent('MouseEvent');
|
||||
event.initEvent('click', true, true);
|
||||
result.firstChild!.firstChild!.firstChild!.firstChild!.dispatchEvent(event);
|
||||
assert.strictEqual(callbackCalled, true);
|
||||
});
|
||||
|
||||
test('escaped formatting', () => {
|
||||
let result: HTMLElement = renderFormattedText('\\*\\*bold\\*\\*');
|
||||
assert.strictEqual(result.children.length, 0);
|
||||
|
@ -111,7 +111,7 @@ suite('MarkdownRenderer', () => {
|
||||
|
||||
const data = <{ script: string, documentUri: URI }>parse(decodeURIComponent(uri.query));
|
||||
assert.ok(data);
|
||||
assert.equal(data.script, 'echo');
|
||||
assert.strictEqual(data.script, 'echo');
|
||||
assert.ok(data.documentUri.toString().startsWith('file:///c%3A/'));
|
||||
});
|
||||
|
||||
|
@ -40,35 +40,35 @@ suite('Grid', function () {
|
||||
});
|
||||
|
||||
test('getRelativeLocation', () => {
|
||||
assert.deepEqual(getRelativeLocation(Orientation.VERTICAL, [0], Direction.Up), [0]);
|
||||
assert.deepEqual(getRelativeLocation(Orientation.VERTICAL, [0], Direction.Down), [1]);
|
||||
assert.deepEqual(getRelativeLocation(Orientation.VERTICAL, [0], Direction.Left), [0, 0]);
|
||||
assert.deepEqual(getRelativeLocation(Orientation.VERTICAL, [0], Direction.Right), [0, 1]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.VERTICAL, [0], Direction.Up), [0]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.VERTICAL, [0], Direction.Down), [1]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.VERTICAL, [0], Direction.Left), [0, 0]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.VERTICAL, [0], Direction.Right), [0, 1]);
|
||||
|
||||
assert.deepEqual(getRelativeLocation(Orientation.HORIZONTAL, [0], Direction.Up), [0, 0]);
|
||||
assert.deepEqual(getRelativeLocation(Orientation.HORIZONTAL, [0], Direction.Down), [0, 1]);
|
||||
assert.deepEqual(getRelativeLocation(Orientation.HORIZONTAL, [0], Direction.Left), [0]);
|
||||
assert.deepEqual(getRelativeLocation(Orientation.HORIZONTAL, [0], Direction.Right), [1]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.HORIZONTAL, [0], Direction.Up), [0, 0]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.HORIZONTAL, [0], Direction.Down), [0, 1]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.HORIZONTAL, [0], Direction.Left), [0]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.HORIZONTAL, [0], Direction.Right), [1]);
|
||||
|
||||
assert.deepEqual(getRelativeLocation(Orientation.VERTICAL, [4], Direction.Up), [4]);
|
||||
assert.deepEqual(getRelativeLocation(Orientation.VERTICAL, [4], Direction.Down), [5]);
|
||||
assert.deepEqual(getRelativeLocation(Orientation.VERTICAL, [4], Direction.Left), [4, 0]);
|
||||
assert.deepEqual(getRelativeLocation(Orientation.VERTICAL, [4], Direction.Right), [4, 1]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.VERTICAL, [4], Direction.Up), [4]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.VERTICAL, [4], Direction.Down), [5]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.VERTICAL, [4], Direction.Left), [4, 0]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.VERTICAL, [4], Direction.Right), [4, 1]);
|
||||
|
||||
assert.deepEqual(getRelativeLocation(Orientation.VERTICAL, [0, 0], Direction.Up), [0, 0, 0]);
|
||||
assert.deepEqual(getRelativeLocation(Orientation.VERTICAL, [0, 0], Direction.Down), [0, 0, 1]);
|
||||
assert.deepEqual(getRelativeLocation(Orientation.VERTICAL, [0, 0], Direction.Left), [0, 0]);
|
||||
assert.deepEqual(getRelativeLocation(Orientation.VERTICAL, [0, 0], Direction.Right), [0, 1]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.VERTICAL, [0, 0], Direction.Up), [0, 0, 0]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.VERTICAL, [0, 0], Direction.Down), [0, 0, 1]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.VERTICAL, [0, 0], Direction.Left), [0, 0]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.VERTICAL, [0, 0], Direction.Right), [0, 1]);
|
||||
|
||||
assert.deepEqual(getRelativeLocation(Orientation.VERTICAL, [1, 2], Direction.Up), [1, 2, 0]);
|
||||
assert.deepEqual(getRelativeLocation(Orientation.VERTICAL, [1, 2], Direction.Down), [1, 2, 1]);
|
||||
assert.deepEqual(getRelativeLocation(Orientation.VERTICAL, [1, 2], Direction.Left), [1, 2]);
|
||||
assert.deepEqual(getRelativeLocation(Orientation.VERTICAL, [1, 2], Direction.Right), [1, 3]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.VERTICAL, [1, 2], Direction.Up), [1, 2, 0]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.VERTICAL, [1, 2], Direction.Down), [1, 2, 1]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.VERTICAL, [1, 2], Direction.Left), [1, 2]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.VERTICAL, [1, 2], Direction.Right), [1, 3]);
|
||||
|
||||
assert.deepEqual(getRelativeLocation(Orientation.VERTICAL, [1, 2, 3], Direction.Up), [1, 2, 3]);
|
||||
assert.deepEqual(getRelativeLocation(Orientation.VERTICAL, [1, 2, 3], Direction.Down), [1, 2, 4]);
|
||||
assert.deepEqual(getRelativeLocation(Orientation.VERTICAL, [1, 2, 3], Direction.Left), [1, 2, 3, 0]);
|
||||
assert.deepEqual(getRelativeLocation(Orientation.VERTICAL, [1, 2, 3], Direction.Right), [1, 2, 3, 1]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.VERTICAL, [1, 2, 3], Direction.Up), [1, 2, 3]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.VERTICAL, [1, 2, 3], Direction.Down), [1, 2, 4]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.VERTICAL, [1, 2, 3], Direction.Left), [1, 2, 3, 0]);
|
||||
assert.deepStrictEqual(getRelativeLocation(Orientation.VERTICAL, [1, 2, 3], Direction.Right), [1, 2, 3, 1]);
|
||||
});
|
||||
|
||||
test('empty', () => {
|
||||
@ -77,7 +77,7 @@ suite('Grid', function () {
|
||||
container.appendChild(gridview.element);
|
||||
gridview.layout(800, 600);
|
||||
|
||||
assert.deepEqual(view1.size, [800, 600]);
|
||||
assert.deepStrictEqual(view1.size, [800, 600]);
|
||||
});
|
||||
|
||||
test('two views vertically', function () {
|
||||
@ -85,12 +85,12 @@ suite('Grid', function () {
|
||||
const grid = new Grid(view1);
|
||||
container.appendChild(grid.element);
|
||||
grid.layout(800, 600);
|
||||
assert.deepEqual(view1.size, [800, 600]);
|
||||
assert.deepStrictEqual(view1.size, [800, 600]);
|
||||
|
||||
const view2 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view2, 200, view1, Direction.Up);
|
||||
assert.deepEqual(view1.size, [800, 400]);
|
||||
assert.deepEqual(view2.size, [800, 200]);
|
||||
assert.deepStrictEqual(view1.size, [800, 400]);
|
||||
assert.deepStrictEqual(view2.size, [800, 200]);
|
||||
});
|
||||
|
||||
test('two views horizontally', function () {
|
||||
@ -99,12 +99,12 @@ suite('Grid', function () {
|
||||
container.appendChild(grid.element);
|
||||
|
||||
grid.layout(800, 600);
|
||||
assert.deepEqual(view1.size, [800, 600]);
|
||||
assert.deepStrictEqual(view1.size, [800, 600]);
|
||||
|
||||
const view2 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view2, 300, view1, Direction.Right);
|
||||
assert.deepEqual(view1.size, [500, 600]);
|
||||
assert.deepEqual(view2.size, [300, 600]);
|
||||
assert.deepStrictEqual(view1.size, [500, 600]);
|
||||
assert.deepStrictEqual(view2.size, [300, 600]);
|
||||
});
|
||||
|
||||
test('simple layout', function () {
|
||||
@ -113,33 +113,33 @@ suite('Grid', function () {
|
||||
container.appendChild(grid.element);
|
||||
|
||||
grid.layout(800, 600);
|
||||
assert.deepEqual(view1.size, [800, 600]);
|
||||
assert.deepStrictEqual(view1.size, [800, 600]);
|
||||
|
||||
const view2 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view2, 200, view1, Direction.Up);
|
||||
assert.deepEqual(view1.size, [800, 400]);
|
||||
assert.deepEqual(view2.size, [800, 200]);
|
||||
assert.deepStrictEqual(view1.size, [800, 400]);
|
||||
assert.deepStrictEqual(view2.size, [800, 200]);
|
||||
|
||||
const view3 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view3, 200, view1, Direction.Right);
|
||||
assert.deepEqual(view1.size, [600, 400]);
|
||||
assert.deepEqual(view2.size, [800, 200]);
|
||||
assert.deepEqual(view3.size, [200, 400]);
|
||||
assert.deepStrictEqual(view1.size, [600, 400]);
|
||||
assert.deepStrictEqual(view2.size, [800, 200]);
|
||||
assert.deepStrictEqual(view3.size, [200, 400]);
|
||||
|
||||
const view4 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view4, 200, view2, Direction.Left);
|
||||
assert.deepEqual(view1.size, [600, 400]);
|
||||
assert.deepEqual(view2.size, [600, 200]);
|
||||
assert.deepEqual(view3.size, [200, 400]);
|
||||
assert.deepEqual(view4.size, [200, 200]);
|
||||
assert.deepStrictEqual(view1.size, [600, 400]);
|
||||
assert.deepStrictEqual(view2.size, [600, 200]);
|
||||
assert.deepStrictEqual(view3.size, [200, 400]);
|
||||
assert.deepStrictEqual(view4.size, [200, 200]);
|
||||
|
||||
const view5 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view5, 100, view1, Direction.Down);
|
||||
assert.deepEqual(view1.size, [600, 300]);
|
||||
assert.deepEqual(view2.size, [600, 200]);
|
||||
assert.deepEqual(view3.size, [200, 400]);
|
||||
assert.deepEqual(view4.size, [200, 200]);
|
||||
assert.deepEqual(view5.size, [600, 100]);
|
||||
assert.deepStrictEqual(view1.size, [600, 300]);
|
||||
assert.deepStrictEqual(view2.size, [600, 200]);
|
||||
assert.deepStrictEqual(view3.size, [200, 400]);
|
||||
assert.deepStrictEqual(view4.size, [200, 200]);
|
||||
assert.deepStrictEqual(view5.size, [600, 100]);
|
||||
});
|
||||
|
||||
test('another simple layout with automatic size distribution', function () {
|
||||
@ -148,42 +148,42 @@ suite('Grid', function () {
|
||||
container.appendChild(grid.element);
|
||||
|
||||
grid.layout(800, 600);
|
||||
assert.deepEqual(view1.size, [800, 600]);
|
||||
assert.deepStrictEqual(view1.size, [800, 600]);
|
||||
|
||||
const view2 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view2, Sizing.Distribute, view1, Direction.Left);
|
||||
assert.deepEqual(view1.size, [400, 600]);
|
||||
assert.deepEqual(view2.size, [400, 600]);
|
||||
assert.deepStrictEqual(view1.size, [400, 600]);
|
||||
assert.deepStrictEqual(view2.size, [400, 600]);
|
||||
|
||||
const view3 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view3, Sizing.Distribute, view1, Direction.Right);
|
||||
assert.deepEqual(view1.size, [266, 600]);
|
||||
assert.deepEqual(view2.size, [266, 600]);
|
||||
assert.deepEqual(view3.size, [268, 600]);
|
||||
assert.deepStrictEqual(view1.size, [266, 600]);
|
||||
assert.deepStrictEqual(view2.size, [266, 600]);
|
||||
assert.deepStrictEqual(view3.size, [268, 600]);
|
||||
|
||||
const view4 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view4, Sizing.Distribute, view2, Direction.Down);
|
||||
assert.deepEqual(view1.size, [266, 600]);
|
||||
assert.deepEqual(view2.size, [266, 300]);
|
||||
assert.deepEqual(view3.size, [268, 600]);
|
||||
assert.deepEqual(view4.size, [266, 300]);
|
||||
assert.deepStrictEqual(view1.size, [266, 600]);
|
||||
assert.deepStrictEqual(view2.size, [266, 300]);
|
||||
assert.deepStrictEqual(view3.size, [268, 600]);
|
||||
assert.deepStrictEqual(view4.size, [266, 300]);
|
||||
|
||||
const view5 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view5, Sizing.Distribute, view3, Direction.Up);
|
||||
assert.deepEqual(view1.size, [266, 600]);
|
||||
assert.deepEqual(view2.size, [266, 300]);
|
||||
assert.deepEqual(view3.size, [268, 300]);
|
||||
assert.deepEqual(view4.size, [266, 300]);
|
||||
assert.deepEqual(view5.size, [268, 300]);
|
||||
assert.deepStrictEqual(view1.size, [266, 600]);
|
||||
assert.deepStrictEqual(view2.size, [266, 300]);
|
||||
assert.deepStrictEqual(view3.size, [268, 300]);
|
||||
assert.deepStrictEqual(view4.size, [266, 300]);
|
||||
assert.deepStrictEqual(view5.size, [268, 300]);
|
||||
|
||||
const view6 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view6, Sizing.Distribute, view3, Direction.Down);
|
||||
assert.deepEqual(view1.size, [266, 600]);
|
||||
assert.deepEqual(view2.size, [266, 300]);
|
||||
assert.deepEqual(view3.size, [268, 200]);
|
||||
assert.deepEqual(view4.size, [266, 300]);
|
||||
assert.deepEqual(view5.size, [268, 200]);
|
||||
assert.deepEqual(view6.size, [268, 200]);
|
||||
assert.deepStrictEqual(view1.size, [266, 600]);
|
||||
assert.deepStrictEqual(view2.size, [266, 300]);
|
||||
assert.deepStrictEqual(view3.size, [268, 200]);
|
||||
assert.deepStrictEqual(view4.size, [266, 300]);
|
||||
assert.deepStrictEqual(view5.size, [268, 200]);
|
||||
assert.deepStrictEqual(view6.size, [268, 200]);
|
||||
});
|
||||
|
||||
test('another simple layout with split size distribution', function () {
|
||||
@ -192,42 +192,42 @@ suite('Grid', function () {
|
||||
container.appendChild(grid.element);
|
||||
|
||||
grid.layout(800, 600);
|
||||
assert.deepEqual(view1.size, [800, 600]);
|
||||
assert.deepStrictEqual(view1.size, [800, 600]);
|
||||
|
||||
const view2 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view2, Sizing.Split, view1, Direction.Left);
|
||||
assert.deepEqual(view1.size, [400, 600]);
|
||||
assert.deepEqual(view2.size, [400, 600]);
|
||||
assert.deepStrictEqual(view1.size, [400, 600]);
|
||||
assert.deepStrictEqual(view2.size, [400, 600]);
|
||||
|
||||
const view3 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view3, Sizing.Split, view1, Direction.Right);
|
||||
assert.deepEqual(view1.size, [200, 600]);
|
||||
assert.deepEqual(view2.size, [400, 600]);
|
||||
assert.deepEqual(view3.size, [200, 600]);
|
||||
assert.deepStrictEqual(view1.size, [200, 600]);
|
||||
assert.deepStrictEqual(view2.size, [400, 600]);
|
||||
assert.deepStrictEqual(view3.size, [200, 600]);
|
||||
|
||||
const view4 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view4, Sizing.Split, view2, Direction.Down);
|
||||
assert.deepEqual(view1.size, [200, 600]);
|
||||
assert.deepEqual(view2.size, [400, 300]);
|
||||
assert.deepEqual(view3.size, [200, 600]);
|
||||
assert.deepEqual(view4.size, [400, 300]);
|
||||
assert.deepStrictEqual(view1.size, [200, 600]);
|
||||
assert.deepStrictEqual(view2.size, [400, 300]);
|
||||
assert.deepStrictEqual(view3.size, [200, 600]);
|
||||
assert.deepStrictEqual(view4.size, [400, 300]);
|
||||
|
||||
const view5 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view5, Sizing.Split, view3, Direction.Up);
|
||||
assert.deepEqual(view1.size, [200, 600]);
|
||||
assert.deepEqual(view2.size, [400, 300]);
|
||||
assert.deepEqual(view3.size, [200, 300]);
|
||||
assert.deepEqual(view4.size, [400, 300]);
|
||||
assert.deepEqual(view5.size, [200, 300]);
|
||||
assert.deepStrictEqual(view1.size, [200, 600]);
|
||||
assert.deepStrictEqual(view2.size, [400, 300]);
|
||||
assert.deepStrictEqual(view3.size, [200, 300]);
|
||||
assert.deepStrictEqual(view4.size, [400, 300]);
|
||||
assert.deepStrictEqual(view5.size, [200, 300]);
|
||||
|
||||
const view6 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view6, Sizing.Split, view3, Direction.Down);
|
||||
assert.deepEqual(view1.size, [200, 600]);
|
||||
assert.deepEqual(view2.size, [400, 300]);
|
||||
assert.deepEqual(view3.size, [200, 150]);
|
||||
assert.deepEqual(view4.size, [400, 300]);
|
||||
assert.deepEqual(view5.size, [200, 300]);
|
||||
assert.deepEqual(view6.size, [200, 150]);
|
||||
assert.deepStrictEqual(view1.size, [200, 600]);
|
||||
assert.deepStrictEqual(view2.size, [400, 300]);
|
||||
assert.deepStrictEqual(view3.size, [200, 150]);
|
||||
assert.deepStrictEqual(view4.size, [400, 300]);
|
||||
assert.deepStrictEqual(view5.size, [200, 300]);
|
||||
assert.deepStrictEqual(view6.size, [200, 150]);
|
||||
});
|
||||
|
||||
test('3/2 layout with split', function () {
|
||||
@ -236,33 +236,33 @@ suite('Grid', function () {
|
||||
container.appendChild(grid.element);
|
||||
|
||||
grid.layout(800, 600);
|
||||
assert.deepEqual(view1.size, [800, 600]);
|
||||
assert.deepStrictEqual(view1.size, [800, 600]);
|
||||
|
||||
const view2 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view2, Sizing.Split, view1, Direction.Down);
|
||||
assert.deepEqual(view1.size, [800, 300]);
|
||||
assert.deepEqual(view2.size, [800, 300]);
|
||||
assert.deepStrictEqual(view1.size, [800, 300]);
|
||||
assert.deepStrictEqual(view2.size, [800, 300]);
|
||||
|
||||
const view3 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view3, Sizing.Split, view2, Direction.Right);
|
||||
assert.deepEqual(view1.size, [800, 300]);
|
||||
assert.deepEqual(view2.size, [400, 300]);
|
||||
assert.deepEqual(view3.size, [400, 300]);
|
||||
assert.deepStrictEqual(view1.size, [800, 300]);
|
||||
assert.deepStrictEqual(view2.size, [400, 300]);
|
||||
assert.deepStrictEqual(view3.size, [400, 300]);
|
||||
|
||||
const view4 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view4, Sizing.Split, view1, Direction.Right);
|
||||
assert.deepEqual(view1.size, [400, 300]);
|
||||
assert.deepEqual(view2.size, [400, 300]);
|
||||
assert.deepEqual(view3.size, [400, 300]);
|
||||
assert.deepEqual(view4.size, [400, 300]);
|
||||
assert.deepStrictEqual(view1.size, [400, 300]);
|
||||
assert.deepStrictEqual(view2.size, [400, 300]);
|
||||
assert.deepStrictEqual(view3.size, [400, 300]);
|
||||
assert.deepStrictEqual(view4.size, [400, 300]);
|
||||
|
||||
const view5 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view5, Sizing.Split, view1, Direction.Right);
|
||||
assert.deepEqual(view1.size, [200, 300]);
|
||||
assert.deepEqual(view2.size, [400, 300]);
|
||||
assert.deepEqual(view3.size, [400, 300]);
|
||||
assert.deepEqual(view4.size, [400, 300]);
|
||||
assert.deepEqual(view5.size, [200, 300]);
|
||||
assert.deepStrictEqual(view1.size, [200, 300]);
|
||||
assert.deepStrictEqual(view2.size, [400, 300]);
|
||||
assert.deepStrictEqual(view3.size, [400, 300]);
|
||||
assert.deepStrictEqual(view4.size, [400, 300]);
|
||||
assert.deepStrictEqual(view5.size, [200, 300]);
|
||||
});
|
||||
|
||||
test('sizing should be correct after branch demotion #50564', function () {
|
||||
@ -280,15 +280,15 @@ suite('Grid', function () {
|
||||
|
||||
const view4 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view4, Sizing.Split, view2, Direction.Right);
|
||||
assert.deepEqual(view1.size, [400, 600]);
|
||||
assert.deepEqual(view2.size, [200, 300]);
|
||||
assert.deepEqual(view3.size, [400, 300]);
|
||||
assert.deepEqual(view4.size, [200, 300]);
|
||||
assert.deepStrictEqual(view1.size, [400, 600]);
|
||||
assert.deepStrictEqual(view2.size, [200, 300]);
|
||||
assert.deepStrictEqual(view3.size, [400, 300]);
|
||||
assert.deepStrictEqual(view4.size, [200, 300]);
|
||||
|
||||
grid.removeView(view3);
|
||||
assert.deepEqual(view1.size, [400, 600]);
|
||||
assert.deepEqual(view2.size, [200, 600]);
|
||||
assert.deepEqual(view4.size, [200, 600]);
|
||||
assert.deepStrictEqual(view1.size, [400, 600]);
|
||||
assert.deepStrictEqual(view2.size, [200, 600]);
|
||||
assert.deepStrictEqual(view4.size, [200, 600]);
|
||||
});
|
||||
|
||||
test('sizing should be correct after branch demotion #50675', function () {
|
||||
@ -306,15 +306,15 @@ suite('Grid', function () {
|
||||
|
||||
const view4 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view4, Sizing.Distribute, view3, Direction.Right);
|
||||
assert.deepEqual(view1.size, [800, 200]);
|
||||
assert.deepEqual(view2.size, [800, 200]);
|
||||
assert.deepEqual(view3.size, [400, 200]);
|
||||
assert.deepEqual(view4.size, [400, 200]);
|
||||
assert.deepStrictEqual(view1.size, [800, 200]);
|
||||
assert.deepStrictEqual(view2.size, [800, 200]);
|
||||
assert.deepStrictEqual(view3.size, [400, 200]);
|
||||
assert.deepStrictEqual(view4.size, [400, 200]);
|
||||
|
||||
grid.removeView(view3, Sizing.Distribute);
|
||||
assert.deepEqual(view1.size, [800, 200]);
|
||||
assert.deepEqual(view2.size, [800, 200]);
|
||||
assert.deepEqual(view4.size, [800, 200]);
|
||||
assert.deepStrictEqual(view1.size, [800, 200]);
|
||||
assert.deepStrictEqual(view2.size, [800, 200]);
|
||||
assert.deepStrictEqual(view4.size, [800, 200]);
|
||||
});
|
||||
|
||||
test('getNeighborViews should work on single view layout', function () {
|
||||
@ -324,15 +324,15 @@ suite('Grid', function () {
|
||||
|
||||
grid.layout(800, 600);
|
||||
|
||||
assert.deepEqual(grid.getNeighborViews(view1, Direction.Up), []);
|
||||
assert.deepEqual(grid.getNeighborViews(view1, Direction.Right), []);
|
||||
assert.deepEqual(grid.getNeighborViews(view1, Direction.Down), []);
|
||||
assert.deepEqual(grid.getNeighborViews(view1, Direction.Left), []);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view1, Direction.Up), []);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view1, Direction.Right), []);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view1, Direction.Down), []);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view1, Direction.Left), []);
|
||||
|
||||
assert.deepEqual(grid.getNeighborViews(view1, Direction.Up, true), [view1]);
|
||||
assert.deepEqual(grid.getNeighborViews(view1, Direction.Right, true), [view1]);
|
||||
assert.deepEqual(grid.getNeighborViews(view1, Direction.Down, true), [view1]);
|
||||
assert.deepEqual(grid.getNeighborViews(view1, Direction.Left, true), [view1]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view1, Direction.Up, true), [view1]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view1, Direction.Right, true), [view1]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view1, Direction.Down, true), [view1]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view1, Direction.Left, true), [view1]);
|
||||
});
|
||||
|
||||
test('getNeighborViews should work on simple layout', function () {
|
||||
@ -348,35 +348,35 @@ suite('Grid', function () {
|
||||
const view3 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view3, Sizing.Distribute, view2, Direction.Down);
|
||||
|
||||
assert.deepEqual(grid.getNeighborViews(view1, Direction.Up), []);
|
||||
assert.deepEqual(grid.getNeighborViews(view1, Direction.Right), []);
|
||||
assert.deepEqual(grid.getNeighborViews(view1, Direction.Down), [view2]);
|
||||
assert.deepEqual(grid.getNeighborViews(view1, Direction.Left), []);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view1, Direction.Up), []);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view1, Direction.Right), []);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view1, Direction.Down), [view2]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view1, Direction.Left), []);
|
||||
|
||||
assert.deepEqual(grid.getNeighborViews(view1, Direction.Up, true), [view3]);
|
||||
assert.deepEqual(grid.getNeighborViews(view1, Direction.Right, true), [view1]);
|
||||
assert.deepEqual(grid.getNeighborViews(view1, Direction.Down, true), [view2]);
|
||||
assert.deepEqual(grid.getNeighborViews(view1, Direction.Left, true), [view1]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view1, Direction.Up, true), [view3]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view1, Direction.Right, true), [view1]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view1, Direction.Down, true), [view2]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view1, Direction.Left, true), [view1]);
|
||||
|
||||
assert.deepEqual(grid.getNeighborViews(view2, Direction.Up), [view1]);
|
||||
assert.deepEqual(grid.getNeighborViews(view2, Direction.Right), []);
|
||||
assert.deepEqual(grid.getNeighborViews(view2, Direction.Down), [view3]);
|
||||
assert.deepEqual(grid.getNeighborViews(view2, Direction.Left), []);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view2, Direction.Up), [view1]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view2, Direction.Right), []);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view2, Direction.Down), [view3]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view2, Direction.Left), []);
|
||||
|
||||
assert.deepEqual(grid.getNeighborViews(view2, Direction.Up, true), [view1]);
|
||||
assert.deepEqual(grid.getNeighborViews(view2, Direction.Right, true), [view2]);
|
||||
assert.deepEqual(grid.getNeighborViews(view2, Direction.Down, true), [view3]);
|
||||
assert.deepEqual(grid.getNeighborViews(view2, Direction.Left, true), [view2]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view2, Direction.Up, true), [view1]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view2, Direction.Right, true), [view2]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view2, Direction.Down, true), [view3]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view2, Direction.Left, true), [view2]);
|
||||
|
||||
assert.deepEqual(grid.getNeighborViews(view3, Direction.Up), [view2]);
|
||||
assert.deepEqual(grid.getNeighborViews(view3, Direction.Right), []);
|
||||
assert.deepEqual(grid.getNeighborViews(view3, Direction.Down), []);
|
||||
assert.deepEqual(grid.getNeighborViews(view3, Direction.Left), []);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view3, Direction.Up), [view2]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view3, Direction.Right), []);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view3, Direction.Down), []);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view3, Direction.Left), []);
|
||||
|
||||
assert.deepEqual(grid.getNeighborViews(view3, Direction.Up, true), [view2]);
|
||||
assert.deepEqual(grid.getNeighborViews(view3, Direction.Right, true), [view3]);
|
||||
assert.deepEqual(grid.getNeighborViews(view3, Direction.Down, true), [view1]);
|
||||
assert.deepEqual(grid.getNeighborViews(view3, Direction.Left, true), [view3]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view3, Direction.Up, true), [view2]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view3, Direction.Right, true), [view3]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view3, Direction.Down, true), [view1]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view3, Direction.Left, true), [view3]);
|
||||
});
|
||||
|
||||
test('getNeighborViews should work on a complex layout', function () {
|
||||
@ -398,26 +398,26 @@ suite('Grid', function () {
|
||||
const view5 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view5, Sizing.Distribute, view4, Direction.Down);
|
||||
|
||||
assert.deepEqual(grid.getNeighborViews(view1, Direction.Up), []);
|
||||
assert.deepEqual(grid.getNeighborViews(view1, Direction.Right), []);
|
||||
assert.deepEqual(grid.getNeighborViews(view1, Direction.Down), [view2, view4]);
|
||||
assert.deepEqual(grid.getNeighborViews(view1, Direction.Left), []);
|
||||
assert.deepEqual(grid.getNeighborViews(view2, Direction.Up), [view1]);
|
||||
assert.deepEqual(grid.getNeighborViews(view2, Direction.Right), [view4, view5]);
|
||||
assert.deepEqual(grid.getNeighborViews(view2, Direction.Down), [view3]);
|
||||
assert.deepEqual(grid.getNeighborViews(view2, Direction.Left), []);
|
||||
assert.deepEqual(grid.getNeighborViews(view4, Direction.Up), [view1]);
|
||||
assert.deepEqual(grid.getNeighborViews(view4, Direction.Right), []);
|
||||
assert.deepEqual(grid.getNeighborViews(view4, Direction.Down), [view5]);
|
||||
assert.deepEqual(grid.getNeighborViews(view4, Direction.Left), [view2]);
|
||||
assert.deepEqual(grid.getNeighborViews(view5, Direction.Up), [view4]);
|
||||
assert.deepEqual(grid.getNeighborViews(view5, Direction.Right), []);
|
||||
assert.deepEqual(grid.getNeighborViews(view5, Direction.Down), [view3]);
|
||||
assert.deepEqual(grid.getNeighborViews(view5, Direction.Left), [view2]);
|
||||
assert.deepEqual(grid.getNeighborViews(view3, Direction.Up), [view2, view5]);
|
||||
assert.deepEqual(grid.getNeighborViews(view3, Direction.Right), []);
|
||||
assert.deepEqual(grid.getNeighborViews(view3, Direction.Down), []);
|
||||
assert.deepEqual(grid.getNeighborViews(view3, Direction.Left), []);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view1, Direction.Up), []);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view1, Direction.Right), []);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view1, Direction.Down), [view2, view4]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view1, Direction.Left), []);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view2, Direction.Up), [view1]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view2, Direction.Right), [view4, view5]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view2, Direction.Down), [view3]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view2, Direction.Left), []);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view4, Direction.Up), [view1]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view4, Direction.Right), []);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view4, Direction.Down), [view5]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view4, Direction.Left), [view2]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view5, Direction.Up), [view4]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view5, Direction.Right), []);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view5, Direction.Down), [view3]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view5, Direction.Left), [view2]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view3, Direction.Up), [view2, view5]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view3, Direction.Right), []);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view3, Direction.Down), []);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view3, Direction.Left), []);
|
||||
});
|
||||
|
||||
test('getNeighborViews should work on another simple layout', function () {
|
||||
@ -436,10 +436,10 @@ suite('Grid', function () {
|
||||
const view4 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view4, Sizing.Distribute, view2, Direction.Right);
|
||||
|
||||
assert.deepEqual(grid.getNeighborViews(view4, Direction.Up), []);
|
||||
assert.deepEqual(grid.getNeighborViews(view4, Direction.Right), []);
|
||||
assert.deepEqual(grid.getNeighborViews(view4, Direction.Down), [view3]);
|
||||
assert.deepEqual(grid.getNeighborViews(view4, Direction.Left), [view2]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view4, Direction.Up), []);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view4, Direction.Right), []);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view4, Direction.Down), [view3]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view4, Direction.Left), [view2]);
|
||||
});
|
||||
|
||||
test('getNeighborViews should only return immediate neighbors', function () {
|
||||
@ -458,7 +458,7 @@ suite('Grid', function () {
|
||||
const view4 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view4, Sizing.Distribute, view2, Direction.Right);
|
||||
|
||||
assert.deepEqual(grid.getNeighborViews(view1, Direction.Right), [view2, view3]);
|
||||
assert.deepStrictEqual(grid.getNeighborViews(view1, Direction.Right), [view2, view3]);
|
||||
});
|
||||
});
|
||||
|
||||
@ -524,7 +524,7 @@ suite('SerializableGrid', function () {
|
||||
grid.layout(800, 600);
|
||||
|
||||
const actual = grid.serialize();
|
||||
assert.deepEqual(actual, {
|
||||
assert.deepStrictEqual(actual, {
|
||||
orientation: 0,
|
||||
width: 800,
|
||||
height: 600,
|
||||
@ -562,7 +562,7 @@ suite('SerializableGrid', function () {
|
||||
const view5 = new TestSerializableView('view5', 50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view5, 100, view1, Direction.Down);
|
||||
|
||||
assert.deepEqual(grid.serialize(), {
|
||||
assert.deepStrictEqual(grid.serialize(), {
|
||||
orientation: 0,
|
||||
width: 800,
|
||||
height: 600,
|
||||
@ -611,7 +611,7 @@ suite('SerializableGrid', function () {
|
||||
const grid2 = SerializableGrid.deserialize(json, deserializer);
|
||||
grid2.layout(800, 600);
|
||||
|
||||
assert.deepEqual(nodesToNames(grid2.getViews()), ['view1']);
|
||||
assert.deepStrictEqual(nodesToNames(grid2.getViews()), ['view1']);
|
||||
});
|
||||
|
||||
test('deserialize simple layout', function () {
|
||||
@ -645,15 +645,15 @@ suite('SerializableGrid', function () {
|
||||
const view4Copy = deserializer.getView('view4');
|
||||
const view5Copy = deserializer.getView('view5');
|
||||
|
||||
assert.deepEqual(nodesToArrays(grid2.getViews()), [[view4Copy, view2Copy], [[view1Copy, view5Copy], view3Copy]]);
|
||||
assert.deepStrictEqual(nodesToArrays(grid2.getViews()), [[view4Copy, view2Copy], [[view1Copy, view5Copy], view3Copy]]);
|
||||
|
||||
grid2.layout(800, 600);
|
||||
|
||||
assert.deepEqual(view1Copy.size, [600, 300]);
|
||||
assert.deepEqual(view2Copy.size, [600, 200]);
|
||||
assert.deepEqual(view3Copy.size, [200, 400]);
|
||||
assert.deepEqual(view4Copy.size, [200, 200]);
|
||||
assert.deepEqual(view5Copy.size, [600, 100]);
|
||||
assert.deepStrictEqual(view1Copy.size, [600, 300]);
|
||||
assert.deepStrictEqual(view2Copy.size, [600, 200]);
|
||||
assert.deepStrictEqual(view3Copy.size, [200, 400]);
|
||||
assert.deepStrictEqual(view4Copy.size, [200, 200]);
|
||||
assert.deepStrictEqual(view5Copy.size, [600, 100]);
|
||||
});
|
||||
|
||||
test('deserialize simple layout with scaling', function () {
|
||||
@ -688,11 +688,11 @@ suite('SerializableGrid', function () {
|
||||
const view5Copy = deserializer.getView('view5');
|
||||
|
||||
grid2.layout(400, 800); // [/2, *4/3]
|
||||
assert.deepEqual(view1Copy.size, [300, 400]);
|
||||
assert.deepEqual(view2Copy.size, [300, 267]);
|
||||
assert.deepEqual(view3Copy.size, [100, 533]);
|
||||
assert.deepEqual(view4Copy.size, [100, 267]);
|
||||
assert.deepEqual(view5Copy.size, [300, 133]);
|
||||
assert.deepStrictEqual(view1Copy.size, [300, 400]);
|
||||
assert.deepStrictEqual(view2Copy.size, [300, 267]);
|
||||
assert.deepStrictEqual(view3Copy.size, [100, 533]);
|
||||
assert.deepStrictEqual(view4Copy.size, [100, 267]);
|
||||
assert.deepStrictEqual(view5Copy.size, [300, 133]);
|
||||
});
|
||||
|
||||
test('deserialize 4 view layout (ben issue #2)', function () {
|
||||
@ -723,10 +723,10 @@ suite('SerializableGrid', function () {
|
||||
|
||||
grid2.layout(800, 600);
|
||||
|
||||
assert.deepEqual(view1Copy.size, [800, 300]);
|
||||
assert.deepEqual(view2Copy.size, [800, 150]);
|
||||
assert.deepEqual(view3Copy.size, [400, 150]);
|
||||
assert.deepEqual(view4Copy.size, [400, 150]);
|
||||
assert.deepStrictEqual(view1Copy.size, [800, 300]);
|
||||
assert.deepStrictEqual(view2Copy.size, [800, 150]);
|
||||
assert.deepStrictEqual(view3Copy.size, [400, 150]);
|
||||
assert.deepStrictEqual(view4Copy.size, [400, 150]);
|
||||
});
|
||||
|
||||
test('deserialize 2 view layout (ben issue #3)', function () {
|
||||
@ -750,8 +750,8 @@ suite('SerializableGrid', function () {
|
||||
|
||||
grid2.layout(800, 600);
|
||||
|
||||
assert.deepEqual(view1Copy.size, [400, 600]);
|
||||
assert.deepEqual(view2Copy.size, [400, 600]);
|
||||
assert.deepStrictEqual(view1Copy.size, [400, 600]);
|
||||
assert.deepStrictEqual(view2Copy.size, [400, 600]);
|
||||
});
|
||||
|
||||
test('deserialize simple view layout #50609', function () {
|
||||
@ -780,21 +780,21 @@ suite('SerializableGrid', function () {
|
||||
|
||||
grid2.layout(800, 600);
|
||||
|
||||
assert.deepEqual(view2Copy.size, [800, 300]);
|
||||
assert.deepEqual(view3Copy.size, [800, 300]);
|
||||
assert.deepStrictEqual(view2Copy.size, [800, 300]);
|
||||
assert.deepStrictEqual(view3Copy.size, [800, 300]);
|
||||
});
|
||||
|
||||
test('sanitizeGridNodeDescriptor', () => {
|
||||
const nodeDescriptor = { groups: [{ size: 0.2 }, { size: 0.2 }, { size: 0.6, groups: [{}, {}] }] };
|
||||
const nodeDescriptorCopy = deepClone<GridNodeDescriptor>(nodeDescriptor);
|
||||
sanitizeGridNodeDescriptor(nodeDescriptorCopy, true);
|
||||
assert.deepEqual(nodeDescriptorCopy, { groups: [{ size: 0.2 }, { size: 0.2 }, { size: 0.6, groups: [{ size: 0.5 }, { size: 0.5 }] }] });
|
||||
assert.deepStrictEqual(nodeDescriptorCopy, { groups: [{ size: 0.2 }, { size: 0.2 }, { size: 0.6, groups: [{ size: 0.5 }, { size: 0.5 }] }] });
|
||||
});
|
||||
|
||||
test('createSerializedGrid', () => {
|
||||
const gridDescriptor = { orientation: Orientation.VERTICAL, groups: [{ size: 0.2 }, { size: 0.2 }, { size: 0.6, groups: [{}, {}] }] };
|
||||
const serializedGrid = createSerializedGrid(gridDescriptor);
|
||||
assert.deepEqual(serializedGrid, {
|
||||
assert.deepStrictEqual(serializedGrid, {
|
||||
root: {
|
||||
type: 'branch',
|
||||
size: undefined,
|
||||
@ -836,7 +836,7 @@ suite('SerializableGrid', function () {
|
||||
};
|
||||
|
||||
const grid = SerializableGrid.deserialize(serializedGrid, deserializer);
|
||||
assert.equal(views.length, 3);
|
||||
assert.strictEqual(views.length, 3);
|
||||
|
||||
// should not throw
|
||||
grid.removeView(views[2]);
|
||||
@ -860,40 +860,40 @@ suite('SerializableGrid', function () {
|
||||
const view5 = new TestSerializableView('view5', 50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view5, 100, view1, Direction.Down);
|
||||
|
||||
assert.deepEqual(view1.size, [600, 300]);
|
||||
assert.deepEqual(view2.size, [600, 200]);
|
||||
assert.deepEqual(view3.size, [200, 400]);
|
||||
assert.deepEqual(view4.size, [200, 200]);
|
||||
assert.deepEqual(view5.size, [600, 100]);
|
||||
assert.deepStrictEqual(view1.size, [600, 300]);
|
||||
assert.deepStrictEqual(view2.size, [600, 200]);
|
||||
assert.deepStrictEqual(view3.size, [200, 400]);
|
||||
assert.deepStrictEqual(view4.size, [200, 200]);
|
||||
assert.deepStrictEqual(view5.size, [600, 100]);
|
||||
|
||||
grid.setViewVisible(view5, false);
|
||||
|
||||
assert.deepEqual(view1.size, [600, 400]);
|
||||
assert.deepEqual(view2.size, [600, 200]);
|
||||
assert.deepEqual(view3.size, [200, 400]);
|
||||
assert.deepEqual(view4.size, [200, 200]);
|
||||
assert.deepEqual(view5.size, [600, 0]);
|
||||
assert.deepStrictEqual(view1.size, [600, 400]);
|
||||
assert.deepStrictEqual(view2.size, [600, 200]);
|
||||
assert.deepStrictEqual(view3.size, [200, 400]);
|
||||
assert.deepStrictEqual(view4.size, [200, 200]);
|
||||
assert.deepStrictEqual(view5.size, [600, 0]);
|
||||
|
||||
grid.setViewVisible(view5, true);
|
||||
|
||||
assert.deepEqual(view1.size, [600, 300]);
|
||||
assert.deepEqual(view2.size, [600, 200]);
|
||||
assert.deepEqual(view3.size, [200, 400]);
|
||||
assert.deepEqual(view4.size, [200, 200]);
|
||||
assert.deepEqual(view5.size, [600, 100]);
|
||||
assert.deepStrictEqual(view1.size, [600, 300]);
|
||||
assert.deepStrictEqual(view2.size, [600, 200]);
|
||||
assert.deepStrictEqual(view3.size, [200, 400]);
|
||||
assert.deepStrictEqual(view4.size, [200, 200]);
|
||||
assert.deepStrictEqual(view5.size, [600, 100]);
|
||||
|
||||
grid.setViewVisible(view5, false);
|
||||
|
||||
assert.deepEqual(view1.size, [600, 400]);
|
||||
assert.deepEqual(view2.size, [600, 200]);
|
||||
assert.deepEqual(view3.size, [200, 400]);
|
||||
assert.deepEqual(view4.size, [200, 200]);
|
||||
assert.deepEqual(view5.size, [600, 0]);
|
||||
assert.deepStrictEqual(view1.size, [600, 400]);
|
||||
assert.deepStrictEqual(view2.size, [600, 200]);
|
||||
assert.deepStrictEqual(view3.size, [200, 400]);
|
||||
assert.deepStrictEqual(view4.size, [200, 200]);
|
||||
assert.deepStrictEqual(view5.size, [600, 0]);
|
||||
|
||||
grid.setViewVisible(view5, false);
|
||||
|
||||
const json = grid.serialize();
|
||||
assert.deepEqual(json, {
|
||||
assert.deepStrictEqual(json, {
|
||||
orientation: 0,
|
||||
width: 800,
|
||||
height: 600,
|
||||
@ -939,34 +939,34 @@ suite('SerializableGrid', function () {
|
||||
const view4Copy = deserializer.getView('view4');
|
||||
const view5Copy = deserializer.getView('view5');
|
||||
|
||||
assert.deepEqual(nodesToArrays(grid2.getViews()), [[view4Copy, view2Copy], [[view1Copy, view5Copy], view3Copy]]);
|
||||
assert.deepStrictEqual(nodesToArrays(grid2.getViews()), [[view4Copy, view2Copy], [[view1Copy, view5Copy], view3Copy]]);
|
||||
|
||||
grid2.layout(800, 600);
|
||||
assert.deepEqual(view1Copy.size, [600, 400]);
|
||||
assert.deepEqual(view2Copy.size, [600, 200]);
|
||||
assert.deepEqual(view3Copy.size, [200, 400]);
|
||||
assert.deepEqual(view4Copy.size, [200, 200]);
|
||||
assert.deepEqual(view5Copy.size, [600, 0]);
|
||||
assert.deepStrictEqual(view1Copy.size, [600, 400]);
|
||||
assert.deepStrictEqual(view2Copy.size, [600, 200]);
|
||||
assert.deepStrictEqual(view3Copy.size, [200, 400]);
|
||||
assert.deepStrictEqual(view4Copy.size, [200, 200]);
|
||||
assert.deepStrictEqual(view5Copy.size, [600, 0]);
|
||||
|
||||
assert.deepEqual(grid2.isViewVisible(view1Copy), true);
|
||||
assert.deepEqual(grid2.isViewVisible(view2Copy), true);
|
||||
assert.deepEqual(grid2.isViewVisible(view3Copy), true);
|
||||
assert.deepEqual(grid2.isViewVisible(view4Copy), true);
|
||||
assert.deepEqual(grid2.isViewVisible(view5Copy), false);
|
||||
assert.deepStrictEqual(grid2.isViewVisible(view1Copy), true);
|
||||
assert.deepStrictEqual(grid2.isViewVisible(view2Copy), true);
|
||||
assert.deepStrictEqual(grid2.isViewVisible(view3Copy), true);
|
||||
assert.deepStrictEqual(grid2.isViewVisible(view4Copy), true);
|
||||
assert.deepStrictEqual(grid2.isViewVisible(view5Copy), false);
|
||||
|
||||
grid2.setViewVisible(view5Copy, true);
|
||||
|
||||
assert.deepEqual(view1Copy.size, [600, 300]);
|
||||
assert.deepEqual(view2Copy.size, [600, 200]);
|
||||
assert.deepEqual(view3Copy.size, [200, 400]);
|
||||
assert.deepEqual(view4Copy.size, [200, 200]);
|
||||
assert.deepEqual(view5Copy.size, [600, 100]);
|
||||
assert.deepStrictEqual(view1Copy.size, [600, 300]);
|
||||
assert.deepStrictEqual(view2Copy.size, [600, 200]);
|
||||
assert.deepStrictEqual(view3Copy.size, [200, 400]);
|
||||
assert.deepStrictEqual(view4Copy.size, [200, 200]);
|
||||
assert.deepStrictEqual(view5Copy.size, [600, 100]);
|
||||
|
||||
assert.deepEqual(grid2.isViewVisible(view1Copy), true);
|
||||
assert.deepEqual(grid2.isViewVisible(view2Copy), true);
|
||||
assert.deepEqual(grid2.isViewVisible(view3Copy), true);
|
||||
assert.deepEqual(grid2.isViewVisible(view4Copy), true);
|
||||
assert.deepEqual(grid2.isViewVisible(view5Copy), true);
|
||||
assert.deepStrictEqual(grid2.isViewVisible(view1Copy), true);
|
||||
assert.deepStrictEqual(grid2.isViewVisible(view2Copy), true);
|
||||
assert.deepStrictEqual(grid2.isViewVisible(view3Copy), true);
|
||||
assert.deepStrictEqual(grid2.isViewVisible(view4Copy), true);
|
||||
assert.deepStrictEqual(grid2.isViewVisible(view5Copy), true);
|
||||
});
|
||||
|
||||
test('serialize should store visibility and previous size even for first leaf', function () {
|
||||
@ -987,22 +987,22 @@ suite('SerializableGrid', function () {
|
||||
const view5 = new TestSerializableView('view5', 50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
|
||||
grid.addView(view5, 100, view1, Direction.Down);
|
||||
|
||||
assert.deepEqual(view1.size, [600, 300]);
|
||||
assert.deepEqual(view2.size, [600, 200]);
|
||||
assert.deepEqual(view3.size, [200, 400]);
|
||||
assert.deepEqual(view4.size, [200, 200]);
|
||||
assert.deepEqual(view5.size, [600, 100]);
|
||||
assert.deepStrictEqual(view1.size, [600, 300]);
|
||||
assert.deepStrictEqual(view2.size, [600, 200]);
|
||||
assert.deepStrictEqual(view3.size, [200, 400]);
|
||||
assert.deepStrictEqual(view4.size, [200, 200]);
|
||||
assert.deepStrictEqual(view5.size, [600, 100]);
|
||||
|
||||
grid.setViewVisible(view4, false);
|
||||
|
||||
assert.deepEqual(view1.size, [600, 300]);
|
||||
assert.deepEqual(view2.size, [800, 200]);
|
||||
assert.deepEqual(view3.size, [200, 400]);
|
||||
assert.deepEqual(view4.size, [0, 200]);
|
||||
assert.deepEqual(view5.size, [600, 100]);
|
||||
assert.deepStrictEqual(view1.size, [600, 300]);
|
||||
assert.deepStrictEqual(view2.size, [800, 200]);
|
||||
assert.deepStrictEqual(view3.size, [200, 400]);
|
||||
assert.deepStrictEqual(view4.size, [0, 200]);
|
||||
assert.deepStrictEqual(view5.size, [600, 100]);
|
||||
|
||||
const json = grid.serialize();
|
||||
assert.deepEqual(json, {
|
||||
assert.deepStrictEqual(json, {
|
||||
orientation: 0,
|
||||
width: 800,
|
||||
height: 600,
|
||||
@ -1048,33 +1048,33 @@ suite('SerializableGrid', function () {
|
||||
const view4Copy = deserializer.getView('view4');
|
||||
const view5Copy = deserializer.getView('view5');
|
||||
|
||||
assert.deepEqual(nodesToArrays(grid2.getViews()), [[view4Copy, view2Copy], [[view1Copy, view5Copy], view3Copy]]);
|
||||
assert.deepStrictEqual(nodesToArrays(grid2.getViews()), [[view4Copy, view2Copy], [[view1Copy, view5Copy], view3Copy]]);
|
||||
|
||||
grid2.layout(800, 600);
|
||||
assert.deepEqual(view1Copy.size, [600, 300]);
|
||||
assert.deepEqual(view2Copy.size, [800, 200]);
|
||||
assert.deepEqual(view3Copy.size, [200, 400]);
|
||||
assert.deepEqual(view4Copy.size, [0, 200]);
|
||||
assert.deepEqual(view5Copy.size, [600, 100]);
|
||||
assert.deepStrictEqual(view1Copy.size, [600, 300]);
|
||||
assert.deepStrictEqual(view2Copy.size, [800, 200]);
|
||||
assert.deepStrictEqual(view3Copy.size, [200, 400]);
|
||||
assert.deepStrictEqual(view4Copy.size, [0, 200]);
|
||||
assert.deepStrictEqual(view5Copy.size, [600, 100]);
|
||||
|
||||
assert.deepEqual(grid2.isViewVisible(view1Copy), true);
|
||||
assert.deepEqual(grid2.isViewVisible(view2Copy), true);
|
||||
assert.deepEqual(grid2.isViewVisible(view3Copy), true);
|
||||
assert.deepEqual(grid2.isViewVisible(view4Copy), false);
|
||||
assert.deepEqual(grid2.isViewVisible(view5Copy), true);
|
||||
assert.deepStrictEqual(grid2.isViewVisible(view1Copy), true);
|
||||
assert.deepStrictEqual(grid2.isViewVisible(view2Copy), true);
|
||||
assert.deepStrictEqual(grid2.isViewVisible(view3Copy), true);
|
||||
assert.deepStrictEqual(grid2.isViewVisible(view4Copy), false);
|
||||
assert.deepStrictEqual(grid2.isViewVisible(view5Copy), true);
|
||||
|
||||
grid2.setViewVisible(view4Copy, true);
|
||||
|
||||
assert.deepEqual(view1Copy.size, [600, 300]);
|
||||
assert.deepEqual(view2Copy.size, [600, 200]);
|
||||
assert.deepEqual(view3Copy.size, [200, 400]);
|
||||
assert.deepEqual(view4Copy.size, [200, 200]);
|
||||
assert.deepEqual(view5Copy.size, [600, 100]);
|
||||
assert.deepStrictEqual(view1Copy.size, [600, 300]);
|
||||
assert.deepStrictEqual(view2Copy.size, [600, 200]);
|
||||
assert.deepStrictEqual(view3Copy.size, [200, 400]);
|
||||
assert.deepStrictEqual(view4Copy.size, [200, 200]);
|
||||
assert.deepStrictEqual(view5Copy.size, [600, 100]);
|
||||
|
||||
assert.deepEqual(grid2.isViewVisible(view1Copy), true);
|
||||
assert.deepEqual(grid2.isViewVisible(view2Copy), true);
|
||||
assert.deepEqual(grid2.isViewVisible(view3Copy), true);
|
||||
assert.deepEqual(grid2.isViewVisible(view4Copy), true);
|
||||
assert.deepEqual(grid2.isViewVisible(view5Copy), true);
|
||||
assert.deepStrictEqual(grid2.isViewVisible(view1Copy), true);
|
||||
assert.deepStrictEqual(grid2.isViewVisible(view2Copy), true);
|
||||
assert.deepStrictEqual(grid2.isViewVisible(view3Copy), true);
|
||||
assert.deepStrictEqual(grid2.isViewVisible(view4Copy), true);
|
||||
assert.deepStrictEqual(grid2.isViewVisible(view5Copy), true);
|
||||
});
|
||||
});
|
||||
|
@ -22,7 +22,7 @@ suite('Gridview', function () {
|
||||
});
|
||||
|
||||
test('empty gridview is empty', function () {
|
||||
assert.deepEqual(nodesToArrays(gridview.getView()), []);
|
||||
assert.deepStrictEqual(nodesToArrays(gridview.getView()), []);
|
||||
gridview.dispose();
|
||||
});
|
||||
|
||||
@ -43,7 +43,7 @@ suite('Gridview', function () {
|
||||
gridview.addView(views[1], 200, [1]);
|
||||
gridview.addView(views[2], 200, [2]);
|
||||
|
||||
assert.deepEqual(nodesToArrays(gridview.getView()), views);
|
||||
assert.deepStrictEqual(nodesToArrays(gridview.getView()), views);
|
||||
|
||||
gridview.dispose();
|
||||
});
|
||||
@ -62,7 +62,7 @@ suite('Gridview', function () {
|
||||
gridview.addView((views[1] as TestView[])[0] as IView, 200, [1]);
|
||||
gridview.addView((views[1] as TestView[])[1] as IView, 200, [1, 1]);
|
||||
|
||||
assert.deepEqual(nodesToArrays(gridview.getView()), views);
|
||||
assert.deepStrictEqual(nodesToArrays(gridview.getView()), views);
|
||||
|
||||
gridview.dispose();
|
||||
});
|
||||
@ -71,35 +71,35 @@ suite('Gridview', function () {
|
||||
|
||||
const view1 = new TestView(20, 20, 20, 20);
|
||||
gridview.addView(view1 as IView, 200, [0]);
|
||||
assert.deepEqual(nodesToArrays(gridview.getView()), [view1]);
|
||||
assert.deepStrictEqual(nodesToArrays(gridview.getView()), [view1]);
|
||||
|
||||
const view2 = new TestView(20, 20, 20, 20);
|
||||
gridview.addView(view2 as IView, 200, [1]);
|
||||
assert.deepEqual(nodesToArrays(gridview.getView()), [view1, view2]);
|
||||
assert.deepStrictEqual(nodesToArrays(gridview.getView()), [view1, view2]);
|
||||
|
||||
const view3 = new TestView(20, 20, 20, 20);
|
||||
gridview.addView(view3 as IView, 200, [1, 0]);
|
||||
assert.deepEqual(nodesToArrays(gridview.getView()), [view1, [view3, view2]]);
|
||||
assert.deepStrictEqual(nodesToArrays(gridview.getView()), [view1, [view3, view2]]);
|
||||
|
||||
const view4 = new TestView(20, 20, 20, 20);
|
||||
gridview.addView(view4 as IView, 200, [1, 0, 0]);
|
||||
assert.deepEqual(nodesToArrays(gridview.getView()), [view1, [[view4, view3], view2]]);
|
||||
assert.deepStrictEqual(nodesToArrays(gridview.getView()), [view1, [[view4, view3], view2]]);
|
||||
|
||||
const view5 = new TestView(20, 20, 20, 20);
|
||||
gridview.addView(view5 as IView, 200, [1, 0]);
|
||||
assert.deepEqual(nodesToArrays(gridview.getView()), [view1, [view5, [view4, view3], view2]]);
|
||||
assert.deepStrictEqual(nodesToArrays(gridview.getView()), [view1, [view5, [view4, view3], view2]]);
|
||||
|
||||
const view6 = new TestView(20, 20, 20, 20);
|
||||
gridview.addView(view6 as IView, 200, [2]);
|
||||
assert.deepEqual(nodesToArrays(gridview.getView()), [view1, [view5, [view4, view3], view2], view6]);
|
||||
assert.deepStrictEqual(nodesToArrays(gridview.getView()), [view1, [view5, [view4, view3], view2], view6]);
|
||||
|
||||
const view7 = new TestView(20, 20, 20, 20);
|
||||
gridview.addView(view7 as IView, 200, [1, 1]);
|
||||
assert.deepEqual(nodesToArrays(gridview.getView()), [view1, [view5, view7, [view4, view3], view2], view6]);
|
||||
assert.deepStrictEqual(nodesToArrays(gridview.getView()), [view1, [view5, view7, [view4, view3], view2], view6]);
|
||||
|
||||
const view8 = new TestView(20, 20, 20, 20);
|
||||
gridview.addView(view8 as IView, 200, [1, 1, 0]);
|
||||
assert.deepEqual(nodesToArrays(gridview.getView()), [view1, [view5, [view8, view7], [view4, view3], view2], view6]);
|
||||
assert.deepStrictEqual(nodesToArrays(gridview.getView()), [view1, [view5, [view8, view7], [view4, view3], view2], view6]);
|
||||
|
||||
gridview.dispose();
|
||||
});
|
||||
@ -109,48 +109,48 @@ suite('Gridview', function () {
|
||||
|
||||
const view1 = new TestView(50, Number.POSITIVE_INFINITY, 50, Number.POSITIVE_INFINITY);
|
||||
gridview.addView(view1, 200, [0]);
|
||||
assert.deepEqual(view1.size, [800, 600]);
|
||||
assert.deepEqual(gridview.getViewSize([0]), { width: 800, height: 600 });
|
||||
assert.deepStrictEqual(view1.size, [800, 600]);
|
||||
assert.deepStrictEqual(gridview.getViewSize([0]), { width: 800, height: 600 });
|
||||
|
||||
const view2 = new TestView(50, Number.POSITIVE_INFINITY, 50, Number.POSITIVE_INFINITY);
|
||||
gridview.addView(view2, 200, [0]);
|
||||
assert.deepEqual(view1.size, [800, 400]);
|
||||
assert.deepEqual(gridview.getViewSize([1]), { width: 800, height: 400 });
|
||||
assert.deepEqual(view2.size, [800, 200]);
|
||||
assert.deepEqual(gridview.getViewSize([0]), { width: 800, height: 200 });
|
||||
assert.deepStrictEqual(view1.size, [800, 400]);
|
||||
assert.deepStrictEqual(gridview.getViewSize([1]), { width: 800, height: 400 });
|
||||
assert.deepStrictEqual(view2.size, [800, 200]);
|
||||
assert.deepStrictEqual(gridview.getViewSize([0]), { width: 800, height: 200 });
|
||||
|
||||
const view3 = new TestView(50, Number.POSITIVE_INFINITY, 50, Number.POSITIVE_INFINITY);
|
||||
gridview.addView(view3, 200, [1, 1]);
|
||||
assert.deepEqual(view1.size, [600, 400]);
|
||||
assert.deepEqual(gridview.getViewSize([1, 0]), { width: 600, height: 400 });
|
||||
assert.deepEqual(view2.size, [800, 200]);
|
||||
assert.deepEqual(gridview.getViewSize([0]), { width: 800, height: 200 });
|
||||
assert.deepEqual(view3.size, [200, 400]);
|
||||
assert.deepEqual(gridview.getViewSize([1, 1]), { width: 200, height: 400 });
|
||||
assert.deepStrictEqual(view1.size, [600, 400]);
|
||||
assert.deepStrictEqual(gridview.getViewSize([1, 0]), { width: 600, height: 400 });
|
||||
assert.deepStrictEqual(view2.size, [800, 200]);
|
||||
assert.deepStrictEqual(gridview.getViewSize([0]), { width: 800, height: 200 });
|
||||
assert.deepStrictEqual(view3.size, [200, 400]);
|
||||
assert.deepStrictEqual(gridview.getViewSize([1, 1]), { width: 200, height: 400 });
|
||||
|
||||
const view4 = new TestView(50, Number.POSITIVE_INFINITY, 50, Number.POSITIVE_INFINITY);
|
||||
gridview.addView(view4, 200, [0, 0]);
|
||||
assert.deepEqual(view1.size, [600, 400]);
|
||||
assert.deepEqual(gridview.getViewSize([1, 0]), { width: 600, height: 400 });
|
||||
assert.deepEqual(view2.size, [600, 200]);
|
||||
assert.deepEqual(gridview.getViewSize([0, 1]), { width: 600, height: 200 });
|
||||
assert.deepEqual(view3.size, [200, 400]);
|
||||
assert.deepEqual(gridview.getViewSize([1, 1]), { width: 200, height: 400 });
|
||||
assert.deepEqual(view4.size, [200, 200]);
|
||||
assert.deepEqual(gridview.getViewSize([0, 0]), { width: 200, height: 200 });
|
||||
assert.deepStrictEqual(view1.size, [600, 400]);
|
||||
assert.deepStrictEqual(gridview.getViewSize([1, 0]), { width: 600, height: 400 });
|
||||
assert.deepStrictEqual(view2.size, [600, 200]);
|
||||
assert.deepStrictEqual(gridview.getViewSize([0, 1]), { width: 600, height: 200 });
|
||||
assert.deepStrictEqual(view3.size, [200, 400]);
|
||||
assert.deepStrictEqual(gridview.getViewSize([1, 1]), { width: 200, height: 400 });
|
||||
assert.deepStrictEqual(view4.size, [200, 200]);
|
||||
assert.deepStrictEqual(gridview.getViewSize([0, 0]), { width: 200, height: 200 });
|
||||
|
||||
const view5 = new TestView(50, Number.POSITIVE_INFINITY, 50, Number.POSITIVE_INFINITY);
|
||||
gridview.addView(view5, 100, [1, 0, 1]);
|
||||
assert.deepEqual(view1.size, [600, 300]);
|
||||
assert.deepEqual(gridview.getViewSize([1, 0, 0]), { width: 600, height: 300 });
|
||||
assert.deepEqual(view2.size, [600, 200]);
|
||||
assert.deepEqual(gridview.getViewSize([0, 1]), { width: 600, height: 200 });
|
||||
assert.deepEqual(view3.size, [200, 400]);
|
||||
assert.deepEqual(gridview.getViewSize([1, 1]), { width: 200, height: 400 });
|
||||
assert.deepEqual(view4.size, [200, 200]);
|
||||
assert.deepEqual(gridview.getViewSize([0, 0]), { width: 200, height: 200 });
|
||||
assert.deepEqual(view5.size, [600, 100]);
|
||||
assert.deepEqual(gridview.getViewSize([1, 0, 1]), { width: 600, height: 100 });
|
||||
assert.deepStrictEqual(view1.size, [600, 300]);
|
||||
assert.deepStrictEqual(gridview.getViewSize([1, 0, 0]), { width: 600, height: 300 });
|
||||
assert.deepStrictEqual(view2.size, [600, 200]);
|
||||
assert.deepStrictEqual(gridview.getViewSize([0, 1]), { width: 600, height: 200 });
|
||||
assert.deepStrictEqual(view3.size, [200, 400]);
|
||||
assert.deepStrictEqual(gridview.getViewSize([1, 1]), { width: 200, height: 400 });
|
||||
assert.deepStrictEqual(view4.size, [200, 200]);
|
||||
assert.deepStrictEqual(gridview.getViewSize([0, 0]), { width: 200, height: 200 });
|
||||
assert.deepStrictEqual(view5.size, [600, 100]);
|
||||
assert.deepStrictEqual(gridview.getViewSize([1, 0, 1]), { width: 600, height: 100 });
|
||||
});
|
||||
|
||||
test('simple layout with automatic size distribution', function () {
|
||||
@ -158,34 +158,34 @@ suite('Gridview', function () {
|
||||
|
||||
const view1 = new TestView(50, Number.POSITIVE_INFINITY, 50, Number.POSITIVE_INFINITY);
|
||||
gridview.addView(view1, Sizing.Distribute, [0]);
|
||||
assert.deepEqual(view1.size, [800, 600]);
|
||||
assert.deepEqual(gridview.getViewSize([0]), { width: 800, height: 600 });
|
||||
assert.deepStrictEqual(view1.size, [800, 600]);
|
||||
assert.deepStrictEqual(gridview.getViewSize([0]), { width: 800, height: 600 });
|
||||
|
||||
const view2 = new TestView(50, Number.POSITIVE_INFINITY, 50, Number.POSITIVE_INFINITY);
|
||||
gridview.addView(view2, Sizing.Distribute, [0]);
|
||||
assert.deepEqual(view1.size, [800, 300]);
|
||||
assert.deepEqual(view2.size, [800, 300]);
|
||||
assert.deepStrictEqual(view1.size, [800, 300]);
|
||||
assert.deepStrictEqual(view2.size, [800, 300]);
|
||||
|
||||
const view3 = new TestView(50, Number.POSITIVE_INFINITY, 50, Number.POSITIVE_INFINITY);
|
||||
gridview.addView(view3, Sizing.Distribute, [1, 1]);
|
||||
assert.deepEqual(view1.size, [400, 300]);
|
||||
assert.deepEqual(view2.size, [800, 300]);
|
||||
assert.deepEqual(view3.size, [400, 300]);
|
||||
assert.deepStrictEqual(view1.size, [400, 300]);
|
||||
assert.deepStrictEqual(view2.size, [800, 300]);
|
||||
assert.deepStrictEqual(view3.size, [400, 300]);
|
||||
|
||||
const view4 = new TestView(50, Number.POSITIVE_INFINITY, 50, Number.POSITIVE_INFINITY);
|
||||
gridview.addView(view4, Sizing.Distribute, [0, 0]);
|
||||
assert.deepEqual(view1.size, [400, 300]);
|
||||
assert.deepEqual(view2.size, [400, 300]);
|
||||
assert.deepEqual(view3.size, [400, 300]);
|
||||
assert.deepEqual(view4.size, [400, 300]);
|
||||
assert.deepStrictEqual(view1.size, [400, 300]);
|
||||
assert.deepStrictEqual(view2.size, [400, 300]);
|
||||
assert.deepStrictEqual(view3.size, [400, 300]);
|
||||
assert.deepStrictEqual(view4.size, [400, 300]);
|
||||
|
||||
const view5 = new TestView(50, Number.POSITIVE_INFINITY, 50, Number.POSITIVE_INFINITY);
|
||||
gridview.addView(view5, Sizing.Distribute, [1, 0, 1]);
|
||||
assert.deepEqual(view1.size, [400, 150]);
|
||||
assert.deepEqual(view2.size, [400, 300]);
|
||||
assert.deepEqual(view3.size, [400, 300]);
|
||||
assert.deepEqual(view4.size, [400, 300]);
|
||||
assert.deepEqual(view5.size, [400, 150]);
|
||||
assert.deepStrictEqual(view1.size, [400, 150]);
|
||||
assert.deepStrictEqual(view2.size, [400, 300]);
|
||||
assert.deepStrictEqual(view3.size, [400, 300]);
|
||||
assert.deepStrictEqual(view4.size, [400, 300]);
|
||||
assert.deepStrictEqual(view5.size, [400, 150]);
|
||||
});
|
||||
|
||||
test('addviews before layout call 1', function () {
|
||||
@ -201,9 +201,9 @@ suite('Gridview', function () {
|
||||
|
||||
gridview.layout(800, 600);
|
||||
|
||||
assert.deepEqual(view1.size, [400, 300]);
|
||||
assert.deepEqual(view2.size, [800, 300]);
|
||||
assert.deepEqual(view3.size, [400, 300]);
|
||||
assert.deepStrictEqual(view1.size, [400, 300]);
|
||||
assert.deepStrictEqual(view2.size, [800, 300]);
|
||||
assert.deepStrictEqual(view3.size, [400, 300]);
|
||||
});
|
||||
|
||||
test('addviews before layout call 2', function () {
|
||||
@ -218,8 +218,8 @@ suite('Gridview', function () {
|
||||
|
||||
gridview.layout(800, 600);
|
||||
|
||||
assert.deepEqual(view1.size, [800, 300]);
|
||||
assert.deepEqual(view2.size, [400, 300]);
|
||||
assert.deepEqual(view3.size, [400, 300]);
|
||||
assert.deepStrictEqual(view1.size, [800, 300]);
|
||||
assert.deepStrictEqual(view2.size, [400, 300]);
|
||||
assert.deepStrictEqual(view3.size, [400, 300]);
|
||||
});
|
||||
});
|
||||
|
@ -31,10 +31,10 @@ suite('ListView', function () {
|
||||
const listView = new ListView<number>(element, delegate, [renderer]);
|
||||
listView.layout(200);
|
||||
|
||||
assert.equal(templatesCount, 0, 'no templates have been allocated');
|
||||
assert.strictEqual(templatesCount, 0, 'no templates have been allocated');
|
||||
listView.splice(0, 0, range(100));
|
||||
assert.equal(templatesCount, 10, 'some templates have been allocated');
|
||||
assert.strictEqual(templatesCount, 10, 'some templates have been allocated');
|
||||
listView.dispose();
|
||||
assert.equal(templatesCount, 0, 'all templates have been disposed');
|
||||
assert.strictEqual(templatesCount, 0, 'all templates have been disposed');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -15,24 +15,24 @@ suite('RangeMap', () => {
|
||||
});
|
||||
|
||||
test('intersection', () => {
|
||||
assert.deepEqual(Range.intersect({ start: 0, end: 0 }, { start: 0, end: 0 }), { start: 0, end: 0 });
|
||||
assert.deepEqual(Range.intersect({ start: 0, end: 0 }, { start: 5, end: 5 }), { start: 0, end: 0 });
|
||||
assert.deepEqual(Range.intersect({ start: 0, end: 1 }, { start: 5, end: 6 }), { start: 0, end: 0 });
|
||||
assert.deepEqual(Range.intersect({ start: 5, end: 6 }, { start: 0, end: 1 }), { start: 0, end: 0 });
|
||||
assert.deepEqual(Range.intersect({ start: 0, end: 5 }, { start: 2, end: 2 }), { start: 0, end: 0 });
|
||||
assert.deepEqual(Range.intersect({ start: 0, end: 1 }, { start: 0, end: 1 }), { start: 0, end: 1 });
|
||||
assert.deepEqual(Range.intersect({ start: 0, end: 10 }, { start: 0, end: 5 }), { start: 0, end: 5 });
|
||||
assert.deepEqual(Range.intersect({ start: 0, end: 5 }, { start: 0, end: 10 }), { start: 0, end: 5 });
|
||||
assert.deepEqual(Range.intersect({ start: 0, end: 10 }, { start: 5, end: 10 }), { start: 5, end: 10 });
|
||||
assert.deepEqual(Range.intersect({ start: 5, end: 10 }, { start: 0, end: 10 }), { start: 5, end: 10 });
|
||||
assert.deepEqual(Range.intersect({ start: 0, end: 10 }, { start: 2, end: 8 }), { start: 2, end: 8 });
|
||||
assert.deepEqual(Range.intersect({ start: 2, end: 8 }, { start: 0, end: 10 }), { start: 2, end: 8 });
|
||||
assert.deepEqual(Range.intersect({ start: 0, end: 10 }, { start: 5, end: 15 }), { start: 5, end: 10 });
|
||||
assert.deepEqual(Range.intersect({ start: 5, end: 15 }, { start: 0, end: 10 }), { start: 5, end: 10 });
|
||||
assert.deepStrictEqual(Range.intersect({ start: 0, end: 0 }, { start: 0, end: 0 }), { start: 0, end: 0 });
|
||||
assert.deepStrictEqual(Range.intersect({ start: 0, end: 0 }, { start: 5, end: 5 }), { start: 0, end: 0 });
|
||||
assert.deepStrictEqual(Range.intersect({ start: 0, end: 1 }, { start: 5, end: 6 }), { start: 0, end: 0 });
|
||||
assert.deepStrictEqual(Range.intersect({ start: 5, end: 6 }, { start: 0, end: 1 }), { start: 0, end: 0 });
|
||||
assert.deepStrictEqual(Range.intersect({ start: 0, end: 5 }, { start: 2, end: 2 }), { start: 0, end: 0 });
|
||||
assert.deepStrictEqual(Range.intersect({ start: 0, end: 1 }, { start: 0, end: 1 }), { start: 0, end: 1 });
|
||||
assert.deepStrictEqual(Range.intersect({ start: 0, end: 10 }, { start: 0, end: 5 }), { start: 0, end: 5 });
|
||||
assert.deepStrictEqual(Range.intersect({ start: 0, end: 5 }, { start: 0, end: 10 }), { start: 0, end: 5 });
|
||||
assert.deepStrictEqual(Range.intersect({ start: 0, end: 10 }, { start: 5, end: 10 }), { start: 5, end: 10 });
|
||||
assert.deepStrictEqual(Range.intersect({ start: 5, end: 10 }, { start: 0, end: 10 }), { start: 5, end: 10 });
|
||||
assert.deepStrictEqual(Range.intersect({ start: 0, end: 10 }, { start: 2, end: 8 }), { start: 2, end: 8 });
|
||||
assert.deepStrictEqual(Range.intersect({ start: 2, end: 8 }, { start: 0, end: 10 }), { start: 2, end: 8 });
|
||||
assert.deepStrictEqual(Range.intersect({ start: 0, end: 10 }, { start: 5, end: 15 }), { start: 5, end: 10 });
|
||||
assert.deepStrictEqual(Range.intersect({ start: 5, end: 15 }, { start: 0, end: 10 }), { start: 5, end: 10 });
|
||||
});
|
||||
|
||||
test('multiIntersect', () => {
|
||||
assert.deepEqual(
|
||||
assert.deepStrictEqual(
|
||||
groupIntersect(
|
||||
{ start: 0, end: 0 },
|
||||
[{ range: { start: 0, end: 10 }, size: 1 }]
|
||||
@ -40,7 +40,7 @@ suite('RangeMap', () => {
|
||||
[]
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
assert.deepStrictEqual(
|
||||
groupIntersect(
|
||||
{ start: 10, end: 20 },
|
||||
[{ range: { start: 0, end: 10 }, size: 1 }]
|
||||
@ -48,7 +48,7 @@ suite('RangeMap', () => {
|
||||
[]
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
assert.deepStrictEqual(
|
||||
groupIntersect(
|
||||
{ start: 2, end: 8 },
|
||||
[{ range: { start: 0, end: 10 }, size: 1 }]
|
||||
@ -56,7 +56,7 @@ suite('RangeMap', () => {
|
||||
[{ range: { start: 2, end: 8 }, size: 1 }]
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
assert.deepStrictEqual(
|
||||
groupIntersect(
|
||||
{ start: 2, end: 8 },
|
||||
[{ range: { start: 0, end: 10 }, size: 1 }, { range: { start: 10, end: 20 }, size: 5 }]
|
||||
@ -64,7 +64,7 @@ suite('RangeMap', () => {
|
||||
[{ range: { start: 2, end: 8 }, size: 1 }]
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
assert.deepStrictEqual(
|
||||
groupIntersect(
|
||||
{ start: 12, end: 18 },
|
||||
[{ range: { start: 0, end: 10 }, size: 1 }, { range: { start: 10, end: 20 }, size: 5 }]
|
||||
@ -72,7 +72,7 @@ suite('RangeMap', () => {
|
||||
[{ range: { start: 12, end: 18 }, size: 5 }]
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
assert.deepStrictEqual(
|
||||
groupIntersect(
|
||||
{ start: 2, end: 18 },
|
||||
[{ range: { start: 0, end: 10 }, size: 1 }, { range: { start: 10, end: 20 }, size: 5 }]
|
||||
@ -80,7 +80,7 @@ suite('RangeMap', () => {
|
||||
[{ range: { start: 2, end: 10 }, size: 1 }, { range: { start: 10, end: 18 }, size: 5 }]
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
assert.deepStrictEqual(
|
||||
groupIntersect(
|
||||
{ start: 2, end: 28 },
|
||||
[{ range: { start: 0, end: 10 }, size: 1 }, { range: { start: 10, end: 20 }, size: 5 }, { range: { start: 20, end: 30 }, size: 10 }]
|
||||
@ -90,14 +90,14 @@ suite('RangeMap', () => {
|
||||
});
|
||||
|
||||
test('consolidate', () => {
|
||||
assert.deepEqual(consolidate([]), []);
|
||||
assert.deepStrictEqual(consolidate([]), []);
|
||||
|
||||
assert.deepEqual(
|
||||
assert.deepStrictEqual(
|
||||
consolidate([{ range: { start: 0, end: 10 }, size: 1 }]),
|
||||
[{ range: { start: 0, end: 10 }, size: 1 }]
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
assert.deepStrictEqual(
|
||||
consolidate([
|
||||
{ range: { start: 0, end: 10 }, size: 1 },
|
||||
{ range: { start: 10, end: 20 }, size: 1 }
|
||||
@ -105,7 +105,7 @@ suite('RangeMap', () => {
|
||||
[{ range: { start: 0, end: 20 }, size: 1 }]
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
assert.deepStrictEqual(
|
||||
consolidate([
|
||||
{ range: { start: 0, end: 10 }, size: 1 },
|
||||
{ range: { start: 10, end: 20 }, size: 1 },
|
||||
@ -114,7 +114,7 @@ suite('RangeMap', () => {
|
||||
[{ range: { start: 0, end: 100 }, size: 1 }]
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
assert.deepStrictEqual(
|
||||
consolidate([
|
||||
{ range: { start: 0, end: 10 }, size: 1 },
|
||||
{ range: { start: 10, end: 20 }, size: 5 },
|
||||
@ -127,7 +127,7 @@ suite('RangeMap', () => {
|
||||
]
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
assert.deepStrictEqual(
|
||||
consolidate([
|
||||
{ range: { start: 0, end: 10 }, size: 1 },
|
||||
{ range: { start: 10, end: 20 }, size: 2 },
|
||||
@ -141,8 +141,8 @@ suite('RangeMap', () => {
|
||||
});
|
||||
|
||||
test('empty', () => {
|
||||
assert.equal(rangeMap.size, 0);
|
||||
assert.equal(rangeMap.count, 0);
|
||||
assert.strictEqual(rangeMap.size, 0);
|
||||
assert.strictEqual(rangeMap.count, 0);
|
||||
});
|
||||
|
||||
const one = { size: 1 };
|
||||
@ -153,44 +153,44 @@ suite('RangeMap', () => {
|
||||
|
||||
test('length & count', () => {
|
||||
rangeMap.splice(0, 0, [one]);
|
||||
assert.equal(rangeMap.size, 1);
|
||||
assert.equal(rangeMap.count, 1);
|
||||
assert.strictEqual(rangeMap.size, 1);
|
||||
assert.strictEqual(rangeMap.count, 1);
|
||||
});
|
||||
|
||||
test('length & count #2', () => {
|
||||
rangeMap.splice(0, 0, [one, one, one, one, one]);
|
||||
assert.equal(rangeMap.size, 5);
|
||||
assert.equal(rangeMap.count, 5);
|
||||
assert.strictEqual(rangeMap.size, 5);
|
||||
assert.strictEqual(rangeMap.count, 5);
|
||||
});
|
||||
|
||||
test('length & count #3', () => {
|
||||
rangeMap.splice(0, 0, [five]);
|
||||
assert.equal(rangeMap.size, 5);
|
||||
assert.equal(rangeMap.count, 1);
|
||||
assert.strictEqual(rangeMap.size, 5);
|
||||
assert.strictEqual(rangeMap.count, 1);
|
||||
});
|
||||
|
||||
test('length & count #4', () => {
|
||||
rangeMap.splice(0, 0, [five, five, five, five, five]);
|
||||
assert.equal(rangeMap.size, 25);
|
||||
assert.equal(rangeMap.count, 5);
|
||||
assert.strictEqual(rangeMap.size, 25);
|
||||
assert.strictEqual(rangeMap.count, 5);
|
||||
});
|
||||
|
||||
test('insert', () => {
|
||||
rangeMap.splice(0, 0, [five, five, five, five, five]);
|
||||
assert.equal(rangeMap.size, 25);
|
||||
assert.equal(rangeMap.count, 5);
|
||||
assert.strictEqual(rangeMap.size, 25);
|
||||
assert.strictEqual(rangeMap.count, 5);
|
||||
|
||||
rangeMap.splice(0, 0, [five, five, five, five, five]);
|
||||
assert.equal(rangeMap.size, 50);
|
||||
assert.equal(rangeMap.count, 10);
|
||||
assert.strictEqual(rangeMap.size, 50);
|
||||
assert.strictEqual(rangeMap.count, 10);
|
||||
|
||||
rangeMap.splice(5, 0, [ten, ten]);
|
||||
assert.equal(rangeMap.size, 70);
|
||||
assert.equal(rangeMap.count, 12);
|
||||
assert.strictEqual(rangeMap.size, 70);
|
||||
assert.strictEqual(rangeMap.count, 12);
|
||||
|
||||
rangeMap.splice(12, 0, [{ size: 200 }]);
|
||||
assert.equal(rangeMap.size, 270);
|
||||
assert.equal(rangeMap.count, 13);
|
||||
assert.strictEqual(rangeMap.size, 270);
|
||||
assert.strictEqual(rangeMap.count, 13);
|
||||
});
|
||||
|
||||
test('delete', () => {
|
||||
@ -198,45 +198,45 @@ suite('RangeMap', () => {
|
||||
five, five, five, five, five,
|
||||
five, five, five, five, five,
|
||||
five, five, five, five, five]);
|
||||
assert.equal(rangeMap.size, 100);
|
||||
assert.equal(rangeMap.count, 20);
|
||||
assert.strictEqual(rangeMap.size, 100);
|
||||
assert.strictEqual(rangeMap.count, 20);
|
||||
|
||||
rangeMap.splice(10, 5);
|
||||
assert.equal(rangeMap.size, 75);
|
||||
assert.equal(rangeMap.count, 15);
|
||||
assert.strictEqual(rangeMap.size, 75);
|
||||
assert.strictEqual(rangeMap.count, 15);
|
||||
|
||||
rangeMap.splice(0, 1);
|
||||
assert.equal(rangeMap.size, 70);
|
||||
assert.equal(rangeMap.count, 14);
|
||||
assert.strictEqual(rangeMap.size, 70);
|
||||
assert.strictEqual(rangeMap.count, 14);
|
||||
|
||||
rangeMap.splice(1, 13);
|
||||
assert.equal(rangeMap.size, 5);
|
||||
assert.equal(rangeMap.count, 1);
|
||||
assert.strictEqual(rangeMap.size, 5);
|
||||
assert.strictEqual(rangeMap.count, 1);
|
||||
|
||||
rangeMap.splice(1, 1);
|
||||
assert.equal(rangeMap.size, 5);
|
||||
assert.equal(rangeMap.count, 1);
|
||||
assert.strictEqual(rangeMap.size, 5);
|
||||
assert.strictEqual(rangeMap.count, 1);
|
||||
});
|
||||
|
||||
test('insert & delete', () => {
|
||||
assert.equal(rangeMap.size, 0);
|
||||
assert.equal(rangeMap.count, 0);
|
||||
assert.strictEqual(rangeMap.size, 0);
|
||||
assert.strictEqual(rangeMap.count, 0);
|
||||
|
||||
rangeMap.splice(0, 0, [one]);
|
||||
assert.equal(rangeMap.size, 1);
|
||||
assert.equal(rangeMap.count, 1);
|
||||
assert.strictEqual(rangeMap.size, 1);
|
||||
assert.strictEqual(rangeMap.count, 1);
|
||||
|
||||
rangeMap.splice(0, 1);
|
||||
assert.equal(rangeMap.size, 0);
|
||||
assert.equal(rangeMap.count, 0);
|
||||
assert.strictEqual(rangeMap.size, 0);
|
||||
assert.strictEqual(rangeMap.count, 0);
|
||||
});
|
||||
|
||||
test('insert & delete #2', () => {
|
||||
rangeMap.splice(0, 0, [one, one, one, one, one,
|
||||
one, one, one, one, one]);
|
||||
rangeMap.splice(2, 6);
|
||||
assert.equal(rangeMap.count, 4);
|
||||
assert.equal(rangeMap.size, 4);
|
||||
assert.strictEqual(rangeMap.count, 4);
|
||||
assert.strictEqual(rangeMap.size, 4);
|
||||
});
|
||||
|
||||
test('insert & delete #3', () => {
|
||||
@ -245,8 +245,8 @@ suite('RangeMap', () => {
|
||||
two, two, two, two, two,
|
||||
two, two, two, two, two]);
|
||||
rangeMap.splice(8, 4);
|
||||
assert.equal(rangeMap.count, 16);
|
||||
assert.equal(rangeMap.size, 24);
|
||||
assert.strictEqual(rangeMap.count, 16);
|
||||
assert.strictEqual(rangeMap.size, 24);
|
||||
});
|
||||
|
||||
test('insert & delete #3', () => {
|
||||
@ -255,91 +255,91 @@ suite('RangeMap', () => {
|
||||
two, two, two, two, two,
|
||||
two, two, two, two, two]);
|
||||
rangeMap.splice(5, 0, [three, three, three, three, three]);
|
||||
assert.equal(rangeMap.count, 25);
|
||||
assert.equal(rangeMap.size, 45);
|
||||
assert.strictEqual(rangeMap.count, 25);
|
||||
assert.strictEqual(rangeMap.size, 45);
|
||||
|
||||
rangeMap.splice(4, 7);
|
||||
assert.equal(rangeMap.count, 18);
|
||||
assert.equal(rangeMap.size, 28);
|
||||
assert.strictEqual(rangeMap.count, 18);
|
||||
assert.strictEqual(rangeMap.size, 28);
|
||||
});
|
||||
|
||||
suite('indexAt, positionAt', () => {
|
||||
test('empty', () => {
|
||||
assert.equal(rangeMap.indexAt(0), 0);
|
||||
assert.equal(rangeMap.indexAt(10), 0);
|
||||
assert.equal(rangeMap.indexAt(-1), -1);
|
||||
assert.equal(rangeMap.positionAt(0), -1);
|
||||
assert.equal(rangeMap.positionAt(10), -1);
|
||||
assert.equal(rangeMap.positionAt(-1), -1);
|
||||
assert.strictEqual(rangeMap.indexAt(0), 0);
|
||||
assert.strictEqual(rangeMap.indexAt(10), 0);
|
||||
assert.strictEqual(rangeMap.indexAt(-1), -1);
|
||||
assert.strictEqual(rangeMap.positionAt(0), -1);
|
||||
assert.strictEqual(rangeMap.positionAt(10), -1);
|
||||
assert.strictEqual(rangeMap.positionAt(-1), -1);
|
||||
});
|
||||
|
||||
test('simple', () => {
|
||||
rangeMap.splice(0, 0, [one]);
|
||||
assert.equal(rangeMap.indexAt(0), 0);
|
||||
assert.equal(rangeMap.indexAt(1), 1);
|
||||
assert.equal(rangeMap.positionAt(0), 0);
|
||||
assert.equal(rangeMap.positionAt(1), -1);
|
||||
assert.strictEqual(rangeMap.indexAt(0), 0);
|
||||
assert.strictEqual(rangeMap.indexAt(1), 1);
|
||||
assert.strictEqual(rangeMap.positionAt(0), 0);
|
||||
assert.strictEqual(rangeMap.positionAt(1), -1);
|
||||
});
|
||||
|
||||
test('simple #2', () => {
|
||||
rangeMap.splice(0, 0, [ten]);
|
||||
assert.equal(rangeMap.indexAt(0), 0);
|
||||
assert.equal(rangeMap.indexAt(5), 0);
|
||||
assert.equal(rangeMap.indexAt(9), 0);
|
||||
assert.equal(rangeMap.indexAt(10), 1);
|
||||
assert.equal(rangeMap.positionAt(0), 0);
|
||||
assert.equal(rangeMap.positionAt(1), -1);
|
||||
assert.strictEqual(rangeMap.indexAt(0), 0);
|
||||
assert.strictEqual(rangeMap.indexAt(5), 0);
|
||||
assert.strictEqual(rangeMap.indexAt(9), 0);
|
||||
assert.strictEqual(rangeMap.indexAt(10), 1);
|
||||
assert.strictEqual(rangeMap.positionAt(0), 0);
|
||||
assert.strictEqual(rangeMap.positionAt(1), -1);
|
||||
});
|
||||
|
||||
test('insert', () => {
|
||||
rangeMap.splice(0, 0, [one, one, one, one, one, one, one, one, one, one]);
|
||||
assert.equal(rangeMap.indexAt(0), 0);
|
||||
assert.equal(rangeMap.indexAt(1), 1);
|
||||
assert.equal(rangeMap.indexAt(5), 5);
|
||||
assert.equal(rangeMap.indexAt(9), 9);
|
||||
assert.equal(rangeMap.indexAt(10), 10);
|
||||
assert.equal(rangeMap.indexAt(11), 10);
|
||||
assert.strictEqual(rangeMap.indexAt(0), 0);
|
||||
assert.strictEqual(rangeMap.indexAt(1), 1);
|
||||
assert.strictEqual(rangeMap.indexAt(5), 5);
|
||||
assert.strictEqual(rangeMap.indexAt(9), 9);
|
||||
assert.strictEqual(rangeMap.indexAt(10), 10);
|
||||
assert.strictEqual(rangeMap.indexAt(11), 10);
|
||||
|
||||
rangeMap.splice(10, 0, [one, one, one, one, one, one, one, one, one, one]);
|
||||
assert.equal(rangeMap.indexAt(10), 10);
|
||||
assert.equal(rangeMap.indexAt(19), 19);
|
||||
assert.equal(rangeMap.indexAt(20), 20);
|
||||
assert.equal(rangeMap.indexAt(21), 20);
|
||||
assert.equal(rangeMap.positionAt(0), 0);
|
||||
assert.equal(rangeMap.positionAt(1), 1);
|
||||
assert.equal(rangeMap.positionAt(19), 19);
|
||||
assert.equal(rangeMap.positionAt(20), -1);
|
||||
assert.strictEqual(rangeMap.indexAt(10), 10);
|
||||
assert.strictEqual(rangeMap.indexAt(19), 19);
|
||||
assert.strictEqual(rangeMap.indexAt(20), 20);
|
||||
assert.strictEqual(rangeMap.indexAt(21), 20);
|
||||
assert.strictEqual(rangeMap.positionAt(0), 0);
|
||||
assert.strictEqual(rangeMap.positionAt(1), 1);
|
||||
assert.strictEqual(rangeMap.positionAt(19), 19);
|
||||
assert.strictEqual(rangeMap.positionAt(20), -1);
|
||||
});
|
||||
|
||||
test('delete', () => {
|
||||
rangeMap.splice(0, 0, [one, one, one, one, one, one, one, one, one, one]);
|
||||
rangeMap.splice(2, 6);
|
||||
|
||||
assert.equal(rangeMap.indexAt(0), 0);
|
||||
assert.equal(rangeMap.indexAt(1), 1);
|
||||
assert.equal(rangeMap.indexAt(3), 3);
|
||||
assert.equal(rangeMap.indexAt(4), 4);
|
||||
assert.equal(rangeMap.indexAt(5), 4);
|
||||
assert.equal(rangeMap.positionAt(0), 0);
|
||||
assert.equal(rangeMap.positionAt(1), 1);
|
||||
assert.equal(rangeMap.positionAt(3), 3);
|
||||
assert.equal(rangeMap.positionAt(4), -1);
|
||||
assert.strictEqual(rangeMap.indexAt(0), 0);
|
||||
assert.strictEqual(rangeMap.indexAt(1), 1);
|
||||
assert.strictEqual(rangeMap.indexAt(3), 3);
|
||||
assert.strictEqual(rangeMap.indexAt(4), 4);
|
||||
assert.strictEqual(rangeMap.indexAt(5), 4);
|
||||
assert.strictEqual(rangeMap.positionAt(0), 0);
|
||||
assert.strictEqual(rangeMap.positionAt(1), 1);
|
||||
assert.strictEqual(rangeMap.positionAt(3), 3);
|
||||
assert.strictEqual(rangeMap.positionAt(4), -1);
|
||||
});
|
||||
|
||||
test('delete #2', () => {
|
||||
rangeMap.splice(0, 0, [ten, ten, ten, ten, ten, ten, ten, ten, ten, ten]);
|
||||
rangeMap.splice(2, 6);
|
||||
|
||||
assert.equal(rangeMap.indexAt(0), 0);
|
||||
assert.equal(rangeMap.indexAt(1), 0);
|
||||
assert.equal(rangeMap.indexAt(30), 3);
|
||||
assert.equal(rangeMap.indexAt(40), 4);
|
||||
assert.equal(rangeMap.indexAt(50), 4);
|
||||
assert.equal(rangeMap.positionAt(0), 0);
|
||||
assert.equal(rangeMap.positionAt(1), 10);
|
||||
assert.equal(rangeMap.positionAt(2), 20);
|
||||
assert.equal(rangeMap.positionAt(3), 30);
|
||||
assert.equal(rangeMap.positionAt(4), -1);
|
||||
assert.strictEqual(rangeMap.indexAt(0), 0);
|
||||
assert.strictEqual(rangeMap.indexAt(1), 0);
|
||||
assert.strictEqual(rangeMap.indexAt(30), 3);
|
||||
assert.strictEqual(rangeMap.indexAt(40), 4);
|
||||
assert.strictEqual(rangeMap.indexAt(50), 4);
|
||||
assert.strictEqual(rangeMap.positionAt(0), 0);
|
||||
assert.strictEqual(rangeMap.positionAt(1), 10);
|
||||
assert.strictEqual(rangeMap.positionAt(2), 20);
|
||||
assert.strictEqual(rangeMap.positionAt(3), 30);
|
||||
assert.strictEqual(rangeMap.positionAt(4), -1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -56,7 +56,7 @@ function validateMenuBarItem(menubar: MenuBar, menubarContainer: HTMLElement, la
|
||||
assert(titleDiv !== null, `Title div not found for ${readableLabel} button.`);
|
||||
|
||||
const mnem = getMnemonicFromTitleDiv(titleDiv!);
|
||||
assert.equal(mnem, mnemonic, 'Mnemonic not correct');
|
||||
assert.strictEqual(mnem, mnemonic, 'Mnemonic not correct');
|
||||
}
|
||||
|
||||
suite('Menubar', () => {
|
||||
@ -78,4 +78,4 @@ suite('Menubar', () => {
|
||||
test('Chinese File menu renders mnemonics', function () {
|
||||
validateMenuBarItem(menubar, container, '文件(&F)', '文件', 'F');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -77,7 +77,7 @@ suite('Splitview', () => {
|
||||
|
||||
test('empty splitview has empty DOM', () => {
|
||||
const splitview = new SplitView(container);
|
||||
assert.equal(container.firstElementChild!.firstElementChild!.childElementCount, 0, 'split view should be empty');
|
||||
assert.strictEqual(container.firstElementChild!.firstElementChild!.childElementCount, 0, 'split view should be empty');
|
||||
splitview.dispose();
|
||||
});
|
||||
|
||||
@ -92,34 +92,34 @@ suite('Splitview', () => {
|
||||
splitview.addView(view3, 20);
|
||||
|
||||
let viewQuery = container.querySelectorAll('.monaco-split-view2 > .monaco-scrollable-element > .split-view-container > .split-view-view');
|
||||
assert.equal(viewQuery.length, 3, 'split view should have 3 views');
|
||||
assert.strictEqual(viewQuery.length, 3, 'split view should have 3 views');
|
||||
|
||||
let sashQuery = container.querySelectorAll('.monaco-split-view2 > .sash-container > .monaco-sash');
|
||||
assert.equal(sashQuery.length, 2, 'split view should have 2 sashes');
|
||||
assert.strictEqual(sashQuery.length, 2, 'split view should have 2 sashes');
|
||||
|
||||
splitview.removeView(2);
|
||||
|
||||
viewQuery = container.querySelectorAll('.monaco-split-view2 > .monaco-scrollable-element > .split-view-container > .split-view-view');
|
||||
assert.equal(viewQuery.length, 2, 'split view should have 2 views');
|
||||
assert.strictEqual(viewQuery.length, 2, 'split view should have 2 views');
|
||||
|
||||
sashQuery = container.querySelectorAll('.monaco-split-view2 > .sash-container > .monaco-sash');
|
||||
assert.equal(sashQuery.length, 1, 'split view should have 1 sash');
|
||||
assert.strictEqual(sashQuery.length, 1, 'split view should have 1 sash');
|
||||
|
||||
splitview.removeView(0);
|
||||
|
||||
viewQuery = container.querySelectorAll('.monaco-split-view2 > .monaco-scrollable-element > .split-view-container > .split-view-view');
|
||||
assert.equal(viewQuery.length, 1, 'split view should have 1 view');
|
||||
assert.strictEqual(viewQuery.length, 1, 'split view should have 1 view');
|
||||
|
||||
sashQuery = container.querySelectorAll('.monaco-split-view2 > .sash-container > .monaco-sash');
|
||||
assert.equal(sashQuery.length, 0, 'split view should have no sashes');
|
||||
assert.strictEqual(sashQuery.length, 0, 'split view should have no sashes');
|
||||
|
||||
splitview.removeView(0);
|
||||
|
||||
viewQuery = container.querySelectorAll('.monaco-split-view2 > .monaco-scrollable-element > .split-view-container > .split-view-view');
|
||||
assert.equal(viewQuery.length, 0, 'split view should have no views');
|
||||
assert.strictEqual(viewQuery.length, 0, 'split view should have no views');
|
||||
|
||||
sashQuery = container.querySelectorAll('.monaco-split-view2 > .sash-container > .monaco-sash');
|
||||
assert.equal(sashQuery.length, 0, 'split view should have no sashes');
|
||||
assert.strictEqual(sashQuery.length, 0, 'split view should have no sashes');
|
||||
|
||||
splitview.dispose();
|
||||
view1.dispose();
|
||||
@ -138,7 +138,7 @@ suite('Splitview', () => {
|
||||
|
||||
splitview.addView(view, 20);
|
||||
|
||||
assert.equal(view.size, 20, 'view has right size');
|
||||
assert.strictEqual(view.size, 20, 'view has right size');
|
||||
assert(didLayout, 'layout is called');
|
||||
assert(didLayout, 'render is called');
|
||||
|
||||
@ -154,22 +154,22 @@ suite('Splitview', () => {
|
||||
splitview.layout(200);
|
||||
|
||||
splitview.addView(view, 20);
|
||||
assert.equal(view.size, 200, 'view is stretched');
|
||||
assert.strictEqual(view.size, 200, 'view is stretched');
|
||||
|
||||
splitview.layout(200);
|
||||
assert.equal(view.size, 200, 'view stayed the same');
|
||||
assert.strictEqual(view.size, 200, 'view stayed the same');
|
||||
|
||||
splitview.layout(100);
|
||||
assert.equal(view.size, 100, 'view is collapsed');
|
||||
assert.strictEqual(view.size, 100, 'view is collapsed');
|
||||
|
||||
splitview.layout(20);
|
||||
assert.equal(view.size, 20, 'view is collapsed');
|
||||
assert.strictEqual(view.size, 20, 'view is collapsed');
|
||||
|
||||
splitview.layout(10);
|
||||
assert.equal(view.size, 20, 'view is clamped');
|
||||
assert.strictEqual(view.size, 20, 'view is clamped');
|
||||
|
||||
splitview.layout(200);
|
||||
assert.equal(view.size, 200, 'view is stretched');
|
||||
assert.strictEqual(view.size, 200, 'view is stretched');
|
||||
|
||||
splitview.dispose();
|
||||
view.dispose();
|
||||
@ -186,27 +186,27 @@ suite('Splitview', () => {
|
||||
splitview.addView(view2, 20);
|
||||
splitview.addView(view3, 20);
|
||||
|
||||
assert.equal(view1.size, 160, 'view1 is stretched');
|
||||
assert.equal(view2.size, 20, 'view2 size is 20');
|
||||
assert.equal(view3.size, 20, 'view3 size is 20');
|
||||
assert.strictEqual(view1.size, 160, 'view1 is stretched');
|
||||
assert.strictEqual(view2.size, 20, 'view2 size is 20');
|
||||
assert.strictEqual(view3.size, 20, 'view3 size is 20');
|
||||
|
||||
splitview.resizeView(1, 40);
|
||||
|
||||
assert.equal(view1.size, 140, 'view1 is collapsed');
|
||||
assert.equal(view2.size, 40, 'view2 is stretched');
|
||||
assert.equal(view3.size, 20, 'view3 stays the same');
|
||||
assert.strictEqual(view1.size, 140, 'view1 is collapsed');
|
||||
assert.strictEqual(view2.size, 40, 'view2 is stretched');
|
||||
assert.strictEqual(view3.size, 20, 'view3 stays the same');
|
||||
|
||||
splitview.resizeView(0, 70);
|
||||
|
||||
assert.equal(view1.size, 70, 'view1 is collapsed');
|
||||
assert.equal(view2.size, 40, 'view2 stays the same');
|
||||
assert.equal(view3.size, 90, 'view3 is stretched');
|
||||
assert.strictEqual(view1.size, 70, 'view1 is collapsed');
|
||||
assert.strictEqual(view2.size, 40, 'view2 stays the same');
|
||||
assert.strictEqual(view3.size, 90, 'view3 is stretched');
|
||||
|
||||
splitview.resizeView(2, 40);
|
||||
|
||||
assert.equal(view1.size, 70, 'view1 stays the same');
|
||||
assert.equal(view2.size, 90, 'view2 is collapsed');
|
||||
assert.equal(view3.size, 40, 'view3 is stretched');
|
||||
assert.strictEqual(view1.size, 70, 'view1 stays the same');
|
||||
assert.strictEqual(view2.size, 90, 'view2 is collapsed');
|
||||
assert.strictEqual(view3.size, 40, 'view3 is stretched');
|
||||
|
||||
splitview.dispose();
|
||||
view3.dispose();
|
||||
@ -225,34 +225,34 @@ suite('Splitview', () => {
|
||||
splitview.addView(view2, 20);
|
||||
splitview.addView(view3, 20);
|
||||
|
||||
assert.equal(view1.size, 160, 'view1 is stretched');
|
||||
assert.equal(view2.size, 20, 'view2 size is 20');
|
||||
assert.equal(view3.size, 20, 'view3 size is 20');
|
||||
assert.strictEqual(view1.size, 160, 'view1 is stretched');
|
||||
assert.strictEqual(view2.size, 20, 'view2 size is 20');
|
||||
assert.strictEqual(view3.size, 20, 'view3 size is 20');
|
||||
|
||||
view1.maximumSize = 20;
|
||||
|
||||
assert.equal(view1.size, 20, 'view1 is collapsed');
|
||||
assert.equal(view2.size, 20, 'view2 stays the same');
|
||||
assert.equal(view3.size, 160, 'view3 is stretched');
|
||||
assert.strictEqual(view1.size, 20, 'view1 is collapsed');
|
||||
assert.strictEqual(view2.size, 20, 'view2 stays the same');
|
||||
assert.strictEqual(view3.size, 160, 'view3 is stretched');
|
||||
|
||||
view3.maximumSize = 40;
|
||||
|
||||
assert.equal(view1.size, 20, 'view1 stays the same');
|
||||
assert.equal(view2.size, 140, 'view2 is stretched');
|
||||
assert.equal(view3.size, 40, 'view3 is collapsed');
|
||||
assert.strictEqual(view1.size, 20, 'view1 stays the same');
|
||||
assert.strictEqual(view2.size, 140, 'view2 is stretched');
|
||||
assert.strictEqual(view3.size, 40, 'view3 is collapsed');
|
||||
|
||||
view2.maximumSize = 200;
|
||||
|
||||
assert.equal(view1.size, 20, 'view1 stays the same');
|
||||
assert.equal(view2.size, 140, 'view2 stays the same');
|
||||
assert.equal(view3.size, 40, 'view3 stays the same');
|
||||
assert.strictEqual(view1.size, 20, 'view1 stays the same');
|
||||
assert.strictEqual(view2.size, 140, 'view2 stays the same');
|
||||
assert.strictEqual(view3.size, 40, 'view3 stays the same');
|
||||
|
||||
view3.maximumSize = Number.POSITIVE_INFINITY;
|
||||
view3.minimumSize = 100;
|
||||
|
||||
assert.equal(view1.size, 20, 'view1 is collapsed');
|
||||
assert.equal(view2.size, 80, 'view2 is collapsed');
|
||||
assert.equal(view3.size, 100, 'view3 is stretched');
|
||||
assert.strictEqual(view1.size, 20, 'view1 is collapsed');
|
||||
assert.strictEqual(view2.size, 80, 'view2 is collapsed');
|
||||
assert.strictEqual(view3.size, 100, 'view3 is stretched');
|
||||
|
||||
splitview.dispose();
|
||||
view3.dispose();
|
||||
@ -272,41 +272,41 @@ suite('Splitview', () => {
|
||||
splitview.addView(view3, Sizing.Distribute);
|
||||
|
||||
let sashes = getSashes(splitview);
|
||||
assert.equal(sashes.length, 2, 'there are two sashes');
|
||||
assert.equal(sashes[0].state, SashState.Enabled, 'first sash is enabled');
|
||||
assert.equal(sashes[1].state, SashState.Enabled, 'second sash is enabled');
|
||||
assert.strictEqual(sashes.length, 2, 'there are two sashes');
|
||||
assert.strictEqual(sashes[0].state, SashState.Enabled, 'first sash is enabled');
|
||||
assert.strictEqual(sashes[1].state, SashState.Enabled, 'second sash is enabled');
|
||||
|
||||
splitview.layout(60);
|
||||
assert.equal(sashes[0].state, SashState.Disabled, 'first sash is disabled');
|
||||
assert.equal(sashes[1].state, SashState.Disabled, 'second sash is disabled');
|
||||
assert.strictEqual(sashes[0].state, SashState.Disabled, 'first sash is disabled');
|
||||
assert.strictEqual(sashes[1].state, SashState.Disabled, 'second sash is disabled');
|
||||
|
||||
splitview.layout(20);
|
||||
assert.equal(sashes[0].state, SashState.Disabled, 'first sash is disabled');
|
||||
assert.equal(sashes[1].state, SashState.Disabled, 'second sash is disabled');
|
||||
assert.strictEqual(sashes[0].state, SashState.Disabled, 'first sash is disabled');
|
||||
assert.strictEqual(sashes[1].state, SashState.Disabled, 'second sash is disabled');
|
||||
|
||||
splitview.layout(200);
|
||||
assert.equal(sashes[0].state, SashState.Enabled, 'first sash is enabled');
|
||||
assert.equal(sashes[1].state, SashState.Enabled, 'second sash is enabled');
|
||||
assert.strictEqual(sashes[0].state, SashState.Enabled, 'first sash is enabled');
|
||||
assert.strictEqual(sashes[1].state, SashState.Enabled, 'second sash is enabled');
|
||||
|
||||
view1.maximumSize = 20;
|
||||
assert.equal(sashes[0].state, SashState.Disabled, 'first sash is disabled');
|
||||
assert.equal(sashes[1].state, SashState.Enabled, 'second sash is enabled');
|
||||
assert.strictEqual(sashes[0].state, SashState.Disabled, 'first sash is disabled');
|
||||
assert.strictEqual(sashes[1].state, SashState.Enabled, 'second sash is enabled');
|
||||
|
||||
view2.maximumSize = 20;
|
||||
assert.equal(sashes[0].state, SashState.Disabled, 'first sash is disabled');
|
||||
assert.equal(sashes[1].state, SashState.Disabled, 'second sash is disabled');
|
||||
assert.strictEqual(sashes[0].state, SashState.Disabled, 'first sash is disabled');
|
||||
assert.strictEqual(sashes[1].state, SashState.Disabled, 'second sash is disabled');
|
||||
|
||||
view1.maximumSize = 300;
|
||||
assert.equal(sashes[0].state, SashState.Minimum, 'first sash is enabled');
|
||||
assert.equal(sashes[1].state, SashState.Minimum, 'second sash is enabled');
|
||||
assert.strictEqual(sashes[0].state, SashState.Minimum, 'first sash is enabled');
|
||||
assert.strictEqual(sashes[1].state, SashState.Minimum, 'second sash is enabled');
|
||||
|
||||
view2.maximumSize = 200;
|
||||
assert.equal(sashes[0].state, SashState.Minimum, 'first sash is enabled');
|
||||
assert.equal(sashes[1].state, SashState.Minimum, 'second sash is enabled');
|
||||
assert.strictEqual(sashes[0].state, SashState.Minimum, 'first sash is enabled');
|
||||
assert.strictEqual(sashes[1].state, SashState.Minimum, 'second sash is enabled');
|
||||
|
||||
splitview.resizeView(0, 40);
|
||||
assert.equal(sashes[0].state, SashState.Enabled, 'first sash is enabled');
|
||||
assert.equal(sashes[1].state, SashState.Enabled, 'second sash is enabled');
|
||||
assert.strictEqual(sashes[0].state, SashState.Enabled, 'first sash is enabled');
|
||||
assert.strictEqual(sashes[1].state, SashState.Enabled, 'second sash is enabled');
|
||||
|
||||
splitview.dispose();
|
||||
view3.dispose();
|
||||
@ -322,7 +322,7 @@ suite('Splitview', () => {
|
||||
splitview.layout(986);
|
||||
|
||||
splitview.addView(view1, 142, 0);
|
||||
assert.equal(view1.size, 986, 'first view is stretched');
|
||||
assert.strictEqual(view1.size, 986, 'first view is stretched');
|
||||
|
||||
view2.onDidGetElement(() => {
|
||||
assert.throws(() => splitview.resizeView(1, 922));
|
||||
@ -330,13 +330,13 @@ suite('Splitview', () => {
|
||||
});
|
||||
|
||||
splitview.addView(view2, 66, 0);
|
||||
assert.equal(view2.size, 66, 'second view is fixed');
|
||||
assert.equal(view1.size, 986 - 66, 'first view is collapsed');
|
||||
assert.strictEqual(view2.size, 66, 'second view is fixed');
|
||||
assert.strictEqual(view1.size, 986 - 66, 'first view is collapsed');
|
||||
|
||||
const viewContainers = container.querySelectorAll('.split-view-view');
|
||||
assert.equal(viewContainers.length, 2, 'there are two view containers');
|
||||
assert.equal((viewContainers.item(0) as HTMLElement).style.height, '66px', 'second view container is 66px');
|
||||
assert.equal((viewContainers.item(1) as HTMLElement).style.height, `${986 - 66}px`, 'first view container is 66px');
|
||||
assert.strictEqual(viewContainers.length, 2, 'there are two view containers');
|
||||
assert.strictEqual((viewContainers.item(0) as HTMLElement).style.height, '66px', 'second view container is 66px');
|
||||
assert.strictEqual((viewContainers.item(1) as HTMLElement).style.height, `${986 - 66}px`, 'first view container is 66px');
|
||||
|
||||
splitview.dispose();
|
||||
view2.dispose();
|
||||
@ -351,16 +351,16 @@ suite('Splitview', () => {
|
||||
splitview.layout(200);
|
||||
|
||||
splitview.addView(view1, Sizing.Distribute);
|
||||
assert.equal(view1.size, 200);
|
||||
assert.strictEqual(view1.size, 200);
|
||||
|
||||
splitview.addView(view2, 50);
|
||||
assert.deepEqual([view1.size, view2.size], [150, 50]);
|
||||
assert.deepStrictEqual([view1.size, view2.size], [150, 50]);
|
||||
|
||||
splitview.addView(view3, Sizing.Distribute);
|
||||
assert.deepEqual([view1.size, view2.size, view3.size], [66, 66, 68]);
|
||||
assert.deepStrictEqual([view1.size, view2.size, view3.size], [66, 66, 68]);
|
||||
|
||||
splitview.removeView(1, Sizing.Distribute);
|
||||
assert.deepEqual([view1.size, view3.size], [100, 100]);
|
||||
assert.deepStrictEqual([view1.size, view3.size], [100, 100]);
|
||||
|
||||
splitview.dispose();
|
||||
view3.dispose();
|
||||
@ -379,7 +379,7 @@ suite('Splitview', () => {
|
||||
splitview.addView(view3, 25);
|
||||
|
||||
splitview.layout(200);
|
||||
assert.deepEqual([view1.size, view2.size, view3.size], [67, 67, 66]);
|
||||
assert.deepStrictEqual([view1.size, view2.size, view3.size], [67, 67, 66]);
|
||||
|
||||
splitview.dispose();
|
||||
view3.dispose();
|
||||
@ -395,13 +395,13 @@ suite('Splitview', () => {
|
||||
splitview.layout(200);
|
||||
|
||||
splitview.addView(view1, Sizing.Distribute);
|
||||
assert.equal(view1.size, 200);
|
||||
assert.strictEqual(view1.size, 200);
|
||||
|
||||
splitview.addView(view2, Sizing.Split(0));
|
||||
assert.deepEqual([view1.size, view2.size], [100, 100]);
|
||||
assert.deepStrictEqual([view1.size, view2.size], [100, 100]);
|
||||
|
||||
splitview.addView(view3, Sizing.Split(1));
|
||||
assert.deepEqual([view1.size, view2.size, view3.size], [100, 50, 50]);
|
||||
assert.deepStrictEqual([view1.size, view2.size, view3.size], [100, 50, 50]);
|
||||
|
||||
splitview.dispose();
|
||||
view3.dispose();
|
||||
@ -417,13 +417,13 @@ suite('Splitview', () => {
|
||||
splitview.layout(200);
|
||||
|
||||
splitview.addView(view1, Sizing.Distribute);
|
||||
assert.equal(view1.size, 200);
|
||||
assert.strictEqual(view1.size, 200);
|
||||
|
||||
splitview.addView(view2, Sizing.Split(0));
|
||||
assert.deepEqual([view1.size, view2.size], [100, 100]);
|
||||
assert.deepStrictEqual([view1.size, view2.size], [100, 100]);
|
||||
|
||||
splitview.addView(view3, Sizing.Split(0));
|
||||
assert.deepEqual([view1.size, view2.size, view3.size], [50, 100, 50]);
|
||||
assert.deepStrictEqual([view1.size, view2.size, view3.size], [50, 100, 50]);
|
||||
|
||||
splitview.dispose();
|
||||
view3.dispose();
|
||||
@ -439,10 +439,10 @@ suite('Splitview', () => {
|
||||
|
||||
splitview.addView(view1, Sizing.Distribute);
|
||||
splitview.addView(view2, Sizing.Distribute);
|
||||
assert.deepEqual([view1.size, view2.size], [100, 100]);
|
||||
assert.deepStrictEqual([view1.size, view2.size], [100, 100]);
|
||||
|
||||
splitview.layout(100);
|
||||
assert.deepEqual([view1.size, view2.size], [50, 50]);
|
||||
assert.deepStrictEqual([view1.size, view2.size], [50, 50]);
|
||||
|
||||
splitview.dispose();
|
||||
view2.dispose();
|
||||
@ -457,10 +457,10 @@ suite('Splitview', () => {
|
||||
|
||||
splitview.addView(view1, Sizing.Distribute);
|
||||
splitview.addView(view2, Sizing.Distribute);
|
||||
assert.deepEqual([view1.size, view2.size], [100, 100]);
|
||||
assert.deepStrictEqual([view1.size, view2.size], [100, 100]);
|
||||
|
||||
splitview.layout(100);
|
||||
assert.deepEqual([view1.size, view2.size], [80, 20]);
|
||||
assert.deepStrictEqual([view1.size, view2.size], [80, 20]);
|
||||
|
||||
splitview.dispose();
|
||||
view2.dispose();
|
||||
@ -477,19 +477,19 @@ suite('Splitview', () => {
|
||||
splitview.addView(view1, Sizing.Distribute);
|
||||
splitview.addView(view2, Sizing.Distribute);
|
||||
splitview.addView(view3, Sizing.Distribute);
|
||||
assert.deepEqual([view1.size, view2.size, view3.size], [66, 68, 66]);
|
||||
assert.deepStrictEqual([view1.size, view2.size, view3.size], [66, 68, 66]);
|
||||
|
||||
splitview.layout(180);
|
||||
assert.deepEqual([view1.size, view2.size, view3.size], [66, 48, 66]);
|
||||
assert.deepStrictEqual([view1.size, view2.size, view3.size], [66, 48, 66]);
|
||||
|
||||
splitview.layout(124);
|
||||
assert.deepEqual([view1.size, view2.size, view3.size], [66, 20, 38]);
|
||||
assert.deepStrictEqual([view1.size, view2.size, view3.size], [66, 20, 38]);
|
||||
|
||||
splitview.layout(60);
|
||||
assert.deepEqual([view1.size, view2.size, view3.size], [20, 20, 20]);
|
||||
assert.deepStrictEqual([view1.size, view2.size, view3.size], [20, 20, 20]);
|
||||
|
||||
splitview.layout(200);
|
||||
assert.deepEqual([view1.size, view2.size, view3.size], [20, 160, 20]);
|
||||
assert.deepStrictEqual([view1.size, view2.size, view3.size], [20, 160, 20]);
|
||||
|
||||
splitview.dispose();
|
||||
view3.dispose();
|
||||
@ -507,19 +507,19 @@ suite('Splitview', () => {
|
||||
splitview.addView(view1, Sizing.Distribute);
|
||||
splitview.addView(view2, Sizing.Distribute);
|
||||
splitview.addView(view3, Sizing.Distribute);
|
||||
assert.deepEqual([view1.size, view2.size, view3.size], [66, 68, 66]);
|
||||
assert.deepStrictEqual([view1.size, view2.size, view3.size], [66, 68, 66]);
|
||||
|
||||
splitview.layout(180);
|
||||
assert.deepEqual([view1.size, view2.size, view3.size], [66, 48, 66]);
|
||||
assert.deepStrictEqual([view1.size, view2.size, view3.size], [66, 48, 66]);
|
||||
|
||||
splitview.layout(132);
|
||||
assert.deepEqual([view1.size, view2.size, view3.size], [46, 20, 66]);
|
||||
assert.deepStrictEqual([view1.size, view2.size, view3.size], [46, 20, 66]);
|
||||
|
||||
splitview.layout(60);
|
||||
assert.deepEqual([view1.size, view2.size, view3.size], [20, 20, 20]);
|
||||
assert.deepStrictEqual([view1.size, view2.size, view3.size], [20, 20, 20]);
|
||||
|
||||
splitview.layout(200);
|
||||
assert.deepEqual([view1.size, view2.size, view3.size], [20, 160, 20]);
|
||||
assert.deepStrictEqual([view1.size, view2.size, view3.size], [20, 160, 20]);
|
||||
|
||||
splitview.dispose();
|
||||
view3.dispose();
|
||||
@ -539,7 +539,7 @@ suite('Splitview', () => {
|
||||
splitview.addView(view3, Sizing.Distribute);
|
||||
|
||||
splitview.layout(200, 100);
|
||||
assert.deepEqual([view1.orthogonalSize, view2.orthogonalSize, view3.orthogonalSize], [100, 100, 100]);
|
||||
assert.deepStrictEqual([view1.orthogonalSize, view2.orthogonalSize, view3.orthogonalSize], [100, 100, 100]);
|
||||
|
||||
splitview.dispose();
|
||||
view3.dispose();
|
||||
|
@ -97,10 +97,10 @@ suite('AsyncDataTree', function () {
|
||||
|
||||
const tree = new AsyncDataTree<Element, Element>('test', container, new VirtualDelegate(), [new Renderer()], new DataSource(), { identityProvider: new IdentityProvider() });
|
||||
tree.layout(200);
|
||||
assert.equal(container.querySelectorAll('.monaco-list-row').length, 0);
|
||||
assert.strictEqual(container.querySelectorAll('.monaco-list-row').length, 0);
|
||||
|
||||
await tree.setInput(model.root);
|
||||
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
assert.strictEqual(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
let twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(!twistie.classList.contains('collapsible'));
|
||||
assert(!twistie.classList.contains('collapsed'));
|
||||
@ -112,14 +112,14 @@ suite('AsyncDataTree', function () {
|
||||
];
|
||||
|
||||
await tree.updateChildren(model.root);
|
||||
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
assert.strictEqual(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
|
||||
await tree.expand(model.get('a'));
|
||||
assert.equal(container.querySelectorAll('.monaco-list-row').length, 4);
|
||||
assert.strictEqual(container.querySelectorAll('.monaco-list-row').length, 4);
|
||||
|
||||
model.get('a').children = [];
|
||||
await tree.updateChildren(model.root);
|
||||
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
assert.strictEqual(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
});
|
||||
|
||||
test('issue #68648', async () => {
|
||||
@ -316,16 +316,16 @@ suite('AsyncDataTree', function () {
|
||||
|
||||
const pUpdateChildrenA = tree.updateChildren(model.get('a'));
|
||||
const pExpandA = tree.expand(model.get('a'));
|
||||
assert.equal(calls.length, 1, 'expand(a) still hasn\'t called getChildren(a)');
|
||||
assert.strictEqual(calls.length, 1, 'expand(a) still hasn\'t called getChildren(a)');
|
||||
|
||||
calls.pop()!();
|
||||
assert.equal(calls.length, 0, 'no pending getChildren calls');
|
||||
assert.strictEqual(calls.length, 0, 'no pending getChildren calls');
|
||||
|
||||
await pUpdateChildrenA;
|
||||
assert.equal(calls.length, 0, 'expand(a) should not have forced a second refresh');
|
||||
assert.strictEqual(calls.length, 0, 'expand(a) should not have forced a second refresh');
|
||||
|
||||
const result = await pExpandA;
|
||||
assert.equal(result, true, 'expand(a) should be done');
|
||||
assert.strictEqual(result, true, 'expand(a) should be done');
|
||||
});
|
||||
|
||||
test('issue #80098 - first expand should call getChildren', async () => {
|
||||
@ -358,16 +358,16 @@ suite('AsyncDataTree', function () {
|
||||
await pSetInput;
|
||||
|
||||
const pExpandA = tree.expand(model.get('a'));
|
||||
assert.equal(calls.length, 1, 'expand(a) should\'ve called getChildren(a)');
|
||||
assert.strictEqual(calls.length, 1, 'expand(a) should\'ve called getChildren(a)');
|
||||
|
||||
let race = await Promise.race([pExpandA.then(() => 'expand'), timeout(1).then(() => 'timeout')]);
|
||||
assert.equal(race, 'timeout', 'expand(a) should not be yet done');
|
||||
assert.strictEqual(race, 'timeout', 'expand(a) should not be yet done');
|
||||
|
||||
calls.pop()!();
|
||||
assert.equal(calls.length, 0, 'no pending getChildren calls');
|
||||
assert.strictEqual(calls.length, 0, 'no pending getChildren calls');
|
||||
|
||||
race = await Promise.race([pExpandA.then(() => 'expand'), timeout(1).then(() => 'timeout')]);
|
||||
assert.equal(race, 'expand', 'expand(a) should now be done');
|
||||
assert.strictEqual(race, 'expand', 'expand(a) should now be done');
|
||||
});
|
||||
|
||||
test('issue #78388 - tree should react to hasChildren toggles', async () => {
|
||||
@ -383,7 +383,7 @@ suite('AsyncDataTree', function () {
|
||||
tree.layout(200);
|
||||
|
||||
await tree.setInput(model.root);
|
||||
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
assert.strictEqual(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
|
||||
let twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(!twistie.classList.contains('collapsible'));
|
||||
@ -391,14 +391,14 @@ suite('AsyncDataTree', function () {
|
||||
|
||||
model.get('a').children = [{ id: 'aa' }];
|
||||
await tree.updateChildren(model.get('a'), false);
|
||||
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
assert.strictEqual(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(twistie.classList.contains('collapsible'));
|
||||
assert(twistie.classList.contains('collapsed'));
|
||||
|
||||
model.get('a').children = [];
|
||||
await tree.updateChildren(model.get('a'), false);
|
||||
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
assert.strictEqual(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(!twistie.classList.contains('collapsible'));
|
||||
assert(!twistie.classList.contains('collapsed'));
|
||||
@ -422,7 +422,7 @@ suite('AsyncDataTree', function () {
|
||||
|
||||
await tree.setInput(model.root);
|
||||
await tree.expand(model.get('a'));
|
||||
assert.deepEqual(Array.from(container.querySelectorAll('.monaco-list-row')).map(e => e.textContent), ['a', 'b1']);
|
||||
assert.deepStrictEqual(Array.from(container.querySelectorAll('.monaco-list-row')).map(e => e.textContent), ['a', 'b1']);
|
||||
|
||||
const a = model.get('a');
|
||||
const b = model.get('b');
|
||||
@ -433,6 +433,6 @@ suite('AsyncDataTree', function () {
|
||||
tree.updateChildren(b, true, true)
|
||||
]);
|
||||
|
||||
assert.deepEqual(Array.from(container.querySelectorAll('.monaco-list-row')).map(e => e.textContent), ['a', 'b2']);
|
||||
assert.deepStrictEqual(Array.from(container.querySelectorAll('.monaco-list-row')).map(e => e.textContent), ['a', 'b2']);
|
||||
});
|
||||
});
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user