Merge branch 'main' into semantic-tree

This commit is contained in:
Adrià Arrufat
2026-03-11 20:52:39 +09:00
100 changed files with 3015 additions and 1663 deletions

View File

@@ -406,7 +406,7 @@ test "cdp Node: search list" {
{
const l1 = try doc.querySelectorAll(.wrap("a"), page);
defer l1.deinit(page);
defer l1.deinit(page._session);
const s1 = try search_list.create(l1._nodes);
try testing.expectEqual("1", s1.name);
try testing.expectEqualSlices(u32, &.{ 1, 2 }, s1.node_ids);
@@ -417,7 +417,7 @@ test "cdp Node: search list" {
{
const l2 = try doc.querySelectorAll(.wrap("#a1"), page);
defer l2.deinit(page);
defer l2.deinit(page._session);
const s2 = try search_list.create(l2._nodes);
try testing.expectEqual("2", s2.name);
try testing.expectEqualSlices(u32, &.{1}, s2.node_ids);
@@ -425,7 +425,7 @@ test "cdp Node: search list" {
{
const l3 = try doc.querySelectorAll(.wrap("#a2"), page);
defer l3.deinit(page);
defer l3.deinit(page._session);
const s3 = try search_list.create(l3._nodes);
try testing.expectEqual("3", s3.name);
try testing.expectEqualSlices(u32, &.{2}, s3.node_ids);

View File

@@ -28,7 +28,7 @@ const js = @import("../browser/js/js.zig");
const App = @import("../App.zig");
const Browser = @import("../browser/Browser.zig");
const Session = @import("../browser/Session.zig");
const HttpClient = @import("../http/Client.zig");
const HttpClient = @import("../browser/HttpClient.zig");
const Page = @import("../browser/Page.zig");
const Incrementing = @import("id.zig").Incrementing;
const Notification = @import("../Notification.zig");
@@ -459,6 +459,12 @@ pub fn BrowserContext(comptime CDP_T: type) type {
}
self.isolated_worlds.clearRetainingCapacity();
// do this before closeSession, since we don't want to process any
// new notification (Or maybe, instead of the deinit above, we just
// rely on those notifications to do our normal cleanup?)
self.notification.unregisterAll(self);
// If the session has a page, we need to clear it first. The page
// context is always nested inside of the isolated world context,
// so we need to shutdown the page one first.
@@ -466,7 +472,6 @@ pub fn BrowserContext(comptime CDP_T: type) type {
self.node_registry.deinit();
self.node_search_list.deinit();
self.notification.unregisterAll(self);
self.notification.deinit();
if (self.http_proxy_changed) {

View File

@@ -98,7 +98,7 @@ fn performSearch(cmd: anytype) !void {
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
const page = bc.session.currentPage() orelse return error.PageNotLoaded;
const list = try Selector.querySelectorAll(page.window._document.asNode(), params.query, page);
defer list.deinit(page);
defer list.deinit(page._session);
const search = try bc.node_search_list.create(list._nodes);
@@ -249,7 +249,7 @@ fn querySelectorAll(cmd: anytype) !void {
};
const selected_nodes = try Selector.querySelectorAll(node.dom, params.selector, page);
defer selected_nodes.deinit(page);
defer selected_nodes.deinit(page._session);
const nodes = selected_nodes._nodes;

View File

@@ -23,7 +23,8 @@ const id = @import("../id.zig");
const log = @import("../../log.zig");
const network = @import("network.zig");
const Http = @import("../../http/Http.zig");
const HttpClient = @import("../../browser/HttpClient.zig");
const net_http = @import("../../network/http.zig");
const Notification = @import("../../Notification.zig");
pub fn processMessage(cmd: anytype) !void {
@@ -49,7 +50,7 @@ pub fn processMessage(cmd: anytype) !void {
// Stored in CDP
pub const InterceptState = struct {
allocator: Allocator,
waiting: std.AutoArrayHashMapUnmanaged(u32, *Http.Transfer),
waiting: std.AutoArrayHashMapUnmanaged(u32, *HttpClient.Transfer),
pub fn init(allocator: Allocator) !InterceptState {
return .{
@@ -62,11 +63,11 @@ pub const InterceptState = struct {
return self.waiting.count() == 0;
}
pub fn put(self: *InterceptState, transfer: *Http.Transfer) !void {
pub fn put(self: *InterceptState, transfer: *HttpClient.Transfer) !void {
return self.waiting.put(self.allocator, transfer.id, transfer);
}
pub fn remove(self: *InterceptState, request_id: u32) ?*Http.Transfer {
pub fn remove(self: *InterceptState, request_id: u32) ?*HttpClient.Transfer {
const entry = self.waiting.fetchSwapRemove(request_id) orelse return null;
return entry.value;
}
@@ -75,7 +76,7 @@ pub const InterceptState = struct {
self.waiting.deinit(self.allocator);
}
pub fn pendingTransfers(self: *const InterceptState) []*Http.Transfer {
pub fn pendingTransfers(self: *const InterceptState) []*HttpClient.Transfer {
return self.waiting.values();
}
};
@@ -221,7 +222,7 @@ fn continueRequest(cmd: anytype) !void {
url: ?[]const u8 = null,
method: ?[]const u8 = null,
postData: ?[]const u8 = null,
headers: ?[]const Http.Header = null,
headers: ?[]const net_http.Header = null,
interceptResponse: bool = false,
})) orelse return error.InvalidParams;
@@ -246,7 +247,7 @@ fn continueRequest(cmd: anytype) !void {
try transfer.updateURL(try arena.dupeZ(u8, url));
}
if (params.method) |method| {
transfer.req.method = std.meta.stringToEnum(Http.Method, method) orelse return error.InvalidParams;
transfer.req.method = std.meta.stringToEnum(net_http.Method, method) orelse return error.InvalidParams;
}
if (params.headers) |headers| {
@@ -323,7 +324,7 @@ fn fulfillRequest(cmd: anytype) !void {
const params = (try cmd.params(struct {
requestId: []const u8, // "INT-{d}"
responseCode: u16,
responseHeaders: ?[]const Http.Header = null,
responseHeaders: ?[]const net_http.Header = null,
binaryResponseHeaders: ?[]const u8 = null,
body: ?[]const u8 = null,
responsePhrase: ?[]const u8 = null,

View File

@@ -24,7 +24,7 @@ const CdpStorage = @import("storage.zig");
const id = @import("../id.zig");
const URL = @import("../../browser/URL.zig");
const Transfer = @import("../../http/Client.zig").Transfer;
const Transfer = @import("../../browser/HttpClient.zig").Transfer;
const Notification = @import("../../Notification.zig");
const Mime = @import("../../browser/Mime.zig");

View File

@@ -292,6 +292,10 @@ pub fn pageNavigate(bc: anytype, event: *const Notification.PageNavigate) !void
}
pub fn pageRemove(bc: anytype) !void {
// Clear all remote object mappings to prevent stale objectIds from being used
// after the context is destroy
bc.inspector_session.inspector.resetContextGroup();
// The main page is going to be removed, we need to remove contexts from other worlds first.
for (bc.isolated_worlds.items) |isolated_world| {
try isolated_world.removeContext();
@@ -410,7 +414,7 @@ pub fn pageNavigated(arena: Allocator, bc: anytype, event: *const Notification.P
bc.inspector_session.inspector.contextCreated(
&ls.local,
"",
try page.getOrigin(arena) orelse "",
page.origin orelse "",
aux_data,
true,
);