Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
Rust
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116//! The node arena. Hand-directed integration scaffolding (see the crate root doc//! comment), not generated code.//!//! Nodes live in a flat `Vec` keyed by [`NodeId`], per `roadmap.md` -> "DOM layer,//! shaped by Stylo": everything above this module reaches a node only through an id//! plus the [`crate::style::Document`] that owns the arena, never through a pointer//! embedded in the node itself.
use std::cell::{Cell, OnceCell};
use selectors::matching::ElementSelectorFlags;use style::properties::PropertyDeclarationBlock;use style::servo_arc::Arc;use style::shared_lock::Locked;
use crate::style_data::StyloData;
/// An index into [`crate::style::Document`]'s node arena.////// Backed by `usize` rather than a smaller integer so that `NodeId` alone -- with no/// other field -- is exactly pointer-sized. Stylo's style-sharing cache (`sharing/mod.rs`/// in the `stylo` source) transmutes a type-erased cache slot into one sized and aligned/// for the concrete element type, asserting the two sizes match; that type is `NodeId`/// here (`style.rs`'s module doc comment has the rest of this story).#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]pub struct NodeId(pub usize);
impl NodeId { pub fn index(self) -> usize { self.0 }}
/// One parsed attribute: name plus string value. `markup5ever`'s own `Attribute`/// carries a `tendril::StrTendril`; that dependency is not worth taking on here, so/// the value is copied into an owned `String` at parse time.#[derive(Debug, Clone)]pub struct Attr { pub name: markup5ever::QualName, pub value: String,}
/// Per-element data. Distinct from Stylo's own `style::data::ElementData`, which is/// the interior-mutable slot in [`StyloData`] below.////// `Debug` is written by hand rather than derived: `ElementSelectorFlags` (a/// `selectors`-crate bitflags type) does not implement it.pub struct ElementData { pub name: markup5ever::QualName, pub attrs: Vec<Attr>, /// The `id` attribute, interned once at parse time since `selectors::Element::has_id` /// is called once per selector-matching attempt against every candidate element. pub id: Option<style::Atom>, pub stylo_data: StyloData, pub dirty_descendants: Cell<bool>, pub selector_flags: Cell<ElementSelectorFlags>, /// The `style=""` attribute, parsed and cached on first access. `None` once parsed /// means the attribute is absent or empty; the outer `OnceCell` being unset means /// parsing hasn't happened yet. pub style_attribute: OnceCell<Option<Arc<Locked<PropertyDeclarationBlock>>>>,}
impl std::fmt::Debug for ElementData { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("ElementData") .field("name", &self.name) .field("attrs", &self.attrs) .field("id", &self.id) .field("stylo_data", &self.stylo_data) .finish_non_exhaustive() }}
impl ElementData { pub fn attr(&self, local_name: &str) -> Option<&str> { self.attrs .iter() .find(|a| &*a.name.local == local_name) .map(|a| a.value.as_str()) }}
#[derive(Debug)]pub enum NodeData { /// The document node, always `NodeId(0)`. Document, Element(ElementData), Text(String), Comment(String),}
#[derive(Debug)]pub struct Node { pub id: NodeId, pub parent: Option<NodeId>, pub children: Vec<NodeId>, pub data: NodeData,}
impl Node { pub fn is_element(&self) -> bool { matches!(self.data, NodeData::Element(_)) }
pub fn is_text(&self) -> bool { matches!(self.data, NodeData::Text(_)) }
pub fn as_element(&self) -> Option<&ElementData> { match &self.data { NodeData::Element(e) => Some(e), _ => None, } }}