/* * Copyright (c) 2022, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include namespace Web::HTML { // https://html.spec.whatwg.org/multipage/document-sequences.html#traversable-navigable class TraversableNavigable final : public Navigable { JS_CELL(TraversableNavigable, Navigable); JS_DECLARE_ALLOCATOR(TraversableNavigable); public: static WebIDL::ExceptionOr> create_a_new_top_level_traversable(JS::NonnullGCPtr, JS::GCPtr opener, String target_name); static WebIDL::ExceptionOr> create_a_fresh_top_level_traversable(JS::NonnullGCPtr, AK::URL const& initial_navigation_url, Variant = Empty {}); virtual ~TraversableNavigable() override; virtual bool is_top_level_traversable() const override; int current_session_history_step() const { return m_current_session_history_step; } Vector>& session_history_entries() { return m_session_history_entries; } Vector> const& session_history_entries() const { return m_session_history_entries; } bool running_nested_apply_history_step() const { return m_running_nested_apply_history_step; } VisibilityState system_visibility_state() const { return m_system_visibility_state; } void set_system_visibility_state(VisibilityState); struct HistoryObjectLengthAndIndex { u64 script_history_length; u64 script_history_index; }; HistoryObjectLengthAndIndex get_the_history_object_length_and_index(int) const; void apply_the_reload_history_step(); void apply_the_push_or_replace_history_step(int step); void update_for_navigable_creation_or_destruction(); int get_the_used_step(int step) const; Vector> get_all_navigables_whose_current_session_history_entry_will_change_or_reload(int) const; Vector get_all_used_history_steps() const; void clear_the_forward_session_history(); void traverse_the_history_by_delta(int delta); void close_top_level_traversable(); void destroy_top_level_traversable(); void append_session_history_traversal_steps(JS::SafeFunction steps) { m_session_history_traversal_queue.append(move(steps)); } void process_session_history_traversal_queue() { m_session_history_traversal_queue.process(); } Page& page() { return m_page; } Page const& page() const { return m_page; } private: TraversableNavigable(JS::NonnullGCPtr); virtual void visit_edges(Cell::Visitor&) override; void apply_the_history_step(int step, Optional = {}); Vector> get_session_history_entries_for_the_navigation_api(JS::NonnullGCPtr, int); // https://html.spec.whatwg.org/multipage/document-sequences.html#tn-current-session-history-step int m_current_session_history_step { 0 }; // https://html.spec.whatwg.org/multipage/document-sequences.html#tn-session-history-entries Vector> m_session_history_entries; // FIXME: https://html.spec.whatwg.org/multipage/document-sequences.html#tn-session-history-traversal-queue // https://html.spec.whatwg.org/multipage/document-sequences.html#tn-running-nested-apply-history-step bool m_running_nested_apply_history_step { false }; // https://html.spec.whatwg.org/multipage/document-sequences.html#system-visibility-state VisibilityState m_system_visibility_state { VisibilityState::Visible }; SessionHistoryTraversalQueue m_session_history_traversal_queue; JS::NonnullGCPtr m_page; }; struct BrowsingContextAndDocument { JS::NonnullGCPtr browsing_context; JS::NonnullGCPtr document; }; WebIDL::ExceptionOr create_a_new_top_level_browsing_context_and_document(JS::NonnullGCPtr page); void finalize_a_same_document_navigation(JS::NonnullGCPtr traversable, JS::NonnullGCPtr target_navigable, JS::NonnullGCPtr target_entry, JS::GCPtr entry_to_replace); }