Files
browser/src/css
2024-06-18 16:13:27 +02:00
..
2024-05-13 20:51:36 +02:00
2024-03-25 18:35:28 +01:00

css

Lightpanda css implements CSS selectors parsing and matching in Zig. This package is a port of the Go lib andybalholm/cascadia.

Usage

Query parser

const css = @import("css.zig");

const selector = try css.parse(alloc, "h1", .{});
defer selector.deinit(alloc);

DOM tree match

The lib expects a Node interface implementation to match your DOM tree.

pub const Node = struct {
    pub fn firstChild(_: Node) !?Node {
        return error.TODO;
    }

    pub fn lastChild(_: Node) !?Node {
        return error.TODO;
    }

    pub fn nextSibling(_: Node) !?Node {
        return error.TODO;
    }

    pub fn prevSibling(_: Node) !?Node {
        return error.TODO;
    }

    pub fn parent(_: Node) !?Node {
        return error.TODO;
    }

    pub fn isElement(_: Node) bool {
        return false;
    }

    pub fn isDocument(_: Node) bool {
        return false;
    }

    pub fn isComment(_: Node) bool {
        return false;
    }

    pub fn isText(_: Node) bool {
        return false;
    }

    pub fn isEmptyText(_: Node) !bool {
        return error.TODO;
    }

    pub fn tag(_: Node) ![]const u8 {
        return error.TODO;
    }

    pub fn attr(_: Node, _: []const u8) !?[]const u8 {
        return error.TODO;
    }

    pub fn eql(_: Node, _: Node) bool {
        return false;
    }
};

You also need do define a Matcher implementing a match function to accumulate the results.

const Matcher = struct {
    const Nodes = std.ArrayList(Node);

    nodes: Nodes,

    fn init(alloc: std.mem.Allocator) Matcher {
        return .{ .nodes = Nodes.init(alloc) };
    }

    fn deinit(m: *Matcher) void {
        m.nodes.deinit();
    }

    pub fn match(m: *Matcher, n: Node) !void {
        try m.nodes.append(n);
    }
};

Then you can use the lib itself.

var matcher = Matcher.init(alloc);
defer matcher.deinit();

try css.matchAll(selector, node, &matcher);
_ = try css.matchFirst(selector, node, &matcher); // returns true if a node matched.

Features

  • parse query selector
  • matchAll
  • matchFirst
  • specificity

Selectors implemented

Selectors

  • Class selectors
  • Id selectors
  • Type selectors
  • Universal selectors
  • Nesting selectors

Combinators

  • Child combinator
  • Column combinator
  • Descendant combinator
  • Namespace combinator
  • Next-sibling combinator
  • Selector list combinator
  • Subsequent-sibling combinator

Attribute

  • [attr]
  • [attr=value]
  • [attr|=value]
  • [attr^=value]
  • [attr$=value]
  • [attr*=value]
  • [attr operator value i]
  • [attr operator value s]

Pseudo classes

  • :active
  • :any-link
  • :autofill
  • :blank Experimental
  • :checked
  • :current Experimental
  • :default
  • :defined
  • :dir() Experimental
  • :disabled
  • :empty
  • :enabled
  • :first
  • :first-child
  • :first-of-type
  • :focus
  • :focus-visible
  • :focus-within
  • :fullscreen
  • :future Experimental
  • :has() Experimental
  • :host
  • :host()
  • :host-context() Experimental
  • :hover
  • :indeterminate
  • :in-range
  • :invalid
  • :is()
  • :lang()
  • :last-child
  • :last-of-type
  • :left
  • :link
  • :local-link Experimental
  • :modal
  • :not()
  • :nth-child()
  • :nth-last-child()
  • :nth-last-of-type()
  • :nth-of-type()
  • :only-child
  • :only-of-type
  • :optional
  • :out-of-range
  • :past Experimental
  • :paused
  • :picture-in-picture
  • :placeholder-shown
  • :playing
  • :read-only
  • :read-write
  • :required
  • :right
  • :root
  • :scope
  • :state() Experimental
  • :target
  • :target-within Experimental
  • :user-invalid Experimental
  • :valid
  • :visited
  • :where()
  • :contains()
  • :containsown()
  • :matched()
  • :matchesown()
  • :root