Bug 1515049 - Port paste-and-go implementation from urlbarBindings.xml to UrlbarInput. r=adw
authorDão Gottwald <dao@mozilla.com>
Sat, 19 Jan 2019 00:27:25 +0000
changeset 514481 edc9fc80bf25f7bfa6896db4274dfedf4e4bcc76
parent 514479 57dc8bbbc38f79ce532feb8947b40311e96ea577
child 514482 c31d2c5695b185f5dab74513f911388ddcb23a46
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersadw
bugs1515049
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1515049 - Port paste-and-go implementation from urlbarBindings.xml to UrlbarInput. r=adw Differential Revision: https://phabricator.services.mozilla.com/D16963
browser/components/urlbar/UrlbarInput.jsm
--- a/browser/components/urlbar/UrlbarInput.jsm
+++ b/browser/components/urlbar/UrlbarInput.jsm
@@ -52,16 +52,17 @@ class UrlbarInput {
       browserWindow: this.window,
     });
     this.controller.setInput(this);
     this.view = new UrlbarView(this);
     this.valueIsTyped = false;
     this.userInitiatedFocus = false;
     this.isPrivate = PrivateBrowsingUtils.isWindowPrivate(this.window);
     this._untrimmedValue = "";
+    this._suppressStartQuery = false;
 
     // Forward textbox methods and properties.
     const METHODS = ["addEventListener", "removeEventListener",
       "setAttribute", "hasAttribute", "removeAttribute", "getAttribute",
       "focus", "blur", "select"];
     const READ_ONLY_PROPERTIES = ["inputField", "editor"];
     const READ_WRITE_PROPERTIES = ["placeholder", "readOnly",
       "selectionStart", "selectionEnd"];
@@ -106,16 +107,17 @@ class UrlbarInput {
     this.inputField.addEventListener("underflow", this);
     this.inputField.addEventListener("scrollend", this);
     this.inputField.addEventListener("select", this);
     this.inputField.addEventListener("keydown", this);
     this.view.panel.addEventListener("popupshowing", this);
     this.view.panel.addEventListener("popuphidden", this);
 
     this.inputField.controllers.insertControllerAt(0, new CopyCutController(this));
+    this._initPasteAndGo();
   }
 
   /**
    * Shortens the given value, usually by removing http:// and trailing slashes,
    * such that calling nsIURIFixup::createFixupURI with the result will produce
    * the same URI.
    *
    * @param {string} val
@@ -370,16 +372,20 @@ class UrlbarInput {
    * Starts a query based on the user input.
    *
    * @param {number} [options.lastKey]
    *   The last key the user entered (as a key code).
    */
   startQuery({
     lastKey = null,
   } = {}) {
+    if (this._suppressStartQuery) {
+      return;
+    }
+
     this.controller.startQuery(new QueryContext({
       enableAutofill: UrlbarPrefs.get("autoFill"),
       isPrivate: this.isPrivate,
       lastKey,
       maxResults: UrlbarPrefs.get("maxRichResults"),
       muxer: "UnifiedComplete",
       providers: ["UnifiedComplete"],
       searchString: this.textValue,
@@ -691,16 +697,61 @@ class UrlbarInput {
     if (where == "tab" &&
         reuseEmpty &&
         this.window.gBrowser.selectedTab.isEmpty) {
       where = "current";
     }
     return where;
   }
 
+  _initPasteAndGo() {
+    let inputBox = this.document.getAnonymousElementByAttribute(
+                     this.textbox, "anonid", "moz-input-box");
+    // Force the Custom Element to upgrade until Bug 1470242 handles this:
+    this.window.customElements.upgrade(inputBox);
+    let contextMenu = inputBox.menupopup;
+    let insertLocation = contextMenu.firstElementChild;
+    while (insertLocation.nextElementSibling &&
+           insertLocation.getAttribute("cmd") != "cmd_paste") {
+      insertLocation = insertLocation.nextElementSibling;
+    }
+    if (!insertLocation) {
+      return;
+    }
+
+    let pasteAndGo = this.document.createXULElement("menuitem");
+    let label = Services.strings
+                        .createBundle("chrome://browser/locale/browser.properties")
+                        .GetStringFromName("pasteAndGo.label");
+    pasteAndGo.setAttribute("label", label);
+    pasteAndGo.setAttribute("anonid", "paste-and-go");
+    pasteAndGo.addEventListener("command", () => {
+      this._suppressStartQuery = true;
+
+      this.select();
+      this.window.goDoCommand("cmd_paste");
+      this.handleCommand();
+
+      this._suppressStartQuery = false;
+    });
+
+    contextMenu.addEventListener("popupshowing", () => {
+      let controller =
+        this.document.commandDispatcher.getControllerForCommand("cmd_paste");
+      let enabled = controller.isCommandEnabled("cmd_paste");
+      if (enabled) {
+        pasteAndGo.removeAttribute("disabled");
+      } else {
+        pasteAndGo.setAttribute("disabled", "true");
+      }
+    });
+
+    insertLocation.insertAdjacentElement("afterend", pasteAndGo);
+  }
+
   // Event handlers below.
 
   _on_blur(event) {
     this.formatValue();
   }
 
   _on_focus(event) {
     this._updateUrlTooltip();