Xterm.js: Consider adding a component API

Created on 21 Jul 2017  路  5Comments  路  Source: xtermjs/xterm.js

Initially discussed in https://github.com/sourcelair/xterm.js/issues/807#issuecomment-316803292

This would involve adding some interface like this that would make implementing addons much easier:

interface IComponent {
  onRefresh(rows: CircularList, startIndex: number, endIndex: number): void
  onDraw(group: RenderGroup, element: HTMLElement): void
  onMousedown(evt: MouseEvent): void
  onMouseup(evt: MouseEvent): void
  onInput(evt: KeyboardEvent): void
  onFocus(): void
  onBlur(): void
  onScroll(): void
  onOpen(term: ITerminal): void
  onResize(rows: number, cols: number)
  // ...
}

Candidates for turning into components:

  • CompositionHelper
  • SelectionManager
  • Search
  • Linkifier

/cc @mofux

typproposal

Most helpful comment

The internal IRenderLayer interface is pretty close to what I imagine the component API to look like:

export interface IRenderLayer {
  /**
   * Called when the terminal loses focus.
   */
  onBlur(terminal: ITerminal): void;

  /**
   * * Called when the terminal gets focus.
   */
  onFocus(terminal: ITerminal): void;

  /**
   * Called when the cursor is moved.
   */
  onCursorMove(terminal: ITerminal): void;

  /**
   * Called when options change.
   */
  onOptionsChanged(terminal: ITerminal): void;

  /**
   * Called when the theme changes.
   */
  onThemeChanged(terminal: ITerminal, colorSet: IColorSet): void;

  /**
   * Called when the data in the grid has changed (or needs to be rendered
   * again).
   */
  onGridChanged(terminal: ITerminal, startRow: number, endRow: number): void;

  /**
   * Calls when the selection changes.
   */
  onSelectionChanged(terminal: ITerminal, start: [number, number], end: [number, number]): void;

  /**
   * Resize the render layer.
   */
  resize(terminal: ITerminal, dim: IRenderDimensions, charSizeChanged: boolean): void;

  /**
   * Clear the state of the render layer.
   */
  reset(terminal: ITerminal): void;
}

Plus exposing the convenience methods on BaseRenderLayer to allow the easy creation of custom canvases

All 5 comments

The internal IRenderLayer interface is pretty close to what I imagine the component API to look like:

export interface IRenderLayer {
  /**
   * Called when the terminal loses focus.
   */
  onBlur(terminal: ITerminal): void;

  /**
   * * Called when the terminal gets focus.
   */
  onFocus(terminal: ITerminal): void;

  /**
   * Called when the cursor is moved.
   */
  onCursorMove(terminal: ITerminal): void;

  /**
   * Called when options change.
   */
  onOptionsChanged(terminal: ITerminal): void;

  /**
   * Called when the theme changes.
   */
  onThemeChanged(terminal: ITerminal, colorSet: IColorSet): void;

  /**
   * Called when the data in the grid has changed (or needs to be rendered
   * again).
   */
  onGridChanged(terminal: ITerminal, startRow: number, endRow: number): void;

  /**
   * Calls when the selection changes.
   */
  onSelectionChanged(terminal: ITerminal, start: [number, number], end: [number, number]): void;

  /**
   * Resize the render layer.
   */
  resize(terminal: ITerminal, dim: IRenderDimensions, charSizeChanged: boolean): void;

  /**
   * Clear the state of the render layer.
   */
  reset(terminal: ITerminal): void;
}

Plus exposing the convenience methods on BaseRenderLayer to allow the easy creation of custom canvases

Looks neat.

Called when the data in the grid has changed (or needs to be rendered again).

Would it make sense to separate grind changing and the need for re-rendering, or are they the same thing?

RIght now they're the same thing, need to re-render is only fired on an animation frame. If we enabled third party addons we may need to reconsider.

Hi!
I'd have to say that I do like the direction where this is going as 1) Having a well-defined interface for internal and external components is a really good idea. 2) Specifically, I think I'm interested in adding a new render layer as well.

(Time and effort permitting) It might be wise to begin refactoring internal objects to follow a similar model so that more of XT is composable. While I admit it might mean a bit of a re-arch if you're already planning on making changes soon, doing this now might pay down a lot of technical (architectural) debt.

Closing in favor of https://github.com/xtermjs/xterm.js/issues/1128#issuecomment-394142177 which is the first step

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Tyriar picture Tyriar  路  4Comments

travisobregon picture travisobregon  路  3Comments

Tyriar picture Tyriar  路  4Comments

kolbe picture kolbe  路  3Comments

Mlocik97-issues picture Mlocik97-issues  路  3Comments