swc_html_ast/
base.rs

1use is_macro::Is;
2use string_enum::StringEnum;
3use swc_atoms::Atom;
4use swc_common::{ast_node, EqIgnoreSpan, Span};
5
6#[ast_node("Document")]
7#[derive(Eq, Hash, EqIgnoreSpan)]
8pub struct Document {
9    pub span: Span,
10    pub mode: DocumentMode,
11    pub children: Vec<Child>,
12}
13
14#[ast_node("DocumentFragment")]
15#[derive(Eq, Hash, EqIgnoreSpan)]
16pub struct DocumentFragment {
17    pub span: Span,
18    pub children: Vec<Child>,
19}
20
21#[derive(StringEnum, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, EqIgnoreSpan)]
22#[cfg_attr(
23    feature = "rkyv",
24    derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
25)]
26#[cfg_attr(feature = "rkyv", derive(bytecheck::CheckBytes))]
27//#[cfg_attr(
28//    feature = "rkyv",
29//    archive(bound(serialize = "__S: rkyv::ser::ScratchSpace +
30// rkyv::ser::Serializer"))
31//)]
32#[cfg_attr(feature = "rkyv", repr(u32))]
33pub enum DocumentMode {
34    /// `no-quirks`
35    NoQuirks,
36    /// `limited-quirks`
37    LimitedQuirks,
38    /// `quirks`
39    Quirks,
40}
41
42#[ast_node]
43#[derive(Eq, Hash, Is, EqIgnoreSpan)]
44pub enum Child {
45    #[tag("DocumentType")]
46    DocumentType(DocumentType),
47    #[tag("Element")]
48    Element(Element),
49    #[tag("Text")]
50    Text(Text),
51    #[tag("Comment")]
52    Comment(Comment),
53}
54
55#[ast_node("DocumentType")]
56#[derive(Eq, Hash)]
57pub struct DocumentType {
58    pub span: Span,
59
60    pub name: Option<Atom>,
61
62    pub public_id: Option<Atom>,
63
64    pub system_id: Option<Atom>,
65    pub raw: Option<Atom>,
66}
67
68impl EqIgnoreSpan for DocumentType {
69    fn eq_ignore_span(&self, other: &Self) -> bool {
70        self.name == other.name
71            && self.public_id == other.public_id
72            && self.system_id == other.system_id
73    }
74}
75
76#[derive(StringEnum, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, EqIgnoreSpan)]
77#[cfg_attr(
78    feature = "rkyv",
79    derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
80)]
81#[cfg_attr(feature = "rkyv", derive(bytecheck::CheckBytes))]
82//#[cfg_attr(
83//    feature = "rkyv",
84//    archive(bound(serialize = "__S: rkyv::ser::ScratchSpace +
85// rkyv::ser::Serializer"))
86//)]
87#[cfg_attr(feature = "rkyv", repr(u32))]
88pub enum Namespace {
89    /// `http://www.w3.org/1999/xhtml`
90    HTML,
91    /// `http://www.w3.org/1998/Math/MathML`
92    MATHML,
93    /// `http://www.w3.org/2000/svg`
94    SVG,
95    /// `http://www.w3.org/1999/xlink`
96    XLINK,
97    /// `http://www.w3.org/XML/1998/namespace`
98    XML,
99    /// `http://www.w3.org/2000/xmlns/`
100    XMLNS,
101}
102
103#[ast_node("Element")]
104#[derive(Eq, Hash, EqIgnoreSpan)]
105pub struct Element {
106    pub span: Span,
107
108    pub tag_name: Atom,
109    pub namespace: Namespace,
110    pub attributes: Vec<Attribute>,
111    pub children: Vec<Child>,
112    /// For child nodes in `<template>`
113    pub content: Option<DocumentFragment>,
114    pub is_self_closing: bool,
115}
116
117#[ast_node("Attribute")]
118#[derive(Eq, Hash)]
119pub struct Attribute {
120    pub span: Span,
121    pub namespace: Option<Namespace>,
122
123    pub prefix: Option<Atom>,
124
125    pub name: Atom,
126    pub raw_name: Option<Atom>,
127
128    pub value: Option<Atom>,
129    pub raw_value: Option<Atom>,
130}
131
132impl EqIgnoreSpan for Attribute {
133    fn eq_ignore_span(&self, other: &Self) -> bool {
134        self.namespace == other.namespace
135            && self.prefix == other.prefix
136            && self.name == other.name
137            && self.value == other.value
138    }
139}
140
141#[ast_node("Text")]
142#[derive(Eq, Hash)]
143pub struct Text {
144    pub span: Span,
145
146    pub data: Atom,
147    pub raw: Option<Atom>,
148}
149
150impl EqIgnoreSpan for Text {
151    fn eq_ignore_span(&self, other: &Self) -> bool {
152        self.data == other.data
153    }
154}
155
156#[ast_node("Comment")]
157#[derive(Eq, Hash)]
158pub struct Comment {
159    pub span: Span,
160
161    pub data: Atom,
162    pub raw: Option<Atom>,
163}
164
165impl EqIgnoreSpan for Comment {
166    fn eq_ignore_span(&self, other: &Self) -> bool {
167        self.data == other.data
168    }
169}