mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 06:43:32 +00:00
Bug 1906134 - Text Fragments: Ensure to scroll the first text directive on a page into the center of the view. r=emilio
Before this patch, it could happen that `PresShell::GoToAnchor()` was called while loading a document. This method did not know about text fragments before, and would scroll the anchor (ie., the first text directive) to the top of the view. This was noticeable for pages that took longer to load, where the text directive was scrolled to the center first, and then to the top. This patch saves the desired vertical scroll position as a member in `PresShell` and makes `GoToAnchor()` scroll to the center as well. Additionally, this patch updates the test file target document to make it more mobile-friendly. Differential Revision: https://phabricator.services.mozilla.com/D216039
This commit is contained in:
parent
0e5d229536
commit
5ce2766d95
@ -749,6 +749,7 @@ PresShell::PresShell(Document* aDocument)
|
||||
: mDocument(aDocument),
|
||||
mViewManager(nullptr),
|
||||
mAutoWeakFrames(nullptr),
|
||||
mLastAnchorVerticalScrollViewPosition(WhereToScroll::Start),
|
||||
#ifdef ACCESSIBILITY
|
||||
mDocAccessible(nullptr),
|
||||
#endif // ACCESSIBILITY
|
||||
@ -3172,6 +3173,7 @@ nsresult PresShell::GoToAnchor(const nsAString& aAnchorName,
|
||||
if (ScrollContainerFrame* rootScroll = GetRootScrollContainerFrame()) {
|
||||
mLastAnchorScrolledTo = target;
|
||||
mLastAnchorScrollPositionY = rootScroll->GetScrollPosition().y;
|
||||
mLastAnchorVerticalScrollViewPosition = verticalScrollPosition;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3279,7 +3281,8 @@ nsresult PresShell::ScrollToAnchor() {
|
||||
return NS_OK;
|
||||
}
|
||||
return ScrollContentIntoView(
|
||||
lastAnchor, ScrollAxis(WhereToScroll::Start, WhenToScroll::Always),
|
||||
lastAnchor,
|
||||
ScrollAxis(mLastAnchorVerticalScrollViewPosition, WhenToScroll::Always),
|
||||
ScrollAxis(), ScrollFlags::AnchorScrollFlags);
|
||||
}
|
||||
|
||||
|
@ -2989,6 +2989,11 @@ class PresShell final : public nsStubDocumentObserver,
|
||||
|
||||
nsCOMPtr<nsIContent> mLastAnchorScrolledTo;
|
||||
|
||||
// Text directives are supposed to be scrolled to the center of the viewport.
|
||||
// Since `ScrollToAnchor()` might get called after `GoToAnchor()` during a
|
||||
// load, the vertical view position should be preserved.
|
||||
WhereToScroll mLastAnchorVerticalScrollViewPosition;
|
||||
|
||||
// Information needed to properly handle scrolling content into view if the
|
||||
// pre-scroll reflow flush can be interrupted. mContentToScrollTo is non-null
|
||||
// between the initial scroll attempt and the first time we finish processing
|
||||
|
@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<title>
|
||||
Ensuring a text directive is scrolled to the center of the view port instead of the top.
|
||||
</title>
|
||||
<script src="stash.js"></script>
|
||||
<script>
|
||||
function checkScroll() {
|
||||
const results = {hasScrolled: window.scrollY != 0};
|
||||
let key = (new URL(document.location)).searchParams.get("key");
|
||||
stashResultsThenClose(key, results);
|
||||
};
|
||||
window.onload = () => {
|
||||
window.requestAnimationFrame(function() {
|
||||
window.requestAnimationFrame(checkScroll);
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<body>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
// trigger a layout flush
|
||||
_ = document.body.getBoundingClientRect();
|
||||
});
|
||||
</script>
|
||||
<div style="margin-top: 20vh; margin-bottom: 100vh">Scroll to me</div>
|
||||
</body>
|
@ -0,0 +1,25 @@
|
||||
<!doctype html>
|
||||
<title>Navigating to a text fragment directive</title>
|
||||
<meta charset=utf-8>
|
||||
<link rel="help" href="https://wicg.github.io/ScrollToTextFragment/">
|
||||
<meta name="timeout" content="long">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/common/utils.js"></script>
|
||||
<script src="stash.js"></script>
|
||||
|
||||
<script>
|
||||
promise_test(t => new Promise((resolve, reject) => {
|
||||
let key = token();
|
||||
test_driver.bless('Open a URL with a text fragment directive', () => {
|
||||
window.open(`scroll-to-text-fragment-scroll-to-center-target.html?key=${key}#:~:text=Scroll`, "_blank", "noopener");
|
||||
|
||||
fetchResults(key, resolve, reject);
|
||||
})
|
||||
}).then(data => {
|
||||
assert_false(data.hasScrolled, "Expected text directive to be scrolled to.");
|
||||
})
|
||||
);
|
||||
</script>
|
@ -1,6 +1,7 @@
|
||||
<!doctype html>
|
||||
<title>Navigating to a text fragment anchor</title>
|
||||
<script src="stash.js"></script>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<script>
|
||||
function isInView(element) {
|
||||
let rect = element.getBoundingClientRect();
|
||||
|
Loading…
Reference in New Issue
Block a user