more Animation accessors

This commit is contained in:
Karl Seguin
2025-12-25 17:00:27 +08:00
parent cc3a498294
commit dca99c338e
4 changed files with 80 additions and 8 deletions

View File

@@ -85,12 +85,12 @@ pub const PromiseResolver = struct {
}
fn _resolve(self: PromiseResolver, value: anytype) !void {
const context = self.context;
const js_value = try context.zigValueToJs(value);
const js_value = try context.zigValueToJs(value, .{});
if (self.resolver.resolve(context.v8_context, js_value) == null) {
return error.FailedToResolvePromise;
}
self.runMicrotasks();
self.context.runMicrotasks();
}
pub fn reject(self: PromiseResolver, comptime source: []const u8, value: anytype) void {
@@ -105,7 +105,7 @@ pub const PromiseResolver = struct {
if (self.resolver.reject(context.v8_context, js_value) == null) {
return error.FailedToRejectPromise;
}
self.runMicrotasks();
self.context.runMicrotasks();
}
};

View File

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=animation>
let a1 = document.createElement('div').animate(null, null);
testing.expectEqual('finished', a1.playState);
let cb = [];
a1.ready.then(() => { cb.push('ready') });
a1.finished.then((x) => {
cb.push('finished');
cb.push(x == a1);
});
testing.eventually(() => testing.expectEqual(['finished', true], cb));
</script>

View File

@@ -724,8 +724,8 @@ pub fn getAnimations(_: *const Element) []*Animation {
return &.{};
}
pub fn animate(_: *Element, _: js.Object, _: js.Object) !Animation {
return Animation.init();
pub fn animate(_: *Element, _: js.Object, _: js.Object, page: *Page) !*Animation {
return Animation.init(page);
}
pub fn closest(self: *Element, selector: []const u8, page: *Page) !?*Element {

View File

@@ -21,8 +21,13 @@ const Page = @import("../../Page.zig");
const Animation = @This();
pub fn init() !Animation {
return .{};
_effect: ?js.Object = null,
_timeline: ?js.Object = null,
_ready_resolver: ?js.PromiseResolver = null,
_finished_resolver: ?js.PromiseResolver = null,
pub fn init(page: *Page) !*Animation {
return page._factory.create(Animation{});
}
pub fn play(_: *Animation) void {}
@@ -31,6 +36,48 @@ pub fn cancel(_: *Animation) void {}
pub fn finish(_: *Animation) void {}
pub fn reverse(_: *Animation) void {}
pub fn getPlayState(_: *const Animation) []const u8 {
return "finished";
}
pub fn getPending(_: *const Animation) bool {
return false;
}
pub fn getFinished(self: *Animation, page: *Page) !js.Promise {
if (self._finished_resolver == null) {
const resolver = page.js.createPromiseResolver(.none);
resolver.resolve("Animation.getFinished", self);
self._finished_resolver = resolver;
}
return self._finished_resolver.?.promise();
}
pub fn getReady(self: *Animation, page: *Page) !js.Promise {
// never resolved, because we're always "finished"
if (self._ready_resolver == null) {
const resolver = page.js.createPromiseResolver(.none);
self._ready_resolver = resolver;
}
return self._ready_resolver.?.promise();
}
pub fn getEffect(self: *const Animation) ?js.Object {
return self._effect;
}
pub fn setEffect(self: *Animation, effect: js.Object) !void {
self._effect = try effect.persist();
}
pub fn getTimeline(self: *const Animation) ?js.Object {
return self._timeline;
}
pub fn setTimeline(self: *Animation, timeline: js.Object) !void {
self._timeline = try timeline.persist();
}
pub const JsApi = struct {
pub const bridge = js.Bridge(Animation);
@@ -38,7 +85,6 @@ pub const JsApi = struct {
pub const name = "Animation";
pub const prototype_chain = bridge.prototypeChain();
pub var class_id: bridge.ClassId = undefined;
pub const empty_with_no_proto = true;
};
pub const play = bridge.function(Animation.play, .{});
@@ -46,4 +92,15 @@ pub const JsApi = struct {
pub const cancel = bridge.function(Animation.cancel, .{});
pub const finish = bridge.function(Animation.finish, .{});
pub const reverse = bridge.function(Animation.reverse, .{});
pub const playState = bridge.accessor(Animation.getPlayState, null, .{});
pub const pending = bridge.accessor(Animation.getPending, null, .{});
pub const finished = bridge.accessor(Animation.getFinished, null, .{});
pub const ready = bridge.accessor(Animation.getReady, null, .{});
pub const effect = bridge.accessor(Animation.getEffect, Animation.setEffect, .{});
pub const timeline = bridge.accessor(Animation.getTimeline, Animation.getTimeline, .{});
};
const testing = @import("../../../testing.zig");
test "WebApi: Animation" {
try testing.htmlRunner("animation/animation.html", .{});
}