Merge pull request #1501 from lightpanda-io/html_picture_element
Some checks failed
e2e-test / zig build release (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
e2e-test / browser fetch (push) Has been cancelled
zig-test / zig test using v8 in debug mode (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
nightly build / build-linux-x86_64 (push) Has been cancelled
nightly build / build-linux-aarch64 (push) Has been cancelled
nightly build / build-macos-aarch64 (push) Has been cancelled
nightly build / build-macos-x86_64 (push) Has been cancelled
wpt / web platform tests json output (push) Has been cancelled
wpt / perf-fmt (push) Has been cancelled
e2e-integration-test / zig build release (push) Has been cancelled
e2e-integration-test / demo-integration-scripts (push) Has been cancelled

Add HTMLPictureElement
This commit is contained in:
Karl Seguin
2026-02-09 23:00:59 +08:00
committed by GitHub
8 changed files with 118 additions and 12 deletions

View File

@@ -2106,6 +2106,12 @@ pub fn createElementNS(self: *Page, namespace: Element.Namespace, name: []const
attribute_iterator,
.{ ._proto = undefined, ._tag_name = String.init(undefined, "address", .{}) catch unreachable, ._tag = .address },
),
asUint("picture") => return self.createHtmlElementT(
Element.Html.Picture,
namespace,
attribute_iterator,
.{ ._proto = undefined },
),
else => {},
},
8 => switch (@as(u64, @bitCast(name[0..8].*))) {

View File

@@ -840,6 +840,7 @@ pub const JsApis = flattenTypes(&.{
@import("../webapi/element/html/Option.zig"),
@import("../webapi/element/html/Output.zig"),
@import("../webapi/element/html/Paragraph.zig"),
@import("../webapi/element/html/Picture.zig"),
@import("../webapi/element/html/Param.zig"),
@import("../webapi/element/html/Pre.zig"),
@import("../webapi/element/html/Progress.zig"),

View File

@@ -0,0 +1,55 @@
<!DOCTYPE html>
<script src="../../testing.js"></script>
<!-- <script id="createElement">
{
const picture = document.createElement('picture');
testing.expectEqual('PICTURE', picture.tagName);
testing.expectEqual('[object HTMLPictureElement]', Object.prototype.toString.call(picture));
}
</script>
<script id="constructor_type">
{
const picture = document.createElement('picture');
testing.expectEqual(true, picture instanceof HTMLElement);
testing.expectEqual(true, picture instanceof Element);
testing.expectEqual(true, picture instanceof Node);
}
</script> -->
<picture id="inline-picture">
<source media="(min-width: 800px)" srcset="large.jpg">
<source media="(min-width: 400px)" srcset="medium.jpg">
<img src="small.jpg" alt="Test image">
</picture>
<script id="inline_picture">
{
const picture = document.getElementById('inline-picture');
testing.expectEqual('PICTURE', picture.tagName);
testing.expectEqual(3, picture.children.length);
const sources = picture.querySelectorAll('source');
testing.expectEqual(2, sources.length);
// const img = picture.querySelector('img');
// testing.expectEqual('IMG', img.tagName);
}
</script>
<!-- <script id="appendChild">
{
const picture = document.createElement('picture');
const source = document.createElement('source');
const img = document.createElement('img');
picture.appendChild(source);
picture.appendChild(img);
testing.expectEqual(2, picture.children.length);
testing.expectEqual('SOURCE', picture.children[0].tagName);
testing.expectEqual('IMG', picture.children[1].tagName);
}
</script>
-->

View File

@@ -235,6 +235,7 @@ pub fn getTagNameLower(self: *const Element) []const u8 {
.option => "option",
.output => "output",
.p => "p",
.picture => "picture",
.param => "param",
.pre => "pre",
.progress => "progress",
@@ -311,6 +312,7 @@ pub fn getTagNameSpec(self: *const Element, buf: []u8) []const u8 {
.option => "OPTION",
.output => "OUTPUT",
.p => "P",
.picture => "PICTURE",
.param => "PARAM",
.pre => "PRE",
.progress => "PROGRESS",
@@ -1224,26 +1226,27 @@ pub fn getTag(self: *const Element) Tag {
.data => .data,
.datalist => .datalist,
.dialog => .dialog,
.directory => .unknown,
.directory => .directory,
.iframe => .iframe,
.img => .img,
.br => .br,
.button => .button,
.canvas => .canvas,
.fieldset => .fieldset,
.font => .unknown,
.font => .font,
.heading => |h| h._tag,
.label => .unknown,
.legend => .unknown,
.label => .label,
.legend => .legend,
.li => .li,
.map => .unknown,
.map => .map,
.ul => .ul,
.ol => .ol,
.object => .unknown,
.object => .object,
.optgroup => .optgroup,
.output => .unknown,
.param => .unknown,
.pre => .unknown,
.output => .output,
.picture => .picture,
.param => .param,
.pre => .pre,
.generic => |g| g._tag,
.media => |m| switch (m._type) {
.audio => .audio,
@@ -1257,7 +1260,7 @@ pub fn getTag(self: *const Element) Tag {
.script => .script,
.select => .select,
.slot => .slot,
.source => .unknown,
.source => .source,
.span => .span,
.option => .option,
.table => .table,
@@ -1269,7 +1272,7 @@ pub fn getTag(self: *const Element) Tag {
.template => .template,
.textarea => .textarea,
.time => .time,
.track => .unknown,
.track => .track,
.input => .input,
.link => .link,
.meta => .meta,
@@ -1316,6 +1319,7 @@ pub const Tag = enum {
dfn,
dialog,
div,
directory,
dl,
dt,
embed,
@@ -1324,6 +1328,7 @@ pub const Tag = enum {
fieldset,
figure,
form,
font,
footer,
g,
h1,
@@ -1343,10 +1348,13 @@ pub const Tag = enum {
img,
input,
ins,
label,
legend,
li,
line,
link,
main,
map,
marquee,
media,
menu,
@@ -1362,8 +1370,10 @@ pub const Tag = enum {
p,
path,
param,
picture,
polygon,
polyline,
pre,
progress,
quote,
rect,

View File

@@ -218,7 +218,7 @@ fn getDefaultDisplay(element: *const Element) []const u8 {
.html => |html| {
return switch (html._type) {
.anchor, .br, .span, .label, .time, .font, .mod, .quote => "inline",
.body, .div, .p, .heading, .form, .button, .canvas, .dialog, .embed, .head, .html, .hr, .iframe, .img, .input, .li, .link, .meta, .ol, .option, .script, .select, .slot, .style, .template, .textarea, .title, .ul, .media, .area, .base, .datalist, .directory, .fieldset, .legend, .map, .meter, .object, .optgroup, .output, .param, .pre, .progress, .source, .table, .table_caption, .table_cell, .table_col, .table_row, .table_section, .track => "block",
.body, .div, .p, .heading, .form, .button, .canvas, .dialog, .embed, .head, .html, .hr, .iframe, .img, .input, .li, .link, .meta, .ol, .option, .script, .select, .slot, .style, .template, .textarea, .title, .ul, .media, .area, .base, .datalist, .directory, .fieldset, .legend, .map, .meter, .object, .optgroup, .output, .param, .picture, .pre, .progress, .source, .table, .table_caption, .table_cell, .table_col, .table_row, .table_section, .track => "block",
.generic, .custom, .unknown, .data => blk: {
const tag = element.getTagNameLower();
if (isInlineTag(tag)) break :blk "inline";

View File

@@ -69,6 +69,7 @@ pub const OptGroup = @import("html/OptGroup.zig");
pub const Option = @import("html/Option.zig");
pub const Output = @import("html/Output.zig");
pub const Paragraph = @import("html/Paragraph.zig");
pub const Picture = @import("html/Picture.zig");
pub const Param = @import("html/Param.zig");
pub const Pre = @import("html/Pre.zig");
pub const Progress = @import("html/Progress.zig");
@@ -145,6 +146,7 @@ pub const Type = union(enum) {
option: *Option,
output: *Output,
p: *Paragraph,
picture: *Picture,
param: *Param,
pre: *Pre,
progress: *Progress,

View File

@@ -0,0 +1,30 @@
const js = @import("../../../js/js.zig");
const Node = @import("../../Node.zig");
const Element = @import("../../Element.zig");
const HtmlElement = @import("../Html.zig");
const Picture = @This();
_proto: *HtmlElement,
pub fn asElement(self: *Picture) *Element {
return self._proto._proto;
}
pub fn asNode(self: *Picture) *Node {
return self.asElement().asNode();
}
pub const JsApi = struct {
pub const bridge = js.Bridge(Picture);
pub const Meta = struct {
pub const name = "HTMLPictureElement";
pub const prototype_chain = bridge.prototypeChain();
pub var class_id: bridge.ClassId = undefined;
};
};
const testing = @import("../../../../testing.zig");
test "WebApi: Picture" {
try testing.htmlRunner("element/html/picture.html", .{});
}

View File

@@ -38,6 +38,8 @@ pub fn main() !void {
.user_agent_suffix = "internal-tester",
},
} });
defer config.deinit(allocator);
var app = try lp.App.init(allocator, &config);
defer app.deinit();