Skip to content

Commit ba66b7c

Browse files
committed
refactor HTMLAnchorElement regarding to URL changes
This still doesn't use `state` since `state` doesn't allow us to iterate the nodes when releasing the memory and we need to call `URL.destructor` when freeing. In the future, we might omit getter allocations by making such change.
1 parent 8342f0c commit ba66b7c

File tree

1 file changed

+93
-92
lines changed

1 file changed

+93
-92
lines changed

src/browser/html/elements.zig

Lines changed: 93 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -269,182 +269,183 @@ pub const HTMLAnchorElement = struct {
269269
if (try parser.elementGetAttribute(@ptrCast(@alignCast(self)), "href")) |href| {
270270
return URL.constructor(.{ .string = href }, null, page); // TODO inject base url
271271
}
272-
return .empty;
272+
return error.NotProvided;
273273
}
274274

275275
// TODO return a disposable string
276276
pub fn get_origin(self: *parser.Anchor, page: *Page) ![]const u8 {
277277
var u = try url(self, page);
278-
return try u.get_origin(page);
278+
defer u.destructor();
279+
return u.get_origin(page);
279280
}
280281

281282
// TODO return a disposable string
282283
pub fn get_protocol(self: *parser.Anchor, page: *Page) ![]const u8 {
283284
var u = try url(self, page);
284-
return u.get_protocol();
285+
defer u.destructor();
286+
287+
return page.arena.dupe(u8, u.get_protocol());
285288
}
286289

287-
pub fn set_protocol(self: *parser.Anchor, v: []const u8, page: *Page) !void {
288-
const arena = page.arena;
290+
pub fn set_protocol(self: *parser.Anchor, protocol: []const u8, page: *Page) !void {
289291
var u = try url(self, page);
292+
defer u.destructor();
293+
try u.set_protocol(protocol);
290294

291-
u.uri.scheme = v;
292-
const href = try u.toString(arena);
293-
try parser.anchorSetHref(self, href);
295+
const href = try u._toString(page);
296+
return parser.anchorSetHref(self, href);
294297
}
295298

296299
// TODO return a disposable string
297300
pub fn get_host(self: *parser.Anchor, page: *Page) ![]const u8 {
298-
var u = try url(self, page);
299-
return try u.get_host(page);
300-
}
301-
302-
pub fn set_host(self: *parser.Anchor, v: []const u8, page: *Page) !void {
303-
// search : separator
304-
var p: ?u16 = null;
305-
var h: []const u8 = undefined;
306-
for (v, 0..) |c, i| {
307-
if (c == ':') {
308-
h = v[0..i];
309-
p = try std.fmt.parseInt(u16, v[i + 1 ..], 10);
310-
break;
311-
}
312-
}
301+
var u = url(self, page) catch return "";
302+
defer u.destructor();
313303

314-
const arena = page.arena;
315-
var u = try url(self, page);
304+
return page.arena.dupe(u8, u.get_host());
305+
}
316306

317-
if (p) |pp| {
318-
u.uri.host = .{ .raw = h };
319-
u.uri.port = pp;
320-
} else {
321-
u.uri.host = .{ .raw = v };
322-
u.uri.port = null;
323-
}
307+
pub fn set_host(self: *parser.Anchor, host: []const u8, page: *Page) !void {
308+
var u = try url(self, page);
309+
defer u.destructor();
310+
try u.set_host(host);
324311

325-
const href = try u.toString(arena);
326-
try parser.anchorSetHref(self, href);
312+
const href = try u._toString(page);
313+
return parser.anchorSetHref(self, href);
327314
}
328315

329316
pub fn get_hostname(self: *parser.Anchor, page: *Page) ![]const u8 {
330-
var u = try url(self, page);
331-
return u.get_hostname();
317+
var u = url(self, page) catch return "";
318+
defer u.destructor();
319+
return page.arena.dupe(u8, u.get_hostname());
332320
}
333321

334-
pub fn set_hostname(self: *parser.Anchor, v: []const u8, page: *Page) !void {
335-
const arena = page.arena;
322+
pub fn set_hostname(self: *parser.Anchor, hostname: []const u8, page: *Page) !void {
336323
var u = try url(self, page);
337-
u.uri.host = .{ .raw = v };
338-
const href = try u.toString(arena);
339-
try parser.anchorSetHref(self, href);
324+
defer u.destructor();
325+
try u.set_hostname(hostname);
326+
327+
const href = try u._toString(page);
328+
return parser.anchorSetHref(self, href);
340329
}
341330

342331
// TODO return a disposable string
343332
pub fn get_port(self: *parser.Anchor, page: *Page) ![]const u8 {
344-
var u = try url(self, page);
345-
return try u.get_port(page);
333+
var u = url(self, page) catch return "";
334+
defer u.destructor();
335+
return page.arena.dupe(u8, u.get_port());
346336
}
347337

348-
pub fn set_port(self: *parser.Anchor, v: ?[]const u8, page: *Page) !void {
349-
const arena = page.arena;
338+
pub fn set_port(self: *parser.Anchor, maybe_port: ?[]const u8, page: *Page) !void {
350339
var u = try url(self, page);
340+
defer u.destructor();
351341

352-
if (v != null and v.?.len > 0) {
353-
u.uri.port = try std.fmt.parseInt(u16, v.?, 10);
342+
if (maybe_port) |port| {
343+
try u.set_port(port);
354344
} else {
355-
u.uri.port = null;
345+
u.clearPort();
356346
}
357347

358-
const href = try u.toString(arena);
359-
try parser.anchorSetHref(self, href);
348+
const href = try u._toString(page);
349+
return parser.anchorSetHref(self, href);
360350
}
361351

362352
// TODO return a disposable string
363353
pub fn get_username(self: *parser.Anchor, page: *Page) ![]const u8 {
364-
var u = try url(self, page);
365-
return u.get_username();
354+
var u = url(self, page) catch return "";
355+
defer u.destructor();
356+
357+
const username = u.get_username();
358+
if (username.len == 0) {
359+
return "";
360+
}
361+
362+
return page.arena.dupe(u8, username);
366363
}
367364

368-
pub fn set_username(self: *parser.Anchor, v: ?[]const u8, page: *Page) !void {
369-
const arena = page.arena;
365+
pub fn set_username(self: *parser.Anchor, maybe_username: ?[]const u8, page: *Page) !void {
370366
var u = try url(self, page);
367+
defer u.destructor();
371368

372-
if (v) |vv| {
373-
u.uri.user = .{ .raw = vv };
374-
} else {
375-
u.uri.user = null;
376-
}
377-
const href = try u.toString(arena);
369+
const username = if (maybe_username) |username| username else "";
370+
try u.set_username(username);
378371

379-
try parser.anchorSetHref(self, href);
372+
const href = try u._toString(page);
373+
return parser.anchorSetHref(self, href);
380374
}
381375

382376
// TODO return a disposable string
383377
pub fn get_password(self: *parser.Anchor, page: *Page) ![]const u8 {
384-
var u = try url(self, page);
385-
return try page.arena.dupe(u8, u.get_password());
378+
var u = url(self, page) catch return "";
379+
defer u.destructor();
380+
381+
return page.arena.dupe(u8, u.get_password());
386382
}
387383

388-
pub fn set_password(self: *parser.Anchor, v: ?[]const u8, page: *Page) !void {
389-
const arena = page.arena;
384+
pub fn set_password(self: *parser.Anchor, maybe_password: ?[]const u8, page: *Page) !void {
390385
var u = try url(self, page);
386+
defer u.destructor();
391387

392-
if (v) |vv| {
393-
u.uri.password = .{ .raw = vv };
394-
} else {
395-
u.uri.password = null;
396-
}
397-
const href = try u.toString(arena);
388+
const password = if (maybe_password) |password| password else "";
389+
try u.set_password(password);
398390

399-
try parser.anchorSetHref(self, href);
391+
const href = try u._toString(page);
392+
return parser.anchorSetHref(self, href);
400393
}
401394

402395
// TODO return a disposable string
403396
pub fn get_pathname(self: *parser.Anchor, page: *Page) ![]const u8 {
404-
var u = try url(self, page);
405-
return u.get_pathname();
397+
var u = url(self, page) catch return "";
398+
defer u.destructor();
399+
400+
return page.arena.dupe(u8, u.get_pathname());
406401
}
407402

408-
pub fn set_pathname(self: *parser.Anchor, v: []const u8, page: *Page) !void {
409-
const arena = page.arena;
403+
pub fn set_pathname(self: *parser.Anchor, pathname: []const u8, page: *Page) !void {
410404
var u = try url(self, page);
411-
u.uri.path = .{ .raw = v };
412-
const href = try u.toString(arena);
405+
defer u.destructor();
406+
407+
try u.set_pathname(pathname);
413408

414-
try parser.anchorSetHref(self, href);
409+
const href = try u._toString(page);
410+
return parser.anchorSetHref(self, href);
415411
}
416412

417413
pub fn get_search(self: *parser.Anchor, page: *Page) ![]const u8 {
418-
var u = try url(self, page);
419-
return try u.get_search(page);
414+
var u = url(self, page) catch return "";
415+
defer u.destructor();
416+
// This allocates in page arena so no need to dupe.
417+
return u.get_search(page);
420418
}
421419

422420
pub fn set_search(self: *parser.Anchor, v: ?[]const u8, page: *Page) !void {
423421
var u = try url(self, page);
422+
defer u.destructor();
424423
try u.set_search(v, page);
425424

426-
const href = try u.toString(page.call_arena);
427-
try parser.anchorSetHref(self, href);
425+
const href = try u._toString(page);
426+
return parser.anchorSetHref(self, href);
428427
}
429428

430429
// TODO return a disposable string
431430
pub fn get_hash(self: *parser.Anchor, page: *Page) ![]const u8 {
432-
var u = try url(self, page);
433-
return try u.get_hash(page);
431+
var u = url(self, page) catch return "";
432+
defer u.destructor();
433+
434+
return page.arena.dupe(u8, u.get_hash());
434435
}
435436

436-
pub fn set_hash(self: *parser.Anchor, v: ?[]const u8, page: *Page) !void {
437-
const arena = page.arena;
437+
pub fn set_hash(self: *parser.Anchor, maybe_hash: ?[]const u8, page: *Page) !void {
438438
var u = try url(self, page);
439+
defer u.destructor();
439440

440-
if (v) |vv| {
441-
u.uri.fragment = .{ .raw = vv };
441+
if (maybe_hash) |hash| {
442+
try u.set_hash(hash);
442443
} else {
443-
u.uri.fragment = null;
444+
u.clearHash();
444445
}
445-
const href = try u.toString(arena);
446446

447-
try parser.anchorSetHref(self, href);
447+
const href = try u._toString(page);
448+
return parser.anchorSetHref(self, href);
448449
}
449450
};
450451

0 commit comments

Comments
 (0)