Implement imagesrcset and imagesizes attributes on link rel=preload
https://bugs.webkit.org/show_bug.cgi?id=192950
Patch by Rob Buis <rbuis@igalia.com> on 2019-05-17
Reviewed by Youenn Fablet.
LayoutTests/imported/w3c:
Import relevant tests for this feature.
* web-platform-tests/preload/dynamic-adding-preload-imagesrcset-expected.txt: Added.
* web-platform-tests/preload/dynamic-adding-preload-imagesrcset.html: Added.
* web-platform-tests/preload/link-header-preload-delay-onload-expected.txt: Added.
* web-platform-tests/preload/link-header-preload-delay-onload.html: Added.
* web-platform-tests/preload/link-header-preload-delay-onload.html.headers: Added.
* web-platform-tests/preload/link-header-preload-expected.txt: Added.
* web-platform-tests/preload/link-header-preload-imagesrcset-expected.txt: Added.
* web-platform-tests/preload/link-header-preload-imagesrcset.html: Added.
* web-platform-tests/preload/link-header-preload-imagesrcset.html.headers: Added.
* web-platform-tests/preload/link-header-preload-nonce-expected.txt: Added.
* web-platform-tests/preload/link-header-preload-nonce.html: Added.
* web-platform-tests/preload/link-header-preload-nonce.html.headers: Added.
* web-platform-tests/preload/link-header-preload.html: Added.
* web-platform-tests/preload/link-header-preload.html.headers: Added.
* web-platform-tests/preload/onload-event-expected.txt: Added.
* web-platform-tests/preload/onload-event.html: Added.
* web-platform-tests/preload/preload-csp.sub-expected.txt:
* web-platform-tests/preload/preload-csp.sub.html:
* web-platform-tests/preload/preload-default-csp.sub-expected.txt:
* web-platform-tests/preload/preload-default-csp.sub.html:
* web-platform-tests/preload/preload-with-type-expected.txt: Added.
* web-platform-tests/preload/preload-with-type.html: Added.
* web-platform-tests/preload/resources/A4.ogv: Added.
* web-platform-tests/preload/resources/A4.ogv.sub.headers: Added.
* web-platform-tests/preload/resources/cross-origin-module.py: Added.
(main):
* web-platform-tests/preload/resources/dummy-preloads-subresource.css: Added.
* web-platform-tests/preload/resources/dummy-preloads-subresource.css.sub.headers: Added.
* web-platform-tests/preload/resources/empty.html: Added.
* web-platform-tests/preload/resources/empty.html.sub.headers: Added.
* web-platform-tests/preload/resources/foo.vtt.sub.headers: Added.
* web-platform-tests/preload/resources/module1.js: Added.
* web-platform-tests/preload/resources/module2.js: Added.
* web-platform-tests/preload/resources/preload_helper.js:
(verifyNumberOfResourceTimingEntries):
(numberOfResourceTimingEntries):
(verifyLoadedAndNoDoubleDownload):
* web-platform-tests/preload/single-download-preload-expected.txt:
* web-platform-tests/preload/single-download-preload.html:
Source/WebCore:
Implement imagesrcset and imagesizes attributes for both Link header
and link element.
Tests: imported/w3c/web-platform-tests/preload/dynamic-adding-preload-imagesrcset.html
imported/w3c/web-platform-tests/preload/link-header-preload-delay-onload.html
imported/w3c/web-platform-tests/preload/link-header-preload-imagesrcset.html
imported/w3c/web-platform-tests/preload/link-header-preload-nonce.html
imported/w3c/web-platform-tests/preload/link-header-preload.html
imported/w3c/web-platform-tests/preload/onload-event.html
imported/w3c/web-platform-tests/preload/preload-with-type.html
* html/HTMLAttributeNames.in:
* html/HTMLLinkElement.cpp:
(WebCore::HTMLLinkElement::process):
* html/HTMLLinkElement.idl:
* loader/LinkHeader.cpp:
(WebCore::paramterNameFromString):
(WebCore::LinkHeader::setValue):
(WebCore::LinkHeader::LinkHeader):
* loader/LinkHeader.h:
(WebCore::LinkHeader::imageSrcSet const):
(WebCore::LinkHeader::imageSizes const):
(WebCore::LinkHeader::isViewportDependent const):
* loader/LinkLoader.cpp:
(WebCore::LinkLoader::loadLinksFromHeader):
(WebCore::LinkLoader::preloadIfNeeded):
(WebCore::LinkLoader::loadLink):
* loader/LinkLoader.h:
LayoutTests:
Write special expectation for link-header-preload-imagesrcset.html because test runner
uses different dimensions on iOS.
* platform/ios-simulator-12-wk2/imported/w3c/web-platform-tests/preload/dynamic-adding-preload-imagesrcset-expected.txt: Added.
* platform/ios-simulator-12-wk2/imported/w3c/web-platform-tests/preload/link-header-preload-imagesrcset-expected.txt: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@245475 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index e15385e..3f60e38 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,16 @@
+2019-05-17 Rob Buis <rbuis@igalia.com>
+
+ Implement imagesrcset and imagesizes attributes on link rel=preload
+ https://bugs.webkit.org/show_bug.cgi?id=192950
+
+ Reviewed by Youenn Fablet.
+
+ Write special expectation for link-header-preload-imagesrcset.html because test runner
+ uses different dimensions on iOS.
+
+ * platform/ios-simulator-12-wk2/imported/w3c/web-platform-tests/preload/dynamic-adding-preload-imagesrcset-expected.txt: Added.
+ * platform/ios-simulator-12-wk2/imported/w3c/web-platform-tests/preload/link-header-preload-imagesrcset-expected.txt: Added.
+
2019-05-17 Shawn Roberts <sroberts@apple.com>
media/controls-after-reload.html failing on iOS after unskip
diff --git a/LayoutTests/imported/w3c/ChangeLog b/LayoutTests/imported/w3c/ChangeLog
index 7e0e47b..b9152e7 100644
--- a/LayoutTests/imported/w3c/ChangeLog
+++ b/LayoutTests/imported/w3c/ChangeLog
@@ -1,3 +1,52 @@
+2019-05-17 Rob Buis <rbuis@igalia.com>
+
+ Implement imagesrcset and imagesizes attributes on link rel=preload
+ https://bugs.webkit.org/show_bug.cgi?id=192950
+
+ Reviewed by Youenn Fablet.
+
+ Import relevant tests for this feature.
+
+ * web-platform-tests/preload/dynamic-adding-preload-imagesrcset-expected.txt: Added.
+ * web-platform-tests/preload/dynamic-adding-preload-imagesrcset.html: Added.
+ * web-platform-tests/preload/link-header-preload-delay-onload-expected.txt: Added.
+ * web-platform-tests/preload/link-header-preload-delay-onload.html: Added.
+ * web-platform-tests/preload/link-header-preload-delay-onload.html.headers: Added.
+ * web-platform-tests/preload/link-header-preload-expected.txt: Added.
+ * web-platform-tests/preload/link-header-preload-imagesrcset-expected.txt: Added.
+ * web-platform-tests/preload/link-header-preload-imagesrcset.html: Added.
+ * web-platform-tests/preload/link-header-preload-imagesrcset.html.headers: Added.
+ * web-platform-tests/preload/link-header-preload-nonce-expected.txt: Added.
+ * web-platform-tests/preload/link-header-preload-nonce.html: Added.
+ * web-platform-tests/preload/link-header-preload-nonce.html.headers: Added.
+ * web-platform-tests/preload/link-header-preload.html: Added.
+ * web-platform-tests/preload/link-header-preload.html.headers: Added.
+ * web-platform-tests/preload/onload-event-expected.txt: Added.
+ * web-platform-tests/preload/onload-event.html: Added.
+ * web-platform-tests/preload/preload-csp.sub-expected.txt:
+ * web-platform-tests/preload/preload-csp.sub.html:
+ * web-platform-tests/preload/preload-default-csp.sub-expected.txt:
+ * web-platform-tests/preload/preload-default-csp.sub.html:
+ * web-platform-tests/preload/preload-with-type-expected.txt: Added.
+ * web-platform-tests/preload/preload-with-type.html: Added.
+ * web-platform-tests/preload/resources/A4.ogv: Added.
+ * web-platform-tests/preload/resources/A4.ogv.sub.headers: Added.
+ * web-platform-tests/preload/resources/cross-origin-module.py: Added.
+ (main):
+ * web-platform-tests/preload/resources/dummy-preloads-subresource.css: Added.
+ * web-platform-tests/preload/resources/dummy-preloads-subresource.css.sub.headers: Added.
+ * web-platform-tests/preload/resources/empty.html: Added.
+ * web-platform-tests/preload/resources/empty.html.sub.headers: Added.
+ * web-platform-tests/preload/resources/foo.vtt.sub.headers: Added.
+ * web-platform-tests/preload/resources/module1.js: Added.
+ * web-platform-tests/preload/resources/module2.js: Added.
+ * web-platform-tests/preload/resources/preload_helper.js:
+ (verifyNumberOfResourceTimingEntries):
+ (numberOfResourceTimingEntries):
+ (verifyLoadedAndNoDoubleDownload):
+ * web-platform-tests/preload/single-download-preload-expected.txt:
+ * web-platform-tests/preload/single-download-preload.html:
+
2019-05-14 Oriol Brufau <obrufau@igalia.com>
[css-grid] Update grid when changing auto repeat type
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/dynamic-adding-preload-imagesrcset-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/preload/dynamic-adding-preload-imagesrcset-expected.txt
new file mode 100644
index 0000000..834fc93
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/dynamic-adding-preload-imagesrcset-expected.txt
@@ -0,0 +1,3 @@
+
+PASS Makes sure that a dynamically added preload with imagesrcset works
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/dynamic-adding-preload-imagesrcset.html b/LayoutTests/imported/w3c/web-platform-tests/preload/dynamic-adding-preload-imagesrcset.html
new file mode 100644
index 0000000..e1b8431
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/dynamic-adding-preload-imagesrcset.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/preload/resources/preload_helper.js"></script>
+<script>
+ var t = async_test('Makes sure that a dynamically added preload with imagesrcset works');
+</script>
+<body>
+<script>
+ t.step(function() {
+ verifyPreloadAndRTSupport();
+ var link = document.createElement("link");
+ link.as = "image";
+ link.rel = "preload";
+ link.href = "resources/square.png?default";
+ link.imageSrcset = "resources/square.png?200 200w, resources/square.png?400 400w, resources/square.png?800 800w";
+ link.imageSizes = "400px";
+ link.onload = t.step_func(function() {
+ t.step_timeout(function() {
+ verifyNumberOfResourceTimingEntries("resources/square.png?default", 0);
+ verifyNumberOfResourceTimingEntries("resources/square.png?200", 0);
+ verifyNumberOfResourceTimingEntries("resources/square.png?400", 1);
+ verifyNumberOfResourceTimingEntries("resources/square.png?800", 0);
+ t.done();
+ }, 0);
+ });
+ document.body.appendChild(link);
+ });
+</script>
+</body>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-delay-onload-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-delay-onload-expected.txt
new file mode 100644
index 0000000..93d88524
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-delay-onload-expected.txt
@@ -0,0 +1,4 @@
+
+
+PASS Makes sure that Link headers preload resources and block window.onload after resource discovery
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-delay-onload.html b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-delay-onload.html
new file mode 100644
index 0000000..a445d80
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-delay-onload.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/preload/resources/preload_helper.js"></script>
+<script>
+ var t = async_test('Makes sure that Link headers preload resources and block window.onload after resource discovery');
+</script>
+<body>
+<style>
+ #background {
+ width: 200px;
+ height: 200px;
+ background-image: url(resources/square.png?background);
+ }
+</style>
+<link rel="stylesheet" href="resources/dummy.css?link-header-preload-delay-onload">
+<script src="resources/dummy.js?link-header-preload-delay-onload"></script>
+<div id="background"></div>
+<script>
+ document.write('<img src="resources/square.png?link-header-preload-delay-onload">');
+ window.addEventListener("load", t.step_func(function() {
+ verifyPreloadAndRTSupport();
+ var entries = performance.getEntriesByType("resource");
+ var found_background_first = false;
+ for (var i = 0; i < entries.length; ++i) {
+ var entry = entries[i];
+ if (entry.name.indexOf("square") != -1) {
+ if (entry.name.indexOf("background") != -1)
+ found_background_first = true;
+ break;
+ }
+ }
+ assert_true(found_background_first);
+ verifyLoadedAndNoDoubleDownload("resources/square.png?link-header-preload-delay-onload");
+ verifyLoadedAndNoDoubleDownload("resources/square.png?background");
+ verifyLoadedAndNoDoubleDownload("resources/dummy.js?link-header-preload-delay-onload");
+ verifyLoadedAndNoDoubleDownload("resources/dummy.css?link-header-preload-delay-onload");
+ t.done();
+ }));
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-delay-onload.html.headers b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-delay-onload.html.headers
new file mode 100644
index 0000000..a9ca424
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-delay-onload.html.headers
@@ -0,0 +1,5 @@
+Link: </preload/resources/square.png?background>;rel=preload;as=image
+Link: </preload/resources/dummy.js?link-header-preload-delay-onload>;rel=preload;as=script
+Link: </preload/resources/dummy.css?link-header-preload-delay-onload>;rel=preload;as=style
+Link: </preload/resources/square.png?link-header-preload-delay-onload>;rel=preload;as=image
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-expected.txt
new file mode 100644
index 0000000..94c4b44
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-expected.txt
@@ -0,0 +1,3 @@
+
+PASS Makes sure that Link headers preload resources
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-imagesrcset-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-imagesrcset-expected.txt
new file mode 100644
index 0000000..4a35913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-imagesrcset-expected.txt
@@ -0,0 +1,3 @@
+
+PASS Makes sure that Link headers preload images with imagesrcset/imagesizes attributes.
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-imagesrcset.html b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-imagesrcset.html
new file mode 100644
index 0000000..b41cbee
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-imagesrcset.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<title>Makes sure that Link headers preload images with imagesrcset/imagesizes attributes.</title>
+<link rel="help" href="https://github.com/w3c/preload/issues/120">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/preload/resources/preload_helper.js"></script>
+<body>
+<script>
+ setup({explicit_done: true});
+
+ var iterations = 0;
+
+ function check_finished() {
+ if (numberOfResourceTimingEntries('resources/square.png?from-header&1x') == 1 &&
+ numberOfResourceTimingEntries('resources/square.png?from-header&2x') == 0 &&
+ numberOfResourceTimingEntries('resources/square.png?from-header&3x') == 0 &&
+ numberOfResourceTimingEntries('resources/square.png?from-header&base') == 0 &&
+ numberOfResourceTimingEntries('resources/square.png?from-header&200') == 0 &&
+ numberOfResourceTimingEntries('resources/square.png?from-header&400') == 1 &&
+ numberOfResourceTimingEntries('resources/square.png?from-header&800') == 0 &&
+ numberOfResourceTimingEntries('resources/square.png?from-header&150') == 0 &&
+ numberOfResourceTimingEntries('resources/square.png?from-header&300') == 1 &&
+ numberOfResourceTimingEntries('resources/square.png?from-header&600') == 0) {
+ done();
+ }
+ iterations++;
+ if (iterations == 10) {
+ // At least one is expected to fail, but this should give details to the exact failure(s).
+ verifyNumberOfResourceTimingEntries('resources/square.png?from-header&1x', 1);
+ verifyNumberOfResourceTimingEntries('resources/square.png?from-header&2x', 0);
+ verifyNumberOfResourceTimingEntries('resources/square.png?from-header&3x', 0);
+ verifyNumberOfResourceTimingEntries('resources/square.png?from-header&base', 0);
+ verifyNumberOfResourceTimingEntries('resources/square.png?from-header&200', 0);
+ verifyNumberOfResourceTimingEntries('resources/square.png?from-header&400', 1);
+ verifyNumberOfResourceTimingEntries('resources/square.png?from-header&800', 0);
+ verifyNumberOfResourceTimingEntries('resources/square.png?from-header&150', 0);
+ verifyNumberOfResourceTimingEntries('resources/square.png?from-header&300', 1);
+ verifyNumberOfResourceTimingEntries('resources/square.png?from-header&600', 0);
+ done();
+ } else {
+ step_timeout(check_finished, 500);
+ }
+ }
+
+ window.addEventListener("load", function() {
+ verifyPreloadAndRTSupport();
+ step_timeout(check_finished, 500);
+ });
+</script>
+</body>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-imagesrcset.html.headers b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-imagesrcset.html.headers
new file mode 100644
index 0000000..906de0c
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-imagesrcset.html.headers
@@ -0,0 +1,3 @@
+Link: <resources/square.png?from-header&1x>; rel=preload; as=image; imagesrcset="resources/square.png?from-header&2x 2x, resources/square.png?from-header&3x 3x"
+Link: <resources/square.png?from-header&base>; rel=preload; as=image; imagesrcset="resources/square.png?from-header&200 200w, resources/square.png?from-header&400 400w, resources/square.png?from-header&800 800w"; imagesizes=400px
+Link: <resources/square.png?from-header&base>; rel=preload; as=image; imagesrcset="resources/square.png?from-header&150 150w, resources/square.png?from-header&300 300w, resources/square.png?from-header&600 600w"; imagesizes="(min-width: 300px) 300px, 150px"
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-nonce-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-nonce-expected.txt
new file mode 100644
index 0000000..3f6ce93
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-nonce-expected.txt
@@ -0,0 +1,6 @@
+CONSOLE MESSAGE: Refused to load http://localhost:8800/preload/resources/dummy.js?from-header&without-nonce because it does not appear in the script-src directive of the Content Security Policy.
+CONSOLE MESSAGE: Refused to load http://localhost:8800/preload/resources/dummy.js?from-header&with-nonce because it does not appear in the script-src directive of the Content Security Policy.
+CONSOLE MESSAGE: line 2659: Error: assert_equals: resources/dummy.js?from-header&with-nonce expected 1 but got 0
+
+FAIL Makes sure that Link headers preload resources with CSP nonce Error: assert_equals: resources/dummy.js?from-header&with-nonce expected 1 but got 0
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-nonce.html b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-nonce.html
new file mode 100644
index 0000000..bfac563
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-nonce.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<title>Makes sure that Link headers preload resources with CSP nonce</title>
+<script nonce="abc" src="/resources/testharness.js"></script>
+<script nonce="abc" src="/resources/testharnessreport.js"></script>
+<script nonce="abc" src="/preload/resources/preload_helper.js"></script>
+<body>
+<script nonce="abc">
+ setup({explicit_done: true});
+
+ var iterations = 0;
+
+ function check_finished() {
+ if (numberOfResourceTimingEntries("resources/dummy.js?from-header&without-nonce") == 0 &&
+ numberOfResourceTimingEntries("resources/dummy.js?from-header&with-nonce") == 1) {
+ done();
+ }
+ iterations++;
+ if (iterations == 10) {
+ // At least one is expected to fail, but this should give details to the exact failure(s).
+ verifyNumberOfResourceTimingEntries("resources/dummy.js?from-header&without-nonce", 0);
+ verifyNumberOfResourceTimingEntries("resources/dummy.js?from-header&with-nonce", 1);
+ done();
+ } else {
+ step_timeout(check_finished, 500);
+ }
+ }
+
+ window.addEventListener("load", function() {
+ verifyPreloadAndRTSupport();
+ step_timeout(check_finished, 500);
+ });
+</script>
+</body>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-nonce.html.headers b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-nonce.html.headers
new file mode 100644
index 0000000..a54b693
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-nonce.html.headers
@@ -0,0 +1,3 @@
+Content-Security-Policy: script-src 'nonce-abc'
+Link: </preload/resources/dummy.js?from-header&without-nonce>;rel=preload;as=script
+Link: </preload/resources/dummy.js?from-header&with-nonce>;rel=preload;as=script;nonce=abc
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload.html b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload.html
new file mode 100644
index 0000000..4dfdfc8
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<title>Makes sure that Link headers preload resources</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/preload/resources/preload_helper.js"></script>
+<body>
+<script>
+ setup({explicit_done: true});
+
+ var iterations = 0;
+
+ function check_finished() {
+ if (numberOfResourceTimingEntries("resources/square.png?link-header-preload") == 1 &&
+ numberOfResourceTimingEntries("resources/dummy.js?link-header-preload") == 1 &&
+ numberOfResourceTimingEntries("resources/dummy.css?link-header-preload") == 1) {
+ done();
+ }
+ iterations++;
+ if (iterations == 10) {
+ // At least one is expected to fail, but this should give details to the exact failure(s).
+ verifyNumberOfResourceTimingEntries("resources/square.png?link-header-preload", 1);
+ verifyNumberOfResourceTimingEntries("resources/dummy.js?link-header-preload", 1);
+ verifyNumberOfResourceTimingEntries("resources/dummy.css?link-header-preload", 1);
+ done();
+ } else {
+ step_timeout(check_finished, 500);
+ }
+ }
+
+ window.addEventListener("load", function() {
+ verifyPreloadAndRTSupport();
+ step_timeout(check_finished, 500);
+ });
+</script>
+</body>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload.html.headers b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload.html.headers
new file mode 100644
index 0000000..293598e
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload.html.headers
@@ -0,0 +1,4 @@
+Link: </preload/resources/dummy.js?link-header-preload>;rel=preload;as=script
+Link: </preload/resources/dummy.css?link-header-preload>;rel=preload;as=style
+Link: </preload/resources/square.png?link-header-preload>;rel=preload;as=image
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/onload-event-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/preload/onload-event-expected.txt
new file mode 100644
index 0000000..0fb9be3
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/onload-event-expected.txt
@@ -0,0 +1,5 @@
+CONSOLE MESSAGE: line 26: <link rel=preload> must have a valid `as` value
+CONSOLE MESSAGE: line 28: <link rel=preload> must have a valid `as` value
+
+PASS Makes sure that preloaded resources trigger the onload event
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/onload-event.html b/LayoutTests/imported/w3c/web-platform-tests/preload/onload-event.html
new file mode 100644
index 0000000..9111cd8
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/onload-event.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<title>Makes sure that preloaded resources trigger the onload event</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/preload/resources/preload_helper.js"></script>
+<script>
+ var scriptLoaded = false;
+ var styleLoaded = false;
+ var imageLoaded = false;
+ var fontLoaded = false;
+ var videoLoaded = false;
+ var audioLoaded = false;
+ var trackLoaded = false;
+ var gibberishLoaded = false;
+ var gibberishErrored = false;
+ var noTypeLoaded = false;
+ var fetchLoaded = false;
+</script>
+<link rel=preload href="resources/dummy.js" as=script onload="scriptLoaded = true;">
+<link rel=preload href="resources/dummy.css" as=style onload="styleLoaded = true;">
+<link rel=preload href="resources/square.png" as=image onload="imageLoaded = true;">
+<link rel=preload href="/fonts/CanvasTest.ttf" as=font crossorigin onload="fontLoaded = true;">
+<link rel=preload href="resources/white.mp4" as=video onload="videoLoaded = true;">
+<link rel=preload href="resources/sound_5.oga" as=audio onload="audioLoaded = true;">
+<link rel=preload href="resources/foo.vtt" as=track onload="trackLoaded = true;">
+<link rel=preload href="resources/dummy.xml?foo=bar" as=foobarxmlthing onload="gibberishLoaded = true;" onerror="gibberishErrored = true;">
+<link rel=preload href="resources/dummy.xml?fetch" as=fetch onload="fetchLoaded = true;">
+<link rel=preload href="resources/dummy.xml" onload="noTypeLoaded = true;">
+<body>
+<script>
+ setup({explicit_done: true});
+
+ var iterations = 0;
+
+ function check_finished() {
+ if (styleLoaded && scriptLoaded && imageLoaded && fontLoaded && videoLoaded && audioLoaded &&
+ trackLoaded && !gibberishLoaded && !gibberishErrored && fetchLoaded && !noTypeLoaded) {
+ done();
+ }
+ iterations++;
+ if (iterations == 10) {
+ // At least one is expected to fail, but this should give details to the exact failure(s).
+ assert_true(styleLoaded, "style triggered load event");
+ assert_true(scriptLoaded, "script triggered load event");
+ assert_true(imageLoaded, "image triggered load event");
+ assert_true(fontLoaded, "font triggered load event");
+ assert_true(videoLoaded, "video triggered load event");
+ assert_true(audioLoaded, "audio triggered load event");
+ assert_true(trackLoaded, "track triggered load event");
+ assert_false(gibberishLoaded, "gibberish as value triggered load event");
+ assert_false(gibberishErrored, "gibberish as value triggered error event");
+ assert_true(fetchLoaded, "fetch as value triggered load event");
+ assert_false(noTypeLoaded, "empty as triggered load event");
+ done();
+ } else {
+ step_timeout(check_finished, 500);
+ }
+ }
+
+ window.addEventListener("load", function() {
+ verifyPreloadAndRTSupport();
+ step_timeout(check_finished, 500);
+ });
+</script>
+</body>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/preload-csp.sub-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/preload/preload-csp.sub-expected.txt
index f6668c7..2a61cb6 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/preload/preload-csp.sub-expected.txt
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/preload-csp.sub-expected.txt
@@ -12,8 +12,8 @@
CONSOLE MESSAGE: Refused to load http://localhost:8800/preload/resources/white.mp4 because it does not appear in the media-src directive of the Content Security Policy.
CONSOLE MESSAGE: Refused to load http://localhost:8800/preload/resources/sound_5.oga because it does not appear in the media-src directive of the Content Security Policy.
CONSOLE MESSAGE: Refused to load http://localhost:8800/preload/resources/foo.vtt because it does not appear in the media-src directive of the Content Security Policy.
-CONSOLE MESSAGE: line 16: <link rel=preload> must have a valid `as` value
-CONSOLE MESSAGE: line 17: <link rel=preload> must have a valid `as` value
+CONSOLE MESSAGE: line 14: <link rel=preload> must have a valid `as` value
+CONSOLE MESSAGE: line 15: <link rel=preload> must have a valid `as` value
PASS Makes sure that preload requests respect CSP
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/preload-csp.sub.html b/LayoutTests/imported/w3c/web-platform-tests/preload/preload-csp.sub.html
index 7fe06eb..62d0c71 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/preload/preload-csp.sub.html
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/preload-csp.sub.html
@@ -1,11 +1,9 @@
<!DOCTYPE html>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'; font-src 'none'; style-src 'none'; img-src 'none'; media-src 'none'; connect-src 'none'">
+<title>Makes sure that preload requests respect CSP</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/preload/resources/preload_helper.js"></script>
-<script>
- var t = async_test('Makes sure that preload requests respect CSP');
-</script>
<link rel=preload href="{{host}}:{{ports[http][1]}}/preload/resources/dummy.js" as=style>
<link rel=preload href="resources/dummy.css" as=style>
<link rel=preload href="resources/square.png" as=image>
@@ -17,9 +15,24 @@
<link rel=preload href="resources/dummy.xml">
<body>
<script>
- window.onload = t.step_func(function() {
- t.step_timeout(function() {
- verifyPreloadAndRTSupport();
+ setup({explicit_done: true});
+
+ var iterations = 0;
+
+ function check_finished() {
+ if (numberOfResourceTimingEntries("{{host}}:{{ports[http][1]}}/preload/resources/dummy.js") == 0 &&
+ numberOfResourceTimingEntries("resources/dummy.css") == 0 &&
+ numberOfResourceTimingEntries("resources/square.png") == 0 &&
+ numberOfResourceTimingEntries("/fonts/CanvasTest.ttf") == 0 &&
+ numberOfResourceTimingEntries("resources/white.mp4") == 0 &&
+ numberOfResourceTimingEntries("resources/sound_5.oga") == 0 &&
+ numberOfResourceTimingEntries("resources/foo.vtt") == 0 &&
+ numberOfResourceTimingEntries("resources/dummy.xml") == 0) {
+ done();
+ }
+ iterations++;
+ if (iterations == 10) {
+ // At least one is expected to fail, but this should give details to the exact failure(s).
verifyNumberOfResourceTimingEntries("{{host}}:{{ports[http][1]}}/preload/resources/dummy.js", 0);
verifyNumberOfResourceTimingEntries("resources/dummy.css", 0);
verifyNumberOfResourceTimingEntries("resources/square.png", 0);
@@ -28,8 +41,15 @@
verifyNumberOfResourceTimingEntries("resources/sound_5.oga", 0);
verifyNumberOfResourceTimingEntries("resources/foo.vtt", 0);
verifyNumberOfResourceTimingEntries("resources/dummy.xml", 0);
- t.done();
- }, 5000);
+ done();
+ } else {
+ step_timeout(check_finished, 500);
+ }
+ }
+
+ window.addEventListener("load", function() {
+ verifyPreloadAndRTSupport();
+ step_timeout(check_finished, 500);
});
</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/preload-default-csp.sub-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/preload/preload-default-csp.sub-expected.txt
index 30cbfd5..f0fa7f2 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/preload/preload-default-csp.sub-expected.txt
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/preload-default-csp.sub-expected.txt
@@ -12,8 +12,8 @@
CONSOLE MESSAGE: Refused to load http://localhost:8800/preload/resources/white.mp4 because it appears in neither the media-src directive nor the default-src directive of the Content Security Policy.
CONSOLE MESSAGE: Refused to load http://localhost:8800/preload/resources/sound_5.oga because it appears in neither the media-src directive nor the default-src directive of the Content Security Policy.
CONSOLE MESSAGE: Refused to load http://localhost:8800/preload/resources/foo.vtt because it appears in neither the media-src directive nor the default-src directive of the Content Security Policy.
-CONSOLE MESSAGE: line 16: <link rel=preload> must have a valid `as` value
-CONSOLE MESSAGE: line 17: <link rel=preload> must have a valid `as` value
+CONSOLE MESSAGE: line 14: <link rel=preload> must have a valid `as` value
+CONSOLE MESSAGE: line 15: <link rel=preload> must have a valid `as` value
PASS Makes sure that preload requests respect CSP
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/preload-default-csp.sub.html b/LayoutTests/imported/w3c/web-platform-tests/preload/preload-default-csp.sub.html
index 7813e36..9fc1194 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/preload/preload-default-csp.sub.html
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/preload-default-csp.sub.html
@@ -1,11 +1,9 @@
<!DOCTYPE html>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'; default-src 'none'">
+<title>Makes sure that preload requests respect CSP</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/preload/resources/preload_helper.js"></script>
-<script>
- var t = async_test('Makes sure that preload requests respect CSP');
-</script>
<link rel=preload href="{{host}}:{{ports[http][1]}}/preload/resources/dummy.js" as=style>
<link rel=preload href="resources/dummy.css" as=style>
<link rel=preload href="resources/square.png" as=image>
@@ -17,9 +15,24 @@
<link rel=preload href="resources/dummy.xml">
<body>
<script>
- window.onload = t.step_func(function() {
- t.step_timeout(function() {
- verifyPreloadAndRTSupport();
+ setup({explicit_done: true});
+
+ var iterations = 0;
+
+ function check_finished() {
+ if (numberOfResourceTimingEntries("{{host}}:{{ports[http][1]}}/preload/resources/dummy.js") == 0 &&
+ numberOfResourceTimingEntries("resources/dummy.css") == 0 &&
+ numberOfResourceTimingEntries("resources/square.png") == 0 &&
+ numberOfResourceTimingEntries("/fonts/CanvasTest.ttf") == 0 &&
+ numberOfResourceTimingEntries("resources/white.mp4") == 0 &&
+ numberOfResourceTimingEntries("resources/sound_5.oga") == 0 &&
+ numberOfResourceTimingEntries("resources/foo.vtt") == 0 &&
+ numberOfResourceTimingEntries("resources/dummy.xml") == 0) {
+ done();
+ }
+ iterations++;
+ if (iterations == 10) {
+ // At least one is expected to fail, but this should give details to the exact failure(s).
verifyNumberOfResourceTimingEntries("{{host}}:{{ports[http][1]}}/preload/resources/dummy.js", 0);
verifyNumberOfResourceTimingEntries("resources/dummy.css", 0);
verifyNumberOfResourceTimingEntries("resources/square.png", 0);
@@ -28,8 +41,15 @@
verifyNumberOfResourceTimingEntries("resources/sound_5.oga", 0);
verifyNumberOfResourceTimingEntries("resources/foo.vtt", 0);
verifyNumberOfResourceTimingEntries("resources/dummy.xml", 0);
- t.done();
- }, 5000);
+ done();
+ } else {
+ step_timeout(check_finished, 500);
+ }
+ }
+
+ window.addEventListener("load", function() {
+ verifyPreloadAndRTSupport();
+ step_timeout(check_finished, 500);
});
</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/preload-with-type-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/preload/preload-with-type-expected.txt
new file mode 100644
index 0000000..1532e8c
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/preload-with-type-expected.txt
@@ -0,0 +1,3 @@
+
+PASS Makes sure that preloaded resources with a type attribute trigger the onload event
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/preload-with-type.html b/LayoutTests/imported/w3c/web-platform-tests/preload/preload-with-type.html
new file mode 100644
index 0000000..9805922
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/preload-with-type.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<title>Makes sure that preloaded resources with a type attribute trigger the onload event</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/preload/resources/preload_helper.js"></script>
+<script src="/common/media.js"></script>
+<script>
+ var scriptLoaded = false;
+ var styleLoaded = false;
+ var imageLoaded = false;
+ var fontLoaded = false;
+ var videoLoaded = false;
+ var audioLoaded = false;
+ var trackLoaded = false;
+ var gibberishLoaded = 0;
+ var getFormat = function(url) {
+ var dot = url.lastIndexOf('.');
+ if (dot != -1) {
+ var extension = url.substring(dot + 1);
+ if (extension.startsWith("og"))
+ return "ogg";
+ return extension;
+ }
+ return null;
+ };
+ var videoURL = getVideoURI("resources/A4");
+ var audioURL = getAudioURI("resources/sound_5");
+ var videoFormat = getFormat(videoURL);
+ var audioFormat = getFormat(audioURL);
+</script>
+<link rel=preload href="resources/dummy.js" as=script type="text/javascript" onload="scriptLoaded = true;">
+<link rel=preload href="resources/dummy.css" as=style type="text/css" onload="styleLoaded = true;">
+<link rel=preload href="resources/square.png" as=image type="image/png" onload="imageLoaded = true;">
+<link rel=preload href="/fonts/CanvasTest.ttf" as=font type="font/ttf" crossorigin onload="fontLoaded = true;">
+<script>
+ document.write('<link rel=preload href="' + videoURL + '" as=video type="video/' + videoFormat + '" onload="videoLoaded = true;">');
+ document.write('<link rel=preload href="' + audioURL + '" as=audio type="audio/' + audioFormat + '" onload="audioLoaded = true;">');
+</script>
+<link rel=preload href="resources/foo.vtt" as=track type="text/vtt" onload="trackLoaded = true;">
+<link rel=preload href="resources/dummy.js" as=script type="application/foobar" onload="gibberishLoaded++;">
+<link rel=preload href="resources/dummy.css" as=style type="text/foobar" onload="gibberishLoaded++;">
+<link rel=preload href="resources/square.png" as=image type="image/foobar" onload="gibberishLoaded++;">
+<link rel=preload href="/fonts/CanvasTest.ttf" as=font type="font/foobar" crossorigin onload="gibberishLoaded++;">
+<script>
+ document.write('<link rel=preload href="' + videoURL + '" as=video type="video/foobar" onload="gibberishLoaded++;">');
+ document.write('<link rel=preload href="' + audioURL + '" as=audio type="audio/foobar" onload="gibberishLoaded++;">');
+</script>
+<link rel=preload href="resources/foo.vtt" as=track type="text/foobar" onload="gibberishLoaded++;">
+<body>
+<script>
+ setup({explicit_done: true});
+
+ var iterations = 0;
+
+ function check_finished() {
+ if (styleLoaded && scriptLoaded && imageLoaded && fontLoaded && videoLoaded && audioLoaded &&
+ trackLoaded && gibberishLoaded == 0) {
+ done();
+ }
+ iterations++;
+ if (iterations == 10) {
+ // At least one is expected to fail, but this should give details to the exact failure(s).
+ assert_true(styleLoaded, "style triggered load event");
+ assert_true(scriptLoaded, "script triggered load event");
+ assert_true(imageLoaded, "image triggered load event");
+ assert_true(fontLoaded, "font triggered load event");
+ assert_true(videoLoaded, "video triggered load event");
+ assert_true(audioLoaded, "audio triggered load event");
+ assert_true(trackLoaded, "track triggered load event");
+ assert_equals(gibberishLoaded, 0, "resources with gibberish type should not be loaded");
+ done();
+ } else {
+ step_timeout(check_finished, 500);
+ }
+ }
+
+ window.addEventListener("load", function() {
+ verifyPreloadAndRTSupport();
+ step_timeout(check_finished, 500);
+ });
+</script>
+</body>
+</html>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/resources/A4.ogv b/LayoutTests/imported/w3c/web-platform-tests/preload/resources/A4.ogv
new file mode 100644
index 0000000..de99616
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/resources/A4.ogv
Binary files differ
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/resources/A4.ogv.sub.headers b/LayoutTests/imported/w3c/web-platform-tests/preload/resources/A4.ogv.sub.headers
new file mode 100644
index 0000000..360e668
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/resources/A4.ogv.sub.headers
@@ -0,0 +1 @@
+Cache-Control: max-age=1000
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/resources/cross-origin-module.py b/LayoutTests/imported/w3c/web-platform-tests/preload/resources/cross-origin-module.py
new file mode 100644
index 0000000..f771c96
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/resources/cross-origin-module.py
@@ -0,0 +1,9 @@
+def main(request, response):
+ headers = [
+ ("Content-Type", "text/javascript"),
+ ("Access-Control-Allow-Origin", request.headers.get("Origin")),
+ ("Timing-Allow-Origin", request.headers.get("Origin")),
+ ("Access-Control-Allow-Credentials", "true")
+ ]
+
+ return headers, "// Cross-origin module, nothing to see here"
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/resources/dummy-preloads-subresource.css b/LayoutTests/imported/w3c/web-platform-tests/preload/resources/dummy-preloads-subresource.css
new file mode 100644
index 0000000..5097166
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/resources/dummy-preloads-subresource.css
@@ -0,0 +1 @@
+/* This is just a dummy, empty CSS file */
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/resources/dummy-preloads-subresource.css.sub.headers b/LayoutTests/imported/w3c/web-platform-tests/preload/resources/dummy-preloads-subresource.css.sub.headers
new file mode 100644
index 0000000..f6b4b49
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/resources/dummy-preloads-subresource.css.sub.headers
@@ -0,0 +1,2 @@
+Cache-Control: max-age=1000
+Link: </fonts/CanvasTest.ttf?link-header-on-subresource>; rel=preload;as=font;crossorigin
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/resources/empty.html b/LayoutTests/imported/w3c/web-platform-tests/preload/resources/empty.html
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/resources/empty.html
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/resources/empty.html.sub.headers b/LayoutTests/imported/w3c/web-platform-tests/preload/resources/empty.html.sub.headers
new file mode 100644
index 0000000..360e668
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/resources/empty.html.sub.headers
@@ -0,0 +1 @@
+Cache-Control: max-age=1000
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/resources/foo.vtt.sub.headers b/LayoutTests/imported/w3c/web-platform-tests/preload/resources/foo.vtt.sub.headers
new file mode 100644
index 0000000..360e668
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/resources/foo.vtt.sub.headers
@@ -0,0 +1 @@
+Cache-Control: max-age=1000
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/resources/module1.js b/LayoutTests/imported/w3c/web-platform-tests/preload/resources/module1.js
new file mode 100644
index 0000000..9c3b675
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/resources/module1.js
@@ -0,0 +1,2 @@
+import { y } from './module2.js';
+export let x = y + 1;
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/resources/module2.js b/LayoutTests/imported/w3c/web-platform-tests/preload/resources/module2.js
new file mode 100644
index 0000000..e4e3217
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/resources/module2.js
@@ -0,0 +1 @@
+export let y = 1;
diff --git a/LayoutTests/imported/w3c/web-platform-tests/preload/resources/preload_helper.js b/LayoutTests/imported/w3c/web-platform-tests/preload/resources/preload_helper.js
index f464908..1c7c1a2 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/preload/resources/preload_helper.js
+++ b/LayoutTests/imported/w3c/web-platform-tests/preload/resources/preload_helper.js
@@ -12,8 +12,12 @@
function verifyNumberOfResourceTimingEntries(url, number)
{
- var numEntries = performance.getEntriesByName(getAbsoluteURL(url)).length;
- assert_equals(numEntries, number, url);
+ assert_equals(numberOfResourceTimingEntries(url), number, url);
+}
+
+function numberOfResourceTimingEntries(url)
+{
+ return performance.getEntriesByName(getAbsoluteURL(url)).length;
}
// Verifies that the resource is loaded, but not downloaded from network
diff --git a/LayoutTests/platform/ios-simulator-12-wk2/imported/w3c/web-platform-tests/preload/dynamic-adding-preload-imagesrcset-expected.txt b/LayoutTests/platform/ios-simulator-12-wk2/imported/w3c/web-platform-tests/preload/dynamic-adding-preload-imagesrcset-expected.txt
new file mode 100644
index 0000000..cf91b1a
--- /dev/null
+++ b/LayoutTests/platform/ios-simulator-12-wk2/imported/w3c/web-platform-tests/preload/dynamic-adding-preload-imagesrcset-expected.txt
@@ -0,0 +1,3 @@
+
+FAIL Makes sure that a dynamically added preload with imagesrcset works assert_equals: resources/square.png?400 expected 1 but got 0
+
diff --git a/LayoutTests/platform/ios-simulator-12-wk2/imported/w3c/web-platform-tests/preload/link-header-preload-imagesrcset-expected.txt b/LayoutTests/platform/ios-simulator-12-wk2/imported/w3c/web-platform-tests/preload/link-header-preload-imagesrcset-expected.txt
new file mode 100644
index 0000000..4981a4f
--- /dev/null
+++ b/LayoutTests/platform/ios-simulator-12-wk2/imported/w3c/web-platform-tests/preload/link-header-preload-imagesrcset-expected.txt
@@ -0,0 +1,7 @@
+CONSOLE MESSAGE: The resource http://localhost:8800/preload/resources/square.png?from-header&2x was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it wasn't preloaded for nothing.
+CONSOLE MESSAGE: The resource http://localhost:8800/preload/resources/square.png?from-header&800 was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it wasn't preloaded for nothing.
+CONSOLE MESSAGE: The resource http://localhost:8800/preload/resources/square.png?from-header&600 was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it wasn't preloaded for nothing.
+CONSOLE MESSAGE: line 2659: Error: assert_equals: resources/square.png?from-header&1x expected 1 but got 0
+
+FAIL Makes sure that Link headers preload images with imagesrcset/imagesizes attributes. Error: assert_equals: resources/square.png?from-header&1x expected 1 but got 0
+
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index f48b5fb..5b989f3 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,39 @@
+2019-05-17 Rob Buis <rbuis@igalia.com>
+
+ Implement imagesrcset and imagesizes attributes on link rel=preload
+ https://bugs.webkit.org/show_bug.cgi?id=192950
+
+ Reviewed by Youenn Fablet.
+
+ Implement imagesrcset and imagesizes attributes for both Link header
+ and link element.
+
+ Tests: imported/w3c/web-platform-tests/preload/dynamic-adding-preload-imagesrcset.html
+ imported/w3c/web-platform-tests/preload/link-header-preload-delay-onload.html
+ imported/w3c/web-platform-tests/preload/link-header-preload-imagesrcset.html
+ imported/w3c/web-platform-tests/preload/link-header-preload-nonce.html
+ imported/w3c/web-platform-tests/preload/link-header-preload.html
+ imported/w3c/web-platform-tests/preload/onload-event.html
+ imported/w3c/web-platform-tests/preload/preload-with-type.html
+
+ * html/HTMLAttributeNames.in:
+ * html/HTMLLinkElement.cpp:
+ (WebCore::HTMLLinkElement::process):
+ * html/HTMLLinkElement.idl:
+ * loader/LinkHeader.cpp:
+ (WebCore::paramterNameFromString):
+ (WebCore::LinkHeader::setValue):
+ (WebCore::LinkHeader::LinkHeader):
+ * loader/LinkHeader.h:
+ (WebCore::LinkHeader::imageSrcSet const):
+ (WebCore::LinkHeader::imageSizes const):
+ (WebCore::LinkHeader::isViewportDependent const):
+ * loader/LinkLoader.cpp:
+ (WebCore::LinkLoader::loadLinksFromHeader):
+ (WebCore::LinkLoader::preloadIfNeeded):
+ (WebCore::LinkLoader::loadLink):
+ * loader/LinkLoader.h:
+
2019-05-17 Keith Rollin <krollin@apple.com>
Re-enable generate-xcfilelists
diff --git a/Source/WebCore/html/HTMLAttributeNames.in b/Source/WebCore/html/HTMLAttributeNames.in
index 606cfb9..1e9a826 100644
--- a/Source/WebCore/html/HTMLAttributeNames.in
+++ b/Source/WebCore/html/HTMLAttributeNames.in
@@ -144,6 +144,8 @@
hspace
http_equiv
id
+imagesizes
+imagesrcset
incremental
indeterminate
inputmode
diff --git a/Source/WebCore/html/HTMLLinkElement.cpp b/Source/WebCore/html/HTMLLinkElement.cpp
index bb438be..adec9ea 100644
--- a/Source/WebCore/html/HTMLLinkElement.cpp
+++ b/Source/WebCore/html/HTMLLinkElement.cpp
@@ -262,7 +262,7 @@
URL url = getNonEmptyURLAttribute(hrefAttr);
- if (!m_linkLoader.loadLink(m_relAttribute, url, attributeWithoutSynchronization(asAttr), attributeWithoutSynchronization(mediaAttr), attributeWithoutSynchronization(typeAttr), attributeWithoutSynchronization(crossoriginAttr), document()))
+ if (!m_linkLoader.loadLink(m_relAttribute, url, attributeWithoutSynchronization(asAttr), attributeWithoutSynchronization(mediaAttr), attributeWithoutSynchronization(typeAttr), attributeWithoutSynchronization(crossoriginAttr), attributeWithoutSynchronization(imagesrcsetAttr), attributeWithoutSynchronization(imagesizesAttr), document()))
return;
bool treatAsStyleSheet = m_relAttribute.isStyleSheet
diff --git a/Source/WebCore/html/HTMLLinkElement.idl b/Source/WebCore/html/HTMLLinkElement.idl
index 8c5c6ee..4fbb938 100644
--- a/Source/WebCore/html/HTMLLinkElement.idl
+++ b/Source/WebCore/html/HTMLLinkElement.idl
@@ -35,6 +35,8 @@
[CEReactions=NotNeeded, Reflect] attribute DOMString type;
[CEReactions=NotNeeded] attribute DOMString as;
[CEReactions=NotNeeded] attribute DOMString? crossOrigin;
+ [CEReactions=NotNeeded, Reflect] attribute DOMString imageSrcset;
+ [CEReactions=NotNeeded, Reflect] attribute DOMString imageSizes;
// DOM Level 2 Style
readonly attribute StyleSheet sheet;
diff --git a/Source/WebCore/loader/LinkHeader.cpp b/Source/WebCore/loader/LinkHeader.cpp
index 0c7e766..32a338b 100644
--- a/Source/WebCore/loader/LinkHeader.cpp
+++ b/Source/WebCore/loader/LinkHeader.cpp
@@ -165,6 +165,10 @@
return LinkHeader::LinkParameterHreflang;
if (equalLettersIgnoringASCIICase(name, "as"))
return LinkHeader::LinkParameterAs;
+ if (equalLettersIgnoringASCIICase(name, "imagesrcset"))
+ return LinkHeader::LinkParameterImageSrcSet;
+ if (equalLettersIgnoringASCIICase(name, "imagesizes"))
+ return LinkHeader::LinkParameterImageSizes;
return LinkHeader::LinkParameterUnknown;
}
@@ -264,27 +268,33 @@
return !hasQuotes || completeQuotes;
}
-void LinkHeader::setValue(LinkParameterName name, String value)
+void LinkHeader::setValue(LinkParameterName name, String&& value)
{
switch (name) {
case LinkParameterRel:
if (!m_rel)
- m_rel = value;
+ m_rel = WTFMove(value);
break;
case LinkParameterAnchor:
m_isValid = false;
break;
case LinkParameterCrossOrigin:
- m_crossOrigin = value;
+ m_crossOrigin = WTFMove(value);
break;
case LinkParameterAs:
- m_as = value;
+ m_as = WTFMove(value);
break;
case LinkParameterType:
- m_mimeType = value;
+ m_mimeType = WTFMove(value);
break;
case LinkParameterMedia:
- m_media = value;
+ m_media = WTFMove(value);
+ break;
+ case LinkParameterImageSrcSet:
+ m_imageSrcSet = WTFMove(value);
+ break;
+ case LinkParameterImageSizes:
+ m_imageSizes = WTFMove(value);
break;
case LinkParameterTitle:
case LinkParameterRev:
@@ -336,7 +346,7 @@
return;
}
- setValue(parameterName, parameterValue);
+ setValue(parameterName, WTFMove(parameterValue));
}
findNextHeader(position, end);
}
diff --git a/Source/WebCore/loader/LinkHeader.h b/Source/WebCore/loader/LinkHeader.h
index 8e35474..467088b 100644
--- a/Source/WebCore/loader/LinkHeader.h
+++ b/Source/WebCore/loader/LinkHeader.h
@@ -41,7 +41,10 @@
const String& mimeType() const { return m_mimeType; }
const String& media() const { return m_media; }
const String& crossOrigin() const { return m_crossOrigin; }
+ const String& imageSrcSet() const { return m_imageSrcSet; }
+ const String& imageSizes() const { return m_imageSizes; }
bool valid() const { return m_isValid; }
+ bool isViewportDependent() const { return !media().isEmpty() || !imageSrcSet().isEmpty() || !imageSizes().isEmpty(); }
enum LinkParameterName {
LinkParameterRel,
@@ -55,10 +58,12 @@
LinkParameterUnknown,
LinkParameterCrossOrigin,
LinkParameterAs,
+ LinkParameterImageSrcSet,
+ LinkParameterImageSizes,
};
private:
- void setValue(LinkParameterName, String value);
+ void setValue(LinkParameterName, String&& value);
String m_url;
String m_rel;
@@ -66,6 +71,8 @@
String m_mimeType;
String m_media;
String m_crossOrigin;
+ String m_imageSrcSet;
+ String m_imageSizes;
bool m_isValid { true };
};
diff --git a/Source/WebCore/loader/LinkLoader.cpp b/Source/WebCore/loader/LinkLoader.cpp
index 2cd76f9..32745d4 100644
--- a/Source/WebCore/loader/LinkLoader.cpp
+++ b/Source/WebCore/loader/LinkLoader.cpp
@@ -44,16 +44,19 @@
#include "FrameLoader.h"
#include "FrameLoaderClient.h"
#include "FrameView.h"
+#include "HTMLSrcsetParser.h"
#include "LinkHeader.h"
#include "LinkPreloadResourceClients.h"
#include "LinkRelAttribute.h"
#include "LoaderStrategy.h"
#include "MIMETypeRegistry.h"
+#include "MediaList.h"
#include "MediaQueryEvaluator.h"
#include "PlatformStrategies.h"
#include "ResourceError.h"
#include "RuntimeEnabledFeatures.h"
#include "Settings.h"
+#include "SizesAttributeParser.h"
#include "StyleResolver.h"
namespace WebCore {
@@ -97,8 +100,8 @@
for (auto& header : headerSet) {
if (!header.valid() || header.url().isEmpty() || header.rel().isEmpty())
continue;
- if ((mediaAttributeCheck == MediaAttributeCheck::MediaAttributeNotEmpty && header.media().isEmpty())
- || (mediaAttributeCheck == MediaAttributeCheck::MediaAttributeEmpty && !header.media().isEmpty())) {
+ if ((mediaAttributeCheck == MediaAttributeCheck::MediaAttributeNotEmpty && !header.isViewportDependent())
+ || (mediaAttributeCheck == MediaAttributeCheck::MediaAttributeEmpty && header.isViewportDependent())) {
continue;
}
@@ -108,7 +111,7 @@
if (equalIgnoringFragmentIdentifier(url, baseURL))
continue;
preconnectIfNeeded(relAttribute, url, document, header.crossOrigin());
- preloadIfNeeded(relAttribute, url, document, header.as(), header.media(), header.mimeType(), header.crossOrigin(), nullptr);
+ preloadIfNeeded(relAttribute, url, document, header.as(), header.media(), header.mimeType(), header.crossOrigin(), header.imageSrcSet(), header.imageSizes(), nullptr);
}
}
@@ -227,28 +230,39 @@
});
}
-std::unique_ptr<LinkPreloadResourceClient> LinkLoader::preloadIfNeeded(const LinkRelAttribute& relAttribute, const URL& href, Document& document, const String& as, const String& media, const String& mimeType, const String& crossOriginMode, LinkLoader* loader)
+std::unique_ptr<LinkPreloadResourceClient> LinkLoader::preloadIfNeeded(const LinkRelAttribute& relAttribute, const URL& href, Document& document, const String& as, const String& media, const String& mimeType, const String& crossOriginMode, const String& imageSrcSet, const String& imageSizes, LinkLoader* loader)
{
if (!document.loader() || !relAttribute.isLinkPreload)
return nullptr;
ASSERT(RuntimeEnabledFeatures::sharedFeatures().linkPreloadEnabled());
- if (!href.isValid()) {
- document.addConsoleMessage(MessageSource::Other, MessageLevel::Error, "<link rel=preload> has an invalid `href` value"_s);
- return nullptr;
- }
auto type = LinkLoader::resourceTypeFromAsAttribute(as);
if (!type) {
document.addConsoleMessage(MessageSource::Other, MessageLevel::Error, "<link rel=preload> must have a valid `as` value"_s);
return nullptr;
}
+ URL url;
+ if (type == CachedResource::Type::ImageResource && !imageSrcSet.isEmpty()) {
+ auto sourceSize = SizesAttributeParser(imageSizes, document).length();
+ auto candidate = bestFitSourceForImageAttributes(document.deviceScaleFactor(), href.string(), imageSrcSet, sourceSize);
+ url = document.completeURL(URL({ }, candidate.string.toString()));
+ } else
+ url = document.completeURL(href);
+
+ if (!url.isValid()) {
+ if (imageSrcSet.isEmpty())
+ document.addConsoleMessage(MessageSource::Other, MessageLevel::Error, "<link rel=preload> has an invalid `href` value"_s);
+ else
+ document.addConsoleMessage(MessageSource::Other, MessageLevel::Error, "<link rel=preload> has an invalid `imagesrcset` value"_s);
+ return nullptr;
+ }
if (!MediaQueryEvaluator::mediaAttributeMatches(document, media))
return nullptr;
if (!isSupportedType(type.value(), mimeType))
return nullptr;
auto options = CachedResourceLoader::defaultCachedResourceOptions();
- auto linkRequest = createPotentialAccessControlRequest(document.completeURL(href), document, crossOriginMode, WTFMove(options));
+ auto linkRequest = createPotentialAccessControlRequest(url, document, crossOriginMode, WTFMove(options));
linkRequest.setPriority(CachedResource::defaultPriorityForResourceType(type.value()));
linkRequest.setInitiator("link");
linkRequest.setIgnoreForRequestCount(true);
@@ -299,7 +313,7 @@
m_preloadResourceClient->clear();
}
-bool LinkLoader::loadLink(const LinkRelAttribute& relAttribute, const URL& href, const String& as, const String& media, const String& mimeType, const String& crossOrigin, Document& document)
+bool LinkLoader::loadLink(const LinkRelAttribute& relAttribute, const URL& href, const String& as, const String& media, const String& mimeType, const String& crossOrigin, const String& imageSrcSet, const String& imageSizes, Document& document)
{
if (relAttribute.isDNSPrefetch) {
// FIXME: The href attribute of the link element can be in "//hostname" form, and we shouldn't attempt
@@ -311,7 +325,7 @@
preconnectIfNeeded(relAttribute, href, document, crossOrigin);
if (m_client.shouldLoadLink()) {
- auto resourceClient = preloadIfNeeded(relAttribute, href, document, as, media, mimeType, crossOrigin, this);
+ auto resourceClient = preloadIfNeeded(relAttribute, href, document, as, media, mimeType, crossOrigin, imageSrcSet, imageSizes, this);
if (m_preloadResourceClient)
m_preloadResourceClient->clear();
if (resourceClient)
diff --git a/Source/WebCore/loader/LinkLoader.h b/Source/WebCore/loader/LinkLoader.h
index 78606c2..c180a160 100644
--- a/Source/WebCore/loader/LinkLoader.h
+++ b/Source/WebCore/loader/LinkLoader.h
@@ -50,7 +50,7 @@
explicit LinkLoader(LinkLoaderClient&);
virtual ~LinkLoader();
- bool loadLink(const LinkRelAttribute&, const URL&, const String& as, const String& media, const String& type, const String& crossOrigin, Document&);
+ bool loadLink(const LinkRelAttribute&, const URL&, const String& as, const String& media, const String& type, const String& crossOrigin, const String& imageSrcSet, const String& imageSizes, Document&);
static Optional<CachedResource::Type> resourceTypeFromAsAttribute(const String& as);
enum class MediaAttributeCheck { MediaAttributeEmpty, MediaAttributeNotEmpty, SkipMediaAttributeCheck };
@@ -63,7 +63,7 @@
private:
void notifyFinished(CachedResource&) override;
static void preconnectIfNeeded(const LinkRelAttribute&, const URL& href, Document&, const String& crossOrigin);
- static std::unique_ptr<LinkPreloadResourceClient> preloadIfNeeded(const LinkRelAttribute&, const URL& href, Document&, const String& as, const String& media, const String& type, const String& crossOriginMode, LinkLoader*);
+ static std::unique_ptr<LinkPreloadResourceClient> preloadIfNeeded(const LinkRelAttribute&, const URL& href, Document&, const String& as, const String& media, const String& type, const String& crossOriginMode, const String&, const String&, LinkLoader*);
void prefetchIfNeeded(const LinkRelAttribute&, const URL& href, Document&);
LinkLoaderClient& m_client;