diff --git a/Userland/Libraries/LibWeb/HTML/HTMLAnchorElement.h b/Userland/Libraries/LibWeb/HTML/HTMLAnchorElement.h index 5df9eaf1dd..a5f9218eab 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLAnchorElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLAnchorElement.h @@ -52,12 +52,18 @@ private: virtual WebIDL::ExceptionOr set_hyperlink_element_utils_href(DeprecatedString) override; virtual bool hyperlink_element_utils_is_html_anchor_element() const final { return true; } virtual bool hyperlink_element_utils_is_connected() const final { return is_connected(); } - virtual DeprecatedString hyperlink_element_utils_target() const final { return target(); } - virtual DeprecatedString hyperlink_element_utils_rel() const final { return rel(); } virtual void hyperlink_element_utils_queue_an_element_task(HTML::Task::Source source, Function steps) override { queue_an_element_task(source, move(steps)); } + virtual DeprecatedString hyperlink_element_utils_get_an_elements_target() const override + { + return get_an_elements_target(); + } + virtual TokenizedFeature::NoOpener hyperlink_element_utils_get_an_elements_noopener(StringView target) const override + { + return get_an_elements_noopener(target); + } virtual Optional default_role() const override; }; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLAreaElement.h b/Userland/Libraries/LibWeb/HTML/HTMLAreaElement.h index 891e4101db..9fb7a7a50a 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLAreaElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLAreaElement.h @@ -35,12 +35,18 @@ private: virtual WebIDL::ExceptionOr set_hyperlink_element_utils_href(DeprecatedString) override; virtual bool hyperlink_element_utils_is_html_anchor_element() const override { return false; } virtual bool hyperlink_element_utils_is_connected() const override { return is_connected(); } - virtual DeprecatedString hyperlink_element_utils_target() const override { return ""; } - virtual DeprecatedString hyperlink_element_utils_rel() const override { return ""; } virtual void hyperlink_element_utils_queue_an_element_task(HTML::Task::Source source, Function steps) override { queue_an_element_task(source, move(steps)); } + virtual DeprecatedString hyperlink_element_utils_get_an_elements_target() const override + { + return get_an_elements_target(); + } + virtual TokenizedFeature::NoOpener hyperlink_element_utils_get_an_elements_noopener(StringView target) const override + { + return get_an_elements_noopener(target); + } virtual Optional default_role() const override; }; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLElement.cpp index 9dbad32be0..120ce68b33 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLElement.cpp @@ -17,11 +17,14 @@ #include #include #include +#include #include #include #include #include #include +#include +#include #include #include #include @@ -426,4 +429,41 @@ Optional HTMLElement::default_role() const return {}; } +// https://html.spec.whatwg.org/multipage/semantics.html#get-an-element's-target +DeprecatedString HTMLElement::get_an_elements_target() const +{ + // To get an element's target, given an a, area, or form element element, run these steps: + + // 1. If element has a target attribute, then return that attribute's value. + if (has_attribute(AttributeNames::target)) + return attribute(AttributeNames::target); + + // FIXME: 2. If element's node document contains a base element with a + // target attribute, then return the value of the target attribute of the + // first such base element. + + // 3. Return the empty string. + return DeprecatedString::empty(); +} + +// https://html.spec.whatwg.org/multipage/links.html#get-an-element's-noopener +TokenizedFeature::NoOpener HTMLElement::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 = attribute(HTML::AttributeNames::rel).to_lowercase(); + auto link_types = rel.view().split_view_if(Infra::is_ascii_whitespace); + + // 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 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 TokenizedFeature::NoOpener::Yes; + + // 3. Return false. + return TokenizedFeature::NoOpener::No; +} + } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLElement.h b/Userland/Libraries/LibWeb/HTML/HTMLElement.h index 86bda36d39..5d21e18cd6 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLElement.h @@ -9,6 +9,7 @@ #include #include #include +#include namespace Web::HTML { @@ -61,6 +62,9 @@ public: virtual Optional default_role() const override; + DeprecatedString get_an_elements_target() const; + TokenizedFeature::NoOpener get_an_elements_noopener(StringView target) const; + protected: HTMLElement(DOM::Document&, DOM::QualifiedName); diff --git a/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.cpp b/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.cpp index 5d4533ce99..2c7560083e 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.cpp @@ -7,8 +7,6 @@ #include #include #include -#include -#include #include namespace Web::HTML { @@ -487,10 +485,10 @@ void HTMLHyperlinkElementUtils::follow_the_hyperlink(Optional // 4. Let targetAttributeValue be the empty string. // 5. If subject is an a or area element, then set targetAttributeValue to // the result of getting an element's target given subject. - DeprecatedString target_attribute_value = get_an_elements_target(); + DeprecatedString target_attribute_value = hyperlink_element_utils_get_an_elements_target(); // 6. Let noopener be the result of getting an element's noopener with subject and targetAttributeValue. - auto noopener = get_an_elements_noopener(target_attribute_value); + auto noopener = hyperlink_element_utils_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 @@ -541,40 +539,4 @@ void HTMLHyperlinkElementUtils::follow_the_hyperlink(Optional }); } -DeprecatedString HTMLHyperlinkElementUtils::get_an_elements_target() const -{ - // To get an element's target, given an a, area, or form element element, run these steps: - - // 1. If element has a target attribute, then return that attribute's value. - if (auto target = hyperlink_element_utils_target(); !target.is_empty()) - return target; - - // FIXME: 2. If element's node document contains a base element with a - // target attribute, then return the value of the target attribute of the - // first such base element. - - // 3. Return the empty string. - return ""; -} - -// https://html.spec.whatwg.org/multipage/links.html#get-an-element's-noopener -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(); - auto link_types = rel.view().split_view_if(Infra::is_ascii_whitespace); - - // 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 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 TokenizedFeature::NoOpener::Yes; - - // 3. Return false. - return TokenizedFeature::NoOpener::No; -} - } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.h b/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.h index 355d7cb2c9..9f25273a8d 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.h @@ -55,8 +55,9 @@ protected: virtual WebIDL::ExceptionOr set_hyperlink_element_utils_href(DeprecatedString) = 0; virtual bool hyperlink_element_utils_is_html_anchor_element() const = 0; virtual bool hyperlink_element_utils_is_connected() const = 0; - virtual DeprecatedString hyperlink_element_utils_target() const = 0; - virtual DeprecatedString hyperlink_element_utils_rel() const = 0; + virtual DeprecatedString hyperlink_element_utils_get_an_elements_target() const = 0; + virtual TokenizedFeature::NoOpener hyperlink_element_utils_get_an_elements_noopener(StringView target) const = 0; + virtual void hyperlink_element_utils_queue_an_element_task(HTML::Task::Source source, Function steps) = 0; void set_the_url(); @@ -66,8 +67,6 @@ private: void reinitialize_url() const; void update_href(); bool cannot_navigate() const; - DeprecatedString get_an_elements_target() const; - TokenizedFeature::NoOpener get_an_elements_noopener(StringView target) const; Optional m_url; };