public open()

in src/Terminal.ts [627:753]


  public open(parent: HTMLElement): void {
    this._parent = parent || this._parent;

    if (!this._parent) {
      throw new Error('Terminal requires a parent element.');
    }

    // Grab global elements
    this._context = this._parent.ownerDocument.defaultView;
    this._document = this._parent.ownerDocument;

    this._screenDprMonitor = new ScreenDprMonitor();
    this._screenDprMonitor.setListener(() => this.emit('dprchange', window.devicePixelRatio));
    this.register(this._screenDprMonitor);

    // Create main element container
    this.element = this._document.createElement('div');
    this.element.dir = 'ltr';   // xterm.css assumes LTR
    this.element.classList.add('terminal');
    this.element.classList.add('xterm');
    this.element.setAttribute('tabindex', '0');
    this._parent.appendChild(this.element);

    // 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');
    this._viewportElement.classList.add('xterm-viewport');
    fragment.appendChild(this._viewportElement);
    this._viewportScrollArea = document.createElement('div');
    this._viewportScrollArea.classList.add('xterm-scroll-area');
    this._viewportElement.appendChild(this._viewportScrollArea);

    this.screenElement = 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.classList.add('xterm-helpers');
    this.screenElement.appendChild(this._helperContainer);
    fragment.appendChild(this.screenElement);

    this._mouseZoneManager = new MouseZoneManager(this);
    this.register(this._mouseZoneManager);
    this.register(this.addDisposableListener('scroll', () => this._mouseZoneManager.clearAll()));
    this.linkifier.attachToDom(this._mouseZoneManager);

    this.textarea = document.createElement('textarea');
    this.textarea.classList.add('xterm-helper-textarea');
    // TODO: New API to set title? This could say "Terminal bash input", etc.
    this.textarea.setAttribute('aria-label', Strings.promptLabel);
    this.textarea.setAttribute('aria-multiline', 'false');
    this.textarea.setAttribute('autocorrect', 'off');
    this.textarea.setAttribute('autocapitalize', 'off');
    this.textarea.setAttribute('spellcheck', 'false');
    this.textarea.tabIndex = 0;
    this.register(addDisposableDomListener(this.textarea, 'focus', (ev: KeyboardEvent) => this._onTextAreaFocus(ev)));
    this.register(addDisposableDomListener(this.textarea, 'blur', () => this._onTextAreaBlur()));
    this._helperContainer.appendChild(this.textarea);

    this._compositionView = document.createElement('div');
    this._compositionView.classList.add('composition-view');
    this._compositionHelper = new CompositionHelper(this.textarea, this._compositionView, this);
    this._helperContainer.appendChild(this._compositionView);

    this.charMeasure = new CharMeasure(document, this._helperContainer);

    // Performance: Add viewport and helper elements from the fragment
    this.element.appendChild(fragment);

    this._setupRenderer();
    this._theme = this.options.theme;
    this.options.theme = null;
    this.viewport = new Viewport(this, this._viewportElement, this._viewportScrollArea, this.charMeasure);
    this.viewport.onThemeChanged(this.renderer.colorManager.colors);
    this.register(this.viewport);

    this.register(this.addDisposableListener('cursormove', () => this.renderer.onCursorMove()));
    this.register(this.addDisposableListener('resize', () => this.renderer.onResize(this.cols, this.rows)));
    this.register(this.addDisposableListener('blur', () => this.renderer.onBlur()));
    this.register(this.addDisposableListener('focus', () => this.renderer.onFocus()));
    this.register(this.addDisposableListener('dprchange', () => this.renderer.onWindowResize(window.devicePixelRatio)));
    // dprchange should handle this case, we need this as well for browsers that don't support the
    // matchMedia query.
    this.register(addDisposableDomListener(window, 'resize', () => this.renderer.onWindowResize(window.devicePixelRatio)));
    this.register(this.charMeasure.addDisposableListener('charsizechanged', () => this.renderer.onCharSizeChanged()));
    this.register(this.renderer.addDisposableListener('resize', (dimensions) => this.viewport.syncScrollArea()));

    this.selectionManager = new SelectionManager(this, this.charMeasure);
    this.register(addDisposableDomListener(this.element, 'mousedown', (e: MouseEvent) => this.selectionManager.onMouseDown(e)));
    this.register(this.selectionManager.addDisposableListener('refresh', data => this.renderer.onSelectionChanged(data.start, data.end, data.columnSelectMode)));
    this.register(this.selectionManager.addDisposableListener('newselection', text => {
      // If there's a new selection, put it into the textarea, focus and select it
      // in order to register it as a selection on the OS. This event is fired
      // only on Linux to enable middle click to paste selection.
      this.textarea.value = text;
      this.textarea.focus();
      this.textarea.select();
    }));
    this.register(this.addDisposableListener('scroll', () => {
      this.viewport.syncScrollArea();
      this.selectionManager.refresh();
    }));
    this.register(addDisposableDomListener(this._viewportElement, 'scroll', () => this.selectionManager.refresh()));

    this.mouseHelper = new MouseHelper(this.renderer);

    if (this.options.screenReaderMode) {
      // Note that this must be done *after* the renderer is created in order to
      // ensure the correct order of the dprchange event
      this._accessibilityManager = new AccessibilityManager(this);
    }

    // Measure the character size
    this.charMeasure.measure(this.options);

    // Setup loop that draws to screen
    this.refresh(0, this.rows - 1);

    // Initialize global actions that need to be taken on the document.
    this._initGlobal();

    // Listen for mouse events and translate
    // them into terminal mouse protocols.
    this.bindMouse();

  }