From 2106617f5b97dd2e3c4aea11ef26685f43e75261 Mon Sep 17 00:00:00 2001 From: Jelle Raaijmakers Date: Wed, 2 Oct 2024 10:33:05 +0200 Subject: [PATCH] LibWeb: Implement `history.scrollRestoration` --- .../HTML/History-scrollRestoration.txt | 4 ++ .../input/HTML/History-scrollRestoration.html | 12 ++++++ Userland/Libraries/LibWeb/HTML/History.cpp | 39 +++++++++++++++++++ Userland/Libraries/LibWeb/HTML/History.h | 3 ++ Userland/Libraries/LibWeb/HTML/History.idl | 2 +- 5 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 Tests/LibWeb/Text/expected/HTML/History-scrollRestoration.txt create mode 100644 Tests/LibWeb/Text/input/HTML/History-scrollRestoration.html diff --git a/Tests/LibWeb/Text/expected/HTML/History-scrollRestoration.txt b/Tests/LibWeb/Text/expected/HTML/History-scrollRestoration.txt new file mode 100644 index 00000000000..8d01915f96d --- /dev/null +++ b/Tests/LibWeb/Text/expected/HTML/History-scrollRestoration.txt @@ -0,0 +1,4 @@ +auto +auto +manual +auto diff --git a/Tests/LibWeb/Text/input/HTML/History-scrollRestoration.html b/Tests/LibWeb/Text/input/HTML/History-scrollRestoration.html new file mode 100644 index 00000000000..1408d0c12b8 --- /dev/null +++ b/Tests/LibWeb/Text/input/HTML/History-scrollRestoration.html @@ -0,0 +1,12 @@ + + diff --git a/Userland/Libraries/LibWeb/HTML/History.cpp b/Userland/Libraries/LibWeb/HTML/History.cpp index 4b6ad2d930a..36e99ea6437 100644 --- a/Userland/Libraries/LibWeb/HTML/History.cpp +++ b/Userland/Libraries/LibWeb/HTML/History.cpp @@ -229,4 +229,43 @@ WebIDL::ExceptionOr History::shared_history_push_replace_state(JS::Value d return {}; } +// https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-history-scroll-restoration +WebIDL::ExceptionOr History::scroll_restoration() const +{ + // 1. If this's relevant global object's associated Document is not fully active, then throw a "SecurityError" DOMException. + if (!m_associated_document->is_fully_active()) + return WebIDL::SecurityError::create(realm(), "Cannot obtain scroll restoration mode for a document that isn't fully active."_fly_string); + + // 2. Return this's node navigable's active session history entry's scroll restoration mode. + auto scroll_restoration_mode = m_associated_document->navigable()->active_session_history_entry()->scroll_restoration_mode(); + switch (scroll_restoration_mode) { + case ScrollRestorationMode::Auto: + return Bindings::ScrollRestoration::Auto; + case ScrollRestorationMode::Manual: + return Bindings::ScrollRestoration::Manual; + } + VERIFY_NOT_REACHED(); +} + +// https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-history-scroll-restoration +WebIDL::ExceptionOr History::set_scroll_restoration(Bindings::ScrollRestoration scroll_restoration) +{ + // 1. If this's relevant global object's associated Document is not fully active, then throw a "SecurityError" DOMException. + if (!m_associated_document->is_fully_active()) + return WebIDL::SecurityError::create(realm(), "Cannot set scroll restoration mode for a document that isn't fully active."_fly_string); + + // 2. Set this's node navigable's active session history entry's scroll restoration mode to the given value. + auto active_session_history_entry = m_associated_document->navigable()->active_session_history_entry(); + switch (scroll_restoration) { + case Bindings::ScrollRestoration::Auto: + active_session_history_entry->set_scroll_restoration_mode(ScrollRestorationMode::Auto); + break; + case Bindings::ScrollRestoration::Manual: + active_session_history_entry->set_scroll_restoration_mode(ScrollRestorationMode::Manual); + break; + } + + return {}; +} + } diff --git a/Userland/Libraries/LibWeb/HTML/History.h b/Userland/Libraries/LibWeb/HTML/History.h index 26493ba3e4e..9e29e3b8673 100644 --- a/Userland/Libraries/LibWeb/HTML/History.h +++ b/Userland/Libraries/LibWeb/HTML/History.h @@ -7,6 +7,7 @@ #pragma once +#include #include #include #include @@ -29,6 +30,8 @@ public: WebIDL::ExceptionOr back(); WebIDL::ExceptionOr forward(); WebIDL::ExceptionOr length() const; + WebIDL::ExceptionOr scroll_restoration() const; + WebIDL::ExceptionOr set_scroll_restoration(Bindings::ScrollRestoration); WebIDL::ExceptionOr state() const; u64 m_index { 0 }; diff --git a/Userland/Libraries/LibWeb/HTML/History.idl b/Userland/Libraries/LibWeb/HTML/History.idl index d9ff38c469f..b7fe6677b2f 100644 --- a/Userland/Libraries/LibWeb/HTML/History.idl +++ b/Userland/Libraries/LibWeb/HTML/History.idl @@ -5,7 +5,7 @@ enum ScrollRestoration { "auto", "manual" }; [Exposed=Window] interface History { readonly attribute unsigned long length; - [FIXME] attribute ScrollRestoration scrollRestoration; + attribute ScrollRestoration scrollRestoration; readonly attribute any state; undefined go(optional long delta = 0); undefined back();