Explorar o código

LibWeb: Respect the trusted state of input events when clicking links

Andrew Kaster hai 1 ano
pai
achega
a5e1364938

+ 16 - 10
Userland/Libraries/LibWeb/HTML/HTMLAnchorElement.cpp

@@ -49,9 +49,10 @@ bool HTMLAnchorElement::has_activation_behavior() const
     return true;
 }
 
-void HTMLAnchorElement::activation_behavior(Web::DOM::Event const&)
+// https://html.spec.whatwg.org/multipage/links.html#links-created-by-a-and-area-elements
+void HTMLAnchorElement::activation_behavior(Web::DOM::Event const& event)
 {
-    // The activation behavior of an a element element given an event event is:
+    // The activation behavior of an a or area element element given an event event is:
 
     // 1. If element has no href attribute, then return.
     if (href().is_empty())
@@ -60,8 +61,8 @@ void HTMLAnchorElement::activation_behavior(Web::DOM::Event const&)
     // 2. Let hyperlinkSuffix be null.
     Optional<String> hyperlink_suffix {};
 
-    // FIXME: 3. If event's target is an img with an ismap attribute
-    //        specified, then:
+    // FIXME: 3. If element is an a element, and event's target is an img with an ismap attribute specified, then:
+    //
     //   3.1. Let x and y be 0.
     //
     //   3.2. If event's isTrusted attribute is initialized to true, then
@@ -78,13 +79,18 @@ void HTMLAnchorElement::activation_behavior(Web::DOM::Event const&)
     //   U+002C (,), and the value of y expressed as a base-ten integer
     //   using ASCII digits.
 
-    // FIXME: 4. If element has a download attribute, or if the user has
-    // expressed a preference to download the hyperlink, then download the
-    // hyperlink created by element given hyperlinkSuffix.
+    // 4. Let userInvolvement be event's user navigation involvement.
+    auto user_involvement = user_navigation_involvement(event);
+
+    // FIXME: 5. If the user has expressed a preference to download the hyperlink, then set userInvolvement to "browser UI".
+    // NOTE: That is, if the user has expressed a specific preference for downloading, this no longer counts as merely "activation".
+
+    // FIXME: 6. If element has a download attribute, or if the user has expressed a preference to download the
+    //     hyperlink, then download the hyperlink created by element with hyperlinkSuffix set to hyperlinkSuffix and
+    //     userInvolvement set to userInvolvement.
 
-    // 5. Otherwise, follow the hyperlink created by element given
-    // hyperlinkSuffix.
-    follow_the_hyperlink(hyperlink_suffix);
+    // 7. Otherwise, follow the hyperlink created by element with hyperlinkSuffix set to hyperlinkSuffix and userInvolvement set to userInvolvement.
+    follow_the_hyperlink(hyperlink_suffix, user_involvement);
 }
 
 // https://html.spec.whatwg.org/multipage/interaction.html#dom-tabindex

+ 9 - 8
Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.cpp

@@ -470,7 +470,7 @@ bool HTMLHyperlinkElementUtils::cannot_navigate() const
 }
 
 // https://html.spec.whatwg.org/multipage/links.html#following-hyperlinks-2
-void HTMLHyperlinkElementUtils::follow_the_hyperlink(Optional<String> hyperlink_suffix)
+void HTMLHyperlinkElementUtils::follow_the_hyperlink(Optional<String> hyperlink_suffix, UserNavigationInvolvement user_involvement)
 {
     // 1. If subject cannot navigate, then return.
     if (cannot_navigate())
@@ -496,18 +496,17 @@ void HTMLHyperlinkElementUtils::follow_the_hyperlink(Optional<String> hyperlink_
     if (!target_navigable)
         return;
 
-    // 8. Parse a URL given subject's href attribute, relative to subject's node document.
+    // 8. Let urlString be the result of encoding-parsing-and-serializing a URL given subject's href attribute value,
+    //    relative to subject's node document.
     auto url = hyperlink_element_utils_document().parse_url(href());
 
-    // 9. If that is successful, let url be the resulting URL string.
-    //    Otherwise, if parsing the URL failed, then return.
+    // 9. If urlString is failure, then return.
     if (!url.is_valid())
         return;
 
-    // 10. If that is successful, let URL be the resulting URL string.
     auto url_string = url.to_byte_string();
 
-    // 12. If hyperlinkSuffix is non-null, then append it to URL.
+    // 10. If hyperlinkSuffix is non-null, then append it to urlString.
     if (hyperlink_suffix.has_value()) {
         StringBuilder url_builder;
         url_builder.append(url_string);
@@ -516,10 +515,12 @@ void HTMLHyperlinkElementUtils::follow_the_hyperlink(Optional<String> hyperlink_
         url_string = url_builder.to_byte_string();
     }
 
+    // FIXME: 11. Let referrerPolicy be the current state of subject's referrerpolicy content attribute.
     // FIXME: 12. If subject's link types includes the noreferrer keyword, then set referrerPolicy to "no-referrer".
+    auto const referrer_policy = ReferrerPolicy::ReferrerPolicy::EmptyString;
 
-    // 13. Navigate targetNavigable to url using subject's node document, with referrerPolicy set to referrerPolicy.
-    MUST(target_navigable->navigate({ .url = url, .source_document = hyperlink_element_utils_document() }));
+    // 13. Navigate targetNavigable to urlString using subject's node document, with referrerPolicy set to referrerPolicy and userInvolvement set to userInvolvement.
+    MUST(target_navigable->navigate({ .url = url, .source_document = hyperlink_element_utils_document(), .referrer_policy = referrer_policy, .user_involvement = user_involvement }));
 }
 
 }

+ 2 - 1
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/Navigable.h>
 #include <LibWeb/HTML/TokenizedFeatures.h>
 
 namespace Web::HTML {
@@ -61,7 +62,7 @@ protected:
     virtual void hyperlink_element_utils_queue_an_element_task(HTML::Task::Source source, Function<void()> steps) = 0;
 
     void set_the_url();
-    void follow_the_hyperlink(Optional<String> hyperlink_suffix);
+    void follow_the_hyperlink(Optional<String> hyperlink_suffix, UserNavigationInvolvement = UserNavigationInvolvement::None);
 
 private:
     void reinitialize_url() const;