tor-browser

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

text-editor.js (3325B)


      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 "use strict";
      6 
      7 const {
      8  createFactory,
      9 } = require("resource://devtools/client/shared/vendor/react.mjs");
     10 
     11 const TextNode = createFactory(
     12  require("resource://devtools/client/inspector/markup/components/TextNode.js")
     13 );
     14 
     15 loader.lazyRequireGetter(
     16  this,
     17  "getAutocompleteMaxWidth",
     18  "resource://devtools/client/inspector/markup/utils.js",
     19  true
     20 );
     21 loader.lazyRequireGetter(
     22  this,
     23  "getLongString",
     24  "resource://devtools/client/inspector/shared/utils.js",
     25  true
     26 );
     27 loader.lazyRequireGetter(
     28  this,
     29  "InplaceEditor",
     30  "resource://devtools/client/shared/inplace-editor.js",
     31  true
     32 );
     33 
     34 /**
     35 * Creates a simple text editor node, used for TEXT and COMMENT
     36 * nodes.
     37 */
     38 class TextEditor {
     39  /**
     40   * @param  {MarkupContainer} container
     41   *         The container owning this editor.
     42   * @param  {DOMNode} node
     43   *         The node being edited.
     44   * @param  {string} type
     45   *         The type of editor to build. This can be either 'text' or 'comment'.
     46   */
     47  constructor(container, node, type) {
     48    this.container = container;
     49    this.markup = this.container.markup;
     50    this.node = node;
     51    this._selected = false;
     52 
     53    this.showTextEditor = this.showTextEditor.bind(this);
     54 
     55    this.buildMarkup(type);
     56  }
     57  buildMarkup(type) {
     58    const doc = this.markup.doc;
     59 
     60    this.elt = doc.createElement("span");
     61    this.elt.classList.add("editor", type);
     62 
     63    getLongString(this.node.getNodeValue()).then(value => {
     64      this.textNode = this.ReactDOM.render(
     65        TextNode({
     66          showTextEditor: this.showTextEditor,
     67          type,
     68          value,
     69        }),
     70        this.elt
     71      );
     72    });
     73  }
     74 
     75  get ReactDOM() {
     76    // Reuse the toolbox's ReactDOM to avoid loading react-dom.js again in the
     77    // Inspector's BrowserLoader.
     78    return this.container.markup.inspector.ReactDOM;
     79  }
     80 
     81  get selected() {
     82    return this._selected;
     83  }
     84 
     85  set selected(value) {
     86    if (value === this._selected) {
     87      return;
     88    }
     89    this._selected = value;
     90    this.update();
     91  }
     92 
     93  showTextEditor(element) {
     94    new InplaceEditor({
     95      cssProperties: this.markup.inspector.cssProperties,
     96      done: (val, commit) => {
     97        if (!commit) {
     98          return;
     99        }
    100        getLongString(this.node.getNodeValue()).then(oldValue => {
    101          this.container.undo.do(
    102            () => {
    103              this.node.setNodeValue(val);
    104            },
    105            () => {
    106              this.node.setNodeValue(oldValue);
    107            }
    108          );
    109        });
    110      },
    111      element,
    112      maxWidth: () => getAutocompleteMaxWidth(element, this.container.elt),
    113      multiline: true,
    114      stopOnReturn: true,
    115      trimOutput: false,
    116    });
    117  }
    118 
    119  async update() {
    120    try {
    121      const value = await getLongString(this.node.getNodeValue());
    122 
    123      if (this.textNode.state.value !== value) {
    124        this.textNode.setState({ value });
    125      }
    126    } catch (e) {
    127      console.error(e);
    128    }
    129  }
    130 
    131  destroy() {
    132    this.ReactDOM.unmountComponentAtNode(this.elt);
    133  }
    134 
    135  /**
    136   * Stub method for consistency with ElementEditor.
    137   */
    138  getInfoAtNode() {
    139    return null;
    140  }
    141 }
    142 
    143 module.exports = TextEditor;