Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 43 additions & 79 deletions src/browser/dom/html_collection.zig
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.

const std = @import("std");
const Allocator = std.mem.Allocator;

const parser = @import("../netsurf.zig");

Expand All @@ -42,25 +43,11 @@ const Matcher = union(enum) {

pub fn match(self: Matcher, node: *parser.Node) !bool {
switch (self) {
inline .matchTrue => return true,
inline .matchFalse => return false,
inline .matchByTagName => |case| return case.match(node),
inline .matchByClassName => |case| return case.match(node),
inline .matchByName => |case| return case.match(node),
inline .matchByLinks => return MatchByLinks.match(node),
inline .matchByAnchors => return MatchByAnchors.match(node),
}
}

pub fn deinit(self: Matcher, alloc: std.mem.Allocator) void {
switch (self) {
inline .matchTrue => return,
inline .matchFalse => return,
inline .matchByTagName => |case| return case.deinit(alloc),
inline .matchByClassName => |case| return case.deinit(alloc),
inline .matchByName => |case| return case.deinit(alloc),
inline .matchByLinks => return,
inline .matchByAnchors => return,
.matchTrue => return true,
.matchFalse => return false,
.matchByLinks => return MatchByLinks.match(node),
.matchByAnchors => return MatchByAnchors.match(node),
inline else => |m| return m.match(node),
}
}
};
Expand All @@ -71,54 +58,49 @@ pub const MatchByTagName = struct {
tag: []const u8,
is_wildcard: bool,

fn init(alloc: std.mem.Allocator, tag_name: []const u8) !MatchByTagName {
const tag_name_alloc = try alloc.alloc(u8, tag_name.len);
@memcpy(tag_name_alloc, tag_name);
return MatchByTagName{
.tag = tag_name_alloc,
.is_wildcard = std.mem.eql(u8, tag_name, "*"),
fn init(arena: Allocator, tag_name: []const u8) !MatchByTagName {
if (std.mem.eql(u8, tag_name, "*")) {
return .{ .tag = "*", .is_wildcard = true };
}

return .{
.tag = try arena.dupe(u8, tag_name),
.is_wildcard = false,
};
}

pub fn match(self: MatchByTagName, node: *parser.Node) !bool {
return self.is_wildcard or std.ascii.eqlIgnoreCase(self.tag, try parser.nodeName(node));
}

fn deinit(self: MatchByTagName, alloc: std.mem.Allocator) void {
alloc.free(self.tag);
}
};

pub fn HTMLCollectionByTagName(
alloc: std.mem.Allocator,
arena: Allocator,
root: ?*parser.Node,
tag_name: []const u8,
include_root: bool,
) !HTMLCollection {
return HTMLCollection{
.root = root,
.walker = Walker{ .walkerDepthFirst = .{} },
.matcher = Matcher{
.matchByTagName = try MatchByTagName.init(alloc, tag_name),
},
.walker = .{ .walkerDepthFirst = .{} },
.matcher = .{ .matchByTagName = try MatchByTagName.init(arena, tag_name) },
.include_root = include_root,
};
}

pub const MatchByClassName = struct {
classNames: []const u8,
class_names: []const u8,

fn init(alloc: std.mem.Allocator, classNames: []const u8) !MatchByClassName {
const class_names_alloc = try alloc.alloc(u8, classNames.len);
@memcpy(class_names_alloc, classNames);
return MatchByClassName{
.classNames = class_names_alloc,
fn init(arena: Allocator, class_names: []const u8) !MatchByClassName {
return .{
.class_names = try arena.dupe(u8, class_names),
};
}

pub fn match(self: MatchByClassName, node: *parser.Node) !bool {
var it = std.mem.splitAny(u8, self.classNames, " ");
const e = parser.nodeToElement(node);

var it = std.mem.splitScalar(u8, self.class_names, ' ');
while (it.next()) |c| {
if (!try parser.elementHasClass(e, c)) {
return false;
Expand All @@ -127,36 +109,28 @@ pub const MatchByClassName = struct {

return true;
}

fn deinit(self: MatchByClassName, alloc: std.mem.Allocator) void {
alloc.free(self.classNames);
}
};

pub fn HTMLCollectionByClassName(
alloc: std.mem.Allocator,
arena: Allocator,
root: ?*parser.Node,
classNames: []const u8,
include_root: bool,
) !HTMLCollection {
return HTMLCollection{
.root = root,
.walker = Walker{ .walkerDepthFirst = .{} },
.matcher = Matcher{
.matchByClassName = try MatchByClassName.init(alloc, classNames),
},
.walker = .{ .walkerDepthFirst = .{} },
.matcher = .{ .matchByClassName = try MatchByClassName.init(arena, classNames) },
.include_root = include_root,
};
}

pub const MatchByName = struct {
name: []const u8,

fn init(alloc: std.mem.Allocator, name: []const u8) !MatchByName {
const names_alloc = try alloc.alloc(u8, name.len);
@memcpy(names_alloc, name);
return MatchByName{
.name = names_alloc,
fn init(arena: Allocator, name: []const u8) !MatchByName {
return .{
.name = try arena.dupe(u8, name),
};
}

Expand All @@ -165,24 +139,18 @@ pub const MatchByName = struct {
const nname = try parser.elementGetAttribute(e, "name") orelse return false;
return std.mem.eql(u8, self.name, nname);
}

fn deinit(self: MatchByName, alloc: std.mem.Allocator) void {
alloc.free(self.name);
}
};

pub fn HTMLCollectionByName(
alloc: std.mem.Allocator,
arena: Allocator,
root: ?*parser.Node,
name: []const u8,
include_root: bool,
) !HTMLCollection {
return HTMLCollection{
.root = root,
.walker = Walker{ .walkerDepthFirst = .{} },
.matcher = Matcher{
.matchByName = try MatchByName.init(alloc, name),
},
.walker = .{ .walkerDepthFirst = .{} },
.matcher = .{ .matchByName = try MatchByName.init(arena, name) },
.include_root = include_root,
};
}
Expand All @@ -193,8 +161,8 @@ pub fn HTMLCollectionAll(
) !HTMLCollection {
return HTMLCollection{
.root = root,
.walker = Walker{ .walkerDepthFirst = .{} },
.matcher = Matcher{ .matchTrue = .{} },
.walker = .{ .walkerDepthFirst = .{} },
.matcher = .{ .matchTrue = .{} },
.include_root = include_root,
};
}
Expand All @@ -205,17 +173,17 @@ pub fn HTMLCollectionChildren(
) !HTMLCollection {
return HTMLCollection{
.root = root,
.walker = Walker{ .walkerChildren = .{} },
.matcher = Matcher{ .matchTrue = .{} },
.walker = .{ .walkerChildren = .{} },
.matcher = .{ .matchTrue = .{} },
.include_root = include_root,
};
}

pub fn HTMLCollectionEmpty() !HTMLCollection {
return HTMLCollection{
.root = null,
.walker = Walker{ .walkerNone = .{} },
.matcher = Matcher{ .matchFalse = .{} },
.walker = .{ .walkerNone = .{} },
.matcher = .{ .matchFalse = .{} },
.include_root = false,
};
}
Expand All @@ -240,10 +208,8 @@ pub fn HTMLCollectionByLinks(
) !HTMLCollection {
return HTMLCollection{
.root = root,
.walker = Walker{ .walkerDepthFirst = .{} },
.matcher = Matcher{
.matchByLinks = MatchByLinks{},
},
.walker = .{ .walkerDepthFirst = .{} },
.matcher = .{ .matchByLinks = MatchByLinks{} },
.include_root = include_root,
};
}
Expand All @@ -267,10 +233,8 @@ pub fn HTMLCollectionByAnchors(
) !HTMLCollection {
return HTMLCollection{
.root = root,
.walker = Walker{ .walkerDepthFirst = .{} },
.matcher = Matcher{
.matchByAnchors = MatchByAnchors{},
},
.walker = .{ .walkerDepthFirst = .{} },
.matcher = .{ .matchByAnchors = MatchByAnchors{} },
.include_root = include_root,
};
}
Expand Down Expand Up @@ -321,7 +285,7 @@ pub const HTMLCollection = struct {
cur_node: ?*parser.Node = undefined,

// start returns the first node to walk on.
fn start(self: HTMLCollection) !?*parser.Node {
fn start(self: *const HTMLCollection) !?*parser.Node {
if (self.root == null) return null;

if (self.include_root) {
Expand Down
26 changes: 5 additions & 21 deletions src/browser/dom/mutation_observer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,6 @@ pub const MutationObserver = struct {
options: MutationObserverInit,
};

const deinitFunc = struct {
fn deinit(ctx: ?*anyopaque, allocator: std.mem.Allocator) void {
const o: *Observer = @ptrCast(@alignCast(ctx));
allocator.destroy(o);
}
}.deinit;

const Observers = std.ArrayListUnmanaged(*Observer);

pub const MutationObserverInit = struct {
Expand Down Expand Up @@ -104,15 +97,15 @@ pub const MutationObserver = struct {
arena,
"DOMNodeInserted",
EventHandler,
.{ .cbk = self.cbk, .ctx = o, .deinitFunc = deinitFunc },
.{ .cbk = self.cbk, .ctx = o },
false,
);
try parser.eventTargetAddEventListener(
parser.toEventTarget(parser.Node, node),
arena,
"DOMNodeRemoved",
EventHandler,
.{ .cbk = self.cbk, .ctx = o, .deinitFunc = deinitFunc },
.{ .cbk = self.cbk, .ctx = o },
false,
);
}
Expand All @@ -122,7 +115,7 @@ pub const MutationObserver = struct {
arena,
"DOMAttrModified",
EventHandler,
.{ .cbk = self.cbk, .ctx = o, .deinitFunc = deinitFunc },
.{ .cbk = self.cbk, .ctx = o },
false,
);
}
Expand All @@ -132,7 +125,7 @@ pub const MutationObserver = struct {
arena,
"DOMCharacterDataModified",
EventHandler,
.{ .cbk = self.cbk, .ctx = o, .deinitFunc = deinitFunc },
.{ .cbk = self.cbk, .ctx = o },
false,
);
}
Expand All @@ -142,7 +135,7 @@ pub const MutationObserver = struct {
arena,
"DOMSubtreeModified",
EventHandler,
.{ .cbk = self.cbk, .ctx = o, .deinitFunc = deinitFunc },
.{ .cbk = self.cbk, .ctx = o },
false,
);
}
Expand All @@ -153,15 +146,6 @@ pub const MutationObserver = struct {
// TODO unregister listeners.
}

pub fn deinit(self: *MutationObserver, state: *SessionState) void {
const arena = state.arena;
// TODO unregister listeners.
for (self.observers.items) |o| {
arena.destroy(o);
}
self.observers.deinit(arena);
}

// TODO
pub fn _takeRecords(_: *const MutationObserver) ?[]const u8 {
return &[_]u8{};
Expand Down
1 change: 0 additions & 1 deletion src/browser/url/url.zig
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ pub const URL = struct {
) !URL {
const arena = state.arena;
const raw = try std.mem.concat(arena, u8, &[_][]const u8{ url, base orelse "" });
errdefer arena.free(raw);

const uri = std.Uri.parse(raw) catch return error.TypeError;
return init(arena, uri);
Expand Down
Loading
Loading