LibWeb/HTML: Update "is script closable" to current spec

Corresponds to d7fc63a84a
and 7a48703e77
This commit is contained in:
Sam Atkins 2025-05-03 13:49:38 +01:00
commit a8529629e2
Notes: github-actions[bot] 2025-05-08 09:40:30 +00:00
2 changed files with 22 additions and 18 deletions

View file

@ -150,16 +150,14 @@ void Navigable::NavigateParams::visit_edges(Cell::Visitor& visitor)
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#script-closable // https://html.spec.whatwg.org/multipage/nav-history-apis.html#script-closable
bool Navigable::is_script_closable() bool Navigable::is_script_closable()
{ {
// A navigable is script-closable if its active browsing context is an auxiliary browsing context that was created // A navigable is script-closable if it is a top-level traversable, and any of the following are true:
// by a script (as opposed to by an action of the user), or if it is a top-level traversable whose session history // - its is created by web content is true; or
// entries's size is 1. // - its session history entries's size is 1.
if (auto browsing_context = active_browsing_context(); browsing_context && browsing_context->is_auxiliary()) if (!is_top_level_traversable())
return true; return false;
if (is_top_level_traversable()) return as<TraversableNavigable>(this)->is_created_by_web_content()
return get_session_history_entries().size() == 1; || get_session_history_entries().size() == 1;
return false;
} }
void Navigable::set_delaying_load_events(bool value) void Navigable::set_delaying_load_events(bool value)
@ -381,7 +379,7 @@ Navigable::ChosenNavigable Navigable::choose_a_navigable(StringView name, Tokeni
// 2. Let windowType be "existing or none". // 2. Let windowType be "existing or none".
auto window_type = WindowType::ExistingOrNone; auto window_type = WindowType::ExistingOrNone;
// 3. Let sandboxingFlagSet be current's active document's active sandboxing flag set. // 3. Let sandboxingFlagSet be currentNavigable's active document's active sandboxing flag set.
auto sandboxing_flag_set = active_document()->active_sandboxing_flag_set(); auto sandboxing_flag_set = active_document()->active_sandboxing_flag_set();
// 4. If name is the empty string or an ASCII case-insensitive match for "_self", then set chosen to currentNavigable. // 4. If name is the empty string or an ASCII case-insensitive match for "_self", then set chosen to currentNavigable.
@ -455,13 +453,10 @@ Navigable::ChosenNavigable Navigable::choose_a_navigable(StringView name, Tokeni
// NOTE: In the presence of an opener policy, // NOTE: In the presence of an opener policy,
// nested documents that are cross-origin with their top-level browsing context's active document always set noopener to true. // nested documents that are cross-origin with their top-level browsing context's active document always set noopener to true.
// 5. Let chosen be null. // 5. Let targetName be the empty string.
chosen = nullptr;
// 6. Let targetName be the empty string.
String target_name; String target_name;
// 7. If name is not an ASCII case-insensitive match for "_blank", then set targetName to name. // 6. If name is not an ASCII case-insensitive match for "_blank", then set targetName to name.
if (!Infra::is_ascii_case_insensitive_match(name, "_blank"sv)) if (!Infra::is_ascii_case_insensitive_match(name, "_blank"sv))
target_name = MUST(String::from_utf8(name)); target_name = MUST(String::from_utf8(name));
@ -475,12 +470,12 @@ Navigable::ChosenNavigable Navigable::choose_a_navigable(StringView name, Tokeni
}; };
auto create_new_traversable = GC::create_function(heap(), move(create_new_traversable_closure)); auto create_new_traversable = GC::create_function(heap(), move(create_new_traversable_closure));
// 8. If noopener is true, then set chosen to the result of creating a new top-level traversable given null and targetName. // 7. If noopener is true, then set chosen to the result of creating a new top-level traversable given null and targetName.
if (no_opener == TokenizedFeature::NoOpener::Yes) { if (no_opener == TokenizedFeature::NoOpener::Yes) {
chosen = create_new_traversable->function()(nullptr); chosen = create_new_traversable->function()(nullptr);
} }
// 9. Otherwise: // 8. Otherwise:
else { else {
// 1. Set chosen to the result of creating a new top-level traversable given currentNavigable's active browsing context, targetName, and currentNavigable. // 1. Set chosen to the result of creating a new top-level traversable given currentNavigable's active browsing context, targetName, and currentNavigable.
// FIXME: "and currentNavigable", which is the openerNavigableForWebDriver parameter. // FIXME: "and currentNavigable", which is the openerNavigableForWebDriver parameter.
@ -492,10 +487,13 @@ Navigable::ChosenNavigable Navigable::choose_a_navigable(StringView name, Tokeni
chosen->active_browsing_context()->set_the_one_permitted_sandboxed_navigator(active_browsing_context()); chosen->active_browsing_context()->set_the_one_permitted_sandboxed_navigator(active_browsing_context());
} }
// 10. If sandboxingFlagSet's sandbox propagates to auxiliary browsing contexts flag is set, // 9. If sandboxingFlagSet's sandbox propagates to auxiliary browsing contexts flag is set,
// then all the flags that are set in sandboxingFlagSet must be set in chosen's active browsing context's popup sandboxing flag set. // then all the flags that are set in sandboxingFlagSet must be set in chosen's active browsing context's popup sandboxing flag set.
if (has_flag(sandboxing_flag_set, SandboxingFlagSet::SandboxPropagatesToAuxiliaryBrowsingContexts)) if (has_flag(sandboxing_flag_set, SandboxingFlagSet::SandboxPropagatesToAuxiliaryBrowsingContexts))
chosen->active_browsing_context()->set_popup_sandboxing_flag_set(chosen->active_browsing_context()->popup_sandboxing_flag_set() | sandboxing_flag_set); chosen->active_browsing_context()->set_popup_sandboxing_flag_set(chosen->active_browsing_context()->popup_sandboxing_flag_set() | sandboxing_flag_set);
// 10. Set chosen's is created by web content to true.
as<TraversableNavigable>(*chosen).set_is_created_by_web_content(true);
} }
// --> If the user agent has been configured such that in this instance it will choose currentNavigable // --> If the user agent has been configured such that in this instance it will choose currentNavigable

View file

@ -47,6 +47,9 @@ public:
VisibilityState system_visibility_state() const { return m_system_visibility_state; } VisibilityState system_visibility_state() const { return m_system_visibility_state; }
void set_system_visibility_state(VisibilityState); void set_system_visibility_state(VisibilityState);
bool is_created_by_web_content() const { return m_is_created_by_web_content; }
void set_is_created_by_web_content(bool value) { m_is_created_by_web_content = value; }
struct HistoryObjectLengthAndIndex { struct HistoryObjectLengthAndIndex {
u64 script_history_length; u64 script_history_length;
u64 script_history_index; u64 script_history_index;
@ -156,6 +159,9 @@ private:
// https://html.spec.whatwg.org/multipage/document-sequences.html#system-visibility-state // https://html.spec.whatwg.org/multipage/document-sequences.html#system-visibility-state
VisibilityState m_system_visibility_state { VisibilityState::Hidden }; VisibilityState m_system_visibility_state { VisibilityState::Hidden };
// https://html.spec.whatwg.org/multipage/document-sequences.html#is-created-by-web-content
bool m_is_created_by_web_content { false };
// https://storage.spec.whatwg.org/#traversable-navigable-storage-shed // https://storage.spec.whatwg.org/#traversable-navigable-storage-shed
// A traversable navigable holds a storage shed, which is a storage shed. A traversable navigables storage shed holds all session storage data. // A traversable navigable holds a storage shed, which is a storage shed. A traversable navigables storage shed holds all session storage data.
StorageAPI::StorageShed m_storage_shed; StorageAPI::StorageShed m_storage_shed;