Merge pull request #1579 from egrs/style-element-sheet
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

return CSSStyleSheet from HTMLStyleElement.sheet
This commit is contained in:
Karl Seguin
2026-02-18 19:59:38 +08:00
committed by GitHub
3 changed files with 67 additions and 6 deletions

View File

@@ -3,7 +3,46 @@
<script id="sheet">
{
// Disconnected style element should have no sheet
testing.expectEqual(null, document.createElement('style').sheet);
// Connected style element should have a CSSStyleSheet
const style = document.createElement('style');
document.head.appendChild(style);
testing.expectEqual(true, style.sheet instanceof CSSStyleSheet);
// Same sheet instance on repeated access
testing.expectEqual(true, style.sheet === style.sheet);
// Non-CSS type should have no sheet
const lessStyle = document.createElement('style');
lessStyle.type = 'text/less';
document.head.appendChild(lessStyle);
testing.expectEqual(null, lessStyle.sheet);
// Empty type attribute is valid (defaults to text/css per spec)
const emptyType = document.createElement('style');
emptyType.setAttribute('type', '');
document.head.appendChild(emptyType);
testing.expectEqual(true, emptyType.sheet instanceof CSSStyleSheet);
// Case-insensitive type check
const upperType = document.createElement('style');
upperType.type = 'TEXT/CSS';
document.head.appendChild(upperType);
testing.expectEqual(true, upperType.sheet instanceof CSSStyleSheet);
// Disconnection clears sheet
const tempStyle = document.createElement('style');
document.head.appendChild(tempStyle);
testing.expectEqual(true, tempStyle.sheet instanceof CSSStyleSheet);
document.head.removeChild(tempStyle);
testing.expectEqual(null, tempStyle.sheet);
// ownerNode points back to the style element
const ownStyle = document.createElement('style');
document.head.appendChild(ownStyle);
testing.expectEqual(true, ownStyle.sheet.ownerNode === ownStyle);
}
</script>

View File

@@ -1,6 +1,7 @@
const std = @import("std");
const js = @import("../../js/js.zig");
const Page = @import("../../Page.zig");
const Element = @import("../Element.zig");
const CSSRuleList = @import("CSSRuleList.zig");
const CSSRule = @import("CSSRule.zig");
@@ -11,14 +12,18 @@ _title: []const u8 = "",
_disabled: bool = false,
_css_rules: ?*CSSRuleList = null,
_owner_rule: ?*CSSRule = null,
_owner_node: ?*Element = null,
pub fn init(page: *Page) !*CSSStyleSheet {
return page._factory.create(CSSStyleSheet{});
}
pub fn getOwnerNode(self: *const CSSStyleSheet) ?*CSSStyleSheet {
_ = self;
return null;
pub fn initWithOwner(owner: *Element, page: *Page) !*CSSStyleSheet {
return page._factory.create(CSSStyleSheet{ ._owner_node = owner });
}
pub fn getOwnerNode(self: *const CSSStyleSheet) ?*Element {
return self._owner_node;
}
pub fn getHref(self: *const CSSStyleSheet) ?[]const u8 {

View File

@@ -16,6 +16,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
const std = @import("std");
const js = @import("../../../js/js.zig");
const Page = @import("../../../Page.zig");
@@ -25,6 +26,7 @@ const HtmlElement = @import("../Html.zig");
const Style = @This();
_proto: *HtmlElement,
_sheet: ?*CSSStyleSheet = null,
pub fn asElement(self: *Style) *Element {
return self._proto._proto;
@@ -75,9 +77,24 @@ pub fn setDisabled(self: *Style, disabled: bool, page: *Page) !void {
}
const CSSStyleSheet = @import("../../css/CSSStyleSheet.zig");
pub fn getSheet(_: *const Style) ?*CSSStyleSheet {
// TODO?
pub fn getSheet(self: *Style, page: *Page) !?*CSSStyleSheet {
// Per spec, sheet is null for disconnected elements or non-CSS types.
// Valid types: absent (defaults to "text/css"), empty string, or
// case-insensitive match for "text/css".
if (!self.asNode().isConnected()) {
self._sheet = null;
return null;
}
const t = self.getType();
if (t.len != 0 and !std.ascii.eqlIgnoreCase(t, "text/css")) {
self._sheet = null;
return null;
}
if (self._sheet) |sheet| return sheet;
const sheet = try CSSStyleSheet.initWithOwner(self.asElement(), page);
self._sheet = sheet;
return sheet;
}
pub const JsApi = struct {