tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SmartbarInputController.mjs (4073B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 /**
      6 * @import {MultilineEditor} from "chrome://browser/content/multilineeditor/multiline-editor.mjs"
      7 */
      8 
      9 /**
     10 * Controller for the Smartbar editor.
     11 *
     12 * The controller abstracts the underlying editor implementation allowing
     13 * the Smartbar to also work with a standard HTML input.
     14 */
     15 export class SmartbarInputController {
     16  /**
     17   * @param {object} adapter
     18   *   Adapter with input and editor references.
     19   *   @param {MultilineEditor | HTMLInputElement} adapter.input
     20   *     The input element.
     21   *   @param {object} adapter.editor
     22   *     The editor object.
     23   */
     24  constructor(adapter) {
     25    /** @type {MultilineEditor | HTMLInputElement} */
     26    this.input = adapter.input;
     27    /** @type {object} */
     28    this.editor = adapter.editor;
     29  }
     30 
     31  /**
     32   * Focuses the input element.
     33   */
     34  focus() {
     35    this.input.focus();
     36  }
     37 
     38  /**
     39   * Removes focus from the input element.
     40   */
     41  blur() {
     42    this.input.blur();
     43  }
     44 
     45  /**
     46   * Whether the input is read-only.
     47   *
     48   * @type {boolean}
     49   */
     50  get readOnly() {
     51    return this.input.readOnly;
     52  }
     53 
     54  set readOnly(val) {
     55    this.input.readOnly = val;
     56  }
     57 
     58  /**
     59   * The placeholder text for the input.
     60   *
     61   * @type {string}
     62   */
     63  get placeholder() {
     64    return this.input.placeholder ?? "";
     65  }
     66 
     67  set placeholder(val) {
     68    this.input.placeholder = val ?? "";
     69  }
     70 
     71  /**
     72   * The current value of the input.
     73   *
     74   * @type {string}
     75   */
     76  get value() {
     77    return this.input.value ?? "";
     78  }
     79 
     80  /**
     81   * Sets the value of the input.
     82   *
     83   * @param {string} val
     84   */
     85  setValue(val) {
     86    this.input.value = val ?? "";
     87  }
     88 
     89  /**
     90   * The start offset of the selection.
     91   *
     92   * @type {number}
     93   */
     94  get selectionStart() {
     95    return this.input.selectionStart ?? 0;
     96  }
     97 
     98  set selectionStart(val) {
     99    this.setSelectionRange(val, this.selectionEnd ?? val);
    100  }
    101 
    102  /**
    103   * The end offset of the selection.
    104   *
    105   * @type {number}
    106   */
    107  get selectionEnd() {
    108    return this.input.selectionEnd ?? 0;
    109  }
    110 
    111  set selectionEnd(val) {
    112    this.setSelectionRange(this.selectionStart ?? 0, val);
    113  }
    114 
    115  /**
    116   * Sets the selection range in the input.
    117   *
    118   * @param {number} start
    119   *   The start offset.
    120   * @param {number} end
    121   *   The end offset.
    122   */
    123  setSelectionRange(start, end) {
    124    if (!this.input.setSelectionRange) {
    125      return;
    126    }
    127    const from = Math.max(0, start ?? 0);
    128    const to = Math.max(from, end ?? from);
    129    this.input.setSelectionRange(from, to);
    130  }
    131 
    132  /**
    133   * Selects all text in the input.
    134   */
    135  select() {
    136    this.input.select?.();
    137  }
    138 
    139  /**
    140   * Dispatches an input event on the input element.
    141   *
    142   * @param {object} [options]
    143   *   The event options.
    144   * @param {string} [options.inputType="insertText"]
    145   *   The input type.
    146   * @param {string} [options.data=""]
    147   *   The data being inserted.
    148   */
    149  dispatchInput({ inputType = "insertText", data = "" } = {}) {
    150    this.input.dispatchEvent(
    151      new InputEvent("input", {
    152        bubbles: true,
    153        composed: true,
    154        inputType,
    155        data,
    156      })
    157    );
    158  }
    159 
    160  /**
    161   * Dispatches a selectionchange event on the input element.
    162   */
    163  dispatchSelectionChange() {
    164    this.input.dispatchEvent(
    165      new Event("selectionchange", { bubbles: true, composed: true })
    166    );
    167  }
    168 
    169  /**
    170   * Whether the editor is in composition mode.
    171   *
    172   * @type {boolean}
    173   */
    174  get composing() {
    175    return this.editor.composing ?? false;
    176  }
    177 
    178  /**
    179   * The number of selection ranges in the editor.
    180   *
    181   * @type {number}
    182   */
    183  get selectionRangeCount() {
    184    return this.editor.selection?.rangeCount ?? 0;
    185  }
    186 
    187  /**
    188   * Returns the string representation of the current selection with formatting.
    189   *
    190   * @returns {string}
    191   *   The formatted selection string.
    192   */
    193  selectionToStringWithFormat() {
    194    return this.editor.selection?.toStringWithFormat() ?? "";
    195  }
    196 }