diff options
author | Timothy Flynn <trflynn89@pm.me> | 2023-03-21 06:52:29 -0400 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-03-22 00:12:53 +0100 |
commit | 1b811191cdbd5af69722b28cc068f94b67114e27 (patch) | |
tree | c874009adcf8c6aef835cd50bbca6fb92fd08090 | |
parent | 496b7ffb2b58043a80d90b8b8f44cab1eaa874e8 (diff) | |
download | serenity-1b811191cdbd5af69722b28cc068f94b67114e27.zip |
LibWeb+WebContent: Change the "noopener" storage type to a named enum
7 files changed, 65 insertions, 16 deletions
diff --git a/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp b/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp index 7a530bb46f..c6c7cc8ef2 100644 --- a/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp +++ b/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp @@ -615,7 +615,7 @@ JS::GCPtr<DOM::Node> BrowsingContext::currently_focused_area() } // https://html.spec.whatwg.org/#the-rules-for-choosing-a-browsing-context-given-a-browsing-context-name -BrowsingContext::ChosenBrowsingContext BrowsingContext::choose_a_browsing_context(StringView name, bool no_opener, ActivateTab activate_tab) +BrowsingContext::ChosenBrowsingContext BrowsingContext::choose_a_browsing_context(StringView name, TokenizedFeature::NoOpener no_opener, ActivateTab activate_tab) { // The rules for choosing a browsing context, given a browsing context name name, a browsing context current, and // a boolean noopener are as follows: @@ -691,14 +691,14 @@ BrowsingContext::ChosenBrowsingContext BrowsingContext::choose_a_browsing_contex // 2. If currentDocument's origin is not same origin with currentDocument's relevant settings object's // top-level origin, then set noopener to true, name to "_blank", and windowType to "new with no opener". if (!current_document->origin().is_same_origin(current_document->relevant_settings_object().top_level_origin)) { - no_opener = true; + no_opener = TokenizedFeature::NoOpener::Yes; name = "_blank"sv; window_type = WindowType::NewWithNoOpener; } } // 3. If noopener is true, then set chosen to the result of creating a new top-level browsing context. - if (no_opener) { + if (no_opener == TokenizedFeature::NoOpener::Yes) { auto handle = m_page->client().page_did_request_new_tab(activate_tab); chosen = RemoteBrowsingContext::create_a_new_remote_browsing_context(handle); } diff --git a/Userland/Libraries/LibWeb/HTML/BrowsingContext.h b/Userland/Libraries/LibWeb/HTML/BrowsingContext.h index dd58643135..f953dd45fb 100644 --- a/Userland/Libraries/LibWeb/HTML/BrowsingContext.h +++ b/Userland/Libraries/LibWeb/HTML/BrowsingContext.h @@ -22,6 +22,7 @@ #include <LibWeb/HTML/HistoryHandlingBehavior.h> #include <LibWeb/HTML/Origin.h> #include <LibWeb/HTML/SessionHistoryEntry.h> +#include <LibWeb/HTML/TokenizedFeatures.h> #include <LibWeb/HTML/VisibilityState.h> #include <LibWeb/Loader/FrameLoader.h> #include <LibWeb/Page/EventHandler.h> @@ -172,7 +173,7 @@ public: WindowType window_type; }; - ChosenBrowsingContext choose_a_browsing_context(StringView name, bool no_opener, ActivateTab = ActivateTab::Yes); + ChosenBrowsingContext choose_a_browsing_context(StringView name, TokenizedFeature::NoOpener no_opener, ActivateTab = ActivateTab::Yes); size_t document_tree_child_browsing_context_count() const; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.cpp b/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.cpp index 190e65812b..05c469db9e 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.cpp @@ -490,7 +490,7 @@ void HTMLHyperlinkElementUtils::follow_the_hyperlink(Optional<DeprecatedString> DeprecatedString target_attribute_value = get_an_elements_target(); // 6. Let noopener be the result of getting an element's noopener with subject and targetAttributeValue. - bool noopener = get_an_elements_noopener(target_attribute_value); + auto noopener = get_an_elements_noopener(target_attribute_value); // 7. Let target be the first return value of applying the rules for // choosing a browsing context given targetAttributeValue, source, and @@ -558,7 +558,7 @@ DeprecatedString HTMLHyperlinkElementUtils::get_an_elements_target() const } // https://html.spec.whatwg.org/multipage/links.html#get-an-element's-noopener -bool HTMLHyperlinkElementUtils::get_an_elements_noopener(StringView target) const +TokenizedFeature::NoOpener HTMLHyperlinkElementUtils::get_an_elements_noopener(StringView target) const { // To get an element's noopener, given an a, area, or form element element and a string target: auto rel = hyperlink_element_utils_rel().to_lowercase(); @@ -566,15 +566,15 @@ bool HTMLHyperlinkElementUtils::get_an_elements_noopener(StringView target) cons // 1. If element's link types include the noopener or noreferrer keyword, then return true. if (link_types.contains_slow("noopener"sv) || link_types.contains_slow("noreferrer"sv)) - return true; + return TokenizedFeature::NoOpener::Yes; // 2. If element's link types do not include the opener keyword and // target is an ASCII case-insensitive match for "_blank", then return true. if (!link_types.contains_slow("opener"sv) && Infra::is_ascii_case_insensitive_match(target, "_blank"sv)) - return true; + return TokenizedFeature::NoOpener::Yes; // 3. Return false. - return false; + return TokenizedFeature::NoOpener::No; } } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.h b/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.h index f11098c279..83388b3ac4 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.h @@ -9,6 +9,7 @@ #include <AK/URL.h> #include <LibWeb/Forward.h> #include <LibWeb/HTML/EventLoop/Task.h> +#include <LibWeb/HTML/TokenizedFeatures.h> namespace Web::HTML { @@ -66,7 +67,7 @@ private: void update_href(); bool cannot_navigate() const; DeprecatedString get_an_elements_target() const; - bool get_an_elements_noopener(StringView target) const; + TokenizedFeature::NoOpener get_an_elements_noopener(StringView target) const; Optional<AK::URL> m_url; }; diff --git a/Userland/Libraries/LibWeb/HTML/TokenizedFeatures.h b/Userland/Libraries/LibWeb/HTML/TokenizedFeatures.h new file mode 100644 index 0000000000..614e21a929 --- /dev/null +++ b/Userland/Libraries/LibWeb/HTML/TokenizedFeatures.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +namespace Web::HTML::TokenizedFeature { + +#define TOKENIZED_FEATURE(Feature) \ + enum class Feature { \ + Yes, \ + No, \ + } + +TOKENIZED_FEATURE(NoOpener); + +} diff --git a/Userland/Libraries/LibWeb/HTML/Window.cpp b/Userland/Libraries/LibWeb/HTML/Window.cpp index 9527cc8c5c..f4fc440378 100644 --- a/Userland/Libraries/LibWeb/HTML/Window.cpp +++ b/Userland/Libraries/LibWeb/HTML/Window.cpp @@ -43,6 +43,7 @@ #include <LibWeb/HTML/Scripting/Environments.h> #include <LibWeb/HTML/Scripting/ExceptionReporter.h> #include <LibWeb/HTML/Storage.h> +#include <LibWeb/HTML/TokenizedFeatures.h> #include <LibWeb/HTML/Window.h> #include <LibWeb/HTML/WindowProxy.h> #include <LibWeb/HighResolutionTime/Performance.h> @@ -223,6 +224,33 @@ static bool parse_boolean_feature(StringView value) return *parsed != 0; } +// https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-window-open-features-parse-boolean +template<Enum T> +static T parse_boolean_feature(StringView value) +{ + // 1. If value is the empty string, then return true. + if (value.is_empty()) + return T::Yes; + + // 2. If value is "yes", then return true. + if (value == "yes"sv) + return T::Yes; + + // 3. If value is "true", then return true. + if (value == "true"sv) + return T::Yes; + + // 4. Let parsed be the result of parsing value as an integer. + auto parsed = value.to_int<i64>(); + + // 5. If parsed is an error, then set it to 0. + if (!parsed.has_value()) + parsed = 0; + + // 6. Return false if parsed is 0, and true otherwise. + return parsed == 0 ? T::No : T::Yes; +} + // https://html.spec.whatwg.org/multipage/window-object.html#popup-window-is-requested static bool check_if_a_popup_window_is_requested(OrderedHashMap<DeprecatedString, DeprecatedString> const& tokenized_features) { @@ -307,13 +335,13 @@ WebIDL::ExceptionOr<JS::GCPtr<WindowProxy>> Window::open_impl(StringView url, St auto tokenized_features = tokenize_open_features(features); // 5. Let noopener and noreferrer be false. - auto no_opener = false; + auto no_opener = TokenizedFeature::NoOpener::No; auto no_referrer = false; // 6. 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(*no_opener_feature); + no_opener = parse_boolean_feature<TokenizedFeature::NoOpener>(*no_opener_feature); // 2. Remove tokenizedFeatures["noopener"]. tokenized_features.remove("noopener"sv); @@ -330,7 +358,7 @@ WebIDL::ExceptionOr<JS::GCPtr<WindowProxy>> Window::open_impl(StringView url, St // 8. If noreferrer is true, then set noopener to true. if (no_referrer) - no_opener = true; + no_opener = TokenizedFeature::NoOpener::Yes; // 9. Let target browsing context and windowType be the result of applying the rules for choosing a browsing context given target, source browsing context, and noopener. auto [target_browsing_context, window_type] = source_browsing_context->choose_a_browsing_context(target, no_opener); @@ -399,12 +427,12 @@ WebIDL::ExceptionOr<JS::GCPtr<WindowProxy>> Window::open_impl(StringView url, St } // 2. If noopener is false, then set target browsing context's opener browsing context to source browsing context. - if (!no_opener) + if (no_opener == TokenizedFeature::NoOpener::No) target_browsing_context->set_opener_browsing_context(source_browsing_context); } // 13. If noopener is true or windowType is "new with no opener", then return null. - if (no_opener || window_type == BrowsingContext::WindowType::NewWithNoOpener) + if (no_opener == TokenizedFeature::NoOpener::Yes || window_type == BrowsingContext::WindowType::NewWithNoOpener) return nullptr; // 14. Return target browsing context's WindowProxy object. diff --git a/Userland/Services/WebContent/WebDriverConnection.cpp b/Userland/Services/WebContent/WebDriverConnection.cpp index e0a7c707ea..5fbc118deb 100644 --- a/Userland/Services/WebContent/WebDriverConnection.cpp +++ b/Userland/Services/WebContent/WebDriverConnection.cpp @@ -577,7 +577,7 @@ Messages::WebDriverClient::NewWindowResponse WebDriverConnection::new_window(Jso // created browsing context should be in a new OS window. In all other cases the details of how the browsing // context is presented to the user are implementation defined. // FIXME: Reuse code of window.open() instead of calling choose_a_browsing_context - auto [browsing_context, window_type] = m_page_client.page().top_level_browsing_context().choose_a_browsing_context("_blank"sv, true, Web::HTML::ActivateTab::No); + auto [browsing_context, window_type] = m_page_client.page().top_level_browsing_context().choose_a_browsing_context("_blank"sv, Web::HTML::TokenizedFeature::NoOpener::Yes, Web::HTML::ActivateTab::No); // 6. Let handle be the associated window handle of the newly created window. auto handle = browsing_context->window_handle(); |