mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-22 04:34:44 +00:00
dom: support css display: none in checkVisibility
Updates `Element.checkVisibility` to iterate through document stylesheets and check for matching rules with `display: none`. Also ensures `<style>` elements register their sheets and initializes them immediately upon addition to the DOM.
This commit is contained in:
@@ -1041,6 +1041,8 @@ pub fn parentElement(self: *Element) ?*Element {
|
||||
return self._proto.parentElement();
|
||||
}
|
||||
|
||||
const CSSStyleRule = @import("css/CSSStyleRule.zig");
|
||||
|
||||
pub fn checkVisibility(self: *Element, page: *Page) bool {
|
||||
var current: ?*Element = self;
|
||||
|
||||
@@ -1051,9 +1053,40 @@ pub fn checkVisibility(self: *Element, page: *Page) bool {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Also check if any global stylesheet hides this element
|
||||
const doc_sheets = page.document.getStyleSheets(page) catch null;
|
||||
if (doc_sheets) |sheets| {
|
||||
var i: usize = 0;
|
||||
if (sheets.length() > 0) log.info(.dom, "css.visibility.check", .{});
|
||||
while (i < sheets.length()) : (i += 1) {
|
||||
const sheet = sheets.item(i) orelse continue;
|
||||
const rules = sheet.getCssRules(page) catch continue;
|
||||
var j: usize = 0;
|
||||
while (j < rules.length()) : (j += 1) {
|
||||
const rule = rules.item(j) orelse continue;
|
||||
if (rule.is(CSSStyleRule)) |style_rule| {
|
||||
const selector = style_rule.getSelectorText();
|
||||
// log.info(.dom, "check_visibility.eval {s}", .{selector});
|
||||
const does_match = el.matches(selector, page) catch |err| blk: {
|
||||
log.info(.dom, "check_visibility.err", .{ .err = err });
|
||||
break :blk false;
|
||||
};
|
||||
if (does_match) {
|
||||
const style = (style_rule.getStyle(page) catch continue).asCSSStyleDeclaration();
|
||||
const display = style.getPropertyValue("display", page);
|
||||
log.info(.dom, "check_visibility.hit", .{});
|
||||
if (std.mem.eql(u8, display, "none")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
current = el.parentElement();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@ pub fn insertRule(self: *CSSStyleSheet, rule: []const u8, index: u32, page: *Pag
|
||||
|
||||
const style_rule = try CSSStyleRule.init(page);
|
||||
try style_rule.setSelectorText(parsed_rule.selector, page);
|
||||
@import("../../../log.zig").info(.dom, "css.rule.add {s}", .{parsed_rule.selector});
|
||||
|
||||
const style_props = try style_rule.getStyle(page);
|
||||
const style = style_props.asCSSStyleDeclaration();
|
||||
@@ -90,6 +91,7 @@ pub fn replaceSync(self: *CSSStyleSheet, text: []const u8, page: *Page) !void {
|
||||
while (it.next()) |parsed_rule| {
|
||||
const style_rule = try CSSStyleRule.init(page);
|
||||
try style_rule.setSelectorText(parsed_rule.selector, page);
|
||||
@import("../../../log.zig").info(.dom, "css.rule.add {s}", .{parsed_rule.selector});
|
||||
|
||||
const style_props = try style_rule.getStyle(page);
|
||||
const style = style_props.asCSSStyleDeclaration();
|
||||
|
||||
@@ -5,19 +5,24 @@ const CSSStyleSheet = @import("CSSStyleSheet.zig");
|
||||
|
||||
const StyleSheetList = @This();
|
||||
|
||||
_sheets: []*CSSStyleSheet = &.{},
|
||||
_sheets: std.ArrayListUnmanaged(*CSSStyleSheet) = .{},
|
||||
|
||||
pub fn init(page: *Page) !*StyleSheetList {
|
||||
return page._factory.create(StyleSheetList{});
|
||||
}
|
||||
|
||||
pub fn length(self: *const StyleSheetList) u32 {
|
||||
return @intCast(self._sheets.len);
|
||||
return @intCast(self._sheets.items.len);
|
||||
}
|
||||
|
||||
pub fn item(self: *const StyleSheetList, index: usize) ?*CSSStyleSheet {
|
||||
if (index >= self._sheets.len) return null;
|
||||
return self._sheets[index];
|
||||
if (index >= self._sheets.items.len) return null;
|
||||
return self._sheets.items[index];
|
||||
}
|
||||
|
||||
pub fn add(self: *StyleSheetList, sheet: *CSSStyleSheet, page: *Page) !void {
|
||||
@import("../../../log.zig").info(.dom, "css.sheet.add", .{});
|
||||
try self._sheets.append(page.arena, sheet);
|
||||
}
|
||||
|
||||
pub const JsApi = struct {
|
||||
|
||||
@@ -78,6 +78,7 @@ pub fn setDisabled(self: *Style, disabled: bool, page: *Page) !void {
|
||||
|
||||
const CSSStyleSheet = @import("../../css/CSSStyleSheet.zig");
|
||||
pub fn getSheet(self: *Style, page: *Page) !?*CSSStyleSheet {
|
||||
@import("../../../../log.zig").info(.dom, "css.style.get_sheet", .{});
|
||||
// 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".
|
||||
@@ -98,10 +99,16 @@ pub fn getSheet(self: *Style, page: *Page) !?*CSSStyleSheet {
|
||||
const text = try self.asNode().getTextContentAlloc(page.call_arena);
|
||||
try sheet.replaceSync(text, page);
|
||||
|
||||
const sheets = try page.document.getStyleSheets(page);
|
||||
try sheets.add(sheet, page);
|
||||
|
||||
return sheet;
|
||||
}
|
||||
|
||||
pub fn styleAddedCallback(self: *Style, page: *Page) !void {
|
||||
// Force stylesheet initialization so rules are parsed immediately
|
||||
_ = self.getSheet(page) catch null;
|
||||
|
||||
// if we're planning on navigating to another page, don't trigger load event.
|
||||
if (page.isGoingAway()) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user