mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-02-04 14:33:47 +00:00
page: use optional base_url to resolve urls
This commit is contained in:
@@ -142,6 +142,11 @@ _queued_navigation: ?QueuedNavigation = null,
|
|||||||
// The URL of the current page
|
// The URL of the current page
|
||||||
url: [:0]const u8,
|
url: [:0]const u8,
|
||||||
|
|
||||||
|
// The base url specifies the base URL used to resolve the relative urls.
|
||||||
|
// It is set by a <base> tag.
|
||||||
|
// If null the url must be used.
|
||||||
|
base_url: ?[:0]const u8,
|
||||||
|
|
||||||
// Arbitrary buffer. Need to temporarily lowercase a value? Use this. No lifetime
|
// Arbitrary buffer. Need to temporarily lowercase a value? Use this. No lifetime
|
||||||
// guarantee - it's valid until someone else uses it.
|
// guarantee - it's valid until someone else uses it.
|
||||||
buf: [BUF_SIZE]u8,
|
buf: [BUF_SIZE]u8,
|
||||||
@@ -218,6 +223,7 @@ fn reset(self: *Page, comptime initializing: bool) !void {
|
|||||||
|
|
||||||
self.version = 0;
|
self.version = 0;
|
||||||
self.url = "about:blank";
|
self.url = "about:blank";
|
||||||
|
self.base_url = null;
|
||||||
|
|
||||||
self.document = (try self._factory.document(Node.Document.HTMLDocument{ ._proto = undefined })).asDocument();
|
self.document = (try self._factory.document(Node.Document.HTMLDocument{ ._proto = undefined })).asDocument();
|
||||||
|
|
||||||
@@ -272,6 +278,10 @@ fn reset(self: *Page, comptime initializing: bool) !void {
|
|||||||
try self.registerBackgroundTasks();
|
try self.registerBackgroundTasks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn base(self: *const Page) [:0]const u8 {
|
||||||
|
return self.base_url orelse self.url;
|
||||||
|
}
|
||||||
|
|
||||||
fn registerBackgroundTasks(self: *Page) !void {
|
fn registerBackgroundTasks(self: *Page) !void {
|
||||||
if (comptime builtin.is_test) {
|
if (comptime builtin.is_test) {
|
||||||
// HTML test runner manually calls these as necessary
|
// HTML test runner manually calls these as necessary
|
||||||
@@ -423,7 +433,7 @@ pub fn scheduleNavigation(self: *Page, request_url: []const u8, opts: NavigateOp
|
|||||||
|
|
||||||
const resolved_url = try URL.resolve(
|
const resolved_url = try URL.resolve(
|
||||||
session.transfer_arena,
|
session.transfer_arena,
|
||||||
self.url,
|
self.base(),
|
||||||
request_url,
|
request_url,
|
||||||
.{ .always_dupe = true },
|
.{ .always_dupe = true },
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -190,11 +190,12 @@ pub fn addFromElement(self: *ScriptManager, comptime from_parser: bool, script_e
|
|||||||
const page = self.page;
|
const page = self.page;
|
||||||
var source: Script.Source = undefined;
|
var source: Script.Source = undefined;
|
||||||
var remote_url: ?[:0]const u8 = null;
|
var remote_url: ?[:0]const u8 = null;
|
||||||
|
const base_url = page.base();
|
||||||
if (element.getAttributeSafe("src")) |src| {
|
if (element.getAttributeSafe("src")) |src| {
|
||||||
if (try parseDataURI(page.arena, src)) |data_uri| {
|
if (try parseDataURI(page.arena, src)) |data_uri| {
|
||||||
source = .{ .@"inline" = data_uri };
|
source = .{ .@"inline" = data_uri };
|
||||||
} else {
|
} else {
|
||||||
remote_url = try URL.resolve(page.arena, page.url, src, .{});
|
remote_url = try URL.resolve(page.arena, base_url, src, .{});
|
||||||
source = .{ .remote = .{} };
|
source = .{ .remote = .{} };
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -215,7 +216,7 @@ pub fn addFromElement(self: *ScriptManager, comptime from_parser: bool, script_e
|
|||||||
.script_element = script_element,
|
.script_element = script_element,
|
||||||
.complete = is_inline,
|
.complete = is_inline,
|
||||||
.status = if (is_inline) 200 else 0,
|
.status = if (is_inline) 200 else 0,
|
||||||
.url = remote_url orelse page.url,
|
.url = remote_url orelse base_url,
|
||||||
.mode = blk: {
|
.mode = blk: {
|
||||||
if (source == .@"inline") {
|
if (source == .@"inline") {
|
||||||
break :blk if (kind == .module) .@"defer" else .normal;
|
break :blk if (kind == .module) .@"defer" else .normal;
|
||||||
@@ -568,7 +569,7 @@ fn parseImportmap(self: *ScriptManager, script: *const Script) !void {
|
|||||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#importing_modules_using_import_maps
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#importing_modules_using_import_maps
|
||||||
const resolved_url = try URL.resolve(
|
const resolved_url = try URL.resolve(
|
||||||
self.page.arena,
|
self.page.arena,
|
||||||
self.page.url,
|
self.page.base(),
|
||||||
entry.value_ptr.*,
|
entry.value_ptr.*,
|
||||||
.{},
|
.{},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ pub fn root(doc: *Node.Document, opts: RootOpts, writer: *std.Io.Writer, page: *
|
|||||||
if (opts.with_base) {
|
if (opts.with_base) {
|
||||||
const parent = if (html_doc.getHead()) |head| head.asNode() else doc.asNode();
|
const parent = if (html_doc.getHead()) |head| head.asNode() else doc.asNode();
|
||||||
const base = try doc.createElement("base", null, page);
|
const base = try doc.createElement("base", null, page);
|
||||||
try base.setAttributeSafe("base", page.url, page);
|
try base.setAttributeSafe("base", page.base(), page);
|
||||||
_ = try parent.insertBefore(base.asNode(), parent.firstChild(), page);
|
_ = try parent.insertBefore(base.asNode(), parent.firstChild(), page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -876,7 +876,7 @@ pub const JsApi = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn _baseURI(_: *Node, page: *const Page) []const u8 {
|
fn _baseURI(_: *Node, page: *const Page) []const u8 {
|
||||||
return page.url[0..];
|
return page.base();
|
||||||
}
|
}
|
||||||
pub const baseURI = bridge.accessor(_baseURI, null, .{});
|
pub const baseURI = bridge.accessor(_baseURI, null, .{});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ pub fn getHref(self: *Anchor, page: *Page) ![]const u8 {
|
|||||||
if (href.len == 0) {
|
if (href.len == 0) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
return URL.resolve(page.call_arena, page.url, href, .{});
|
return URL.resolve(page.call_arena, page.base(), href, .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setHref(self: *Anchor, value: []const u8, page: *Page) !void {
|
pub fn setHref(self: *Anchor, value: []const u8, page: *Page) !void {
|
||||||
@@ -195,7 +195,7 @@ fn getResolvedHref(self: *Anchor, page: *Page) !?[:0]const u8 {
|
|||||||
if (href.len == 0) {
|
if (href.len == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return try URL.resolve(page.call_arena, page.url, href, .{});
|
return try URL.resolve(page.call_arena, page.base(), href, .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const JsApi = struct {
|
pub const JsApi = struct {
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ pub fn getSrc(self: *const Image, page: *Page) ![]const u8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Always resolve the src against the page URL
|
// Always resolve the src against the page URL
|
||||||
return URL.resolve(page.call_arena, page.url, src, .{});
|
return URL.resolve(page.call_arena, page.base(), src, .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setSrc(self: *Image, value: []const u8, page: *Page) !void {
|
pub fn setSrc(self: *Image, value: []const u8, page: *Page) !void {
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ pub fn getHref(self: *Link, page: *Page) ![]const u8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Always resolve the href against the page URL
|
// Always resolve the href against the page URL
|
||||||
return URL.resolve(page.call_arena, page.url, href, .{});
|
return URL.resolve(page.call_arena, page.base(), href, .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setHref(self: *Link, value: []const u8, page: *Page) !void {
|
pub fn setHref(self: *Link, value: []const u8, page: *Page) !void {
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ pub fn getSrc(self: *const Media, page: *Page) ![]const u8 {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
const URL = @import("../../URL.zig");
|
const URL = @import("../../URL.zig");
|
||||||
return URL.resolve(page.call_arena, page.url, src, .{});
|
return URL.resolve(page.call_arena, page.base(), src, .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setSrc(self: *Media, value: []const u8, page: *Page) !void {
|
pub fn setSrc(self: *Media, value: []const u8, page: *Page) !void {
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ pub fn getPoster(self: *const Video, page: *Page) ![]const u8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const URL = @import("../../URL.zig");
|
const URL = @import("../../URL.zig");
|
||||||
return URL.resolve(page.call_arena, page.url, poster, .{});
|
return URL.resolve(page.call_arena, page.base(), poster, .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setPoster(self: *Video, value: []const u8, page: *Page) !void {
|
pub fn setPoster(self: *Video, value: []const u8, page: *Page) !void {
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ pub fn key(self: *const NavigationHistoryEntry) []const u8 {
|
|||||||
|
|
||||||
pub fn sameDocument(self: *const NavigationHistoryEntry, page: *Page) bool {
|
pub fn sameDocument(self: *const NavigationHistoryEntry, page: *Page) bool {
|
||||||
const got_url = self._url orelse return false;
|
const got_url = self._url orelse return false;
|
||||||
return URL.eqlDocument(got_url, page.url);
|
return URL.eqlDocument(got_url, page.base());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn url(self: *const NavigationHistoryEntry) ?[:0]const u8 {
|
pub fn url(self: *const NavigationHistoryEntry) ?[:0]const u8 {
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ const Cache = enum {
|
|||||||
pub fn init(input: Input, opts_: ?InitOpts, page: *Page) !*Request {
|
pub fn init(input: Input, opts_: ?InitOpts, page: *Page) !*Request {
|
||||||
const arena = page.arena;
|
const arena = page.arena;
|
||||||
const url = switch (input) {
|
const url = switch (input) {
|
||||||
.url => |u| try URL.resolve(arena, page.url, u, .{ .always_dupe = true }),
|
.url => |u| try URL.resolve(arena, page.base(), u, .{ .always_dupe = true }),
|
||||||
.request => |r| try arena.dupeZ(u8, r._url),
|
.request => |r| try arena.dupeZ(u8, r._url),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ pub fn open(self: *XMLHttpRequest, method_: []const u8, url: [:0]const u8) !void
|
|||||||
self._request_body = null;
|
self._request_body = null;
|
||||||
|
|
||||||
self._method = try parseMethod(method_);
|
self._method = try parseMethod(method_);
|
||||||
self._url = try URL.resolve(self._arena, self._page.url, url, .{ .always_dupe = true });
|
self._url = try URL.resolve(self._arena, self._page.base(), url, .{ .always_dupe = true });
|
||||||
try self.stateChanged(.opened, self._page);
|
try self.stateChanged(.opened, self._page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user