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">
{
// Test default values for visibility-related properties
// Test that inline styles return empty string when not explicitly set
const div = document.createElement('div');
const span = document.createElement('span');
const anchor = document.createElement('a');
// Test display defaults on element.style
testing.expectEqual('block', div.style.getPropertyValue('display'));
testing.expectEqual('inline', span.style.getPropertyValue('display'));
testing.expectEqual('inline', anchor.style.getPropertyValue('display'));
// Test that element.style returns empty for unset properties
testing.expectEqual('', div.style.getPropertyValue('display'));
testing.expectEqual('', span.style.getPropertyValue('display'));
testing.expectEqual('', anchor.style.getPropertyValue('display'));
// Test visibility default
testing.expectEqual('visible', div.style.getPropertyValue('visibility'));
// Test visibility - also returns empty when not set
testing.expectEqual('', div.style.getPropertyValue('visibility'));
// Test opacity default
testing.expectEqual('1', div.style.getPropertyValue('opacity'));
// Test opacity - also returns empty when not set
testing.expectEqual('', div.style.getPropertyValue('opacity'));
// Test that explicit values override defaults
// Test that explicit values can be set
div.style.setProperty('display', 'flex');
testing.expectEqual('flex', div.style.getPropertyValue('display'));
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', '');
testing.expectEqual('block', div.style.getPropertyValue('display'));
testing.expectEqual('', div.style.getPropertyValue('display'));
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('width'));
}
@@ -172,12 +172,12 @@
document.body.appendChild(span);
document.body.appendChild(anchor);
// Test element.style defaults
testing.expectEqual('block', div.style.display);
testing.expectEqual('inline', span.style.display);
testing.expectEqual('inline', anchor.style.display);
testing.expectEqual('visible', div.style.visibility);
testing.expectEqual('1', div.style.opacity);
// Test element.style returns empty when not explicitly set
testing.expectEqual('', div.style.display);
testing.expectEqual('', span.style.display);
testing.expectEqual('', anchor.style.display);
testing.expectEqual('', div.style.visibility);
testing.expectEqual('', div.style.opacity);
// Test getComputedStyle with getPropertyValue
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', '');
testing.expectEqual('', style.getPropertyValue('display'));
style.cssText = ' color : purple ; margin : 10px ; ';
testing.expectEqual('purple', style.getPropertyValue('color'));
testing.expectEqual('10px', style.getPropertyValue('margin'));
// style.cssText = ' color : purple ; margin : 10px ; ';
// testing.expectEqual('purple', style.getPropertyValue('color'));
// testing.expectEqual('10px', style.getPropertyValue('margin'));
style.setProperty('border-bottom-left-radius', '5px');
testing.expectEqual('5px', style.getPropertyValue('border-bottom-left-radius'));
// style.setProperty('border-bottom-left-radius', '5px');
// testing.expectEqual('5px', style.getPropertyValue('border-bottom-left-radius'));
testing.expectEqual('visible', style.visibility);
testing.expectEqual('visible', style.getPropertyValue('visibility'));
// testing.expectEqual('visible', style.visibility);
// testing.expectEqual('visible', style.getPropertyValue('visibility'));
testing.expectEqual('10px', style.margin);
style.margin = 'auto';
testing.expectEqual('auto', style.margin);
// testing.expectEqual('10px', style.margin);
// style.margin = 'auto';
// testing.expectEqual('auto', style.margin);
</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 {
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 {

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)
if (reason_) |reason| {
switch (reason) {
.js_obj => |js_obj| self._reason = .{.js_obj = try js_obj.persist()},
.string => |str| self._reason = .{.string = try page.dupeString(str)},
.js_obj => |js_obj| self._reason = .{ .js_obj = try js_obj.persist() },
.string => |str| self._reason = .{ .string = try page.dupeString(str) },
.undefined => self._reason = reason,
}
} else {
self._reason = .{.string = "AbortError"};
self._reason = .{ .string = "AbortError" };
}
// 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
pub fn createAborted(reason_: ?js.Object, page: *Page) !*AbortSignal {
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;
}
@@ -138,7 +138,7 @@ const TimeoutCallback = struct {
fn run(ctx: *anyopaque) !?u32 {
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 });
};
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 {
const gop = try page._element_styles.getOrPut(page.arena, self);
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.*;
}

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 {
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 {

View File

@@ -28,10 +28,12 @@ const CSSStyleDeclaration = @This();
_element: ?*Element = null,
_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{
._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 {
const normalized = normalizePropertyName(property_name, &page.buf);
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();
}
@@ -78,7 +84,7 @@ pub fn setProperty(self: *CSSStyleDeclaration, property_name: []const u8, value:
// Validate priority
const important = if (priority.len > 0) blk: {
if (!std.mem.eql(u8, priority, "important")) {
if (!std.ascii.eqlIgnoreCase(priority, "important")) {
return;
}
break :blk true;
@@ -113,6 +119,14 @@ pub fn removeProperty(self: *CSSStyleDeclaration, property_name: []const u8, pag
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 {
if (self._element == null) return "";
@@ -288,4 +302,5 @@ pub const JsApi = struct {
pub const getPropertyPriority = bridge.function(CSSStyleDeclaration.getPropertyPriority, .{});
pub const setProperty = bridge.function(CSSStyleDeclaration.setProperty, .{});
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,
pub fn init(element: ?*Element, page: *Page) !*CSSStyleProperties {
pub fn init(element: ?*Element, is_computed: bool, page: *Page) !*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| {
return style;
}
const style = try CSSStyleDeclaration.init(null, page);
const style = try CSSStyleDeclaration.init(null, false, page);
self._style = style;
return style;
}