mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-08-02 10:47:15 -04:00
Merge pull request #2721 from rohitsux/feat/html-source-reflection
feat(webapi): reflect attributes on HTMLSourceElement
This commit is contained in:
79
src/browser/tests/element/html/source.html
Normal file
79
src/browser/tests/element/html/source.html
Normal file
@@ -0,0 +1,79 @@
|
||||
<!DOCTYPE html>
|
||||
<script src="../../testing.js"></script>
|
||||
|
||||
<source id="s1" src="/video.webm" srcset="/img-1x.png 1x, /img-2x.png 2x" sizes="100vw" media="(min-width: 600px)" type="video/webm" width="640" height="480">
|
||||
<source id="s2">
|
||||
|
||||
<script id="source-from-html">
|
||||
{
|
||||
const s1 = document.getElementById('s1');
|
||||
testing.expectEqual('HTMLSourceElement', s1.constructor.name);
|
||||
testing.expectEqual(testing.ORIGIN + '/video.webm', s1.src);
|
||||
testing.expectEqual('/img-1x.png 1x, /img-2x.png 2x', s1.srcset);
|
||||
testing.expectEqual('100vw', s1.sizes);
|
||||
testing.expectEqual('(min-width: 600px)', s1.media);
|
||||
testing.expectEqual('video/webm', s1.type);
|
||||
testing.expectEqual(640, s1.width);
|
||||
testing.expectEqual(480, s1.height);
|
||||
|
||||
const s2 = document.getElementById('s2');
|
||||
testing.expectEqual('', s2.src);
|
||||
testing.expectEqual('', s2.srcset);
|
||||
testing.expectEqual('', s2.sizes);
|
||||
testing.expectEqual('', s2.media);
|
||||
testing.expectEqual('', s2.type);
|
||||
testing.expectEqual(0, s2.width);
|
||||
testing.expectEqual(0, s2.height);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="source-reflection">
|
||||
{
|
||||
const s = document.createElement('source');
|
||||
|
||||
s.srcset = '/a.png 1x';
|
||||
testing.expectEqual('/a.png 1x', s.getAttribute('srcset'));
|
||||
s.setAttribute('srcset', '/b.png 2x');
|
||||
testing.expectEqual('/b.png 2x', s.srcset);
|
||||
|
||||
s.sizes = '50vw';
|
||||
testing.expectEqual('50vw', s.getAttribute('sizes'));
|
||||
s.setAttribute('sizes', '25vw');
|
||||
testing.expectEqual('25vw', s.sizes);
|
||||
|
||||
s.media = 'screen';
|
||||
testing.expectEqual('screen', s.getAttribute('media'));
|
||||
s.setAttribute('media', 'print');
|
||||
testing.expectEqual('print', s.media);
|
||||
|
||||
s.type = 'video/mp4';
|
||||
testing.expectEqual('video/mp4', s.getAttribute('type'));
|
||||
s.setAttribute('type', 'image/svg+xml');
|
||||
testing.expectEqual('image/svg+xml', s.type);
|
||||
|
||||
s.width = 320;
|
||||
testing.expectEqual('320', s.getAttribute('width'));
|
||||
s.setAttribute('width', '160');
|
||||
testing.expectEqual(160, s.width);
|
||||
s.setAttribute('width', 'not-a-number');
|
||||
testing.expectEqual(0, s.width);
|
||||
|
||||
s.height = 240;
|
||||
testing.expectEqual('240', s.getAttribute('height'));
|
||||
s.setAttribute('height', '120');
|
||||
testing.expectEqual(120, s.height);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="source-src-url">
|
||||
{
|
||||
const s = document.createElement('source');
|
||||
testing.expectEqual('', s.src);
|
||||
|
||||
s.src = 'https://lightpanda.io/clip.webm';
|
||||
testing.expectEqual('https://lightpanda.io/clip.webm', s.src);
|
||||
|
||||
s.src = '/relative.webm';
|
||||
testing.expectEqual(testing.ORIGIN + '/relative.webm', s.src);
|
||||
}
|
||||
</script>
|
||||
@@ -1,4 +1,6 @@
|
||||
const std = @import("std");
|
||||
const js = @import("../../../js/js.zig");
|
||||
const Frame = @import("../../../Frame.zig");
|
||||
const Node = @import("../../Node.zig");
|
||||
const Element = @import("../../Element.zig");
|
||||
const HtmlElement = @import("../Html.zig");
|
||||
@@ -10,10 +12,78 @@ _proto: *HtmlElement,
|
||||
pub fn asElement(self: *Source) *Element {
|
||||
return self._proto._proto;
|
||||
}
|
||||
pub fn asConstElement(self: *const Source) *const Element {
|
||||
return self._proto._proto;
|
||||
}
|
||||
pub fn asNode(self: *Source) *Node {
|
||||
return self.asElement().asNode();
|
||||
}
|
||||
|
||||
pub fn getSrc(self: *const Source, frame: *Frame) ![]const u8 {
|
||||
const element = self.asConstElement();
|
||||
const src = element.getAttributeSafe(comptime .wrap("src")) orelse return "";
|
||||
if (src.len == 0) {
|
||||
return "";
|
||||
}
|
||||
return element.asConstNode().resolveURL(src, frame, .{});
|
||||
}
|
||||
|
||||
pub fn setSrc(self: *Source, value: []const u8, frame: *Frame) !void {
|
||||
try self.asElement().setAttributeSafe(comptime .wrap("src"), .wrap(value), frame);
|
||||
}
|
||||
|
||||
pub fn getSrcset(self: *const Source) []const u8 {
|
||||
return self.asConstElement().getAttributeSafe(comptime .wrap("srcset")) orelse "";
|
||||
}
|
||||
|
||||
pub fn setSrcset(self: *Source, value: []const u8, frame: *Frame) !void {
|
||||
try self.asElement().setAttributeSafe(comptime .wrap("srcset"), .wrap(value), frame);
|
||||
}
|
||||
|
||||
pub fn getSizes(self: *const Source) []const u8 {
|
||||
return self.asConstElement().getAttributeSafe(comptime .wrap("sizes")) orelse "";
|
||||
}
|
||||
|
||||
pub fn setSizes(self: *Source, value: []const u8, frame: *Frame) !void {
|
||||
try self.asElement().setAttributeSafe(comptime .wrap("sizes"), .wrap(value), frame);
|
||||
}
|
||||
|
||||
pub fn getMedia(self: *const Source) []const u8 {
|
||||
return self.asConstElement().getAttributeSafe(comptime .wrap("media")) orelse "";
|
||||
}
|
||||
|
||||
pub fn setMedia(self: *Source, value: []const u8, frame: *Frame) !void {
|
||||
try self.asElement().setAttributeSafe(comptime .wrap("media"), .wrap(value), frame);
|
||||
}
|
||||
|
||||
pub fn getType(self: *const Source) []const u8 {
|
||||
return self.asConstElement().getAttributeSafe(comptime .wrap("type")) orelse "";
|
||||
}
|
||||
|
||||
pub fn setType(self: *Source, value: []const u8, frame: *Frame) !void {
|
||||
try self.asElement().setAttributeSafe(comptime .wrap("type"), .wrap(value), frame);
|
||||
}
|
||||
|
||||
pub fn getWidth(self: *const Source) u32 {
|
||||
const attr = self.asConstElement().getAttributeSafe(comptime .wrap("width")) orelse return 0;
|
||||
return std.fmt.parseUnsigned(u32, attr, 10) catch 0;
|
||||
}
|
||||
|
||||
pub fn setWidth(self: *Source, value: u32, frame: *Frame) !void {
|
||||
const str = try std.fmt.allocPrint(frame.call_arena, "{d}", .{value});
|
||||
try self.asElement().setAttributeSafe(comptime .wrap("width"), .wrap(str), frame);
|
||||
}
|
||||
|
||||
pub fn getHeight(self: *const Source) u32 {
|
||||
const attr = self.asConstElement().getAttributeSafe(comptime .wrap("height")) orelse return 0;
|
||||
return std.fmt.parseUnsigned(u32, attr, 10) catch 0;
|
||||
}
|
||||
|
||||
pub fn setHeight(self: *Source, value: u32, frame: *Frame) !void {
|
||||
const str = try std.fmt.allocPrint(frame.call_arena, "{d}", .{value});
|
||||
try self.asElement().setAttributeSafe(comptime .wrap("height"), .wrap(str), frame);
|
||||
}
|
||||
|
||||
pub const JsApi = struct {
|
||||
pub const bridge = js.Bridge(Source);
|
||||
|
||||
@@ -22,4 +92,17 @@ pub const JsApi = struct {
|
||||
pub const prototype_chain = bridge.prototypeChain();
|
||||
pub var class_id: bridge.ClassId = undefined;
|
||||
};
|
||||
|
||||
pub const height = bridge.accessor(Source.getHeight, Source.setHeight, .{ .ce_reactions = true });
|
||||
pub const media = bridge.accessor(Source.getMedia, Source.setMedia, .{ .ce_reactions = true });
|
||||
pub const sizes = bridge.accessor(Source.getSizes, Source.setSizes, .{ .ce_reactions = true });
|
||||
pub const src = bridge.accessor(Source.getSrc, Source.setSrc, .{ .ce_reactions = true });
|
||||
pub const srcset = bridge.accessor(Source.getSrcset, Source.setSrcset, .{ .ce_reactions = true });
|
||||
pub const @"type" = bridge.accessor(Source.getType, Source.setType, .{ .ce_reactions = true });
|
||||
pub const width = bridge.accessor(Source.getWidth, Source.setWidth, .{ .ce_reactions = true });
|
||||
};
|
||||
|
||||
const testing = @import("../../../../testing.zig");
|
||||
test "WebApi: HTML.Source" {
|
||||
try testing.htmlRunner("element/html/source.html", .{});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user