mirror of
				https://github.com/lightpanda-io/browser.git
				synced 2025-10-29 15:13:28 +00:00 
			
		
		
		
	Implement location.reload(), location.assign() and location setter
I'm not sure that _any_ location instance should be able to change the page URL. But you can't create a new location (i.e. new Location() isn't valid), and the only two ways I know of are via `window.location` and `document.location` both of which _should_ alter the location of the window/document.
This commit is contained in:
		| @@ -174,6 +174,10 @@ pub const HTMLDocument = struct { | ||||
|         return try parser.documentHTMLGetLocation(Location, self); | ||||
|     } | ||||
|  | ||||
|     pub fn set_location(_: *const parser.DocumentHTML, url: []const u8, page: *Page) !void { | ||||
|         return page.navigateFromWebAPI(url); | ||||
|     } | ||||
|  | ||||
|     pub fn get_designMode(_: *parser.DocumentHTML) []const u8 { | ||||
|         return "off"; | ||||
|     } | ||||
|   | ||||
| @@ -69,18 +69,17 @@ pub const Location = struct { | ||||
|         return ""; | ||||
|     } | ||||
|  | ||||
|     // TODO | ||||
|     pub fn _assign(_: *Location, url: []const u8) !void { | ||||
|         _ = url; | ||||
|     pub fn _assign(_: *const Location, url: []const u8, page: *Page) !void { | ||||
|         return page.navigateFromWebAPI(url); | ||||
|     } | ||||
|  | ||||
|     // TODO | ||||
|     pub fn _replace(_: *Location, url: []const u8) !void { | ||||
|         _ = url; | ||||
|     pub fn _replace(_: *const Location, url: []const u8, page: *Page) !void { | ||||
|         return page.navigateFromWebAPI(url); | ||||
|     } | ||||
|  | ||||
|     // TODO | ||||
|     pub fn _reload(_: *Location) !void {} | ||||
|     pub fn _reload(_: *const Location, page: *Page) !void { | ||||
|         return page.navigateFromWebAPI(page.url.raw); | ||||
|     } | ||||
|  | ||||
|     pub fn _toString(self: *Location, page: *Page) ![]const u8 { | ||||
|         return try self.get_href(page); | ||||
|   | ||||
| @@ -100,6 +100,10 @@ pub const Window = struct { | ||||
|         return &self.location; | ||||
|     } | ||||
|  | ||||
|     pub fn set_location(_: *const Window, url: []const u8, page: *Page) !void { | ||||
|         return page.navigateFromWebAPI(url); | ||||
|     } | ||||
|  | ||||
|     pub fn get_console(self: *Window) *Console { | ||||
|         return &self.console; | ||||
|     } | ||||
|   | ||||
| @@ -541,23 +541,25 @@ pub const Page = struct { | ||||
|             .a => { | ||||
|                 const element: *parser.Element = @ptrCast(node); | ||||
|                 const href = (try parser.elementGetAttribute(element, "href")) orelse return; | ||||
|  | ||||
|                 // We cannot navigate immediately as navigating will delete the DOM tree, which holds this event's node. | ||||
|                 // As such we schedule the function to be called as soon as possible. | ||||
|                 // NOTE Using the page.arena assumes that the scheduling loop does use this object after invoking the callback | ||||
|                 // If that changes we may want to consider storing DelayedNavigation in the session instead. | ||||
|                 const arena = self.arena; | ||||
|                 const navi = try arena.create(DelayedNavigation); | ||||
|                 navi.* = .{ | ||||
|                     .session = self.session, | ||||
|                     .href = try arena.dupe(u8, href), | ||||
|                 }; | ||||
|                 _ = try self.loop.timeout(0, &navi.navigate_node); | ||||
|                 try self.navigateFromWebAPI(href); | ||||
|             }, | ||||
|             else => {}, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // As such we schedule the function to be called as soon as possible. | ||||
|     // The page.arena is safe to use here, but the transfer_arena exists | ||||
|     // specifically for this type of lifetime. | ||||
|     pub fn navigateFromWebAPI(self: *Page, url: []const u8) !void { | ||||
|         const arena = self.session.transfer_arena; | ||||
|         const navi = try arena.create(DelayedNavigation); | ||||
|         navi.* = .{ | ||||
|             .session = self.session, | ||||
|             .url = try arena.dupe(u8, url), | ||||
|         }; | ||||
|         _ = try self.loop.timeout(0, &navi.navigate_node); | ||||
|     } | ||||
|  | ||||
|     pub fn getOrCreateNodeWrapper(self: *Page, comptime T: type, node: *parser.Node) !*T { | ||||
|         if (try self.getNodeWrapper(T, node)) |wrap| { | ||||
|             return wrap; | ||||
| @@ -579,16 +581,15 @@ pub const Page = struct { | ||||
| }; | ||||
|  | ||||
| const DelayedNavigation = struct { | ||||
|     navigate_node: Loop.CallbackNode = .{ .func = DelayedNavigation.delay_navigate }, | ||||
|     url: []const u8, | ||||
|     session: *Session, | ||||
|     href: []const u8, | ||||
|     navigate_node: Loop.CallbackNode = .{ .func = delayNavigate }, | ||||
|  | ||||
|     fn delay_navigate(node: *Loop.CallbackNode, repeat_delay: *?u63) void { | ||||
|     fn delayNavigate(node: *Loop.CallbackNode, repeat_delay: *?u63) void { | ||||
|         _ = repeat_delay; | ||||
|         const self: *DelayedNavigation = @fieldParentPtr("navigate_node", node); | ||||
|         self.session.pageNavigate(self.href) catch |err| { | ||||
|             // TODO: should we trigger a specific event here? | ||||
|             log.err(.page, "delayed navigation error", .{ .err = err }); | ||||
|         self.session.pageNavigate(self.url) catch |err| { | ||||
|             log.err(.page, "delayed navigation error", .{ .err = err, .url = self.url }); | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Karl Seguin
					Karl Seguin