From edec05a07b379151626f9ed83fab788d0c9fb32b Mon Sep 17 00:00:00 2001 From: Neil Deakin Date: Fri, 12 Feb 2021 00:51:19 +0000 Subject: [PATCH] Bug 1690791, update the scroll tick marks when the browser window is resized. In addition, this ensures that the tick marks update when the scrollbar is made visible after resizing the content area, r=mikedeboer Differential Revision: https://phabricator.services.mozilla.com/D104319 --- .../tests/browser/browser_findbar_marks.js | 82 ++++++++++++++----- toolkit/modules/FinderHighlighter.jsm | 29 ++++--- 2 files changed, 82 insertions(+), 29 deletions(-) diff --git a/toolkit/content/tests/browser/browser_findbar_marks.js b/toolkit/content/tests/browser/browser_findbar_marks.js index 02a057f14e28..0e98fe26bba3 100644 --- a/toolkit/content/tests/browser/browser_findbar_marks.js +++ b/toolkit/content/tests/browser/browser_findbar_marks.js @@ -8,19 +8,8 @@ const TEST_PAGE_URI = let gUpdateCount = 0; -add_task(async function test_findmarks() { - let tab = await BrowserTestUtils.openNewForegroundTab( - gBrowser, - TEST_PAGE_URI - ); - - // Open the findbar so that the content scroll size can be measured. - await promiseFindFinished(gBrowser, "s"); - - let browser = tab.linkedBrowser; - let scrollMaxY = await SpecialPowers.spawn(browser, [], () => { - return content.scrollMaxY; - }); +function initForBrowser(browser) { + gUpdateCount = 0; browser.sendMessageToActor( "Finder:EnableMarkTesting", @@ -44,6 +33,33 @@ add_task(async function test_findmarks() { checkFn ); + return () => { + browser.sendMessageToActor( + "Finder:EnableMarkTesting", + { enable: false }, + "Finder" + ); + + endFn(); + }; +} + +add_task(async function test_findmarks() { + let tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + TEST_PAGE_URI + ); + + // Open the findbar so that the content scroll size can be measured. + await promiseFindFinished(gBrowser, "s"); + + let browser = tab.linkedBrowser; + let scrollMaxY = await SpecialPowers.spawn(browser, [], () => { + return content.scrollMaxY; + }); + + let endFn = initForBrowser(browser); + // For the first value, get the numbers and ensure that they are approximately // in the right place. Later tests should give the same values. await promiseFindFinished(gBrowser, "tex", true); @@ -71,13 +87,41 @@ add_task(async function test_findmarks() { endFn(); - browser.sendMessageToActor( - "Finder:EnableMarkTesting", - { enable: false }, - "Finder" + gBrowser.removeTab(tab); +}); + +// This test verifies what happens when scroll marks are visible and the window is resized. +add_task(async function test_found_resize() { + let window2 = await BrowserTestUtils.openNewBrowserWindow({}); + let tab = await BrowserTestUtils.openNewForegroundTab( + window2.gBrowser, + TEST_PAGE_URI ); - gBrowser.removeTab(tab); + let browser = tab.linkedBrowser; + let endFn = initForBrowser(browser); + + await promiseFindFinished(window2.gBrowser, "tex", true); + let values = await getMarks(browser, true); + + let resizePromise = BrowserTestUtils.waitForContentEvent( + browser, + "resize", + true + ); + window2.resizeTo(outerWidth - 100, outerHeight - 80); + await resizePromise; + + // Some number of extra scrollbar adjustment and painting events can occur + // when resizing the window, so don't use an exact match for the count. + let resizedValues = await getMarks(browser, true); + SimpleTest.isfuzzy(resizedValues[0], values[0], 2, "first value"); + SimpleTest.ok(resizedValues[1] - 50 > values[1], "second value"); + SimpleTest.ok(resizedValues[2] - 50 > values[2], "third value"); + + endFn(); + + await BrowserTestUtils.closeWindow(window2); }); // Returns the scroll marks that should have been assigned @@ -110,7 +154,7 @@ async function getMarks(browser, increase) { } async function doAndVerifyFind(browser, text, increase, expectedMarks) { - await promiseFindFinished(gBrowser, text, true); + await promiseFindFinished(browser.getTabBrowser(), text, true); return verifyFind(browser, text, increase, expectedMarks); } diff --git a/toolkit/modules/FinderHighlighter.jsm b/toolkit/modules/FinderHighlighter.jsm index 255b49bef92f..34f218ae1b61 100644 --- a/toolkit/modules/FinderHighlighter.jsm +++ b/toolkit/modules/FinderHighlighter.jsm @@ -612,8 +612,8 @@ FinderHighlighter.prototype = { let window = this.finder._getWindow(); let yStart = window.scrollY; - // If the document is not scrollable, there is no scrollbar to show marks on. - if (window && window.scrollMaxY > 0) { + let hasRanges = false; + if (window) { let controllers = [this.finder._getSelectionController(window)]; let editors = this.editors; if (editors) { @@ -627,18 +627,25 @@ FinderHighlighter.prototype = { ); let rangeCount = findSelection.rangeCount; - let yAdj = - window.scrollMaxY / - window.document.documentElement.getBoundingClientRect().height; - for (let r = 0; r < rangeCount; r++) { - let rect = findSelection.getRangeAt(r).getBoundingClientRect(); - let yPos = Math.round((yStart + rect.y + rect.height / 2) * yAdj); // use the midpoint - marks.add(yPos); + if (rangeCount > 0) { + hasRanges = true; + } + + // No need to calculate the mark positions if there is no visible scrollbar. + if (window.scrollMaxY > 0) { + let yAdj = + window.scrollMaxY / + window.document.documentElement.getBoundingClientRect().height; + for (let r = 0; r < rangeCount; r++) { + let rect = findSelection.getRangeAt(r).getBoundingClientRect(); + let yPos = Math.round((yStart + rect.y + rect.height / 2) * yAdj); // use the midpoint + marks.add(yPos); + } } } } - if (marks.size) { + if (hasRanges) { // Assign the marks to the window and add a listener for the MozScrolledAreaChanged // event which fires whenever the scrollable area's size is updated. this.setScrollMarks(window, Array.from(marks)); @@ -653,6 +660,7 @@ FinderHighlighter.prototype = { this._marksListener, true ); + window.addEventListener("resize", this._marksListener); } } else if (this._marksListener) { // No results were found so remove any existing ones and the MozScrolledAreaChanged listener. @@ -676,6 +684,7 @@ FinderHighlighter.prototype = { this._marksListener, true ); + window.removeEventListener("resize", this._marksListener); this._marksListener = null; } this.setScrollMarks(window, []);