Skip to content

Commit c03a764

Browse files
domenicchromium-wpt-export-bot
authored andcommitted
Fire error events for invalid speculation rules tags
This CL introduces error handling for <script type=speculationrules> with invalid ruleset-level tags. This changes the behavior: previously we would ignore such tags and preload with the null tag. But now, we error the entire <script type=speculationrules>, since it is better to avoid preloading if the web developer is expecting it to get a certain tag and we cannot fulfill that request. This matches the spec update at whatwg/html#11426. Bug: None Change-Id: I5d2211510bd4e3a3ecce15010325b411f18fde3a Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6746174 Commit-Queue: Domenic Denicola <domenic@chromium.org> Reviewed-by: Danil Somsikov <dsv@chromium.org> Reviewed-by: Hiroki Nakagawa <nhiroki@chromium.org> Cr-Commit-Position: refs/heads/main@{#1488633}
1 parent 6621a1e commit c03a764

File tree

1 file changed

+29
-23
lines changed

1 file changed

+29
-23
lines changed

speculation-rules/speculation-tags/resources/speculation-tags-utils.js

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,22 @@
2626
return type;
2727
}
2828

29+
function assertHeaders(headers, expectedTag, preloadingType) {
30+
if (expectedTag === undefined) {
31+
// If `tag` is invalid, preloading should not be
32+
// triggered, and the navigation should fall back to network. Confirm
33+
// this behavior by checking the request headers.
34+
assert_false(headers.has("sec-purpose"));
35+
assert_false(headers.has("sec-speculation-tags"));
36+
} else {
37+
// Make sure the page is preloaded.
38+
assert_equals(
39+
headers.get("sec-purpose"),
40+
preloadingType === "prefetch" ? "prefetch" : "prefetch;prerender");
41+
assert_equals(headers.get("sec-speculation-tags"), expectedTag);
42+
}
43+
}
44+
2945
function testRulesetTag(tag, expectedTag, description) {
3046
promise_test(async t => {
3147
const rcHelper = new RemoteContextHelper();
@@ -35,7 +51,7 @@
3551
const preloadingType = getPreloadingType();
3652
const preloadedRC = await referrerRC.helper.createContext({
3753
executorCreator(url) {
38-
return referrerRC.executeScript((preloadingType, tag, url) => {
54+
return referrerRC.executeScript((preloadingType, tag, url, expectedTag) => {
3955
const script = document.createElement("script");
4056
script.type = "speculationrules";
4157
script.textContent = JSON.stringify({
@@ -47,20 +63,24 @@
4763
}
4864
]
4965
});
66+
67+
if (expectedTag === undefined) {
68+
return new Promise(resolve => {
69+
script.addEventListener('error', resolve, { once: true });
70+
document.head.append(script);
71+
});
72+
}
73+
5074
document.head.append(script);
51-
}, [preloadingType, tag, url]);
75+
}, [preloadingType, tag, url, expectedTag]);
5276
}, extraConfig
5377
});
5478

5579
// Navigate to the preloaded page.
5680
referrerRC.navigateTo(preloadedRC.url);
5781

5882
const headers = await preloadedRC.getRequestHeaders();
59-
// Make sure the page is preloaded.
60-
assert_equals(
61-
headers.get("sec-purpose"),
62-
preloadingType === "prefetch" ? "prefetch" : "prefetch;prerender");
63-
assert_equals(headers.get("sec-speculation-tags"), expectedTag);
83+
assertHeaders(headers, expectedTag, preloadingType);
6484
}, "Sec-Speculation-Tags [ruleset-based]: " + description);
6585
}
6686

@@ -94,21 +114,7 @@
94114
referrerRC.navigateTo(preloadedRC.url);
95115

96116
const headers = await preloadedRC.getRequestHeaders();
97-
98-
if (expectedTag === undefined) {
99-
// If `tag` on the rule level is invalid, preloading should not be
100-
// triggered, and the navigation should fall back to network. Confirm
101-
// this behavior by checking the request headers.
102-
assert_false(headers.has("sec-purpose"));
103-
assert_false(headers.has("sec-speculation-tags"));
104-
} else {
105-
// Make sure the page is preloaded.
106-
assert_equals(
107-
headers.get("sec-purpose"),
108-
preloadingType === "prefetch" ? "prefetch" : "prefetch;prerender");
109-
assert_equals(headers.get("sec-speculation-tags"), expectedTag);
110-
}
111-
117+
assertHeaders(headers, expectedTag, preloadingType);
112118
}, "Sec-Speculation-Tags [rule-based]: " + description);
113119
}
114120

@@ -124,7 +130,7 @@
124130
// Runs the test function for invalid tag cases based on the tag level.
125131
globalThis.testInvalidTag = (tag, description) => {
126132
if (getTagLevel() === 'ruleset') {
127-
testRulesetTag(tag, 'null', description);
133+
testRulesetTag(tag, undefined, description);
128134
} else {
129135
// Pass `undefined` to indicate this preloading is expected to fail.
130136
testRuleTag(tag, undefined, description);

0 commit comments

Comments
 (0)