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();
|
return self._proto.parentElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CSSStyleRule = @import("css/CSSStyleRule.zig");
|
||||||
|
|
||||||
pub fn checkVisibility(self: *Element, page: *Page) bool {
|
pub fn checkVisibility(self: *Element, page: *Page) bool {
|
||||||
var current: ?*Element = self;
|
var current: ?*Element = self;
|
||||||
|
|
||||||
@@ -1051,9 +1053,40 @@ pub fn checkVisibility(self: *Element, page: *Page) bool {
|
|||||||
return false;
|
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();
|
current = el.parentElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
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);
|
const style_rule = try CSSStyleRule.init(page);
|
||||||
try style_rule.setSelectorText(parsed_rule.selector, 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_props = try style_rule.getStyle(page);
|
||||||
const style = style_props.asCSSStyleDeclaration();
|
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| {
|
while (it.next()) |parsed_rule| {
|
||||||
const style_rule = try CSSStyleRule.init(page);
|
const style_rule = try CSSStyleRule.init(page);
|
||||||
try style_rule.setSelectorText(parsed_rule.selector, 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_props = try style_rule.getStyle(page);
|
||||||
const style = style_props.asCSSStyleDeclaration();
|
const style = style_props.asCSSStyleDeclaration();
|
||||||
|
|||||||
@@ -5,19 +5,24 @@ const CSSStyleSheet = @import("CSSStyleSheet.zig");
|
|||||||
|
|
||||||
const StyleSheetList = @This();
|
const StyleSheetList = @This();
|
||||||
|
|
||||||
_sheets: []*CSSStyleSheet = &.{},
|
_sheets: std.ArrayListUnmanaged(*CSSStyleSheet) = .{},
|
||||||
|
|
||||||
pub fn init(page: *Page) !*StyleSheetList {
|
pub fn init(page: *Page) !*StyleSheetList {
|
||||||
return page._factory.create(StyleSheetList{});
|
return page._factory.create(StyleSheetList{});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn length(self: *const StyleSheetList) u32 {
|
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 {
|
pub fn item(self: *const StyleSheetList, index: usize) ?*CSSStyleSheet {
|
||||||
if (index >= self._sheets.len) return null;
|
if (index >= self._sheets.items.len) return null;
|
||||||
return self._sheets[index];
|
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 {
|
pub const JsApi = struct {
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ pub fn setDisabled(self: *Style, disabled: bool, page: *Page) !void {
|
|||||||
|
|
||||||
const CSSStyleSheet = @import("../../css/CSSStyleSheet.zig");
|
const CSSStyleSheet = @import("../../css/CSSStyleSheet.zig");
|
||||||
pub fn getSheet(self: *Style, page: *Page) !?*CSSStyleSheet {
|
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.
|
// Per spec, sheet is null for disconnected elements or non-CSS types.
|
||||||
// Valid types: absent (defaults to "text/css"), empty string, or
|
// Valid types: absent (defaults to "text/css"), empty string, or
|
||||||
// case-insensitive match for "text/css".
|
// 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);
|
const text = try self.asNode().getTextContentAlloc(page.call_arena);
|
||||||
try sheet.replaceSync(text, page);
|
try sheet.replaceSync(text, page);
|
||||||
|
|
||||||
|
const sheets = try page.document.getStyleSheets(page);
|
||||||
|
try sheets.add(sheet, page);
|
||||||
|
|
||||||
return sheet;
|
return sheet;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn styleAddedCallback(self: *Style, page: *Page) !void {
|
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 we're planning on navigating to another page, don't trigger load event.
|
||||||
if (page.isGoingAway()) {
|
if (page.isGoingAway()) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user