Skip to content

Commit 997ec7f

Browse files
authored
Merge pull request #805 from lightpanda-io/performance-mark
add PerformanceEntry and PerformanceMark
2 parents 8a005bc + 6b651cd commit 997ec7f

File tree

3 files changed

+124
-3
lines changed

3 files changed

+124
-3
lines changed

src/browser/dom/dom.zig

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ const IntersectionObserver = @import("intersection_observer.zig");
2828
const DOMParser = @import("dom_parser.zig").DOMParser;
2929
const TreeWalker = @import("tree_walker.zig").TreeWalker;
3030
const NodeFilter = @import("node_filter.zig").NodeFilter;
31-
const Performance = @import("performance.zig").Performance;
3231
const PerformanceObserver = @import("performance_observer.zig").PerformanceObserver;
3332

3433
pub const Interfaces = .{
@@ -46,6 +45,6 @@ pub const Interfaces = .{
4645
DOMParser,
4746
TreeWalker,
4847
NodeFilter,
49-
Performance,
48+
@import("performance.zig").Interfaces,
5049
PerformanceObserver,
5150
};

src/browser/dom/performance.zig

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,19 @@ const std = @import("std");
2020

2121
const parser = @import("../netsurf.zig");
2222
const EventTarget = @import("../dom/event_target.zig").EventTarget;
23+
const Env = @import("../env.zig").Env;
24+
const Page = @import("../page.zig").Page;
25+
26+
pub const Interfaces = .{
27+
Performance,
28+
PerformanceEntry,
29+
PerformanceMark,
30+
};
31+
32+
const MarkOptions = struct {
33+
detail: ?Env.JsObject = null,
34+
start_time: ?f64 = null,
35+
};
2336

2437
// https://developer.mozilla.org/en-US/docs/Web/API/Performance
2538
pub const Performance = struct {
@@ -52,6 +65,93 @@ pub const Performance = struct {
5265
pub fn _now(self: *Performance) f64 {
5366
return limitedResolutionMs(self.time_origin.read());
5467
}
68+
69+
pub fn _mark(_: *Performance, name: []const u8, _options: ?MarkOptions, page: *Page) !PerformanceMark {
70+
const mark: PerformanceMark = try .constructor(name, _options, page);
71+
// TODO: Should store this in an entries list
72+
return mark;
73+
}
74+
};
75+
76+
// https://developer.mozilla.org/en-US/docs/Web/API/PerformanceEntry
77+
pub const PerformanceEntry = struct {
78+
const PerformanceEntryType = enum {
79+
element,
80+
event,
81+
first_input,
82+
largest_contentful_paint,
83+
layout_shift,
84+
long_animation_frame,
85+
longtask,
86+
mark,
87+
measure,
88+
navigation,
89+
paint,
90+
resource,
91+
taskattribution,
92+
visibility_state,
93+
94+
pub fn toString(self: PerformanceEntryType) []const u8 {
95+
return switch (self) {
96+
.first_input => "first-input",
97+
.largest_contentful_paint => "largest-contentful-paint",
98+
.layout_shift => "layout-shift",
99+
.long_animation_frame => "long-animation-frame",
100+
.visibility_state => "visibility-state",
101+
else => @tagName(self),
102+
};
103+
}
104+
};
105+
106+
duration: f64 = 0.0,
107+
entry_type: PerformanceEntryType,
108+
name: []const u8,
109+
start_time: f64 = 0.0,
110+
111+
pub fn get_duration(self: *const PerformanceEntry) f64 {
112+
return self.duration;
113+
}
114+
115+
pub fn get_entryType(self: *const PerformanceEntry) PerformanceEntryType {
116+
return self.entry_type;
117+
}
118+
119+
pub fn get_name(self: *const PerformanceEntry) []const u8 {
120+
return self.name;
121+
}
122+
123+
pub fn get_startTime(self: *const PerformanceEntry) f64 {
124+
return self.start_time;
125+
}
126+
};
127+
128+
// https://developer.mozilla.org/en-US/docs/Web/API/PerformanceMark
129+
pub const PerformanceMark = struct {
130+
pub const prototype = *PerformanceEntry;
131+
132+
proto: PerformanceEntry,
133+
detail: ?Env.JsObject,
134+
135+
pub fn constructor(name: []const u8, _options: ?MarkOptions, page: *Page) !PerformanceMark {
136+
const perf = &page.window.performance;
137+
138+
const options = _options orelse MarkOptions{};
139+
const start_time = options.start_time orelse perf._now();
140+
const detail = if (options.detail) |d| try d.persist() else null;
141+
142+
if (start_time < 0.0) {
143+
return error.TypeError;
144+
}
145+
146+
const duped_name = try page.arena.dupe(u8, name);
147+
const proto = PerformanceEntry{ .name = duped_name, .entry_type = .mark, .start_time = start_time };
148+
149+
return .{ .proto = proto, .detail = detail };
150+
}
151+
152+
pub fn get_detail(self: *const PerformanceMark) ?Env.JsObject {
153+
return self.detail;
154+
}
55155
};
56156

57157
const testing = @import("./../../testing.zig");
@@ -85,3 +185,19 @@ test "Performance: now" {
85185
// Check resolution
86186
try testing.expectDelta(@rem(after * std.time.us_per_ms, 100.0), 0.0, 0.1);
87187
}
188+
189+
test "Browser.Performance.Mark" {
190+
var runner = try testing.jsRunner(testing.tracking_allocator, .{});
191+
defer runner.deinit();
192+
193+
try runner.testCases(&.{
194+
.{ "let performance = window.performance", "undefined" },
195+
.{ "performance instanceof Performance", "true" },
196+
.{ "let mark = performance.mark(\"start\")", "undefined" },
197+
.{ "mark instanceof PerformanceMark", "true" },
198+
.{ "mark.name", "start" },
199+
.{ "mark.entryType", "mark" },
200+
.{ "mark.duration", "0" },
201+
.{ "mark.detail", "null" },
202+
}, .{});
203+
}

src/runtime/js.zig

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2215,7 +2215,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
22152215

22162216
const T = @TypeOf(value);
22172217
switch (@typeInfo(T)) {
2218-
.void, .bool, .int, .comptime_int, .float, .comptime_float => {
2218+
.void, .bool, .int, .comptime_int, .float, .comptime_float, .@"enum" => {
22192219
// Need to do this to keep the compiler happy
22202220
// simpleZigValueToJs handles all of these cases.
22212221
unreachable;
@@ -3098,6 +3098,12 @@ fn simpleZigValueToJs(isolate: v8.Isolate, value: anytype, comptime fail: bool)
30983098
}
30993099
},
31003100
.@"union" => return simpleZigValueToJs(isolate, std.meta.activeTag(value), fail),
3101+
.@"enum" => {
3102+
const T = @TypeOf(value);
3103+
if (@hasDecl(T, "toString")) {
3104+
return simpleZigValueToJs(isolate, value.toString(), fail);
3105+
}
3106+
},
31013107
else => {},
31023108
}
31033109
if (fail) {

0 commit comments

Comments
 (0)