Bug 1491252 - Port URL overflow handling from urlbarBindings.xml to UrlbarInput.jsm. r=standard8
authorDão Gottwald <dao@mozilla.com>
Fri, 21 Sep 2018 19:12:05 +0200
changeset 437732 f138b7d87e7f728534d4cc416eb84a66fdddbd7a
parent 437731 56a2c01222f33df319fae273aca4921ee2d44d14
child 437733 1879856ca1ab0def40038be7482a9bc2e140cfee
push id34694
push userbtara@mozilla.com
push dateFri, 21 Sep 2018 21:59:56 +0000
treeherdermozilla-central@eddbfdc38cbc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersstandard8
bugs1491252
milestone64.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 1491252 - Port URL overflow handling from urlbarBindings.xml to UrlbarInput.jsm. r=standard8
browser/components/urlbar/UrlbarInput.jsm
browser/components/urlbar/tests/unit/test_UrlbarInput_unit.js
--- a/browser/components/urlbar/UrlbarInput.jsm
+++ b/browser/components/urlbar/UrlbarInput.jsm
@@ -29,21 +29,22 @@ class UrlbarInput {
    *   The <panel> element.
    * @param {UrlbarController} [options.controller]
    *   Optional fake controller to override the built-in UrlbarController.
    *   Intended for use in unit tests only.
    */
   constructor(options = {}) {
     this.textbox = options.textbox;
     this.panel = options.panel;
+    this.window = this.textbox.ownerGlobal;
     this.controller = options.controller || new UrlbarController();
     this.view = new UrlbarView(this);
     this.valueIsTyped = false;
     this.userInitiatedFocus = false;
-    this.isPrivate = PrivateBrowsingUtils.isWindowPrivate(this.panel.ownerGlobal);
+    this.isPrivate = PrivateBrowsingUtils.isWindowPrivate(this.window);
 
     const METHODS = ["addEventListener", "removeEventListener",
       "setAttribute", "hasAttribute", "removeAttribute", "getAttribute",
       "focus", "blur", "select"];
     const READ_ONLY_PROPERTIES = ["focused", "inputField", "editor"];
     const READ_WRITE_PROPERTIES = ["value", "placeholder", "readOnly",
       "selectionStart", "selectionEnd"];
 
@@ -70,16 +71,19 @@ class UrlbarInput {
         },
         set(val) {
           return this.textbox[property] = val;
         },
       });
     }
 
     this.addEventListener("input", this);
+    this.inputField.addEventListener("overflow", this);
+    this.inputField.addEventListener("underflow", this);
+    this.inputField.addEventListener("scrollend", this);
   }
 
   formatValue() {
   }
 
   closePopup() {
     this.view.close();
   }
@@ -99,18 +103,65 @@ class UrlbarInput {
       this[methodName](event);
     } else {
       throw "Unrecognized urlbar event: " + event.type;
     }
   }
 
   // Private methods below.
 
+  _updateTextOverflow() {
+    if (!this._inOverflow) {
+      this.removeAttribute("textoverflow");
+      return;
+    }
+
+    this.window.promiseDocumentFlushed(() => {
+      // Check overflow again to ensure it didn't change in the meantime.
+      let input = this.inputField;
+      if (input && this._inOverflow) {
+        let side = input.scrollLeft &&
+                   input.scrollLeft == input.scrollLeftMax ? "start" : "end";
+        this.setAttribute("textoverflow", side);
+      }
+    });
+  }
+
+  // Event handlers below.
+
   _oninput(event) {
     // XXX Fill in lastKey & maxResults, and add anything else we need.
     this.controller.handleQuery(new QueryContext({
       searchString: event.target.value,
       lastKey: "",
       maxResults: 12,
       isPrivate: this.isPrivate,
     }));
   }
+
+  _onoverflow(event) {
+    const targetIsPlaceholder =
+      !event.originalTarget.classList.contains("anonymous-div");
+    // We only care about the non-placeholder text.
+    // This shouldn't be needed, see bug 1487036.
+    if (targetIsPlaceholder) {
+      return;
+    }
+    this._inOverflow = true;
+    this._updateTextOverflow();
+  }
+
+  _onunderflow(event) {
+    const targetIsPlaceholder =
+      !event.originalTarget.classList.contains("anonymous-div");
+    // We only care about the non-placeholder text.
+    // This shouldn't be needed, see bug 1487036.
+    if (targetIsPlaceholder) {
+      return;
+    }
+    this._inOverflow = false;
+    this._updateTextOverflow();
+  }
+
+  _onscrollend(event) {
+    this._updateTextOverflow();
+  }
 }
--- a/browser/components/urlbar/tests/unit/test_UrlbarInput_unit.js
+++ b/browser/components/urlbar/tests/unit/test_UrlbarInput_unit.js
@@ -71,18 +71,20 @@ function checkHandleQueryCall(stub, expe
 add_task(function setup() {
   sandbox = sinon.sandbox.create();
 
   fakeController = new UrlbarController();
 
   sandbox.stub(fakeController, "handleQuery");
   sandbox.stub(PrivateBrowsingUtils, "isWindowPrivate").returns(false);
 
+  let textbox = createFakeElement();
+  textbox.inputField = createFakeElement();
   inputOptions = {
-    textbox: createFakeElement(),
+    textbox,
     panel: {
       ownerDocument: {},
       querySelector() {
         return createFakeElement();
       },
     },
     controller: fakeController,
   };