summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/semantics/links
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/html/semantics/links
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/html/semantics/links')
-rw-r--r--testing/web-platform/tests/html/semantics/links/META.yml2
-rw-r--r--testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-no-referrer-when-downgrade.html20
-rw-r--r--testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-no-referrer.html20
-rw-r--r--testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-origin-when-cross-origin.html20
-rw-r--r--testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-origin.html20
-rw-r--r--testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-same-origin.html20
-rw-r--r--testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-strict-origin-when-cross-origin.html20
-rw-r--r--testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-strict-origin.html20
-rw-r--r--testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-unsafe-url.html20
-rw-r--r--testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin.html19
-rw-r--r--testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin.js40
-rw-r--r--testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-no-referrer-when-downgrade.html20
-rw-r--r--testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-no-referrer.html20
-rw-r--r--testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-origin-when-cross-origin.html20
-rw-r--r--testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-origin.html20
-rw-r--r--testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-same-origin.html20
-rw-r--r--testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-strict-origin-when-cross-origin.html20
-rw-r--r--testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-strict-origin.html20
-rw-r--r--testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-unsafe-url.html20
-rw-r--r--testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer.html19
-rw-r--r--testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer.js40
-rw-r--r--testing/web-platform/tests/html/semantics/links/downloading-resources/resources/inspect-header.py18
-rw-r--r--testing/web-platform/tests/html/semantics/links/following-hyperlinks/activation-behavior.window.js50
-rw-r--r--testing/web-platform/tests/html/semantics/links/following-hyperlinks/active-document.window.js23
-rw-r--r--testing/web-platform/tests/html/semantics/links/hyperlink-auditing/headers.optional.html55
-rw-r--r--testing/web-platform/tests/html/semantics/links/hyperlink-auditing/resources/stash-headers.py27
-rw-r--r--testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_attribute-getter-setter.html65
-rw-r--r--testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_getter.html48
-rw-r--r--testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html78
-rw-r--r--testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/non-parsable-url-getter-setter.window.js54
-rw-r--r--testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/non-special-opaque-path-url-getter-setter.window.js59
-rw-r--r--testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/non-special-url-getter-setter.window.js63
-rw-r--r--testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-popup.html19
-rw-r--r--testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-target-1.html4
-rw-r--r--testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-target-2.html8
-rw-r--r--testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/target_blank_implicit_noopener.html6
-rw-r--r--testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/target_blank_implicit_noopener.html58
-rw-r--r--testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/target_blank_implicit_noopener_base.html59
-rw-r--r--testing/web-platform/tests/html/semantics/links/linktypes/alternate-css-ref.html5
-rw-r--r--testing/web-platform/tests/html/semantics/links/linktypes/alternate-css.html7
-rw-r--r--testing/web-platform/tests/html/semantics/links/linktypes/alternate-import.css3
-rw-r--r--testing/web-platform/tests/html/semantics/links/linktypes/alternate.css5
-rw-r--r--testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive-lower.css1
-rw-r--r--testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive-mixed.css1
-rw-r--r--testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive-other.css1
-rw-r--r--testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive-ref.html9
-rw-r--r--testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive.css3
-rw-r--r--testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive.html14
-rw-r--r--testing/web-platform/tests/html/semantics/links/linktypes/original-id.json1
-rw-r--r--testing/web-platform/tests/html/semantics/links/linktypes/preferred.css3
50 files changed, 1187 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/semantics/links/META.yml b/testing/web-platform/tests/html/semantics/links/META.yml
new file mode 100644
index 0000000000..b2167370d1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/META.yml
@@ -0,0 +1,2 @@
+suggested_reviewers:
+ - annevk
diff --git a/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-no-referrer-when-downgrade.html b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-no-referrer-when-downgrade.html
new file mode 100644
index 0000000000..466868dd7b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-no-referrer-when-downgrade.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Ping attribute Origin Header No Referrer When Downgrade Policy</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <meta name='referrer' content='no-referrer-when-downgrade'>
+ </head>
+ <body>
+ <a id="a" href="#">
+ <script src="/common/utils.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script src="/resources/chromium/enable-hyperlink-auditing.js"></script>
+ <script src="header-origin.js"></script>
+ <script>
+ testOriginHeader(self.location.origin);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-no-referrer.html b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-no-referrer.html
new file mode 100644
index 0000000000..cd7a1804f3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-no-referrer.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Ping attribute Origin Header No Referrer Policy</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <meta name='referrer' content='no-referrer'>
+ </head>
+ <body>
+ <a id="a" href="#">
+ <script src="/common/utils.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script src="/resources/chromium/enable-hyperlink-auditing.js"></script>
+ <script src="header-origin.js"></script>
+ <script>
+ testOriginHeader("null");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-origin-when-cross-origin.html b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-origin-when-cross-origin.html
new file mode 100644
index 0000000000..98115aa653
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-origin-when-cross-origin.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Ping attribute Origin Header Origin When Cross Origin Policy</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <meta name='referrer' content='origin-when-cross-origin'>
+ </head>
+ <body>
+ <a id="a" href="#">
+ <script src="/common/utils.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script src="/resources/chromium/enable-hyperlink-auditing.js"></script>
+ <script src="header-origin.js"></script>
+ <script>
+ testOriginHeader(self.location.origin);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-origin.html b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-origin.html
new file mode 100644
index 0000000000..194ca9d4ad
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-origin.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Ping attribute Origin Header Origin Policy</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <meta name='referrer' content='origin'>
+ </head>
+ <body>
+ <a id="a" href="#">
+ <script src="/common/utils.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script src="/resources/chromium/enable-hyperlink-auditing.js"></script>
+ <script src="header-origin.js"></script>
+ <script>
+ testOriginHeader(self.location.origin);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-same-origin.html b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-same-origin.html
new file mode 100644
index 0000000000..eb86708d5b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-same-origin.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Ping attribute Origin Header Same Origin Policy</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <meta name='referrer' content='same-origin'>
+ </head>
+ <body>
+ <a id="a" href="#">
+ <script src="/common/utils.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script src="/resources/chromium/enable-hyperlink-auditing.js"></script>
+ <script src="header-origin.js"></script>
+ <script>
+ testOriginHeader(self.location.origin);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-strict-origin-when-cross-origin.html b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-strict-origin-when-cross-origin.html
new file mode 100644
index 0000000000..f6514ff2ae
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-strict-origin-when-cross-origin.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Ping attribute Origin Header Strict Origin When Cross Origin Policy</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <meta name='referrer' content='strict-origin-when-cross-origin'>
+ </head>
+ <body>
+ <a id="a" href="#">
+ <script src="/common/utils.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script src="/resources/chromium/enable-hyperlink-auditing.js"></script>
+ <script src="header-origin.js"></script>
+ <script>
+ testOriginHeader(self.location.origin);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-strict-origin.html b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-strict-origin.html
new file mode 100644
index 0000000000..4aa311e833
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-strict-origin.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Ping attribute Origin Header Strict Origin Policy</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <meta name='referrer' content='strict-origin'>
+ </head>
+ <body>
+ <a id="a" href="#">
+ <script src="/common/utils.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script src="/resources/chromium/enable-hyperlink-auditing.js"></script>
+ <script src="header-origin.js"></script>
+ <script>
+ testOriginHeader(self.location.origin);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-unsafe-url.html b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-unsafe-url.html
new file mode 100644
index 0000000000..59742404fe
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin-unsafe-url.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Ping attribute Origin Header Unsafe Url Policy</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <meta name='referrer' content='unsafe-url'>
+ </head>
+ <body>
+ <a id="a" href="#">
+ <script src="/common/utils.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script src="/resources/chromium/enable-hyperlink-auditing.js"></script>
+ <script src="header-origin.js"></script>
+ <script>
+ testOriginHeader(self.location.origin);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin.html b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin.html
new file mode 100644
index 0000000000..189e2e66d4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Ping attribute Origin no Referrer Policy</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <a id="a" href="#">
+ <script src="/common/utils.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script src="/resources/chromium/enable-hyperlink-auditing.js"></script>
+ <script src="header-origin.js"></script>
+ <script>
+ testOriginHeader(self.location.origin);
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin.js b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin.js
new file mode 100644
index 0000000000..acc62ef93b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-origin.js
@@ -0,0 +1,40 @@
+const RESOURCES_DIR = "/html/semantics/links/downloading-resources/resources/";
+
+function testOriginHeader(expectedOrigin) {
+ var id = self.token();
+ let testUrl = RESOURCES_DIR + "inspect-header.py?header=origin&cmd=put&id=" + id;
+
+ promise_test(function(test) {
+ const anchor = document.getElementById("a");
+ anchor.setAttribute("ping", testUrl);
+ anchor.click();
+ return pollResult(id) .then(result => {
+ assert_equals(result, expectedOrigin, "Correct origin header result");
+ });
+ }, "Test origin header " + RESOURCES_DIR);
+}
+
+// Sending a ping is an asynchronous and non-blocking request to a web server.
+// We may have to create a poll loop to get result from server
+function pollResult(id) {
+ let checkUrl = RESOURCES_DIR + "inspect-header.py?header=origin&cmd=get&id=" + id;
+
+ return new Promise(resolve => {
+ function checkResult() {
+ fetch(checkUrl).then(
+ function(response) {
+ assert_equals(response.status, 200, "Inspect header response's status is 200");
+ let result = response.headers.get("x-request-origin");
+
+ if (result != undefined) {
+ resolve(result);
+ } else {
+ step_timeout(checkResult.bind(this), 100);
+ }
+ });
+ }
+
+ checkResult();
+ });
+
+}
diff --git a/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-no-referrer-when-downgrade.html b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-no-referrer-when-downgrade.html
new file mode 100644
index 0000000000..96c19d1d0e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-no-referrer-when-downgrade.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Ping attribute Referrer Header No Referrer When Downgrade Policy</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <meta name='referrer' content='no-referrer-when-downgrade'>
+ </head>
+ <body>
+ <a id="a" href="#">
+ <script src="/common/utils.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script src="/resources/chromium/enable-hyperlink-auditing.js"></script>
+ <script src="header-referrer.js"></script>
+ <script>
+ testReferrerHeader("");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-no-referrer.html b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-no-referrer.html
new file mode 100644
index 0000000000..065063075c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-no-referrer.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Ping attribute Referrer Header No Referrer Policy</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <meta name='referrer' content='no-referrer'>
+ </head>
+ <body>
+ <a id="a" href="#">
+ <script src="/common/utils.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script src="/resources/chromium/enable-hyperlink-auditing.js"></script>
+ <script src="header-referrer.js"></script>
+ <script>
+ testReferrerHeader("");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-origin-when-cross-origin.html b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-origin-when-cross-origin.html
new file mode 100644
index 0000000000..f0394261a1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-origin-when-cross-origin.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Ping attribute Referrer Header Origin When Cross Origin Policy</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <meta name='referrer' content='origin-when-cross-origin'>
+ </head>
+ <body>
+ <a id="a" href="#">
+ <script src="/common/utils.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script src="/resources/chromium/enable-hyperlink-auditing.js"></script>
+ <script src="header-referrer.js"></script>
+ <script>
+ testReferrerHeader("");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-origin.html b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-origin.html
new file mode 100644
index 0000000000..bef435581c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-origin.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Ping attribute Referrer Header Origin Policy</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <meta name='referrer' content='origin'>
+ </head>
+ <body>
+ <a id="a" href="#">
+ <script src="/common/utils.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script src="/resources/chromium/enable-hyperlink-auditing.js"></script>
+ <script src="header-referrer.js"></script>
+ <script>
+ testReferrerHeader("");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-same-origin.html b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-same-origin.html
new file mode 100644
index 0000000000..19b2d022af
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-same-origin.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Ping attribute Referrer Header Same Origin Policy</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <meta name='referrer' content='same-origin'>
+ </head>
+ <body>
+ <a id="a" href="#">
+ <script src="/common/utils.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script src="/resources/chromium/enable-hyperlink-auditing.js"></script>
+ <script src="header-referrer.js"></script>
+ <script>
+ testReferrerHeader("");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-strict-origin-when-cross-origin.html b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-strict-origin-when-cross-origin.html
new file mode 100644
index 0000000000..95132eee5c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-strict-origin-when-cross-origin.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Ping attribute Referrer Header Strict Origin When Cross Origin Policy</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <meta name='referrer' content='strict-origin-when-cross-origin'>
+ </head>
+ <body>
+ <a id="a" href="#">
+ <script src="/common/utils.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script src="/resources/chromium/enable-hyperlink-auditing.js"></script>
+ <script src="header-referrer.js"></script>
+ <script>
+ testReferrerHeader("");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-strict-origin.html b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-strict-origin.html
new file mode 100644
index 0000000000..e2678e8de8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-strict-origin.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Ping attribute Referrer Header Strict Origin Policy</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <meta name='referrer' content='strict-origin'>
+ </head>
+ <body>
+ <a id="a" href="#">
+ <script src="/common/utils.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script src="/resources/chromium/enable-hyperlink-auditing.js"></script>
+ <script src="header-referrer.js"></script>
+ <script>
+ testReferrerHeader("");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-unsafe-url.html b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-unsafe-url.html
new file mode 100644
index 0000000000..cc3d1dde86
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer-unsafe-url.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Ping attribute Referrer Header Unsafe Url Policy</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <meta name='referrer' content='unsafe-url'>
+ </head>
+ <body>
+ <a id="a" href="#">
+ <script src="/common/utils.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script src="/resources/chromium/enable-hyperlink-auditing.js"></script>
+ <script src="header-referrer.js"></script>
+ <script>
+ testReferrerHeader("");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer.html b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer.html
new file mode 100644
index 0000000000..5e2d136443
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Ping attribute no Referrer Header given</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <a id="a" href="#">
+ <script src="/common/utils.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script src="/resources/chromium/enable-hyperlink-auditing.js"></script>
+ <script src="header-referrer.js"></script>
+ <script>
+ testReferrerHeader("");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer.js b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer.js
new file mode 100644
index 0000000000..818649fbff
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/downloading-resources/header-referrer.js
@@ -0,0 +1,40 @@
+const RESOURCES_DIR = "/html/semantics/links/downloading-resources/resources/";
+
+function testReferrerHeader(expectedReferrer) {
+ let id = self.token();
+ let testUrl = RESOURCES_DIR + "inspect-header.py?header=referer&cmd=put&id=" + id;
+
+ promise_test(function(test) {
+ const anchor = document.getElementById("a");
+ anchor.setAttribute("ping", testUrl);
+ anchor.click();
+ return pollResult(id) .then(result => {
+ assert_equals(result, expectedReferrer, "Correct referrer header result");
+ });
+ }, "Test referer header " + RESOURCES_DIR);
+}
+
+// Sending a ping is an asynchronous and non-blocking request to a web server.
+// We may have to create a poll loop to get result from server
+function pollResult(id) {
+ let checkUrl = RESOURCES_DIR + "inspect-header.py?header=referer&cmd=get&id=" + id;
+
+ return new Promise(resolve => {
+ function checkResult() {
+ fetch(checkUrl).then(
+ function(response) {
+ assert_equals(response.status, 200, "Inspect header response's status is 200");
+ let result = response.headers.get("x-request-referer");
+
+ if (result != undefined) {
+ resolve(result);
+ } else {
+ step_timeout(checkResult.bind(this), 100);
+ }
+ });
+ }
+
+ checkResult();
+ });
+
+}
diff --git a/testing/web-platform/tests/html/semantics/links/downloading-resources/resources/inspect-header.py b/testing/web-platform/tests/html/semantics/links/downloading-resources/resources/inspect-header.py
new file mode 100644
index 0000000000..2c68e475ff
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/downloading-resources/resources/inspect-header.py
@@ -0,0 +1,18 @@
+def main(request, response):
+ headers = [(b"Content-Type", b"text/plain")]
+ command = request.GET.first(b"cmd").lower()
+ test_id = request.GET.first(b"id")
+ header = request.GET.first(b"header")
+ if command == b"put":
+ request.server.stash.put(test_id, request.headers.get(header, b""))
+
+ elif command == b"get":
+ stashed_header = request.server.stash.take(test_id)
+ if stashed_header is not None:
+ headers.append((b"x-request-" + header, stashed_header))
+
+ else:
+ response.set_error(400, u"Bad Command")
+ return b"ERROR: Bad Command!"
+
+ return headers, b""
diff --git a/testing/web-platform/tests/html/semantics/links/following-hyperlinks/activation-behavior.window.js b/testing/web-platform/tests/html/semantics/links/following-hyperlinks/activation-behavior.window.js
new file mode 100644
index 0000000000..d530642b9e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/following-hyperlinks/activation-behavior.window.js
@@ -0,0 +1,50 @@
+["a",
+ "area"].forEach(type => {
+
+ const followed = type === "a" ? true : false;
+ async_test(t => {
+ const target = document.createElement("iframe"),
+ link = document.createElement(type);
+ t.add_cleanup(() => target.remove());
+ target.name = "certifiedrandom" + type;
+ link.target = "certifiedrandom" + type;
+ link.href = "/";
+ document.body.appendChild(target);
+ target.onload = t.step_func(() => {
+ if(target.contentWindow.location.href === "about:blank")
+ return;
+ if(followed) {
+ assert_equals(target.contentWindow.location.pathname, "/");
+ t.done();
+ } else {
+ assert_unreached();
+ }
+ });
+ link.click();
+ t.step_timeout(() => {
+ if(followed) {
+ assert_unreached();
+ } else {
+ t.done();
+ }
+ }, 500);
+ }, "<" + type + "> that is not connected should " + (followed ? "" : "not ") + "be followed");
+
+ async_test(t => {
+ const target = document.createElement("iframe"),
+ doc = document.implementation.createDocument("", ""),
+ link = doc.createElementNS("http://www.w3.org/1999/xhtml", type);
+ t.add_cleanup(() => target.remove());
+ target.name = "certifiedrandom2" + type;
+ link.target = "certifiedrandom2" + type;
+ link.href = "/";
+ document.body.appendChild(target);
+ target.onload = t.step_func(() => {
+ if(target.contentWindow.location.href === "about:blank")
+ return;
+ assert_unreached();
+ });
+ link.click();
+ t.step_timeout(() => t.done(), 500);
+ }, "<" + type + "> that is from an inactive document should not be followed");
+});
diff --git a/testing/web-platform/tests/html/semantics/links/following-hyperlinks/active-document.window.js b/testing/web-platform/tests/html/semantics/links/following-hyperlinks/active-document.window.js
new file mode 100644
index 0000000000..efa16e7d17
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/following-hyperlinks/active-document.window.js
@@ -0,0 +1,23 @@
+["a",
+ "area",
+ "link"].forEach(type => {
+ async_test(t => {
+ const frame = document.createElement("iframe"),
+ link = document.createElement(type);
+ t.add_cleanup(() => frame.remove());
+ frame.onload = t.step_func(() => {
+ // See https://github.com/whatwg/html/issues/490
+ if(frame.contentWindow.location.href === "about:blank")
+ return;
+ link.click(); // must be ignored because document is not active
+ t.step_timeout(() => {
+ assert_equals(frame.contentWindow.location.pathname, "/common/blank.html");
+ t.done();
+ }, 500);
+ });
+ document.body.appendChild(frame);
+ frame.contentDocument.body.appendChild(link);
+ link.href = "/";
+ frame.src = "/common/blank.html";
+ }, "<" + type + "> in navigated away <iframe>'s document cannot follow hyperlinks");
+});
diff --git a/testing/web-platform/tests/html/semantics/links/hyperlink-auditing/headers.optional.html b/testing/web-platform/tests/html/semantics/links/hyperlink-auditing/headers.optional.html
new file mode 100644
index 0000000000..dd524fa5fa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/hyperlink-auditing/headers.optional.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+
+<iframe id="i" src="/common/blank.html"></iframe>
+
+<!-- Test is optional because hyperlink auditing is optional. -->
+
+<script>
+promise_test(async t => {
+ await new Promise(resolve => window.onload = resolve);
+
+ const id = token();
+
+ const el = document.createElement("a");
+ el.ping = new URL(`resources/stash-headers.py?id=${id}`, location.href); // this will be a POST
+ el.href = "/common/blank.html?1";
+
+ i.contentDocument.body.append(el);
+ el.click();
+
+ let headers;
+ await pollForConditionFunc(t, async () => {
+ const res = await fetch(el.ping); // this will be a GET
+ const json = await res.json();
+
+ if (json !== "no headers yet") {
+ headers = json;
+ return true;
+ }
+ return false;
+ });
+
+ assert_equals(headers["content-type"], "text/ping", "content-type");
+ assert_equals(headers["ping-from"], i.src, "ping-from");
+ assert_equals(headers["ping-to"], el.href, "ping-to");
+});
+
+async function pollForConditionFunc(t, func, timeout = 3000, interval = 100) {
+ let remaining = Math.ceil(timeout / interval);
+
+ while (remaining > 0) {
+ --remaining;
+ await new Promise(resolve => t.step_timeout(resolve, interval));
+
+ if (await func()) {
+ return;
+ }
+ }
+
+ assert_true(false, "Condition never became true");
+}
+</script>
diff --git a/testing/web-platform/tests/html/semantics/links/hyperlink-auditing/resources/stash-headers.py b/testing/web-platform/tests/html/semantics/links/hyperlink-auditing/resources/stash-headers.py
new file mode 100644
index 0000000000..a0d4a38812
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/hyperlink-auditing/resources/stash-headers.py
@@ -0,0 +1,27 @@
+import json
+from wptserve.utils import isomorphic_decode
+
+def main(request, response):
+ key = request.GET[b"id"]
+
+ if request.method == "POST":
+ content_type = request.headers.get(b"content-type", b"no content-type header")
+ ping_from = request.headers.get(b"ping-from", b"no ping-from header")
+ ping_to = request.headers.get(b"ping-to", b"no ping-to header")
+
+ value = json.dumps({
+ 'content-type': isomorphic_decode(content_type),
+ 'ping-from': isomorphic_decode(ping_from),
+ 'ping-to': isomorphic_decode(ping_to)
+ })
+ request.server.stash.put(key, value)
+
+ return (204, [], "")
+
+ elif request.method == "GET":
+ value = request.server.stash.take(key)
+ if value is None:
+ value = "\"no headers yet\""
+ return (200, [("Content-Type", "application/json")], str(value))
+
+ return (405, [], "")
diff --git a/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_attribute-getter-setter.html b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_attribute-getter-setter.html
new file mode 100644
index 0000000000..2db3082e21
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_attribute-getter-setter.html
@@ -0,0 +1,65 @@
+<!doctype html>
+<meta charset="utf-8">
+<html>
+<head>
+<title>HTMLAnchorElement getters and setters</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<a>anchor</a>
+<script>
+function test_gettersetter(property, oldresult, newval, newresult, oldurl, newurl) {
+ var a = document.querySelector('a');
+ a.href = oldurl;
+ var r1 = a[property];
+ assert_equals(r1, oldresult);
+ a[property] = newval;
+ var r2 = a[property];
+ assert_equals(r2, newresult);
+ var r3 = a.href;
+ assert_equals(r3, newurl);
+}
+
+//Elements for each test: [property, oldresult, newvalue, newresult, oldurl, newurl]
+// [0] [1] [2] [3] [4] [5]
+tests = [
+ ["hash", "#somehash", "someother", "#someother",
+ "http://google.com/index.html#somehash",
+ "http://google.com/index.html#someother"],
+ ["hash", "#somehash", "#someother", "#someother",
+ "http://google.com/index.html#somehash",
+ "http://google.com/index.html#someother"],
+ ["host", "google.com:1234", "github.com:4444", "github.com:4444",
+ "http://google.com:1234/somedir",
+ "http://github.com:4444/somedir"],
+ ["hostname", "google.com", "github.com", "github.com",
+ "http://google.com:1234/somedir",
+ "http://github.com:1234/somedir"],
+ ["href", "http://google.com:1234/somedir", "http://goo-gle.com:1234/other/x.html", "http://goo-gle.com:1234/other/x.html",
+ "http://google.com:1234/somedir",
+ "http://goo-gle.com:1234/other/x.html"],
+ ["password", "flabada", "blubb", "blubb",
+ "https://anonymous:flabada@developer.mozilla.org/en-US/docs/",
+ "https://anonymous:blubb@developer.mozilla.org/en-US/docs/"],
+ ["pathname", "/somedir/someotherdir/index.html", "/newpath/x.txt", "/newpath/x.txt",
+ "http://google.com:1234/somedir/someotherdir/index.html",
+ "http://google.com:1234/newpath/x.txt"],
+ ["port", "1234", "4444", "4444", "http://google.com:1234/somedir", "http://google.com:4444/somedir"],
+ ["protocol", "http:", "ftp:", "ftp:", "http://google.com/somedir", "ftp://google.com/somedir"],
+ ["protocol", "http:", "ftp", "ftp:", "http://google.com/somedir", "ftp://google.com/somedir"],
+ ["search", "?ho", "?hi", "?hi", "http://google.com/q.php?ho", "http://google.com/q.php?hi"],
+ ["search", "?ho", "hi", "?hi", "http://google.com/q.php?ho", "http://google.com/q.php?hi"],
+ ["search", "?ho", "?hi", "?hi", "http://google.com/?ho", "http://google.com/?hi"],
+ ["search", "?ho", "hi", "?hi", "http://google.com/?ho", "http://google.com/?hi"],
+ ["username", "anonymous", "wellknown", "wellknown",
+ "https://anonymous:pwd@developer.mozilla.org:1234/en-US/",
+ "https://wellknown:pwd@developer.mozilla.org:1234/en-US/"]
+];
+
+for (var i = 0; i < tests.length; i++) {
+ test(function() {
+ test_gettersetter(tests[i][0], tests[i][1], tests[i][2], tests[i][3], tests[i][4], tests[i][5])
+ }, "Getter and setter for attribute of anchor element(" + i + "):" + tests[i][0] );
+}
+</script>
+</head>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_getter.html b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_getter.html
new file mode 100644
index 0000000000..759eada220
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_getter.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<meta charset="utf-8">
+<html>
+<head>
+<title>HTMLAnchorElement getters test</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<a id=a1 href="http://google.com?hi">a1</a>
+<a id=a2 href="http://google.com#somehash">a2</a>
+<a id=a3 href="http://google.com:1234/somedir">a3</a>
+<a id=a4 href="http://google.com:1234/somedir">a4</a>
+<a id=a5 href="http://google.com:1234/somedir">a5</a>
+<a id=a6 href="https://anonymous:flabada@developer.mozilla.org/en-US/docs/">a6</a>
+<a id=a7 href="http://google.com:1234/somedir/someotherdir/index.html">a7</a>
+<a id=a8 href="http://google.com:1234/somedir">a8</a>
+<a id=a9 href="http://google.com/somedir">a9</a>
+<a id=a10 href="https://anonymous:pwd@developer.mozilla.org:1234/en-US/">a10</a>
+<script>
+function test_getter(property, result, id) {
+ var a = document.getElementById(id);
+ var r = a[property];
+ assert_equals(r, result);
+}
+
+//Elements for each test: [property, result, id]
+// [0] [1] [2]
+tests = [
+ ["search", "?hi", "a1"],
+ ["hash", "#somehash", "a2"],
+ ["host", "google.com:1234", "a3"],
+ ["hostname", "google.com", "a4"],
+ ["href", "http://google.com:1234/somedir", "a5"],
+ ["password", "flabada", "a6"],
+ ["pathname", "/somedir/someotherdir/index.html", "a7"],
+ ["port", "1234", "a8"],
+ ["protocol", "http:", "a9"],
+ ["username", "anonymous", "a10"]
+];
+
+for (var i = 0; i < tests.length; i++) {
+ test(function() {
+ test_getter(tests[i][0], tests[i][1], tests[i][2])
+ }, "Getter for attribute of anchor element(" + i + "):" + tests[i][0]);
+}
+</script>
+</head>
+</html>
+
diff --git a/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html
new file mode 100644
index 0000000000..95ab1c81fb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html
@@ -0,0 +1,78 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test behavior of rel="noopener" links</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<iframe name="oursubframe"></iframe>
+<a href="support/noopener-target-2.html" rel="noopener" target="ourpopup"></a>
+<a href="support/noopener-target-2.html" rel="noopener" target="oursubframe"></a>
+<script>
+var tests = [];
+// First test the special targets
+function target1Loaded(win) {
+ // Find the relevant test
+ var test = tests.find((t) => t.openedWindow == win);
+ test.step(function() {
+ assert_equals(win.opener, window);
+ win.close();
+ test.done();
+ });
+}
+/**
+ * Test that <a rel="noopener"> targeted at one of _self, _parent, _top does the
+ * load in the appropriate existing browsing context instead of opening a new
+ * one. The test is run in a separate popup window we open and which we can
+ * navigate without causing the test harness going into conniptions.
+ */
+for (var target of ["self", "parent", "top"]) {
+ var t = async_test("Check that rel=noopener with target=_" + target + " does a normal load");
+ tests.push(t);
+ t.openedWindow = window.open("support/noopener-popup.html");
+ t.targetName = target;
+ t.openedWindow.onload = t.step_func(function() {
+ this.openedWindow.findLink(this.targetName).click();
+ });
+}
+
+/**
+ * And now check that a noopener load targeted at something other than one of
+ * the three special targets above is still able to reuse existing things with the
+ * given name. We do this in two ways. First, by opening a window named
+ * "ourpopup" and then doing a load via <a rel="noopener" target="ourpopup"> and
+ * verifying that the load happens in a window with a null opener, etc, while
+ * the opener of the thing we opened is not modified. And second, by targeting
+ * <a rel="noopener"> at a name that an existing subframe has, and ensuring that
+ * this subframe is not navigated.
+ */
+var t1 = async_test("Check that targeting of rel=noopener with a given name reuses an existing window with that name");
+var w;
+t1.add_cleanup(function() { w.close(); });
+var channel = new BroadcastChannel("ourpopup");
+channel.onmessage = t1.step_func_done(function(e) {
+ var data = e.data;
+ assert_true(data.hasOpener);
+ assert_false(data.hasParent);
+ assert_equals(data.name, "ourpopup");
+ assert_equals(w.opener, window);
+ assert_not_equals(w.location.href, "about:blank");
+});
+t1.step(function() {
+ w = window.open("", "ourpopup");
+ assert_equals(w.opener, window);
+ document.querySelectorAll("a")[0].click();
+});
+
+var t2 = async_test("Check that targeting of rel=noopener with a given name reuses an existing subframe with that name");
+var channel = new BroadcastChannel("oursubframe");
+channel.onmessage = t2.step_func_done(function(e) {
+ var data = e.data;
+ assert_false(data.hasOpener);
+ assert_true(data.hasParent);
+ assert_equals(data.name, "oursubframe");
+ assert_not_equals(document.querySelector("iframe").contentWindow.location.href,
+ "about:blank");
+});
+t2.step(function() {
+ document.querySelectorAll("a")[1].click();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/non-parsable-url-getter-setter.window.js b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/non-parsable-url-getter-setter.window.js
new file mode 100644
index 0000000000..587f9b9c46
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/non-parsable-url-getter-setter.window.js
@@ -0,0 +1,54 @@
+[
+ {
+ "property": "origin",
+ "set": null
+ },
+ {
+ "property": "protocol",
+ "get": ":",
+ "set": "https"
+ },
+ {
+ "property": "username"
+ },
+ {
+ "property": "password"
+ },
+ {
+ "property": "host"
+ },
+ {
+ "property": "hostname"
+ },
+ {
+ "property": "port",
+ "set": "8000"
+ },
+ {
+ "property": "pathname"
+ },
+ {
+ "property": "search"
+ },
+ {
+ "property": "hash"
+ }
+].forEach(({ property, get = "", set = "string" }) => {
+ ["a", "area"].forEach(name => {
+ test(() => {
+ const link = document.createElement(name);
+ link.href = "http://test:test/"; // non-parsable URL
+ assert_equals(link[property], get);
+ }, `<${name} href="http://test:test/">.${property} getter`);
+
+ if (set !== null) {
+ test(() => {
+ const link = document.createElement(name);
+ link.href = "http://test:test/"; // non-parsable URL
+ link[property] = set;
+ assert_equals(link[property], get);
+ assert_equals(link.href, "http://test:test/");
+ }, `<${name} href="http://test:test/">.${property} setter`);
+ }
+ });
+});
diff --git a/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/non-special-opaque-path-url-getter-setter.window.js b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/non-special-opaque-path-url-getter-setter.window.js
new file mode 100644
index 0000000000..9549c6e2a6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/non-special-opaque-path-url-getter-setter.window.js
@@ -0,0 +1,59 @@
+[
+ {
+ "property": "origin",
+ "get": "null",
+ "set": null
+ },
+ {
+ "property": "protocol",
+ "get": "non-special:",
+ "set": "super-special",
+ "setget": "super-special:"
+ },
+ {
+ "property": "username"
+ },
+ {
+ "property": "password"
+ },
+ {
+ "property": "host",
+ },
+ {
+ "property": "hostname",
+ },
+ {
+ "property": "port",
+ "set": "8000"
+ },
+ {
+ "property": "pathname",
+ "get": "opaque",
+ "setget": "opaque"
+ },
+ {
+ "property": "search",
+ "setget": "?string"
+ },
+ {
+ "property": "hash",
+ "setget": "#string"
+ }
+].forEach(({ property, get = "", set = "string", setget = get }) => {
+ ["a", "area"].forEach(name => {
+ test(() => {
+ const link = document.createElement(name);
+ link.href = "non-special:opaque";
+ assert_equals(link[property], get);
+ }, `<${name} href="non-special:opaque">.${property} getter`);
+
+ if (set !== null) {
+ test(() => {
+ const link = document.createElement(name);
+ link.href = "non-special:opaque";
+ link[property] = set;
+ assert_equals(link[property], setget);
+ }, `<${name} href="non-special:opaque">.${property} setter`);
+ }
+ });
+});
diff --git a/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/non-special-url-getter-setter.window.js b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/non-special-url-getter-setter.window.js
new file mode 100644
index 0000000000..de528a2f97
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/non-special-url-getter-setter.window.js
@@ -0,0 +1,63 @@
+[
+ {
+ "property": "origin",
+ "get": "null",
+ "set": null
+ },
+ {
+ "property": "protocol",
+ "get": "non-special:",
+ "set": "super-special",
+ "setget": "super-special:"
+ },
+ {
+ "property": "username"
+ },
+ {
+ "property": "password"
+ },
+ {
+ "property": "host",
+ "get": "test:9001",
+ "setget": "string:9001"
+ },
+ {
+ "property": "hostname",
+ "get": "test"
+ },
+ {
+ "property": "port",
+ "get": "9001",
+ "set": "8000"
+ },
+ {
+ "property": "pathname",
+ "get": "/",
+ "setget": "/string"
+ },
+ {
+ "property": "search",
+ "setget": "?string"
+ },
+ {
+ "property": "hash",
+ "setget": "#string"
+ }
+].forEach(({ property, get = "", set = "string", setget = set }) => {
+ ["a", "area"].forEach(name => {
+ test(() => {
+ const link = document.createElement(name);
+ link.href = "non-special://test:9001/";
+ assert_equals(link[property], get);
+ }, `<${name} href="non-special://test:9001/">.${property} getter`);
+
+ if (set !== null) {
+ test(() => {
+ const link = document.createElement(name);
+ link.href = "non-special://test:9001/";
+ link[property] = set;
+ assert_equals(link[property], setget);
+ }, `<${name} href="non-special://test:9001/">.${property} setter`);
+ }
+ });
+});
diff --git a/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-popup.html b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-popup.html
new file mode 100644
index 0000000000..2057dbf0be
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-popup.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<script>
+ function findLink(arg) {
+ var doc;
+ if (arg == "self") {
+ doc = document;
+ } else {
+ doc = frames[0].document;
+ }
+ return doc.getElementById(arg + "target");
+ }
+</script>
+<a rel="noopener" target="_self" id="selftarget"
+ href="noopener-target-1.html"></a>
+<iframe srcdoc='
+ <a rel="noopener" target="_parent" id="parenttarget"
+ href="noopener-target-1.html"></a>
+ <a rel="noopener" target="_top" id="toptarget"
+ href="noopener-target-1.html"></a>'></iframe>
diff --git a/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-target-1.html b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-target-1.html
new file mode 100644
index 0000000000..0dbd14275c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-target-1.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<script>
+ opener.target1Loaded(this);
+</script>
diff --git a/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-target-2.html b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-target-2.html
new file mode 100644
index 0000000000..dd2d719134
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-target-2.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<script>
+ var channel = new BroadcastChannel(this.name);
+ channel.postMessage({ hasOpener: opener !== null ,
+ hasParent: parent != this,
+ name: window.name });
+ window.close();
+</script>
diff --git a/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/target_blank_implicit_noopener.html b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/target_blank_implicit_noopener.html
new file mode 100644
index 0000000000..bf6a1ae5bf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/target_blank_implicit_noopener.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<script>
+ let bc = new BroadcastChannel(window.location.search.substring(1));
+ bc.postMessage({ hasOpener: opener !== null });
+ window.close();
+</script>
diff --git a/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/target_blank_implicit_noopener.html b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/target_blank_implicit_noopener.html
new file mode 100644
index 0000000000..73eebaff70
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/target_blank_implicit_noopener.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset=utf-8>
+ <meta name="timeout" content="long">
+ <title>Test behavior of target=_blank links</title>
+ <script src=/resources/testharness.js></script>
+ <script src=/resources/testharnessreport.js></script>
+</head>
+<body>
+ <a href="support/target_blank_implicit_noopener.html?a1" id="a1" rel="noopener" target="_blank">Click me</a>
+ <a href="support/target_blank_implicit_noopener.html?a2" id="a2" rel="opener" target="_blank">Click me</a>
+ <a href="support/target_blank_implicit_noopener.html?a3" id="a3" target="_blank">Click me</a>
+ <a href="support/target_blank_implicit_noopener.html?a4" id="a4" rel="opener noopener" target="_blank">Click me</a>
+ <a href="support/target_blank_implicit_noopener.html?a5" id="a5" rel="noopener opener" target="_blank">Click me</a>
+ <a href="support/target_blank_implicit_noopener.html?a6" id="a6" rel="noreferrer" target="_blank">Click me</a>
+ <a href="support/target_blank_implicit_noopener.html?a7" id="a7" rel="opener noreferrer" target="_blank">Click me</a>
+ <a href="support/target_blank_implicit_noopener.html?a8" id="a8" rel="noopener opener noreferrer" target="_blank">Click me</a>
+
+ <!-- Although this is not valid, per the processing model of area it ought to work -->
+ <area shape="rect" coords="0,0,99,50" href="support/target_blank_implicit_noopener.html?area1" id="area1" rel="noopener" target="_blank">
+ <area shape="rect" coords="0,0,99,50" href="support/target_blank_implicit_noopener.html?area2" id="area2" rel="opener" target="_blank">
+ <area shape="rect" coords="0,0,99,50" href="support/target_blank_implicit_noopener.html?area3" id="area3" target="_blank">
+ <area shape="rect" coords="0,0,99,50" href="support/target_blank_implicit_noopener.html?area4" id="area4" rel="opener noopener" target="_blank">
+ <area shape="rect" coords="0,0,99,50" href="support/target_blank_implicit_noopener.html?area5" id="area5" rel="noopener opener" target="_blank">
+
+ <script>
+
+ let tests = [
+ { id: "a1", hasOpener: false, name: "Anchor element with target=_blank with rel=noopener" },
+ { id: "a2", hasOpener: true, name: "Anchor element with target=_blank with rel=opener" },
+ { id: "a3", hasOpener: false, name: "Anchor element with target=_blank with implicit rel=noopener" },
+ { id: "a4", hasOpener: false, name: "Anchor element with target=_blank with rel=opener+noopener" },
+ { id: "a5", hasOpener: false, name: "Anchor element with target=_blank with rel=noopener+opener" },
+ { id: "a6", hasOpener: false, name: "Anchor element with target=_blank with rel=noreferrer" },
+ { id: "a7", hasOpener: false, name: "Anchor element with target=_blank with rel=opener+noreferrer" },
+ { id: "a8", hasOpener: false, name: "Anchor element with target=_blank with rel=noopener+opener+noreferrer" },
+ { id: "area1", hasOpener: false, name: "Area element with target=_blank with rel=noopener" },
+ { id: "area2", hasOpener: true, name: "Area element with target=_blank with rel=opener" },
+ { id: "area3", hasOpener: false, name: "Area element with target=_blank with implicit rel=noopener" },
+ { id: "area4", hasOpener: false, name: "Area element with target=_blank with rel=opener+noopener" },
+ { id: "area5", hasOpener: false, name: "Area element with target=_blank with rel=noopener+opener" },
+ ];
+
+ tests.forEach(data => {
+ async_test(
+ test => {
+ let bc = new BroadcastChannel(data.id);
+ bc.addEventListener("message", test.step_func_done(e => {
+ assert_equals(e.data.hasOpener, data.hasOpener);
+ }), {once: true});
+
+ document.getElementById(data.id).click();
+ }, data.name);
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/target_blank_implicit_noopener_base.html b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/target_blank_implicit_noopener_base.html
new file mode 100644
index 0000000000..3da6a49ef8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/target_blank_implicit_noopener_base.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset=utf-8>
+ <meta name="timeout" content="long">
+ <title>Test behavior of base target=_blank links</title>
+ <script src=/resources/testharness.js></script>
+ <script src=/resources/testharnessreport.js></script>
+ <base target=_blank>
+</head>
+<body>
+ <a href="support/target_blank_implicit_noopener.html?a1" id="a1" rel="noopener">Click me</a>
+ <a href="support/target_blank_implicit_noopener.html?a2" id="a2" rel="opener">Click me</a>
+ <a href="support/target_blank_implicit_noopener.html?a3" id="a3">Click me</a>
+ <a href="support/target_blank_implicit_noopener.html?a4" id="a4" rel="opener noopener">Click me</a>
+ <a href="support/target_blank_implicit_noopener.html?a5" id="a5" rel="noopener opener">Click me</a>
+ <a href="support/target_blank_implicit_noopener.html?a6" id="a6" rel="noreferrer">Click me</a>
+ <a href="support/target_blank_implicit_noopener.html?a7" id="a7" rel="opener noreferrer">Click me</a>
+ <a href="support/target_blank_implicit_noopener.html?a8" id="a8" rel="noopener opener noreferrer">Click me</a>
+
+ <!-- Although this is not valid, per the processing model of area it ought to work -->
+ <area shape="rect" coords="0,0,99,50" href="support/target_blank_implicit_noopener.html?area1" id="area1" rel="noopener">
+ <area shape="rect" coords="0,0,99,50" href="support/target_blank_implicit_noopener.html?area2" id="area2" rel="opener">
+ <area shape="rect" coords="0,0,99,50" href="support/target_blank_implicit_noopener.html?area3" id="area3">
+ <area shape="rect" coords="0,0,99,50" href="support/target_blank_implicit_noopener.html?area4" id="area4" rel="opener noopener">
+ <area shape="rect" coords="0,0,99,50" href="support/target_blank_implicit_noopener.html?area5" id="area5" rel="noopener opener">
+
+ <script>
+
+ let tests = [
+ { id: "a1", hasOpener: false, name: "Anchor element with base target=_blank with rel=noopener" },
+ { id: "a2", hasOpener: true, name: "Anchor element with base target=_blank with rel=opener" },
+ { id: "a3", hasOpener: false, name: "Anchor element with base target=_blank with implicit rel=noopener" },
+ { id: "a4", hasOpener: false, name: "Anchor element with base target=_blank with rel=opener+noopener" },
+ { id: "a5", hasOpener: false, name: "Anchor element with base target=_blank with rel=noopener+opener" },
+ { id: "a6", hasOpener: false, name: "Anchor element with base target=_blank with rel=noreferrer" },
+ { id: "a7", hasOpener: false, name: "Anchor element with base target=_blank with rel=opener+noreferrer" },
+ { id: "a8", hasOpener: false, name: "Anchor element with base target=_blank with rel=noopener+opener+noreferrer" },
+ { id: "area1", hasOpener: false, name: "Area element with base target=_blank with rel=noopener" },
+ { id: "area2", hasOpener: true, name: "Area element with base target=_blank with rel=opener" },
+ { id: "area3", hasOpener: false, name: "Area element with base target=_blank with implicit rel=noopener" },
+ { id: "area4", hasOpener: false, name: "Area element with base target=_blank with rel=opener+noopener" },
+ { id: "area5", hasOpener: false, name: "Area element with base target=_blank with rel=noopener+opener" },
+ ];
+
+ tests.forEach(data => {
+ async_test(
+ test => {
+ let bc = new BroadcastChannel(data.id);
+ bc.addEventListener("message", test.step_func_done(e => {
+ assert_equals(e.data.hasOpener, data.hasOpener);
+ }), {once: true});
+
+ document.getElementById(data.id).click();
+ }, data.name);
+ });
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/links/linktypes/alternate-css-ref.html b/testing/web-platform/tests/html/semantics/links/linktypes/alternate-css-ref.html
new file mode 100644
index 0000000000..ec961eac15
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/linktypes/alternate-css-ref.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Reference of Alternate css</title>
+<link rel="stylesheet" href="preferred.css" title="preferred">
+<div>foobar</div>
diff --git a/testing/web-platform/tests/html/semantics/links/linktypes/alternate-css.html b/testing/web-platform/tests/html/semantics/links/linktypes/alternate-css.html
new file mode 100644
index 0000000000..366d6c5593
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/linktypes/alternate-css.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Alternate css</title>
+<link rel="match" href="alternate-css-ref.html">
+<link rel="stylesheet" href="preferred.css" title="preferred">
+<link rel="alternate stylesheet" href="alternate.css" title="alternate">
+<div>foobar</div>
diff --git a/testing/web-platform/tests/html/semantics/links/linktypes/alternate-import.css b/testing/web-platform/tests/html/semantics/links/linktypes/alternate-import.css
new file mode 100644
index 0000000000..7db3df1d78
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/linktypes/alternate-import.css
@@ -0,0 +1,3 @@
+body {
+ background-color: black;
+}
diff --git a/testing/web-platform/tests/html/semantics/links/linktypes/alternate.css b/testing/web-platform/tests/html/semantics/links/linktypes/alternate.css
new file mode 100644
index 0000000000..b101ab91f0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/linktypes/alternate.css
@@ -0,0 +1,5 @@
+@import url("alternate-import.css");
+
+div {
+ background-color: red;
+}
diff --git a/testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive-lower.css b/testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive-lower.css
new file mode 100644
index 0000000000..a19c9dfd72
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive-lower.css
@@ -0,0 +1 @@
+#z-lower:after { content: "PASS"; color: green; }
diff --git a/testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive-mixed.css b/testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive-mixed.css
new file mode 100644
index 0000000000..7389ea1a1a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive-mixed.css
@@ -0,0 +1 @@
+#z-mixed:after { content: "PASS"; color: green; }
diff --git a/testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive-other.css b/testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive-other.css
new file mode 100644
index 0000000000..a6c2616d86
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive-other.css
@@ -0,0 +1 @@
+#z-other:after { content: "FAIL"; color: red; }
diff --git a/testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive-ref.html b/testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive-ref.html
new file mode 100644
index 0000000000..5ac2432547
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<style>
+p:after { font-weight: bold; }
+p:after { content: "PASS"; color: green; }
+</style>
+<p>text/css treated as CSS?
+<p>TeXt/CsS treated as CSS?
+<p>text/cſs ignored?
diff --git a/testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive.css b/testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive.css
new file mode 100644
index 0000000000..5d647d0f2e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive.css
@@ -0,0 +1,3 @@
+p:after { font-weight: bold; }
+p:after { content: "FAIL"; color: red; }
+#z-other:after { content: "PASS"; color: green; }
diff --git a/testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive.html b/testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive.html
new file mode 100644
index 0000000000..39fd5520d2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/linktypes/link-type-stylesheet/process-stylesheet-linked-resource-ascii-case-insensitive.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="help" href="https://html.spec.whatwg.org/#link-type-stylesheet:process-the-linked-resource">
+<link rel="help" href="https://html.spec.whatwg.org/#content-type">
+<link rel="help" href="https://mimesniff.spec.whatwg.org/#mime-type-representation">
+<link rel="match" href="process-stylesheet-linked-resource-ascii-case-insensitive-ref.html">
+<meta name="assert" content="link@type values for stylesheet resources are ASCII case-insensitive">
+<link rel="stylesheet" href="process-stylesheet-linked-resource-ascii-case-insensitive.css">
+<link rel="stylesheet" href="process-stylesheet-linked-resource-ascii-case-insensitive-lower.css" type="text/css">
+<link rel="stylesheet" href="process-stylesheet-linked-resource-ascii-case-insensitive-mixed.css" type="TeXt/CsS">
+<link rel="stylesheet" href="process-stylesheet-linked-resource-ascii-case-insensitive-other.css" type="text/cſs">
+<p id="z-lower">text/css treated as CSS?
+<p id="z-mixed">TeXt/CsS treated as CSS?
+<p id="z-other">text/cſs ignored?
diff --git a/testing/web-platform/tests/html/semantics/links/linktypes/original-id.json b/testing/web-platform/tests/html/semantics/links/linktypes/original-id.json
new file mode 100644
index 0000000000..1e5f7b5ed3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/linktypes/original-id.json
@@ -0,0 +1 @@
+{"original_id":"linkTypes"} \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/links/linktypes/preferred.css b/testing/web-platform/tests/html/semantics/links/linktypes/preferred.css
new file mode 100644
index 0000000000..54b95ac280
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/linktypes/preferred.css
@@ -0,0 +1,3 @@
+div {
+ border: 4px solid green;
+}