chromium/third_party/google-closure-library/closure/goog/editor/plugins/spacestabhandler.js

/**
 * @license
 * Copyright The Closure Library Authors.
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @fileoverview Editor plugin to handle tab keys not in lists to add 4 spaces.
 */

goog.provide('goog.editor.plugins.SpacesTabHandler');

goog.require('goog.dom.TagName');
goog.require('goog.editor.plugins.AbstractTabHandler');
goog.require('goog.editor.range');



/**
 * Plugin to handle tab keys when not in lists to add 4 spaces.
 * @constructor
 * @extends {goog.editor.plugins.AbstractTabHandler}
 * @final
 */
goog.editor.plugins.SpacesTabHandler = function() {
  'use strict';
  goog.editor.plugins.AbstractTabHandler.call(this);
};
goog.inherits(
    goog.editor.plugins.SpacesTabHandler,
    goog.editor.plugins.AbstractTabHandler);


/** @override */
goog.editor.plugins.SpacesTabHandler.prototype.getTrogClassId = function() {
  'use strict';
  return 'SpacesTabHandler';
};


/** @override */
goog.editor.plugins.SpacesTabHandler.prototype.handleTabKey = function(e) {
  'use strict';
  var dh = this.getFieldDomHelper();
  var range = this.getFieldObject().getRange();
  if (!goog.editor.range.intersectsTag(range, goog.dom.TagName.LI)) {
    // In the shift + tab case we don't want to insert spaces, but we don't
    // want focus to move either so skip the spacing logic and just prevent
    // default.
    if (!e.shiftKey) {
      // Not in a list but we want to insert 4 spaces.

      // Stop change events while we make multiple field changes.
      this.getFieldObject().stopChangeEvents(true, true);

      // Inserting nodes below completely messes up the selection, doing the
      // deletion here before it's messed up. Only delete if text is selected,
      // otherwise we would remove the character to the right of the cursor.
      if (!range.isCollapsed()) {
        dh.getDocument().execCommand('delete', false, null);
        // Safari 3 has some DOM exceptions if we don't reget the range here,
        // doing it all the time just to be safe.
        range = this.getFieldObject().getRange();
      }

      // Emulate tab by removing selection and inserting 4 spaces
      // Two breaking spaces in a row can be collapsed by the browser into one
      // space. Inserting the string below because it is guaranteed to never
      // collapse to less than four spaces, regardless of what is adjacent to
      // the inserted spaces. This might make line wrapping slightly
      // sub-optimal around a grouping of non-breaking spaces.
      var elem =
          dh.createDom(goog.dom.TagName.SPAN, null, '\u00a0\u00a0 \u00a0');
      elem = range.insertNode(elem, false);

      this.getFieldObject().dispatchChange();
      goog.editor.range.placeCursorNextTo(elem, false);
      this.getFieldObject().dispatchSelectionChangeEvent();
    }

    e.preventDefault();
    return true;
  }

  return false;
};