diff --git a/browser/components/urlbar/UrlbarResult.jsm b/browser/components/urlbar/UrlbarResult.jsm index 69db09329a25..311cf9f4ab20 100644 --- a/browser/components/urlbar/UrlbarResult.jsm +++ b/browser/components/urlbar/UrlbarResult.jsm @@ -177,6 +177,14 @@ class UrlbarResult { 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, _]]) => { diff --git a/browser/components/urlbar/UrlbarUtils.jsm b/browser/components/urlbar/UrlbarUtils.jsm index 7bd9da0e3afd..5b502989cc17 100644 --- a/browser/components/urlbar/UrlbarUtils.jsm +++ b/browser/components/urlbar/UrlbarUtils.jsm @@ -127,6 +127,10 @@ var UrlbarUtils = { 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. diff --git a/browser/components/urlbar/tests/browser/browser.ini b/browser/components/urlbar/tests/browser/browser.ini index 0ffe977f6d16..02f066775dfc 100644 --- a/browser/components/urlbar/tests/browser/browser.ini +++ b/browser/components/urlbar/tests/browser/browser.ini @@ -84,6 +84,7 @@ 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 diff --git a/browser/components/urlbar/tests/browser/browser_UrlbarInput_tooltip.js b/browser/components/urlbar/tests/browser/browser_UrlbarInput_tooltip.js index 298c2639b8ab..ff3108e85be2 100644 --- a/browser/components/urlbar/tests/browser/browser_UrlbarInput_tooltip.js +++ b/browser/components/urlbar/tests/browser/browser_UrlbarInput_tooltip.js @@ -4,24 +4,20 @@ "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; } @@ -36,6 +32,7 @@ async function expectTooltip(text) { 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"); @@ -66,7 +63,6 @@ add_task(async function() { // 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"; diff --git a/browser/components/urlbar/tests/browser/browser_textruns.js b/browser/components/urlbar/tests/browser/browser_textruns.js new file mode 100644 index 000000000000..c83548905bfd --- /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); +}); diff --git a/browser/components/urlbar/tests/legacy/browser.ini b/browser/components/urlbar/tests/legacy/browser.ini index 1079fdd91c2a..d320f228560b 100644 --- a/browser/components/urlbar/tests/legacy/browser.ini +++ b/browser/components/urlbar/tests/legacy/browser.ini @@ -100,6 +100,7 @@ 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