mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-07-31 17:55:59 -04:00
webapi: keep explicit null as AbortSignal abort reason
Fixes 1 failing test in WPT /dom/abort/event.any.html (and its .worker variant): "AbortController abort(null) should set signal.reason". abort() reason parameters were typed ?js.Value.Global, and the JS->Zig conversion collapses an explicit JS null into a missing argument, so controller.abort(null) fell back to the default "AbortError" DOMException. Per the DOM spec, the abort reason defaults to a new AbortError only when the reason is not given (undefined); an explicit null must be stored as-is. The parameters are now ?js.Value, which preserves the missing vs explicit-null distinction, and the new AbortSignal.reasonFromJs helper only falls back to the default for a missing or undefined reason. Coverage: /dom/abort/event.any.worker.html 15/16 -> 16/16, /dom/abort/event.any.html 15/16 -> 16/16. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -37,8 +37,8 @@ pub fn getSignal(self: *const AbortController) *AbortSignal {
|
||||
return self._signal;
|
||||
}
|
||||
|
||||
pub fn abort(self: *AbortController, reason_: ?js.Value.Global, exec: *const Execution) !void {
|
||||
try self._signal.abort(if (reason_) |r| .{ .js_val = r } else null, exec);
|
||||
pub fn abort(self: *AbortController, reason_: ?js.Value, exec: *const Execution) !void {
|
||||
try self._signal.abort(try AbortSignal.reasonFromJs(reason_), exec);
|
||||
}
|
||||
|
||||
pub const JsApi = struct {
|
||||
|
||||
@@ -149,10 +149,21 @@ fn dispatchAbortEvent(self: *AbortSignal, exec: *const Execution) !void {
|
||||
}
|
||||
}
|
||||
|
||||
// Converts an abort(reason) JS argument to a Reason. Per spec, only a
|
||||
// missing or undefined reason falls back to the default "AbortError"
|
||||
// DOMException: an explicit null (or any other value) is kept as-is.
|
||||
pub fn reasonFromJs(reason_: ?js.Value) !?Reason {
|
||||
const reason = reason_ orelse return null;
|
||||
if (reason.isUndefined()) {
|
||||
return null;
|
||||
}
|
||||
return .{ .js_val = try reason.persist() };
|
||||
}
|
||||
|
||||
// Static method to create an already-aborted signal
|
||||
pub fn createAborted(reason_: ?js.Value.Global, exec: *const Execution) !*AbortSignal {
|
||||
pub fn createAborted(reason_: ?js.Value, exec: *const Execution) !*AbortSignal {
|
||||
const signal = try init(exec);
|
||||
try signal.abort(if (reason_) |r| .{ .js_val = r } else null, exec);
|
||||
try signal.abort(try reasonFromJs(reason_), exec);
|
||||
return signal;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user