diff --git a/src/browser/Browser.zig b/src/browser/Browser.zig
index 16ff2a97..1d3bcbfe 100644
--- a/src/browser/Browser.zig
+++ b/src/browser/Browser.zig
@@ -108,8 +108,3 @@ pub fn runMessageLoop(self: *const Browser) void {
}
self.env.runIdleTasks();
}
-
-const testing = @import("../testing.zig");
-test "Browser" {
- try testing.htmlRunner("browser.html", .{});
-}
diff --git a/src/browser/EventManager.zig b/src/browser/EventManager.zig
index cce80fe9..5efa111b 100644
--- a/src/browser/EventManager.zig
+++ b/src/browser/EventManager.zig
@@ -92,7 +92,7 @@ pub fn dispatch(self: *EventManager, target: *EventTarget, event: *Event) !void
event._target = target;
switch (target._type) {
.node => |node| try self.dispatchNode(node, event),
- .xhr, .window, .abort_signal => {
+ .xhr, .window, .abort_signal, .media_query_list => {
const list = self.lookup.getPtr(@intFromPtr(target)) orelse return;
try self.dispatchAll(list, target, event);
},
diff --git a/src/browser/js/bridge.zig b/src/browser/js/bridge.zig
index 95d2bb29..160abb7b 100644
--- a/src/browser/js/bridge.zig
+++ b/src/browser/js/bridge.zig
@@ -442,6 +442,7 @@ pub const JsApis = flattenTypes(&.{
@import("../webapi/Crypto.zig"),
@import("../webapi/css/CSSStyleDeclaration.zig"),
@import("../webapi/css/CSSStyleProperties.zig"),
+ @import("../webapi/css/MediaQueryList.zig"),
@import("../webapi/Document.zig"),
@import("../webapi/HTMLDocument.zig"),
@import("../webapi/KeyValueList.zig"),
diff --git a/src/browser/tests/css/media_query_list.html b/src/browser/tests/css/media_query_list.html
new file mode 100644
index 00000000..63cf3c97
--- /dev/null
+++ b/src/browser/tests/css/media_query_list.html
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/browser/tests/page/meta.html b/src/browser/tests/page/meta.html
index bf310c41..80647a87 100644
--- a/src/browser/tests/page/meta.html
+++ b/src/browser/tests/page/meta.html
@@ -37,4 +37,6 @@
testing.expectEqual('string', typeof plainDoc.URL);
testing.expectEqual('string', typeof document.readyState);
testing.expectEqual('string', typeof plainDoc.readyState);
+
+ testing.expectEqual("[object Intl.DateTimeFormat]", new Intl.DateTimeFormat().toString());
diff --git a/src/browser/webapi/EventTarget.zig b/src/browser/webapi/EventTarget.zig
index 45379018..cfb9be4d 100644
--- a/src/browser/webapi/EventTarget.zig
+++ b/src/browser/webapi/EventTarget.zig
@@ -15,6 +15,7 @@ pub const Type = union(enum) {
window: *@import("Window.zig"),
xhr: *@import("net/XMLHttpRequestEventTarget.zig"),
abort_signal: *@import("AbortSignal.zig"),
+ media_query_list: *@import("css/MediaQueryList.zig"),
};
pub fn dispatchEvent(self: *EventTarget, event: *Event, page: *Page) !bool {
@@ -62,6 +63,7 @@ pub fn format(self: *EventTarget, writer: *std.Io.Writer) !void {
.window => writer.writeAll(""),
.xhr => writer.writeAll(""),
.abort_signal => writer.writeAll(""),
+ .media_query_list => writer.writeAll(""),
};
}
diff --git a/src/browser/webapi/Location.zig b/src/browser/webapi/Location.zig
index 3b9ed58d..0d6bea3b 100644
--- a/src/browser/webapi/Location.zig
+++ b/src/browser/webapi/Location.zig
@@ -65,7 +65,7 @@ pub const JsApi = struct {
pub const hash = bridge.accessor(Location.getHash, null, .{});
pub const pathname = bridge.accessor(Location.getPathname, null, .{});
pub const hostname = bridge.accessor(Location.getHostname, null, .{});
- pub const host = bridge.accessor(URL.getHost, null, .{});
+ pub const host = bridge.accessor(Location.getHost, null, .{});
pub const port = bridge.accessor(Location.getPort, null, .{});
pub const origin = bridge.accessor(Location.getOrigin, null, .{});
pub const protocol = bridge.accessor(Location.getProtocol, null, .{});
diff --git a/src/browser/webapi/URL.zig b/src/browser/webapi/URL.zig
index 32ca1759..96938403 100644
--- a/src/browser/webapi/URL.zig
+++ b/src/browser/webapi/URL.zig
@@ -130,41 +130,6 @@ pub fn toString(self: *const URL, page: *const Page) ![:0]const u8 {
return buf.written()[0 .. buf.written().len - 1 :0];
}
-fn getUserInfo(self: *const URL) ?[]const u8 {
- const raw = self._raw;
- const scheme_end = std.mem.indexOf(u8, raw, "://") orelse return null;
- const authority_start = scheme_end + 3;
-
- const pos = std.mem.indexOfScalar(u8, raw[authority_start..], '@') orelse return null;
- const path_start = std.mem.indexOfScalarPos(u8, raw, authority_start, '/') orelse raw.len;
-
- const full_pos = authority_start + pos;
- if (full_pos < path_start) {
- return raw[authority_start..full_pos];
- }
-
- return null;
-}
-
-fn getHost(self: *const URL) []const u8 {
- const raw = self._raw;
- const scheme_end = std.mem.indexOf(u8, raw, "://") orelse return "";
-
- var authority_start = scheme_end + 3;
- if (std.mem.indexOf(u8, raw[authority_start..], "@")) |pos| {
- authority_start += pos + 1;
- }
-
- const authority = raw[authority_start..];
- const path_start = std.mem.indexOfAny(u8, authority, "/?#") orelse return authority;
- return authority[0..path_start];
-}
-
-const KnownProtocol = enum {
- @"http:",
- @"https:",
-};
-
pub const JsApi = struct {
pub const bridge = js.Bridge(URL);
diff --git a/src/browser/webapi/Window.zig b/src/browser/webapi/Window.zig
index a288e9e5..899a7cfc 100644
--- a/src/browser/webapi/Window.zig
+++ b/src/browser/webapi/Window.zig
@@ -11,6 +11,7 @@ const Location = @import("Location.zig");
const Fetch = @import("net/Fetch.zig");
const EventTarget = @import("EventTarget.zig");
const ErrorEvent = @import("event/ErrorEvent.zig");
+const MediaQueryList = @import("css/MediaQueryList.zig");
const storage = @import("storage/storage.zig");
const Window = @This();
@@ -135,6 +136,13 @@ pub fn cancelAnimationFrame(self: *Window, id: u32) void {
sc.removed = true;
}
+pub fn matchMedia(_: *const Window, query: []const u8, page: *Page) !*MediaQueryList {
+ return page._factory.eventTarget(MediaQueryList{
+ ._proto = undefined,
+ ._media = try page.dupeString(query),
+ });
+}
+
pub fn btoa(_: *const Window, input: []const u8, page: *Page) ![]const u8 {
const encoded_len = std.base64.standard.Encoder.calcSize(input.len);
const encoded = try page.call_arena.alloc(u8, encoded_len);
@@ -266,6 +274,7 @@ pub const JsApi = struct {
pub const clearImmediate = bridge.function(Window.clearImmediate, .{});
pub const requestAnimationFrame = bridge.function(Window.requestAnimationFrame, .{});
pub const cancelAnimationFrame = bridge.function(Window.cancelAnimationFrame, .{});
+ pub const matchMedia = bridge.function(Window.matchMedia, .{});
pub const btoa = bridge.function(Window.btoa, .{});
pub const atob = bridge.function(Window.atob, .{});
};
diff --git a/src/browser/webapi/css/MediaQueryList.zig b/src/browser/webapi/css/MediaQueryList.zig
new file mode 100644
index 00000000..aec6559f
--- /dev/null
+++ b/src/browser/webapi/css/MediaQueryList.zig
@@ -0,0 +1,44 @@
+// zlint-disable unused-decls
+const std = @import("std");
+const js = @import("../../js/js.zig");
+const EventTarget = @import("../EventTarget.zig");
+
+const MediaQueryList = @This();
+
+_proto: *EventTarget,
+_media: []const u8,
+
+pub fn deinit(self: *MediaQueryList) void {
+ _ = self;
+}
+
+pub fn asEventTarget(self: *MediaQueryList) *EventTarget {
+ return self._proto;
+}
+
+pub fn getMedia(self: *const MediaQueryList) []const u8 {
+ return self._media;
+}
+
+/// Always returns false for dummy implementation
+pub fn getMatches(_: *const MediaQueryList) bool {
+ return false;
+}
+
+pub const JsApi = struct {
+ pub const bridge = js.Bridge(MediaQueryList);
+
+ pub const Meta = struct {
+ pub const name = "MediaQueryList";
+ pub const prototype_chain = bridge.prototypeChain();
+ pub var class_index: u16 = 0;
+ };
+
+ pub const media = bridge.accessor(MediaQueryList.getMedia, null, .{});
+ pub const matches = bridge.accessor(MediaQueryList.getMatches, null, .{});
+};
+
+const testing = @import("../../../testing.zig");
+test "WebApi: MediaQueryList" {
+ try testing.htmlRunner("css/media_query_list.html", .{});
+}