Skip to content

Commit acf06fd

Browse files
Resolve importmap against page's url
Co-authored-by: Karl Seguin <karlseguin@users.noreply.github.com>
1 parent 58cc5b4 commit acf06fd

File tree

1 file changed

+17
-7
lines changed

1 file changed

+17
-7
lines changed

src/browser/ScriptManager.zig

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ sync_modules: std.StringHashMapUnmanaged(*SyncModule),
7272

7373
// Mapping between module specifier and resolution.
7474
// see https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/script/type/importmap
75-
importmap: std.StringHashMapUnmanaged([]const u8),
75+
// importmap contains resolved urls.
76+
importmap: std.StringHashMapUnmanaged([:0]const u8),
7677

7778
const OrderList = std.DoublyLinkedList;
7879

@@ -124,7 +125,7 @@ pub fn reset(self: *ScriptManager) void {
124125
self.sync_modules.clearRetainingCapacity();
125126
// Our allocator is the page arena, it's been reset. We cannot use
126127
// clearAndRetainCapacity, since that space is no longer ours
127-
self.importmap.clearAndFree(self.page.arena);
128+
self.importmap = .empty;
128129

129130
self.clearList(&self.asyncs);
130131
self.clearList(&self.scripts);
@@ -262,11 +263,10 @@ pub fn addFromElement(self: *ScriptManager, element: *parser.Element, comptime c
262263
}
263264

264265
// Resolve a module specifier to an valid URL.
265-
pub fn resolveSpecifier(self: *ScriptManager, arena: Allocator, _specifier: []const u8, base: []const u8) ![:0]const u8 {
266-
var specifier = _specifier;
267-
// If the specifier is mapped in the importmap, use it to resolve the path.
266+
pub fn resolveSpecifier(self: *ScriptManager, arena: Allocator, specifier: []const u8, base: []const u8) ![:0]const u8 {
267+
// If the specifier is mapped in the importmap, return the pre-resolved value.
268268
if (self.importmap.get(specifier)) |s| {
269-
specifier = s;
269+
return s;
270270
}
271271

272272
return URL.stitch(
@@ -497,7 +497,17 @@ fn parseImportmap(self: *ScriptManager, script: *const Script) !void {
497497

498498
var iter = imports.imports.map.iterator();
499499
while (iter.next()) |entry| {
500-
try self.importmap.put(self.page.arena, entry.key_ptr.*, entry.value_ptr.*);
500+
// > Relative URLs are resolved to absolute URL addresses using the
501+
// > base URL of the document containing the import map.
502+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#importing_modules_using_import_maps
503+
const resolved_url = try URL.stitch(
504+
self.page.arena,
505+
entry.value_ptr.*,
506+
self.page.url.raw,
507+
.{ .alloc = .if_needed, .null_terminated = true },
508+
);
509+
510+
try self.importmap.put(self.page.arena, entry.key_ptr.*, resolved_url);
501511
}
502512

503513
return;

0 commit comments

Comments
 (0)