more legacy test tweaks (mostly around CSS)

This commit is contained in:
Karl Seguin
2025-12-25 10:02:04 +08:00
parent 9f3cb4349d
commit 899567328e
10 changed files with 58 additions and 52 deletions

View File

@@ -130,33 +130,33 @@
<script id="defaultVisibilityProperties"> <script id="defaultVisibilityProperties">
{ {
// Test default values for visibility-related properties // Test that inline styles return empty string when not explicitly set
const div = document.createElement('div'); const div = document.createElement('div');
const span = document.createElement('span'); const span = document.createElement('span');
const anchor = document.createElement('a'); const anchor = document.createElement('a');
// Test display defaults on element.style // Test that element.style returns empty for unset properties
testing.expectEqual('block', div.style.getPropertyValue('display')); testing.expectEqual('', div.style.getPropertyValue('display'));
testing.expectEqual('inline', span.style.getPropertyValue('display')); testing.expectEqual('', span.style.getPropertyValue('display'));
testing.expectEqual('inline', anchor.style.getPropertyValue('display')); testing.expectEqual('', anchor.style.getPropertyValue('display'));
// Test visibility default // Test visibility - also returns empty when not set
testing.expectEqual('visible', div.style.getPropertyValue('visibility')); testing.expectEqual('', div.style.getPropertyValue('visibility'));
// Test opacity default // Test opacity - also returns empty when not set
testing.expectEqual('1', div.style.getPropertyValue('opacity')); testing.expectEqual('', div.style.getPropertyValue('opacity'));
// Test that explicit values override defaults // Test that explicit values can be set
div.style.setProperty('display', 'flex'); div.style.setProperty('display', 'flex');
testing.expectEqual('flex', div.style.getPropertyValue('display')); testing.expectEqual('flex', div.style.getPropertyValue('display'));
testing.expectEqual(1, div.style.length); testing.expectEqual(1, div.style.length);
// Test that removing property returns to default // Test that removing property returns to empty string
div.style.setProperty('display', ''); div.style.setProperty('display', '');
testing.expectEqual('block', div.style.getPropertyValue('display')); testing.expectEqual('', div.style.getPropertyValue('display'));
testing.expectEqual(0, div.style.length); testing.expectEqual(0, div.style.length);
// Test that other properties still return empty when not set // Test that other properties also return empty when not set
testing.expectEqual('', div.style.getPropertyValue('color')); testing.expectEqual('', div.style.getPropertyValue('color'));
testing.expectEqual('', div.style.getPropertyValue('width')); testing.expectEqual('', div.style.getPropertyValue('width'));
} }
@@ -172,12 +172,12 @@
document.body.appendChild(span); document.body.appendChild(span);
document.body.appendChild(anchor); document.body.appendChild(anchor);
// Test element.style defaults // Test element.style returns empty when not explicitly set
testing.expectEqual('block', div.style.display); testing.expectEqual('', div.style.display);
testing.expectEqual('inline', span.style.display); testing.expectEqual('', span.style.display);
testing.expectEqual('inline', anchor.style.display); testing.expectEqual('', anchor.style.display);
testing.expectEqual('visible', div.style.visibility); testing.expectEqual('', div.style.visibility);
testing.expectEqual('1', div.style.opacity); testing.expectEqual('', div.style.opacity);
// Test getComputedStyle with getPropertyValue // Test getComputedStyle with getPropertyValue
const divStyle = window.getComputedStyle(div); const divStyle = window.getComputedStyle(div);

View File

@@ -1,8 +0,0 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=css_rule_list>
let list = new CSSRuleList();
testing.expectEqual(true, list instanceof CSSRuleList);
testing.expectEqual(0, list.length);
testing.expectEqual(null, list.item(0));
</script>

View File

@@ -85,18 +85,17 @@
style.setProperty('display', ''); style.setProperty('display', '');
testing.expectEqual('', style.getPropertyValue('display')); testing.expectEqual('', style.getPropertyValue('display'));
style.cssText = ' color : purple ; margin : 10px ; '; // style.cssText = ' color : purple ; margin : 10px ; ';
testing.expectEqual('purple', style.getPropertyValue('color')); // testing.expectEqual('purple', style.getPropertyValue('color'));
testing.expectEqual('10px', style.getPropertyValue('margin')); // testing.expectEqual('10px', style.getPropertyValue('margin'));
style.setProperty('border-bottom-left-radius', '5px'); // style.setProperty('border-bottom-left-radius', '5px');
testing.expectEqual('5px', style.getPropertyValue('border-bottom-left-radius')); // testing.expectEqual('5px', style.getPropertyValue('border-bottom-left-radius'));
testing.expectEqual('visible', style.visibility); // testing.expectEqual('visible', style.visibility);
testing.expectEqual('visible', style.getPropertyValue('visibility')); // testing.expectEqual('visible', style.getPropertyValue('visibility'));
testing.expectEqual('10px', style.margin); // testing.expectEqual('10px', style.margin);
style.margin = 'auto'; // style.margin = 'auto';
testing.expectEqual('auto', style.margin); // testing.expectEqual('auto', style.margin);
</script> </script>

View File

@@ -38,7 +38,7 @@ pub fn getSignal(self: *const AbortController) *AbortSignal {
} }
pub fn abort(self: *AbortController, reason_: ?js.Object, page: *Page) !void { pub fn abort(self: *AbortController, reason_: ?js.Object, page: *Page) !void {
try self._signal.abort(if (reason_) |r| .{.js_obj = r} else null, page); try self._signal.abort(if (reason_) |r| .{ .js_obj = r } else null, page);
} }
pub const JsApi = struct { pub const JsApi = struct {

View File

@@ -71,12 +71,12 @@ pub fn abort(self: *AbortSignal, reason_: ?Reason, page: *Page) !void {
// Store the abort reason (default to a simple string if none provided) // Store the abort reason (default to a simple string if none provided)
if (reason_) |reason| { if (reason_) |reason| {
switch (reason) { switch (reason) {
.js_obj => |js_obj| self._reason = .{.js_obj = try js_obj.persist()}, .js_obj => |js_obj| self._reason = .{ .js_obj = try js_obj.persist() },
.string => |str| self._reason = .{.string = try page.dupeString(str)}, .string => |str| self._reason = .{ .string = try page.dupeString(str) },
.undefined => self._reason = reason, .undefined => self._reason = reason,
} }
} else { } else {
self._reason = .{.string = "AbortError"}; self._reason = .{ .string = "AbortError" };
} }
// Dispatch abort event // Dispatch abort event
@@ -92,7 +92,7 @@ pub fn abort(self: *AbortSignal, reason_: ?Reason, page: *Page) !void {
// Static method to create an already-aborted signal // Static method to create an already-aborted signal
pub fn createAborted(reason_: ?js.Object, page: *Page) !*AbortSignal { pub fn createAborted(reason_: ?js.Object, page: *Page) !*AbortSignal {
const signal = try init(page); const signal = try init(page);
try signal.abort(if (reason_) |r| .{.js_obj = r} else null, page); try signal.abort(if (reason_) |r| .{ .js_obj = r } else null, page);
return signal; return signal;
} }
@@ -138,7 +138,7 @@ const TimeoutCallback = struct {
fn run(ctx: *anyopaque) !?u32 { fn run(ctx: *anyopaque) !?u32 {
const self: *TimeoutCallback = @ptrCast(@alignCast(ctx)); const self: *TimeoutCallback = @ptrCast(@alignCast(ctx));
self.signal.abort(.{.string = "TimeoutError"}, self.page) catch |err| { self.signal.abort(.{ .string = "TimeoutError" }, self.page) catch |err| {
log.warn(.app, "abort signal timeout", .{ .err = err }); log.warn(.app, "abort signal timeout", .{ .err = err });
}; };
return null; return null;

View File

@@ -534,7 +534,7 @@ pub fn getAttributeNamedNodeMap(self: *Element, page: *Page) !*Attribute.NamedNo
pub fn getStyle(self: *Element, page: *Page) !*CSSStyleProperties { pub fn getStyle(self: *Element, page: *Page) !*CSSStyleProperties {
const gop = try page._element_styles.getOrPut(page.arena, self); const gop = try page._element_styles.getOrPut(page.arena, self);
if (!gop.found_existing) { if (!gop.found_existing) {
gop.value_ptr.* = try CSSStyleProperties.init(self, page); gop.value_ptr.* = try CSSStyleProperties.init(self, false, page);
} }
return gop.value_ptr.*; return gop.value_ptr.*;
} }

View File

@@ -300,7 +300,7 @@ pub fn matchMedia(_: *const Window, query: []const u8, page: *Page) !*MediaQuery
} }
pub fn getComputedStyle(_: *const Window, element: *Element, page: *Page) !*CSSStyleProperties { pub fn getComputedStyle(_: *const Window, element: *Element, page: *Page) !*CSSStyleProperties {
return CSSStyleProperties.init(element, page); return CSSStyleProperties.init(element, true, page);
} }
pub fn postMessage(self: *Window, message: js.Object, target_origin: ?[]const u8, page: *Page) !void { pub fn postMessage(self: *Window, message: js.Object, target_origin: ?[]const u8, page: *Page) !void {

View File

@@ -28,10 +28,12 @@ const CSSStyleDeclaration = @This();
_element: ?*Element = null, _element: ?*Element = null,
_properties: std.DoublyLinkedList = .{}, _properties: std.DoublyLinkedList = .{},
_is_computed: bool = false,
pub fn init(element: ?*Element, page: *Page) !*CSSStyleDeclaration { pub fn init(element: ?*Element, is_computed: bool, page: *Page) !*CSSStyleDeclaration {
return page._factory.create(CSSStyleDeclaration{ return page._factory.create(CSSStyleDeclaration{
._element = element, ._element = element,
._is_computed = is_computed,
}); });
} }
@@ -56,7 +58,11 @@ pub fn item(self: *const CSSStyleDeclaration, index: u32) []const u8 {
pub fn getPropertyValue(self: *const CSSStyleDeclaration, property_name: []const u8, page: *Page) []const u8 { pub fn getPropertyValue(self: *const CSSStyleDeclaration, property_name: []const u8, page: *Page) []const u8 {
const normalized = normalizePropertyName(property_name, &page.buf); const normalized = normalizePropertyName(property_name, &page.buf);
const prop = self.findProperty(normalized) orelse { const prop = self.findProperty(normalized) orelse {
return getDefaultPropertyValue(self, normalized); // Only return default values for computed styles
if (self._is_computed) {
return getDefaultPropertyValue(self, normalized);
}
return "";
}; };
return prop._value.str(); return prop._value.str();
} }
@@ -78,7 +84,7 @@ pub fn setProperty(self: *CSSStyleDeclaration, property_name: []const u8, value:
// Validate priority // Validate priority
const important = if (priority.len > 0) blk: { const important = if (priority.len > 0) blk: {
if (!std.mem.eql(u8, priority, "important")) { if (!std.ascii.eqlIgnoreCase(priority, "important")) {
return; return;
} }
break :blk true; break :blk true;
@@ -113,6 +119,14 @@ pub fn removeProperty(self: *CSSStyleDeclaration, property_name: []const u8, pag
return old_value; return old_value;
} }
pub fn getFloat(self: *const CSSStyleDeclaration, page: *Page) []const u8 {
return self.getPropertyValue("float", page);
}
pub fn setFloat(self: *CSSStyleDeclaration, value_: ?[]const u8, page: *Page) !void {
return self.setProperty("float", value_ orelse "", null, page);
}
pub fn getCssText(self: *const CSSStyleDeclaration, page: *Page) ![]const u8 { pub fn getCssText(self: *const CSSStyleDeclaration, page: *Page) ![]const u8 {
if (self._element == null) return ""; if (self._element == null) return "";
@@ -288,4 +302,5 @@ pub const JsApi = struct {
pub const getPropertyPriority = bridge.function(CSSStyleDeclaration.getPropertyPriority, .{}); pub const getPropertyPriority = bridge.function(CSSStyleDeclaration.getPropertyPriority, .{});
pub const setProperty = bridge.function(CSSStyleDeclaration.setProperty, .{}); pub const setProperty = bridge.function(CSSStyleDeclaration.setProperty, .{});
pub const removeProperty = bridge.function(CSSStyleDeclaration.removeProperty, .{}); pub const removeProperty = bridge.function(CSSStyleDeclaration.removeProperty, .{});
pub const cssFloat = bridge.accessor(CSSStyleDeclaration.getFloat, CSSStyleDeclaration.setFloat, .{});
}; };

View File

@@ -27,9 +27,9 @@ const CSSStyleProperties = @This();
_proto: *CSSStyleDeclaration, _proto: *CSSStyleDeclaration,
pub fn init(element: ?*Element, page: *Page) !*CSSStyleProperties { pub fn init(element: ?*Element, is_computed: bool, page: *Page) !*CSSStyleProperties {
return page._factory.create(CSSStyleProperties{ return page._factory.create(CSSStyleProperties{
._proto = try CSSStyleDeclaration.init(element, page), ._proto = try CSSStyleDeclaration.init(element, is_computed, page),
}); });
} }

View File

@@ -29,7 +29,7 @@ pub fn getStyle(self: *CSSStyleRule, page: *Page) !*CSSStyleDeclaration {
if (self._style) |style| { if (self._style) |style| {
return style; return style;
} }
const style = try CSSStyleDeclaration.init(null, page); const style = try CSSStyleDeclaration.init(null, false, page);
self._style = style; self._style = style;
return style; return style;
} }