Bug 1540861 - Limit the length of titles and URLs we display so layout doesn't spend too much time building text runs. r=dao
authorMarco Bonardo <mbonardo@mozilla.com>
Wed, 10 Apr 2019 18:53:13 +0000
changeset 468879 e46daa136cf014180d3414d149d4cf67f1dc8ff1
parent 468878 9f42988f15dfbfd0ea802c58455156bcc4e70a9e
child 468880 3a8da7745d0072c09f9d19be8cf27e75f6f4440e
push id82830
push usermak77@bonardo.net
push dateWed, 10 Apr 2019 22:08:16 +0000
treeherderautoland@e46daa136cf0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdao
bugs1540861
milestone68.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 1540861 - Limit the length of titles and URLs we display so layout doesn't spend too much time building text runs. r=dao Differential Revision: https://phabricator.services.mozilla.com/D26709
browser/components/urlbar/UrlbarResult.jsm
browser/components/urlbar/UrlbarUtils.jsm
browser/components/urlbar/tests/browser/browser.ini
browser/components/urlbar/tests/browser/browser_UrlbarInput_tooltip.js
browser/components/urlbar/tests/browser/browser_textruns.js
browser/components/urlbar/tests/legacy/browser.ini
--- a/browser/components/urlbar/UrlbarResult.jsm
+++ b/browser/components/urlbar/UrlbarResult.jsm
@@ -172,16 +172,24 @@ class UrlbarResult {
       payloadInfo.displayUrl = [...payloadInfo.url];
       let url = payloadInfo.displayUrl[0];
       if (UrlbarPrefs.get("trimURLs")) {
         url = BrowserUtils.trimURL(url || "");
       }
       payloadInfo.displayUrl[0] = Services.textToSubURI.unEscapeURIForUI("UTF-8", url);
     }
 
+    // For performance reasons limit excessive string lengths, to reduce the
+    // amount of string matching we do here, and avoid wasting resources to
+    // handle long textruns that the user would never see anyway.
+    for (let prop of ["displayUrl", "title"].filter(p => p in payloadInfo)) {
+      payloadInfo[prop][0] =
+        payloadInfo[prop][0].substring(0, UrlbarUtils.MAX_TEXT_LENGTH);
+    }
+
     let entries = Object.entries(payloadInfo);
     return [
       entries.reduce((payload, [name, [val, _]]) => {
         payload[name] = val;
         return payload;
       }, {}),
       entries.reduce((highlights, [name, [val, shouldHighlight]]) => {
         if (shouldHighlight) {
--- a/browser/components/urlbar/UrlbarUtils.jsm
+++ b/browser/components/urlbar/UrlbarUtils.jsm
@@ -122,16 +122,20 @@ var UrlbarUtils = {
   },
 
   // This defines possible reasons for canceling a query.
   CANCEL_REASON: {
     // 1 is intentionally left in case we want a none/undefined/other later.
     BLUR: 2,
   },
 
+  // Limit the length of titles and URLs we display so layout doesn't spend too
+  // much time building text runs.
+  MAX_TEXT_LENGTH: 255,
+
   /**
    * Adds a url to history as long as it isn't in a private browsing window,
    * and it is valid.
    *
    * @param {string} url The url to add to history.
    * @param {nsIDomWindow} window The window from where the url is being added.
    */
   addToUrlbarHistory(url, window) {
--- a/browser/components/urlbar/tests/browser/browser.ini
+++ b/browser/components/urlbar/tests/browser/browser.ini
@@ -79,16 +79,17 @@ skip-if = ((os == 'win') && verify && de
 [browser_switchToTab_closes_newtab.js]
 [browser_switchToTab_fullUrl_repeatedKeydown.js]
 [browser_switchToTabHavingURI_aOpenParams.js]
 [browser_tabMatchesInAwesomebar_perwindowpb.js]
 skip-if = os == 'linux' # Bug 1104755 (Intermittent failure)
 [browser_tabMatchesInAwesomebar.js]
 support-files =
   moz.png
+[browser_textruns.js]
 [browser_urlbar_blanking.js]
 support-files =
   file_blank_but_not_blank.html
 [browser_urlbar_content_opener.js]
 [browser_urlbar_empty_search.js]
 [browser_urlbar_locationchange_urlbar_edit_dos.js]
 support-files =
   file_urlbar_edit_dos.html
--- a/browser/components/urlbar/tests/browser/browser_UrlbarInput_tooltip.js
+++ b/browser/components/urlbar/tests/browser/browser_UrlbarInput_tooltip.js
@@ -1,46 +1,43 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 function synthesizeMouseOver(element) {
+  info("synthesize mouseover");
   let promise = BrowserTestUtils.waitForEvent(element, "mouseover");
-
-  EventUtils.synthesizeMouse(element, 1, 1, {type: "mouseover"});
-  EventUtils.synthesizeMouse(element, 2, 2, {type: "mousemove"});
-  EventUtils.synthesizeMouse(element, 3, 3, {type: "mousemove"});
-  EventUtils.synthesizeMouse(element, 4, 4, {type: "mousemove"});
-
+  EventUtils.synthesizeMouseAtCenter(document.documentElement, {type: "mouseout"});
+  EventUtils.synthesizeMouseAtCenter(element, {type: "mouseover"});
+  EventUtils.synthesizeMouseAtCenter(element, {type: "mousemove"});
   return promise;
 }
 
 function synthesizeMouseOut(element) {
+  info("synthesize mouseout");
   let promise = BrowserTestUtils.waitForEvent(element, "mouseout");
-
-  EventUtils.synthesizeMouse(element, 0, 0, {type: "mouseout"});
+  EventUtils.synthesizeMouseAtCenter(element, {type: "mouseover"});
+  EventUtils.synthesizeMouseAtCenter(element, {type: "mouseout"});
   EventUtils.synthesizeMouseAtCenter(document.documentElement, {type: "mousemove"});
-  EventUtils.synthesizeMouseAtCenter(document.documentElement, {type: "mousemove"});
-  EventUtils.synthesizeMouseAtCenter(document.documentElement, {type: "mousemove"});
-
   return promise;
 }
 
 async function expectTooltip(text) {
   if (!gURLBar._overflowing && !gURLBar._inOverflow) {
     info("waiting for overflow event");
     await BrowserTestUtils.waitForEvent(gURLBar.inputField, "overflow");
   }
 
   let tooltip = document.getElementById("aHTMLTooltip");
   let element = gURLBar.inputField;
 
   let popupShownPromise = BrowserTestUtils.waitForEvent(tooltip, "popupshown");
   await synthesizeMouseOver(element);
+  info("awaiting for tooltip popup");
   await popupShownPromise;
 
   is(element.getAttribute("title"), text, "title attribute has expected text");
   is(tooltip.textContent, text, "tooltip shows expected text");
 
   await synthesizeMouseOut(element);
 }
 
@@ -61,17 +58,16 @@ async function expectNoTooltip() {
 add_task(async function() {
   window.windowUtils.disableNonTestMouseEvents(true);
   registerCleanupFunction(() => {
     window.windowUtils.disableNonTestMouseEvents(false);
   });
 
   // Ensure the URL bar is neither focused nor hovered before we start.
   gBrowser.selectedBrowser.focus();
-  await synthesizeMouseOver(gURLBar.inputField);
   await synthesizeMouseOut(gURLBar.inputField);
 
   gURLBar.value = "short string";
   await expectNoTooltip();
 
   let longURL = "http://longurl.com/" + "foobar/".repeat(30);
   gURLBar.value = longURL;
   is(gURLBar.inputField.value, longURL.replace(/^http:\/\//, ""), "Urlbar value has http:// stripped");
new file mode 100644
--- /dev/null
+++ b/browser/components/urlbar/tests/browser/browser_textruns.js
@@ -0,0 +1,26 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+/**
+ * This test ensures that we limit textruns in case of very long urls or titles.
+ */
+
+ add_task(async function() {
+  let lotsOfSpaces = "%20".repeat(300);
+  await PlacesTestUtils.addVisits({
+    uri: `https://textruns.mozilla.org/${lotsOfSpaces}/test/`,
+    title: `A long ${lotsOfSpaces} title`});
+  registerCleanupFunction(async function() {
+    await PlacesUtils.history.clear();
+  });
+
+  await promiseAutocompleteResultPopup("textruns");
+  let result = await UrlbarTestUtils.getDetailsOfResultAt(window, 1);
+  Assert.equal(result.displayed.title.length, UrlbarUtils.MAX_TEXT_LENGTH,
+               "Result title should be limited");
+  Assert.equal(result.displayed.url.length, UrlbarUtils.MAX_TEXT_LENGTH,
+               "Result url should be limited");
+  await UrlbarTestUtils.promisePopupClose(window);
+});
--- a/browser/components/urlbar/tests/legacy/browser.ini
+++ b/browser/components/urlbar/tests/legacy/browser.ini
@@ -95,16 +95,17 @@ skip-if = ((os == 'win') && verify && de
 [../browser/browser_switchToTab_fullUrl_repeatedKeydown.js]
 skip-if = true # Bug 1507755
 [../browser/browser_switchToTabHavingURI_aOpenParams.js]
 [../browser/browser_tabMatchesInAwesomebar_perwindowpb.js]
 skip-if = os == 'linux' # Bug 1104755
 [../browser/browser_tabMatchesInAwesomebar.js]
 support-files =
   ../browser/moz.png
+[../browser/browser_textruns.js]
 [../browser/browser_urlbarAboutHomeLoading.js]
 [../browser/browser_urlbarCopying.js]
 subsuite = clipboard
 support-files =
   ../browser/authenticate.sjs
 [../browser/browser_urlbarCutting.js]
 [../browser/browser_urlbarDecode.js]
 [../browser/browser_urlbar_blanking.js]