/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
// This is loaded into chrome windows with the subscript loader. Wrap in
// a block to prevent accidentally leaking globals onto `window`.
{
const cachedFragments = {
  get entities() {
    return [
      "chrome://global/locale/textcontext.dtd",
    ];
  },
  get editMenuItems() {
    return `
      
      
      
      
      
      
      
      
    `;
  },
  get normal() {
    delete this.normal;
    this.normal = MozXULElement.parseXULToFragment(`
      
    `, this.entities);
    return this.normal;
  },
  get spellcheck() {
    delete this.spellcheck;
    this.spellcheck = MozXULElement.parseXULToFragment(`
      
    `, this.entities);
    return this.spellcheck;
  },
};
class MozInputBox extends MozXULElement {
  static get observedAttributes() {
    return ["spellcheck"];
  }
  attributeChangedCallback(name, oldValue, newValue) {
    if (name === "spellcheck" && oldValue != newValue) {
      this._initUI();
    }
  }
  connectedCallback() {
    this._initUI();
  }
  _initUI() {
    this.spellcheck = this.hasAttribute("spellcheck");
    if (this.menupopup) {
      this.menupopup.remove();
    }
    this.setAttribute("context", "_child");
    this.appendChild(this.spellcheck ? cachedFragments.spellcheck.cloneNode(true) :
                                       cachedFragments.normal.cloneNode(true));
    this.menupopup = this.querySelector(".textbox-contextmenu");
    this.menupopup.addEventListener("popupshowing", event => {
      var input = this.getElementsByAttribute("anonid", "input")[0];
      if (document.commandDispatcher.focusedElement != input)
        input.focus();
      this._doPopupItemEnabling(event.target);
    });
    if (this.spellcheck) {
      this.menupopup.addEventListener("popuphiding", event => {
        if (this.spellCheckerUI) {
          this.spellCheckerUI.clearSuggestionsFromMenu();
          this.spellCheckerUI.clearDictionaryListFromMenu();
        }
      });
    }
    this.menupopup.addEventListener("command", event => {
      var cmd = event.originalTarget.getAttribute("cmd");
      if (cmd) {
        this.doCommand(cmd);
        event.stopPropagation();
      }
    });
  }
  _doPopupItemEnablingSpell(popupNode) {
    var spellui = this.spellCheckerUI;
    if (!spellui || !spellui.canSpellCheck) {
      this._setMenuItemVisibility("spell-no-suggestions", false);
      this._setMenuItemVisibility("spell-check-enabled", false);
      this._setMenuItemVisibility("spell-check-separator", false);
      this._setMenuItemVisibility("spell-add-to-dictionary", false);
      this._setMenuItemVisibility("spell-undo-add-to-dictionary", false);
      this._setMenuItemVisibility("spell-suggestions-separator", false);
      this._setMenuItemVisibility("spell-dictionaries", false);
      return;
    }
    spellui.initFromEvent(document.popupRangeParent,
      document.popupRangeOffset);
    var enabled = spellui.enabled;
    var showUndo = spellui.canSpellCheck && spellui.canUndo();
    var enabledCheckbox = this.getMenuItem("spell-check-enabled");
    enabledCheckbox.setAttribute("checked", enabled);
    var overMisspelling = spellui.overMisspelling;
    this._setMenuItemVisibility("spell-add-to-dictionary", overMisspelling);
    this._setMenuItemVisibility("spell-undo-add-to-dictionary", showUndo);
    this._setMenuItemVisibility("spell-suggestions-separator", overMisspelling || showUndo);
    // suggestion list
    var suggestionsSeparator = this.getMenuItem("spell-no-suggestions");
    var numsug = spellui.addSuggestionsToMenu(popupNode, suggestionsSeparator, 5);
    this._setMenuItemVisibility("spell-no-suggestions", overMisspelling && numsug == 0);
    // dictionary list
    var dictionariesMenu = this.getMenuItem("spell-dictionaries-menu");
    var numdicts = spellui.addDictionaryListToMenu(dictionariesMenu, null);
    this._setMenuItemVisibility("spell-dictionaries", enabled && numdicts > 1);
  }
  _doPopupItemEnabling(popupNode) {
    if (this.spellcheck) {
      this._doPopupItemEnablingSpell(popupNode);
    }
    var children = popupNode.childNodes;
    for (var i = 0; i < children.length; i++) {
      var command = children[i].getAttribute("cmd");
      if (command) {
        var controller = document.commandDispatcher.getControllerForCommand(command);
        var enabled = controller.isCommandEnabled(command);
        if (enabled)
          children[i].removeAttribute("disabled");
        else
          children[i].setAttribute("disabled", "true");
      }
    }
  }
  get spellCheckerUI() {
    if (!this._spellCheckInitialized) {
      this._spellCheckInitialized = true;
      if (ChromeUtils.getClassName(document) != "XULDocument")
        return null;
      var textbox = document.getBindingParent(this);
      if (!textbox || textbox.localName != "textbox")
        return null;
      try {
        ChromeUtils.import("resource://gre/modules/InlineSpellChecker.jsm", this);
        this.InlineSpellCheckerUI = new this.InlineSpellChecker(textbox.editor);
      } catch (ex) {}
    }
    return this.InlineSpellCheckerUI;
  }
  getMenuItem(anonid) {
    return this.querySelector(`[anonid="${anonid}"]`);
  }
  _setMenuItemVisibility(anonid, visible) {
    this.getMenuItem(anonid).hidden = !visible;
  }
  doCommand(command) {
    var controller = document.commandDispatcher.getControllerForCommand(command);
    controller.doCommand(command);
  }
}
customElements.define("moz-input-box", MozInputBox);
}