Use correct document when creating elements

This commit is contained in:
Daniel Imms
2023-10-16 11:09:36 -07:00
parent 4245283e05
commit c80453f602
12 changed files with 40 additions and 28 deletions
@@ -59,7 +59,7 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer
) {
super();
this._cellColorResolver = new CellColorResolver(this._terminal, this._selectionModel, this._decorationService, this._coreBrowserService, this._themeService);
this._canvas = document.createElement('canvas');
this._canvas = this._coreBrowserService.mainDocument.createElement('canvas');
this._canvas.classList.add(`xterm-${id}-layer`);
this._canvas.style.zIndex = zIndex.toString();
this._initCanvas();
@@ -88,7 +88,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
this._updateCursorBlink();
this.register(_optionsService.onOptionChange(() => this._handleOptionsChanged()));
this._canvas = document.createElement('canvas');
this._canvas = this._coreBrowserService.mainDocument.createElement('canvas');
const contextAttributes = {
antialias: false,
@@ -38,7 +38,7 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer
protected readonly _themeService: IThemeService
) {
super();
this._canvas = document.createElement('canvas');
this._canvas = this._coreBrowserService.mainDocument.createElement('canvas');
this._canvas.classList.add(`xterm-${id}-layer`);
this._canvas.style.zIndex = zIndex.toString();
this._initCanvas();
+6 -5
View File
@@ -8,7 +8,7 @@ import { ITerminal, IRenderDebouncer } from 'browser/Types';
import { TimeBasedDebouncer } from 'browser/TimeBasedDebouncer';
import { Disposable, toDisposable } from 'common/Lifecycle';
import { ScreenDprMonitor } from 'browser/ScreenDprMonitor';
import { IRenderService } from 'browser/services/Services';
import { ICoreBrowserService, IRenderService } from 'browser/services/Services';
import { addDisposableDomListener } from 'browser/Lifecycle';
import { IBuffer } from 'common/buffer/Types';
@@ -49,13 +49,14 @@ export class AccessibilityManager extends Disposable {
constructor(
private readonly _terminal: ITerminal,
@ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,
@IRenderService private readonly _renderService: IRenderService
) {
super();
this._accessibilityContainer = document.createElement('div');
this._accessibilityContainer = this._coreBrowserService.mainDocument.createElement('div');
this._accessibilityContainer.classList.add('xterm-accessibility');
this._rowContainer = document.createElement('div');
this._rowContainer = this._coreBrowserService.mainDocument.createElement('div');
this._rowContainer.setAttribute('role', 'list');
this._rowContainer.classList.add('xterm-accessibility-tree');
this._rowElements = [];
@@ -72,7 +73,7 @@ export class AccessibilityManager extends Disposable {
this._refreshRowsDimensions();
this._accessibilityContainer.appendChild(this._rowContainer);
this._liveRegion = document.createElement('div');
this._liveRegion = this._coreBrowserService.mainDocument.createElement('div');
this._liveRegion.classList.add('live-region');
this._liveRegion.setAttribute('aria-live', 'assertive');
this._accessibilityContainer.appendChild(this._liveRegion);
@@ -261,7 +262,7 @@ export class AccessibilityManager extends Disposable {
}
private _createAccessibilityTreeNode(): HTMLElement {
const element = document.createElement('div');
const element = this._coreBrowserService.mainDocument.createElement('div');
element.setAttribute('role', 'listitem');
element.tabIndex = -1;
this._refreshRowDimensions(element);
+8 -8
View File
@@ -411,25 +411,25 @@ export class Terminal extends CoreTerminal implements ITerminal {
// Performance: Use a document fragment to build the terminal
// viewport and helper elements detached from the DOM
const fragment = document.createDocumentFragment();
this._viewportElement = document.createElement('div');
const fragment = this._document.createDocumentFragment();
this._viewportElement = this._document.createElement('div');
this._viewportElement.classList.add('xterm-viewport');
fragment.appendChild(this._viewportElement);
this._viewportScrollArea = document.createElement('div');
this._viewportScrollArea = this._document.createElement('div');
this._viewportScrollArea.classList.add('xterm-scroll-area');
this._viewportElement.appendChild(this._viewportScrollArea);
this.screenElement = document.createElement('div');
this.screenElement = this._document.createElement('div');
this.screenElement.classList.add('xterm-screen');
// Create the container that will hold helpers like the textarea for
// capturing DOM Events. Then produce the helpers.
this._helperContainer = document.createElement('div');
this._helperContainer = this._document.createElement('div');
this._helperContainer.classList.add('xterm-helpers');
this.screenElement.appendChild(this._helperContainer);
fragment.appendChild(this.screenElement);
this.textarea = document.createElement('textarea');
this.textarea = this._document.createElement('textarea');
this.textarea.classList.add('xterm-helper-textarea');
this.textarea.setAttribute('aria-label', Strings.promptLabel);
if (!Browser.isChromeOS) {
@@ -444,7 +444,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
// Register the core browser service before the generic textarea handlers are registered so it
// handles them first. Otherwise the renderers may use the wrong focus state.
this._coreBrowserService = this._instantiationService.createInstance(CoreBrowserService, this.textarea, this._document.defaultView ?? window);
this._coreBrowserService = this._instantiationService.createInstance(CoreBrowserService, this.textarea, parent.ownerDocument.defaultView ?? window, this._document ?? window.document);
this._instantiationService.setService(ICoreBrowserService, this._coreBrowserService);
this.register(addDisposableDomListener(this.textarea, 'focus', (ev: KeyboardEvent) => this._handleTextAreaFocus(ev)));
@@ -466,7 +466,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
this.register(this._renderService.onRenderedViewportChange(e => this._onRender.fire(e)));
this.onResize(e => this._renderService!.resize(e.cols, e.rows));
this._compositionView = document.createElement('div');
this._compositionView = this._document.createElement('div');
this._compositionView.classList.add('composition-view');
this._compositionHelper = this._instantiationService.createInstance(CompositionHelper, this.textarea, this._compositionView);
this._helperContainer.appendChild(this._compositionView);
+3
View File
@@ -355,6 +355,9 @@ export class MockCoreBrowserService implements ICoreBrowserService {
public get window(): Window & typeof globalThis {
throw Error('Window object not available in tests');
}
public get mainDocument(): Document {
throw Error('Document object not available in tests');
}
public dpr: number = 1;
}
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { addDisposableDomListener } from 'browser/Lifecycle';
import { IRenderService } from 'browser/services/Services';
import { ICoreBrowserService, IRenderService } from 'browser/services/Services';
import { Disposable, toDisposable } from 'common/Lifecycle';
import { IBufferService, IDecorationService, IInternalDecoration } from 'common/services/Services';
@@ -19,6 +19,7 @@ export class BufferDecorationRenderer extends Disposable {
constructor(
private readonly _screenElement: HTMLElement,
@IBufferService private readonly _bufferService: IBufferService,
@ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,
@IDecorationService private readonly _decorationService: IDecorationService,
@IRenderService private readonly _renderService: IRenderService
) {
@@ -70,7 +71,7 @@ export class BufferDecorationRenderer extends Disposable {
}
private _createElement(decoration: IInternalDecoration): HTMLElement {
const element = document.createElement('div');
const element = this._coreBrowserService.mainDocument.createElement('div');
element.classList.add('xterm-decoration');
element.classList.toggle('xterm-decoration-top-layer', decoration?.options?.layer === 'top');
element.style.width = `${Math.round((decoration.options.width || 1) * this._renderService.dimensions.css.cell.width)}px`;
@@ -52,10 +52,10 @@ export class OverviewRulerRenderer extends Disposable {
@IDecorationService private readonly _decorationService: IDecorationService,
@IRenderService private readonly _renderService: IRenderService,
@IOptionsService private readonly _optionsService: IOptionsService,
@ICoreBrowserService private readonly _coreBrowseService: ICoreBrowserService
@ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService
) {
super();
this._canvas = document.createElement('canvas');
this._canvas = this._coreBrowserService.mainDocument.createElement('canvas');
this._canvas.classList.add('xterm-decoration-overview-ruler');
this._refreshCanvasDimensions();
this._viewportElement.parentElement?.insertBefore(this._canvas, this._viewportElement);
@@ -112,7 +112,7 @@ export class OverviewRulerRenderer extends Disposable {
// overview ruler width changed
this.register(this._optionsService.onSpecificOptionChange('overviewRulerWidth', () => this._queueRefresh(true)));
// device pixel ratio changed
this.register(addDisposableDomListener(this._coreBrowseService.window, 'resize', () => this._queueRefresh(true)));
this.register(addDisposableDomListener(this._coreBrowserService.window, 'resize', () => this._queueRefresh(true)));
// set the canvas dimensions
this._queueRefresh(true);
}
@@ -135,11 +135,11 @@ export class OverviewRulerRenderer extends Disposable {
}
private _refreshDrawHeightConstants(): void {
drawHeight.full = Math.round(2 * this._coreBrowseService.dpr);
drawHeight.full = Math.round(2 * this._coreBrowserService.dpr);
// Calculate actual pixels per line
const pixelsPerLine = this._canvas.height / this._bufferService.buffer.lines.length;
// Clamp actual pixels within a range
const nonFullHeight = Math.round(Math.max(Math.min(pixelsPerLine, 12), 6) * this._coreBrowseService.dpr);
const nonFullHeight = Math.round(Math.max(Math.min(pixelsPerLine, 12), 6) * this._coreBrowserService.dpr);
drawHeight.left = nonFullHeight;
drawHeight.center = nonFullHeight;
drawHeight.right = nonFullHeight;
@@ -157,9 +157,9 @@ export class OverviewRulerRenderer extends Disposable {
private _refreshCanvasDimensions(): void {
this._canvas.style.width = `${this._width}px`;
this._canvas.width = Math.round(this._width * this._coreBrowseService.dpr);
this._canvas.width = Math.round(this._width * this._coreBrowserService.dpr);
this._canvas.style.height = `${this._screenElement.clientHeight}px`;
this._canvas.height = Math.round(this._screenElement.clientHeight * this._coreBrowseService.dpr);
this._canvas.height = Math.round(this._screenElement.clientHeight * this._coreBrowserService.dpr);
this._refreshDrawConstants();
this._refreshColorZonePadding();
}
@@ -211,7 +211,7 @@ export class OverviewRulerRenderer extends Disposable {
if (this._animationFrame !== undefined) {
return;
}
this._animationFrame = this._coreBrowseService.window.requestAnimationFrame(() => {
this._animationFrame = this._coreBrowserService.window.requestAnimationFrame(() => {
this._refreshDecorations();
this._animationFrame = undefined;
});
+1 -1
View File
@@ -474,7 +474,7 @@ function drawPatternChar(
if (!pattern) {
const width = charDefinition[0].length;
const height = charDefinition.length;
const tmpCanvas = document.createElement('canvas');
const tmpCanvas = ctx.canvas.ownerDocument.createElement('canvas');
tmpCanvas.width = width;
tmpCanvas.height = height;
const tmpCtx = throwIfFalsy(tmpCanvas.getContext('2d'));
+2 -1
View File
@@ -13,7 +13,8 @@ export class CoreBrowserService implements ICoreBrowserService {
constructor(
private _textarea: HTMLTextAreaElement,
public readonly window: Window & typeof globalThis
public readonly window: Window & typeof globalThis,
public readonly mainDocument: Document
) {
this._textarea.addEventListener('focus', () => this._isFocused = true);
this._textarea.addEventListener('blur', () => this._isFocused = false);
+5
View File
@@ -34,6 +34,11 @@ export interface ICoreBrowserService {
* window.
*/
readonly window: Window & typeof globalThis;
/**
* The document of the primary window if working with multiple windows. This
* is set by the documentOverride setting.
*/
readonly mainDocument: Document;
/**
* Helper for getting the devicePixelRatio of the parent window.
*/
+1
View File
@@ -113,6 +113,7 @@ export namespace css {
let $ctx: CanvasRenderingContext2D | undefined;
let $litmusColor: CanvasGradient | undefined;
if (!isNode) {
// This is guaranteed to run in the first window, so document should be correct
const canvas = document.createElement('canvas');
canvas.width = 1;
canvas.height = 1;