From 1bd73184da7bfd4f68ebe2cba16f572e6e465784 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Wed, 29 Jan 2025 16:56:55 +0000 Subject: [PATCH] LibWeb/HTML: Update get_an_elements_noopener() to current spec Note that this preemptively includes this fix to step 3: https://github.com/whatwg/html/pull/10962 --- Libraries/LibWeb/HTML/HTMLAnchorElement.h | 4 ++-- Libraries/LibWeb/HTML/HTMLAreaElement.h | 4 ++-- Libraries/LibWeb/HTML/HTMLElement.cpp | 20 ++++++++++++++++--- Libraries/LibWeb/HTML/HTMLElement.h | 2 +- Libraries/LibWeb/HTML/HTMLFormElement.cpp | 2 +- .../LibWeb/HTML/HTMLHyperlinkElementUtils.cpp | 2 +- .../LibWeb/HTML/HTMLHyperlinkElementUtils.h | 2 +- 7 files changed, 25 insertions(+), 11 deletions(-) diff --git a/Libraries/LibWeb/HTML/HTMLAnchorElement.h b/Libraries/LibWeb/HTML/HTMLAnchorElement.h index 08fccdef996..f781dfe08b8 100644 --- a/Libraries/LibWeb/HTML/HTMLAnchorElement.h +++ b/Libraries/LibWeb/HTML/HTMLAnchorElement.h @@ -65,9 +65,9 @@ private: { return get_an_elements_target(target); } - virtual TokenizedFeature::NoOpener hyperlink_element_utils_get_an_elements_noopener(StringView target) const override + virtual TokenizedFeature::NoOpener hyperlink_element_utils_get_an_elements_noopener(URL::URL const& url, StringView target) const override { - return get_an_elements_noopener(target); + return get_an_elements_noopener(url, target); } virtual Optional default_role() const override; diff --git a/Libraries/LibWeb/HTML/HTMLAreaElement.h b/Libraries/LibWeb/HTML/HTMLAreaElement.h index d7df7ed9806..0ac96cb03a9 100644 --- a/Libraries/LibWeb/HTML/HTMLAreaElement.h +++ b/Libraries/LibWeb/HTML/HTMLAreaElement.h @@ -48,9 +48,9 @@ private: { return get_an_elements_target(target); } - virtual TokenizedFeature::NoOpener hyperlink_element_utils_get_an_elements_noopener(StringView target) const override + virtual TokenizedFeature::NoOpener hyperlink_element_utils_get_an_elements_noopener(URL::URL const& url, StringView target) const override { - return get_an_elements_noopener(target); + return get_an_elements_noopener(url, target); } virtual Optional default_role() const override; diff --git a/Libraries/LibWeb/HTML/HTMLElement.cpp b/Libraries/LibWeb/HTML/HTMLElement.cpp index 3aef2904d07..6f90ba78b70 100644 --- a/Libraries/LibWeb/HTML/HTMLElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLElement.cpp @@ -930,9 +930,10 @@ String HTMLElement::get_an_elements_target(Optional target) const } // https://html.spec.whatwg.org/multipage/links.html#get-an-element's-noopener -TokenizedFeature::NoOpener HTMLElement::get_an_elements_noopener(StringView target) const +TokenizedFeature::NoOpener HTMLElement::get_an_elements_noopener(URL::URL const& url, StringView target) const { - // To get an element's noopener, given an a, area, or form element element and a string target: + // To get an element's noopener, given an a, area, or form element element, a URL record url, and a string target, + // perform the following steps. They return a boolean. auto rel = MUST(get_attribute_value(HTML::AttributeNames::rel).to_lowercase()); auto link_types = rel.bytes_as_string_view().split_view_if(Infra::is_ascii_whitespace); @@ -945,7 +946,20 @@ TokenizedFeature::NoOpener HTMLElement::get_an_elements_noopener(StringView targ if (!link_types.contains_slow("opener"sv) && Infra::is_ascii_case_insensitive_match(target, "_blank"sv)) return TokenizedFeature::NoOpener::Yes; - // 3. Return false. + // 3. If url's blob URL entry is not null: + if (url.blob_url_entry().has_value()) { + // 1. Let blobOrigin be url's blob URL entry's environment's origin. + auto const& blob_origin = url.blob_url_entry()->environment.origin; + + // 2. Let topLevelOrigin be element's relevant settings object's top-level origin. + auto const& top_level_origin = relevant_settings_object(*this).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; + } + + // 4. Return false. return TokenizedFeature::NoOpener::No; } diff --git a/Libraries/LibWeb/HTML/HTMLElement.h b/Libraries/LibWeb/HTML/HTMLElement.h index fa9f8994022..230bded54e2 100644 --- a/Libraries/LibWeb/HTML/HTMLElement.h +++ b/Libraries/LibWeb/HTML/HTMLElement.h @@ -117,7 +117,7 @@ public: virtual Optional default_role() const override; String get_an_elements_target(Optional target = {}) const; - TokenizedFeature::NoOpener get_an_elements_noopener(StringView target) const; + TokenizedFeature::NoOpener get_an_elements_noopener(URL::URL const& url, StringView target) const; WebIDL::ExceptionOr> attach_internals(); diff --git a/Libraries/LibWeb/HTML/HTMLFormElement.cpp b/Libraries/LibWeb/HTML/HTMLFormElement.cpp index 29a54fec7f9..fae2052a923 100644 --- a/Libraries/LibWeb/HTML/HTMLFormElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLFormElement.cpp @@ -250,7 +250,7 @@ WebIDL::ExceptionOr HTMLFormElement::submit_form(GC::Ref subm auto target = get_an_elements_target(form_target); // 21. Let noopener be the result of getting an element's noopener with form, parsed action, and target. - auto no_opener = get_an_elements_noopener(target); + auto no_opener = get_an_elements_noopener(*parsed_action, target); // 22. Let targetNavigable be the first return value of applying the rules for choosing a navigable given target, // form's node navigable, and noopener. diff --git a/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.cpp b/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.cpp index 06c2e023351..cd11f795b00 100644 --- a/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.cpp +++ b/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.cpp @@ -488,7 +488,7 @@ void HTMLHyperlinkElementUtils::follow_the_hyperlink(Optional hyperlink_ return; // 6. Let noopener be the result of getting an element's noopener with subject, urlRecord, and targetAttributeValue. - auto noopener = hyperlink_element_utils_get_an_elements_noopener(target_attribute_value); + auto noopener = hyperlink_element_utils_get_an_elements_noopener(*url_record, target_attribute_value); // 7. Let targetNavigable be the first return value of applying the rules for choosing a navigable given // targetAttributeValue, subject's node navigable, and noopener. diff --git a/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.h b/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.h index 52a24173a4a..fe728fa843c 100644 --- a/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.h +++ b/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.h @@ -59,7 +59,7 @@ protected: virtual bool hyperlink_element_utils_is_html_anchor_element() const = 0; virtual bool hyperlink_element_utils_is_connected() const = 0; virtual String hyperlink_element_utils_get_an_elements_target(Optional target = {}) const = 0; - virtual TokenizedFeature::NoOpener hyperlink_element_utils_get_an_elements_noopener(StringView target) const = 0; + virtual TokenizedFeature::NoOpener hyperlink_element_utils_get_an_elements_noopener(URL::URL const& url, StringView target) const = 0; virtual void hyperlink_element_utils_queue_an_element_task(HTML::Task::Source source, Function steps) = 0;