LibWeb/HTML: Scroll to the fragment before loading the document

Otherwise nowhere ends up scrolling to the fragment specified by the
fragment in document's URL. This fixes ladybird scrolling to the
correct location in the document when navigating to a link that
has a fragment, e.g:

https://html.spec.whatwg.org/multipage/browsing-the-web.html#try-to-scroll-to-the-fragment

As well as use of the :target selector.
This commit is contained in:
Shannon Booth 2025-01-15 17:15:25 +13:00 committed by Sam Atkins
parent e74ca82083
commit 51102254b5
Notes: github-actions[bot] 2025-01-15 12:44:49 +00:00
4 changed files with 49 additions and 6 deletions

View file

@ -310,6 +310,9 @@ void HTMLParser::the_end(GC::Ref<DOM::Document> document, GC::Ptr<HTMLParser> pa
(void)document->scripts_to_execute_when_parsing_has_finished().take_first();
}
// FIXME: Spec bug: https://github.com/whatwg/html/issues/10914
document->scroll_to_the_fragment();
// 6. Queue a global task on the DOM manipulation task source given the Document's relevant global object to run the following substeps:
queue_global_task(HTML::Task::Source::DOMManipulation, *document, GC::create_function(heap, [document] {
// 1. Set the Document's load timing info's DOM content loaded event start time to the current high resolution time given the Document's relevant global object.

View file

@ -2,8 +2,8 @@ Harness status: OK
Found 1975 tests
1955 Pass
20 Fail
1959 Pass
16 Fail
Pass Selectors-API Test Suite: HTML
Pass Document supports querySelector
Pass Document supports querySelectorAll
@ -601,8 +601,8 @@ Pass Document.querySelectorAll: :link and :visited pseudo-class selectors, match
Pass Document.querySelector: :link and :visited pseudo-class selectors, matching a and area elements with href attributes: #pseudo-link :link, #pseudo-link :visited
Pass Document.querySelectorAll: :link and :visited pseudo-class selectors, matching no elements: #head :link, #head :visited
Pass Document.querySelector: :link and :visited pseudo-class selectors, matching no elements: #head :link, #head :visited
Fail Document.querySelectorAll: :target pseudo-class selector, matching the element referenced by the URL fragment identifier: :target
Fail Document.querySelector: :target pseudo-class selector, matching the element referenced by the URL fragment identifier: :target
Pass Document.querySelectorAll: :target pseudo-class selector, matching the element referenced by the URL fragment identifier: :target
Pass Document.querySelector: :target pseudo-class selector, matching the element referenced by the URL fragment identifier: :target
Pass Document.querySelectorAll: :lang pseudo-class selector, matching inherited language: #pseudo-lang-div1:lang(en)
Pass Document.querySelector: :lang pseudo-class selector, matching inherited language: #pseudo-lang-div1:lang(en)
Pass Document.querySelectorAll: :lang pseudo-class selector, matching specified language with exact value: #pseudo-lang-div2:lang(fr)
@ -1893,8 +1893,8 @@ Pass In-document Element.querySelectorAll: :link and :visited pseudo-class selec
Pass In-document Element.querySelector: :link and :visited pseudo-class selectors, not matching link elements with href attributes: #head :link, #head :visited
Pass In-document Element.querySelectorAll: :link and :visited pseudo-class selectors, chained, mutually exclusive pseudo-classes match nothing: :link:visited
Pass In-document Element.querySelector: :link and :visited pseudo-class selectors, chained, mutually exclusive pseudo-classes match nothing: :link:visited
Fail In-document Element.querySelectorAll: :target pseudo-class selector, matching the element referenced by the URL fragment identifier: :target
Fail In-document Element.querySelector: :target pseudo-class selector, matching the element referenced by the URL fragment identifier: :target
Pass In-document Element.querySelectorAll: :target pseudo-class selector, matching the element referenced by the URL fragment identifier: :target
Pass In-document Element.querySelector: :target pseudo-class selector, matching the element referenced by the URL fragment identifier: :target
Pass In-document Element.querySelectorAll: :lang pseudo-class selector, matching inherited language: #pseudo-lang-div1:lang(en)
Pass In-document Element.querySelector: :lang pseudo-class selector, matching inherited language: #pseudo-lang-div1:lang(en)
Pass In-document Element.querySelectorAll: :lang pseudo-class selector, matching specified language with exact value: #pseudo-lang-div2:lang(fr)

View file

@ -0,0 +1,6 @@
Harness status: OK
Found 1 tests
1 Pass
Pass Data URI parsing of fragments

View file

@ -0,0 +1,34 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Data URI parsing of fragments</title>
<link rel="help" href="https://url.spec.whatwg.org/">
<meta name="assert" content="Fragments should not be included as part of a data URI's body">
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<iframe id="iframe"></iframe>
<script>
const IFRAME_DATA_SRC = `data:text/html,
<style>:target { color: green; }<\/style>
<script>window.addEventListener('load', function() {
const data = {
foo_matches_target_selector: document.getElementById('foo').matches(':target'),
body_html: document.body.innerHTML,
};
parent.postMessage(data, '*');
});<\/script>
<p id="foo">This should be the only visible text.</p>#foo`.replace('\n', '');
async_test(function(t) {
window.addEventListener("message", t.step_func_done(function(event) {
assert_true(event.data.foo_matches_target_selector);
assert_equals(event.data.body_html,
'<p id="foo">This should be the only visible text.</p>');
}));
const iframe = document.getElementById("iframe");
iframe.src = IFRAME_DATA_SRC;
});
</script>