Add HTMLElement.dir and HTMLElement.lang properties

Added as attribute-backed accessors on HTMLElement (inherited by all
HTML elements) and on HTMLDocument (delegates to documentElement).
This commit is contained in:
Pierre Tachoire
2026-03-31 16:11:34 +02:00
parent 20cadd2282
commit 68e2140bb3
3 changed files with 85 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
<html lang="en" dir="ltr">
<head>
<script src="../testing.js"></script>
</head>
<body>
<script id="test-document-dir-lang">
// HTMLElement.dir and HTMLElement.lang
testing.expectEqual('ltr', document.documentElement.dir);
testing.expectEqual('en', document.documentElement.lang);
// Document.dir and Document.lang delegate to documentElement
testing.expectEqual('ltr', document.dir);
testing.expectEqual('en', document.lang);
// Setting via document updates the documentElement attribute
document.dir = 'rtl';
testing.expectEqual('rtl', document.documentElement.dir);
testing.expectEqual('rtl', document.documentElement.getAttribute('dir'));
document.lang = 'fr';
testing.expectEqual('fr', document.documentElement.lang);
testing.expectEqual('fr', document.documentElement.getAttribute('lang'));
// Setting via element is reflected in document
document.documentElement.dir = 'ltr';
testing.expectEqual('ltr', document.dir);
document.documentElement.lang = 'de';
testing.expectEqual('de', document.lang);
// div elements also have dir and lang
const div = document.createElement('div');
testing.expectEqual('', div.dir);
testing.expectEqual('', div.lang);
div.dir = 'rtl';
div.lang = 'ar';
testing.expectEqual('rtl', div.dir);
testing.expectEqual('ar', div.lang);
</script>
</body>
</html>

View File

@@ -182,6 +182,30 @@ pub fn setLocation(self: *HTMLDocument, url: [:0]const u8, page: *Page) !void {
return page.scheduleNavigation(url, .{ .reason = .script, .kind = .{ .push = null } }, .{ .script = self._proto._page });
}
pub fn getDir(self: *HTMLDocument) []const u8 {
const el = self._proto.getDocumentElement() orelse return "";
const html = el.is(Element.Html) orelse return "";
return html.getDir();
}
pub fn setDir(self: *HTMLDocument, value: []const u8, page: *Page) !void {
const el = self._proto.getDocumentElement() orelse return;
const html = el.is(Element.Html) orelse return;
try html.setDir(value, page);
}
pub fn getLang(self: *HTMLDocument) []const u8 {
const el = self._proto.getDocumentElement() orelse return "";
const html = el.is(Element.Html) orelse return "";
return html.getLang();
}
pub fn setLang(self: *HTMLDocument, value: []const u8, page: *Page) !void {
const el = self._proto.getDocumentElement() orelse return;
const html = el.is(Element.Html) orelse return;
try html.setLang(value, page);
}
pub fn getAll(self: *HTMLDocument, page: *Page) !*collections.HTMLAllCollection {
return page._factory.create(collections.HTMLAllCollection.init(self.asNode(), page));
}
@@ -250,8 +274,10 @@ pub const JsApi = struct {
});
}
pub const dir = bridge.accessor(HTMLDocument.getDir, HTMLDocument.setDir, .{});
pub const head = bridge.accessor(HTMLDocument.getHead, null, .{});
pub const body = bridge.accessor(HTMLDocument.getBody, null, .{});
pub const lang = bridge.accessor(HTMLDocument.getLang, HTMLDocument.setLang, .{});
pub const title = bridge.accessor(HTMLDocument.getTitle, HTMLDocument.setTitle, .{});
pub const images = bridge.accessor(HTMLDocument.getImages, null, .{});
pub const scripts = bridge.accessor(HTMLDocument.getScripts, null, .{});

View File

@@ -375,6 +375,22 @@ pub fn setTabIndex(self: *HtmlElement, value: i32, page: *Page) !void {
try self.asElement().setAttributeSafe(comptime .wrap("tabindex"), .wrap(str), page);
}
pub fn getDir(self: *HtmlElement) []const u8 {
return self.asElement().getAttributeSafe(comptime .wrap("dir")) orelse "";
}
pub fn setDir(self: *HtmlElement, value: []const u8, page: *Page) !void {
try self.asElement().setAttributeSafe(comptime .wrap("dir"), .wrap(value), page);
}
pub fn getLang(self: *HtmlElement) []const u8 {
return self.asElement().getAttributeSafe(comptime .wrap("lang")) orelse "";
}
pub fn setLang(self: *HtmlElement, value: []const u8, page: *Page) !void {
try self.asElement().setAttributeSafe(comptime .wrap("lang"), .wrap(value), page);
}
pub fn getAttributeFunction(
self: *HtmlElement,
listener_type: GlobalEventHandler,
@@ -1211,7 +1227,9 @@ pub const JsApi = struct {
pub const insertAdjacentHTML = bridge.function(HtmlElement.insertAdjacentHTML, .{ .dom_exception = true });
pub const click = bridge.function(HtmlElement.click, .{});
pub const dir = bridge.accessor(HtmlElement.getDir, HtmlElement.setDir, .{});
pub const hidden = bridge.accessor(HtmlElement.getHidden, HtmlElement.setHidden, .{});
pub const lang = bridge.accessor(HtmlElement.getLang, HtmlElement.setLang, .{});
pub const tabIndex = bridge.accessor(HtmlElement.getTabIndex, HtmlElement.setTabIndex, .{});
pub const onabort = bridge.accessor(HtmlElement.getOnAbort, HtmlElement.setOnAbort, .{});