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;
+}
diff --git a/src/vs/base/browser/markdownRenderer.ts b/src/vs/base/browser/markdownRenderer.ts
index 255bc67187..d967357163 100644
--- a/src/vs/base/browser/markdownRenderer.ts
+++ b/src/vs/base/browser/markdownRenderer.ts
@@ -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 `${markdown.supportThemeIcons ? renderCodicons(text) : text}
`;
+ if (markdown.supportThemeIcons) {
+ const elements = renderCodicons(text);
+ text = elements.map(e => typeof e === 'string' ? e : e.outerHTML).join('');
+ }
+ return `${text}
`;
};
if (options.codeBlockRenderer) {
diff --git a/src/vs/base/browser/ui/actionbar/actionViewItems.ts b/src/vs/base/browser/ui/actionbar/actionViewItems.ts
index c1a7429181..de95c381fd 100644
--- a/src/vs/base/browser/ui/actionbar/actionViewItems.ts
+++ b/src/vs/base/browser/ui/actionbar/actionViewItems.ts
@@ -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');
}
}
}
diff --git a/src/vs/base/browser/ui/actionbar/actionbar.ts b/src/vs/base/browser/ui/actionbar/actionbar.ts
index 13ec2ad808..f6c5166ac8 100644
--- a/src/vs/base/browser/ui/actionbar/actionbar.ts
+++ b/src/vs/base/browser/ui/actionbar/actionbar.ts
@@ -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());
- readonly onDidBlur: Event = this._onDidBlur.event;
+ readonly onDidBlur = this._onDidBlur.event;
private _onDidCancel = this._register(new Emitter());
- readonly onDidCancel: Event = this._onDidCancel.event;
+ readonly onDidCancel = this._onDidCancel.event;
private _onDidRun = this._register(new Emitter());
- readonly onDidRun: Event = this._onDidRun.event;
+ readonly onDidRun = this._onDidRun.event;
private _onDidBeforeRun = this._register(new Emitter());
- readonly onDidBeforeRun: Event = 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, options: IActionOptions = {}): void {
const actions: ReadonlyArray = 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();
}
diff --git a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts
index 90f01d31db..4a0a3f2f67 100644
--- a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts
+++ b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts
@@ -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;
}
}
diff --git a/src/vs/base/browser/ui/button/button.ts b/src/vs/base/browser/ui/button/button.ts
index 2976a3c145..2c310a1794 100644
--- a/src/vs/base/browser/ui/button/button.ts
+++ b/src/vs/base/browser/ui/button/button.ts
@@ -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());
get onDidClick(): BaseEvent { 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);
}
}));
diff --git a/src/vs/base/browser/ui/codicons/codicon/codicon.ttf b/src/vs/base/browser/ui/codicons/codicon/codicon.ttf
index 82acc8995b..bb7ce5a582 100644
Binary files a/src/vs/base/browser/ui/codicons/codicon/codicon.ttf and b/src/vs/base/browser/ui/codicons/codicon/codicon.ttf differ
diff --git a/src/vs/base/browser/ui/codicons/codiconLabel.ts b/src/vs/base/browser/ui/codicons/codiconLabel.ts
index 3da4558e5d..8141a44925 100644
--- a/src/vs/base/browser/ui/codicons/codiconLabel.ts
+++ b/src/vs/base/browser/ui/codicons/codiconLabel.ts
@@ -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) {
diff --git a/src/vs/base/browser/ui/codicons/codiconStyles.ts b/src/vs/base/browser/ui/codicons/codiconStyles.ts
index 274e9de74c..3ef34818ba 100644
--- a/src/vs/base/browser/ui/codicons/codiconStyles.ts
+++ b/src/vs/base/browser/ui/codicons/codiconStyles.ts
@@ -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);
diff --git a/src/vs/base/browser/ui/contextview/contextview.ts b/src/vs/base/browser/ui/contextview/contextview.ts
index b8f31da856..d80fb4b9a5 100644
--- a/src/vs/base/browser/ui/contextview/contextview.ts
+++ b/src/vs/base/browser/ui/contextview/contextview.ts
@@ -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; }
diff --git a/src/vs/base/browser/ui/dropdown/dropdown.ts b/src/vs/base/browser/ui/dropdown/dropdown.ts
index 9a06c87cac..0acb019a5a 100644
--- a/src/vs/base/browser/ui/dropdown/dropdown.ts
+++ b/src/vs/base/browser/ui/dropdown/dropdown.ts
@@ -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');
}
}
diff --git a/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts b/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts
index c6ffcc87c8..054813f782 100644
--- a/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts
+++ b/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts
@@ -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}`);
diff --git a/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts b/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts
index 1d582c6959..f7618c6ba1 100644
--- a/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts
+++ b/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts
@@ -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 += '';
const substring = this.text.substring(pos, highlight.start);
- htmlContent += this.supportCodicons ? renderCodicons(escape(substring)) : escape(substring);
- htmlContent += '';
+ children.push(dom.$('span', undefined, ...this.supportCodicons ? renderCodicons(substring) : [substring]));
pos = highlight.end;
}
- if (highlight.extraClasses) {
- htmlContent += `