LoAF: Use document character position for inline scripts
This applies to classic/module script blocks and event content
attributes.
Bug: 328209286
Change-Id: Id11e0a9324c529925b11b950d73ed4491410f96d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5425010
Reviewed-by: Michal Mocny <mmocny@chromium.org>
Reviewed-by: Kouhei Ueno <kouhei@chromium.org>
Commit-Queue: Noam Rosenthal <nrosenthal@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1291353}
diff --git a/long-animation-frame/tentative/loaf-source-location-inline-classic-script.html b/long-animation-frame/tentative/loaf-source-location-inline-classic-script.html
new file mode 100644
index 0000000..30033c9
--- /dev/null
+++ b/long-animation-frame/tentative/loaf-source-location-inline-classic-script.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>Long Animation Frame Timing: source location for inline classic scripts</title>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+
+<body>
+ <script>
+ busy_wait();
+ </script>
+ <script>
+ promise_test(async () => {
+ const script = await loaf_with_inline_script("classic-script");
+ assert_equals(script.sourceURL, location.href);
+ assert_greater_than(script.sourceCharPosition, 0);
+ }, "Source location should be available for inline classic scripts");
+ </script>
+</body>
diff --git a/long-animation-frame/tentative/loaf-source-location-inline-event-listener.html b/long-animation-frame/tentative/loaf-source-location-inline-event-listener.html
new file mode 100644
index 0000000..bd7e8bb
--- /dev/null
+++ b/long-animation-frame/tentative/loaf-source-location-inline-event-listener.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>Long Animation Frame Timing: source location for inline scripts</title>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+
+<body>
+<img id=image onload="busy_wait()">
+<script>
+ promise_test(async () => {
+ document.querySelector("#image").src = "/images/green.png";
+ const script = await loaf_with_inline_script("event-listener");
+ assert_equals(script.sourceURL, location.href);
+ assert_equals(script.sourceFunctionName, "onload");
+ assert_greater_than(script.sourceCharPosition, 0);
+ }, "Source location should be available for event handlers");
+</script>
+</body>
diff --git a/long-animation-frame/tentative/loaf-source-location-inline-module-script.html b/long-animation-frame/tentative/loaf-source-location-inline-module-script.html
new file mode 100644
index 0000000..f40b3e4
--- /dev/null
+++ b/long-animation-frame/tentative/loaf-source-location-inline-module-script.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>Long Animation Frame Timing: source location for inline module scripts</title>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+
+<body>
+<script type=module>
+ busy_wait();
+</script>
+<script>
+ promise_test(async () => {
+ const script = await loaf_with_inline_script("module-script");
+ assert_equals(script.sourceURL, location.href);
+ assert_greater_than(script.sourceCharPosition, 0);
+ }, "Source location should be available for inline classic scripts");
+ </script>
+</body>
diff --git a/long-animation-frame/tentative/resources/utils.js b/long-animation-frame/tentative/resources/utils.js
index aa537d3..a3f3da0 100644
--- a/long-animation-frame/tentative/resources/utils.js
+++ b/long-animation-frame/tentative/resources/utils.js
@@ -7,7 +7,7 @@
const no_long_frame_timeout = very_long_frame_duration * 2;
const waiting_for_long_frame_timeout = very_long_frame_duration * 10;
-function loaf_promise(t) {
+function loaf_promise(t, options = {}) {
return new Promise(resolve => {
const observer = new PerformanceObserver(entries => {
const entry = entries.getEntries()[0];
@@ -20,7 +20,7 @@
t.add_cleanup(() => observer.disconnect());
- observer.observe({entryTypes: ['long-animation-frame']});
+ observer.observe({type: 'long-animation-frame', ...options});
});
}
@@ -29,7 +29,7 @@
while (performance.now() < deadline) {}
}
-async function expect_long_frame(cb, t) {
+async function expect_long_frame(cb, t, opt = {}) {
await windowLoaded;
await new Promise(resolve => t.step_timeout(resolve, 0));
const timeout = new Promise((resolve, reject) =>
@@ -43,9 +43,9 @@
return entry;
}
-async function expect_long_frame_with_script(cb, predicate, t) {
+async function expect_long_frame_with_script(cb, predicate, t, opt = {}) {
for (let i = 0; i < 10; ++i) {
- const entry = await expect_long_frame(cb, t);
+ const entry = await expect_long_frame(cb, t, opt);
if (entry === "timeout" || !entry.scripts.length)
continue;
for (const script of entry.scripts) {
@@ -129,3 +129,15 @@
function test_self_script_block(cb, invoker, type) {
test_loaf_script(cb, invoker, type);
}
+
+function loaf_with_inline_script(type) {
+ return new Promise(resolve => new PerformanceObserver(entries => {
+ for (const e of entries.getEntries()) {
+ if (e.duration < very_long_frame_duration - 5)
+ return;
+ const script = e.scripts.find(s => s.invokerType === type && s.sourceURL === location.href);
+ if (script)
+ resolve(script);
+ }
+ }).observe({ type: "long-animation-frame", buffered: true }));
+}