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
101 lines
3.2 KiB
HTML
101 lines
3.2 KiB
HTML
<!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();
|
|
return rect.top >= 0 && rect.top <= window.innerHeight
|
|
&& rect.left >= 0 && rect.left <= window.innerWidth;
|
|
}
|
|
|
|
function checkScroll() {
|
|
let position = 'unknown';
|
|
if (window.scrollY == 0)
|
|
position = 'top';
|
|
else if (isInView(document.getElementById('element')))
|
|
position = 'element';
|
|
else if (isInView(document.getElementById('text')))
|
|
position = 'text';
|
|
else if (isInView(document.getElementById('more-text')))
|
|
position = 'more-text';
|
|
else if (isInView(document.getElementById('cross-node-context')))
|
|
position = 'cross-node-context';
|
|
else if (isInView(document.getElementById('text-directive-parameters')))
|
|
position = 'text-directive-parameters';
|
|
else if (isInView(document.getElementById('shadow-parent')))
|
|
position = 'shadow-parent';
|
|
else if (isInView(document.getElementById('hidden')))
|
|
position = 'hidden';
|
|
else if (isInView(document.getElementById('horizontal-scroll')) && window.scrollX > 0)
|
|
position = 'horizontal-scroll';
|
|
|
|
let target = document.querySelector(":target");
|
|
|
|
if (!target && position == 'shadow-parent') {
|
|
let shadow = document.getElementById("shadow-parent").shadowRoot.firstElementChild;
|
|
if (shadow.matches(":target")) {
|
|
target = shadow;
|
|
position = 'shadow';
|
|
}
|
|
}
|
|
|
|
let results = {
|
|
scrollPosition: position,
|
|
href: window.location.href,
|
|
target: target ? target.id : 'undefined'
|
|
};
|
|
|
|
let key = (new URL(document.location)).searchParams.get("key");
|
|
stashResultsThenClose(key, results);
|
|
}
|
|
|
|
// Ensure two animation frames on load to test the fallback to element anchor,
|
|
// which gets queued for the next frame if the text fragment is not found.
|
|
window.onload = function() {
|
|
window.requestAnimationFrame(function() {
|
|
window.requestAnimationFrame(checkScroll);
|
|
})
|
|
}
|
|
</script>
|
|
<style>
|
|
.scroll-section {
|
|
/* 1000px margin on top and bottom so only one section can be in view. */
|
|
margin: 1000px 0px;
|
|
}
|
|
#hidden {
|
|
visibility: hidden;
|
|
}
|
|
#horizontal-scroll {
|
|
margin-left: 2000px;
|
|
}
|
|
#display-none {
|
|
display: none;
|
|
}
|
|
</style>
|
|
<body>
|
|
<div id="element" class="scroll-section">Element</div>
|
|
<p id="text" class="scroll-section">
|
|
This is a test page !$'()*+./:;=?@_~ &,- ネコ
|
|
<br>
|
|
foo foo foo bar bar bar
|
|
</p>
|
|
<p id="more-text" class="scroll-section">More test page text</p>
|
|
<div class="scroll-section">
|
|
<div>
|
|
<p>prefix</p>
|
|
<p id="cross-node-context">test page</p>
|
|
</div>
|
|
<div><p>suffix</p></div>
|
|
</div>
|
|
<p id="text-directive-parameters" class="scroll-section">this,is,test,page</p>
|
|
<div id="shadow-parent" class="scroll-section"></div>
|
|
<script>
|
|
let shadow = document.getElementById("shadow-parent").attachShadow({mode: 'open'});
|
|
shadow.innerHTML = '<p id="shadow">shadow text</p>';
|
|
</script>
|
|
<p id="hidden" class="scroll-section">hidden text</p>
|
|
<p id="horizontal-scroll" class="scroll-section">horizontally scrolled text</p>
|
|
<p id="display-none" class="scroll-section">display none</p>
|
|
</body>
|