@@ -51,7 +51,7 @@ pub const Window = struct {
5151 storage_shelf : ? * storage.Shelf = null ,
5252
5353 // counter for having unique timer ids
54- timer_id : u31 = 0 ,
54+ timer_id : u30 = 0 ,
5555 timers : std .AutoHashMapUnmanaged (u32 , * TimerCallback ) = .{},
5656
5757 crypto : Crypto = .{},
@@ -209,6 +209,15 @@ pub const Window = struct {
209209 }
210210
211211 fn createTimeout (self : * Window , cbk : Function , delay_ : ? u32 , page : * Page , comptime repeat : bool ) ! u32 {
212+ const delay = delay_ orelse 0 ;
213+ if (delay > 5000 ) {
214+ log .warn (.window , "long timeout ignored" , .{ .delay = delay , .interval = repeat });
215+ // self.timer_id is u30, so the largest value we can generate is
216+ // 1_073_741_824. Returning 2_000_000_000 makes sure that clients
217+ // can call cancelTimer/cancelInterval without breaking anything.
218+ return 2_000_000_000 ;
219+ }
220+
212221 if (self .timers .count () > 512 ) {
213222 return error .TooManyTimeout ;
214223 }
@@ -224,7 +233,7 @@ pub const Window = struct {
224233 }
225234 errdefer _ = self .timers .remove (timer_id );
226235
227- const delay : u63 = @as (u63 , ( delay_ orelse 0 ) ) * std .time .ns_per_ms ;
236+ const delay_ms : u63 = @as (u63 , delay ) * std .time .ns_per_ms ;
228237 const callback = try arena .create (TimerCallback );
229238
230239 callback .* = .{
@@ -233,9 +242,9 @@ pub const Window = struct {
233242 .window = self ,
234243 .timer_id = timer_id ,
235244 .node = .{ .func = TimerCallback .run },
236- .repeat = if (repeat ) delay else null ,
245+ .repeat = if (repeat ) delay_ms else null ,
237246 };
238- callback .loop_id = try page .loop .timeout (delay , & callback .node );
247+ callback .loop_id = try page .loop .timeout (delay_ms , & callback .node );
239248
240249 gop .value_ptr .* = callback ;
241250 return timer_id ;
@@ -345,4 +354,11 @@ test "Browser.HTML.Window" {
345354 .{ "innerHeight" , "1" },
346355 .{ "innerWidth" , "2" },
347356 }, .{});
357+
358+ // cancelAnimationFrame should be able to cancel a request with the given id
359+ try runner .testCases (&.{
360+ .{ "let longCall = false;" , null },
361+ .{ "window.setTimeout(() => {longCall = true}, 5001);" , null },
362+ .{ "longCall;" , "false" },
363+ }, .{});
348364}
0 commit comments