Inline script tags ignore defer/async

According to MDN, inline script tags should not have defer/async attributes. But
some do. This ignores those attributes for inline script tags.

(Previously, we were only half ignoring them. We were treating them as inline,
but flagging them as deferred or async, which was causing issues with cleanup)

Fixes: https://github.com/lightpanda-io/browser/issues/1014
This commit is contained in:
Karl Seguin
2025-09-05 23:23:31 +08:00
parent 42828c64fb
commit eb453f471b
4 changed files with 34 additions and 2 deletions

View File

@@ -162,8 +162,8 @@ pub fn addFromElement(self: *ScriptManager, element: *parser.Element) !void {
.element = element, .element = element,
.source = source, .source = source,
.url = remote_url orelse page.url.raw, .url = remote_url orelse page.url.raw,
.is_defer = try parser.elementGetAttribute(element, "defer") != null, .is_defer = if (remote_url == null) false else try parser.elementGetAttribute(element, "defer") != null,
.is_async = try parser.elementGetAttribute(element, "async") != null, .is_async = if (remote_url == null) false else try parser.elementGetAttribute(element, "async") != null,
}; };
if (source == .@"inline" and self.scripts.first == null) { if (source == .@"inline" and self.scripts.first == null) {

View File

@@ -1480,6 +1480,10 @@ test "Browser.HTML.HTMLStyleElement" {
}, .{}); }, .{});
} }
test "Browser: HTML.HTMLScriptElement" {
try testing.htmlRunner("html/script/inline_defer.html");
}
const Check = struct { const Check = struct {
input: []const u8, input: []const u8,
expected: ?[]const u8 = null, // Needed when input != expected expected: ?[]const u8 = null, // Needed when input != expected

View File

@@ -0,0 +1,27 @@
<head>
<script>
let dyn1_loaded = 0;
function loadScript(src) {
const script = document.createElement('script');
script.src = src;
document.getElementsByTagName("head")[0].appendChild(script)
}
</script>
</head>
<script src="../../testing.js"></script>
<script defer>
loadScript('inline_defer.js');
</script>
<script async>
loadScript('inline_defer.js');
</script>
<script id=inline_defer>
// inline script should ignore defer and async attributes. If we don't do
// this correctly, we'd end up in an infinite loop
// https://github.com/lightpanda-io/browser/issues/1014
testing.eventually(() => testing.expectEqual(2, dyn1_loaded));
</script>

View File

@@ -0,0 +1 @@
dyn1_loaded += 1;