diff --git a/.eslintrc.json b/.eslintrc.json index eb2c7c3c8d1e9c..4d5b300eafbd57 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -308,6 +308,10 @@ "selector": "BinaryExpression[operator='instanceof'][right.name='MouseEvent']", "message": "Use DOM.isMouseEvent() to support multi-window scenarios." }, + { + "selector": "BinaryExpression[operator='instanceof'][right.name=/^HTML\\w+/]", + "message": "Use DOM.isHTMLElement() and related methods to support multi-window scenarios." + }, { "selector": "BinaryExpression[operator='instanceof'][right.name='KeyboardEvent']", "message": "Use DOM.isKeyboardEvent() to support multi-window scenarios." diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 76abbb844ecece..3614986c445239 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -795,7 +795,7 @@ export function isAncestorUsingFlowTo(testChild: Node, testAncestor: Node): bool return true; } - if (node instanceof HTMLElement) { + if (isHTMLElement(node)) { const flowToParentElement = getParentFlowToElement(node); if (flowToParentElement) { node = flowToParentElement; @@ -1148,6 +1148,41 @@ function isCSSStyleRule(rule: CSSRule): rule is CSSStyleRule { return typeof (rule as CSSStyleRule).selectorText === 'string'; } +export function isHTMLElement(e: unknown): e is HTMLElement { + // eslint-disable-next-line no-restricted-syntax + return e instanceof HTMLElement || e instanceof getWindow(e as Node).HTMLElement; +} + +export function isHTMLAnchorElement(e: unknown): e is HTMLAnchorElement { + // eslint-disable-next-line no-restricted-syntax + return e instanceof HTMLAnchorElement || e instanceof getWindow(e as Node).HTMLAnchorElement; +} + +export function isHTMLSpanElement(e: unknown): e is HTMLSpanElement { + // eslint-disable-next-line no-restricted-syntax + return e instanceof HTMLSpanElement || e instanceof getWindow(e as Node).HTMLSpanElement; +} + +export function isHTMLTextAreaElement(e: unknown): e is HTMLTextAreaElement { + // eslint-disable-next-line no-restricted-syntax + return e instanceof HTMLTextAreaElement || e instanceof getWindow(e as Node).HTMLTextAreaElement; +} + +export function isHTMLInputElement(e: unknown): e is HTMLInputElement { + // eslint-disable-next-line no-restricted-syntax + return e instanceof HTMLInputElement || e instanceof getWindow(e as Node).HTMLInputElement; +} + +export function isHTMLButtonElement(e: unknown): e is HTMLButtonElement { + // eslint-disable-next-line no-restricted-syntax + return e instanceof HTMLButtonElement || e instanceof getWindow(e as Node).HTMLButtonElement; +} + +export function isHTMLDivElement(e: unknown): e is HTMLDivElement { + // eslint-disable-next-line no-restricted-syntax + return e instanceof HTMLDivElement || e instanceof getWindow(e as Node).HTMLDivElement; +} + export function isMouseEvent(e: unknown): e is MouseEvent { // eslint-disable-next-line no-restricted-syntax return e instanceof MouseEvent || e instanceof getWindow(e as UIEvent).MouseEvent; @@ -1286,7 +1321,7 @@ class FocusTracker extends Disposable implements IFocusTracker { private _refreshStateHandler: () => void; private static hasFocusWithin(element: HTMLElement | Window): boolean { - if (element instanceof HTMLElement) { + if (isHTMLElement(element)) { const shadowRoot = getShadowRoot(element); const activeElement = (shadowRoot ? shadowRoot.activeElement : element.ownerDocument.activeElement); return isAncestor(activeElement, element); @@ -1312,7 +1347,7 @@ class FocusTracker extends Disposable implements IFocusTracker { const onBlur = () => { if (hasFocus) { loosingFocus = true; - (element instanceof HTMLElement ? getWindow(element) : element).setTimeout(() => { + (isHTMLElement(element) ? getWindow(element) : element).setTimeout(() => { if (loosingFocus) { loosingFocus = false; hasFocus = false; @@ -1335,7 +1370,7 @@ class FocusTracker extends Disposable implements IFocusTracker { this._register(addDisposableListener(element, EventType.FOCUS, onFocus, true)); this._register(addDisposableListener(element, EventType.BLUR, onBlur, true)); - if (element instanceof HTMLElement) { + if (isHTMLElement(element)) { this._register(addDisposableListener(element, EventType.FOCUS_IN, () => this._refreshStateHandler())); this._register(addDisposableListener(element, EventType.FOCUS_OUT, () => this._refreshStateHandler())); } @@ -1488,7 +1523,7 @@ export function hide(...elements: HTMLElement[]): void { function findParentWithAttribute(node: Node | null, attribute: string): HTMLElement | null { while (node && node.nodeType === node.ELEMENT_NODE) { - if (node instanceof HTMLElement && node.hasAttribute(attribute)) { + if (isHTMLElement(node) && node.hasAttribute(attribute)) { return node; } @@ -2304,7 +2339,7 @@ export function h(tag: string, ...args: [] | [attributes: { $: string } & Partia if (children) { for (const c of children) { - if (c instanceof HTMLElement) { + if (isHTMLElement(c)) { el.appendChild(c); } else if (typeof c === 'string') { el.append(c); diff --git a/src/vs/base/browser/ui/actionbar/actionbar.ts b/src/vs/base/browser/ui/actionbar/actionbar.ts index 05505b768a5eab..a9b62dd7be5352 100644 --- a/src/vs/base/browser/ui/actionbar/actionbar.ts +++ b/src/vs/base/browser/ui/actionbar/actionbar.ts @@ -328,7 +328,7 @@ export class ActionBar extends Disposable implements IActionRunner { } // by element - if (indexOrElement instanceof HTMLElement) { + if (DOM.isHTMLElement(indexOrElement)) { while (indexOrElement.parentElement !== this.actionsList) { if (!indexOrElement.parentElement) { return undefined; diff --git a/src/vs/base/browser/ui/contextview/contextview.ts b/src/vs/base/browser/ui/contextview/contextview.ts index c10dda88f896b9..4f07df5b8f9016 100644 --- a/src/vs/base/browser/ui/contextview/contextview.ts +++ b/src/vs/base/browser/ui/contextview/contextview.ts @@ -274,7 +274,7 @@ export class ContextView extends Disposable { let around: IView; // Get the element's position and size (to anchor the view) - if (anchor instanceof HTMLElement) { + if (DOM.isHTMLElement(anchor)) { const elementPosition = DOM.getDomNodePagePosition(anchor); // In areas where zoom is applied to the element or its ancestors, we need to adjust the size of the element diff --git a/src/vs/base/browser/ui/iconLabel/iconLabel.ts b/src/vs/base/browser/ui/iconLabel/iconLabel.ts index 2b297fa6defd82..214af03716cf07 100644 --- a/src/vs/base/browser/ui/iconLabel/iconLabel.ts +++ b/src/vs/base/browser/ui/iconLabel/iconLabel.ts @@ -158,7 +158,7 @@ export class IconLabel extends Disposable { const existingIconNode = this.domNode.element.querySelector('.monaco-icon-label-iconpath'); if (options?.iconPath) { let iconNode; - if (!existingIconNode || !(existingIconNode instanceof HTMLElement)) { + if (!existingIconNode || !(dom.isHTMLElement(existingIconNode))) { iconNode = dom.$('.monaco-icon-label-iconpath'); this.domNode.element.prepend(iconNode); } else { diff --git a/src/vs/base/browser/ui/list/listView.ts b/src/vs/base/browser/ui/list/listView.ts index 1550e7cc10edef..005d34d67385f7 100644 --- a/src/vs/base/browser/ui/list/listView.ts +++ b/src/vs/base/browser/ui/list/listView.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { DataTransfers, IDragAndDropData } from 'vs/base/browser/dnd'; -import { $, addDisposableListener, animate, Dimension, getContentHeight, getContentWidth, getTopLeftOffset, getWindow, isAncestor, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom'; +import { $, addDisposableListener, animate, Dimension, getContentHeight, getContentWidth, getTopLeftOffset, getWindow, isAncestor, isHTMLElement, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom'; import { DomEmitter } from 'vs/base/browser/event'; import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent'; import { EventType as TouchEventType, Gesture, GestureEvent } from 'vs/base/browser/touch'; @@ -1384,7 +1384,7 @@ export class ListView implements IListView { const scrollableElement = this.scrollableElement.getDomNode(); let element: HTMLElement | null = target as (HTMLElement | null); - while (element instanceof HTMLElement && element !== this.rowsContainer && scrollableElement.contains(element)) { + while (isHTMLElement(element) && element !== this.rowsContainer && scrollableElement.contains(element)) { const rawIndex = element.getAttribute('data-index'); if (rawIndex) { diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index 576a0bfa640967..535b245d71d579 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IDragAndDropData } from 'vs/base/browser/dnd'; -import { asCssValueWithDefault, createStyleSheet, Dimension, EventHelper, getActiveElement, getWindow, isActiveElement, isMouseEvent } from 'vs/base/browser/dom'; +import { asCssValueWithDefault, createStyleSheet, Dimension, EventHelper, getActiveElement, getWindow, isActiveElement, isHTMLElement, isMouseEvent } from 'vs/base/browser/dom'; import { DomEmitter } from 'vs/base/browser/event'; import { IKeyboardEvent, StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { Gesture } from 'vs/base/browser/touch'; @@ -635,7 +635,7 @@ class DOMFocusController implements IDisposable { const tabIndexElement = focusedDomElement.querySelector('[tabIndex]'); - if (!tabIndexElement || !(tabIndexElement instanceof HTMLElement) || tabIndexElement.tabIndex === -1) { + if (!tabIndexElement || !(isHTMLElement(tabIndexElement)) || tabIndexElement.tabIndex === -1) { return; } diff --git a/src/vs/base/browser/ui/sash/sash.ts b/src/vs/base/browser/ui/sash/sash.ts index 44fa17be826879..dfacef7d6e2a06 100644 --- a/src/vs/base/browser/ui/sash/sash.ts +++ b/src/vs/base/browser/ui/sash/sash.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { $, append, createStyleSheet, EventHelper, EventLike, getWindow } from 'vs/base/browser/dom'; +import { $, append, createStyleSheet, EventHelper, EventLike, getWindow, isHTMLElement } from 'vs/base/browser/dom'; import { DomEmitter } from 'vs/base/browser/event'; import { EventType, Gesture } from 'vs/base/browser/touch'; import { Delayer } from 'vs/base/common/async'; @@ -670,7 +670,7 @@ export class Sash extends Disposable { private getOrthogonalSash(e: PointerEvent): Sash | undefined { const target = e.initialTarget ?? e.target; - if (!target || !(target instanceof HTMLElement)) { + if (!target || !(isHTMLElement(target))) { return undefined; } diff --git a/src/vs/base/browser/ui/splitview/paneview.ts b/src/vs/base/browser/ui/splitview/paneview.ts index 0b519e434110b7..a934addd1fb3fd 100644 --- a/src/vs/base/browser/ui/splitview/paneview.ts +++ b/src/vs/base/browser/ui/splitview/paneview.ts @@ -5,7 +5,7 @@ import { isFirefox } from 'vs/base/browser/browser'; import { DataTransfers } from 'vs/base/browser/dnd'; -import { $, addDisposableListener, append, clearNode, EventHelper, EventType, getWindow, trackFocus } from 'vs/base/browser/dom'; +import { $, addDisposableListener, append, clearNode, EventHelper, EventType, getWindow, isHTMLElement, trackFocus } from 'vs/base/browser/dom'; import { DomEmitter } from 'vs/base/browser/event'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { Gesture, EventType as TouchEventType } from 'vs/base/browser/touch'; @@ -513,7 +513,7 @@ export class PaneView extends Disposable { const eventDisposables = this._register(new DisposableStore()); const onKeyDown = this._register(new DomEmitter(this.element, 'keydown')); - const onHeaderKeyDown = Event.map(Event.filter(onKeyDown.event, e => e.target instanceof HTMLElement && e.target.classList.contains('pane-header'), eventDisposables), e => new StandardKeyboardEvent(e), eventDisposables); + const onHeaderKeyDown = Event.map(Event.filter(onKeyDown.event, e => isHTMLElement(e.target) && e.target.classList.contains('pane-header'), eventDisposables), e => new StandardKeyboardEvent(e), eventDisposables); this._register(Event.filter(onHeaderKeyDown, e => e.keyCode === KeyCode.UpArrow, eventDisposables)(() => this.focusPrevious())); this._register(Event.filter(onHeaderKeyDown, e => e.keyCode === KeyCode.DownArrow, eventDisposables)(() => this.focusNext())); diff --git a/src/vs/base/test/browser/dom.test.ts b/src/vs/base/test/browser/dom.test.ts index f3ad0d55effc86..03d618b1f0ce95 100644 --- a/src/vs/base/test/browser/dom.test.ts +++ b/src/vs/base/test/browser/dom.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { $, asCssValueWithDefault, h, multibyteAwareBtoa, trackAttributes, copyAttributes, disposableWindowInterval, getWindows, getWindowsCount, getWindowId, getWindowById, hasWindow, getWindow, getDocument } from 'vs/base/browser/dom'; +import { $, asCssValueWithDefault, h, multibyteAwareBtoa, trackAttributes, copyAttributes, disposableWindowInterval, getWindows, getWindowsCount, getWindowId, getWindowById, hasWindow, getWindow, getDocument, isHTMLElement } from 'vs/base/browser/dom'; import { ensureCodeWindow, isAuxiliaryWindow, mainWindow } from 'vs/base/browser/window'; import { DeferredPromise, timeout } from 'vs/base/common/async'; import { runWithFakedTimers } from 'vs/base/test/common/timeTravelScheduler'; @@ -85,7 +85,7 @@ suite('dom', () => { test('should build simple nodes', () => { const div = $('div'); assert(div); - assert(div instanceof HTMLElement); + assert(isHTMLElement(div)); assert.strictEqual(div.tagName, 'DIV'); assert(!div.firstChild); }); @@ -93,7 +93,7 @@ suite('dom', () => { test('should build nodes with id', () => { const div = $('div#foo'); assert(div); - assert(div instanceof HTMLElement); + assert(isHTMLElement(div)); assert.strictEqual(div.tagName, 'DIV'); assert.strictEqual(div.id, 'foo'); }); @@ -101,7 +101,7 @@ suite('dom', () => { test('should build nodes with class-name', () => { const div = $('div.foo'); assert(div); - assert(div instanceof HTMLElement); + assert(isHTMLElement(div)); assert.strictEqual(div.tagName, 'DIV'); assert.strictEqual(div.className, 'foo'); }); @@ -136,15 +136,15 @@ suite('dom', () => { suite('h', () => { test('should build simple nodes', () => { const div = h('div'); - assert(div.root instanceof HTMLElement); + assert(isHTMLElement(div.root)); assert.strictEqual(div.root.tagName, 'DIV'); const span = h('span'); - assert(span.root instanceof HTMLElement); + assert(isHTMLElement(span.root)); assert.strictEqual(span.root.tagName, 'SPAN'); const img = h('img'); - assert(img.root instanceof HTMLElement); + assert(isHTMLElement(img.root)); assert.strictEqual(img.root.tagName, 'IMG'); }); diff --git a/src/vs/base/test/browser/iconLabels.test.ts b/src/vs/base/test/browser/iconLabels.test.ts index c076d4ec38e411..3972977f65f4d5 100644 --- a/src/vs/base/test/browser/iconLabels.test.ts +++ b/src/vs/base/test/browser/iconLabels.test.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; +import { isHTMLElement } from 'vs/base/browser/dom'; import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels'; import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; @@ -47,7 +48,7 @@ suite('renderLabelWithIcons', () => { const elementsToString = (elements: Array): string => { return elements - .map(elem => elem instanceof HTMLElement ? elem.outerHTML : elem) + .map(elem => isHTMLElement(elem) ? elem.outerHTML : elem) .reduce((a, b) => a + b, ''); }; diff --git a/src/vs/editor/browser/services/hoverService/hoverService.ts b/src/vs/editor/browser/services/hoverService/hoverService.ts index 8c5e73193310ec..0c554ca039ebc3 100644 --- a/src/vs/editor/browser/services/hoverService/hoverService.ts +++ b/src/vs/editor/browser/services/hoverService/hoverService.ts @@ -12,7 +12,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { HoverWidget } from 'vs/editor/browser/services/hoverService/hoverWidget'; import { IContextViewProvider, IDelegate } from 'vs/base/browser/ui/contextview/contextview'; import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { addDisposableListener, EventType, getActiveElement, isAncestorOfActiveElement, isAncestor, getWindow } from 'vs/base/browser/dom'; +import { addDisposableListener, EventType, getActiveElement, isAncestorOfActiveElement, isAncestor, getWindow, isHTMLElement } from 'vs/base/browser/dom'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { ResultKind } from 'vs/platform/keybinding/common/keybindingResolver'; @@ -90,7 +90,7 @@ export class HoverService extends Disposable implements IHoverService { }, undefined, hoverDisposables); // Set the container explicitly to enable aux window support if (!options.container) { - const targetElement = options.target instanceof HTMLElement ? options.target : options.target.targetElements[0]; + const targetElement = isHTMLElement(options.target) ? options.target : options.target.targetElements[0]; options.container = this._layoutService.getContainer(getWindow(targetElement)); } @@ -259,7 +259,7 @@ export class HoverService extends Disposable implements IHoverService { // track the mouse position const onMouseMove = (e: MouseEvent) => { target.x = e.x + 10; - if ((e.target instanceof HTMLElement) && getHoverTargetElement(e.target, htmlElement) !== htmlElement) { + if ((isHTMLElement(e.target)) && getHoverTargetElement(e.target, htmlElement) !== htmlElement) { hideHover(true, true); } }; @@ -268,7 +268,7 @@ export class HoverService extends Disposable implements IHoverService { hoverPreparation = toDispose; - if ((e.target instanceof HTMLElement) && getHoverTargetElement(e.target as HTMLElement, htmlElement) !== htmlElement) { + if ((isHTMLElement(e.target)) && getHoverTargetElement(e.target as HTMLElement, htmlElement) !== htmlElement) { return; // Do not show hover when the mouse is over another hover target } diff --git a/src/vs/editor/browser/services/hoverService/hoverWidget.ts b/src/vs/editor/browser/services/hoverService/hoverWidget.ts index 163633fa206330..ed929bc965cf37 100644 --- a/src/vs/editor/browser/services/hoverService/hoverWidget.ts +++ b/src/vs/editor/browser/services/hoverService/hoverWidget.ts @@ -150,7 +150,7 @@ export class HoverWidget extends Widget implements IHoverWidget { contentsElement.textContent = options.content; contentsElement.style.whiteSpace = 'pre-wrap'; - } else if (options.content instanceof HTMLElement) { + } else if (dom.isHTMLElement(options.content)) { contentsElement.appendChild(options.content); contentsElement.classList.add('html-hover-contents'); diff --git a/src/vs/editor/browser/services/hoverService/updatableHoverWidget.ts b/src/vs/editor/browser/services/hoverService/updatableHoverWidget.ts index 762b6626aff4ca..3b746de6f43c45 100644 --- a/src/vs/editor/browser/services/hoverService/updatableHoverWidget.ts +++ b/src/vs/editor/browser/services/hoverService/updatableHoverWidget.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { isHTMLElement } from 'vs/base/browser/dom'; import type { IHoverWidget, IUpdatableHoverContent, IUpdatableHoverOptions } from 'vs/base/browser/ui/hover/hover'; import type { IHoverDelegate, IHoverDelegateOptions, IHoverDelegateTarget } from 'vs/base/browser/ui/hover/hoverDelegate'; import { HoverPosition } from 'vs/base/browser/ui/hover/hoverWidget'; @@ -33,7 +34,7 @@ export class UpdatableHoverWidget implements IDisposable { } let resolvedContent; - if (content === undefined || isString(content) || content instanceof HTMLElement) { + if (content === undefined || isString(content) || isHTMLElement(content)) { resolvedContent = content; } else if (!isFunction(content.markdown)) { resolvedContent = content.markdown ?? content.markdownNotSupportedFallback; diff --git a/src/vs/editor/contrib/inlayHints/browser/inlayHintsController.ts b/src/vs/editor/contrib/inlayHints/browser/inlayHintsController.ts index b2b665a7eddbec..accb88043ff9c1 100644 --- a/src/vs/editor/contrib/inlayHints/browser/inlayHintsController.ts +++ b/src/vs/editor/contrib/inlayHints/browser/inlayHintsController.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { ModifierKeyEmitter } from 'vs/base/browser/dom'; +import { isHTMLElement, ModifierKeyEmitter } from 'vs/base/browser/dom'; import { isNonEmptyArray } from 'vs/base/common/arrays'; import { RunOnceScheduler } from 'vs/base/common/async'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; @@ -358,7 +358,7 @@ export class InlayHintsController implements IEditorContribution { private _installContextMenu(): IDisposable { return this._editor.onContextMenu(async e => { - if (!(e.event.target instanceof HTMLElement)) { + if (!(isHTMLElement(e.event.target))) { return; } const part = this._getInlayHintLabelPart(e); diff --git a/src/vs/platform/clipboard/browser/clipboardService.ts b/src/vs/platform/clipboard/browser/clipboardService.ts index 7af565a3b34511..ed5490e783f746 100644 --- a/src/vs/platform/clipboard/browser/clipboardService.ts +++ b/src/vs/platform/clipboard/browser/clipboardService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { isSafari, isWebkitWebView } from 'vs/base/browser/browser'; -import { $, addDisposableListener, getActiveDocument, getActiveWindow, onDidRegisterWindow } from 'vs/base/browser/dom'; +import { $, addDisposableListener, getActiveDocument, getActiveWindow, isHTMLElement, onDidRegisterWindow } from 'vs/base/browser/dom'; import { mainWindow } from 'vs/base/browser/window'; import { DeferredPromise } from 'vs/base/common/async'; import { Event } from 'vs/base/common/event'; @@ -130,7 +130,7 @@ export class BrowserClipboardService extends Disposable implements IClipboardSer activeDocument.execCommand('copy'); - if (activeElement instanceof HTMLElement) { + if (isHTMLElement(activeElement)) { activeElement.focus(); } diff --git a/src/vs/platform/contextview/browser/contextMenuHandler.ts b/src/vs/platform/contextview/browser/contextMenuHandler.ts index 55e0d50422d128..abc08f92252359 100644 --- a/src/vs/platform/contextview/browser/contextMenuHandler.ts +++ b/src/vs/platform/contextview/browser/contextMenuHandler.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IContextMenuDelegate } from 'vs/base/browser/contextmenu'; -import { $, addDisposableListener, EventType, getActiveElement, getWindow, isAncestor } from 'vs/base/browser/dom'; +import { $, addDisposableListener, EventType, getActiveElement, getWindow, isAncestor, isHTMLElement } from 'vs/base/browser/dom'; import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { Menu } from 'vs/base/browser/ui/menu/menu'; import { ActionRunner, IRunEvent, WorkbenchActionExecutedClassification, WorkbenchActionExecutedEvent } from 'vs/base/common/actions'; @@ -49,7 +49,7 @@ export class ContextMenuHandler { let menu: Menu | undefined; - const shadowRootElement = delegate.domForShadowRoot instanceof HTMLElement ? delegate.domForShadowRoot : undefined; + const shadowRootElement = isHTMLElement(delegate.domForShadowRoot) ? delegate.domForShadowRoot : undefined; this.contextViewService.showContextView({ getAnchor: () => delegate.getAnchor(), canRelayout: false, diff --git a/src/vs/platform/dnd/browser/dnd.ts b/src/vs/platform/dnd/browser/dnd.ts index 1bd55afefafa46..b742b3ae448ce1 100644 --- a/src/vs/platform/dnd/browser/dnd.ts +++ b/src/vs/platform/dnd/browser/dnd.ts @@ -201,6 +201,7 @@ async function extractFilesDropData(accessor: ServicesAccessor, event: DragEvent async function extractFileTransferData(accessor: ServicesAccessor, items: DataTransferItemList): Promise { const fileSystemProvider = accessor.get(IFileService).getProvider(Schemas.file); + // eslint-disable-next-line no-restricted-syntax if (!(fileSystemProvider instanceof HTMLFileSystemProvider)) { return []; // only supported when running in web } diff --git a/src/vs/platform/hover/browser/hover.ts b/src/vs/platform/hover/browser/hover.ts index b856f528c5b522..51ead712fcb59a 100644 --- a/src/vs/platform/hover/browser/hover.ts +++ b/src/vs/platform/hover/browser/hover.ts @@ -7,7 +7,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation' import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { IHoverDelegate, IHoverDelegateOptions } from 'vs/base/browser/ui/hover/hoverDelegate'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { addStandardDisposableListener } from 'vs/base/browser/dom'; +import { addStandardDisposableListener, isHTMLElement } from 'vs/base/browser/dom'; import { KeyCode } from 'vs/base/common/keyCodes'; import type { IHoverDelegate2, IHoverOptions, IHoverWidget } from 'vs/base/browser/ui/hover/hover'; @@ -54,7 +54,7 @@ export class WorkbenchHoverDelegate extends Disposable implements IHoverDelegate // close hover on escape this.hoverDisposables.clear(); - const targets = options.target instanceof HTMLElement ? [options.target] : options.target.targetElements; + const targets = isHTMLElement(options.target) ? [options.target] : options.target.targetElements; for (const target of targets) { this.hoverDisposables.add(addStandardDisposableListener(target, 'keydown', (e) => { if (e.equals(KeyCode.Escape)) { @@ -63,7 +63,7 @@ export class WorkbenchHoverDelegate extends Disposable implements IHoverDelegate })); } - const id = options.content instanceof HTMLElement ? undefined : options.content.toString(); + const id = isHTMLElement(options.content) ? undefined : options.content.toString(); return this.hoverService.showHover({ ...options, diff --git a/src/vs/platform/quickinput/browser/quickInput.ts b/src/vs/platform/quickinput/browser/quickInput.ts index 7b43505fb646e5..4c6dfbe6b7d6d5 100644 --- a/src/vs/platform/quickinput/browser/quickInput.ts +++ b/src/vs/platform/quickinput/browser/quickInput.ts @@ -206,7 +206,7 @@ abstract class QuickInput extends Disposable implements IQuickInput { } set widget(widget: unknown | undefined) { - if (!(widget instanceof HTMLElement)) { + if (!(dom.isHTMLElement(widget))) { return; } if (this._widget !== widget) { @@ -1271,7 +1271,7 @@ export class QuickInputHoverDelegate extends WorkbenchHoverDelegate { private getOverrideOptions(options: IHoverDelegateOptions): Partial { // Only show the hover hint if the content is of a decent size const showHoverHint = ( - options.content instanceof HTMLElement + dom.isHTMLElement(options.content) ? options.content.textContent ?? '' : typeof options.content === 'string' ? options.content diff --git a/src/vs/platform/quickinput/browser/quickInputController.ts b/src/vs/platform/quickinput/browser/quickInputController.ts index e95080154871e3..626b74e8fa5209 100644 --- a/src/vs/platform/quickinput/browser/quickInputController.ts +++ b/src/vs/platform/quickinput/browser/quickInputController.ts @@ -225,7 +225,7 @@ export class QuickInputController extends Disposable { return; } this.inQuickInputContext.set(true); - this.previousFocusElement = e.relatedTarget instanceof HTMLElement ? e.relatedTarget : undefined; + this.previousFocusElement = dom.isHTMLElement(e.relatedTarget) ? e.relatedTarget : undefined; }, true)); this._register(focusTracker.onDidBlur(() => { if (!this.getUI().ignoreFocusOut && !this.options.ignoreFocusOut()) { diff --git a/src/vs/platform/quickinput/browser/quickInputTree.ts b/src/vs/platform/quickinput/browser/quickInputTree.ts index 3a492f78a1ee32..6fa28c37170a39 100644 --- a/src/vs/platform/quickinput/browser/quickInputTree.ts +++ b/src/vs/platform/quickinput/browser/quickInputTree.ts @@ -903,13 +903,13 @@ export class QuickInputTree extends Disposable { this._register(this._tree.onMouseOver(async e => { // If we hover over an anchor element, we don't want to show the hover because // the anchor may have a tooltip that we want to show instead. - if (e.browserEvent.target instanceof HTMLAnchorElement) { + if (dom.isHTMLAnchorElement(e.browserEvent.target)) { delayer.cancel(); return; } if ( // anchors are an exception as called out above so we skip them here - !(e.browserEvent.relatedTarget instanceof HTMLAnchorElement) && + !(dom.isHTMLAnchorElement(e.browserEvent.relatedTarget)) && // check if the mouse is still over the same element dom.isAncestor(e.browserEvent.relatedTarget as Node, e.element?.element as Node) ) { diff --git a/src/vs/workbench/browser/actions/textInputActions.ts b/src/vs/workbench/browser/actions/textInputActions.ts index dae9d15bd89506..c06fb52ca305e1 100644 --- a/src/vs/workbench/browser/actions/textInputActions.ts +++ b/src/vs/workbench/browser/actions/textInputActions.ts @@ -8,7 +8,7 @@ import { localize } from 'vs/nls'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { Disposable } from 'vs/base/common/lifecycle'; -import { EventHelper, addDisposableListener, getActiveDocument, getWindow } from 'vs/base/browser/dom'; +import { EventHelper, addDisposableListener, getActiveDocument, getWindow, isHTMLElement, isHTMLInputElement, isHTMLTextAreaElement } from 'vs/base/browser/dom'; import { IWorkbenchContribution, WorkbenchPhase, registerWorkbenchContribution2 } from 'vs/workbench/common/contributions'; import { isNative } from 'vs/base/common/platform'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; @@ -54,8 +54,8 @@ export class TextInputActionsProvider extends Disposable implements IWorkbenchCo else { const clipboardText = await this.clipboardService.readText(); if ( - element instanceof HTMLTextAreaElement || - element instanceof HTMLInputElement + isHTMLTextAreaElement(element) || + isHTMLInputElement(element) ) { const selectionStart = element.selectionStart || 0; const selectionEnd = element.selectionEnd || 0; @@ -88,7 +88,7 @@ export class TextInputActionsProvider extends Disposable implements IWorkbenchCo } const target = e.target; - if (!(target instanceof HTMLElement) || (target.nodeName.toLowerCase() !== 'input' && target.nodeName.toLowerCase() !== 'textarea')) { + if (!(isHTMLElement(target)) || (target.nodeName.toLowerCase() !== 'input' && target.nodeName.toLowerCase() !== 'textarea')) { return; // only for inputs or textareas } diff --git a/src/vs/workbench/browser/actions/windowActions.ts b/src/vs/workbench/browser/actions/windowActions.ts index 4020ac2b0e6d8e..26c0b61d3d16a1 100644 --- a/src/vs/workbench/browser/actions/windowActions.ts +++ b/src/vs/workbench/browser/actions/windowActions.ts @@ -34,7 +34,7 @@ import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { isFolderBackupInfo, isWorkspaceBackupInfo } from 'vs/platform/backup/common/backup'; -import { getActiveElement, getActiveWindow } from 'vs/base/browser/dom'; +import { getActiveElement, getActiveWindow, isHTMLElement } from 'vs/base/browser/dom'; export const inRecentFilesPickerContextKey = 'inRecentFilesPicker'; @@ -404,7 +404,7 @@ class BlurAction extends Action2 { run(): void { const activeElement = getActiveElement(); - if (activeElement instanceof HTMLElement) { + if (isHTMLElement(activeElement)) { activeElement.blur(); } } diff --git a/src/vs/workbench/browser/parts/banner/bannerPart.ts b/src/vs/workbench/browser/parts/banner/bannerPart.ts index dda7c882d5ec81..e8957eae627396 100644 --- a/src/vs/workbench/browser/parts/banner/bannerPart.ts +++ b/src/vs/workbench/browser/parts/banner/bannerPart.ts @@ -5,7 +5,7 @@ import 'vs/css!./media/bannerpart'; import { localize2 } from 'vs/nls'; -import { $, addDisposableListener, append, asCSSUrl, clearNode, EventType } from 'vs/base/browser/dom'; +import { $, addDisposableListener, append, asCSSUrl, clearNode, EventType, isHTMLElement } from 'vs/base/browser/dom'; import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; @@ -112,7 +112,7 @@ export class BannerPart extends Part implements IBannerService { if (this.focusedActionIndex < length) { const actionLink = this.messageActionsContainer?.children[this.focusedActionIndex]; - if (actionLink instanceof HTMLElement) { + if (isHTMLElement(actionLink)) { this.actionBar?.setFocusable(false); actionLink.focus(); } diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index 6d2df54a866729..d785a5137981e6 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -5,7 +5,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; import { Part } from 'vs/workbench/browser/part'; -import { Dimension, $, EventHelper, addDisposableGenericMouseDownListener, getWindow, isAncestorOfActiveElement, getActiveElement } from 'vs/base/browser/dom'; +import { Dimension, $, EventHelper, addDisposableGenericMouseDownListener, getWindow, isAncestorOfActiveElement, getActiveElement, isHTMLElement } from 'vs/base/browser/dom'; import { Event, Emitter, Relay, PauseableEmitter } from 'vs/base/common/event'; import { contrastBorder, editorBackground } from 'vs/platform/theme/common/colorRegistry'; import { GroupDirection, GroupsArrangement, GroupOrientation, IMergeGroupOptions, MergeGroupMode, GroupsOrder, GroupLocation, IFindGroupScope, EditorGroupLayout, GroupLayoutArgument, IEditorSideGroup, IEditorDropTargetDelegate, IEditorPart } from 'vs/workbench/services/editor/common/editorGroupsService'; @@ -934,7 +934,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupsView { } createEditorDropTarget(container: unknown, delegate: IEditorDropTargetDelegate): IDisposable { - assertType(container instanceof HTMLElement); + assertType(isHTMLElement(container)); return this.scopedInstantiationService.createInstance(EditorDropTarget, container, delegate); } diff --git a/src/vs/workbench/browser/parts/editor/editorParts.ts b/src/vs/workbench/browser/parts/editor/editorParts.ts index 564464012e0d20..e505a3fd466ee0 100644 --- a/src/vs/workbench/browser/parts/editor/editorParts.ts +++ b/src/vs/workbench/browser/parts/editor/editorParts.ts @@ -21,6 +21,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IAuxiliaryWindowOpenOptions, IAuxiliaryWindowService } from 'vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService'; import { generateUuid } from 'vs/base/common/uuid'; import { ContextKeyValue, IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; +import { isHTMLElement } from 'vs/base/browser/dom'; interface IEditorPartsUIState { readonly auxiliary: IAuxiliaryEditorPartState[]; @@ -161,7 +162,7 @@ export class EditorParts extends MultiWindowParts implements IEditor override getPart(element: HTMLElement): EditorPart; override getPart(groupOrElement: IEditorGroupView | GroupIdentifier | HTMLElement): EditorPart { if (this._parts.size > 1) { - if (groupOrElement instanceof HTMLElement) { + if (isHTMLElement(groupOrElement)) { const element = groupOrElement; return this.getPartByDocument(element.ownerDocument); diff --git a/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts b/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts index b6b3dd436ac344..cfbf35f736a2b4 100644 --- a/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts +++ b/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts @@ -10,7 +10,7 @@ import { EditorTabsControl } from 'vs/workbench/browser/parts/editor/editorTabsC import { ResourceLabel, IResourceLabel } from 'vs/workbench/browser/labels'; import { TAB_ACTIVE_FOREGROUND, TAB_UNFOCUSED_ACTIVE_FOREGROUND } from 'vs/workbench/common/theme'; import { EventType as TouchEventType, GestureEvent, Gesture } from 'vs/base/browser/touch'; -import { addDisposableListener, EventType, EventHelper, Dimension, isAncestor, DragAndDropObserver } from 'vs/base/browser/dom'; +import { addDisposableListener, EventType, EventHelper, Dimension, isAncestor, DragAndDropObserver, isHTMLElement } from 'vs/base/browser/dom'; import { CLOSE_EDITOR_COMMAND_ID, UNLOCK_GROUP_COMMAND_ID } from 'vs/workbench/browser/parts/editor/editorCommands'; import { Color } from 'vs/base/common/color'; import { assertIsDefined, assertAllDefined } from 'vs/base/common/types'; @@ -130,7 +130,7 @@ export class SingleEditorTabsControl extends EditorTabsControl { // to check on the target // (https://github.com/microsoft/vscode/issues/107543) const target = e.initialTarget; - if (!(target instanceof HTMLElement) || !this.editorLabel || !isAncestor(target, this.editorLabel.element)) { + if (!(isHTMLElement(target)) || !this.editorLabel || !isAncestor(target, this.editorLabel.element)) { return; } diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index 0bee377dce951a..80c99f1557d2fa 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -19,7 +19,7 @@ import { ThemeIcon } from 'vs/base/common/themables'; import { TITLE_BAR_ACTIVE_BACKGROUND, TITLE_BAR_ACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_BACKGROUND, TITLE_BAR_BORDER, WORKBENCH_BACKGROUND } from 'vs/workbench/common/theme'; import { isMacintosh, isWindows, isLinux, isWeb, isNative, platformLocale } from 'vs/base/common/platform'; import { Color } from 'vs/base/common/color'; -import { EventType, EventHelper, Dimension, append, $, addDisposableListener, prepend, reset, getWindow, getWindowId, isAncestor, getActiveDocument } from 'vs/base/browser/dom'; +import { EventType, EventHelper, Dimension, append, $, addDisposableListener, prepend, reset, getWindow, getWindowId, isAncestor, getActiveDocument, isHTMLElement } from 'vs/base/browser/dom'; import { CustomMenubarControl } from 'vs/workbench/browser/parts/titlebar/menubarControl'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { Emitter, Event } from 'vs/base/common/event'; @@ -474,7 +474,7 @@ export class BrowserTitlebarPart extends Part implements ITitlebarPart { EventHelper.stop(e); let targetMenu: MenuId; - if (isMacintosh && e.target instanceof HTMLElement && isAncestor(e.target, this.title)) { + if (isMacintosh && isHTMLElement(e.target) && isAncestor(e.target, this.title)) { targetMenu = MenuId.TitleBarTitleContext; } else { targetMenu = MenuId.TitleBarContext; diff --git a/src/vs/workbench/browser/parts/views/treeView.ts b/src/vs/workbench/browser/parts/views/treeView.ts index becd185fd60ea6..db78e940c5d929 100644 --- a/src/vs/workbench/browser/parts/views/treeView.ts +++ b/src/vs/workbench/browser/parts/views/treeView.ts @@ -877,7 +877,7 @@ abstract class AbstractTreeView extends Disposable implements ITreeView { const container = document.createElement('div'); container.classList.add('rendered-message'); for (const child of result) { - if (child instanceof HTMLElement) { + if (DOM.isHTMLElement(child)) { container.appendChild(child); } else { container.appendChild(child.element); diff --git a/src/vs/workbench/contrib/codeEditor/browser/inspectEditorTokens/inspectEditorTokens.ts b/src/vs/workbench/contrib/codeEditor/browser/inspectEditorTokens/inspectEditorTokens.ts index e4d481e7fe12cc..8b2fa1d66320b2 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/inspectEditorTokens/inspectEditorTokens.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/inspectEditorTokens/inspectEditorTokens.ts @@ -326,7 +326,7 @@ class InspectEditorTokensWidget extends Disposable implements IContentWidget { if (semanticTokenInfo.metadata[property] !== undefined) { const definition = semanticTokenInfo.definitions[property]; const defValue = this._renderTokenStyleDefinition(definition, property); - const defValueStr = defValue.map(el => el instanceof HTMLElement ? el.outerHTML : el).join(); + const defValueStr = defValue.map(el => dom.isHTMLElement(el) ? el.outerHTML : el).join(); let properties = propertiesByDefValue[defValueStr]; if (!properties) { propertiesByDefValue[defValueStr] = properties = []; diff --git a/src/vs/workbench/contrib/debug/test/browser/baseDebugView.test.ts b/src/vs/workbench/contrib/debug/test/browser/baseDebugView.test.ts index 075791be12aefc..a5ba220e380c56 100644 --- a/src/vs/workbench/contrib/debug/test/browser/baseDebugView.test.ts +++ b/src/vs/workbench/contrib/debug/test/browser/baseDebugView.test.ts @@ -42,7 +42,7 @@ suite('Debug - Base Debug View', () => { assert.strictEqual(treeContainer.className, 'debug-view-content'); assert.strictEqual(container.childElementCount, 1); assert.strictEqual(container.firstChild, treeContainer); - assert.strictEqual(treeContainer instanceof HTMLDivElement, true); + assert.strictEqual(dom.isHTMLDivElement(treeContainer), true); }); test('render expression value', () => { diff --git a/src/vs/workbench/contrib/debug/test/browser/debugANSIHandling.test.ts b/src/vs/workbench/contrib/debug/test/browser/debugANSIHandling.test.ts index c6901f77f8597d..c92a240a22055d 100644 --- a/src/vs/workbench/contrib/debug/test/browser/debugANSIHandling.test.ts +++ b/src/vs/workbench/contrib/debug/test/browser/debugANSIHandling.test.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; +import { isHTMLSpanElement } from 'vs/base/browser/dom'; import { Color, RGBA } from 'vs/base/common/color'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { generateUuid } from 'vs/base/common/uuid'; @@ -66,7 +67,7 @@ suite('Debug - ANSI Handling', () => { assert.strictEqual(2, root.children.length); child = root.firstChild!; - if (child instanceof HTMLSpanElement) { + if (isHTMLSpanElement(child)) { assert.strictEqual('content1', child.textContent); assert(child.classList.contains('class1')); assert(child.classList.contains('class2')); @@ -75,7 +76,7 @@ suite('Debug - ANSI Handling', () => { } child = root.lastChild!; - if (child instanceof HTMLSpanElement) { + if (isHTMLSpanElement(child)) { assert.strictEqual('content2', child.textContent); assert(child.classList.contains('class2')); assert(child.classList.contains('class3')); @@ -94,7 +95,7 @@ suite('Debug - ANSI Handling', () => { const root: HTMLSpanElement = handleANSIOutput(sequence, linkDetector, themeService, session.root); assert.strictEqual(1, root.children.length); const child: Node = root.lastChild!; - if (child instanceof HTMLSpanElement) { + if (isHTMLSpanElement(child)) { return child; } else { assert.fail('Unexpected assertion error'); @@ -408,7 +409,7 @@ suite('Debug - ANSI Handling', () => { assert.strictEqual(elementsExpected, root.children.length); for (let i = 0; i < elementsExpected; i++) { const child: Node = root.children[i]; - if (child instanceof HTMLSpanElement) { + if (isHTMLSpanElement(child)) { assertions[i](child); } else { assert.fail('Unexpected assertion error'); diff --git a/src/vs/workbench/contrib/debug/test/browser/linkDetector.test.ts b/src/vs/workbench/contrib/debug/test/browser/linkDetector.test.ts index e389f76ae26ef4..6a38dac9fdc43a 100644 --- a/src/vs/workbench/contrib/debug/test/browser/linkDetector.test.ts +++ b/src/vs/workbench/contrib/debug/test/browser/linkDetector.test.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; +import { isHTMLAnchorElement } from 'vs/base/browser/dom'; import { isWindows } from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; @@ -33,7 +34,7 @@ suite('Debug - Link Detector', () => { * @param element The Element to verify. */ function assertElementIsLink(element: Element) { - assert(element instanceof HTMLAnchorElement); + assert(isHTMLAnchorElement(element)); } test('noLinks', () => { diff --git a/src/vs/workbench/contrib/files/browser/views/explorerView.ts b/src/vs/workbench/contrib/files/browser/views/explorerView.ts index d8e22884dc841f..a94048551aa3fa 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerView.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerView.ts @@ -610,7 +610,7 @@ export class ExplorerView extends ViewPane implements IExplorerView { let anchor = e.anchor; // Adjust for compressed folders (except when mouse is used) - if (anchor instanceof HTMLElement) { + if (DOM.isHTMLElement(anchor)) { if (stat) { const controllers = this.renderer.getCompressedNavigationController(stat); diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 068fde51b808dd..bda9eb9b2aaa55 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -575,7 +575,7 @@ export class FilesRenderer implements ICompressibleTreeRenderer { } function getIconLabelNameFromHTMLElement(target: HTMLElement | EventTarget | Element | null): { element: HTMLElement; count: number; index: number } | null { - if (!(target instanceof HTMLElement)) { + if (!(DOM.isHTMLElement(target))) { return null; } diff --git a/src/vs/workbench/contrib/issue/browser/issueReporterService.ts b/src/vs/workbench/contrib/issue/browser/issueReporterService.ts index b89619f91bcc7d..59eae428a919bd 100644 --- a/src/vs/workbench/contrib/issue/browser/issueReporterService.ts +++ b/src/vs/workbench/contrib/issue/browser/issueReporterService.ts @@ -2,7 +2,7 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { $, reset, windowOpenNoOpener } from 'vs/base/browser/dom'; +import { $, isHTMLInputElement, isHTMLTextAreaElement, reset, windowOpenNoOpener } from 'vs/base/browser/dom'; import { Codicon } from 'vs/base/common/codicons'; import { groupBy } from 'vs/base/common/collections'; import { isMacintosh } from 'vs/base/common/platform'; @@ -124,7 +124,7 @@ export class IssueWebReporter extends BaseIssueReporterService { // Manually perform the selection if (isMacintosh) { if (cmdOrCtrlKey && e.key === 'a' && e.target) { - if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) { + if (isHTMLInputElement(e.target) || isHTMLTextAreaElement(e.target)) { (e.target).select(); } } diff --git a/src/vs/workbench/contrib/issue/browser/issueService.ts b/src/vs/workbench/contrib/issue/browser/issueService.ts index 82f3ac2eb0002e..6030bbfd928a93 100644 --- a/src/vs/workbench/contrib/issue/browser/issueService.ts +++ b/src/vs/workbench/contrib/issue/browser/issueService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as dom from 'vs/base/browser/dom'; -import { isFirefox, userAgent } from 'vs/base/common/platform'; +import { userAgent } from 'vs/base/common/platform'; import { IExtensionDescription, ExtensionType } from 'vs/platform/extensions/common/extensions'; import { normalizeGitHubUrl } from 'vs/platform/issue/common/issueReporterUtil'; import { getZoomLevel } from 'vs/base/browser/browser'; @@ -49,8 +49,8 @@ export class BrowserIssueService implements IWorkbenchIssueService { } async openReporter(options: Partial): Promise { - // If web reporter setting is false, or if we are in Firefox, open the old GitHub issue reporter - if (!this.configurationService.getValue('issueReporter.experimental.webReporter') || isFirefox) { + // If web reporter setting is false open the old GitHub issue reporter + if (!this.configurationService.getValue('issueReporter.experimental.webReporter')) { const extensionId = options.extensionId; // If we don't have a extensionId, treat this as a Core issue if (!extensionId) { diff --git a/src/vs/workbench/contrib/issue/electron-sandbox/issueReporterService.ts b/src/vs/workbench/contrib/issue/electron-sandbox/issueReporterService.ts index 873d3b92a3a1a6..961ba3291a1fad 100644 --- a/src/vs/workbench/contrib/issue/electron-sandbox/issueReporterService.ts +++ b/src/vs/workbench/contrib/issue/electron-sandbox/issueReporterService.ts @@ -2,7 +2,7 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { $, createStyleSheet, reset, windowOpenNoOpener } from 'vs/base/browser/dom'; +import { $, createStyleSheet, isHTMLInputElement, isHTMLTextAreaElement, reset, windowOpenNoOpener } from 'vs/base/browser/dom'; import { Button, unthemedButtonStyles } from 'vs/base/browser/ui/button/button'; import { renderIcon } from 'vs/base/browser/ui/iconLabel/iconLabels'; import { mainWindow } from 'vs/base/browser/window'; @@ -458,7 +458,7 @@ export class IssueReporter extends Disposable { // Manually perform the selection if (isMacintosh) { if (cmdOrCtrlKey && e.keyCode === 65 && e.target) { - if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) { + if (isHTMLInputElement(e.target) || isHTMLTextAreaElement(e.target)) { (e.target).select(); } } diff --git a/src/vs/workbench/contrib/issue/electron-sandbox/issueReporterService2.ts b/src/vs/workbench/contrib/issue/electron-sandbox/issueReporterService2.ts index 0c6477b7bfec89..6f6bdd1c1f4884 100644 --- a/src/vs/workbench/contrib/issue/electron-sandbox/issueReporterService2.ts +++ b/src/vs/workbench/contrib/issue/electron-sandbox/issueReporterService2.ts @@ -2,7 +2,7 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { $, reset, windowOpenNoOpener } from 'vs/base/browser/dom'; +import { $, isHTMLInputElement, isHTMLTextAreaElement, reset, windowOpenNoOpener } from 'vs/base/browser/dom'; import { mainWindow } from 'vs/base/browser/window'; import { Codicon } from 'vs/base/common/codicons'; import { groupBy } from 'vs/base/common/collections'; @@ -146,7 +146,7 @@ export class IssueReporter2 extends BaseIssueReporterService { // Manually perform the selection if (isMacintosh) { if (cmdOrCtrlKey && e.key === 'a' && e.target) { - if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) { + if (isHTMLInputElement(e.target) || isHTMLTextAreaElement(e.target)) { (e.target).select(); } } diff --git a/src/vs/workbench/contrib/languageStatus/browser/languageStatus.contribution.ts b/src/vs/workbench/contrib/languageStatus/browser/languageStatus.contribution.ts index fd3f51d3560682..3feb89c66166f3 100644 --- a/src/vs/workbench/contrib/languageStatus/browser/languageStatus.contribution.ts +++ b/src/vs/workbench/contrib/languageStatus/browser/languageStatus.contribution.ts @@ -231,7 +231,7 @@ class LanguageStatus { const targetWindow = dom.getWindow(editor?.getContainerDomNode()); const node = targetWindow.document.querySelector('.monaco-workbench .statusbar DIV#status\\.languageStatus A>SPAN.codicon'); const container = targetWindow.document.querySelector('.monaco-workbench .statusbar DIV#status\\.languageStatus'); - if (node instanceof HTMLElement && container) { + if (dom.isHTMLElement(node) && container) { const _wiggle = 'wiggle'; const _flash = 'flash'; if (!isOneBusy) { @@ -251,7 +251,7 @@ class LanguageStatus { // use that as signal that the user has interacted/learned language status items work if (!userHasInteractedWithStatus) { const hoverTarget = targetWindow.document.querySelector('.monaco-workbench .context-view'); - if (hoverTarget instanceof HTMLElement) { + if (dom.isHTMLElement(hoverTarget)) { const observer = new MutationObserver(() => { if (targetWindow.document.contains(element)) { this._interactionCounter.increment(); diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/clipboard/notebookClipboard.ts b/src/vs/workbench/contrib/notebook/browser/contrib/clipboard/notebookClipboard.ts index 2c4a1d43436750..8aa8b3f3319eb8 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/clipboard/notebookClipboard.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/clipboard/notebookClipboard.ts @@ -28,7 +28,7 @@ import { Categories } from 'vs/platform/action/common/actionCommonCategories'; import { ILogService } from 'vs/platform/log/common/log'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { showWindowLogActionId } from 'vs/workbench/services/log/common/logConstants'; -import { getActiveElement, getWindow, isAncestor } from 'vs/base/browser/dom'; +import { getActiveElement, getWindow, isAncestor, isHTMLElement } from 'vs/base/browser/dom'; let _logging: boolean = false; function toggleLogging() { @@ -360,7 +360,7 @@ export class NotebookClipboardContribution extends Disposable { const loggerService = accessor.get(ILogService); const activeElement = getActiveElement(); - if (activeElement instanceof HTMLElement && ['input', 'textarea'].indexOf(activeElement.tagName.toLowerCase()) >= 0) { + if (isHTMLElement(activeElement) && ['input', 'textarea'].indexOf(activeElement.tagName.toLowerCase()) >= 0) { _log(loggerService, '[NotebookEditor] focus is on input or textarea element, bypass'); return false; } diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/find/notebookFindWidget.ts b/src/vs/workbench/contrib/notebook/browser/contrib/find/notebookFindWidget.ts index 51a075fe24a611..c4307db60b983e 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/find/notebookFindWidget.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/find/notebookFindWidget.ts @@ -121,7 +121,7 @@ class NotebookFindWidget extends SimpleFindReplaceWidget implements INotebookEdi })); this._register(DOM.addDisposableListener(this.getDomNode(), DOM.EventType.FOCUS, e => { - this._previousFocusElement = e.relatedTarget instanceof HTMLElement ? e.relatedTarget : undefined; + this._previousFocusElement = DOM.isHTMLElement(e.relatedTarget) ? e.relatedTarget : undefined; }, true)); } diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts index 4ded337182e92e..fb7dffded14d39 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts @@ -90,7 +90,7 @@ declare function __import(path: string): Promise; async function webviewPreloads(ctx: PreloadContext) { - /* eslint-disable no-restricted-globals */ + /* eslint-disable no-restricted-globals, no-restricted-syntax */ // The use of global `window` should be fine in this context, even // with aux windows. This code is running from within an `iframe` diff --git a/src/vs/workbench/contrib/terminalContrib/find/browser/textInputContextMenu.ts b/src/vs/workbench/contrib/terminalContrib/find/browser/textInputContextMenu.ts index 7253be4ca8e5f6..d63dd7c113cdb7 100644 --- a/src/vs/workbench/contrib/terminalContrib/find/browser/textInputContextMenu.ts +++ b/src/vs/workbench/contrib/terminalContrib/find/browser/textInputContextMenu.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { getActiveWindow } from 'vs/base/browser/dom'; +import { getActiveWindow, isHTMLInputElement, isHTMLTextAreaElement } from 'vs/base/browser/dom'; import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { Action, IAction, Separator } from 'vs/base/common/actions'; import { isNative } from 'vs/base/common/platform'; @@ -37,8 +37,8 @@ export function openContextMenu(targetWindow: Window, event: MouseEvent, clipboa else { const clipboardText = await clipboardService.readText(); if ( - element instanceof HTMLTextAreaElement || - element instanceof HTMLInputElement + isHTMLTextAreaElement(element) || + isHTMLInputElement(element) ) { const selectionStart = element.selectionStart || 0; const selectionEnd = element.selectionEnd || 0; diff --git a/src/vs/workbench/contrib/welcomeWalkthrough/browser/walkThroughPart.ts b/src/vs/workbench/contrib/welcomeWalkthrough/browser/walkThroughPart.ts index dd11b080f6bc90..c2c1e099961e48 100644 --- a/src/vs/workbench/contrib/welcomeWalkthrough/browser/walkThroughPart.ts +++ b/src/vs/workbench/contrib/welcomeWalkthrough/browser/walkThroughPart.ts @@ -32,7 +32,7 @@ import { UILabelProvider } from 'vs/base/common/keybindingLabels'; import { OS, OperatingSystem } from 'vs/base/common/platform'; import { deepClone } from 'vs/base/common/objects'; import { INotificationService } from 'vs/platform/notification/common/notification'; -import { addDisposableListener, Dimension, safeInnerHtml, size } from 'vs/base/browser/dom'; +import { addDisposableListener, Dimension, isHTMLAnchorElement, isHTMLButtonElement, isHTMLElement, safeInnerHtml, size } from 'vs/base/browser/dom'; import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { CancellationToken } from 'vs/base/common/cancellation'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; @@ -142,12 +142,12 @@ export class WalkThroughPart extends EditorPane { })); this.disposables.add(this.addEventListener(this.content, 'focusin', (e: FocusEvent) => { // Work around scrolling as side-effect of setting focus on the offscreen zone widget (#18929) - if (e.target instanceof HTMLElement && e.target.classList.contains('zone-widget-container')) { + if (isHTMLElement(e.target) && e.target.classList.contains('zone-widget-container')) { const scrollPosition = this.scrollbar.getScrollPosition(); this.content.scrollTop = scrollPosition.scrollTop; this.content.scrollLeft = scrollPosition.scrollLeft; } - if (e.target instanceof HTMLElement) { + if (isHTMLElement(e.target)) { this.lastFocus = e.target; } })); @@ -156,7 +156,7 @@ export class WalkThroughPart extends EditorPane { private registerClickHandler() { this.content.addEventListener('click', event => { for (let node = event.target as HTMLElement; node; node = node.parentNode as HTMLElement) { - if (node instanceof HTMLAnchorElement && node.href) { + if (isHTMLAnchorElement(node) && node.href) { const baseElement = node.ownerDocument.getElementsByTagName('base')[0] || this.window.location; if (baseElement && node.href.indexOf(baseElement.href) >= 0 && node.hash) { const scrollTarget = this.content.querySelector(node.hash); @@ -171,7 +171,7 @@ export class WalkThroughPart extends EditorPane { } event.preventDefault(); break; - } else if (node instanceof HTMLButtonElement) { + } else if (isHTMLButtonElement(node)) { const href = node.getAttribute('data-href'); if (href) { this.open(URI.parse(href)); diff --git a/src/vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService.ts b/src/vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService.ts index e47c892301994b..5178f4c9457c2d 100644 --- a/src/vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService.ts +++ b/src/vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService.ts @@ -6,14 +6,14 @@ import { localize } from 'vs/nls'; import { mark } from 'vs/base/common/performance'; import { Emitter, Event } from 'vs/base/common/event'; -import { Dimension, EventHelper, EventType, ModifierKeyEmitter, addDisposableListener, cloneGlobalStylesheets, copyAttributes, createLinkElement, createMetaElement, getActiveWindow, getClientArea, getWindowId, isGlobalStylesheet, position, registerWindow, sharedMutationObserver, trackAttributes } from 'vs/base/browser/dom'; +import { Dimension, EventHelper, EventType, ModifierKeyEmitter, addDisposableListener, cloneGlobalStylesheets, copyAttributes, createLinkElement, createMetaElement, getActiveWindow, getClientArea, getWindowId, isGlobalStylesheet, isHTMLElement, position, registerWindow, sharedMutationObserver, trackAttributes } from 'vs/base/browser/dom'; import { CodeWindow, ensureCodeWindow, mainWindow } from 'vs/base/browser/window'; import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { onUnexpectedError } from 'vs/base/common/errors'; -import { isWeb } from 'vs/base/common/platform'; +import { isFirefox, isWeb } from 'vs/base/common/platform'; import { IRectangle, WindowMinimumSize } from 'vs/platform/window/common/window'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import Severity from 'vs/base/common/severity'; @@ -332,7 +332,7 @@ export class BrowserAuxiliaryWindowService extends Disposable implements IAuxili options?.mode === AuxiliaryWindowMode.Fullscreen ? 'window-fullscreen=yes' : undefined // non-standard property ]); - const auxiliaryWindow = mainWindow.open('about:blank', undefined, features.join(',')); + const auxiliaryWindow = mainWindow.open(isFirefox ? '' /* FF immediately fires an unload event if using about:blank */ : 'about:blank', undefined, features.join(',')); if (!auxiliaryWindow && isWeb) { return (await this.dialogService.prompt({ type: Severity.Warning, @@ -461,7 +461,7 @@ export class BrowserAuxiliaryWindowService extends Disposable implements IAuxili for (const node of mutation.addedNodes) { //