mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 08:45:46 +00:00
Bug 1566783 - Don't prevent PresShell::ScrollToAnchor() from working due to scroll anchoring adjustments that happen without the user scrolling. r=dholbert
We were bailing out because scroll anchoring adjustments can make this check fail: * https://searchfox.org/mozilla-central/rev/22b330ecb3edba1536a54887060cbdd09db21c59/layout/base/PresShell.cpp#3194 Differential Revision: https://phabricator.services.mozilla.com/D38397 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
cf7beea50e
commit
937b1f9834
@ -1593,13 +1593,34 @@ class PresShell final : public nsStubDocumentObserver,
|
||||
/**
|
||||
* Tells the presshell to scroll again to the last anchor scrolled to by
|
||||
* GoToAnchor, if any. This scroll only happens if the scroll
|
||||
* position has not changed since the last GoToAnchor. This is called
|
||||
* by nsDocumentViewer::LoadComplete. This clears the last anchor
|
||||
* scrolled to by GoToAnchor (we don't want to keep it alive if it's
|
||||
* removed from the DOM), so don't call this more than once.
|
||||
* position has not changed since the last GoToAnchor (modulo scroll anchoring
|
||||
* adjustments). This is called by nsDocumentViewer::LoadComplete. This clears
|
||||
* the last anchor scrolled to by GoToAnchor (we don't want to keep it alive
|
||||
* if it's removed from the DOM), so don't call this more than once.
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT nsresult ScrollToAnchor();
|
||||
|
||||
/**
|
||||
* When scroll anchoring adjusts positions in the root frame during page load,
|
||||
* it may move our scroll position in the root frame.
|
||||
*
|
||||
* While that's generally desirable, when scrolling to an anchor via an id-ref
|
||||
* we have a more direct target. If the id-ref points to something that cannot
|
||||
* be selected as a scroll anchor container (like an image or an inline), we
|
||||
* may select a node following it as a scroll anchor, and if then stuff is
|
||||
* inserted on top, we may end up moving the id-ref element offscreen to the
|
||||
* top inadvertently.
|
||||
*
|
||||
* On page load, the document viewer will call ScrollToAnchor(), and will only
|
||||
* scroll to the anchor again if the scroll position is not changed. We don't
|
||||
* want scroll anchoring adjustments to prevent this, so account for them.
|
||||
*/
|
||||
void RootScrollFrameAdjusted(nscoord aYAdjustment) {
|
||||
if (mLastAnchorScrolledTo) {
|
||||
mLastAnchorScrollPositionY += aYAdjustment;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scrolls the view of the document so that the primary frame of the content
|
||||
* is displayed in the window. Layout is flushed before scrolling.
|
||||
|
@ -378,8 +378,10 @@ void ScrollAnchorContainer::ApplyAdjustments() {
|
||||
mApplyingAnchorAdjustment = false;
|
||||
|
||||
nsPresContext* pc = Frame()->PresContext();
|
||||
Document* doc = pc->Document();
|
||||
doc->UpdateForScrollAnchorAdjustment(logicalAdjustment);
|
||||
if (mScrollFrame->mIsRoot) {
|
||||
pc->PresShell()->RootScrollFrameAdjusted(physicalAdjustment.y);
|
||||
}
|
||||
pc->Document()->UpdateForScrollAnchorAdjustment(logicalAdjustment);
|
||||
|
||||
// The anchor position may not be in the same relative position after
|
||||
// adjustment. Update ourselves so we have consistent state.
|
||||
|
20
layout/generic/test/file_SlowTallImage.sjs
Normal file
20
layout/generic/test/file_SlowTallImage.sjs
Normal file
@ -0,0 +1,20 @@
|
||||
"use strict";
|
||||
|
||||
/* eslint-disable-next-line mozilla/use-chromeutils-import */
|
||||
let {setTimeout} = Cu.import("resource://gre/modules/Timer.jsm", {});
|
||||
|
||||
// A tall 1x1000 black png.
|
||||
const IMG_BYTES = atob(
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAPoAQMAAAAleAYdAAAABlBMVEUAAAD///+l2Z/dAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAF0lEQVQ4jWNgGAWjYBSMglEwCkbBUAcAB9AAASBs/t4AAAAASUVORK5CYII="
|
||||
);
|
||||
|
||||
// Cargo-culted from file_SlowImage.sjs
|
||||
function handleRequest(request, response) {
|
||||
response.processAsync();
|
||||
response.setHeader("Content-Type", "image/png");
|
||||
let delay = request.queryString.indexOf("slow") >= 0 ? 600 : 200;
|
||||
setTimeout(function() {
|
||||
response.write(IMG_BYTES);
|
||||
response.finish();
|
||||
}, delay);
|
||||
}
|
24
layout/generic/test/file_bug1566783.html
Normal file
24
layout/generic/test/file_bug1566783.html
Normal file
@ -0,0 +1,24 @@
|
||||
<!doctype html>
|
||||
<style>
|
||||
.spacer { height: 200vh; }
|
||||
</style>
|
||||
<script>
|
||||
function loadFailed() {
|
||||
parent.ok(false, "Image load should not fail");
|
||||
}
|
||||
</script>
|
||||
<div class="spacer"></div>
|
||||
<img id="fast" src="file_SlowTallImage.sjs?fast" onerror="loadFailed()">
|
||||
<div class="spacer"></div>
|
||||
<img id="slow" src="file_SlowTallImage.sjs?slow" onerror="loadFailed()">
|
||||
<div class="spacer"></div>
|
||||
<script>
|
||||
onload = function() {
|
||||
setTimeout(function() {
|
||||
let rect = document.getElementById("slow").getBoundingClientRect();
|
||||
parent.is(rect.height, 1000, "#slow should take space");
|
||||
parent.is(rect.top, 0, "#slow should be at the top of the viewport");
|
||||
parent.SimpleTest.finish();
|
||||
}, 0);
|
||||
}
|
||||
</script>
|
@ -16,6 +16,7 @@ support-files =
|
||||
file_LoadingImageReference.png
|
||||
file_SlowImage.sjs
|
||||
file_SlowPage.sjs
|
||||
file_SlowTallImage.sjs
|
||||
bug1174521.html
|
||||
!/gfx/layers/apz/test/mochitest/apz_test_utils.js
|
||||
|
||||
@ -100,6 +101,8 @@ support-files = bug633762_iframe.html
|
||||
support-files = file_bug1307853.html
|
||||
[test_bug1408607.html]
|
||||
[test_bug1499961.html]
|
||||
[test_bug1566783.html]
|
||||
support-files = file_bug1566783.html
|
||||
[test_contained_plugin_transplant.html]
|
||||
skip-if = os=='win'
|
||||
[test_dynamic_reflow_root_disallowal.html]
|
||||
|
8
layout/generic/test/test_bug1566783.html
Normal file
8
layout/generic/test/test_bug1566783.html
Normal file
@ -0,0 +1,8 @@
|
||||
<!doctype html>
|
||||
<title>Test for scroll anchoring adjustments during onload</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script>
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
|
||||
<iframe width="300" height="300" src="file_bug1566783.html#slow"></iframe>
|
Loading…
Reference in New Issue
Block a user