Skip to content

Commit

Permalink
LibWeb/HTML: Scroll to the fragment before loading the document
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
shannonbooth committed Jan 15, 2025
1 parent e95096d commit 07d3197
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 6 deletions.
3 changes: 3 additions & 0 deletions Libraries/LibWeb/HTML/Parser/HTMLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Harness status: OK

Found 1 tests

1 Pass
Pass Data URI parsing of fragments
34 changes: 34 additions & 0 deletions Tests/LibWeb/Text/input/wpt-import/url/data-uri-fragment.html
Original file line number Diff line number Diff line change
@@ -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>

0 comments on commit 07d3197

Please sign in to comment.