mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 15:13:28 +00:00
Merge pull request #470 from lightpanda-io/resove-module
Some checks are pending
e2e-test / zig build release (push) Waiting to run
e2e-test / puppeteer-perf (push) Blocked by required conditions
e2e-test / demo-scripts (push) Blocked by required conditions
wpt / web platform tests (push) Waiting to run
wpt / perf-fmt (push) Blocked by required conditions
zig-test / zig build dev (push) Waiting to run
zig-test / zig test (push) Waiting to run
zig-test / perf-fmt (push) Blocked by required conditions
Some checks are pending
e2e-test / zig build release (push) Waiting to run
e2e-test / puppeteer-perf (push) Blocked by required conditions
e2e-test / demo-scripts (push) Blocked by required conditions
wpt / web platform tests (push) Waiting to run
wpt / perf-fmt (push) Blocked by required conditions
zig-test / zig build dev (push) Waiting to run
zig-test / zig test (push) Waiting to run
zig-test / perf-fmt (push) Blocked by required conditions
browser: fix module URL resolution
This commit is contained in:
@@ -184,17 +184,18 @@ pub const Session = struct {
|
|||||||
_ = referrer;
|
_ = referrer;
|
||||||
|
|
||||||
const self: *Session = @ptrCast(@alignCast(ctx));
|
const self: *Session = @ptrCast(@alignCast(ctx));
|
||||||
|
const page = &(self.page orelse return error.NoPage);
|
||||||
if (self.page == null) {
|
|
||||||
return error.NoPage;
|
|
||||||
}
|
|
||||||
|
|
||||||
log.debug("fetch module: specifier: {s}", .{specifier});
|
log.debug("fetch module: specifier: {s}", .{specifier});
|
||||||
// fetchModule is called within the context of processing a page.
|
// fetchModule is called within the context of processing a page.
|
||||||
// Use the page_arena for this, which has a more appropriate lifetime
|
// Use the page_arena for this, which has a more appropriate lifetime
|
||||||
// and which has more retained memory between sessions and pages.
|
// and which has more retained memory between sessions and pages.
|
||||||
const arena = self.browser.page_arena.allocator();
|
const arena = self.browser.page_arena.allocator();
|
||||||
const body = try self.page.?.fetchData(arena, specifier);
|
const body = try page.fetchData(
|
||||||
|
arena,
|
||||||
|
specifier,
|
||||||
|
if (page.current_script) |s| s.src else null,
|
||||||
|
);
|
||||||
return self.env.compileModule(body, specifier);
|
return self.env.compileModule(body, specifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,6 +284,10 @@ pub const Page = struct {
|
|||||||
|
|
||||||
raw_data: ?[]const u8 = null,
|
raw_data: ?[]const u8 = null,
|
||||||
|
|
||||||
|
// current_script is the script currently evaluated by the page.
|
||||||
|
// current_script could by fetch module to resolve module's url to fetch.
|
||||||
|
current_script: ?*const Script = null,
|
||||||
|
|
||||||
fn init(session: *Session) Page {
|
fn init(session: *Session) Page {
|
||||||
return .{
|
return .{
|
||||||
.session = session,
|
.session = session,
|
||||||
@@ -504,7 +509,7 @@ pub const Page = struct {
|
|||||||
// > page.
|
// > page.
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#notes
|
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#notes
|
||||||
try parser.documentHTMLSetCurrentScript(html_doc, @ptrCast(e));
|
try parser.documentHTMLSetCurrentScript(html_doc, @ptrCast(e));
|
||||||
self.evalScript(script) catch |err| log.warn("evaljs: {any}", .{err});
|
self.evalScript(&script) catch |err| log.warn("evaljs: {any}", .{err});
|
||||||
try parser.documentHTMLSetCurrentScript(html_doc, null);
|
try parser.documentHTMLSetCurrentScript(html_doc, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -523,7 +528,7 @@ pub const Page = struct {
|
|||||||
// eval async scripts.
|
// eval async scripts.
|
||||||
for (sasync.items) |s| {
|
for (sasync.items) |s| {
|
||||||
try parser.documentHTMLSetCurrentScript(html_doc, @ptrCast(s.element));
|
try parser.documentHTMLSetCurrentScript(html_doc, @ptrCast(s.element));
|
||||||
self.evalScript(s) catch |err| log.warn("evaljs: {any}", .{err});
|
self.evalScript(&s) catch |err| log.warn("evaljs: {any}", .{err});
|
||||||
try parser.documentHTMLSetCurrentScript(html_doc, null);
|
try parser.documentHTMLSetCurrentScript(html_doc, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -545,7 +550,10 @@ pub const Page = struct {
|
|||||||
// evalScript evaluates the src in priority.
|
// evalScript evaluates the src in priority.
|
||||||
// if no src is present, we evaluate the text source.
|
// if no src is present, we evaluate the text source.
|
||||||
// https://html.spec.whatwg.org/multipage/scripting.html#script-processing-model
|
// https://html.spec.whatwg.org/multipage/scripting.html#script-processing-model
|
||||||
fn evalScript(self: *Page, s: Script) !void {
|
fn evalScript(self: *Page, s: *const Script) !void {
|
||||||
|
self.current_script = s;
|
||||||
|
defer self.current_script = null;
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-classic-script
|
// https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-classic-script
|
||||||
const opt_src = try parser.elementGetAttribute(s.element, "src");
|
const opt_src = try parser.elementGetAttribute(s.element, "src");
|
||||||
if (opt_src) |src| {
|
if (opt_src) |src| {
|
||||||
@@ -590,13 +598,27 @@ pub const Page = struct {
|
|||||||
JsErr,
|
JsErr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// fetchData returns the data corresponding to the src target.
|
||||||
|
// It resolves src using the page's uri.
|
||||||
|
// If a base path is given, src is resolved according to the base first.
|
||||||
// the caller owns the returned string
|
// the caller owns the returned string
|
||||||
fn fetchData(self: *Page, arena: Allocator, src: []const u8) ![]const u8 {
|
fn fetchData(self: *const Page, arena: Allocator, src: []const u8, base: ?[]const u8) ![]const u8 {
|
||||||
log.debug("starting fetch {s}", .{src});
|
log.debug("starting fetch {s}", .{src});
|
||||||
|
|
||||||
var buffer: [1024]u8 = undefined;
|
var buffer: [1024]u8 = undefined;
|
||||||
var b: []u8 = buffer[0..];
|
var b: []u8 = buffer[0..];
|
||||||
const u = try std.Uri.resolve_inplace(self.uri, src, &b);
|
|
||||||
|
var res_src = src;
|
||||||
|
|
||||||
|
// if a base path is given, we resolve src using base.
|
||||||
|
if (base) |_base| {
|
||||||
|
const dir = std.fs.path.dirname(_base);
|
||||||
|
if (dir) |_dir| {
|
||||||
|
res_src = try std.fs.path.resolve(arena, &.{ _dir, src });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const u = try std.Uri.resolve_inplace(self.uri, res_src, &b);
|
||||||
|
|
||||||
var fetchres = try self.session.loader.get(arena, u);
|
var fetchres = try self.session.loader.get(arena, u);
|
||||||
defer fetchres.deinit();
|
defer fetchres.deinit();
|
||||||
@@ -622,9 +644,10 @@ pub const Page = struct {
|
|||||||
|
|
||||||
// fetchScript senf a GET request to the src and execute the script
|
// fetchScript senf a GET request to the src and execute the script
|
||||||
// received.
|
// received.
|
||||||
fn fetchScript(self: *Page, s: Script) !void {
|
fn fetchScript(self: *const Page, s: *const Script) !void {
|
||||||
const arena = self.arena;
|
const arena = self.arena;
|
||||||
const body = try self.fetchData(arena, s.src);
|
|
||||||
|
const body = try self.fetchData(arena, s.src, null);
|
||||||
// TODO: change to &self.session.env when
|
// TODO: change to &self.session.env when
|
||||||
// https://github.com/lightpanda-io/zig-js-runtime/pull/285 lands
|
// https://github.com/lightpanda-io/zig-js-runtime/pull/285 lands
|
||||||
try s.eval(arena, self.session.env, body);
|
try s.eval(arena, self.session.env, body);
|
||||||
|
|||||||
Reference in New Issue
Block a user