1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-23 10:37:41 +00:00

LibWeb: Implement and use "scroll to the fragment" algorithm

This will eventually be used by Navigable but for now, it's just when
traversing the history.
This commit is contained in:
Sam Atkins 2023-08-11 20:26:02 +01:00 committed by Andreas Kling
parent be9c975b2e
commit 8bd3b74e3a
3 changed files with 64 additions and 5 deletions

View file

@ -49,6 +49,7 @@
#include <LibWeb/HTML/DocumentState.h> #include <LibWeb/HTML/DocumentState.h>
#include <LibWeb/HTML/EventLoop/EventLoop.h> #include <LibWeb/HTML/EventLoop/EventLoop.h>
#include <LibWeb/HTML/EventNames.h> #include <LibWeb/HTML/EventNames.h>
#include <LibWeb/HTML/Focus.h>
#include <LibWeb/HTML/HTMLAnchorElement.h> #include <LibWeb/HTML/HTMLAnchorElement.h>
#include <LibWeb/HTML/HTMLAreaElement.h> #include <LibWeb/HTML/HTMLAreaElement.h>
#include <LibWeb/HTML/HTMLBaseElement.h> #include <LibWeb/HTML/HTMLBaseElement.h>
@ -1796,6 +1797,64 @@ Element* Document::find_a_potential_indicated_element(DeprecatedString fragment)
return nullptr; return nullptr;
} }
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#scroll-to-the-fragment-identifier
void Document::scroll_to_the_fragment()
{
// To scroll to the fragment given a Document document:
// 1. If document's indicated part is null, then set document's target element to null.
auto indicated_part = determine_the_indicated_part();
if (indicated_part.has<Element*>() && indicated_part.get<Element*>() == nullptr) {
set_target_element(nullptr);
}
// 2. Otherwise, if document's indicated part is top of the document, then:
else if (indicated_part.has<TopOfTheDocument>()) {
// 1. Set document's target element to null.
set_target_element(nullptr);
// 2. Scroll to the beginning of the document for document. [CSSOMVIEW]
scroll_to_the_beginning_of_the_document();
// 3. Return.
return;
}
// 3. Otherwise:
else {
// 1. Assert: document's indicated part is an element.
VERIFY(indicated_part.has<Element*>());
// 2. Let target be document's indicated part.
auto target = indicated_part.get<Element*>();
// 3. Set document's target element to target.
set_target_element(target);
// FIXME: 4. Run the ancestor details revealing algorithm on target.
// FIXME: 5. Run the ancestor hidden-until-found revealing algorithm on target.
// 6. Scroll target into view, with behavior set to "auto", block set to "start", and inline set to "nearest". [CSSOMVIEW]
// FIXME: Do this properly!
(void)target->scroll_into_view();
// 7. Run the focusing steps for target, with the Document's viewport as the fallback target.
// FIXME: Pass the Document's viewport somehow.
HTML::run_focusing_steps(target);
// FIXME: 8. Move the sequential focus navigation starting point to target.
}
}
// https://drafts.csswg.org/cssom-view-1/#scroll-to-the-beginning-of-the-document
void Document::scroll_to_the_beginning_of_the_document()
{
// FIXME: Actually implement this algorithm
if (auto browsing_context = this->browsing_context())
browsing_context->scroll_to({ 0, 0 });
}
DeprecatedString Document::ready_state() const DeprecatedString Document::ready_state() const
{ {
switch (m_readiness) { switch (m_readiness) {

View file

@ -298,6 +298,9 @@ public:
Element const* target_element() const { return m_target_element.ptr(); } Element const* target_element() const { return m_target_element.ptr(); }
void set_target_element(Element*); void set_target_element(Element*);
void scroll_to_the_fragment();
void scroll_to_the_beginning_of_the_document();
bool created_for_appropriate_template_contents() const { return m_created_for_appropriate_template_contents; } bool created_for_appropriate_template_contents() const { return m_created_for_appropriate_template_contents; }
JS::NonnullGCPtr<Document> appropriate_template_contents_owner_document(); JS::NonnullGCPtr<Document> appropriate_template_contents_owner_document();

View file

@ -1407,11 +1407,8 @@ WebIDL::ExceptionOr<void> BrowsingContext::traverse_the_history(size_t entry_ind
} }
// 10. If entry's persisted user state is null, and its URL's fragment is non-null, then scroll to the fragment. // 10. If entry's persisted user state is null, and its URL's fragment is non-null, then scroll to the fragment.
if (!entry->url.fragment().is_null()) { if (!entry->url.fragment().is_null())
// FIXME: Implement the full "scroll to the fragment" algorithm: active_document()->scroll_to_the_fragment();
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#scroll-to-the-fragment-identifier
scroll_to_anchor(entry->url.fragment());
}
// 11. Set the current entry to entry. // 11. Set the current entry to entry.
m_session_history_index = entry_index; m_session_history_index = entry_index;