mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-12-16 16:28:58 +00:00
browser: refactor session and page
Now session owns the js env and the loader. page start and stop the js session.
This commit is contained in:
@@ -15,9 +15,13 @@ const Window = @import("../nav/window.zig").Window;
|
|||||||
|
|
||||||
const log = std.log.scoped(.lpd_browser);
|
const log = std.log.scoped(.lpd_browser);
|
||||||
|
|
||||||
|
// Browser is an instance of the browser.
|
||||||
|
// You can create multiple browser instances.
|
||||||
|
// It contains only one session but initVM() and deinitVM() must be called only
|
||||||
|
// once per main.
|
||||||
pub const Browser = struct {
|
pub const Browser = struct {
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
session: Session = undefined,
|
session: *Session = undefined,
|
||||||
|
|
||||||
var vm: jsruntime.VM = undefined;
|
var vm: jsruntime.VM = undefined;
|
||||||
pub fn initVM() void {
|
pub fn initVM() void {
|
||||||
@@ -27,74 +31,93 @@ pub const Browser = struct {
|
|||||||
vm.deinit();
|
vm.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator) Browser {
|
pub fn init(allocator: std.mem.Allocator) !Browser {
|
||||||
var b = Browser{ .allocator = allocator };
|
return Browser{
|
||||||
b.session = try b.createSession(null);
|
.allocator = allocator,
|
||||||
|
.session = try Session.init(allocator, "about:blank"),
|
||||||
return b;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Browser) void {
|
pub fn deinit(self: *Browser) void {
|
||||||
var session = self.session;
|
self.session.deinit();
|
||||||
session.deinit();
|
self.allocator.destroy(self.session);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn currentSession(self: *Browser) *Session {
|
pub fn currentSession(self: *Browser) *Session {
|
||||||
return &self.session;
|
return self.session;
|
||||||
}
|
|
||||||
|
|
||||||
fn createSession(self: *Browser, uri: ?[]const u8) !Session {
|
|
||||||
return Session.init(self.allocator, uri orelse "about:blank");
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Session is like a browser's tab.
|
||||||
|
// It owns the js env and the loader and an allocator arena for all the pages
|
||||||
|
// of the session.
|
||||||
|
// You can create successively multiple pages for a session, but you must
|
||||||
|
// deinit a page before running another one.
|
||||||
pub const Session = struct {
|
pub const Session = struct {
|
||||||
allocator: std.mem.Allocator,
|
arena: std.heap.ArenaAllocator,
|
||||||
uri: []const u8,
|
uri: []const u8,
|
||||||
// TODO handle proxy
|
tpls: [apis.len]TPL = undefined,
|
||||||
loader: Loader,
|
|
||||||
|
|
||||||
fn init(allocator: std.mem.Allocator, uri: []const u8) Session {
|
// TODO handle proxy
|
||||||
return Session{
|
loader: Loader = undefined,
|
||||||
.allocator = allocator,
|
env: Env = undefined,
|
||||||
|
loop: Loop = undefined,
|
||||||
|
|
||||||
|
fn init(allocator: std.mem.Allocator, uri: []const u8) !*Session {
|
||||||
|
var self = try allocator.create(Session);
|
||||||
|
self.* = Session{
|
||||||
.uri = uri,
|
.uri = uri,
|
||||||
.loader = Loader.init(allocator),
|
.arena = std.heap.ArenaAllocator.init(allocator),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const aallocator = self.arena.allocator();
|
||||||
|
|
||||||
|
self.loader = Loader.init(aallocator);
|
||||||
|
self.loop = try Loop.init(aallocator);
|
||||||
|
self.env = try Env.init(aallocator, &self.loop);
|
||||||
|
|
||||||
|
try self.env.load(apis, &self.tpls);
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deinit(self: *Session) void {
|
fn deinit(self: *Session) void {
|
||||||
self.loader.deinit();
|
self.loader.deinit();
|
||||||
}
|
self.loop.deinit();
|
||||||
|
self.env.deinit();
|
||||||
pub fn createPage(self: *Session) !Page {
|
|
||||||
return Page.init(self);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const Page = struct {
|
|
||||||
arena: std.heap.ArenaAllocator,
|
|
||||||
session: *Session,
|
|
||||||
env: Env,
|
|
||||||
|
|
||||||
fn init(session: *Session) Page {
|
|
||||||
return Page{
|
|
||||||
.session = session,
|
|
||||||
.arena = std.heap.ArenaAllocator.init(session.allocator),
|
|
||||||
.env = undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deinit(self: *Page) void {
|
|
||||||
self.arena.deinit();
|
self.arena.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn navigate(self: *Page, uri: []const u8) !void {
|
pub fn createPage(self: *Session) !Page {
|
||||||
const allocator = self.arena.allocator();
|
return Page.init(self.arena.allocator(), &self.loader, &self.env);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Page navigates to an url.
|
||||||
|
// You can navigates multiple urls with the same page, but you have to call
|
||||||
|
// end() to stop the previous navigation before starting a new one.
|
||||||
|
pub const Page = struct {
|
||||||
|
allocator: std.mem.Allocator,
|
||||||
|
loader: *Loader,
|
||||||
|
env: *Env,
|
||||||
|
|
||||||
|
fn init(allocator: std.mem.Allocator, loader: *Loader, env: *Env) Page {
|
||||||
|
return Page{
|
||||||
|
.allocator = allocator,
|
||||||
|
.loader = loader,
|
||||||
|
.env = env,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn end(self: *Page) void {
|
||||||
|
self.env.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn navigate(self: *Page, uri: []const u8) !void {
|
||||||
log.debug("starting GET {s}", .{uri});
|
log.debug("starting GET {s}", .{uri});
|
||||||
|
|
||||||
// load the data
|
// load the data
|
||||||
var result = try self.session.loader.fetch(allocator, uri);
|
var result = try self.loader.fetch(self.allocator, uri);
|
||||||
defer result.deinit();
|
defer result.deinit();
|
||||||
|
|
||||||
log.info("GET {s} {d}", .{ uri, result.status });
|
log.info("GET {s} {d}", .{ uri, result.status });
|
||||||
@@ -110,27 +133,12 @@ pub const Page = struct {
|
|||||||
|
|
||||||
// document
|
// document
|
||||||
log.debug("parse html", .{});
|
log.debug("parse html", .{});
|
||||||
const html_doc = try parser.documentHTMLParseFromStrAlloc(allocator, result.body.?);
|
const html_doc = try parser.documentHTMLParseFromStrAlloc(self.allocator, result.body.?);
|
||||||
const doc = parser.documentHTMLToDocument(html_doc);
|
const doc = parser.documentHTMLToDocument(html_doc);
|
||||||
|
|
||||||
log.debug("init loop", .{});
|
|
||||||
var loop = try Loop.init(allocator);
|
|
||||||
defer loop.deinit();
|
|
||||||
|
|
||||||
// create JS env
|
|
||||||
log.debug("init js env", .{});
|
|
||||||
self.env = try Env.init(allocator, &loop);
|
|
||||||
defer self.env.deinit();
|
|
||||||
|
|
||||||
// load APIs in JS env
|
|
||||||
log.debug("load js apis", .{});
|
|
||||||
var tpls: [apis.len]TPL = undefined;
|
|
||||||
try self.env.load(apis, &tpls);
|
|
||||||
|
|
||||||
// start JS env
|
// start JS env
|
||||||
log.debug("start js env", .{});
|
log.debug("start js env", .{});
|
||||||
try self.env.start(allocator, apis);
|
try self.env.start(self.allocator, apis);
|
||||||
defer self.env.stop();
|
|
||||||
|
|
||||||
// add global objects
|
// add global objects
|
||||||
log.debug("setup global env", .{});
|
log.debug("setup global env", .{});
|
||||||
@@ -142,12 +150,3 @@ pub const Page = struct {
|
|||||||
try self.env.addObject(apis, doc, "document");
|
try self.env.addObject(apis, doc, "document");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
test "create page" {
|
|
||||||
const allocator = std.testing.allocator;
|
|
||||||
var browser = Browser.init(allocator);
|
|
||||||
defer browser.deinit();
|
|
||||||
|
|
||||||
var page = try browser.currentSession().createPage();
|
|
||||||
defer page.deinit();
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -50,11 +50,10 @@ pub fn main() !void {
|
|||||||
Browser.initVM();
|
Browser.initVM();
|
||||||
defer Browser.deinitVM();
|
defer Browser.deinitVM();
|
||||||
|
|
||||||
var browser = Browser.init(allocator);
|
var browser = try Browser.init(allocator);
|
||||||
defer browser.deinit();
|
defer browser.deinit();
|
||||||
|
|
||||||
var page = try browser.currentSession().createPage();
|
var page = try browser.currentSession().createPage();
|
||||||
defer page.deinit();
|
defer page.end();
|
||||||
|
|
||||||
try page.navigate(url);
|
try page.navigate(url);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user