Skip to content

Commit 7ee338a

Browse files
committed
add NavigationCurrentEntryChangeEvent
1 parent 8340696 commit 7ee338a

File tree

5 files changed

+96
-49
lines changed

5 files changed

+96
-49
lines changed

src/browser/events/event.zig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const KeyboardEvent = @import("keyboard_event.zig").KeyboardEvent;
3737
const ErrorEvent = @import("../html/error_event.zig").ErrorEvent;
3838
const MessageEvent = @import("../dom/MessageChannel.zig").MessageEvent;
3939
const PopStateEvent = @import("../html/History.zig").PopStateEvent;
40+
const NavigationCurrentEntryChangeEvent = @import("../html/Navigation.zig").NavigationCurrentEntryChangeEvent;
4041

4142
// Event interfaces
4243
pub const Interfaces = .{
@@ -48,6 +49,7 @@ pub const Interfaces = .{
4849
ErrorEvent,
4950
MessageEvent,
5051
PopStateEvent,
52+
NavigationCurrentEntryChangeEvent,
5153
};
5254

5355
pub const Union = generate.Union(Interfaces);
@@ -76,6 +78,7 @@ pub const Event = struct {
7678
.message_event => .{ .MessageEvent = @as(*MessageEvent, @ptrCast(evt)).* },
7779
.keyboard_event => .{ .KeyboardEvent = @as(*parser.KeyboardEvent, @ptrCast(evt)) },
7880
.pop_state => .{ .PopStateEvent = @as(*PopStateEvent, @ptrCast(evt)).* },
81+
.navigation_current_entry_change => .{ .NavigationCurrentEntryChangeEvent = @as(*NavigationCurrentEntryChangeEvent, @ptrCast(*evt)).* },
7982
};
8083
}
8184

src/browser/html/History.zig

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,22 +60,19 @@ pub fn dispatchPopStateEvent(state: ?[]const u8, page: *Page) void {
6060
.type = "popstate",
6161
.source = "history",
6262
});
63-
History._dispatchPopStateEvent(state, page) catch |err| {
64-
log.err(.app, "dispatch popstate event error", .{
65-
.err = err,
66-
.type = "popstate",
67-
.source = "history",
68-
});
69-
};
70-
}
7163

72-
fn _dispatchPopStateEvent(state: ?[]const u8, page: *Page) !void {
7364
var evt = try PopStateEvent.constructor("popstate", .{ .state = state });
7465

7566
_ = try parser.eventTargetDispatchEvent(
7667
@as(*parser.EventTarget, @ptrCast(&page.window)),
7768
&evt.proto,
78-
);
69+
) catch |e| {
70+
log.err(.app, "dispatch popstate event error", .{
71+
.err = e,
72+
.type = "popstate",
73+
.source = "history",
74+
});
75+
};
7976
}
8077

8178
pub fn _pushState(_: *const History, state: js.Object, _: ?[]const u8, _url: ?[]const u8, page: *Page) !void {

src/browser/html/Navigation.zig

Lines changed: 84 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,15 @@
1717
// along with this program. If not, see <https://www.gnu.org/licenses/>.
1818

1919
const std = @import("std");
20+
2021
const log = @import("../../log.zig");
22+
const testing = @import("../../testing.zig");
2123
const URL = @import("../../url.zig").URL;
22-
23-
const js = @import("../js/js.zig");
24-
const Page = @import("../page.zig").Page;
25-
2624
const EventTarget = @import("../dom/event_target.zig").EventTarget;
2725
const EventHandler = @import("../events/event.zig").EventHandler;
28-
26+
const js = @import("../js/js.zig");
2927
const parser = @import("../netsurf.zig");
28+
const Page = @import("../page.zig").Page;
3029

3130
// https://developer.mozilla.org/en-US/docs/Web/API/Navigation
3231
const Navigation = @This();
@@ -38,12 +37,20 @@ pub const Interfaces = .{
3837
NavigationHistoryEntry,
3938
};
4039

41-
pub const NavigationKind = union(enum) {
42-
initial,
40+
pub const NavigationType = enum {
41+
pub const ENUM_JS_USE_TAG = true;
42+
43+
push,
44+
replace,
45+
reload,
46+
traverse,
47+
};
48+
49+
pub const NavigationKind = union(NavigationType) {
4350
push: ?[]const u8,
4451
replace,
45-
traverse: usize,
4652
reload,
53+
traverse: usize,
4754
};
4855

4956
pub const prototype = *EventTarget;
@@ -103,18 +110,9 @@ const NavigationHistoryEntry = struct {
103110

104111
// https://developer.mozilla.org/en-US/docs/Web/API/NavigationActivation
105112
const NavigationActivation = struct {
106-
const NavigationActivationType = enum {
107-
pub const ENUM_JS_USE_TAG = true;
108-
109-
push,
110-
reload,
111-
replace,
112-
traverse,
113-
};
114-
115113
entry: NavigationHistoryEntry,
116114
from: ?NavigationHistoryEntry = null,
117-
type: NavigationActivationType,
115+
type: NavigationType,
118116

119117
pub fn get_entry(self: *const NavigationActivation) NavigationHistoryEntry {
120118
return self.entry;
@@ -124,7 +122,7 @@ const NavigationActivation = struct {
124122
return self.from;
125123
}
126124

127-
pub fn get_navigationType(self: *const NavigationActivation) NavigationActivationType {
125+
pub fn get_navigationType(self: *const NavigationActivation) NavigationType {
128126
return self.type;
129127
}
130128
};
@@ -133,7 +131,7 @@ const NavigationActivation = struct {
133131
const NavigationTransition = struct {
134132
finished: js.Promise,
135133
from: NavigationHistoryEntry,
136-
navigation_type: NavigationActivation.NavigationActivationType,
134+
navigation_type: NavigationType,
137135
};
138136

139137
pub fn get_canGoBack(self: *const Navigation) bool {
@@ -191,21 +189,22 @@ pub fn _forward(self: *Navigation, page: *Page) !NavigationReturn {
191189
}
192190

193191
// This is for after true navigation processing, where we need to ensure that our entries are up to date.
194-
pub fn processNavigation(self: *Navigation, url: []const u8, kind: NavigationKind, page: *Page) !void {
195-
switch (kind) {
196-
.initial => {
197-
_ = try self.pushEntry(url, null, page);
198-
},
199-
.replace => {
200-
// When replacing, we just update the URL but the state is nullified.
201-
const entry = self.currentEntry();
202-
entry.url = url;
203-
entry.state = null;
204-
},
205-
.push => |state| {
206-
_ = try self.pushEntry(url, state, page);
207-
},
208-
.traverse, .reload => {},
192+
pub fn processNavigation(self: *Navigation, url: []const u8, kind: ?NavigationKind, page: *Page) !void {
193+
if (kind) |k| {
194+
switch (k) {
195+
.replace => {
196+
// When replacing, we just update the URL but the state is nullified.
197+
const entry = self.currentEntry();
198+
entry.url = url;
199+
entry.state = null;
200+
},
201+
.push => |state| {
202+
_ = try self.pushEntry(url, state, page);
203+
},
204+
.traverse, .reload => {},
205+
}
206+
} else {
207+
_ = try self.pushEntry(url, null, page);
209208
}
210209
}
211210

@@ -300,7 +299,7 @@ pub fn navigate(
300299
.reload => {
301300
try page.navigateFromWebAPI(url, .{ .reason = .navigation }, kind);
302301
},
303-
else => unreachable,
302+
.replace => {},
304303
}
305304

306305
return .{
@@ -312,7 +311,17 @@ pub fn navigate(
312311
pub fn _navigate(self: *Navigation, _url: []const u8, _opts: ?NavigateOptions, page: *Page) !NavigationReturn {
313312
const opts = _opts orelse NavigateOptions{};
314313
const json = if (opts.state) |state| state.toJson(page.session.arena) catch return error.DataClone else null;
315-
return try self.navigate(_url, .{ .push = json }, page);
314+
315+
switch (opts.history) {
316+
.auto, .push => {
317+
return try self.navigate(_url, .{ .push = json }, page);
318+
},
319+
.replace => {
320+
const entry = self.currentEntry();
321+
entry.state = json;
322+
return try self.navigate(_url, .replace, page);
323+
},
324+
}
316325
}
317326

318327
pub const ReloadOptions = struct {
@@ -357,7 +366,44 @@ pub fn _updateCurrentEntry(self: *Navigation, options: UpdateCurrentEntryOptions
357366
self.currentEntry().state = options.state.toJson(arena) catch return error.DataClone;
358367
}
359368

360-
const testing = @import("../../testing.zig");
369+
const Event = @import("../events/event.zig").Event;
370+
371+
pub const NavigationCurrentEntryChangeEvent = struct {
372+
pub const prototype = *Event;
373+
pub const union_make_copy = true;
374+
375+
pub const EventInit = struct {
376+
from: NavigationHistoryEntry,
377+
navigation_type: ?NavigationType = null,
378+
};
379+
380+
proto: parser.Event,
381+
form: NavigationHistoryEntry,
382+
navigation_type: ?NavigationType,
383+
384+
pub fn constructor(event_type: []const u8, opts: ?EventInit) !NavigationCurrentEntryChangeEvent {
385+
const event = try parser.eventCreate();
386+
defer parser.eventDestroy(event);
387+
try parser.eventInit(event, event_type, .{});
388+
parser.eventSetInternalType(event, .navigation_current_entry_change);
389+
390+
const o = opts orelse EventInit{};
391+
392+
return .{
393+
.proto = event.*,
394+
.state = o.state,
395+
};
396+
}
397+
398+
pub fn get_from(self: *const NavigationCurrentEntryChangeEvent) NavigationHistoryEntry {
399+
return self.from;
400+
}
401+
402+
pub fn get_navigationType(self: *const NavigationCurrentEntryChangeEvent) NavigationType {
403+
return self.navigation_type.?;
404+
}
405+
};
406+
361407
test "Browser: Navigation" {
362408
try testing.htmlRunner("html/navigation.html");
363409
}

src/browser/netsurf.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,7 @@ pub const EventType = enum(u8) {
559559
message_event = 7,
560560
keyboard_event = 8,
561561
pop_state = 9,
562+
navigation_current_entry_change = 10,
562563
};
563564

564565
pub const MutationEvent = c.dom_mutation_event;

src/browser/session.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub const Session = struct {
6060
// https://developer.mozilla.org/en-US/docs/Web/API/History
6161
history: History = .{},
6262
navigation: Navigation = .{},
63-
navigation_kind: NavigationKind = .initial,
63+
navigation_kind: ?NavigationKind = null,
6464

6565
page: ?Page = null,
6666

0 commit comments

Comments
 (0)