/* * Copyright (c) 2022, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include #include #ifdef AK_OS_MACOS # include #endif #ifdef USE_VULKAN # include #endif namespace Web::HTML { // https://html.spec.whatwg.org/multipage/document-sequences.html#traversable-navigable class TraversableNavigable final : public Navigable { GC_CELL(TraversableNavigable, Navigable); GC_DECLARE_ALLOCATOR(TraversableNavigable); public: static WebIDL::ExceptionOr> create_a_new_top_level_traversable(GC::Ref, GC::Ptr opener, String target_name); static WebIDL::ExceptionOr> create_a_fresh_top_level_traversable(GC::Ref, URL::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; enum class HistoryStepResult { InitiatorDisallowed, CanceledByBeforeUnload, CanceledByNavigate, Applied, }; HistoryStepResult apply_the_traverse_history_step(int, Optional, GC::Ptr, UserNavigationInvolvement); HistoryStepResult apply_the_reload_history_step(UserNavigationInvolvement); enum class SynchronousNavigation : bool { Yes, No, }; HistoryStepResult apply_the_push_or_replace_history_step(int step, HistoryHandlingBehavior history_handling, UserNavigationInvolvement, SynchronousNavigation); HistoryStepResult 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_navigables_that_only_need_history_object_length_index_update(int) const; Vector> get_all_navigables_that_might_experience_a_cross_document_traversal(int) const; Vector get_all_used_history_steps() const; void clear_the_forward_session_history(); void traverse_the_history_by_delta(int delta, Optional source_document = {}); void close_top_level_traversable(); void definitely_close_top_level_traversable(); void destroy_top_level_traversable(); void append_session_history_traversal_steps(GC::Ref> steps) { m_session_history_traversal_queue->append(steps); } void append_session_history_synchronous_navigation_steps(GC::Ref target_navigable, GC::Ref> steps) { m_session_history_traversal_queue->append_sync(steps, target_navigable); } String window_handle() const { return m_window_handle; } void set_window_handle(String window_handle) { m_window_handle = move(window_handle); } [[nodiscard]] GC::Ptr currently_focused_area(); void paint(Web::DevicePixelRect const&, Painting::BackingStore&, Web::PaintOptions); enum class CheckIfUnloadingIsCanceledResult { CanceledByBeforeUnload, CanceledByNavigate, Continue, }; CheckIfUnloadingIsCanceledResult check_if_unloading_is_canceled(Vector> navigables_that_need_before_unload); RefPtr skia_backend_context() const { return m_skia_backend_context; } StorageAPI::StorageShed& storage_shed() { return m_storage_shed; } StorageAPI::StorageShed const& storage_shed() const { return m_storage_shed; } private: TraversableNavigable(GC::Ref); virtual void visit_edges(Cell::Visitor&) override; // FIXME: Fix spec typo cancelation --> cancellation HistoryStepResult apply_the_history_step( int step, bool check_for_cancelation, Optional, GC::Ptr initiator_to_check, UserNavigationInvolvement user_involvement, Optional navigation_type, SynchronousNavigation); CheckIfUnloadingIsCanceledResult check_if_unloading_is_canceled(Vector> navigables_that_need_before_unload, GC::Ptr traversable, Optional target_step, Optional user_involvement_for_navigate_events); Vector> get_session_history_entries_for_the_navigation_api(GC::Ref, int); [[nodiscard]] bool can_go_forward() const; // 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::Hidden }; // https://storage.spec.whatwg.org/#traversable-navigable-storage-shed // A traversable navigable holds a storage shed, which is a storage shed. A traversable navigable’s storage shed holds all session storage data. StorageAPI::StorageShed m_storage_shed; GC::Ref m_session_history_traversal_queue; String m_window_handle; RefPtr m_skia_backend_context; #ifdef AK_OS_MACOS RefPtr m_metal_context; #endif }; struct BrowsingContextAndDocument { GC::Ref browsing_context; GC::Ref document; }; WebIDL::ExceptionOr create_a_new_top_level_browsing_context_and_document(GC::Ref page); void finalize_a_same_document_navigation(GC::Ref traversable, GC::Ref target_navigable, GC::Ref target_entry, GC::Ptr entry_to_replace, HistoryHandlingBehavior, UserNavigationInvolvement); }