mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-20 19:45:12 +00:00
LibWeb: Update "window open steps" to current spec
Corresponds to https://github.com/whatwg/html/pull/10683 As part of this, I noticed we incorrectly were setting the "is popup" flag on the Navigable instead of the BrowsingContext. I've fixed that and removed the erroneous flag from Navigable.
This commit is contained in:
parent
b83f015c70
commit
70c8535b8a
Notes:
github-actions[bot]
2024-11-30 11:23:36 +00:00
Author: https://github.com/AtkinsSJ Commit: https://github.com/LadybirdBrowser/ladybird/commit/70c8535b8a7 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2610 Reviewed-by: https://github.com/shannonbooth ✅
2 changed files with 49 additions and 31 deletions
|
@ -177,8 +177,6 @@ public:
|
|||
|
||||
void set_needs_display(InvalidateDisplayList = InvalidateDisplayList::Yes);
|
||||
|
||||
void set_is_popup(TokenizedFeature::Popup is_popup) { m_is_popup = is_popup; }
|
||||
|
||||
// https://html.spec.whatwg.org/#rendering-opportunity
|
||||
[[nodiscard]] bool has_a_rendering_opportunity() const;
|
||||
|
||||
|
@ -202,9 +200,6 @@ protected:
|
|||
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#ongoing-navigation
|
||||
Variant<Empty, Traversal, String> m_ongoing_navigation;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/browsers.html#is-popup
|
||||
TokenizedFeature::Popup m_is_popup { TokenizedFeature::Popup::No };
|
||||
|
||||
private:
|
||||
void reset_cursor_blink_cycle();
|
||||
|
||||
|
|
|
@ -146,14 +146,42 @@ WebIDL::ExceptionOr<GC::Ptr<WindowProxy>> Window::window_open_steps(StringView u
|
|||
if (target_navigable == nullptr)
|
||||
return nullptr;
|
||||
|
||||
// 14. If noopener is true or windowType is "new with no opener", then return null.
|
||||
// 17. If noopener is true or windowType is "new with no opener", then return null.
|
||||
if (no_opener == TokenizedFeature::NoOpener::Yes || window_type == Navigable::WindowType::NewWithNoOpener)
|
||||
return nullptr;
|
||||
|
||||
// 15. Return targetNavigable's active WindowProxy.
|
||||
// 18. Return targetNavigable's active WindowProxy.
|
||||
return target_navigable->active_window_proxy();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#get-noopener-for-window-open
|
||||
static TokenizedFeature::NoOpener get_noopener_for_window_open(DOM::Document const& source_document, TokenizedFeature::Map const& tokenized_features, URL::URL url)
|
||||
{
|
||||
// 1. If url's scheme is "blob":
|
||||
if (url.scheme() == "blob"sv) {
|
||||
// 1. Let blobOrigin be url's blob URL entry's environment's origin.
|
||||
auto blob_origin = url.blob_url_entry()->environment_origin;
|
||||
|
||||
// 2. Let topLevelOrigin be sourceDocument's relevant settings object's top-level origin.
|
||||
auto top_level_origin = source_document.relevant_settings_object().top_level_origin;
|
||||
|
||||
// 3. If blobOrigin is not same site with topLevelOrigin, then return true.
|
||||
if (!blob_origin.is_same_site(top_level_origin))
|
||||
return TokenizedFeature::NoOpener::Yes;
|
||||
}
|
||||
|
||||
// 2. Let noopener be false.
|
||||
auto noopener = TokenizedFeature::NoOpener::No;
|
||||
|
||||
// 3. If tokenizedFeatures["noopener"] exists, then set noopener to the result of parsing tokenizedFeatures["noopener"] as a boolean feature.
|
||||
if (auto value = tokenized_features.get("noopener"sv); value.has_value()) {
|
||||
noopener = parse_boolean_feature<TokenizedFeature::NoOpener>(*value);
|
||||
}
|
||||
|
||||
// 4. Return noopener.
|
||||
return noopener;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/window-object.html#window-open-steps
|
||||
WebIDL::ExceptionOr<Window::OpenedWindow> Window::window_open_steps_internal(StringView url, StringView target, StringView features)
|
||||
{
|
||||
|
@ -184,49 +212,43 @@ WebIDL::ExceptionOr<Window::OpenedWindow> Window::window_open_steps_internal(Str
|
|||
// 6. Let tokenizedFeatures be the result of tokenizing features.
|
||||
auto tokenized_features = tokenize_open_features(features);
|
||||
|
||||
// 7. Let noopener and noreferrer be false.
|
||||
auto no_opener = TokenizedFeature::NoOpener::No;
|
||||
// 7. Let noreferrer be false.
|
||||
auto no_referrer = TokenizedFeature::NoReferrer::No;
|
||||
|
||||
// 8. If tokenizedFeatures["noopener"] exists, then:
|
||||
if (auto no_opener_feature = tokenized_features.get("noopener"sv); no_opener_feature.has_value()) {
|
||||
// 1. Set noopener to the result of parsing tokenizedFeatures["noopener"] as a boolean feature.
|
||||
no_opener = parse_boolean_feature<TokenizedFeature::NoOpener>(*no_opener_feature);
|
||||
|
||||
// 2. Remove tokenizedFeatures["noopener"].
|
||||
tokenized_features.remove("noopener"sv);
|
||||
}
|
||||
|
||||
// 9. If tokenizedFeatures["noreferrer"] exists, then:
|
||||
// 8. If tokenizedFeatures["noreferrer"] exists, then set noreferrer to the result of parsing tokenizedFeatures["noreferrer"] as a boolean feature.
|
||||
if (auto no_referrer_feature = tokenized_features.get("noreferrer"sv); no_referrer_feature.has_value()) {
|
||||
// 1. Set noreferrer to the result of parsing tokenizedFeatures["noreferrer"] as a boolean feature.
|
||||
no_referrer = parse_boolean_feature<TokenizedFeature::NoReferrer>(*no_referrer_feature);
|
||||
|
||||
// 2. Remove tokenizedFeatures["noreferrer"].
|
||||
tokenized_features.remove("noreferrer"sv);
|
||||
}
|
||||
|
||||
// 10. Let referrerPolicy be the empty string.
|
||||
// 9. Let noopener be the result of getting noopener for window open with sourceDocument, tokenizedFeatures, and urlRecord.
|
||||
// FIXME: Is it safe to assume url_record has a value here?
|
||||
auto no_opener = get_noopener_for_window_open(source_document, tokenized_features, *url_record);
|
||||
|
||||
// 10. Remove tokenizedFeatures["noopener"] and tokenizedFeatures["noreferrer"].
|
||||
tokenized_features.remove("noopener"sv);
|
||||
tokenized_features.remove("noreferrer"sv);
|
||||
|
||||
// 11. Let referrerPolicy be the empty string.
|
||||
auto referrer_policy = ReferrerPolicy::ReferrerPolicy::EmptyString;
|
||||
|
||||
// 11. If noreferrer is true, then set noopener to true and set referrerPolicy to "no-referrer".
|
||||
// 12. If noreferrer is true, then set noopener to true and set referrerPolicy to "no-referrer".
|
||||
if (no_referrer == TokenizedFeature::NoReferrer::Yes) {
|
||||
no_opener = TokenizedFeature::NoOpener::Yes;
|
||||
referrer_policy = ReferrerPolicy::ReferrerPolicy::NoReferrer;
|
||||
}
|
||||
|
||||
// 12. Let targetNavigable and windowType be the result of applying the rules for choosing a navigable given target, sourceDocument's node navigable, and noopener.
|
||||
// 13. Let targetNavigable and windowType be the result of applying the rules for choosing a navigable given target, sourceDocument's node navigable, and noopener.
|
||||
VERIFY(source_document.navigable());
|
||||
auto [target_navigable, window_type] = source_document.navigable()->choose_a_navigable(target, no_opener, ActivateTab::Yes, tokenized_features);
|
||||
|
||||
// 13. If targetNavigable is null, then return null.
|
||||
// 14. If targetNavigable is null, then return null.
|
||||
if (target_navigable == nullptr)
|
||||
return OpenedWindow {};
|
||||
|
||||
// 14. If windowType is either "new and unrestricted" or "new with no opener", then:
|
||||
// 15. If windowType is either "new and unrestricted" or "new with no opener", then:
|
||||
if (window_type == Navigable::WindowType::NewAndUnrestricted || window_type == Navigable::WindowType::NewWithNoOpener) {
|
||||
// 1. Set the target browsing context's is popup to the result of checking if a popup window is requested, given tokenizedFeatures.
|
||||
target_navigable->set_is_popup(check_if_a_popup_window_is_requested(tokenized_features));
|
||||
// 1. Set targetNavigable's active browsing context's is popup to the result of checking if a popup window is requested, given tokenizedFeatures.
|
||||
target_navigable->active_browsing_context()->set_is_popup(check_if_a_popup_window_is_requested(tokenized_features));
|
||||
|
||||
// 2. Set up browsing context features for target browsing context given tokenizedFeatures. [CSSOMVIEW]
|
||||
// NOTE: This is implemented in choose_a_navigable when creating the top level traversable.
|
||||
|
@ -249,7 +271,7 @@ WebIDL::ExceptionOr<Window::OpenedWindow> Window::window_open_steps_internal(Str
|
|||
TRY(target_navigable->navigate({ .url = url_record.release_value(), .source_document = source_document, .exceptions_enabled = true, .referrer_policy = referrer_policy }));
|
||||
}
|
||||
}
|
||||
// 15. Otherwise:
|
||||
// 16. Otherwise:
|
||||
else {
|
||||
// 1. If urlRecord is not null, then navigate targetNavigable to urlRecord using sourceDocument, with referrerPolicy set to referrerPolicy and exceptionsEnabled set to true.
|
||||
if (url_record.has_value())
|
||||
|
@ -260,6 +282,7 @@ WebIDL::ExceptionOr<Window::OpenedWindow> Window::window_open_steps_internal(Str
|
|||
target_navigable->active_browsing_context()->set_opener_browsing_context(source_document.browsing_context());
|
||||
}
|
||||
|
||||
// NOTE: Steps 17 and 18 are implemented in window_open_steps().
|
||||
return OpenedWindow { target_navigable, no_opener, window_type };
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue