mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-06-11 09:35:59 -04:00
Merge pull request #2191 from lightpanda-io/feat/timer-string-handler
Feat/timer string handler
This commit is contained in:
@@ -120,14 +120,14 @@ pub fn exec(self: *const Local, src: []const u8, name: ?[]const u8) !js.Value {
|
||||
/// https://v8.github.io/api/head/classv8_1_1ScriptCompiler.html#a3a15bb5a7dfc3f998e6ac789e6b4646a
|
||||
pub fn compileFunction(
|
||||
self: *const Local,
|
||||
function_body: []const u8,
|
||||
src: anytype,
|
||||
/// We tend to know how many params we'll pass; can remove the comptime if necessary.
|
||||
comptime parameter_names: []const []const u8,
|
||||
extensions: []const v8.Object,
|
||||
) !js.Function {
|
||||
// TODO: Make configurable.
|
||||
const script_name = self.isolate.initStringHandle("anonymous");
|
||||
const script_source = self.isolate.initStringHandle(function_body);
|
||||
const script_source = if (@TypeOf(src) == js.String) src.handle else self.isolate.initStringHandle(src);
|
||||
|
||||
var parameter_list: [parameter_names.len]*const v8.String = undefined;
|
||||
inline for (0..parameter_names.len) |i| {
|
||||
@@ -742,6 +742,7 @@ fn jsValueToStruct(self: *const Local, comptime T: type, js_val: js.Value) !?T {
|
||||
else => unreachable,
|
||||
};
|
||||
},
|
||||
js.String => return js_val.isString(),
|
||||
string.String => {
|
||||
const js_str = js_val.isString() orelse return null;
|
||||
return try js_str.toSSO(false);
|
||||
|
||||
@@ -51,3 +51,33 @@
|
||||
clearImmediate(-3);
|
||||
testing.expectEqual(true, true);
|
||||
</script>
|
||||
|
||||
<script id=setTimeout-string-handler>
|
||||
// Per HTML spec, TimerHandler = Function or DOMString. The string form
|
||||
// is legacy but still required by the spec, and many sites (especially
|
||||
// legacy or server-rendered pages) rely on it.
|
||||
window.__st_string_ran = 0;
|
||||
const st_id = window.setTimeout("window.__st_string_ran = 42;", 1);
|
||||
testing.expectEqual('number', typeof st_id);
|
||||
testing.onload(() => testing.expectEqual(42, window.__st_string_ran));
|
||||
</script>
|
||||
|
||||
<script id=setInterval-string-handler>
|
||||
window.__si_string_ran = 0;
|
||||
const si_id = window.setInterval("window.__si_string_ran += 1;", 1);
|
||||
testing.expectEqual('number', typeof si_id);
|
||||
window.setTimeout(() => window.clearInterval(si_id), 5);
|
||||
testing.onload(() => testing.expectEqual(true, window.__si_string_ran >= 1));
|
||||
</script>
|
||||
|
||||
<script id=setTimeout-invalid-handler>
|
||||
// Non-function, non-string handlers must throw a TypeError.
|
||||
let threw = false;
|
||||
try {
|
||||
window.setTimeout(123, 1);
|
||||
} catch (e) {
|
||||
threw = true;
|
||||
}
|
||||
testing.expectEqual(true, threw);
|
||||
</script>
|
||||
|
||||
|
||||
@@ -253,7 +253,13 @@ pub fn fetch(_: *const Window, input: Fetch.Input, options: ?Fetch.InitOpts, pag
|
||||
return Fetch.init(input, options, page);
|
||||
}
|
||||
|
||||
pub fn setTimeout(self: *Window, cb: js.Function.Temp, delay_ms: ?u32, params: []js.Value.Temp, page: *Page) !u32 {
|
||||
const LegacyHandler = union(enum) {
|
||||
function: js.Function.Temp,
|
||||
string: js.String,
|
||||
};
|
||||
|
||||
pub fn setTimeout(self: *Window, handler: LegacyHandler, delay_ms: ?u32, params: []js.Value.Temp, page: *Page) !u32 {
|
||||
const cb = try resolveTimerHandler(handler, page);
|
||||
return self.scheduleCallback(cb, delay_ms orelse 0, .{
|
||||
.repeat = false,
|
||||
.params = params,
|
||||
@@ -262,7 +268,8 @@ pub fn setTimeout(self: *Window, cb: js.Function.Temp, delay_ms: ?u32, params: [
|
||||
}, page);
|
||||
}
|
||||
|
||||
pub fn setInterval(self: *Window, cb: js.Function.Temp, delay_ms: ?u32, params: []js.Value.Temp, page: *Page) !u32 {
|
||||
pub fn setInterval(self: *Window, handler: LegacyHandler, delay_ms: ?u32, params: []js.Value.Temp, page: *Page) !u32 {
|
||||
const cb = try resolveTimerHandler(handler, page);
|
||||
return self.scheduleCallback(cb, delay_ms orelse 0, .{
|
||||
.repeat = true,
|
||||
.params = params,
|
||||
@@ -271,6 +278,21 @@ pub fn setInterval(self: *Window, cb: js.Function.Temp, delay_ms: ?u32, params:
|
||||
}, page);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-settimeout
|
||||
// https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timerhandler
|
||||
// TimerHandler = Function or DOMString. When a string is passed, it is
|
||||
// compiled into an anonymous function body, matching how legacy browsers
|
||||
// (and all current UAs) interpret `setTimeout("foo()", 100)`.
|
||||
fn resolveTimerHandler(handler: LegacyHandler, page: *Page) !js.Function.Temp {
|
||||
switch (handler) {
|
||||
.function => |fun| return fun,
|
||||
.string => |str| {
|
||||
const fun = try page.js.local.?.compileFunction(str, &.{}, &.{});
|
||||
return fun.temp();
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setImmediate(self: *Window, cb: js.Function.Temp, params: []js.Value.Temp, page: *Page) !u32 {
|
||||
return self.scheduleCallback(cb, 0, .{
|
||||
.repeat = false,
|
||||
|
||||
Reference in New Issue
Block a user