mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge from vscode fcf3346a8e9f5ee1e00674461d9e2c2292a14ee3 (#12295)
* Merge from vscode fcf3346a8e9f5ee1e00674461d9e2c2292a14ee3 * Fix test build break * Update distro * Fix build errors * Update distro * Update REH build file * Update build task names for REL * Fix product build yaml * Fix product REH task name * Fix type in task name * Update linux build step * Update windows build tasks * Turn off server publish * Disable REH * Fix typo * Bump distro * Update vscode tests * Bump distro * Fix type in disto * Bump distro * Turn off docker build * Remove docker step from release Co-authored-by: ADS Merger <andresse@microsoft.com> Co-authored-by: Karl Burtram <karlb@microsoft.com>
This commit is contained in:
@@ -4,9 +4,10 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { renderCodiconsRegex } from 'vs/base/common/codicons';
|
||||
|
||||
export function renderCodiconsAsElement(text: string): Array<HTMLSpanElement | string> {
|
||||
const renderCodiconsRegex = /(\\)?\$\((([a-z0-9\-]+?)(?:~([a-z0-9\-]*?))?)\)/gi;
|
||||
|
||||
export function renderCodicons(text: string): Array<HTMLSpanElement | string> {
|
||||
const elements = new Array<HTMLSpanElement | string>();
|
||||
let match: RegExpMatchArray | null;
|
||||
|
||||
@@ -24,4 +25,4 @@ export function renderCodiconsAsElement(text: string): Array<HTMLSpanElement | s
|
||||
elements.push(text.substring(textStart));
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { coalesce } from 'vs/base/common/arrays';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Schemas, RemoteAuthorities } from 'vs/base/common/network';
|
||||
import { BrowserFeatures } from 'vs/base/browser/canIUse';
|
||||
@@ -84,17 +83,17 @@ const _classList: IDomClassList = new class implements IDomClassList {
|
||||
};
|
||||
|
||||
/** @deprecated ES6 - use classList*/
|
||||
export const hasClass: (node: HTMLElement | SVGElement, className: string) => boolean = _classList.hasClass.bind(_classList);
|
||||
export function hasClass(node: HTMLElement | SVGElement, className: string): boolean { return _classList.hasClass(node, className); }
|
||||
/** @deprecated ES6 - use classList*/
|
||||
export const addClass: (node: HTMLElement | SVGElement, className: string) => void = _classList.addClass.bind(_classList);
|
||||
export function addClass(node: HTMLElement | SVGElement, className: string): void { return _classList.addClass(node, className); }
|
||||
/** @deprecated ES6 - use classList*/
|
||||
export const addClasses: (node: HTMLElement | SVGElement, ...classNames: string[]) => void = _classList.addClasses.bind(_classList);
|
||||
export function addClasses(node: HTMLElement | SVGElement, ...classNames: string[]): void { return _classList.addClasses(node, ...classNames); }
|
||||
/** @deprecated ES6 - use classList*/
|
||||
export const removeClass: (node: HTMLElement | SVGElement, className: string) => void = _classList.removeClass.bind(_classList);
|
||||
export function removeClass(node: HTMLElement | SVGElement, className: string): void { return _classList.removeClass(node, className); }
|
||||
/** @deprecated ES6 - use classList*/
|
||||
export const removeClasses: (node: HTMLElement | SVGElement, ...classNames: string[]) => void = _classList.removeClasses.bind(_classList);
|
||||
export function removeClasses(node: HTMLElement | SVGElement, ...classNames: string[]): void { return _classList.removeClasses(node, ...classNames); }
|
||||
/** @deprecated ES6 - use classList*/
|
||||
export const toggleClass: (node: HTMLElement | SVGElement, className: string, shouldHaveIt?: boolean) => void = _classList.toggleClass.bind(_classList);
|
||||
export function toggleClass(node: HTMLElement | SVGElement, className: string, shouldHaveIt?: boolean): void { return _classList.toggleClass(node, className, shouldHaveIt); }
|
||||
|
||||
class DomListener implements IDisposable {
|
||||
|
||||
@@ -411,9 +410,9 @@ export function getClientArea(element: HTMLElement): Dimension {
|
||||
}
|
||||
|
||||
// If visual view port exits and it's on mobile, it should be used instead of window innerWidth / innerHeight, or document.body.clientWidth / document.body.clientHeight
|
||||
if (platform.isIOS && (<any>window).visualViewport) {
|
||||
const width = (<any>window).visualViewport.width;
|
||||
const height = (<any>window).visualViewport.height - (
|
||||
if (platform.isIOS && window.visualViewport) {
|
||||
const width = window.visualViewport.width;
|
||||
const height = window.visualViewport.height - (
|
||||
browser.isStandalone
|
||||
// in PWA mode, the visual viewport always includes the safe-area-inset-bottom (which is for the home indicator)
|
||||
// even when you are using the onscreen monitor, the visual viewport will include the area between system statusbar and the onscreen keyboard
|
||||
@@ -785,11 +784,11 @@ function getSharedStyleSheet(): HTMLStyleElement {
|
||||
}
|
||||
|
||||
function getDynamicStyleSheetRules(style: any) {
|
||||
if (style && style.sheet && style.sheet.rules) {
|
||||
if (style?.sheet?.rules) {
|
||||
// Chrome, IE
|
||||
return style.sheet.rules;
|
||||
}
|
||||
if (style && style.sheet && style.sheet.cssRules) {
|
||||
if (style?.sheet?.cssRules) {
|
||||
// FF
|
||||
return style.sheet.cssRules;
|
||||
}
|
||||
@@ -1012,20 +1011,23 @@ export function prepend<T extends Node>(parent: HTMLElement, child: T): T {
|
||||
return child;
|
||||
}
|
||||
|
||||
const SELECTOR_REGEX = /([\w\-]+)?(#([\w\-]+))?((\.([\w\-]+))*)/;
|
||||
|
||||
export function reset<T extends Node>(parent: HTMLElement, ...children: Array<Node | string>) {
|
||||
/**
|
||||
* Removes all children from `parent` and appends `children`
|
||||
*/
|
||||
export function reset(parent: HTMLElement, ...children: Array<Node | string>) {
|
||||
parent.innerText = '';
|
||||
coalesce(children)
|
||||
.forEach(child => {
|
||||
if (child instanceof Node) {
|
||||
parent.appendChild(child);
|
||||
} else {
|
||||
parent.appendChild(document.createTextNode(child as string));
|
||||
}
|
||||
});
|
||||
for (const child of children) {
|
||||
if (child instanceof Node) {
|
||||
parent.appendChild(child);
|
||||
} else if (typeof child === 'string') {
|
||||
parent.appendChild(document.createTextNode(child));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const SELECTOR_REGEX = /([\w\-]+)?(#([\w\-]+))?((\.([\w\-]+))*)/;
|
||||
|
||||
export enum Namespace {
|
||||
HTML = 'http://www.w3.org/1999/xhtml',
|
||||
SVG = 'http://www.w3.org/2000/svg'
|
||||
@@ -1075,14 +1077,13 @@ function _$<T extends Element>(namespace: Namespace, description: string, attrs?
|
||||
}
|
||||
});
|
||||
|
||||
coalesce(children)
|
||||
.forEach(child => {
|
||||
if (child instanceof Node) {
|
||||
result.appendChild(child);
|
||||
} else {
|
||||
result.appendChild(document.createTextNode(child as string));
|
||||
}
|
||||
});
|
||||
for (const child of children) {
|
||||
if (child instanceof Node) {
|
||||
result.appendChild(child);
|
||||
} else if (typeof child === 'string') {
|
||||
result.appendChild(document.createTextNode(child));
|
||||
}
|
||||
}
|
||||
|
||||
return result as T;
|
||||
}
|
||||
@@ -1276,3 +1277,66 @@ export function triggerDownload(dataOrUri: Uint8Array | URI, name: string): void
|
||||
// Ensure to remove the element from DOM eventually
|
||||
setTimeout(() => document.body.removeChild(anchor));
|
||||
}
|
||||
|
||||
export enum DetectedFullscreenMode {
|
||||
|
||||
/**
|
||||
* The document is fullscreen, e.g. because an element
|
||||
* in the document requested to be fullscreen.
|
||||
*/
|
||||
DOCUMENT = 1,
|
||||
|
||||
/**
|
||||
* The browser is fullsreen, e.g. because the user enabled
|
||||
* native window fullscreen for it.
|
||||
*/
|
||||
BROWSER
|
||||
}
|
||||
|
||||
export interface IDetectedFullscreen {
|
||||
|
||||
/**
|
||||
* Figure out if the document is fullscreen or the browser.
|
||||
*/
|
||||
mode: DetectedFullscreenMode;
|
||||
|
||||
/**
|
||||
* Wether we know for sure that we are in fullscreen mode or
|
||||
* it is a guess.
|
||||
*/
|
||||
guess: boolean;
|
||||
}
|
||||
|
||||
export function detectFullscreen(): IDetectedFullscreen | null {
|
||||
|
||||
// Browser fullscreen: use DOM APIs to detect
|
||||
if (document.fullscreenElement || (<any>document).webkitFullscreenElement || (<any>document).webkitIsFullScreen) {
|
||||
return { mode: DetectedFullscreenMode.DOCUMENT, guess: false };
|
||||
}
|
||||
|
||||
// There is no standard way to figure out if the browser
|
||||
// is using native fullscreen. Via checking on screen
|
||||
// height and comparing that to window height, we can guess
|
||||
// it though.
|
||||
|
||||
if (window.innerHeight === screen.height) {
|
||||
// if the height of the window matches the screen height, we can
|
||||
// safely assume that the browser is fullscreen because no browser
|
||||
// chrome is taking height away (e.g. like toolbars).
|
||||
return { mode: DetectedFullscreenMode.BROWSER, guess: false };
|
||||
}
|
||||
|
||||
if (platform.isMacintosh || platform.isLinux) {
|
||||
// macOS and Linux do not properly report `innerHeight`, only Windows does
|
||||
if (window.outerHeight === screen.height && window.outerWidth === screen.width) {
|
||||
// if the height of the browser matches the screen height, we can
|
||||
// only guess that we are in fullscreen. It is also possible that
|
||||
// the user has turned off taskbars in the OS and the browser is
|
||||
// simply able to span the entire size of the screen.
|
||||
return { mode: DetectedFullscreenMode.BROWSER, guess: true };
|
||||
}
|
||||
}
|
||||
|
||||
// Not in fullscreen
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -15,9 +15,10 @@ import { cloneAndChange } from 'vs/base/common/objects';
|
||||
import { escape } from 'vs/base/common/strings';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { renderCodicons, markdownEscapeEscapedCodicons } from 'vs/base/common/codicons';
|
||||
import { markdownEscapeEscapedCodicons } from 'vs/base/common/codicons';
|
||||
import { resolvePath } from 'vs/base/common/resources';
|
||||
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { renderCodicons } from 'vs/base/browser/codicons';
|
||||
|
||||
export interface MarkedOptions extends marked.MarkedOptions {
|
||||
baseUrl?: never;
|
||||
@@ -143,7 +144,11 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
|
||||
}
|
||||
};
|
||||
renderer.paragraph = (text): string => {
|
||||
return `<p>${markdown.supportThemeIcons ? renderCodicons(text) : text}</p>`;
|
||||
if (markdown.supportThemeIcons) {
|
||||
const elements = renderCodicons(text);
|
||||
text = elements.map(e => typeof e === 'string' ? e : e.outerHTML).join('');
|
||||
}
|
||||
return `<p>${text}</p>`;
|
||||
};
|
||||
|
||||
if (options.codeBlockRenderer) {
|
||||
|
||||
@@ -9,12 +9,12 @@ import * as nls from 'vs/nls';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { SelectBox, ISelectOptionItem, ISelectBoxOptions } from 'vs/base/browser/ui/selectBox/selectBox';
|
||||
import { IAction, IActionRunner, Action, IActionChangeEvent, ActionRunner, Separator, IActionViewItem } from 'vs/base/common/actions';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import * as types from 'vs/base/common/types';
|
||||
import { EventType, Gesture } from 'vs/base/browser/touch';
|
||||
import { EventType as TouchEventType, Gesture } from 'vs/base/browser/touch';
|
||||
import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
|
||||
import { DataTransfers } from 'vs/base/browser/dnd';
|
||||
import { isFirefox } from 'vs/base/browser/browser';
|
||||
import { $, addClasses, addDisposableListener, append, EventHelper, EventLike, EventType, removeClasses, removeTabIndexAndUpdateFocus } from 'vs/base/browser/dom';
|
||||
|
||||
export interface IBaseActionViewItemOptions {
|
||||
draggable?: boolean;
|
||||
@@ -112,19 +112,19 @@ export class BaseActionViewItem extends Disposable implements IActionViewItem {
|
||||
|
||||
if (isFirefox) {
|
||||
// Firefox: requires to set a text data transfer to get going
|
||||
this._register(DOM.addDisposableListener(container, DOM.EventType.DRAG_START, e => e.dataTransfer?.setData(DataTransfers.TEXT, this._action.label)));
|
||||
this._register(addDisposableListener(container, EventType.DRAG_START, e => e.dataTransfer?.setData(DataTransfers.TEXT, this._action.label)));
|
||||
}
|
||||
}
|
||||
|
||||
this._register(DOM.addDisposableListener(element, EventType.Tap, e => this.onClick(e)));
|
||||
this._register(addDisposableListener(element, TouchEventType.Tap, e => this.onClick(e)));
|
||||
|
||||
this._register(DOM.addDisposableListener(element, DOM.EventType.MOUSE_DOWN, e => {
|
||||
this._register(addDisposableListener(element, EventType.MOUSE_DOWN, e => {
|
||||
if (!enableDragging) {
|
||||
DOM.EventHelper.stop(e, true); // do not run when dragging is on because that would disable it
|
||||
EventHelper.stop(e, true); // do not run when dragging is on because that would disable it
|
||||
}
|
||||
|
||||
if (this._action.enabled && e.button === 0) {
|
||||
DOM.addClass(element, 'active');
|
||||
element.classList.add('active');
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -133,15 +133,15 @@ export class BaseActionViewItem extends Disposable implements IActionViewItem {
|
||||
// main mouse button. This is for scenarios where e.g. some interaction forces
|
||||
// the Ctrl+key to be pressed and hold but the user still wants to interact
|
||||
// with the actions (for example quick access in quick navigation mode).
|
||||
this._register(DOM.addDisposableListener(element, DOM.EventType.CONTEXT_MENU, e => {
|
||||
this._register(addDisposableListener(element, EventType.CONTEXT_MENU, e => {
|
||||
if (e.button === 0 && e.ctrlKey === true) {
|
||||
this.onClick(e);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
this._register(DOM.addDisposableListener(element, DOM.EventType.CLICK, e => {
|
||||
DOM.EventHelper.stop(e, true);
|
||||
this._register(addDisposableListener(element, EventType.CLICK, e => {
|
||||
EventHelper.stop(e, true);
|
||||
|
||||
// menus do not use the click event
|
||||
if (!(this.options && this.options.isMenu)) {
|
||||
@@ -149,20 +149,20 @@ export class BaseActionViewItem extends Disposable implements IActionViewItem {
|
||||
}
|
||||
}));
|
||||
|
||||
this._register(DOM.addDisposableListener(element, DOM.EventType.DBLCLICK, e => {
|
||||
DOM.EventHelper.stop(e, true);
|
||||
this._register(addDisposableListener(element, EventType.DBLCLICK, e => {
|
||||
EventHelper.stop(e, true);
|
||||
}));
|
||||
|
||||
[DOM.EventType.MOUSE_UP, DOM.EventType.MOUSE_OUT].forEach(event => {
|
||||
this._register(DOM.addDisposableListener(element, event, e => {
|
||||
DOM.EventHelper.stop(e);
|
||||
DOM.removeClass(element, 'active');
|
||||
[EventType.MOUSE_UP, EventType.MOUSE_OUT].forEach(event => {
|
||||
this._register(addDisposableListener(element, event, e => {
|
||||
EventHelper.stop(e);
|
||||
element.classList.remove('active');
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
onClick(event: DOM.EventLike): void {
|
||||
DOM.EventHelper.stop(event, true);
|
||||
onClick(event: EventLike): void {
|
||||
EventHelper.stop(event, true);
|
||||
|
||||
const context = types.isUndefinedOrNull(this._context) ? this.options?.useEventAsContext ? event : undefined : this._context;
|
||||
this.actionRunner.run(this._action, context);
|
||||
@@ -171,14 +171,14 @@ export class BaseActionViewItem extends Disposable implements IActionViewItem {
|
||||
focus(): void {
|
||||
if (this.element) {
|
||||
this.element.focus();
|
||||
DOM.addClass(this.element, 'focused');
|
||||
this.element.classList.add('focused');
|
||||
}
|
||||
}
|
||||
|
||||
blur(): void {
|
||||
if (this.element) {
|
||||
this.element.blur();
|
||||
DOM.removeClass(this.element, 'focused');
|
||||
this.element.classList.remove('focused');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ export class BaseActionViewItem extends Disposable implements IActionViewItem {
|
||||
|
||||
dispose(): void {
|
||||
if (this.element) {
|
||||
DOM.removeNode(this.element);
|
||||
this.element.remove();
|
||||
this.element = undefined;
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ export class ActionViewItem extends BaseActionViewItem {
|
||||
super.render(container);
|
||||
|
||||
if (this.element) {
|
||||
this.label = DOM.append(this.element, DOM.$('a.action-label'));
|
||||
this.label = append(this.element, $('a.action-label'));
|
||||
}
|
||||
|
||||
if (this.label) {
|
||||
@@ -259,7 +259,7 @@ export class ActionViewItem extends BaseActionViewItem {
|
||||
}
|
||||
|
||||
if (this.options.label && this.options.keybinding && this.element) {
|
||||
DOM.append(this.element, DOM.$('span.keybinding')).textContent = this.options.keybinding;
|
||||
append(this.element, $('span.keybinding')).textContent = this.options.keybinding;
|
||||
}
|
||||
|
||||
this.updateClass();
|
||||
@@ -304,23 +304,23 @@ export class ActionViewItem extends BaseActionViewItem {
|
||||
|
||||
updateClass(): void {
|
||||
if (this.cssClass && this.label) {
|
||||
DOM.removeClasses(this.label, this.cssClass);
|
||||
removeClasses(this.label, this.cssClass);
|
||||
}
|
||||
|
||||
if (this.options.icon) {
|
||||
this.cssClass = this.getAction().class;
|
||||
|
||||
if (this.label) {
|
||||
DOM.addClass(this.label, 'codicon');
|
||||
this.label.classList.add('codicon');
|
||||
if (this.cssClass) {
|
||||
DOM.addClasses(this.label, this.cssClass);
|
||||
addClasses(this.label, this.cssClass);
|
||||
}
|
||||
}
|
||||
|
||||
this.updateEnabled();
|
||||
} else {
|
||||
if (this.label) {
|
||||
DOM.removeClass(this.label, 'codicon');
|
||||
this.label.classList.remove('codicon');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -329,22 +329,22 @@ export class ActionViewItem extends BaseActionViewItem {
|
||||
if (this.getAction().enabled) {
|
||||
if (this.label) {
|
||||
this.label.removeAttribute('aria-disabled');
|
||||
DOM.removeClass(this.label, 'disabled');
|
||||
this.label.classList.remove('disabled');
|
||||
this.label.tabIndex = 0;
|
||||
}
|
||||
|
||||
if (this.element) {
|
||||
DOM.removeClass(this.element, 'disabled');
|
||||
this.element.classList.remove('disabled');
|
||||
}
|
||||
} else {
|
||||
if (this.label) {
|
||||
this.label.setAttribute('aria-disabled', 'true');
|
||||
DOM.addClass(this.label, 'disabled');
|
||||
DOM.removeTabIndexAndUpdateFocus(this.label);
|
||||
this.label.classList.add('disabled');
|
||||
removeTabIndexAndUpdateFocus(this.label);
|
||||
}
|
||||
|
||||
if (this.element) {
|
||||
DOM.addClass(this.element, 'disabled');
|
||||
this.element.classList.add('disabled');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -352,9 +352,9 @@ export class ActionViewItem extends BaseActionViewItem {
|
||||
updateChecked(): void {
|
||||
if (this.label) {
|
||||
if (this.getAction().checked) {
|
||||
DOM.addClass(this.label, 'checked');
|
||||
this.label.classList.add('checked');
|
||||
} else {
|
||||
DOM.removeClass(this.label, 'checked');
|
||||
this.label.classList.remove('checked');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import * as DOM from 'vs/base/browser/dom';
|
||||
import * as types from 'vs/base/common/types';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { IActionViewItemOptions, ActionViewItem, BaseActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
|
||||
|
||||
export const enum ActionsOrientation {
|
||||
@@ -47,8 +47,9 @@ export class ActionBar extends Disposable implements IActionRunner {
|
||||
|
||||
private _actionRunner: IActionRunner;
|
||||
private _context: unknown;
|
||||
private _orientation: ActionsOrientation;
|
||||
private _triggerKeys: ActionTrigger;
|
||||
private readonly _orientation: ActionsOrientation;
|
||||
private readonly _triggerKeys: ActionTrigger;
|
||||
private _actionIds: string[];
|
||||
|
||||
// View Items
|
||||
viewItems: IActionViewItem[];
|
||||
@@ -60,16 +61,16 @@ export class ActionBar extends Disposable implements IActionRunner {
|
||||
protected actionsList: HTMLElement;
|
||||
|
||||
private _onDidBlur = this._register(new Emitter<void>());
|
||||
readonly onDidBlur: Event<void> = this._onDidBlur.event;
|
||||
readonly onDidBlur = this._onDidBlur.event;
|
||||
|
||||
private _onDidCancel = this._register(new Emitter<void>());
|
||||
readonly onDidCancel: Event<void> = this._onDidCancel.event;
|
||||
readonly onDidCancel = this._onDidCancel.event;
|
||||
|
||||
private _onDidRun = this._register(new Emitter<IRunEvent>());
|
||||
readonly onDidRun: Event<IRunEvent> = this._onDidRun.event;
|
||||
readonly onDidRun = this._onDidRun.event;
|
||||
|
||||
private _onDidBeforeRun = this._register(new Emitter<IRunEvent>());
|
||||
readonly onDidBeforeRun: Event<IRunEvent> = this._onDidBeforeRun.event;
|
||||
readonly onDidBeforeRun = this._onDidBeforeRun.event;
|
||||
|
||||
constructor(container: HTMLElement, options: IActionBarOptions = {}) {
|
||||
super();
|
||||
@@ -92,6 +93,7 @@ export class ActionBar extends Disposable implements IActionRunner {
|
||||
this._register(this._actionRunner.onDidRun(e => this._onDidRun.fire(e)));
|
||||
this._register(this._actionRunner.onDidBeforeRun(e => this._onDidBeforeRun.fire(e)));
|
||||
|
||||
this._actionIds = [];
|
||||
this.viewItems = [];
|
||||
this.focusedItem = undefined;
|
||||
|
||||
@@ -245,6 +247,10 @@ export class ActionBar extends Disposable implements IActionRunner {
|
||||
return this.domNode;
|
||||
}
|
||||
|
||||
hasAction(action: IAction): boolean {
|
||||
return this._actionIds.includes(action.id);
|
||||
}
|
||||
|
||||
push(arg: IAction | ReadonlyArray<IAction>, options: IActionOptions = {}): void {
|
||||
const actions: ReadonlyArray<IAction> = Array.isArray(arg) ? arg : [arg];
|
||||
|
||||
@@ -279,9 +285,11 @@ export class ActionBar extends Disposable implements IActionRunner {
|
||||
if (index === null || index < 0 || index >= this.actionsList.children.length) {
|
||||
this.actionsList.appendChild(actionViewItemElement);
|
||||
this.viewItems.push(item);
|
||||
this._actionIds.push(action.id);
|
||||
} else {
|
||||
this.actionsList.insertBefore(actionViewItemElement, this.actionsList.children[index]);
|
||||
this.viewItems.splice(index, 0, item);
|
||||
this._actionIds.splice(index, 0, action.id);
|
||||
index++;
|
||||
}
|
||||
});
|
||||
@@ -317,12 +325,14 @@ export class ActionBar extends Disposable implements IActionRunner {
|
||||
if (index >= 0 && index < this.viewItems.length) {
|
||||
this.actionsList.removeChild(this.actionsList.childNodes[index]);
|
||||
dispose(this.viewItems.splice(index, 1));
|
||||
this._actionIds.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
dispose(this.viewItems);
|
||||
this.viewItems = [];
|
||||
this._actionIds = [];
|
||||
DOM.clearNode(this.actionsList);
|
||||
}
|
||||
|
||||
@@ -463,7 +473,9 @@ export class ActionBar extends Disposable implements IActionRunner {
|
||||
dispose(this.viewItems);
|
||||
this.viewItems = [];
|
||||
|
||||
DOM.removeNode(this.getContainer());
|
||||
this._actionIds = [];
|
||||
|
||||
this.getContainer().remove();
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ export class BreadcrumbsWidget {
|
||||
|
||||
dispose(): void {
|
||||
this._disposables.dispose();
|
||||
dispose(this._pendingLayout);
|
||||
this._pendingLayout?.dispose();
|
||||
this._onDidSelectItem.dispose();
|
||||
this._onDidFocusItem.dispose();
|
||||
this._onDidChangeFocus.dispose();
|
||||
@@ -131,9 +131,7 @@ export class BreadcrumbsWidget {
|
||||
if (dim && dom.Dimension.equals(dim, this._dimension)) {
|
||||
return;
|
||||
}
|
||||
if (this._pendingLayout) {
|
||||
this._pendingLayout.dispose();
|
||||
}
|
||||
this._pendingLayout?.dispose();
|
||||
if (dim) {
|
||||
// only measure
|
||||
this._pendingLayout = this._updateDimensions(dim);
|
||||
@@ -180,8 +178,8 @@ export class BreadcrumbsWidget {
|
||||
if (style.breadcrumbsHoverForeground) {
|
||||
content += `.monaco-breadcrumbs .monaco-breadcrumb-item:hover:not(.focused):not(.selected) { color: ${style.breadcrumbsHoverForeground}}\n`;
|
||||
}
|
||||
if (this._styleElement.innerHTML !== content) {
|
||||
this._styleElement.innerHTML = content;
|
||||
if (this._styleElement.innerText !== content) {
|
||||
this._styleElement.innerText = content;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,15 +4,15 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./button';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
import { Event as BaseEvent, Emitter } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { Gesture, EventType } from 'vs/base/browser/touch';
|
||||
import { renderCodiconsAsElement } from 'vs/base/browser/codicons';
|
||||
import { Gesture, EventType as TouchEventType } from 'vs/base/browser/touch';
|
||||
import { renderCodicons } from 'vs/base/browser/codicons';
|
||||
import { addDisposableListener, IFocusTracker, EventType, EventHelper, trackFocus, reset, removeTabIndexAndUpdateFocus } from 'vs/base/browser/dom';
|
||||
|
||||
export interface IButtonOptions extends IButtonStyles {
|
||||
readonly title?: boolean | string;
|
||||
@@ -52,7 +52,7 @@ export class Button extends Disposable {
|
||||
private _onDidClick = this._register(new Emitter<Event>());
|
||||
get onDidClick(): BaseEvent<Event> { return this._onDidClick.event; }
|
||||
|
||||
private focusTracker: DOM.IFocusTracker;
|
||||
private focusTracker: IFocusTracker;
|
||||
|
||||
constructor(container: HTMLElement, options?: IButtonOptions) {
|
||||
super();
|
||||
@@ -71,7 +71,7 @@ export class Button extends Disposable {
|
||||
this.buttonBorder = this.options.buttonBorder;
|
||||
|
||||
this._element = document.createElement('a');
|
||||
DOM.addClass(this._element, 'monaco-button');
|
||||
this._element.classList.add('monaco-button');
|
||||
this._element.tabIndex = 0;
|
||||
this._element.setAttribute('role', 'button');
|
||||
|
||||
@@ -79,10 +79,10 @@ export class Button extends Disposable {
|
||||
|
||||
this._register(Gesture.addTarget(this._element));
|
||||
|
||||
[DOM.EventType.CLICK, EventType.Tap].forEach(eventType => {
|
||||
this._register(DOM.addDisposableListener(this._element, eventType, e => {
|
||||
[EventType.CLICK, TouchEventType.Tap].forEach(eventType => {
|
||||
this._register(addDisposableListener(this._element, eventType, e => {
|
||||
if (!this.enabled) {
|
||||
DOM.EventHelper.stop(e);
|
||||
EventHelper.stop(e);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ export class Button extends Disposable {
|
||||
}));
|
||||
});
|
||||
|
||||
this._register(DOM.addDisposableListener(this._element, DOM.EventType.KEY_DOWN, 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))) {
|
||||
@@ -102,22 +102,22 @@ export class Button extends Disposable {
|
||||
}
|
||||
|
||||
if (eventHandled) {
|
||||
DOM.EventHelper.stop(event, true);
|
||||
EventHelper.stop(event, true);
|
||||
}
|
||||
}));
|
||||
|
||||
this._register(DOM.addDisposableListener(this._element, DOM.EventType.MOUSE_OVER, e => {
|
||||
if (!DOM.hasClass(this._element, 'disabled')) {
|
||||
this._register(addDisposableListener(this._element, EventType.MOUSE_OVER, e => {
|
||||
if (!this._element.classList.contains('disabled')) {
|
||||
this.setHoverBackground();
|
||||
}
|
||||
}));
|
||||
|
||||
this._register(DOM.addDisposableListener(this._element, DOM.EventType.MOUSE_OUT, e => {
|
||||
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(DOM.trackFocus(this._element));
|
||||
this.focusTracker = this._register(trackFocus(this._element));
|
||||
this._register(this.focusTracker.onDidFocus(() => this.setHoverBackground()));
|
||||
this._register(this.focusTracker.onDidBlur(() => this.applyStyles())); // restore standard styles
|
||||
|
||||
@@ -176,11 +176,9 @@ export class Button extends Disposable {
|
||||
}
|
||||
|
||||
set label(value: string) {
|
||||
if (!DOM.hasClass(this._element, 'monaco-text-button')) {
|
||||
DOM.addClass(this._element, 'monaco-text-button');
|
||||
}
|
||||
this._element.classList.add('monaco-text-button');
|
||||
if (this.options.supportCodicons) {
|
||||
DOM.reset(this._element, ...renderCodiconsAsElement(value));
|
||||
reset(this._element, ...renderCodicons(value));
|
||||
} else {
|
||||
this._element.textContent = value;
|
||||
}
|
||||
@@ -192,25 +190,25 @@ export class Button extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}} from addClass to addClasses to support multiple classes @todo anthonydresser 4/12/19 invesitgate a better way to do this.
|
||||
// {{SQL CARBON EDIT}}
|
||||
set icon(iconClassName: string) {
|
||||
DOM.addClasses(this._element, ...iconClassName.split(' '));
|
||||
this._element.classList.add(...iconClassName.split(' '));
|
||||
}
|
||||
|
||||
set enabled(value: boolean) {
|
||||
if (value) {
|
||||
DOM.removeClass(this._element, 'disabled');
|
||||
this._element.classList.remove('disabled');
|
||||
this._element.setAttribute('aria-disabled', String(false));
|
||||
this._element.tabIndex = 0;
|
||||
} else {
|
||||
DOM.addClass(this._element, 'disabled');
|
||||
this._element.classList.add('disabled');
|
||||
this._element.setAttribute('aria-disabled', String(true));
|
||||
DOM.removeTabIndexAndUpdateFocus(this._element);
|
||||
removeTabIndexAndUpdateFocus(this._element);
|
||||
}
|
||||
}
|
||||
|
||||
get enabled() {
|
||||
return !DOM.hasClass(this._element, 'disabled');
|
||||
return !this._element.classList.contains('disabled');
|
||||
}
|
||||
|
||||
focus(): void {
|
||||
@@ -238,7 +236,7 @@ export class ButtonGroup extends Disposable {
|
||||
|
||||
// Implement keyboard access in buttons if there are multiple
|
||||
if (count > 1) {
|
||||
this._register(DOM.addDisposableListener(button.element, DOM.EventType.KEY_DOWN, e => {
|
||||
this._register(addDisposableListener(button.element, EventType.KEY_DOWN, e => {
|
||||
const event = new StandardKeyboardEvent(e);
|
||||
let eventHandled = true;
|
||||
|
||||
@@ -254,7 +252,7 @@ export class ButtonGroup extends Disposable {
|
||||
|
||||
if (eventHandled && typeof buttonIndexToFocus === 'number') {
|
||||
this._buttons[buttonIndexToFocus].focus();
|
||||
DOM.EventHelper.stop(e, true);
|
||||
EventHelper.stop(e, true);
|
||||
}
|
||||
|
||||
}));
|
||||
|
||||
Binary file not shown.
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { reset } from 'vs/base/browser/dom';
|
||||
import { renderCodiconsAsElement } from 'vs/base/browser/codicons';
|
||||
import { renderCodicons } from 'vs/base/browser/codicons';
|
||||
|
||||
export class CodiconLabel {
|
||||
|
||||
@@ -13,7 +13,7 @@ export class CodiconLabel {
|
||||
) { }
|
||||
|
||||
set text(text: string) {
|
||||
reset(this._container, ...renderCodiconsAsElement(text ?? ''));
|
||||
reset(this._container, ...renderCodicons(text ?? ''));
|
||||
}
|
||||
|
||||
set title(title: string) {
|
||||
|
||||
@@ -20,7 +20,7 @@ function initialize() {
|
||||
for (let c of iconRegistry.all) {
|
||||
rules.push(formatRule(c));
|
||||
}
|
||||
codiconStyleSheet.innerHTML = rules.join('\n');
|
||||
codiconStyleSheet.textContent = rules.join('\n');
|
||||
}
|
||||
|
||||
const delayer = new RunOnceScheduler(updateAll, 0);
|
||||
|
||||
@@ -139,7 +139,7 @@ export class ContextView extends Disposable {
|
||||
if (this.shadowRoot) {
|
||||
this.shadowRoot.removeChild(this.view);
|
||||
this.shadowRoot = null;
|
||||
DOM.removeNode(this.shadowRootHostElement!);
|
||||
this.shadowRootHostElement?.remove();
|
||||
this.shadowRootHostElement = null;
|
||||
} else {
|
||||
this.container.removeChild(this.view);
|
||||
@@ -364,6 +364,10 @@ let SHADOW_ROOT_CSS = /* css */ `
|
||||
-ms-user-select: none;
|
||||
}
|
||||
|
||||
:host {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", system-ui, "Ubuntu", "Droid Sans", sans-serif;
|
||||
}
|
||||
|
||||
:host-context(.mac) { font-family: -apple-system, BlinkMacSystemFont, sans-serif; }
|
||||
:host-context(.mac:lang(zh-Hans)) { font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", sans-serif; }
|
||||
:host-context(.mac:lang(zh-Hant)) { font-family: -apple-system, BlinkMacSystemFont, "PingFang TC", sans-serif; }
|
||||
|
||||
@@ -10,7 +10,7 @@ import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IContextViewProvider, IAnchor, AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
|
||||
import { IMenuOptions } from 'vs/base/browser/ui/menu/menu';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { EventHelper, EventType, removeClass, addClass, append, $, addDisposableListener, DOMEvent } from 'vs/base/browser/dom';
|
||||
import { EventHelper, EventType, append, $, addDisposableListener, DOMEvent } from 'vs/base/browser/dom';
|
||||
import { IContextMenuProvider } from 'vs/base/browser/contextmenu';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
@@ -162,7 +162,7 @@ export class Dropdown extends BaseDropdown {
|
||||
show(): void {
|
||||
super.show();
|
||||
|
||||
addClass(this.element, 'active');
|
||||
this.element.classList.add('active');
|
||||
|
||||
this.contextViewProvider.showContextView({
|
||||
getAnchor: () => this.getAnchor(),
|
||||
@@ -184,7 +184,7 @@ export class Dropdown extends BaseDropdown {
|
||||
}
|
||||
|
||||
protected onHide(): void {
|
||||
removeClass(this.element, 'active');
|
||||
this.element.classList.remove('active');
|
||||
}
|
||||
|
||||
hide(): void {
|
||||
@@ -206,8 +206,8 @@ export interface IActionProvider {
|
||||
|
||||
export interface IDropdownMenuOptions extends IBaseDropdownOptions {
|
||||
contextMenuProvider: IContextMenuProvider;
|
||||
actions?: IAction[];
|
||||
actionProvider?: IActionProvider;
|
||||
readonly actions?: IAction[];
|
||||
readonly actionProvider?: IActionProvider;
|
||||
menuClassName?: string;
|
||||
menuAsChild?: boolean; // scope down for #99448
|
||||
}
|
||||
@@ -253,7 +253,7 @@ export class DropdownMenu extends BaseDropdown {
|
||||
show(): void {
|
||||
super.show();
|
||||
|
||||
addClass(this.element, 'active');
|
||||
this.element.classList.add('active');
|
||||
|
||||
this._contextMenuProvider.showContextMenu({
|
||||
getAnchor: () => this.element,
|
||||
@@ -275,6 +275,6 @@ export class DropdownMenu extends BaseDropdown {
|
||||
|
||||
private onHide(): void {
|
||||
this.hide();
|
||||
removeClass(this.element, 'active');
|
||||
this.element.classList.remove('active');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,12 +8,11 @@ import { IAction, IActionRunner, IActionViewItemProvider } from 'vs/base/common/
|
||||
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, $, addClasses } from 'vs/base/browser/dom';
|
||||
import { append, $ } from 'vs/base/browser/dom';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { BaseActionViewItem, 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 { asArray } from 'vs/base/common/arrays';
|
||||
|
||||
export interface IKeybindingProvider {
|
||||
(action: IAction): ResolvedKeybinding | undefined;
|
||||
@@ -60,14 +59,20 @@ export class DropdownMenuActionViewItem extends BaseActionViewItem {
|
||||
const labelRenderer: ILabelRenderer = (el: HTMLElement): IDisposable | null => {
|
||||
this.element = append(el, $('a.action-label'));
|
||||
|
||||
const classNames = this.options.classNames ? asArray(this.options.classNames) : [];
|
||||
let classNames: string[] = [];
|
||||
|
||||
if (typeof this.options.classNames === 'string') {
|
||||
classNames = this.options.classNames.split(/\W+/g).filter(s => !!s);
|
||||
} else if (this.options.classNames) {
|
||||
classNames = this.options.classNames;
|
||||
}
|
||||
|
||||
// todo@aeschli: remove codicon, should come through `this.options.classNames`
|
||||
if (!classNames.find(c => c === 'icon')) {
|
||||
classNames.push('codicon');
|
||||
}
|
||||
|
||||
addClasses(this.element, ...classNames);
|
||||
this.element.classList.add(...classNames);
|
||||
|
||||
this.element.tabIndex = 0;
|
||||
this.element.setAttribute('role', 'button');
|
||||
@@ -78,19 +83,15 @@ export class DropdownMenuActionViewItem extends BaseActionViewItem {
|
||||
return null;
|
||||
};
|
||||
|
||||
const isActionsArray = Array.isArray(this.menuActionsOrProvider);
|
||||
const options: IDropdownMenuOptions = {
|
||||
contextMenuProvider: this.contextMenuProvider,
|
||||
labelRenderer: labelRenderer,
|
||||
menuAsChild: this.options.menuAsChild
|
||||
menuAsChild: this.options.menuAsChild,
|
||||
actions: isActionsArray ? this.menuActionsOrProvider as IAction[] : undefined,
|
||||
actionProvider: isActionsArray ? undefined : this.menuActionsOrProvider as IActionProvider
|
||||
};
|
||||
|
||||
// Render the DropdownMenu around a simple action to toggle it
|
||||
if (Array.isArray(this.menuActionsOrProvider)) {
|
||||
options.actions = this.menuActionsOrProvider;
|
||||
} else {
|
||||
options.actionProvider = this.menuActionsOrProvider as IActionProvider;
|
||||
}
|
||||
|
||||
this.dropdownMenu = this._register(new DropdownMenu(container, options));
|
||||
this._register(this.dropdownMenu.onDidChangeVisibility(visible => {
|
||||
this.element?.setAttribute('aria-expanded', `${visible}`);
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import { renderCodicons } from 'vs/base/common/codicons';
|
||||
import { escape } from 'vs/base/common/strings';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { renderCodicons } from 'vs/base/browser/codicons';
|
||||
|
||||
export interface IHighlight {
|
||||
start: number;
|
||||
@@ -15,7 +15,7 @@ export interface IHighlight {
|
||||
|
||||
export class HighlightedLabel {
|
||||
|
||||
private domNode: HTMLElement;
|
||||
private readonly domNode: HTMLElement;
|
||||
private text: string = '';
|
||||
private title: string = '';
|
||||
private highlights: IHighlight[] = [];
|
||||
@@ -44,10 +44,6 @@ export class HighlightedLabel {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Array.isArray(highlights)) {
|
||||
highlights = [];
|
||||
}
|
||||
|
||||
this.text = text;
|
||||
this.title = title;
|
||||
this.highlights = highlights;
|
||||
@@ -56,7 +52,7 @@ export class HighlightedLabel {
|
||||
|
||||
private render(): void {
|
||||
|
||||
let htmlContent = '';
|
||||
const children: HTMLSpanElement[] = [];
|
||||
let pos = 0;
|
||||
|
||||
for (const highlight of this.highlights) {
|
||||
@@ -64,31 +60,26 @@ export class HighlightedLabel {
|
||||
continue;
|
||||
}
|
||||
if (pos < highlight.start) {
|
||||
htmlContent += '<span>';
|
||||
const substring = this.text.substring(pos, highlight.start);
|
||||
htmlContent += this.supportCodicons ? renderCodicons(escape(substring)) : escape(substring);
|
||||
htmlContent += '</span>';
|
||||
children.push(dom.$('span', undefined, ...this.supportCodicons ? renderCodicons(substring) : [substring]));
|
||||
pos = highlight.end;
|
||||
}
|
||||
if (highlight.extraClasses) {
|
||||
htmlContent += `<span class="highlight ${highlight.extraClasses}">`;
|
||||
} else {
|
||||
htmlContent += `<span class="highlight">`;
|
||||
}
|
||||
|
||||
const substring = this.text.substring(highlight.start, highlight.end);
|
||||
htmlContent += this.supportCodicons ? renderCodicons(escape(substring)) : escape(substring);
|
||||
htmlContent += '</span>';
|
||||
const element = dom.$('span.highlight', undefined, ...this.supportCodicons ? renderCodicons(substring) : [substring]);
|
||||
if (highlight.extraClasses) {
|
||||
element.classList.add(highlight.extraClasses);
|
||||
}
|
||||
children.push(element);
|
||||
pos = highlight.end;
|
||||
}
|
||||
|
||||
if (pos < this.text.length) {
|
||||
htmlContent += '<span>';
|
||||
const substring = this.text.substring(pos);
|
||||
htmlContent += this.supportCodicons ? renderCodicons(escape(substring)) : escape(substring);
|
||||
htmlContent += '</span>';
|
||||
const substring = this.text.substring(pos,);
|
||||
children.push(dom.$('span', undefined, ...this.supportCodicons ? renderCodicons(substring) : [substring]));
|
||||
}
|
||||
|
||||
this.domNode.innerHTML = htmlContent;
|
||||
dom.reset(this.domNode, ...children);
|
||||
if (this.title) {
|
||||
this.domNode.title = this.title;
|
||||
} else {
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
import { getOrDefault } from 'vs/base/common/objects';
|
||||
import { IDisposable, dispose, Disposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { Gesture, EventType as TouchEventType, GestureEvent } from 'vs/base/browser/touch';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { SmoothScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
|
||||
@@ -22,6 +21,7 @@ import { DataTransfers, StaticDND, IDragAndDropData } from 'vs/base/browser/dnd'
|
||||
import { disposableTimeout, Delayer } from 'vs/base/common/async';
|
||||
import { isFirefox } from 'vs/base/browser/browser';
|
||||
import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { $, animate, getContentHeight, getContentWidth, getTopLeftOffset, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
|
||||
|
||||
interface IItem<T> {
|
||||
readonly id: string;
|
||||
@@ -260,7 +260,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
}
|
||||
|
||||
this._horizontalScrolling = value;
|
||||
DOM.toggleClass(this.domNode, 'horizontal-scrolling', this._horizontalScrolling);
|
||||
this.domNode.classList.toggle('horizontal-scrolling', this._horizontalScrolling);
|
||||
|
||||
if (this._horizontalScrolling) {
|
||||
for (const item of this.items) {
|
||||
@@ -268,7 +268,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
}
|
||||
|
||||
this.updateScrollWidth();
|
||||
this.scrollableElement.setScrollDimensions({ width: DOM.getContentWidth(this.domNode) });
|
||||
this.scrollableElement.setScrollDimensions({ width: getContentWidth(this.domNode) });
|
||||
this.rowsContainer.style.width = `${Math.max(this.scrollWidth || 0, this.renderWidth)}px`;
|
||||
} else {
|
||||
this.scrollableElementWidthDelayer.cancel();
|
||||
@@ -303,13 +303,13 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
this.domNode = document.createElement('div');
|
||||
this.domNode.className = 'monaco-list';
|
||||
|
||||
DOM.addClass(this.domNode, this.domId);
|
||||
this.domNode.classList.add(this.domId);
|
||||
this.domNode.tabIndex = 0;
|
||||
|
||||
DOM.toggleClass(this.domNode, 'mouse-support', typeof options.mouseSupport === 'boolean' ? options.mouseSupport : true);
|
||||
this.domNode.classList.toggle('mouse-support', typeof options.mouseSupport === 'boolean' ? options.mouseSupport : true);
|
||||
|
||||
this._horizontalScrolling = getOrDefault(options, o => o.horizontalScrolling, DefaultOptions.horizontalScrolling);
|
||||
DOM.toggleClass(this.domNode, 'horizontal-scrolling', this._horizontalScrolling);
|
||||
this.domNode.classList.toggle('horizontal-scrolling', this._horizontalScrolling);
|
||||
|
||||
this.additionalScrollHeight = typeof options.additionalScrollHeight === 'undefined' ? 0 : options.additionalScrollHeight;
|
||||
|
||||
@@ -325,7 +325,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
|
||||
this.disposables.add(Gesture.addTarget(this.rowsContainer));
|
||||
|
||||
this.scrollable = new Scrollable(getOrDefault(options, o => o.smoothScrolling, false) ? 125 : 0, cb => DOM.scheduleAtNextAnimationFrame(cb));
|
||||
this.scrollable = new Scrollable(getOrDefault(options, o => o.smoothScrolling, false) ? 125 : 0, cb => scheduleAtNextAnimationFrame(cb));
|
||||
this.scrollableElement = this.disposables.add(new SmoothScrollableElement(this.rowsContainer, {
|
||||
alwaysConsumeMouseWheel: true,
|
||||
horizontal: ScrollbarVisibility.Auto,
|
||||
@@ -510,7 +510,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
this.rowsContainer.style.height = `${this._scrollHeight}px`;
|
||||
|
||||
if (!this.scrollableElementUpdateDisposable) {
|
||||
this.scrollableElementUpdateDisposable = DOM.scheduleAtNextAnimationFrame(() => {
|
||||
this.scrollableElementUpdateDisposable = scheduleAtNextAnimationFrame(() => {
|
||||
this.scrollableElement.setScrollDimensions({ scrollHeight: this.scrollHeight });
|
||||
this.updateScrollWidth();
|
||||
this.scrollableElementUpdateDisposable = null;
|
||||
@@ -629,7 +629,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
|
||||
layout(height?: number, width?: number): void {
|
||||
let scrollDimensions: INewScrollDimensions = {
|
||||
height: typeof height === 'number' ? height : DOM.getContentHeight(this.domNode)
|
||||
height: typeof height === 'number' ? height : getContentHeight(this.domNode)
|
||||
};
|
||||
|
||||
if (this.scrollableElementUpdateDisposable) {
|
||||
@@ -649,7 +649,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
|
||||
if (this.horizontalScrolling) {
|
||||
this.scrollableElement.setScrollDimensions({
|
||||
width: typeof width === 'number' ? width : DOM.getContentWidth(this.domNode)
|
||||
width: typeof width === 'number' ? width : getContentWidth(this.domNode)
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -754,7 +754,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
}
|
||||
|
||||
item.row.domNode.style.width = isFirefox ? '-moz-fit-content' : 'fit-content';
|
||||
item.width = DOM.getContentWidth(item.row.domNode);
|
||||
item.width = getContentWidth(item.row.domNode);
|
||||
const style = window.getComputedStyle(item.row.domNode);
|
||||
|
||||
if (style.paddingLeft) {
|
||||
@@ -785,7 +785,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
item.row!.domNode!.setAttribute('aria-posinset', String(this.accessibilityProvider.getPosInSet(item.element, index)));
|
||||
item.row!.domNode!.setAttribute('id', this.getElementDomId(index));
|
||||
|
||||
DOM.toggleClass(item.row!.domNode!, 'drop-target', item.dropTarget);
|
||||
item.row!.domNode!.classList.toggle('drop-target', item.dropTarget);
|
||||
}
|
||||
|
||||
private removeItemFromDOM(index: number): void {
|
||||
@@ -896,7 +896,9 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
this.render(previousRenderRange, e.scrollTop, e.height, e.scrollLeft, e.scrollWidth);
|
||||
|
||||
if (this.supportDynamicHeights) {
|
||||
this._rerender(e.scrollTop, e.height);
|
||||
// Don't update scrollTop from within an scroll event
|
||||
// so we don't break smooth scrolling. #104144
|
||||
this._rerender(e.scrollTop, e.height, false);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Got bad scroll event:', e);
|
||||
@@ -934,7 +936,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
label = String(elements.length);
|
||||
}
|
||||
|
||||
const dragImage = DOM.$('.monaco-drag-image');
|
||||
const dragImage = $('.monaco-drag-image');
|
||||
dragImage.textContent = label;
|
||||
document.body.appendChild(dragImage);
|
||||
event.dataTransfer.setDragImage(dragImage, -10, -10);
|
||||
@@ -1015,11 +1017,11 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
this.currentDragFeedbackDisposable.dispose();
|
||||
|
||||
if (feedback[0] === -1) { // entire list feedback
|
||||
DOM.addClass(this.domNode, 'drop-target');
|
||||
DOM.addClass(this.rowsContainer, 'drop-target');
|
||||
this.domNode.classList.add('drop-target');
|
||||
this.rowsContainer.classList.add('drop-target');
|
||||
this.currentDragFeedbackDisposable = toDisposable(() => {
|
||||
DOM.removeClass(this.domNode, 'drop-target');
|
||||
DOM.removeClass(this.rowsContainer, 'drop-target');
|
||||
this.domNode.classList.remove('drop-target');
|
||||
this.rowsContainer.classList.remove('drop-target');
|
||||
});
|
||||
} else {
|
||||
for (const index of feedback) {
|
||||
@@ -1027,7 +1029,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
item.dropTarget = true;
|
||||
|
||||
if (item.row && item.row.domNode) {
|
||||
DOM.addClass(item.row.domNode, 'drop-target');
|
||||
item.row.domNode.classList.add('drop-target');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1037,7 +1039,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
item.dropTarget = false;
|
||||
|
||||
if (item.row && item.row.domNode) {
|
||||
DOM.removeClass(item.row.domNode, 'drop-target');
|
||||
item.row.domNode.classList.remove('drop-target');
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1093,8 +1095,8 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
|
||||
private setupDragAndDropScrollTopAnimation(event: DragEvent): void {
|
||||
if (!this.dragOverAnimationDisposable) {
|
||||
const viewTop = DOM.getTopLeftOffset(this.domNode).top;
|
||||
this.dragOverAnimationDisposable = DOM.animate(this.animateDragAndDropScrollTop.bind(this, viewTop));
|
||||
const viewTop = getTopLeftOffset(this.domNode).top;
|
||||
this.dragOverAnimationDisposable = animate(this.animateDragAndDropScrollTop.bind(this, viewTop));
|
||||
}
|
||||
|
||||
this.dragOverAnimationStopDisposable.dispose();
|
||||
@@ -1166,7 +1168,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
* Given a stable rendered state, checks every rendered element whether it needs
|
||||
* to be probed for dynamic height. Adjusts scroll height and top if necessary.
|
||||
*/
|
||||
private _rerender(renderTop: number, renderHeight: number): void {
|
||||
private _rerender(renderTop: number, renderHeight: number, updateScrollTop: boolean = true): void {
|
||||
const previousRenderRange = this.getRenderRange(renderTop, renderHeight);
|
||||
|
||||
// Let's remember the second element's position, this helps in scrolling up
|
||||
@@ -1232,7 +1234,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof anchorElementIndex === 'number') {
|
||||
if (updateScrollTop && typeof anchorElementIndex === 'number') {
|
||||
this.scrollTop = this.elementTop(anchorElementIndex) - anchorElementTopDelta!;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,9 +6,8 @@
|
||||
import 'vs/css!./list';
|
||||
import { IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { isNumber } from 'vs/base/common/types';
|
||||
import { range, firstIndex, binarySearch } from 'vs/base/common/arrays';
|
||||
import { range, binarySearch } from 'vs/base/common/arrays';
|
||||
import { memoize } from 'vs/base/common/decorators';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { Gesture } from 'vs/base/browser/touch';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
@@ -27,6 +26,7 @@ import { matchesPrefix } from 'vs/base/common/filters';
|
||||
import { IDragAndDropData } from 'vs/base/browser/dnd';
|
||||
import { alert } from 'vs/base/browser/ui/aria/aria';
|
||||
import { IThemable } from 'vs/base/common/styler';
|
||||
import { createStyleSheet } from 'vs/base/browser/dom';
|
||||
|
||||
interface ITraitChangeEvent {
|
||||
indexes: number[];
|
||||
@@ -55,7 +55,7 @@ class TraitRenderer<T> implements IListRenderer<T, ITraitTemplateData>
|
||||
}
|
||||
|
||||
renderElement(element: T, index: number, templateData: ITraitTemplateData): void {
|
||||
const renderedElementIndex = firstIndex(this.renderedElements, el => el.templateData === templateData);
|
||||
const renderedElementIndex = this.renderedElements.findIndex(el => el.templateData === templateData);
|
||||
|
||||
if (renderedElementIndex >= 0) {
|
||||
const rendered = this.renderedElements[renderedElementIndex];
|
||||
@@ -96,7 +96,7 @@ class TraitRenderer<T> implements IListRenderer<T, ITraitTemplateData>
|
||||
}
|
||||
|
||||
disposeTemplate(templateData: ITraitTemplateData): void {
|
||||
const index = firstIndex(this.renderedElements, el => el.templateData === templateData);
|
||||
const index = this.renderedElements.findIndex(el => el.templateData === templateData);
|
||||
|
||||
if (index < 0) {
|
||||
return;
|
||||
@@ -137,11 +137,11 @@ class Trait<T> implements ISpliceable<boolean>, IDisposable {
|
||||
}
|
||||
|
||||
renderIndex(index: number, container: HTMLElement): void {
|
||||
DOM.toggleClass(container, this._trait, this.contains(index));
|
||||
container.classList.toggle(this._trait, this.contains(index));
|
||||
}
|
||||
|
||||
unrender(container: HTMLElement): void {
|
||||
DOM.removeClass(container, this._trait);
|
||||
container.classList.remove(this._trait);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -230,11 +230,11 @@ export function isInputElement(e: HTMLElement): boolean {
|
||||
}
|
||||
|
||||
export function isMonacoEditor(e: HTMLElement): boolean {
|
||||
if (DOM.hasClass(e, 'monaco-editor')) {
|
||||
if (e.classList.contains('monaco-editor')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (DOM.hasClass(e, 'monaco-list')) {
|
||||
if (e.classList.contains('monaco-list')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -824,10 +824,7 @@ export class DefaultStyleController implements IStyleController {
|
||||
content.push(`.monaco-list-type-filter { box-shadow: 1px 1px 1px ${styles.listMatchesShadow}; }`);
|
||||
}
|
||||
|
||||
const newStyles = content.join('\n');
|
||||
if (newStyles !== this.styleElement.innerHTML) {
|
||||
this.styleElement.innerHTML = newStyles;
|
||||
}
|
||||
this.styleElement.textContent = content.join('\n');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1228,7 +1225,7 @@ export class List<T> implements ISpliceable<T>, IThemable, IDisposable {
|
||||
if (_options.styleController) {
|
||||
this.styleController = _options.styleController(this.view.domId);
|
||||
} else {
|
||||
const styleElement = DOM.createStyleSheet(this.view.domNode);
|
||||
const styleElement = createStyleSheet(this.view.domNode);
|
||||
this.styleController = new DefaultStyleController(styleElement, this.view.domId);
|
||||
}
|
||||
|
||||
@@ -1636,7 +1633,7 @@ export class List<T> implements ISpliceable<T>, IThemable, IDisposable {
|
||||
|
||||
private _onFocusChange(): void {
|
||||
const focus = this.focus.get();
|
||||
DOM.toggleClass(this.view.domNode, 'element-focused', focus.length > 0);
|
||||
this.view.domNode.classList.toggle('element-focused', focus.length > 0);
|
||||
this.onDidChangeActiveDescendant();
|
||||
}
|
||||
|
||||
@@ -1659,9 +1656,9 @@ export class List<T> implements ISpliceable<T>, IThemable, IDisposable {
|
||||
private _onSelectionChange(): void {
|
||||
const selection = this.selection.get();
|
||||
|
||||
DOM.toggleClass(this.view.domNode, 'selection-none', selection.length === 0);
|
||||
DOM.toggleClass(this.view.domNode, 'selection-single', selection.length === 1);
|
||||
DOM.toggleClass(this.view.domNode, 'selection-multiple', selection.length > 1);
|
||||
this.view.domNode.classList.toggle('selection-none', selection.length === 0);
|
||||
this.view.domNode.classList.toggle('selection-single', selection.length === 1);
|
||||
this.view.domNode.classList.toggle('selection-multiple', selection.length > 1);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { IListRenderer } from './list';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { $, removeClass } from 'vs/base/browser/dom';
|
||||
import { $ } from 'vs/base/browser/dom';
|
||||
|
||||
export interface IRow {
|
||||
domNode: HTMLElement | null;
|
||||
@@ -60,7 +60,7 @@ export class RowCache<T> implements IDisposable {
|
||||
private releaseRow(row: IRow): void {
|
||||
const { domNode, templateId } = row;
|
||||
if (domNode) {
|
||||
removeClass(domNode, 'scrolling');
|
||||
domNode.classList.remove('scrolling');
|
||||
removeFromParent(domNode);
|
||||
}
|
||||
|
||||
|
||||
@@ -229,11 +229,11 @@ export class Menu extends ActionBar {
|
||||
private initializeStyleSheet(container: HTMLElement): void {
|
||||
if (isInShadowDOM(container)) {
|
||||
this.styleSheet = createStyleSheet(container);
|
||||
this.styleSheet.innerHTML = MENU_WIDGET_CSS;
|
||||
this.styleSheet.textContent = MENU_WIDGET_CSS;
|
||||
} else {
|
||||
if (!Menu.globalStyleSheet) {
|
||||
Menu.globalStyleSheet = createStyleSheet();
|
||||
Menu.globalStyleSheet.innerHTML = MENU_WIDGET_CSS;
|
||||
Menu.globalStyleSheet.textContent = MENU_WIDGET_CSS;
|
||||
}
|
||||
|
||||
this.styleSheet = Menu.globalStyleSheet;
|
||||
|
||||
@@ -532,25 +532,31 @@ export class MenuBar extends Disposable {
|
||||
// Update the button label to reflect mnemonics
|
||||
|
||||
if (this.options.enableMnemonics) {
|
||||
let innerHtml = strings.escape(label);
|
||||
let cleanLabel = strings.escape(label);
|
||||
|
||||
// This is global so reset it
|
||||
MENU_ESCAPED_MNEMONIC_REGEX.lastIndex = 0;
|
||||
let escMatch = MENU_ESCAPED_MNEMONIC_REGEX.exec(innerHtml);
|
||||
let escMatch = MENU_ESCAPED_MNEMONIC_REGEX.exec(cleanLabel);
|
||||
|
||||
// We can't use negative lookbehind so we match our negative and skip
|
||||
while (escMatch && escMatch[1]) {
|
||||
escMatch = MENU_ESCAPED_MNEMONIC_REGEX.exec(innerHtml);
|
||||
escMatch = MENU_ESCAPED_MNEMONIC_REGEX.exec(cleanLabel);
|
||||
}
|
||||
|
||||
const replaceDoubleEscapes = (str: string) => str.replace(/&&/g, '&');
|
||||
|
||||
if (escMatch) {
|
||||
innerHtml = `${innerHtml.substr(0, escMatch.index)}<mnemonic aria-hidden="true">${escMatch[3]}</mnemonic>${innerHtml.substr(escMatch.index + escMatch[0].length)}`;
|
||||
titleElement.innerText = '';
|
||||
titleElement.append(
|
||||
strings.ltrim(replaceDoubleEscapes(cleanLabel.substr(0, escMatch.index)), ' '),
|
||||
$('mnemonic', { 'aria-hidden': 'true' }, escMatch[3]),
|
||||
strings.rtrim(replaceDoubleEscapes(cleanLabel.substr(escMatch.index + escMatch[0].length)), ' ')
|
||||
);
|
||||
} else {
|
||||
titleElement.innerText = replaceDoubleEscapes(cleanLabel).trim();
|
||||
}
|
||||
|
||||
innerHtml = innerHtml.replace(/&&/g, '&');
|
||||
titleElement.innerHTML = innerHtml;
|
||||
} else {
|
||||
titleElement.innerHTML = cleanMenuLabel.replace(/&&/g, '&');
|
||||
titleElement.innerText = cleanMenuLabel.replace(/&&/g, '&');
|
||||
}
|
||||
|
||||
let mnemonicMatches = MENU_MNEMONIC_REGEX.exec(label);
|
||||
|
||||
@@ -10,7 +10,7 @@ import * as types from 'vs/base/common/types';
|
||||
import { EventType, GestureEvent, Gesture } from 'vs/base/browser/touch';
|
||||
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { getElementsByTagName, EventHelper, createStyleSheet, addDisposableListener, append, $, addClass, removeClass, toggleClass } from 'vs/base/browser/dom';
|
||||
import { getElementsByTagName, EventHelper, createStyleSheet, addDisposableListener, append, $ } from 'vs/base/browser/dom';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
|
||||
const DEBUG = false;
|
||||
@@ -86,9 +86,9 @@ export class Sash extends Disposable {
|
||||
return;
|
||||
}
|
||||
|
||||
toggleClass(this.el, 'disabled', state === SashState.Disabled);
|
||||
toggleClass(this.el, 'minimum', state === SashState.Minimum);
|
||||
toggleClass(this.el, 'maximum', state === SashState.Maximum);
|
||||
this.el.classList.toggle('disabled', state === SashState.Disabled);
|
||||
this.el.classList.toggle('minimum', state === SashState.Minimum);
|
||||
this.el.classList.toggle('maximum', state === SashState.Maximum);
|
||||
|
||||
this._state = state;
|
||||
this._onDidEnablementChange.fire(state);
|
||||
@@ -151,7 +151,7 @@ export class Sash extends Disposable {
|
||||
this.el = append(container, $('.monaco-sash'));
|
||||
|
||||
if (isMacintosh) {
|
||||
addClass(this.el, 'mac');
|
||||
this.el.classList.add('mac');
|
||||
}
|
||||
|
||||
this._register(domEvent(this.el, 'mousedown')(this.onMouseDown, this));
|
||||
@@ -185,14 +185,14 @@ export class Sash extends Disposable {
|
||||
this.orientation = options.orientation || Orientation.VERTICAL;
|
||||
|
||||
if (this.orientation === Orientation.HORIZONTAL) {
|
||||
addClass(this.el, 'horizontal');
|
||||
removeClass(this.el, 'vertical');
|
||||
this.el.classList.add('horizontal');
|
||||
this.el.classList.remove('vertical');
|
||||
} else {
|
||||
removeClass(this.el, 'horizontal');
|
||||
addClass(this.el, 'vertical');
|
||||
this.el.classList.remove('horizontal');
|
||||
this.el.classList.add('vertical');
|
||||
}
|
||||
|
||||
toggleClass(this.el, 'debug', DEBUG);
|
||||
this.el.classList.toggle('debug', DEBUG);
|
||||
|
||||
this.layout();
|
||||
}
|
||||
@@ -238,7 +238,7 @@ export class Sash extends Disposable {
|
||||
const altKey = mouseDownEvent.altKey;
|
||||
const startEvent: ISashEvent = { startX, currentX: startX, startY, currentY: startY, altKey };
|
||||
|
||||
addClass(this.el, 'active');
|
||||
this.el.classList.add('active');
|
||||
this._onDidStart.fire(startEvent);
|
||||
|
||||
// fix https://github.com/Microsoft/vscode/issues/21675
|
||||
@@ -266,7 +266,7 @@ export class Sash extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
style.innerHTML = `* { cursor: ${cursor} !important; }`;
|
||||
style.textContent = `* { cursor: ${cursor} !important; }`;
|
||||
};
|
||||
|
||||
const disposables = new DisposableStore();
|
||||
@@ -290,7 +290,7 @@ export class Sash extends Disposable {
|
||||
|
||||
this.el.removeChild(style);
|
||||
|
||||
removeClass(this.el, 'active');
|
||||
this.el.classList.remove('active');
|
||||
this._onDidEnd.fire();
|
||||
|
||||
disposables.dispose();
|
||||
@@ -396,11 +396,11 @@ export class Sash extends Disposable {
|
||||
}
|
||||
|
||||
private onOrthogonalStartSashEnablementChange(state: SashState): void {
|
||||
toggleClass(this.el, 'orthogonal-start', state !== SashState.Disabled);
|
||||
this.el.classList.toggle('orthogonal-start', state !== SashState.Disabled);
|
||||
}
|
||||
|
||||
private onOrthogonalEndSashEnablementChange(state: SashState): void {
|
||||
toggleClass(this.el, 'orthogonal-end', state !== SashState.Disabled);
|
||||
this.el.classList.toggle('orthogonal-end', state !== SashState.Disabled);
|
||||
}
|
||||
|
||||
private getOrthogonalSash(e: MouseEvent): Sash | undefined {
|
||||
|
||||
@@ -45,7 +45,7 @@ class SelectListRenderer implements IListRenderer<ISelectOptionItem, ISelectList
|
||||
data.text = dom.append(container, $('.option-text'));
|
||||
data.decoratorRight = dom.append(container, $('.option-decorator-right'));
|
||||
data.itemDescription = dom.append(container, $('.option-text-description'));
|
||||
dom.addClass(data.itemDescription, 'visually-hidden');
|
||||
data.itemDescription.classList.add('visually-hidden');
|
||||
|
||||
return data;
|
||||
}
|
||||
@@ -70,10 +70,10 @@ class SelectListRenderer implements IListRenderer<ISelectOptionItem, ISelectList
|
||||
|
||||
// pseudo-select disabled option
|
||||
if (isDisabled) {
|
||||
dom.addClass(data.root, 'option-disabled');
|
||||
data.root.classList.add('option-disabled');
|
||||
} else {
|
||||
// Make sure we do class removal from prior template rendering
|
||||
dom.removeClass(data.root, 'option-disabled');
|
||||
data.root.classList.remove('option-disabled');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
|
||||
this.contextViewProvider = contextViewProvider;
|
||||
this.selectDropDownContainer = dom.$('.monaco-select-box-dropdown-container');
|
||||
// Use custom CSS vars for padding calculation (shared with parent select)
|
||||
dom.addClass(this.selectDropDownContainer, 'monaco-select-box-dropdown-padding');
|
||||
this.selectDropDownContainer.classList.add('monaco-select-box-dropdown-padding');
|
||||
|
||||
// Setup container for select option details
|
||||
this.selectionDetailsPane = dom.append(this.selectDropDownContainer, $('.select-box-details-pane'));
|
||||
@@ -311,7 +311,7 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
|
||||
|
||||
public render(container: HTMLElement): void {
|
||||
this.container = container;
|
||||
dom.addClass(container, 'select-container');
|
||||
container.classList.add('select-container');
|
||||
container.appendChild(this.selectElement);
|
||||
this.applyStyles();
|
||||
}
|
||||
@@ -369,7 +369,7 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
|
||||
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.option-disabled:hover { outline: none !important; }`);
|
||||
}
|
||||
|
||||
this.styleElement.innerHTML = content.join('\n');
|
||||
this.styleElement.textContent = content.join('\n');
|
||||
|
||||
this.applyStyles();
|
||||
}
|
||||
@@ -451,8 +451,8 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
|
||||
this.layoutSelectDropDown();
|
||||
},
|
||||
onHide: () => {
|
||||
dom.toggleClass(this.selectDropDownContainer, 'visible', false);
|
||||
dom.toggleClass(this.selectElement, 'synthetic-focus', false);
|
||||
this.selectDropDownContainer.classList.remove('visible');
|
||||
this.selectElement.classList.remove('synthetic-focus');
|
||||
},
|
||||
anchorPosition: this._dropDownPosition
|
||||
}, this.selectBoxOptions.optionsAsChildren ? this.container : undefined);
|
||||
@@ -466,8 +466,8 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
|
||||
render: (container: HTMLElement) => this.renderSelectDropDown(container),
|
||||
layout: () => this.layoutSelectDropDown(),
|
||||
onHide: () => {
|
||||
dom.toggleClass(this.selectDropDownContainer, 'visible', false);
|
||||
dom.toggleClass(this.selectElement, 'synthetic-focus', false);
|
||||
this.selectDropDownContainer.classList.remove('visible');
|
||||
this.selectElement.classList.remove('synthetic-focus');
|
||||
},
|
||||
anchorPosition: this._dropDownPosition
|
||||
}, this.selectBoxOptions.optionsAsChildren ? this.container : undefined);
|
||||
@@ -514,42 +514,15 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
|
||||
|
||||
// Iterate over detailed descriptions, find max height
|
||||
private measureMaxDetailsHeight(): number {
|
||||
|
||||
let maxDetailsPaneHeight = 0;
|
||||
this.options.forEach((option, index) => {
|
||||
|
||||
this.selectionDetailsPane.innerText = '';
|
||||
|
||||
if (option.description) {
|
||||
if (option.descriptionIsMarkdown) {
|
||||
this.selectionDetailsPane.appendChild(this.renderDescriptionMarkdown(option.description));
|
||||
} else {
|
||||
this.selectionDetailsPane.innerText = option.description;
|
||||
}
|
||||
this.selectionDetailsPane.style.display = 'block';
|
||||
} else {
|
||||
this.selectionDetailsPane.style.display = 'none';
|
||||
}
|
||||
this.options.forEach((_option, index) => {
|
||||
this.updateDetail(index);
|
||||
|
||||
if (this.selectionDetailsPane.offsetHeight > maxDetailsPaneHeight) {
|
||||
maxDetailsPaneHeight = this.selectionDetailsPane.offsetHeight;
|
||||
}
|
||||
});
|
||||
|
||||
// Reset description to selected
|
||||
|
||||
this.selectionDetailsPane.innerText = '';
|
||||
const description = this.options[this.selected].description || null;
|
||||
const descriptionIsMarkdown = this.options[this.selected].descriptionIsMarkdown || null;
|
||||
|
||||
if (description) {
|
||||
if (descriptionIsMarkdown) {
|
||||
this.selectionDetailsPane.appendChild(this.renderDescriptionMarkdown(description));
|
||||
} else {
|
||||
this.selectionDetailsPane.innerText = description;
|
||||
}
|
||||
this.selectionDetailsPane.style.display = 'block';
|
||||
}
|
||||
return maxDetailsPaneHeight;
|
||||
}
|
||||
|
||||
@@ -567,7 +540,7 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
|
||||
if (this.selectList) {
|
||||
|
||||
// Make visible to enable measurements
|
||||
dom.toggleClass(this.selectDropDownContainer, 'visible', true);
|
||||
this.selectDropDownContainer.classList.add('visible');
|
||||
|
||||
const selectPosition = dom.getDomNodePagePosition(this.selectElement);
|
||||
const styles = getComputedStyle(this.selectElement);
|
||||
@@ -622,8 +595,8 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
|
||||
this.selectDropDownContainer.appendChild(this.selectionDetailsPane);
|
||||
this.selectDropDownContainer.appendChild(this.selectDropDownListContainer);
|
||||
|
||||
dom.removeClass(this.selectionDetailsPane, 'border-top');
|
||||
dom.addClass(this.selectionDetailsPane, 'border-bottom');
|
||||
this.selectionDetailsPane.classList.remove('border-top');
|
||||
this.selectionDetailsPane.classList.add('border-bottom');
|
||||
|
||||
} else {
|
||||
this._dropDownPosition = AnchorPosition.BELOW;
|
||||
@@ -632,8 +605,8 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
|
||||
this.selectDropDownContainer.appendChild(this.selectDropDownListContainer);
|
||||
this.selectDropDownContainer.appendChild(this.selectionDetailsPane);
|
||||
|
||||
dom.removeClass(this.selectionDetailsPane, 'border-bottom');
|
||||
dom.addClass(this.selectionDetailsPane, 'border-top');
|
||||
this.selectionDetailsPane.classList.remove('border-bottom');
|
||||
this.selectionDetailsPane.classList.add('border-top');
|
||||
}
|
||||
// Do full layout on showSelectDropDown only
|
||||
return true;
|
||||
@@ -687,12 +660,14 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
|
||||
this.selectDropDownContainer.style.height = (listHeight + verticalPadding) + 'px';
|
||||
}
|
||||
|
||||
this.updateDetail(this.selected);
|
||||
|
||||
this.selectDropDownContainer.style.width = selectOptimalWidth;
|
||||
|
||||
// Maintain focus outline on parent select as well as list container - tabindex for focus
|
||||
this.selectDropDownListContainer.setAttribute('tabindex', '0');
|
||||
dom.toggleClass(this.selectElement, 'synthetic-focus', true);
|
||||
dom.toggleClass(this.selectDropDownContainer, 'synthetic-focus', true);
|
||||
this.selectElement.classList.add('synthetic-focus');
|
||||
this.selectDropDownContainer.classList.add('synthetic-focus');
|
||||
|
||||
return true;
|
||||
} else {
|
||||
@@ -717,7 +692,6 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
|
||||
|
||||
container.innerHTML = this.options[longest]?.text + (!!this.options[longest]?.decoratorRight ? (this.options[longest].decoratorRight + ' ') : ''); // {{ SQL CARBON EDIT }} Don't error if no option found (empty list)
|
||||
|
||||
|
||||
elementWidth = dom.getTotalWidth(container);
|
||||
}
|
||||
|
||||
@@ -883,8 +857,11 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
|
||||
return;
|
||||
}
|
||||
|
||||
this.updateDetail(e.indexes[0]);
|
||||
}
|
||||
|
||||
private updateDetail(selectedIndex: number): void {
|
||||
this.selectionDetailsPane.innerText = '';
|
||||
const selectedIndex = e.indexes[0];
|
||||
const description = this.options[selectedIndex].description;
|
||||
const descriptionIsMarkdown = this.options[selectedIndex].descriptionIsMarkdown;
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ export class SelectBoxNative extends Disposable implements ISelectBoxDelegate {
|
||||
}
|
||||
|
||||
public render(container: HTMLElement): void {
|
||||
dom.addClass(container, 'select-container');
|
||||
container.classList.add('select-container');
|
||||
container.appendChild(this.selectElement);
|
||||
this.setOptions(this.options, this.selected);
|
||||
this.applyStyles();
|
||||
|
||||
@@ -9,8 +9,7 @@ import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { $, append, addClass, removeClass, toggleClass, trackFocus, EventHelper, clearNode } from 'vs/base/browser/dom';
|
||||
import { firstIndex } from 'vs/base/common/arrays';
|
||||
import { $, append, trackFocus, EventHelper, clearNode } from 'vs/base/browser/dom';
|
||||
import { Color, RGBA } from 'vs/base/common/color';
|
||||
import { SplitView, IView } from './splitview';
|
||||
import { isFirefox } from 'vs/base/browser/browser';
|
||||
@@ -143,7 +142,7 @@ export abstract class Pane extends Disposable implements IView {
|
||||
}
|
||||
|
||||
if (this.element) {
|
||||
toggleClass(this.element, 'expanded', expanded);
|
||||
this.element.classList.toggle('expanded', expanded);
|
||||
}
|
||||
|
||||
this._expanded = !!expanded;
|
||||
@@ -191,8 +190,8 @@ export abstract class Pane extends Disposable implements IView {
|
||||
this._orientation = orientation;
|
||||
|
||||
if (this.element) {
|
||||
toggleClass(this.element, 'horizontal', this.orientation === Orientation.HORIZONTAL);
|
||||
toggleClass(this.element, 'vertical', this.orientation === Orientation.VERTICAL);
|
||||
this.element.classList.toggle('horizontal', this.orientation === Orientation.HORIZONTAL);
|
||||
this.element.classList.toggle('vertical', this.orientation === Orientation.VERTICAL);
|
||||
}
|
||||
|
||||
if (this.header) {
|
||||
@@ -201,9 +200,9 @@ export abstract class Pane extends Disposable implements IView {
|
||||
}
|
||||
|
||||
render(): void {
|
||||
toggleClass(this.element, 'expanded', this.isExpanded());
|
||||
toggleClass(this.element, 'horizontal', this.orientation === Orientation.HORIZONTAL);
|
||||
toggleClass(this.element, 'vertical', this.orientation === Orientation.VERTICAL);
|
||||
this.element.classList.toggle('expanded', this.isExpanded());
|
||||
this.element.classList.toggle('horizontal', this.orientation === Orientation.HORIZONTAL);
|
||||
this.element.classList.toggle('vertical', this.orientation === Orientation.VERTICAL);
|
||||
|
||||
this.header = $('.pane-header');
|
||||
append(this.element, this.header);
|
||||
@@ -215,8 +214,8 @@ export abstract class Pane extends Disposable implements IView {
|
||||
|
||||
const focusTracker = trackFocus(this.header);
|
||||
this._register(focusTracker);
|
||||
this._register(focusTracker.onDidFocus(() => addClass(this.header, 'focused'), null));
|
||||
this._register(focusTracker.onDidBlur(() => removeClass(this.header, 'focused'), null));
|
||||
this._register(focusTracker.onDidFocus(() => this.header.classList.add('focused'), null));
|
||||
this._register(focusTracker.onDidBlur(() => this.header.classList.remove('focused'), null));
|
||||
|
||||
this.updateHeader();
|
||||
|
||||
@@ -255,7 +254,7 @@ export abstract class Pane extends Disposable implements IView {
|
||||
const height = this._orientation === Orientation.VERTICAL ? size - headerSize : this.orthogonalSize - headerSize;
|
||||
|
||||
if (this.isExpanded()) {
|
||||
toggleClass(this.body, 'wide', width >= 600);
|
||||
this.body.classList.toggle('wide', width >= 600);
|
||||
this.layoutBody(height, width);
|
||||
this.expandedSize = size;
|
||||
}
|
||||
@@ -275,8 +274,8 @@ export abstract class Pane extends Disposable implements IView {
|
||||
const expanded = !this.headerVisible || this.isExpanded();
|
||||
|
||||
this.header.style.lineHeight = `${this.headerSize}px`;
|
||||
toggleClass(this.header, 'hidden', !this.headerVisible);
|
||||
toggleClass(this.header, 'expanded', expanded);
|
||||
this.header.classList.toggle('hidden', !this.headerVisible);
|
||||
this.header.classList.toggle('expanded', expanded);
|
||||
this.header.setAttribute('aria-expanded', String(expanded));
|
||||
|
||||
this.header.style.color = this.styles.headerForeground ? this.styles.headerForeground.toString() : '';
|
||||
@@ -474,7 +473,7 @@ export class PaneView extends Disposable {
|
||||
}
|
||||
|
||||
removePane(pane: Pane): void {
|
||||
const index = firstIndex(this.paneItems, item => item.pane === pane);
|
||||
const index = this.paneItems.findIndex(item => item.pane === pane);
|
||||
|
||||
if (index === -1) {
|
||||
return;
|
||||
@@ -486,8 +485,8 @@ export class PaneView extends Disposable {
|
||||
}
|
||||
|
||||
movePane(from: Pane, to: Pane): void {
|
||||
const fromIndex = firstIndex(this.paneItems, item => item.pane === from);
|
||||
const toIndex = firstIndex(this.paneItems, item => item.pane === to);
|
||||
const fromIndex = this.paneItems.findIndex(item => item.pane === from);
|
||||
const toIndex = this.paneItems.findIndex(item => item.pane === to);
|
||||
|
||||
if (fromIndex === -1 || toIndex === -1) {
|
||||
return;
|
||||
@@ -500,7 +499,7 @@ export class PaneView extends Disposable {
|
||||
}
|
||||
|
||||
resizePane(pane: Pane, size: number): void {
|
||||
const index = firstIndex(this.paneItems, item => item.pane === pane);
|
||||
const index = this.paneItems.findIndex(item => item.pane === pane);
|
||||
|
||||
if (index === -1) {
|
||||
return;
|
||||
@@ -510,7 +509,7 @@ export class PaneView extends Disposable {
|
||||
}
|
||||
|
||||
getPaneSize(pane: Pane): number {
|
||||
const index = firstIndex(this.paneItems, item => item.pane === pane);
|
||||
const index = this.paneItems.findIndex(item => item.pane === pane);
|
||||
|
||||
if (index === -1) {
|
||||
return -1;
|
||||
@@ -561,11 +560,11 @@ export class PaneView extends Disposable {
|
||||
window.clearTimeout(this.animationTimer);
|
||||
}
|
||||
|
||||
addClass(this.el, 'animated');
|
||||
this.el.classList.add('animated');
|
||||
|
||||
this.animationTimer = window.setTimeout(() => {
|
||||
this.animationTimer = undefined;
|
||||
removeClass(this.el, 'animated');
|
||||
this.el.classList.remove('animated');
|
||||
}, 200);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,12 +7,12 @@ import 'vs/css!./splitview';
|
||||
import { IDisposable, toDisposable, Disposable, combinedDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import * as types from 'vs/base/common/types';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { clamp } from 'vs/base/common/numbers';
|
||||
import { range, firstIndex, pushToStart, pushToEnd } from 'vs/base/common/arrays';
|
||||
import { range, pushToStart, pushToEnd } from 'vs/base/common/arrays';
|
||||
import { Sash, Orientation, ISashEvent as IBaseSashEvent, SashState } from 'vs/base/browser/ui/sash/sash';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { $, append } from 'vs/base/browser/dom';
|
||||
export { Orientation } from 'vs/base/browser/ui/sash/sash';
|
||||
|
||||
export interface ISplitViewStyles {
|
||||
@@ -93,7 +93,7 @@ abstract class ViewItem<TLayoutContext> {
|
||||
this.size = 0;
|
||||
}
|
||||
|
||||
dom.toggleClass(this.container, 'visible', visible);
|
||||
this.container.classList.toggle('visible', visible);
|
||||
|
||||
if (this.view.setVisible) {
|
||||
this.view.setVisible(visible);
|
||||
@@ -122,7 +122,7 @@ abstract class ViewItem<TLayoutContext> {
|
||||
if (typeof size === 'number') {
|
||||
this._size = size;
|
||||
this._cachedVisibleSize = undefined;
|
||||
dom.addClass(container, 'visible');
|
||||
container.classList.add('visible');
|
||||
} else {
|
||||
this._size = 0;
|
||||
this._cachedVisibleSize = size.cachedVisibleSize;
|
||||
@@ -296,12 +296,12 @@ export class SplitView<TLayoutContext = undefined> extends Disposable {
|
||||
this.proportionalLayout = types.isUndefined(options.proportionalLayout) ? true : !!options.proportionalLayout;
|
||||
|
||||
this.el = document.createElement('div');
|
||||
dom.addClass(this.el, 'monaco-split-view2');
|
||||
dom.addClass(this.el, this.orientation === Orientation.VERTICAL ? 'vertical' : 'horizontal');
|
||||
this.el.classList.add('monaco-split-view2');
|
||||
this.el.classList.add(this.orientation === Orientation.VERTICAL ? 'vertical' : 'horizontal');
|
||||
container.appendChild(this.el);
|
||||
|
||||
this.sashContainer = dom.append(this.el, dom.$('.sash-container'));
|
||||
this.viewContainer = dom.append(this.el, dom.$('.split-view-container'));
|
||||
this.sashContainer = append(this.el, $('.sash-container'));
|
||||
this.viewContainer = append(this.el, $('.split-view-container'));
|
||||
|
||||
this.style(options.styles || defaultStyles);
|
||||
|
||||
@@ -323,10 +323,10 @@ export class SplitView<TLayoutContext = undefined> extends Disposable {
|
||||
|
||||
style(styles: ISplitViewStyles): void {
|
||||
if (styles.separatorBorder.isTransparent()) {
|
||||
dom.removeClass(this.el, 'separator-border');
|
||||
this.el.classList.remove('separator-border');
|
||||
this.el.style.removeProperty('--separator-border');
|
||||
} else {
|
||||
dom.addClass(this.el, 'separator-border');
|
||||
this.el.classList.add('separator-border');
|
||||
this.el.style.setProperty('--separator-border', styles.separatorBorder.toString());
|
||||
}
|
||||
}
|
||||
@@ -460,7 +460,7 @@ export class SplitView<TLayoutContext = undefined> extends Disposable {
|
||||
item.enabled = false;
|
||||
}
|
||||
|
||||
const index = firstIndex(this.sashItems, item => item.sash === sash);
|
||||
const index = this.sashItems.findIndex(item => item.sash === sash);
|
||||
|
||||
// This way, we can press Alt while we resize a sash, macOS style!
|
||||
const disposable = combinedDisposable(
|
||||
@@ -657,7 +657,7 @@ export class SplitView<TLayoutContext = undefined> extends Disposable {
|
||||
this.state = State.Busy;
|
||||
|
||||
// Add view
|
||||
const container = dom.$('.split-view-view');
|
||||
const container = $('.split-view-view');
|
||||
|
||||
if (index === this.viewItems.length) {
|
||||
this.viewContainer.appendChild(container);
|
||||
@@ -709,11 +709,11 @@ export class SplitView<TLayoutContext = undefined> extends Disposable {
|
||||
const onStartDisposable = onStart(this.onSashStart, this);
|
||||
const onChange = Event.map(sash.onDidChange, sashEventMapper);
|
||||
const onChangeDisposable = onChange(this.onSashChange, this);
|
||||
const onEnd = Event.map(sash.onDidEnd, () => firstIndex(this.sashItems, item => item.sash === sash));
|
||||
const onEnd = Event.map(sash.onDidEnd, () => this.sashItems.findIndex(item => item.sash === sash));
|
||||
const onEndDisposable = onEnd(this.onSashEnd, this);
|
||||
|
||||
const onDidResetDisposable = sash.onDidReset(() => {
|
||||
const index = firstIndex(this.sashItems, item => item.sash === sash);
|
||||
const index = this.sashItems.findIndex(item => item.sash === sash);
|
||||
const upIndexes = range(index, -1);
|
||||
const downIndexes = range(index + 1, this.viewItems.length);
|
||||
const snapBeforeIndex = this.findFirstSnapIndex(upIndexes);
|
||||
|
||||
@@ -72,7 +72,7 @@ export class ToolBar extends Disposable {
|
||||
actionViewItemProvider: this.options.actionViewItemProvider,
|
||||
actionRunner: this.actionRunner,
|
||||
keybindingProvider: this.options.getKeyBinding,
|
||||
classNames: toolBarMoreIcon.classNames,
|
||||
classNames: toolBarMoreIcon.classNamesArray,
|
||||
anchorAlignmentProvider: this.options.anchorAlignmentProvider,
|
||||
menuAsChild: !!this.options.renderDropdownAsChildElement
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import 'vs/css!./media/tree';
|
||||
import { IDisposable, dispose, Disposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IListOptions, List, IListStyles, MouseController, DefaultKeyboardNavigationDelegate, isInputElement, isMonacoEditor } from 'vs/base/browser/ui/list/listWidget';
|
||||
import { IListVirtualDelegate, IListRenderer, IListMouseEvent, IListContextMenuEvent, IListDragAndDrop, IListDragOverReaction, IKeyboardNavigationLabelProvider, IIdentityProvider, IKeyboardNavigationDelegate } from 'vs/base/browser/ui/list/list';
|
||||
import { append, $, toggleClass, getDomNodePagePosition, removeClass, addClass, hasClass, hasParentWithClass, createStyleSheet, clearNode, addClasses, removeClasses } from 'vs/base/browser/dom';
|
||||
import { append, $, getDomNodePagePosition, hasParentWithClass, createStyleSheet, clearNode } from 'vs/base/browser/dom';
|
||||
import { Event, Relay, Emitter, EventBufferer } from 'vs/base/common/event';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
@@ -405,10 +405,10 @@ class TreeRenderer<T, TFilterData, TRef, TTemplateData> implements IListRenderer
|
||||
}
|
||||
|
||||
if (node.collapsible && (!this.hideTwistiesOfChildlessElements || node.visibleChildrenCount > 0)) {
|
||||
addClasses(templateData.twistie, treeItemExpandedIcon.classNames, 'collapsible');
|
||||
toggleClass(templateData.twistie, 'collapsed', node.collapsed);
|
||||
templateData.twistie.classList.add(...treeItemExpandedIcon.classNamesArray, 'collapsible');
|
||||
templateData.twistie.classList.toggle('collapsed', node.collapsed);
|
||||
} else {
|
||||
removeClasses(templateData.twistie, treeItemExpandedIcon.classNames, 'collapsible', 'collapsed');
|
||||
templateData.twistie.classList.remove(...treeItemExpandedIcon.classNamesArray, 'collapsible', 'collapsed');
|
||||
}
|
||||
|
||||
if (node.collapsible) {
|
||||
@@ -443,7 +443,7 @@ class TreeRenderer<T, TFilterData, TRef, TTemplateData> implements IListRenderer
|
||||
const guide = $<HTMLDivElement>('.indent-guide', { style: `width: ${this.indent}px` });
|
||||
|
||||
if (this.activeIndentNodes.has(parent)) {
|
||||
addClass(guide, 'active');
|
||||
guide.classList.add('active');
|
||||
}
|
||||
|
||||
if (templateData.indent.childElementCount === 0) {
|
||||
@@ -486,13 +486,13 @@ class TreeRenderer<T, TFilterData, TRef, TTemplateData> implements IListRenderer
|
||||
|
||||
this.activeIndentNodes.forEach(node => {
|
||||
if (!set.has(node)) {
|
||||
this.renderedIndentGuides.forEach(node, line => removeClass(line, 'active'));
|
||||
this.renderedIndentGuides.forEach(node, line => line.classList.remove('active'));
|
||||
}
|
||||
});
|
||||
|
||||
set.forEach(node => {
|
||||
if (!this.activeIndentNodes.has(node)) {
|
||||
this.renderedIndentGuides.forEach(node, line => addClass(line, 'active'));
|
||||
this.renderedIndentGuides.forEach(node, line => line.classList.add('active'));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -833,10 +833,10 @@ class TypeFilterController<T, TFilterData> implements IDisposable {
|
||||
};
|
||||
|
||||
updatePosition();
|
||||
removeClass(this.domNode, positionClassName);
|
||||
this.domNode.classList.remove(positionClassName);
|
||||
|
||||
addClass(this.domNode, 'dragging');
|
||||
disposables.add(toDisposable(() => removeClass(this.domNode, 'dragging')));
|
||||
this.domNode.classList.add('dragging');
|
||||
disposables.add(toDisposable(() => this.domNode.classList.remove('dragging')));
|
||||
|
||||
domEvent(document, 'dragover')(onDragOver, null, disposables);
|
||||
domEvent(this.domNode, 'dragend')(onDragEnd, null, disposables);
|
||||
@@ -864,12 +864,12 @@ class TypeFilterController<T, TFilterData> implements IDisposable {
|
||||
|
||||
private updateFilterOnTypeTitleAndIcon(): void {
|
||||
if (this.filterOnType) {
|
||||
removeClasses(this.filterOnTypeDomNode, treeFilterOnTypeOffIcon.classNames);
|
||||
addClasses(this.filterOnTypeDomNode, treeFilterOnTypeOnIcon.classNames);
|
||||
this.filterOnTypeDomNode.classList.remove(...treeFilterOnTypeOffIcon.classNamesArray);
|
||||
this.filterOnTypeDomNode.classList.add(...treeFilterOnTypeOnIcon.classNamesArray);
|
||||
this.filterOnTypeDomNode.title = localize('disable filter on type', "Disable Filter on Type");
|
||||
} else {
|
||||
removeClasses(this.filterOnTypeDomNode, treeFilterOnTypeOnIcon.classNames);
|
||||
addClasses(this.filterOnTypeDomNode, treeFilterOnTypeOffIcon.classNames);
|
||||
this.filterOnTypeDomNode.classList.remove(...treeFilterOnTypeOnIcon.classNamesArray);
|
||||
this.filterOnTypeDomNode.classList.add(...treeFilterOnTypeOffIcon.classNamesArray);
|
||||
this.filterOnTypeDomNode.title = localize('enable filter on type', "Enable Filter on Type");
|
||||
}
|
||||
}
|
||||
@@ -885,7 +885,7 @@ class TypeFilterController<T, TFilterData> implements IDisposable {
|
||||
this._empty = false;
|
||||
}
|
||||
|
||||
toggleClass(this.domNode, 'no-matches', noMatches);
|
||||
this.domNode.classList.toggle('no-matches', noMatches);
|
||||
this.domNode.title = localize('found', "Matched {0} out of {1} elements", this.filter.matchCount, this.filter.totalCount);
|
||||
this.labelDomNode.textContent = this.pattern.length > 16 ? '…' + this.pattern.substr(this.pattern.length - 16) : this.pattern;
|
||||
|
||||
@@ -1096,8 +1096,8 @@ class TreeNodeListMouseController<T, TFilterData, TRef> extends MouseController<
|
||||
}
|
||||
|
||||
const target = e.browserEvent.target as HTMLElement;
|
||||
const onTwistie = hasClass(target, 'monaco-tl-twistie')
|
||||
|| (hasClass(target, 'monaco-icon-label') && hasClass(target, 'folder-icon') && e.browserEvent.offsetX < 16);
|
||||
const onTwistie = target.classList.contains('monaco-tl-twistie')
|
||||
|| (target.classList.contains('monaco-icon-label') && target.classList.contains('folder-icon') && e.browserEvent.offsetX < 16);
|
||||
|
||||
let expandOnlyOnTwistieClick = false;
|
||||
|
||||
@@ -1130,7 +1130,7 @@ class TreeNodeListMouseController<T, TFilterData, TRef> extends MouseController<
|
||||
}
|
||||
|
||||
protected onDoubleClick(e: IListMouseEvent<ITreeNode<T, TFilterData>>): void {
|
||||
const onTwistie = hasClass(e.browserEvent.target as HTMLElement, 'monaco-tl-twistie');
|
||||
const onTwistie = (e.browserEvent.target as HTMLElement).classList.contains('monaco-tl-twistie');
|
||||
|
||||
if (onTwistie) {
|
||||
return;
|
||||
@@ -1340,7 +1340,7 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
|
||||
}
|
||||
|
||||
this.styleElement = createStyleSheet(this.view.getHTMLElement());
|
||||
toggleClass(this.getHTMLElement(), 'always', this._options.renderIndentGuides === RenderIndentGuides.Always);
|
||||
this.getHTMLElement().classList.toggle('always', this._options.renderIndentGuides === RenderIndentGuides.Always);
|
||||
}
|
||||
|
||||
updateOptions(optionsUpdate: IAbstractTreeOptionsUpdate = {}): void {
|
||||
@@ -1363,7 +1363,7 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
|
||||
|
||||
this._onDidUpdateOptions.fire(this._options);
|
||||
|
||||
toggleClass(this.getHTMLElement(), 'always', this._options.renderIndentGuides === RenderIndentGuides.Always);
|
||||
this.getHTMLElement().classList.toggle('always', this._options.renderIndentGuides === RenderIndentGuides.Always);
|
||||
}
|
||||
|
||||
get options(): IAbstractTreeOptions<T, TFilterData> {
|
||||
@@ -1474,11 +1474,7 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
|
||||
content.push(`.monaco-list${suffix} .monaco-tl-indent > .indent-guide.active { border-color: ${styles.treeIndentGuidesStroke}; }`);
|
||||
}
|
||||
|
||||
const newStyles = content.join('\n');
|
||||
if (newStyles !== this.styleElement.innerHTML) {
|
||||
this.styleElement.innerHTML = newStyles;
|
||||
}
|
||||
|
||||
this.styleElement.textContent = content.join('\n');
|
||||
this.view.style(styles);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ import { Iterable } from 'vs/base/common/iterator';
|
||||
import { IDragAndDropData } from 'vs/base/browser/dnd';
|
||||
import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView';
|
||||
import { isPromiseCanceledError, onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { removeClasses, addClasses } from 'vs/base/browser/dom';
|
||||
import { ScrollEvent } from 'vs/base/common/scrollable';
|
||||
import { ICompressedTreeNode, ICompressedTreeElement } from 'vs/base/browser/ui/tree/compressedObjectTreeModel';
|
||||
import { IThemable } from 'vs/base/common/styler';
|
||||
@@ -110,9 +109,9 @@ class AsyncDataTreeRenderer<TInput, T, TFilterData, TTemplateData> implements IT
|
||||
|
||||
renderTwistie(element: IAsyncDataTreeNode<TInput, T>, twistieElement: HTMLElement): boolean {
|
||||
if (element.slow) {
|
||||
addClasses(twistieElement, treeItemLoadingIcon.classNames);
|
||||
twistieElement.classList.add(...treeItemLoadingIcon.classNamesArray);
|
||||
} else {
|
||||
removeClasses(twistieElement, treeItemLoadingIcon.classNames);
|
||||
twistieElement.classList.remove(...treeItemLoadingIcon.classNamesArray);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1053,9 +1052,9 @@ class CompressibleAsyncDataTreeRenderer<TInput, T, TFilterData, TTemplateData> i
|
||||
|
||||
renderTwistie(element: IAsyncDataTreeNode<TInput, T>, twistieElement: HTMLElement): boolean {
|
||||
if (element.slow) {
|
||||
addClasses(twistieElement, treeItemLoadingIcon.classNames);
|
||||
twistieElement.classList.add(...treeItemLoadingIcon.classNamesArray);
|
||||
} else {
|
||||
removeClasses(twistieElement, treeItemLoadingIcon.classNames);
|
||||
twistieElement.classList.remove(...treeItemLoadingIcon.classNamesArray);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -399,29 +399,13 @@ export function lastIndex<T>(array: ReadonlyArray<T>, fn: (item: T) => boolean):
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated ES6: use `Array.findIndex`
|
||||
*/
|
||||
export function firstIndex<T>(array: ReadonlyArray<T>, fn: (item: T) => boolean): number {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const element = array[i];
|
||||
|
||||
if (fn(element)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated ES6: use `Array.find`
|
||||
*/
|
||||
export function first<T>(array: ReadonlyArray<T>, fn: (item: T) => boolean, notFoundValue: T): T;
|
||||
export function first<T>(array: ReadonlyArray<T>, fn: (item: T) => boolean): T | undefined;
|
||||
export function first<T>(array: ReadonlyArray<T>, fn: (item: T) => boolean, notFoundValue: T | undefined = undefined): T | undefined {
|
||||
const index = firstIndex(array, fn);
|
||||
const index = array.findIndex(fn);
|
||||
return index < 0 ? notFoundValue : array[index];
|
||||
}
|
||||
|
||||
@@ -565,21 +549,6 @@ export function pushToEnd<T>(arr: T[], value: T): void {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated ES6: use `Array.find`
|
||||
*/
|
||||
export function find<T>(arr: ArrayLike<T>, predicate: (value: T, index: number, arr: ArrayLike<T>) => any): T | undefined {
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
const element = arr[i];
|
||||
if (predicate(element, i, arr)) {
|
||||
return element;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function mapArrayOrNot<T, U>(items: T | T[], fn: (_: T) => U): U | U[] {
|
||||
return Array.isArray(items) ?
|
||||
items.map(fn) :
|
||||
|
||||
@@ -52,21 +52,21 @@ export function createCancelablePromise<T>(callback: (token: CancellationToken)
|
||||
|
||||
export function raceCancellation<T>(promise: Promise<T>, token: CancellationToken): Promise<T | undefined>;
|
||||
export function raceCancellation<T>(promise: Promise<T>, token: CancellationToken, defaultValue: T): Promise<T>;
|
||||
export function raceCancellation<T>(promise: Promise<T>, token: CancellationToken, defaultValue?: T): Promise<T> {
|
||||
return Promise.race([promise, new Promise<T>(resolve => token.onCancellationRequested(() => resolve(defaultValue)))]);
|
||||
export function raceCancellation<T>(promise: Promise<T>, token: CancellationToken, defaultValue?: T): Promise<T | undefined> {
|
||||
return Promise.race([promise, new Promise<T | undefined>(resolve => token.onCancellationRequested(() => resolve(defaultValue)))]);
|
||||
}
|
||||
|
||||
export function raceTimeout<T>(promise: Promise<T>, timeout: number, onTimeout?: () => void): Promise<T> {
|
||||
let promiseResolve: (() => void) | undefined = undefined;
|
||||
export function raceTimeout<T>(promise: Promise<T>, timeout: number, onTimeout?: () => void): Promise<T | undefined> {
|
||||
let promiseResolve: ((value: T | undefined) => void) | undefined = undefined;
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
promiseResolve?.();
|
||||
promiseResolve?.(undefined);
|
||||
onTimeout?.();
|
||||
}, timeout);
|
||||
|
||||
return Promise.race([
|
||||
promise.finally(() => clearTimeout(timer)),
|
||||
new Promise<T>(resolve => promiseResolve = resolve)
|
||||
new Promise<T | undefined>(resolve => promiseResolve = resolve)
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -432,7 +432,7 @@ export function first<T>(promiseFactories: ITask<Promise<T>>[], shouldStop: (t:
|
||||
|
||||
interface ILimitedTaskFactory<T> {
|
||||
factory: ITask<Promise<T>>;
|
||||
c: (value?: T | Promise<T>) => void;
|
||||
c: (value: T | Promise<T>) => void;
|
||||
e: (error?: any) => void;
|
||||
}
|
||||
|
||||
@@ -618,10 +618,10 @@ export class RunOnceScheduler {
|
||||
private timeout: number;
|
||||
private timeoutHandler: () => void;
|
||||
|
||||
constructor(runner: (...args: any[]) => void, timeout: number) {
|
||||
constructor(runner: (...args: any[]) => void, delay: number) {
|
||||
this.timeoutToken = -1;
|
||||
this.runner = runner;
|
||||
this.timeout = timeout;
|
||||
this.timeout = delay;
|
||||
this.timeoutHandler = this.onTimeout.bind(this);
|
||||
}
|
||||
|
||||
@@ -651,6 +651,14 @@ export class RunOnceScheduler {
|
||||
this.timeoutToken = setTimeout(this.timeoutHandler, delay);
|
||||
}
|
||||
|
||||
get delay(): number {
|
||||
return this.timeout;
|
||||
}
|
||||
|
||||
set delay(value: number) {
|
||||
this.timeout = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if scheduled.
|
||||
*/
|
||||
|
||||
@@ -478,6 +478,9 @@ export namespace Codicon {
|
||||
export const vmConnect = new Codicon('vm-connect', { character: '\\eba9' });
|
||||
export const cloud = new Codicon('cloud', { character: '\\ebaa' });
|
||||
export const merge = new Codicon('merge', { character: '\\ebab' });
|
||||
export const exportIcon = new Codicon('export', { character: '\\ebac' });
|
||||
export const graphLeft = new Codicon('graph-left', { character: '\\ebad' });
|
||||
export const magnet = new Codicon('magnet', { character: '\\ebae' });
|
||||
}
|
||||
|
||||
|
||||
@@ -499,20 +502,6 @@ export function markdownUnescapeCodicons(text: string): string {
|
||||
return text.replace(markdownUnescapeCodiconsRegex, (match, escaped, codicon) => escaped ? match : `$(${codicon})`);
|
||||
}
|
||||
|
||||
export const renderCodiconsRegex = /(\\)?\$\((([a-z0-9\-]+?)(?:~([a-z0-9\-]*?))?)\)/gi;
|
||||
|
||||
/**
|
||||
* @deprecated Use `renderCodiconsAsElement` instead
|
||||
*/
|
||||
export function renderCodicons(text: string): string {
|
||||
return text.replace(renderCodiconsRegex, (_, escaped, codicon, name, animation) => {
|
||||
// If the class for codicons is changed, it should also be updated in src\vs\base\browser\markdownRenderer.ts
|
||||
return escaped
|
||||
? `$(${codicon})`
|
||||
: `<span class="codicon codicon-${name}${animation ? ` codicon-animation-${animation}` : ''}"></span>`;
|
||||
});
|
||||
}
|
||||
|
||||
const stripCodiconsRegex = /(\s)?(\\)?\$\([a-z0-9\-]+?(?:~[a-z0-9\-]*?)?\)(\s)?/gi;
|
||||
export function stripCodicons(text: string): string {
|
||||
if (text.indexOf(codiconStartMarker) === -1) {
|
||||
|
||||
@@ -179,18 +179,18 @@ export function equals(one: any, other: any): boolean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls JSON.Stringify with a replacer to break apart any circular references.
|
||||
* This prevents JSON.stringify from throwing the exception
|
||||
* Calls `JSON.Stringify` with a replacer to break apart any circular references.
|
||||
* This prevents `JSON`.stringify` from throwing the exception
|
||||
* "Uncaught TypeError: Converting circular structure to JSON"
|
||||
*/
|
||||
export function safeStringify(obj: any): string {
|
||||
const seen: any[] = [];
|
||||
const seen = new Set<any>();
|
||||
return JSON.stringify(obj, (key, value) => {
|
||||
if (isObject(value) || Array.isArray(value)) {
|
||||
if (seen.indexOf(value) !== -1) {
|
||||
if (seen.has(value)) {
|
||||
return '[Circular]';
|
||||
} else {
|
||||
seen.push(value);
|
||||
seen.add(value);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
|
||||
@@ -454,15 +454,15 @@ export class ResourceGlobMatcher {
|
||||
}
|
||||
}
|
||||
|
||||
export function toLocalResource(resource: URI, authority: string | undefined): URI {
|
||||
export function toLocalResource(resource: URI, authority: string | undefined, localScheme: string): URI {
|
||||
if (authority) {
|
||||
let path = resource.path;
|
||||
if (path && path[0] !== paths.posix.sep) {
|
||||
path = paths.posix.sep + path;
|
||||
}
|
||||
|
||||
return resource.with({ scheme: Schemas.vscodeRemote, authority, path });
|
||||
return resource.with({ scheme: localScheme, authority, path });
|
||||
}
|
||||
|
||||
return resource.with({ scheme: Schemas.file });
|
||||
return resource.with({ scheme: localScheme });
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ export class SkipList<K, V> implements Map<K, V> {
|
||||
readonly [Symbol.toStringTag] = 'SkipList';
|
||||
|
||||
private _maxLevel: number;
|
||||
private _level: number = 1;
|
||||
private _level: number = 0;
|
||||
private _header: Node<K, V>;
|
||||
private _size: number = 0;
|
||||
|
||||
@@ -122,7 +122,7 @@ export class SkipList<K, V> implements Map<K, V> {
|
||||
|
||||
private static _search<K, V>(list: SkipList<K, V>, searchKey: K, comparator: Comparator<K>) {
|
||||
let x = list._header;
|
||||
for (let i = list._level; i >= 0; i--) {
|
||||
for (let i = list._level - 1; i >= 0; i--) {
|
||||
while (x.forward[i] && comparator(x.forward[i].key, searchKey) < 0) {
|
||||
x = x.forward[i];
|
||||
}
|
||||
@@ -137,7 +137,7 @@ export class SkipList<K, V> implements Map<K, V> {
|
||||
private static _insert<K, V>(list: SkipList<K, V>, searchKey: K, value: V, comparator: Comparator<K>) {
|
||||
let update: Node<K, V>[] = [];
|
||||
let x = list._header;
|
||||
for (let i = list._level; i >= 0; i--) {
|
||||
for (let i = list._level - 1; i >= 0; i--) {
|
||||
while (x.forward[i] && comparator(x.forward[i].key, searchKey) < 0) {
|
||||
x = x.forward[i];
|
||||
}
|
||||
@@ -152,13 +152,13 @@ export class SkipList<K, V> implements Map<K, V> {
|
||||
// insert
|
||||
let lvl = SkipList._randomLevel(list);
|
||||
if (lvl > list._level) {
|
||||
for (let i = list._level + 1; i <= lvl; i++) {
|
||||
for (let i = list._level; i < lvl; i++) {
|
||||
update[i] = list._header;
|
||||
}
|
||||
list._level = lvl;
|
||||
}
|
||||
x = new Node<K, V>(lvl, searchKey, value);
|
||||
for (let i = 0; i <= lvl; i++) {
|
||||
for (let i = 0; i < lvl; i++) {
|
||||
x.forward[i] = update[i].forward[i];
|
||||
update[i].forward[i] = x;
|
||||
}
|
||||
@@ -177,7 +177,7 @@ export class SkipList<K, V> implements Map<K, V> {
|
||||
private static _delete<K, V>(list: SkipList<K, V>, searchKey: K, comparator: Comparator<K>) {
|
||||
let update: Node<K, V>[] = [];
|
||||
let x = list._header;
|
||||
for (let i = list._level; i >= 0; i--) {
|
||||
for (let i = list._level - 1; i >= 0; i--) {
|
||||
while (x.forward[i] && comparator(x.forward[i].key, searchKey) < 0) {
|
||||
x = x.forward[i];
|
||||
}
|
||||
@@ -194,7 +194,7 @@ export class SkipList<K, V> implements Map<K, V> {
|
||||
}
|
||||
update[i].forward[i] = x.forward[i];
|
||||
}
|
||||
while (list._level >= 1 && list._header.forward[list._level] === NIL) {
|
||||
while (list._level > 0 && list._header.forward[list._level - 1] === NIL) {
|
||||
list._level -= 1;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -18,7 +18,7 @@ import { CommandOptions, ForkOptions, SuccessData, Source, TerminateResponse, Te
|
||||
import { getPathFromAmdModule } from 'vs/base/common/amd';
|
||||
export { CommandOptions, ForkOptions, SuccessData, Source, TerminateResponse, TerminateResponseCode };
|
||||
|
||||
export type ValueCallback<T> = (value?: T | Promise<T>) => void;
|
||||
export type ValueCallback<T> = (value: T | Promise<T>) => void;
|
||||
export type ErrorCallback = (error?: any) => void;
|
||||
export type ProgressCallback<T> = (progress: T) => void;
|
||||
|
||||
@@ -98,7 +98,7 @@ export abstract class AbstractProcess<TProgressData> {
|
||||
|
||||
private childProcess: cp.ChildProcess | null;
|
||||
protected childProcessPromise: Promise<cp.ChildProcess> | null;
|
||||
private pidResolve?: ValueCallback<number>;
|
||||
private pidResolve: ValueCallback<number> | undefined;
|
||||
protected terminateRequested: boolean;
|
||||
|
||||
private static WellKnowCommands: IStringDictionary<boolean> = {
|
||||
|
||||
@@ -193,6 +193,11 @@ export function listProcesses(rootPid: number): Promise<ProcessItem> {
|
||||
processInfo.load = parseFloat(cpuUsage[i]);
|
||||
}
|
||||
|
||||
if (!rootItem) {
|
||||
reject(new Error(`Root process ${rootPid} not found`));
|
||||
return;
|
||||
}
|
||||
|
||||
resolve(rootItem);
|
||||
}
|
||||
});
|
||||
@@ -228,7 +233,11 @@ export function listProcesses(rootPid: number): Promise<ProcessItem> {
|
||||
if (process.platform === 'linux') {
|
||||
calculateLinuxCpuUsage();
|
||||
} else {
|
||||
resolve(rootItem);
|
||||
if (!rootItem) {
|
||||
reject(new Error(`Root process ${rootPid} not found`));
|
||||
} else {
|
||||
resolve(rootItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -40,7 +40,7 @@ const JSCHARDET_TO_ICONV_ENCODINGS: { [name: string]: string } = {
|
||||
const UTF8 = 'utf8';
|
||||
|
||||
export async function resolveTerminalEncoding(verbose?: boolean): Promise<string> {
|
||||
let rawEncodingPromise: Promise<string>;
|
||||
let rawEncodingPromise: Promise<string | undefined>;
|
||||
|
||||
// Support a global environment variable to win over other mechanics
|
||||
const cliEncodingEnv = process.env['VSCODE_CLI_ENCODING'];
|
||||
@@ -54,7 +54,7 @@ export async function resolveTerminalEncoding(verbose?: boolean): Promise<string
|
||||
|
||||
// Windows: educated guess
|
||||
else if (isWindows) {
|
||||
rawEncodingPromise = new Promise<string>(resolve => {
|
||||
rawEncodingPromise = new Promise<string | undefined>(resolve => {
|
||||
if (verbose) {
|
||||
console.log('Running "chcp" to detect terminal encoding...');
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import { mkdirp, rimraf } from 'vs/base/node/pfs';
|
||||
import { open as _openZip, Entry, ZipFile } from 'yauzl';
|
||||
import * as yazl from 'yazl';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { assertIsDefined } from 'vs/base/common/types';
|
||||
|
||||
export interface IExtractOptions {
|
||||
overwrite?: boolean;
|
||||
@@ -161,24 +162,24 @@ function extractZip(zipfile: ZipFile, targetPath: string, options: IOptions, tok
|
||||
}
|
||||
|
||||
function openZip(zipFile: string, lazy: boolean = false): Promise<ZipFile> {
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise<ZipFile>((resolve, reject) => {
|
||||
_openZip(zipFile, lazy ? { lazyEntries: true } : undefined!, (error?: Error, zipfile?: ZipFile) => {
|
||||
if (error) {
|
||||
reject(toExtractError(error));
|
||||
} else {
|
||||
resolve(zipfile);
|
||||
resolve(assertIsDefined(zipfile));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function openZipStream(zipFile: ZipFile, entry: Entry): Promise<Readable> {
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise<Readable>((resolve, reject) => {
|
||||
zipFile.openReadStream(entry, (error?: Error, stream?: Readable) => {
|
||||
if (error) {
|
||||
reject(toExtractError(error));
|
||||
} else {
|
||||
resolve(stream);
|
||||
resolve(assertIsDefined(stream));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { ChildProcess, fork, ForkOptions } from 'child_process';
|
||||
import { IDisposable, toDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { Delayer, createCancelablePromise } from 'vs/base/common/async';
|
||||
import { deepClone, assign } from 'vs/base/common/objects';
|
||||
import { deepClone } from 'vs/base/common/objects';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { createQueuedSender } from 'vs/base/node/processes';
|
||||
import { IChannel, ChannelServer as IPCServer, ChannelClient as IPCClient, IChannelClient } from 'vs/base/parts/ipc/common/ipc';
|
||||
@@ -14,6 +14,7 @@ import { isRemoteConsoleLog, log } from 'vs/base/common/console';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import * as errors from 'vs/base/common/errors';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { isMacintosh } from 'vs/base/common/platform';
|
||||
|
||||
/**
|
||||
* This implementation doesn't perform well since it uses base64 encoding for buffers.
|
||||
@@ -179,10 +180,10 @@ export class Client implements IChannelClient, IDisposable {
|
||||
const args = this.options && this.options.args ? this.options.args : [];
|
||||
const forkOpts: ForkOptions = Object.create(null);
|
||||
|
||||
forkOpts.env = assign(deepClone(process.env), { 'VSCODE_PARENT_PID': String(process.pid) });
|
||||
forkOpts.env = { ...deepClone(process.env), 'VSCODE_PARENT_PID': String(process.pid) };
|
||||
|
||||
if (this.options && this.options.env) {
|
||||
forkOpts.env = assign(forkOpts.env, this.options.env);
|
||||
forkOpts.env = { ...forkOpts.env, ...this.options.env };
|
||||
}
|
||||
|
||||
if (this.options && this.options.freshExecArgv) {
|
||||
@@ -197,6 +198,12 @@ export class Client implements IChannelClient, IDisposable {
|
||||
forkOpts.execArgv = ['--nolazy', '--inspect-brk=' + this.options.debugBrk];
|
||||
}
|
||||
|
||||
if (isMacintosh && forkOpts.env) {
|
||||
// Unset `DYLD_LIBRARY_PATH`, as it leads to process crashes
|
||||
// See https://github.com/microsoft/vscode/issues/105848
|
||||
delete forkOpts.env['DYLD_LIBRARY_PATH'];
|
||||
}
|
||||
|
||||
this.child = fork(this.modulePath, args, forkOpts);
|
||||
|
||||
const onMessageEmitter = new Emitter<VSBuffer>();
|
||||
|
||||
@@ -1416,7 +1416,7 @@ export class QuickInputController extends Disposable {
|
||||
}
|
||||
|
||||
input(options: IInputOptions = {}, token: CancellationToken = CancellationToken.None): Promise<string | undefined> {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
return new Promise<string | undefined>((resolve) => {
|
||||
if (token.isCancellationRequested) {
|
||||
resolve(undefined);
|
||||
return;
|
||||
@@ -1692,8 +1692,8 @@ export class QuickInputController extends Disposable {
|
||||
content.push(`.quick-input-list .quick-input-list-separator { color: ${this.styles.list.pickerGroupForeground}; }`);
|
||||
}
|
||||
const newStyles = content.join('\n');
|
||||
if (newStyles !== this.ui.styleSheet.innerHTML) {
|
||||
this.ui.styleSheet.innerHTML = newStyles;
|
||||
if (newStyles !== this.ui.styleSheet.textContent) {
|
||||
this.ui.styleSheet.textContent = newStyles;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,13 +5,15 @@
|
||||
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { canceled } from 'vs/base/common/errors';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
import { VSBuffer, bufferToStream } from 'vs/base/common/buffer';
|
||||
import { IRequestOptions, IRequestContext } from 'vs/base/parts/request/common/request';
|
||||
|
||||
export function request(options: IRequestOptions, token: CancellationToken): Promise<IRequestContext> {
|
||||
if (options.proxyAuthorization) {
|
||||
options.headers = assign(options.headers || {}, { 'Proxy-Authorization': options.proxyAuthorization });
|
||||
options.headers = {
|
||||
...(options.headers || {}),
|
||||
'Proxy-Authorization': options.proxyAuthorization
|
||||
};
|
||||
}
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
|
||||
@@ -93,6 +93,7 @@
|
||||
process: {
|
||||
platform: process.platform,
|
||||
env: process.env,
|
||||
versions: process.versions,
|
||||
_whenEnvResolved: undefined,
|
||||
get whenEnvResolved() {
|
||||
if (!this._whenEnvResolved) {
|
||||
|
||||
@@ -94,6 +94,11 @@ export const process = (window as any).vscode.process as {
|
||||
* A listener on the process. Only a small subset of listener types are allowed.
|
||||
*/
|
||||
on: (type: string, callback: Function) => void;
|
||||
|
||||
/**
|
||||
* A list of versions for the current node.js/electron configuration.
|
||||
*/
|
||||
versions: { [key: string]: string | undefined };
|
||||
};
|
||||
|
||||
export const context = (window as any).vscode.context as {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { prepareActions } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { ActionBar, prepareActions } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { Action, Separator } from 'vs/base/common/actions';
|
||||
|
||||
suite('Actionbar', () => {
|
||||
@@ -24,4 +24,37 @@ suite('Actionbar', () => {
|
||||
assert(actions[1] === a5);
|
||||
assert(actions[2] === a6);
|
||||
});
|
||||
|
||||
test('hasAction()', function () {
|
||||
const container = document.createElement('div');
|
||||
const actionbar = new ActionBar(container);
|
||||
|
||||
let a1 = new Action('a1');
|
||||
let a2 = new Action('a2');
|
||||
|
||||
actionbar.push(a1);
|
||||
assert.equal(actionbar.hasAction(a1), true);
|
||||
assert.equal(actionbar.hasAction(a2), false);
|
||||
|
||||
actionbar.pull(0);
|
||||
assert.equal(actionbar.hasAction(a1), false);
|
||||
|
||||
actionbar.push(a1, { index: 1 });
|
||||
actionbar.push(a2, { index: 0 });
|
||||
assert.equal(actionbar.hasAction(a1), true);
|
||||
assert.equal(actionbar.hasAction(a2), true);
|
||||
|
||||
actionbar.pull(0);
|
||||
assert.equal(actionbar.hasAction(a1), true);
|
||||
assert.equal(actionbar.hasAction(a2), false);
|
||||
|
||||
actionbar.pull(0);
|
||||
assert.equal(actionbar.hasAction(a1), false);
|
||||
assert.equal(actionbar.hasAction(a2), false);
|
||||
|
||||
actionbar.push(a1);
|
||||
assert.equal(actionbar.hasAction(a1), true);
|
||||
actionbar.clear();
|
||||
assert.equal(actionbar.hasAction(a1), false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,43 +3,43 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { renderCodiconsAsElement } from 'vs/base/browser/codicons';
|
||||
import { renderCodicons } from 'vs/base/browser/codicons';
|
||||
import * as assert from 'assert';
|
||||
|
||||
suite('renderCodicons', () => {
|
||||
|
||||
test('no codicons', () => {
|
||||
const result = renderCodiconsAsElement(' hello World .');
|
||||
const result = renderCodicons(' hello World .');
|
||||
|
||||
assert.equal(elementsToString(result), ' hello World .');
|
||||
});
|
||||
|
||||
test('codicon only', () => {
|
||||
const result = renderCodiconsAsElement('$(alert)');
|
||||
const result = renderCodicons('$(alert)');
|
||||
|
||||
assert.equal(elementsToString(result), '<span class="codicon codicon-alert"></span>');
|
||||
});
|
||||
|
||||
test('codicon and non-codicon strings', () => {
|
||||
const result = renderCodiconsAsElement(` $(alert) Unresponsive`);
|
||||
const result = renderCodicons(` $(alert) Unresponsive`);
|
||||
|
||||
assert.equal(elementsToString(result), ' <span class="codicon codicon-alert"></span> Unresponsive');
|
||||
});
|
||||
|
||||
test('multiple codicons', () => {
|
||||
const result = renderCodiconsAsElement('$(check)$(error)');
|
||||
const result = renderCodicons('$(check)$(error)');
|
||||
|
||||
assert.equal(elementsToString(result), '<span class="codicon codicon-check"></span><span class="codicon codicon-error"></span>');
|
||||
});
|
||||
|
||||
test('escaped codicon', () => {
|
||||
const result = renderCodiconsAsElement('\\$(escaped)');
|
||||
const result = renderCodicons('\\$(escaped)');
|
||||
|
||||
assert.equal(elementsToString(result), '$(escaped)');
|
||||
});
|
||||
|
||||
test('codicon with animation', () => {
|
||||
const result = renderCodiconsAsElement('$(zip~anim)');
|
||||
const result = renderCodicons('$(zip~anim)');
|
||||
|
||||
assert.equal(elementsToString(result), '<span class="codicon codicon-zip codicon-animation-anim"></span>');
|
||||
});
|
||||
|
||||
@@ -7,7 +7,6 @@ import * as assert from 'assert';
|
||||
import { ITreeNode, ITreeRenderer, IAsyncDataSource } from 'vs/base/browser/ui/tree/tree';
|
||||
import { AsyncDataTree } from 'vs/base/browser/ui/tree/asyncDataTree';
|
||||
import { IListVirtualDelegate, IIdentityProvider } from 'vs/base/browser/ui/list/list';
|
||||
import { hasClass } from 'vs/base/browser/dom';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
|
||||
interface Element {
|
||||
@@ -103,8 +102,8 @@ suite('AsyncDataTree', function () {
|
||||
await tree.setInput(model.root);
|
||||
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
let twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(!hasClass(twistie, 'collapsible'));
|
||||
assert(!hasClass(twistie, 'collapsed'));
|
||||
assert(!twistie.classList.contains('collapsible'));
|
||||
assert(!twistie.classList.contains('collapsed'));
|
||||
|
||||
model.get('a').children = [
|
||||
{ id: 'aa' },
|
||||
@@ -151,8 +150,8 @@ suite('AsyncDataTree', function () {
|
||||
assert.deepStrictEqual(getChildrenCalls, ['root']);
|
||||
|
||||
let twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(!hasClass(twistie, 'collapsible'));
|
||||
assert(!hasClass(twistie, 'collapsed'));
|
||||
assert(!twistie.classList.contains('collapsible'));
|
||||
assert(!twistie.classList.contains('collapsed'));
|
||||
assert(tree.getNode().children[0].collapsed);
|
||||
|
||||
model.get('a').children = [{ id: 'aa' }, { id: 'ab' }, { id: 'ac' }];
|
||||
@@ -160,8 +159,8 @@ suite('AsyncDataTree', function () {
|
||||
|
||||
assert.deepStrictEqual(getChildrenCalls, ['root', 'root']);
|
||||
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(hasClass(twistie, 'collapsible'));
|
||||
assert(hasClass(twistie, 'collapsed'));
|
||||
assert(twistie.classList.contains('collapsible'));
|
||||
assert(twistie.classList.contains('collapsed'));
|
||||
assert(tree.getNode().children[0].collapsed);
|
||||
|
||||
model.get('a').children = [];
|
||||
@@ -169,8 +168,8 @@ suite('AsyncDataTree', function () {
|
||||
|
||||
assert.deepStrictEqual(getChildrenCalls, ['root', 'root', 'root']);
|
||||
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(!hasClass(twistie, 'collapsible'));
|
||||
assert(!hasClass(twistie, 'collapsed'));
|
||||
assert(!twistie.classList.contains('collapsible'));
|
||||
assert(!twistie.classList.contains('collapsed'));
|
||||
assert(tree.getNode().children[0].collapsed);
|
||||
|
||||
model.get('a').children = [{ id: 'aa' }, { id: 'ab' }, { id: 'ac' }];
|
||||
@@ -178,8 +177,8 @@ suite('AsyncDataTree', function () {
|
||||
|
||||
assert.deepStrictEqual(getChildrenCalls, ['root', 'root', 'root', 'root']);
|
||||
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(hasClass(twistie, 'collapsible'));
|
||||
assert(hasClass(twistie, 'collapsed'));
|
||||
assert(twistie.classList.contains('collapsible'));
|
||||
assert(twistie.classList.contains('collapsed'));
|
||||
assert(tree.getNode().children[0].collapsed);
|
||||
});
|
||||
|
||||
@@ -241,8 +240,8 @@ suite('AsyncDataTree', function () {
|
||||
await tree.expand(model.get('a'));
|
||||
|
||||
let twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(hasClass(twistie, 'collapsible'));
|
||||
assert(!hasClass(twistie, 'collapsed'));
|
||||
assert(twistie.classList.contains('collapsible'));
|
||||
assert(!twistie.classList.contains('collapsed'));
|
||||
assert(!tree.getNode(model.get('a')).collapsed);
|
||||
|
||||
tree.collapse(model.get('a'));
|
||||
@@ -250,8 +249,8 @@ suite('AsyncDataTree', function () {
|
||||
await tree.updateChildren(model.root);
|
||||
|
||||
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(!hasClass(twistie, 'collapsible'));
|
||||
assert(!hasClass(twistie, 'collapsed'));
|
||||
assert(!twistie.classList.contains('collapsible'));
|
||||
assert(!twistie.classList.contains('collapsed'));
|
||||
assert(tree.getNode(model.get('a')).collapsed);
|
||||
});
|
||||
|
||||
@@ -295,7 +294,7 @@ suite('AsyncDataTree', function () {
|
||||
return !!element.children && element.children.length > 0;
|
||||
}
|
||||
getChildren(element: Element): Promise<Element[]> {
|
||||
return new Promise(c => calls.push(() => c(element.children)));
|
||||
return new Promise(c => calls.push(() => c(element.children || [])));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -338,7 +337,7 @@ suite('AsyncDataTree', function () {
|
||||
return !!element.children && element.children.length > 0;
|
||||
}
|
||||
getChildren(element: Element): Promise<Element[]> {
|
||||
return new Promise(c => calls.push(() => c(element.children)));
|
||||
return new Promise(c => calls.push(() => c(element.children || [])));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -387,22 +386,22 @@ suite('AsyncDataTree', function () {
|
||||
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
|
||||
let twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(!hasClass(twistie, 'collapsible'));
|
||||
assert(!hasClass(twistie, 'collapsed'));
|
||||
assert(!twistie.classList.contains('collapsible'));
|
||||
assert(!twistie.classList.contains('collapsed'));
|
||||
|
||||
model.get('a').children = [{ id: 'aa' }];
|
||||
await tree.updateChildren(model.get('a'), false);
|
||||
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(hasClass(twistie, 'collapsible'));
|
||||
assert(hasClass(twistie, 'collapsed'));
|
||||
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);
|
||||
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(!hasClass(twistie, 'collapsible'));
|
||||
assert(!hasClass(twistie, 'collapsed'));
|
||||
assert(!twistie.classList.contains('collapsible'));
|
||||
assert(!twistie.classList.contains('collapsed'));
|
||||
});
|
||||
|
||||
test('issues #84569, #82629 - rerender', async () => {
|
||||
|
||||
@@ -527,7 +527,7 @@ suite('Async', () => {
|
||||
|
||||
r1Queue.queue(syncPromiseFactory);
|
||||
|
||||
return new Promise(c => setTimeout(() => c(), 0)).then(() => {
|
||||
return new Promise<void>(c => setTimeout(() => c(), 0)).then(() => {
|
||||
const r1Queue2 = queue.queueFor(URI.file('/some/path'));
|
||||
assert.notEqual(r1Queue, r1Queue2); // previous one got disposed after finishing
|
||||
});
|
||||
|
||||
@@ -25,21 +25,21 @@ export class DeferredPromise<T> {
|
||||
}
|
||||
|
||||
public complete(value: T) {
|
||||
return new Promise(resolve => {
|
||||
return new Promise<void>(resolve => {
|
||||
this.completeCallback(value);
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
public error(err: any) {
|
||||
return new Promise(resolve => {
|
||||
return new Promise<void>(resolve => {
|
||||
this.errorCallback(err);
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
public cancel() {
|
||||
new Promise(resolve => {
|
||||
new Promise<void>(resolve => {
|
||||
this.errorCallback(canceled());
|
||||
resolve();
|
||||
});
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
|
||||
require.config({
|
||||
baseUrl: monacoBaseUrl,
|
||||
catchError: true
|
||||
catchError: true,
|
||||
createTrustedScriptURL: (value: string) => value,
|
||||
});
|
||||
|
||||
let loadCode = function (moduleId: string) {
|
||||
|
||||
Reference in New Issue
Block a user