diff --git a/Libraries/LibWeb/HTML/HTMLFrameElement.cpp b/Libraries/LibWeb/HTML/HTMLFrameElement.cpp index 45a5aac519b..e171b199e7b 100644 --- a/Libraries/LibWeb/HTML/HTMLFrameElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLFrameElement.cpp @@ -51,7 +51,7 @@ void HTMLFrameElement::inserted() // 3. Create a new child navigable for insertedNode. MUST(create_new_child_navigable(GC::create_function(realm().heap(), [this] { // 4. Process the frame attributes for insertedNode, with initialInsertion set to true. - process_the_frame_attributes(true); + process_the_frame_attributes(InitialInsertion::Yes); set_content_navigable_has_session_history_entry_and_ready_for_navigation(); }))); } @@ -91,7 +91,7 @@ void HTMLFrameElement::adjust_computed_style(CSS::ComputedProperties& style) } // https://html.spec.whatwg.org/multipage/obsolete.html#process-the-frame-attributes -void HTMLFrameElement::process_the_frame_attributes(bool initial_insertion) +void HTMLFrameElement::process_the_frame_attributes(InitialInsertion initial_insertion) { // 1. Let url be the result of running the shared attribute processing steps for iframe and frame elements given // element and initialInsertion. @@ -102,7 +102,7 @@ void HTMLFrameElement::process_the_frame_attributes(bool initial_insertion) return; // 3. If url matches about:blank and initialInsertion is true, then: - if (url_matches_about_blank(*url) && initial_insertion) { + if (url_matches_about_blank(*url) && initial_insertion == InitialInsertion::Yes) { // 1. Fire an event named load at element. dispatch_event(DOM::Event::create(realm(), HTML::EventNames::load)); @@ -110,8 +110,8 @@ void HTMLFrameElement::process_the_frame_attributes(bool initial_insertion) return; } - // 3. Navigate an iframe or frame given element, url, and the empty string. - navigate_an_iframe_or_frame(*url, ReferrerPolicy::ReferrerPolicy::EmptyString); + // 3. Navigate an iframe or frame given element, url, the empty string, and initialInsertion. + navigate_an_iframe_or_frame(*url, ReferrerPolicy::ReferrerPolicy::EmptyString, {}, initial_insertion); } } diff --git a/Libraries/LibWeb/HTML/HTMLFrameElement.h b/Libraries/LibWeb/HTML/HTMLFrameElement.h index 0708e0a9e2a..e4328795608 100644 --- a/Libraries/LibWeb/HTML/HTMLFrameElement.h +++ b/Libraries/LibWeb/HTML/HTMLFrameElement.h @@ -30,7 +30,7 @@ private: virtual i32 default_tab_index_value() const override; virtual void adjust_computed_style(CSS::ComputedProperties&) override; - void process_the_frame_attributes(bool initial_insertion = false); + void process_the_frame_attributes(InitialInsertion = InitialInsertion::No); }; } diff --git a/Libraries/LibWeb/HTML/HTMLIFrameElement.cpp b/Libraries/LibWeb/HTML/HTMLIFrameElement.cpp index a9cbc1ca59d..1a8a7743fb2 100644 --- a/Libraries/LibWeb/HTML/HTMLIFrameElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLIFrameElement.cpp @@ -93,7 +93,7 @@ void HTMLIFrameElement::post_connection() // value and insertedNode's iframe sandboxing flag set. // 3. Process the iframe attributes for insertedNode, with initialInsertion set to true. - process_the_iframe_attributes(true); + process_the_iframe_attributes(InitialInsertion::Yes); if (auto navigable = content_navigable()) { auto traversable = navigable->traversable_navigable(); @@ -105,7 +105,7 @@ void HTMLIFrameElement::post_connection() } // https://html.spec.whatwg.org/multipage/iframe-embed-object.html#process-the-iframe-attributes -void HTMLIFrameElement::process_the_iframe_attributes(bool initial_insertion) +void HTMLIFrameElement::process_the_iframe_attributes(InitialInsertion initial_insertion) { if (!content_navigable()) return; @@ -152,7 +152,7 @@ void HTMLIFrameElement::process_the_iframe_attributes(bool initial_insertion) } // 3. If url matches about:blank and initialInsertion is true, then: - if (url_matches_about_blank(*url) && initial_insertion) { + if (url_matches_about_blank(*url) && initial_insertion == InitialInsertion::Yes) { // 1. Run the iframe load event steps given element. run_iframe_load_event_steps(*this); diff --git a/Libraries/LibWeb/HTML/HTMLIFrameElement.h b/Libraries/LibWeb/HTML/HTMLIFrameElement.h index f51c811e4ed..d773ecef84a 100644 --- a/Libraries/LibWeb/HTML/HTMLIFrameElement.h +++ b/Libraries/LibWeb/HTML/HTMLIFrameElement.h @@ -55,7 +55,7 @@ private: virtual bool supports_dimension_attributes() const override { return true; } // https://html.spec.whatwg.org/multipage/iframe-embed-object.html#process-the-iframe-attributes - void process_the_iframe_attributes(bool initial_insertion = false); + void process_the_iframe_attributes(InitialInsertion = InitialInsertion::No); // https://html.spec.whatwg.org/multipage/iframe-embed-object.html#current-navigation-was-lazy-loaded bool m_current_navigation_was_lazy_loaded { false }; diff --git a/Libraries/LibWeb/HTML/Navigable.cpp b/Libraries/LibWeb/HTML/Navigable.cpp index 65c4870050c..4901648888f 100644 --- a/Libraries/LibWeb/HTML/Navigable.cpp +++ b/Libraries/LibWeb/HTML/Navigable.cpp @@ -1453,7 +1453,8 @@ WebIDL::ExceptionOr Navigable::navigate(NavigateParams params) // an optional entry list or null formDataEntryList (default null), // an optional referrer policy referrerPolicy (default the empty string), // an optional user navigation involvement userInvolvement (default "none"), -// and an optional Element sourceElement (default null): +// an optional Element sourceElement (default null), +// and an optional boolean initialInsertion (default false): // https://html.spec.whatwg.org/multipage/browsing-the-web.html#navigate void Navigable::begin_navigation(NavigateParams params) @@ -1472,6 +1473,7 @@ void Navigable::begin_navigation(NavigateParams params) auto referrer_policy = params.referrer_policy; auto user_involvement = params.user_involvement; auto source_element = params.source_element; + auto initial_insertion = params.initial_insertion; auto& active_document = *this->active_document(); auto& vm = this->vm(); @@ -1575,10 +1577,10 @@ void Navigable::begin_navigation(NavigateParams params) // 19. If url's scheme is "javascript", then: if (url.scheme() == "javascript"sv) { - // 1. Queue a global task on the navigation and traversal task source given navigable's active window to navigate to a javascript: URL given navigable, url, historyHandling, sourceSnapshotParams, initiatorOriginSnapshot, userInvolvement, and cspNavigationType. + // 1. Queue a global task on the navigation and traversal task source given navigable's active window to navigate to a javascript: URL given navigable, url, historyHandling, sourceSnapshotParams, initiatorOriginSnapshot, userInvolvement, cspNavigationType, and initialInsertion. VERIFY(active_window()); - queue_global_task(Task::Source::NavigationAndTraversal, *active_window(), GC::create_function(heap(), [this, url, history_handling, source_snapshot_params, initiator_origin_snapshot, user_involvement, csp_navigation_type, navigation_id] { - navigate_to_a_javascript_url(url, to_history_handling_behavior(history_handling), source_snapshot_params, initiator_origin_snapshot, user_involvement, csp_navigation_type, navigation_id); + queue_global_task(Task::Source::NavigationAndTraversal, *active_window(), GC::create_function(heap(), [this, url, history_handling, source_snapshot_params, initiator_origin_snapshot, user_involvement, csp_navigation_type, initial_insertion, navigation_id] { + navigate_to_a_javascript_url(url, to_history_handling_behavior(history_handling), source_snapshot_params, initiator_origin_snapshot, user_involvement, csp_navigation_type, initial_insertion, navigation_id); })); // 2. Return. @@ -1921,7 +1923,7 @@ GC::Ptr Navigable::evaluate_javascript_url(URL::URL const& url, U } // https://html.spec.whatwg.org/multipage/browsing-the-web.html#navigate-to-a-javascript:-url -void Navigable::navigate_to_a_javascript_url(URL::URL const& url, HistoryHandlingBehavior history_handling, GC::Ref source_snapshot_params, URL::Origin const& initiator_origin, UserNavigationInvolvement user_involvement, ContentSecurityPolicy::Directives::Directive::NavigationType csp_navigation_type, String navigation_id) +void Navigable::navigate_to_a_javascript_url(URL::URL const& url, HistoryHandlingBehavior history_handling, GC::Ref source_snapshot_params, URL::Origin const& initiator_origin, UserNavigationInvolvement user_involvement, ContentSecurityPolicy::Directives::Directive::NavigationType csp_navigation_type, InitialInsertion initial_insertion, String navigation_id) { auto& vm = this->vm(); @@ -1947,8 +1949,15 @@ void Navigable::navigate_to_a_javascript_url(URL::URL const& url, HistoryHandlin // 6. Let newDocument be the result of evaluating a javascript: URL given targetNavigable, url, initiatorOrigin, and userInvolvement. auto new_document = evaluate_javascript_url(url, initiator_origin, user_involvement, navigation_id); - // 7. If newDocument is null, then return. + // 7. If newDocument is null: if (!new_document) { + // 1. If initialInsertion is true and targetNavigable's active document's is initial about:blank is true, + // then run the iframe load event steps given targetNavigable's container. + if (initial_insertion == InitialInsertion::Yes && active_document()->is_initial_about_blank()) { + run_iframe_load_event_steps(as(*container())); + } + + // 2. Return. // NOTE: In this case, some JavaScript code was executed, but no new Document was created, so we will not perform a navigation. return; } diff --git a/Libraries/LibWeb/HTML/Navigable.h b/Libraries/LibWeb/HTML/Navigable.h index 0ed73282546..0a1bcdc15c6 100644 --- a/Libraries/LibWeb/HTML/Navigable.h +++ b/Libraries/LibWeb/HTML/Navigable.h @@ -28,6 +28,11 @@ namespace Web::HTML { +enum class InitialInsertion : u8 { + Yes, + No, +}; + // https://html.spec.whatwg.org/multipage/browsing-the-web.html#target-snapshot-params struct TargetSnapshotParams { SandboxingFlagSet sandboxing_flags {}; @@ -142,6 +147,7 @@ public: ReferrerPolicy::ReferrerPolicy referrer_policy = ReferrerPolicy::ReferrerPolicy::EmptyString; UserNavigationInvolvement user_involvement = UserNavigationInvolvement::None; GC::Ptr source_element = nullptr; + InitialInsertion initial_insertion = InitialInsertion::No; void visit_edges(Cell::Visitor& visitor); }; @@ -205,7 +211,7 @@ protected: private: void begin_navigation(NavigateParams); void navigate_to_a_fragment(URL::URL const&, HistoryHandlingBehavior, UserNavigationInvolvement, GC::Ptr source_element, Optional navigation_api_state, String navigation_id); - void navigate_to_a_javascript_url(URL::URL const&, HistoryHandlingBehavior, GC::Ref, URL::Origin const& initiator_origin, UserNavigationInvolvement, ContentSecurityPolicy::Directives::Directive::NavigationType csp_navigation_type, String navigation_id); + void navigate_to_a_javascript_url(URL::URL const&, HistoryHandlingBehavior, GC::Ref, URL::Origin const& initiator_origin, UserNavigationInvolvement, ContentSecurityPolicy::Directives::Directive::NavigationType csp_navigation_type, InitialInsertion, String navigation_id); void reset_cursor_blink_cycle(); diff --git a/Libraries/LibWeb/HTML/NavigableContainer.cpp b/Libraries/LibWeb/HTML/NavigableContainer.cpp index ae6eefdaab8..ef55557df12 100644 --- a/Libraries/LibWeb/HTML/NavigableContainer.cpp +++ b/Libraries/LibWeb/HTML/NavigableContainer.cpp @@ -195,14 +195,14 @@ HTML::WindowProxy* NavigableContainer::content_window() } // https://html.spec.whatwg.org/multipage/iframe-embed-object.html#shared-attribute-processing-steps-for-iframe-and-frame-elements -Optional NavigableContainer::shared_attribute_processing_steps_for_iframe_and_frame(bool initial_insertion) +Optional NavigableContainer::shared_attribute_processing_steps_for_iframe_and_frame(InitialInsertion initial_insertion) { // AD-HOC: If the element was added and immediately removed, the content navigable will be null. Don't process the // src attribute any further. if (!m_content_navigable) return {}; - if (initial_insertion && m_content_navigable->has_pending_navigations()) { + if (initial_insertion == InitialInsertion::Yes && m_content_navigable->has_pending_navigations()) { return {}; } @@ -228,7 +228,7 @@ Optional NavigableContainer::shared_attribute_processing_steps_for_ifr } // 4. If url matches about:blank and initialInsertion is true, then perform the URL and history update steps given element's content navigable's active document and url. - if (url_matches_about_blank(url) && initial_insertion) { + if (url_matches_about_blank(url) && initial_insertion == InitialInsertion::Yes) { auto& document = *m_content_navigable->active_document(); perform_url_and_history_update_steps(document, url); } @@ -238,7 +238,7 @@ Optional NavigableContainer::shared_attribute_processing_steps_for_ifr } // https://html.spec.whatwg.org/multipage/iframe-embed-object.html#navigate-an-iframe-or-frame -void NavigableContainer::navigate_an_iframe_or_frame(URL::URL url, ReferrerPolicy::ReferrerPolicy referrer_policy, Optional srcdoc_string) +void NavigableContainer::navigate_an_iframe_or_frame(URL::URL url, ReferrerPolicy::ReferrerPolicy referrer_policy, Optional srcdoc_string, InitialInsertion initial_insertion) { // 1. Let historyHandling be "auto". auto history_handling = Bindings::NavigationHistoryBehavior::Auto; @@ -252,7 +252,8 @@ void NavigableContainer::navigate_an_iframe_or_frame(URL::URL url, ReferrerPolic // time given element's node document's relevant global object. // 4. Navigate element's content navigable to url using element's node document, with historyHandling set to historyHandling, - // referrerPolicy set to referrerPolicy, and documentResource set to scrdocString. + // referrerPolicy set to referrerPolicy, documentResource set to srcdocString, and initialInsertion set to + // initialInsertion. Variant document_resource = Empty {}; if (srcdoc_string.has_value()) document_resource = srcdoc_string.value(); @@ -263,6 +264,7 @@ void NavigableContainer::navigate_an_iframe_or_frame(URL::URL url, ReferrerPolic .document_resource = document_resource, .history_handling = history_handling, .referrer_policy = referrer_policy, + .initial_insertion = initial_insertion, })); } diff --git a/Libraries/LibWeb/HTML/NavigableContainer.h b/Libraries/LibWeb/HTML/NavigableContainer.h index 5a39f16e3cd..95da4af5a2a 100644 --- a/Libraries/LibWeb/HTML/NavigableContainer.h +++ b/Libraries/LibWeb/HTML/NavigableContainer.h @@ -51,10 +51,10 @@ protected: virtual void visit_edges(Cell::Visitor&) override; // https://html.spec.whatwg.org/multipage/iframe-embed-object.html#shared-attribute-processing-steps-for-iframe-and-frame-elements - Optional shared_attribute_processing_steps_for_iframe_and_frame(bool initial_insertion); + Optional shared_attribute_processing_steps_for_iframe_and_frame(InitialInsertion initial_insertion); // https://html.spec.whatwg.org/multipage/iframe-embed-object.html#navigate-an-iframe-or-frame - void navigate_an_iframe_or_frame(URL::URL url, ReferrerPolicy::ReferrerPolicy referrer_policy, Optional srcdoc_string = {}); + void navigate_an_iframe_or_frame(URL::URL url, ReferrerPolicy::ReferrerPolicy referrer_policy, Optional srcdoc_string = {}, InitialInsertion = InitialInsertion::No); WebIDL::ExceptionOr create_new_child_navigable(GC::Ptr> after_session_history_update = {});