add CSSStyleSheet

This commit is contained in:
Muki Kiboigo
2025-06-03 13:33:06 -07:00
parent ac759a6eed
commit ba94818415
6 changed files with 249 additions and 8 deletions

View File

@@ -0,0 +1,80 @@
// Copyright (C) 2023-2024 Lightpanda (Selecy SAS)
//
// Francis Bouvier <francis@lightpanda.io>
// Pierre Tachoire <pierre@lightpanda.io>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// 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 Page = @import("../page.zig").Page;
const CSSStyleDeclaration = @import("css_style_declaration.zig").CSSStyleDeclaration;
const CSSStyleSheet = @import("css_stylesheet.zig").CSSStyleSheet;
pub const Interfaces = .{
CSSRule,
CSSImportRule,
};
// https://developer.mozilla.org/en-US/docs/Web/API/CSSRule
pub const CSSRule = struct {
css_text: []const u8,
parent_rule: ?*CSSRule = null,
parent_stylesheet: ?*CSSStyleSheet = null,
};
pub const CSSImportRule = struct {
pub const prototype = *CSSRule;
href: []const u8,
layer_name: ?[]const u8,
media: void,
style_sheet: CSSStyleSheet,
supports_text: ?[]const u8,
};
// pub const CSSGroupingRule = struct {
// pub const prototype = *CSSRule;
// list: std.ArrayListUnmanaged(CSSRule),
// pub fn _insertRule(self: *CSSGroupingRule, rule: []const u8, _index: ?usize, page: *Page) !usize {
// const index = _index orelse 0;
// if (index > self.list.items.len) return error.IndexSizeError;
// const css_rule: CSSRule = .{ .css_text = rule, .parent_rule = null, .parent_stylesheet = null };
// try self.list.insert(page.arena, index, css_rule);
// return self.list.items.len;
// }
// pub fn _deleteRule(self: *CSSGroupingRule, index: usize) !void {
// if (index > self.list.items.len) return error.IndexSizeError;
// _ = self.list.orderedRemove(index);
// }
// };
// pub const CSSStyleRule = struct {
// pub const prototype = *CSSGroupingRule;
// selector_text: []const u8,
// style: CSSStyleDeclaration,
// };
// pub const CSSFontFaceRule = struct {
// pub const prototype = *CSSRule;
// };
// pub const CSSPageRule = struct {
// pub const prototype = *CSSGroupingRule;
// selector_text: []const u8,
// style: CSSStyleDeclaration,
// };

View File

@@ -20,15 +20,9 @@ const std = @import("std");
const CSSParser = @import("./css_parser.zig").CSSParser; const CSSParser = @import("./css_parser.zig").CSSParser;
const CSSValueAnalyzer = @import("./css_value_analyzer.zig").CSSValueAnalyzer; const CSSValueAnalyzer = @import("./css_value_analyzer.zig").CSSValueAnalyzer;
const CSSRule = @import("css_rule.zig").CSSRule;
const Page = @import("../page.zig").Page; const Page = @import("../page.zig").Page;
pub const Interfaces = .{
CSSStyleDeclaration,
CSSRule,
};
const CSSRule = struct {};
pub const CSSStyleDeclaration = struct { pub const CSSStyleDeclaration = struct {
store: std.StringHashMapUnmanaged(Property), store: std.StringHashMapUnmanaged(Property),
order: std.ArrayListUnmanaged([]const u8), order: std.ArrayListUnmanaged([]const u8),

View File

@@ -0,0 +1,84 @@
// Copyright (C) 2023-2024 Lightpanda (Selecy SAS)
//
// Francis Bouvier <francis@lightpanda.io>
// Pierre Tachoire <pierre@lightpanda.io>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// 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 Page = @import("../page.zig").Page;
const StyleSheet = @import("stylesheet.zig").StyleSheet;
const CSSRule = @import("css_rule.zig").CSSRule;
const CSSImportRule = @import("css_rule.zig").CSSImportRule;
pub const CSSStyleSheet = struct {
pub const prototype = *StyleSheet;
// TODO: For now, we won't parse any rules.
css_rules: std.ArrayListUnmanaged([]const u8),
// TODO: Support owner_rule here.
const CSSStyleSheetOpts = struct {
base_url: ?[]const u8,
// TODO: Suupport media
disabled: bool = false,
};
pub fn constructor(_opts: ?CSSStyleSheetOpts) CSSStyleSheet {
const opts = _opts orelse CSSStyleSheetOpts{};
_ = opts;
return .{ .css_rules = .empty, .owner_rule = null };
}
pub fn get_ownerRule(_: *CSSStyleSheet) ?*CSSImportRule {
return null;
}
pub fn get_cssRules(self: *CSSStyleSheet) *std.ArrayListUnmanaged([]const u8) {
return self.css_rules;
}
pub fn _insertRule(self: *CSSStyleSheet, rule: []const u8, _index: ?usize, page: *Page) !usize {
const index = _index orelse 0;
if (index > self.css_rules.items.len) {
return error.IndexSize;
}
const arena = page.arena;
try self.css_rules.insert(arena, index, arena.dupe(u8, rule));
return index;
}
pub fn _deleteRule(self: *CSSStyleSheet, index: usize) !void {
if (index > self.css_rules.items.len) {
return error.IndexSize;
}
_ = self.css_rules.orderedRemove(index);
}
};
const testing = @import("../../testing.zig");
test "Browser.CSS.StyleSheet" {
var runner = try testing.jsRunner(testing.tracking_allocator, .{});
defer runner.deinit();
try runner.testCases(&.{
.{ "let css = new CSSStylesheet()", "" },
}, .{});
}

View File

@@ -0,0 +1,28 @@
// Copyright (C) 2023-2024 Lightpanda (Selecy SAS)
//
// Francis Bouvier <francis@lightpanda.io>
// Pierre Tachoire <pierre@lightpanda.io>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// 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/>.
pub const Stylesheet = @import("stylesheet.zig").StyleSheet;
pub const CSSStylesheet = @import("css_stylesheet.zig").CSSStyleSheet;
pub const CSSStyleDeclaration = @import("css_style_declaration.zig").CSSStyleDeclaration;
pub const Interfaces = .{
Stylesheet,
CSSStylesheet,
CSSStyleDeclaration,
@import("css_rule.zig").Interfaces,
};

View File

@@ -0,0 +1,55 @@
// Copyright (C) 2023-2024 Lightpanda (Selecy SAS)
//
// Francis Bouvier <francis@lightpanda.io>
// Pierre Tachoire <pierre@lightpanda.io>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// 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 parser = @import("../netsurf.zig");
// https://developer.mozilla.org/en-US/docs/Web/API/StyleSheet#specifications
pub const StyleSheet = struct {
disabled: bool,
href: []const u8,
owner_node: *parser.Node,
parent_stylesheet: ?*StyleSheet,
title: []const u8,
type: []const u8,
pub fn get_disabled(self: *StyleSheet) bool {
return self.disabled;
}
pub fn get_href(self: *StyleSheet) []const u8 {
return self.href;
}
// TODO: media
pub fn get_ownerNode(self: *StyleSheet) *parser.Node {
return self.owner_node;
}
pub fn get_parentStyleSheet(self: *StyleSheet) ?*StyleSheet {
return self.parent_stylesheet;
}
pub fn get_title(self: *StyleSheet) []const u8 {
return self.title;
}
pub fn get_type(self: *StyleSheet) []const u8 {
return self.type;
}
};

View File

@@ -22,7 +22,7 @@ const WebApis = struct {
pub const Interfaces = generate.Tuple(.{ pub const Interfaces = generate.Tuple(.{
@import("crypto/crypto.zig").Crypto, @import("crypto/crypto.zig").Crypto,
@import("console/console.zig").Console, @import("console/console.zig").Console,
@import("cssom/css_style_declaration.zig").Interfaces, @import("cssom/cssom.zig").Interfaces,
@import("dom/dom.zig").Interfaces, @import("dom/dom.zig").Interfaces,
@import("encoding/text_encoder.zig").Interfaces, @import("encoding/text_encoder.zig").Interfaces,
@import("events/event.zig").Interfaces, @import("events/event.zig").Interfaces,