mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-22 09:21:57 -05:00
LibWeb: Add a NavigationObserver to be notified of navigable updates
This contains a hook to be notified when a navigable navigation is complete, to be used by WebDriver. (cherry picked from commit 74ef9dc3936d678fdf811bb3c1b39a6ffba2b106)
This commit is contained in:
parent
750ef1466f
commit
528fa3bbdb
6 changed files with 105 additions and 0 deletions
|
@ -410,6 +410,7 @@ set(SOURCES
|
|||
HTML/NavigationDestination.cpp
|
||||
HTML/NavigationCurrentEntryChangeEvent.cpp
|
||||
HTML/NavigationHistoryEntry.cpp
|
||||
HTML/NavigationObserver.cpp
|
||||
HTML/NavigationParams.cpp
|
||||
HTML/NavigationTransition.cpp
|
||||
HTML/Navigator.cpp
|
||||
|
|
|
@ -490,6 +490,7 @@ class Navigation;
|
|||
class NavigationCurrentEntryChangeEvent;
|
||||
class NavigationDestination;
|
||||
class NavigationHistoryEntry;
|
||||
class NavigationObserver;
|
||||
class NavigationTransition;
|
||||
class Navigator;
|
||||
class PageTransitionEvent;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <LibWeb/HTML/HistoryHandlingBehavior.h>
|
||||
#include <LibWeb/HTML/Navigable.h>
|
||||
#include <LibWeb/HTML/Navigation.h>
|
||||
#include <LibWeb/HTML/NavigationObserver.h>
|
||||
#include <LibWeb/HTML/NavigationParams.h>
|
||||
#include <LibWeb/HTML/POSTResource.h>
|
||||
#include <LibWeb/HTML/Parser/HTMLParser.h>
|
||||
|
@ -124,6 +125,7 @@ void Navigable::visit_edges(Cell::Visitor& visitor)
|
|||
visitor.visit(m_current_session_history_entry);
|
||||
visitor.visit(m_active_session_history_entry);
|
||||
visitor.visit(m_container);
|
||||
visitor.visit(m_navigation_observers);
|
||||
m_event_handler.visit_edges(visitor);
|
||||
}
|
||||
|
||||
|
@ -213,6 +215,13 @@ void Navigable::activate_history_entry(JS::GCPtr<SessionHistoryEntry> entry)
|
|||
|
||||
// 5. Make active newDocument.
|
||||
new_document->make_active();
|
||||
|
||||
if (m_ongoing_navigation.has<Empty>()) {
|
||||
for (auto navigation_observer : m_navigation_observers) {
|
||||
if (navigation_observer->navigation_complete())
|
||||
navigation_observer->navigation_complete()->function()();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/document-sequences.html#nav-document
|
||||
|
@ -2228,4 +2237,16 @@ void Navigable::paste(String const& text)
|
|||
m_event_handler.handle_paste(text);
|
||||
}
|
||||
|
||||
void Navigable::register_navigation_observer(Badge<NavigationObserver>, NavigationObserver& navigation_observer)
|
||||
{
|
||||
auto result = m_navigation_observers.set(navigation_observer);
|
||||
VERIFY(result == AK::HashSetResult::InsertedNewEntry);
|
||||
}
|
||||
|
||||
void Navigable::unregister_navigation_observer(Badge<NavigationObserver>, NavigationObserver& navigation_observer)
|
||||
{
|
||||
bool was_removed = m_navigation_observers.remove(navigation_observer);
|
||||
VERIFY(was_removed);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -57,6 +57,9 @@ public:
|
|||
|
||||
ErrorOr<void> initialize_navigable(JS::NonnullGCPtr<DocumentState> document_state, JS::GCPtr<Navigable> parent);
|
||||
|
||||
void register_navigation_observer(Badge<NavigationObserver>, NavigationObserver&);
|
||||
void unregister_navigation_observer(Badge<NavigationObserver>, NavigationObserver&);
|
||||
|
||||
Vector<JS::Handle<Navigable>> child_navigables() const;
|
||||
|
||||
bool is_traversable() const;
|
||||
|
@ -239,6 +242,8 @@ private:
|
|||
|
||||
JS::NonnullGCPtr<Page> m_page;
|
||||
|
||||
HashTable<JS::NonnullGCPtr<NavigationObserver>> m_navigation_observers;
|
||||
|
||||
bool m_has_been_destroyed { false };
|
||||
|
||||
CSSPixelSize m_size;
|
||||
|
|
43
Userland/Libraries/LibWeb/HTML/NavigationObserver.cpp
Normal file
43
Userland/Libraries/LibWeb/HTML/NavigationObserver.cpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/Runtime/Realm.h>
|
||||
#include <LibWeb/HTML/Navigable.h>
|
||||
#include <LibWeb/HTML/NavigationObserver.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
JS_DEFINE_ALLOCATOR(NavigationObserver);
|
||||
|
||||
NavigationObserver::NavigationObserver(JS::Realm& realm, Navigable& navigable)
|
||||
: Bindings::PlatformObject(realm)
|
||||
, m_navigable(navigable)
|
||||
{
|
||||
m_navigable->register_navigation_observer({}, *this);
|
||||
}
|
||||
|
||||
void NavigationObserver::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_navigable);
|
||||
visitor.visit(m_navigation_complete);
|
||||
}
|
||||
|
||||
void NavigationObserver::finalize()
|
||||
{
|
||||
Base::finalize();
|
||||
m_navigable->unregister_navigation_observer({}, *this);
|
||||
}
|
||||
|
||||
void NavigationObserver::set_navigation_complete(Function<void()> callback)
|
||||
{
|
||||
if (callback)
|
||||
m_navigation_complete = JS::create_heap_function(vm().heap(), move(callback));
|
||||
else
|
||||
m_navigation_complete = nullptr;
|
||||
}
|
||||
|
||||
}
|
34
Userland/Libraries/LibWeb/HTML/NavigationObserver.h
Normal file
34
Userland/Libraries/LibWeb/HTML/NavigationObserver.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibJS/Heap/GCPtr.h>
|
||||
#include <LibJS/Heap/HeapFunction.h>
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
class NavigationObserver final : public Bindings::PlatformObject {
|
||||
WEB_PLATFORM_OBJECT(NavigationObserver, Bindings::PlatformObject);
|
||||
JS_DECLARE_ALLOCATOR(NavigationObserver);
|
||||
|
||||
public:
|
||||
[[nodiscard]] JS::GCPtr<JS::HeapFunction<void()>> navigation_complete() const { return m_navigation_complete; }
|
||||
void set_navigation_complete(Function<void()>);
|
||||
|
||||
private:
|
||||
NavigationObserver(JS::Realm&, Navigable&);
|
||||
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
virtual void finalize() override;
|
||||
|
||||
JS::NonnullGCPtr<Navigable> m_navigable;
|
||||
JS::GCPtr<JS::HeapFunction<void()>> m_navigation_complete;
|
||||
};
|
||||
|
||||
}
|
Loading…
Reference in a new issue