facet_html_dom/
lib.rs

1//! Typed HTML element definitions for use with `facet-html`.
2//!
3//! This crate provides Facet-derived types for all standard HTML5 elements,
4//! allowing you to parse and serialize HTML documents with full type safety.
5//!
6//! # Quick Start
7//!
8//! ```rust
9//! use facet_html_dom::{Html, Body, Div, P, FlowContent};
10//!
11//! // Parse an HTML document
12//! let html_source = r#"
13//!     <!DOCTYPE html>
14//!     <html>
15//!         <body>
16//!             <div class="container">
17//!                 <p>Hello, world!</p>
18//!             </div>
19//!         </body>
20//!     </html>
21//! "#;
22//!
23//! let doc: Html = facet_html::from_str(html_source).unwrap();
24//!
25//! // Access the parsed structure
26//! if let Some(body) = &doc.body {
27//!     for child in &body.children {
28//!         if let FlowContent::Div(div) = child {
29//!             println!("Found div with class: {:?}", div.attrs.class);
30//!         }
31//!     }
32//! }
33//!
34//! // Serialize back to HTML
35//! let output = facet_html::to_string_pretty(&doc).unwrap();
36//! ```
37//!
38//! # Content Models
39//!
40//! HTML elements are organized by their content model:
41//!
42//! - [`FlowContent`] - Block and inline elements that can appear in `<body>`, `<div>`, etc.
43//! - [`PhrasingContent`] - Inline elements that can appear in `<p>`, `<span>`, `<a>`, etc.
44//!
45//! These enums allow mixed content with proper nesting validation at the type level.
46//!
47//! # Global Attributes
48//!
49//! All elements include [`GlobalAttrs`] via the `attrs` field, which provides:
50//! - Standard attributes: `id`, `class`, `style`, `lang`, `dir`, etc.
51//! - Common event handlers: `onclick`, `onchange`, `onfocus`, etc.
52//! - An `extra` field that captures unknown attributes like `data-*` and `aria-*`
53//!
54//! # Custom Elements
55//!
56//! Unknown HTML elements (like `<my-component>` or syntax highlighting tags like `<a-k>`)
57//! are captured via [`CustomElement`] and [`CustomPhrasingElement`], preserving their
58//! tag names, attributes, and children during parse/serialize roundtrips.
59//!
60//! # Element Categories
61//!
62//! Elements are organized by category:
63//! - **Document**: [`Html`], [`Head`], [`Body`]
64//! - **Metadata**: [`Title`], [`Base`], [`Link`], [`Meta`], [`Style`]
65//! - **Sections**: [`Header`], [`Footer`], [`Main`], [`Article`], [`Section`], [`Nav`], [`Aside`]
66//! - **Headings**: [`H1`], [`H2`], [`H3`], [`H4`], [`H5`], [`H6`]
67//! - **Grouping**: [`P`], [`Div`], [`Span`], [`Pre`], [`Blockquote`], [`Ol`], [`Ul`], [`Li`], etc.
68//! - **Text-level**: [`A`], [`Em`], [`Strong`], [`Code`], [`Br`], [`Wbr`], etc.
69//! - **Embedded**: [`Img`], [`Iframe`], [`Video`], [`Audio`], [`Source`], [`Picture`]
70//! - **Tables**: [`Table`], [`Thead`], [`Tbody`], [`Tr`], [`Th`], [`Td`], etc.
71//! - **Forms**: [`Form`], [`Input`], [`Button`], [`Select`], [`OptionElement`], [`Textarea`], [`Label`]
72//! - **Interactive**: [`Details`], [`Summary`], [`Dialog`]
73//! - **Scripting**: [`Script`], [`Noscript`], [`Template`], [`Canvas`]
74
75use facet::Facet;
76use facet_html as html;
77
78// =============================================================================
79// Global Attributes (common to all HTML elements)
80// =============================================================================
81
82/// Global attributes that can appear on any HTML element.
83///
84/// This includes standard HTML global attributes and common event handlers.
85/// Unknown attributes (like data-*, aria-*, and less common event handlers)
86/// are captured in the `extra` field.
87#[derive(Default, Facet)]
88#[facet(default, skip_all_unless_truthy)]
89pub struct GlobalAttrs {
90    // Standard global attributes
91    /// Unique identifier for the element.
92    #[facet(html::attribute, default)]
93    pub id: Option<String>,
94    /// CSS class names.
95    #[facet(html::attribute, default)]
96    pub class: Option<String>,
97    /// Inline CSS styles.
98    #[facet(html::attribute, default)]
99    pub style: Option<String>,
100    /// Advisory title/tooltip.
101    /// Note: Named `tooltip` in Rust to avoid collision with `<title>` child element in Head.
102    /// Serializes as the `title` HTML attribute.
103    #[facet(html::attribute, default, rename = "title")]
104    pub tooltip: Option<String>,
105    /// Language of the element's content.
106    #[facet(html::attribute, default)]
107    pub lang: Option<String>,
108    /// Text directionality (ltr, rtl, auto).
109    #[facet(html::attribute, default)]
110    pub dir: Option<String>,
111    /// Whether the element is hidden.
112    #[facet(html::attribute, default)]
113    pub hidden: Option<String>,
114    /// Tab order of the element.
115    #[facet(html::attribute, default)]
116    pub tabindex: Option<String>,
117    /// Access key for the element.
118    #[facet(html::attribute, default)]
119    pub accesskey: Option<String>,
120    /// Whether the element is draggable.
121    #[facet(html::attribute, default)]
122    pub draggable: Option<String>,
123    /// Whether the element is editable.
124    #[facet(html::attribute, default)]
125    pub contenteditable: Option<String>,
126    /// Whether spellchecking is enabled.
127    #[facet(html::attribute, default)]
128    pub spellcheck: Option<String>,
129    /// Whether the element should be translated.
130    #[facet(html::attribute, default)]
131    pub translate: Option<String>,
132    /// ARIA role.
133    #[facet(html::attribute, default)]
134    pub role: Option<String>,
135
136    // Common event handlers (most frequently used)
137    /// Script to run on mouse click.
138    #[facet(html::attribute, default)]
139    pub onclick: Option<String>,
140    /// Script to run on mouse double-click.
141    #[facet(html::attribute, default)]
142    pub ondblclick: Option<String>,
143    /// Script to run when mouse button is pressed.
144    #[facet(html::attribute, default)]
145    pub onmousedown: Option<String>,
146    /// Script to run when mouse pointer moves over element.
147    #[facet(html::attribute, default)]
148    pub onmouseover: Option<String>,
149    /// Script to run when mouse pointer moves out of element.
150    #[facet(html::attribute, default)]
151    pub onmouseout: Option<String>,
152    /// Script to run when mouse button is released.
153    #[facet(html::attribute, default)]
154    pub onmouseup: Option<String>,
155    /// Script to run when mouse enters element.
156    #[facet(html::attribute, default)]
157    pub onmouseenter: Option<String>,
158    /// Script to run when mouse leaves element.
159    #[facet(html::attribute, default)]
160    pub onmouseleave: Option<String>,
161    /// Script to run when key is pressed down.
162    #[facet(html::attribute, default)]
163    pub onkeydown: Option<String>,
164    /// Script to run when key is released.
165    #[facet(html::attribute, default)]
166    pub onkeyup: Option<String>,
167    /// Script to run when element receives focus.
168    #[facet(html::attribute, default)]
169    pub onfocus: Option<String>,
170    /// Script to run when element loses focus.
171    #[facet(html::attribute, default)]
172    pub onblur: Option<String>,
173    /// Script to run when value changes.
174    #[facet(html::attribute, default)]
175    pub onchange: Option<String>,
176    /// Script to run on input.
177    #[facet(html::attribute, default)]
178    pub oninput: Option<String>,
179    /// Script to run when form is submitted.
180    #[facet(html::attribute, default)]
181    pub onsubmit: Option<String>,
182    /// Script to run when resource is loaded.
183    #[facet(html::attribute, default)]
184    pub onload: Option<String>,
185    /// Script to run when error occurs.
186    #[facet(html::attribute, default)]
187    pub onerror: Option<String>,
188    /// Script to run when element is scrolled.
189    #[facet(html::attribute, default)]
190    pub onscroll: Option<String>,
191    /// Script to run on context menu (right-click).
192    #[facet(html::attribute, default)]
193    pub oncontextmenu: Option<String>,
194
195    // Catch-all for unknown attributes (data-*, aria-*, less common events, etc.)
196    /// Extra attributes not explicitly modeled.
197    /// Includes data-* attributes, aria-* attributes, and less common event handlers.
198    /// Keys are the full attribute names as they appear in HTML.
199    /// Uses BTreeMap for deterministic serialization order.
200    #[facet(flatten, default)]
201    pub extra: std::collections::BTreeMap<String, String>,
202}
203
204// =============================================================================
205// Document Structure
206// =============================================================================
207
208/// The root HTML document element.
209#[derive(Default, Facet)]
210#[facet(rename = "html")]
211pub struct Html {
212    /// DOCTYPE declaration name (e.g., "html" for `<!DOCTYPE html>`).
213    /// When present, the serializer will emit `<!DOCTYPE {name}>` before the html element.
214    /// Set to `Some("html".to_string())` for standard HTML5 documents.
215    /// This is handled specially by the HTML parser/serializer using the "doctype" pseudo-attribute.
216    #[facet(html::attribute, default)]
217    pub doctype: Option<String>,
218    /// Global attributes.
219    #[facet(flatten, default)]
220    pub attrs: GlobalAttrs,
221    /// Document head.
222    #[facet(default)]
223    pub head: Option<Head>,
224    /// Document body.
225    #[facet(default)]
226    pub body: Option<Body>,
227}
228
229/// The document head containing metadata.
230#[derive(Default, Facet)]
231#[facet(rename = "head")]
232pub struct Head {
233    /// Global attributes.
234    #[facet(flatten, default)]
235    pub attrs: GlobalAttrs,
236    /// Document title.
237    #[facet(default)]
238    pub title: Option<Title>,
239    /// Base URL element.
240    #[facet(default)]
241    pub base: Option<Base>,
242    /// Linked resources (stylesheets, icons, etc.).
243    #[facet(html::elements, default)]
244    pub link: Vec<Link>,
245    /// Metadata elements.
246    #[facet(html::elements, default)]
247    pub meta: Vec<Meta>,
248    /// Inline styles.
249    #[facet(html::elements, default)]
250    pub style: Vec<Style>,
251    /// Scripts.
252    #[facet(html::elements, default)]
253    pub script: Vec<Script>,
254}
255
256/// The document body containing visible content.
257#[derive(Default, Facet)]
258#[facet(rename = "body")]
259pub struct Body {
260    /// Global attributes.
261    #[facet(flatten, default)]
262    pub attrs: GlobalAttrs,
263    /// Child elements (mixed content).
264    #[facet(html::elements, default)]
265    #[facet(recursive_type)]
266    pub children: Vec<FlowContent>,
267}
268
269// =============================================================================
270// Metadata Elements
271// =============================================================================
272
273/// The document title.
274#[derive(Default, Facet)]
275#[facet(rename = "title")]
276pub struct Title {
277    /// Global attributes.
278    #[facet(flatten, default)]
279    pub attrs: GlobalAttrs,
280    /// Text content of the title.
281    #[facet(html::text, default)]
282    pub text: String,
283}
284
285/// Base URL for relative URLs.
286#[derive(Default, Facet)]
287#[facet(rename = "base")]
288pub struct Base {
289    /// Global attributes.
290    #[facet(flatten, default)]
291    pub attrs: GlobalAttrs,
292    /// Base URL.
293    #[facet(html::attribute, default)]
294    pub href: Option<String>,
295    /// Default browsing context.
296    #[facet(html::attribute, default)]
297    pub target: Option<String>,
298}
299
300/// External resource link.
301#[derive(Default, Facet)]
302#[facet(rename = "link")]
303pub struct Link {
304    /// Global attributes.
305    #[facet(flatten, default)]
306    pub attrs: GlobalAttrs,
307    /// URL of the linked resource.
308    #[facet(html::attribute, default)]
309    pub href: Option<String>,
310    /// Relationship type.
311    #[facet(html::attribute, default)]
312    pub rel: Option<String>,
313    /// MIME type of the resource.
314    #[facet(html::attribute, default, rename = "type")]
315    pub type_: Option<String>,
316    /// Media query for the resource.
317    #[facet(html::attribute, default)]
318    pub media: Option<String>,
319    /// Integrity hash.
320    #[facet(html::attribute, default)]
321    pub integrity: Option<String>,
322    /// Crossorigin attribute.
323    #[facet(html::attribute, default)]
324    pub crossorigin: Option<String>,
325    /// Resource sizes (for icons).
326    #[facet(html::attribute, default)]
327    pub sizes: Option<String>,
328    /// Alternative stylesheet title.
329    #[facet(html::attribute, default, rename = "as")]
330    pub as_: Option<String>,
331}
332
333/// Document metadata.
334#[derive(Default, Facet)]
335#[facet(rename = "meta")]
336pub struct Meta {
337    /// Global attributes.
338    #[facet(flatten, default)]
339    pub attrs: GlobalAttrs,
340    /// Metadata name.
341    #[facet(html::attribute, default)]
342    pub name: Option<String>,
343    /// Metadata content.
344    #[facet(html::attribute, default)]
345    pub content: Option<String>,
346    /// Character encoding.
347    #[facet(html::attribute, default)]
348    pub charset: Option<String>,
349    /// Pragma directive.
350    #[facet(html::attribute, default, rename = "http-equiv")]
351    pub http_equiv: Option<String>,
352    /// Property (for Open Graph, etc.).
353    #[facet(html::attribute, default)]
354    pub property: Option<String>,
355}
356
357/// Inline stylesheet.
358#[derive(Default, Facet)]
359#[facet(rename = "style")]
360pub struct Style {
361    /// Global attributes.
362    #[facet(flatten, default)]
363    pub attrs: GlobalAttrs,
364    /// Media query.
365    #[facet(html::attribute, default)]
366    pub media: Option<String>,
367    /// MIME type.
368    #[facet(html::attribute, default, rename = "type")]
369    pub type_: Option<String>,
370    /// CSS content.
371    #[facet(html::text, default)]
372    pub text: String,
373}
374
375// =============================================================================
376// Section Elements
377// =============================================================================
378
379/// Page header.
380#[derive(Default, Facet)]
381#[facet(rename = "header")]
382pub struct Header {
383    /// Global attributes.
384    #[facet(flatten, default)]
385    pub attrs: GlobalAttrs,
386    /// Child elements.
387    #[facet(html::elements, default)]
388    #[facet(recursive_type)]
389    pub children: Vec<FlowContent>,
390}
391
392/// Page or section footer.
393#[derive(Default, Facet)]
394#[facet(rename = "footer")]
395pub struct Footer {
396    /// Global attributes.
397    #[facet(flatten, default)]
398    pub attrs: GlobalAttrs,
399    /// Child elements.
400    #[facet(html::elements, default)]
401    #[facet(recursive_type)]
402    pub children: Vec<FlowContent>,
403}
404
405/// Main content area.
406#[derive(Default, Facet)]
407#[facet(rename = "main")]
408pub struct Main {
409    /// Global attributes.
410    #[facet(flatten, default)]
411    pub attrs: GlobalAttrs,
412    /// Child elements.
413    #[facet(html::elements, default)]
414    #[facet(recursive_type)]
415    pub children: Vec<FlowContent>,
416}
417
418/// Self-contained article.
419#[derive(Default, Facet)]
420#[facet(rename = "article")]
421pub struct Article {
422    /// Global attributes.
423    #[facet(flatten, default)]
424    pub attrs: GlobalAttrs,
425    /// Child elements.
426    #[facet(html::elements, default)]
427    #[facet(recursive_type)]
428    pub children: Vec<FlowContent>,
429}
430
431/// Generic section.
432#[derive(Default, Facet)]
433#[facet(rename = "section")]
434pub struct Section {
435    /// Global attributes.
436    #[facet(flatten, default)]
437    pub attrs: GlobalAttrs,
438    /// Child elements.
439    #[facet(html::elements, default)]
440    #[facet(recursive_type)]
441    pub children: Vec<FlowContent>,
442}
443
444/// Navigation section.
445#[derive(Default, Facet)]
446#[facet(rename = "nav")]
447pub struct Nav {
448    /// Global attributes.
449    #[facet(flatten, default)]
450    pub attrs: GlobalAttrs,
451    /// Child elements.
452    #[facet(html::elements, default)]
453    #[facet(recursive_type)]
454    pub children: Vec<FlowContent>,
455}
456
457/// Sidebar content.
458#[derive(Default, Facet)]
459#[facet(rename = "aside")]
460pub struct Aside {
461    /// Global attributes.
462    #[facet(flatten, default)]
463    pub attrs: GlobalAttrs,
464    /// Child elements.
465    #[facet(html::elements, default)]
466    #[facet(recursive_type)]
467    pub children: Vec<FlowContent>,
468}
469
470/// Address/contact information.
471#[derive(Default, Facet)]
472#[facet(rename = "address")]
473pub struct Address {
474    /// Global attributes.
475    #[facet(flatten, default)]
476    pub attrs: GlobalAttrs,
477    /// Child elements.
478    #[facet(html::elements, default)]
479    #[facet(recursive_type)]
480    pub children: Vec<FlowContent>,
481}
482
483// =============================================================================
484// Heading Elements
485// =============================================================================
486
487/// Level 1 heading.
488#[derive(Default, Facet)]
489#[facet(rename = "h1")]
490pub struct H1 {
491    /// Global attributes.
492    #[facet(flatten, default)]
493    pub attrs: GlobalAttrs,
494    /// Child elements.
495    #[facet(html::elements, default)]
496    #[facet(recursive_type)]
497    pub children: Vec<PhrasingContent>,
498}
499
500/// Level 2 heading.
501#[derive(Default, Facet)]
502#[facet(rename = "h2")]
503pub struct H2 {
504    /// Global attributes.
505    #[facet(flatten, default)]
506    pub attrs: GlobalAttrs,
507    /// Child elements.
508    #[facet(html::elements, default)]
509    #[facet(recursive_type)]
510    pub children: Vec<PhrasingContent>,
511}
512
513/// Level 3 heading.
514#[derive(Default, Facet)]
515#[facet(rename = "h3")]
516pub struct H3 {
517    /// Global attributes.
518    #[facet(flatten, default)]
519    pub attrs: GlobalAttrs,
520    /// Child elements.
521    #[facet(html::elements, default)]
522    #[facet(recursive_type)]
523    pub children: Vec<PhrasingContent>,
524}
525
526/// Level 4 heading.
527#[derive(Default, Facet)]
528#[facet(rename = "h4")]
529pub struct H4 {
530    /// Global attributes.
531    #[facet(flatten, default)]
532    pub attrs: GlobalAttrs,
533    /// Child elements.
534    #[facet(html::elements, default)]
535    #[facet(recursive_type)]
536    pub children: Vec<PhrasingContent>,
537}
538
539/// Level 5 heading.
540#[derive(Default, Facet)]
541#[facet(rename = "h5")]
542pub struct H5 {
543    /// Global attributes.
544    #[facet(flatten, default)]
545    pub attrs: GlobalAttrs,
546    /// Child elements.
547    #[facet(html::elements, default)]
548    #[facet(recursive_type)]
549    pub children: Vec<PhrasingContent>,
550}
551
552/// Level 6 heading.
553#[derive(Default, Facet)]
554#[facet(rename = "h6")]
555pub struct H6 {
556    /// Global attributes.
557    #[facet(flatten, default)]
558    pub attrs: GlobalAttrs,
559    /// Child elements.
560    #[facet(html::elements, default)]
561    #[facet(recursive_type)]
562    pub children: Vec<PhrasingContent>,
563}
564
565// =============================================================================
566// Grouping Content
567// =============================================================================
568
569/// Paragraph.
570#[derive(Default, Facet)]
571#[facet(rename = "p")]
572pub struct P {
573    /// Global attributes.
574    #[facet(flatten, default)]
575    pub attrs: GlobalAttrs,
576    /// Child elements.
577    #[facet(html::elements, default)]
578    #[facet(recursive_type)]
579    pub children: Vec<PhrasingContent>,
580}
581
582/// Generic container (block).
583#[derive(Default, Facet)]
584#[facet(rename = "div")]
585pub struct Div {
586    /// Global attributes.
587    #[facet(flatten, default)]
588    pub attrs: GlobalAttrs,
589    /// Child elements.
590    #[facet(html::elements, default)]
591    #[facet(recursive_type)]
592    pub children: Vec<FlowContent>,
593}
594
595/// Generic container (inline).
596#[derive(Default, Facet)]
597#[facet(rename = "span")]
598pub struct Span {
599    /// Global attributes.
600    #[facet(flatten, default)]
601    pub attrs: GlobalAttrs,
602    /// Child elements.
603    #[facet(html::elements, default)]
604    #[facet(recursive_type)]
605    pub children: Vec<PhrasingContent>,
606}
607
608/// Preformatted text.
609#[derive(Default, Facet)]
610#[facet(rename = "pre")]
611pub struct Pre {
612    /// Global attributes.
613    #[facet(flatten, default)]
614    pub attrs: GlobalAttrs,
615    /// Child elements.
616    #[facet(html::elements, default)]
617    #[facet(recursive_type)]
618    pub children: Vec<PhrasingContent>,
619}
620
621/// Block quotation.
622#[derive(Default, Facet)]
623#[facet(rename = "blockquote")]
624pub struct Blockquote {
625    /// Global attributes.
626    #[facet(flatten, default)]
627    pub attrs: GlobalAttrs,
628    /// Citation URL.
629    #[facet(html::attribute, default)]
630    pub cite: Option<String>,
631    /// Child elements.
632    #[facet(html::elements, default)]
633    #[facet(recursive_type)]
634    pub children: Vec<FlowContent>,
635}
636
637/// Ordered list.
638#[derive(Default, Facet)]
639#[facet(rename = "ol")]
640pub struct Ol {
641    /// Global attributes.
642    #[facet(flatten, default)]
643    pub attrs: GlobalAttrs,
644    /// Starting number.
645    #[facet(html::attribute, default)]
646    pub start: Option<String>,
647    /// Numbering type (1, a, A, i, I).
648    #[facet(html::attribute, default, rename = "type")]
649    pub type_: Option<String>,
650    /// Reversed order.
651    #[facet(html::attribute, default)]
652    pub reversed: Option<String>,
653    /// List items.
654    #[facet(html::elements, default)]
655    pub li: Vec<Li>,
656}
657
658/// Unordered list.
659#[derive(Default, Facet)]
660#[facet(rename = "ul")]
661pub struct Ul {
662    /// Global attributes.
663    #[facet(flatten, default)]
664    pub attrs: GlobalAttrs,
665    /// List items.
666    #[facet(html::elements, default)]
667    pub li: Vec<Li>,
668}
669
670/// List item.
671#[derive(Default, Facet)]
672#[facet(rename = "li")]
673pub struct Li {
674    /// Global attributes.
675    #[facet(flatten, default)]
676    pub attrs: GlobalAttrs,
677    /// Value (for ol).
678    #[facet(html::attribute, default)]
679    pub value: Option<String>,
680    /// Child elements.
681    #[facet(html::elements, default)]
682    #[facet(recursive_type)]
683    pub children: Vec<FlowContent>,
684}
685
686/// Description list.
687#[derive(Default, Facet)]
688#[facet(rename = "dl")]
689pub struct Dl {
690    /// Global attributes.
691    #[facet(flatten, default)]
692    pub attrs: GlobalAttrs,
693    /// Terms and descriptions (mixed dt/dd).
694    #[facet(html::elements, default)]
695    pub dt: Vec<Dt>,
696    /// Descriptions.
697    #[facet(html::elements, default)]
698    pub dd: Vec<Dd>,
699}
700
701/// Description term.
702#[derive(Default, Facet)]
703#[facet(rename = "dt")]
704pub struct Dt {
705    /// Global attributes.
706    #[facet(flatten, default)]
707    pub attrs: GlobalAttrs,
708    /// Child elements.
709    #[facet(html::elements, default)]
710    #[facet(recursive_type)]
711    pub children: Vec<FlowContent>,
712}
713
714/// Description details.
715#[derive(Default, Facet)]
716#[facet(rename = "dd")]
717pub struct Dd {
718    /// Global attributes.
719    #[facet(flatten, default)]
720    pub attrs: GlobalAttrs,
721    /// Child elements.
722    #[facet(html::elements, default)]
723    #[facet(recursive_type)]
724    pub children: Vec<FlowContent>,
725}
726
727/// Figure with optional caption.
728#[derive(Default, Facet)]
729#[facet(rename = "figure")]
730pub struct Figure {
731    /// Global attributes.
732    #[facet(flatten, default)]
733    pub attrs: GlobalAttrs,
734    /// Figure caption.
735    #[facet(default)]
736    pub figcaption: Option<Figcaption>,
737    /// Child elements.
738    #[facet(html::elements, default)]
739    #[facet(recursive_type)]
740    pub children: Vec<FlowContent>,
741}
742
743/// Figure caption.
744#[derive(Default, Facet)]
745#[facet(rename = "figcaption")]
746pub struct Figcaption {
747    /// Global attributes.
748    #[facet(flatten, default)]
749    pub attrs: GlobalAttrs,
750    /// Child elements.
751    #[facet(html::elements, default)]
752    #[facet(recursive_type)]
753    pub children: Vec<FlowContent>,
754}
755
756/// Horizontal rule (thematic break).
757#[derive(Default, Facet)]
758#[facet(rename = "hr")]
759pub struct Hr {
760    /// Global attributes.
761    #[facet(flatten, default)]
762    pub attrs: GlobalAttrs,
763}
764
765// =============================================================================
766// Text-level Semantics
767// =============================================================================
768
769/// Hyperlink.
770#[derive(Default, Facet)]
771#[facet(rename = "a")]
772pub struct A {
773    /// Global attributes.
774    #[facet(flatten, default)]
775    pub attrs: GlobalAttrs,
776    /// URL.
777    #[facet(html::attribute, default)]
778    pub href: Option<String>,
779    /// Target browsing context.
780    #[facet(html::attribute, default)]
781    pub target: Option<String>,
782    /// Relationship.
783    #[facet(html::attribute, default)]
784    pub rel: Option<String>,
785    /// Download filename.
786    #[facet(html::attribute, default)]
787    pub download: Option<String>,
788    /// MIME type hint.
789    #[facet(html::attribute, default, rename = "type")]
790    pub type_: Option<String>,
791    /// Language of linked resource.
792    #[facet(html::attribute, default)]
793    pub hreflang: Option<String>,
794    /// Referrer policy.
795    #[facet(html::attribute, default)]
796    pub referrerpolicy: Option<String>,
797    /// Child elements.
798    #[facet(html::elements, default)]
799    #[facet(recursive_type)]
800    pub children: Vec<PhrasingContent>,
801}
802
803/// Emphasis.
804#[derive(Default, Facet)]
805#[facet(rename = "em")]
806pub struct Em {
807    /// Global attributes.
808    #[facet(flatten, default)]
809    pub attrs: GlobalAttrs,
810    /// Child elements.
811    #[facet(html::elements, default)]
812    #[facet(recursive_type)]
813    pub children: Vec<PhrasingContent>,
814}
815
816/// Strong importance.
817#[derive(Default, Facet)]
818#[facet(rename = "strong")]
819pub struct Strong {
820    /// Global attributes.
821    #[facet(flatten, default)]
822    pub attrs: GlobalAttrs,
823    /// Child elements.
824    #[facet(html::elements, default)]
825    #[facet(recursive_type)]
826    pub children: Vec<PhrasingContent>,
827}
828
829/// Small print.
830#[derive(Default, Facet)]
831#[facet(rename = "small")]
832pub struct Small {
833    /// Global attributes.
834    #[facet(flatten, default)]
835    pub attrs: GlobalAttrs,
836    /// Child elements.
837    #[facet(html::elements, default)]
838    #[facet(recursive_type)]
839    pub children: Vec<PhrasingContent>,
840}
841
842/// Strikethrough (no longer accurate).
843#[derive(Default, Facet)]
844#[facet(rename = "s")]
845pub struct S {
846    /// Global attributes.
847    #[facet(flatten, default)]
848    pub attrs: GlobalAttrs,
849    /// Child elements.
850    #[facet(html::elements, default)]
851    #[facet(recursive_type)]
852    pub children: Vec<PhrasingContent>,
853}
854
855/// Citation.
856#[derive(Default, Facet)]
857#[facet(rename = "cite")]
858pub struct Cite {
859    /// Global attributes.
860    #[facet(flatten, default)]
861    pub attrs: GlobalAttrs,
862    /// Child elements.
863    #[facet(html::elements, default)]
864    #[facet(recursive_type)]
865    pub children: Vec<PhrasingContent>,
866}
867
868/// Inline quotation.
869#[derive(Default, Facet)]
870#[facet(rename = "q")]
871pub struct Q {
872    /// Global attributes.
873    #[facet(flatten, default)]
874    pub attrs: GlobalAttrs,
875    /// Citation URL.
876    #[facet(html::attribute, default)]
877    pub cite: Option<String>,
878    /// Child elements.
879    #[facet(html::elements, default)]
880    #[facet(recursive_type)]
881    pub children: Vec<PhrasingContent>,
882}
883
884/// Definition term.
885#[derive(Default, Facet)]
886#[facet(rename = "dfn")]
887pub struct Dfn {
888    /// Global attributes.
889    #[facet(flatten, default)]
890    pub attrs: GlobalAttrs,
891    /// Child elements.
892    #[facet(html::elements, default)]
893    #[facet(recursive_type)]
894    pub children: Vec<PhrasingContent>,
895}
896
897/// Abbreviation.
898#[derive(Default, Facet)]
899#[facet(rename = "abbr")]
900pub struct Abbr {
901    /// Global attributes.
902    #[facet(flatten, default)]
903    pub attrs: GlobalAttrs,
904    /// Child elements.
905    #[facet(html::elements, default)]
906    #[facet(recursive_type)]
907    pub children: Vec<PhrasingContent>,
908}
909
910/// Ruby annotation (for East Asian typography).
911#[derive(Default, Facet)]
912#[facet(rename = "ruby")]
913pub struct Ruby {
914    /// Global attributes.
915    #[facet(flatten, default)]
916    pub attrs: GlobalAttrs,
917    /// Child elements.
918    #[facet(html::elements, default)]
919    #[facet(recursive_type)]
920    pub children: Vec<PhrasingContent>,
921}
922
923/// Data with machine-readable value.
924#[derive(Default, Facet)]
925#[facet(rename = "data")]
926pub struct Data {
927    /// Global attributes.
928    #[facet(flatten, default)]
929    pub attrs: GlobalAttrs,
930    /// Machine-readable value.
931    #[facet(html::attribute, default)]
932    pub value: Option<String>,
933    /// Child elements.
934    #[facet(html::elements, default)]
935    #[facet(recursive_type)]
936    pub children: Vec<PhrasingContent>,
937}
938
939/// Time.
940#[derive(Default, Facet)]
941#[facet(rename = "time")]
942pub struct Time {
943    /// Global attributes.
944    #[facet(flatten, default)]
945    pub attrs: GlobalAttrs,
946    /// Machine-readable datetime.
947    #[facet(html::attribute, default)]
948    pub datetime: Option<String>,
949    /// Child elements.
950    #[facet(html::elements, default)]
951    #[facet(recursive_type)]
952    pub children: Vec<PhrasingContent>,
953}
954
955/// Code fragment.
956#[derive(Default, Facet)]
957#[facet(rename = "code")]
958pub struct Code {
959    /// Global attributes.
960    #[facet(flatten, default)]
961    pub attrs: GlobalAttrs,
962    /// Child elements.
963    #[facet(html::elements, default)]
964    #[facet(recursive_type)]
965    pub children: Vec<PhrasingContent>,
966}
967
968/// Variable.
969#[derive(Default, Facet)]
970#[facet(rename = "var")]
971pub struct Var {
972    /// Global attributes.
973    #[facet(flatten, default)]
974    pub attrs: GlobalAttrs,
975    /// Child elements.
976    #[facet(html::elements, default)]
977    #[facet(recursive_type)]
978    pub children: Vec<PhrasingContent>,
979}
980
981/// Sample output.
982#[derive(Default, Facet)]
983#[facet(rename = "samp")]
984pub struct Samp {
985    /// Global attributes.
986    #[facet(flatten, default)]
987    pub attrs: GlobalAttrs,
988    /// Child elements.
989    #[facet(html::elements, default)]
990    #[facet(recursive_type)]
991    pub children: Vec<PhrasingContent>,
992}
993
994/// Keyboard input.
995#[derive(Default, Facet)]
996#[facet(rename = "kbd")]
997pub struct Kbd {
998    /// Global attributes.
999    #[facet(flatten, default)]
1000    pub attrs: GlobalAttrs,
1001    /// Child elements.
1002    #[facet(html::elements, default)]
1003    #[facet(recursive_type)]
1004    pub children: Vec<PhrasingContent>,
1005}
1006
1007/// Subscript.
1008#[derive(Default, Facet)]
1009#[facet(rename = "sub")]
1010pub struct Sub {
1011    /// Global attributes.
1012    #[facet(flatten, default)]
1013    pub attrs: GlobalAttrs,
1014    /// Child elements.
1015    #[facet(html::elements, default)]
1016    #[facet(recursive_type)]
1017    pub children: Vec<PhrasingContent>,
1018}
1019
1020/// Superscript.
1021#[derive(Default, Facet)]
1022#[facet(rename = "sup")]
1023pub struct Sup {
1024    /// Global attributes.
1025    #[facet(flatten, default)]
1026    pub attrs: GlobalAttrs,
1027    /// Child elements.
1028    #[facet(html::elements, default)]
1029    #[facet(recursive_type)]
1030    pub children: Vec<PhrasingContent>,
1031}
1032
1033/// Italic.
1034#[derive(Default, Facet)]
1035#[facet(rename = "i")]
1036pub struct I {
1037    /// Global attributes.
1038    #[facet(flatten, default)]
1039    pub attrs: GlobalAttrs,
1040    /// Child elements.
1041    #[facet(html::elements, default)]
1042    #[facet(recursive_type)]
1043    pub children: Vec<PhrasingContent>,
1044}
1045
1046/// Bold.
1047#[derive(Default, Facet)]
1048#[facet(rename = "b")]
1049pub struct B {
1050    /// Global attributes.
1051    #[facet(flatten, default)]
1052    pub attrs: GlobalAttrs,
1053    /// Child elements.
1054    #[facet(html::elements, default)]
1055    #[facet(recursive_type)]
1056    pub children: Vec<PhrasingContent>,
1057}
1058
1059/// Underline.
1060#[derive(Default, Facet)]
1061#[facet(rename = "u")]
1062pub struct U {
1063    /// Global attributes.
1064    #[facet(flatten, default)]
1065    pub attrs: GlobalAttrs,
1066    /// Child elements.
1067    #[facet(html::elements, default)]
1068    #[facet(recursive_type)]
1069    pub children: Vec<PhrasingContent>,
1070}
1071
1072/// Highlighted text.
1073#[derive(Default, Facet)]
1074#[facet(rename = "mark")]
1075pub struct Mark {
1076    /// Global attributes.
1077    #[facet(flatten, default)]
1078    pub attrs: GlobalAttrs,
1079    /// Child elements.
1080    #[facet(html::elements, default)]
1081    #[facet(recursive_type)]
1082    pub children: Vec<PhrasingContent>,
1083}
1084
1085/// Bidirectional isolation.
1086#[derive(Default, Facet)]
1087#[facet(rename = "bdi")]
1088pub struct Bdi {
1089    /// Global attributes.
1090    #[facet(flatten, default)]
1091    pub attrs: GlobalAttrs,
1092    /// Child elements.
1093    #[facet(html::elements, default)]
1094    #[facet(recursive_type)]
1095    pub children: Vec<PhrasingContent>,
1096}
1097
1098/// Bidirectional override.
1099#[derive(Default, Facet)]
1100#[facet(rename = "bdo")]
1101pub struct Bdo {
1102    /// Global attributes.
1103    #[facet(flatten, default)]
1104    pub attrs: GlobalAttrs,
1105    /// Child elements.
1106    #[facet(html::elements, default)]
1107    #[facet(recursive_type)]
1108    pub children: Vec<PhrasingContent>,
1109}
1110
1111/// Line break.
1112#[derive(Default, Facet)]
1113#[facet(rename = "br")]
1114pub struct Br {
1115    /// Global attributes.
1116    #[facet(flatten, default)]
1117    pub attrs: GlobalAttrs,
1118}
1119
1120/// Word break opportunity.
1121#[derive(Default, Facet)]
1122#[facet(rename = "wbr")]
1123pub struct Wbr {
1124    /// Global attributes.
1125    #[facet(flatten, default)]
1126    pub attrs: GlobalAttrs,
1127}
1128
1129// =============================================================================
1130// Embedded Content
1131// =============================================================================
1132
1133/// Image.
1134#[derive(Default, Facet)]
1135#[facet(rename = "img")]
1136pub struct Img {
1137    /// Global attributes.
1138    #[facet(flatten, default)]
1139    pub attrs: GlobalAttrs,
1140    /// Image URL.
1141    #[facet(html::attribute, default)]
1142    pub src: Option<String>,
1143    /// Alternative text.
1144    #[facet(html::attribute, default)]
1145    pub alt: Option<String>,
1146    /// Width.
1147    #[facet(html::attribute, default)]
1148    pub width: Option<String>,
1149    /// Height.
1150    #[facet(html::attribute, default)]
1151    pub height: Option<String>,
1152    /// Srcset for responsive images.
1153    #[facet(html::attribute, default)]
1154    pub srcset: Option<String>,
1155    /// Sizes attribute.
1156    #[facet(html::attribute, default)]
1157    pub sizes: Option<String>,
1158    /// Loading behavior.
1159    #[facet(html::attribute, default)]
1160    pub loading: Option<String>,
1161    /// Decoding hint.
1162    #[facet(html::attribute, default)]
1163    pub decoding: Option<String>,
1164    /// Crossorigin.
1165    #[facet(html::attribute, default)]
1166    pub crossorigin: Option<String>,
1167    /// Referrer policy.
1168    #[facet(html::attribute, default)]
1169    pub referrerpolicy: Option<String>,
1170    /// Usemap reference.
1171    #[facet(html::attribute, default)]
1172    pub usemap: Option<String>,
1173    /// Whether this is a server-side image map.
1174    #[facet(html::attribute, default)]
1175    pub ismap: Option<String>,
1176}
1177
1178/// Inline frame.
1179#[derive(Default, Facet)]
1180#[facet(rename = "iframe")]
1181pub struct Iframe {
1182    /// Global attributes.
1183    #[facet(flatten, default)]
1184    pub attrs: GlobalAttrs,
1185    /// URL.
1186    #[facet(html::attribute, default)]
1187    pub src: Option<String>,
1188    /// Srcdoc content.
1189    #[facet(html::attribute, default)]
1190    pub srcdoc: Option<String>,
1191    /// Frame name.
1192    #[facet(html::attribute, default)]
1193    pub name: Option<String>,
1194    /// Width.
1195    #[facet(html::attribute, default)]
1196    pub width: Option<String>,
1197    /// Height.
1198    #[facet(html::attribute, default)]
1199    pub height: Option<String>,
1200    /// Sandbox restrictions.
1201    #[facet(html::attribute, default)]
1202    pub sandbox: Option<String>,
1203    /// Feature policy.
1204    #[facet(html::attribute, default)]
1205    pub allow: Option<String>,
1206    /// Fullscreen allowed.
1207    #[facet(html::attribute, default)]
1208    pub allowfullscreen: Option<String>,
1209    /// Loading behavior.
1210    #[facet(html::attribute, default)]
1211    pub loading: Option<String>,
1212    /// Referrer policy.
1213    #[facet(html::attribute, default)]
1214    pub referrerpolicy: Option<String>,
1215}
1216
1217/// Embedded object.
1218#[derive(Default, Facet)]
1219#[facet(rename = "object")]
1220pub struct Object {
1221    /// Global attributes.
1222    #[facet(flatten, default)]
1223    pub attrs: GlobalAttrs,
1224    /// Data URL.
1225    #[facet(html::attribute, default)]
1226    pub data: Option<String>,
1227    /// MIME type.
1228    #[facet(html::attribute, default, rename = "type")]
1229    pub type_: Option<String>,
1230    /// Name.
1231    #[facet(html::attribute, default)]
1232    pub name: Option<String>,
1233    /// Width.
1234    #[facet(html::attribute, default)]
1235    pub width: Option<String>,
1236    /// Height.
1237    #[facet(html::attribute, default)]
1238    pub height: Option<String>,
1239    /// Usemap reference.
1240    #[facet(html::attribute, default)]
1241    pub usemap: Option<String>,
1242    /// Fallback content.
1243    #[facet(html::elements, default)]
1244    #[facet(recursive_type)]
1245    pub children: Vec<FlowContent>,
1246}
1247
1248/// Video player.
1249#[derive(Default, Facet)]
1250#[facet(rename = "video")]
1251pub struct Video {
1252    /// Global attributes.
1253    #[facet(flatten, default)]
1254    pub attrs: GlobalAttrs,
1255    /// Video URL.
1256    #[facet(html::attribute, default)]
1257    pub src: Option<String>,
1258    /// Poster image.
1259    #[facet(html::attribute, default)]
1260    pub poster: Option<String>,
1261    /// Width.
1262    #[facet(html::attribute, default)]
1263    pub width: Option<String>,
1264    /// Height.
1265    #[facet(html::attribute, default)]
1266    pub height: Option<String>,
1267    /// Show controls.
1268    #[facet(html::attribute, default)]
1269    pub controls: Option<String>,
1270    /// Autoplay.
1271    #[facet(html::attribute, default)]
1272    pub autoplay: Option<String>,
1273    /// Loop playback.
1274    #[facet(html::attribute, default, rename = "loop")]
1275    pub loop_: Option<String>,
1276    /// Muted by default.
1277    #[facet(html::attribute, default)]
1278    pub muted: Option<String>,
1279    /// Preload behavior.
1280    #[facet(html::attribute, default)]
1281    pub preload: Option<String>,
1282    /// Plays inline (iOS).
1283    #[facet(html::attribute, default)]
1284    pub playsinline: Option<String>,
1285    /// Crossorigin.
1286    #[facet(html::attribute, default)]
1287    pub crossorigin: Option<String>,
1288    /// Source elements.
1289    #[facet(html::elements, default)]
1290    pub source: Vec<Source>,
1291    /// Track elements.
1292    #[facet(html::elements, default)]
1293    pub track: Vec<Track>,
1294}
1295
1296/// Audio player.
1297#[derive(Default, Facet)]
1298#[facet(rename = "audio")]
1299pub struct Audio {
1300    /// Global attributes.
1301    #[facet(flatten, default)]
1302    pub attrs: GlobalAttrs,
1303    /// Audio URL.
1304    #[facet(html::attribute, default)]
1305    pub src: Option<String>,
1306    /// Show controls.
1307    #[facet(html::attribute, default)]
1308    pub controls: Option<String>,
1309    /// Autoplay.
1310    #[facet(html::attribute, default)]
1311    pub autoplay: Option<String>,
1312    /// Loop playback.
1313    #[facet(html::attribute, default, rename = "loop")]
1314    pub loop_: Option<String>,
1315    /// Muted by default.
1316    #[facet(html::attribute, default)]
1317    pub muted: Option<String>,
1318    /// Preload behavior.
1319    #[facet(html::attribute, default)]
1320    pub preload: Option<String>,
1321    /// Crossorigin.
1322    #[facet(html::attribute, default)]
1323    pub crossorigin: Option<String>,
1324    /// Source elements.
1325    #[facet(html::elements, default)]
1326    pub source: Vec<Source>,
1327}
1328
1329/// Media source.
1330#[derive(Default, Facet)]
1331#[facet(rename = "source")]
1332pub struct Source {
1333    /// Global attributes.
1334    #[facet(flatten, default)]
1335    pub attrs: GlobalAttrs,
1336    /// URL.
1337    #[facet(html::attribute, default)]
1338    pub src: Option<String>,
1339    /// MIME type.
1340    #[facet(html::attribute, default, rename = "type")]
1341    pub type_: Option<String>,
1342    /// Srcset (for picture).
1343    #[facet(html::attribute, default)]
1344    pub srcset: Option<String>,
1345    /// Sizes.
1346    #[facet(html::attribute, default)]
1347    pub sizes: Option<String>,
1348    /// Media query.
1349    #[facet(html::attribute, default)]
1350    pub media: Option<String>,
1351    /// Width.
1352    #[facet(html::attribute, default)]
1353    pub width: Option<String>,
1354    /// Height.
1355    #[facet(html::attribute, default)]
1356    pub height: Option<String>,
1357}
1358
1359/// Text track for video/audio.
1360#[derive(Default, Facet)]
1361#[facet(rename = "track")]
1362pub struct Track {
1363    /// Global attributes.
1364    #[facet(flatten, default)]
1365    pub attrs: GlobalAttrs,
1366    /// URL.
1367    #[facet(html::attribute, default)]
1368    pub src: Option<String>,
1369    /// Track kind.
1370    #[facet(html::attribute, default)]
1371    pub kind: Option<String>,
1372    /// Language.
1373    #[facet(html::attribute, default)]
1374    pub srclang: Option<String>,
1375    /// Label.
1376    #[facet(html::attribute, default)]
1377    pub label: Option<String>,
1378    /// Default track.
1379    #[facet(html::attribute, default)]
1380    pub default: Option<String>,
1381}
1382
1383/// Picture element for art direction.
1384#[derive(Default, Facet)]
1385#[facet(rename = "picture")]
1386pub struct Picture {
1387    /// Global attributes.
1388    #[facet(flatten, default)]
1389    pub attrs: GlobalAttrs,
1390    /// Source elements.
1391    #[facet(html::elements, default)]
1392    pub source: Vec<Source>,
1393    /// Fallback image.
1394    #[facet(default)]
1395    pub img: Option<Img>,
1396}
1397
1398/// Canvas for graphics.
1399#[derive(Default, Facet)]
1400#[facet(rename = "canvas")]
1401pub struct Canvas {
1402    /// Global attributes.
1403    #[facet(flatten, default)]
1404    pub attrs: GlobalAttrs,
1405    /// Width.
1406    #[facet(html::attribute, default)]
1407    pub width: Option<String>,
1408    /// Height.
1409    #[facet(html::attribute, default)]
1410    pub height: Option<String>,
1411    /// Fallback content.
1412    #[facet(html::elements, default)]
1413    #[facet(recursive_type)]
1414    pub children: Vec<FlowContent>,
1415}
1416
1417/// SVG root element (simplified).
1418#[derive(Default, Facet)]
1419#[facet(rename = "svg")]
1420pub struct Svg {
1421    /// Global attributes.
1422    #[facet(flatten, default)]
1423    pub attrs: GlobalAttrs,
1424    /// Width.
1425    #[facet(html::attribute, default)]
1426    pub width: Option<String>,
1427    /// Height.
1428    #[facet(html::attribute, default)]
1429    pub height: Option<String>,
1430    /// ViewBox.
1431    #[facet(html::attribute, default, rename = "viewBox")]
1432    pub view_box: Option<String>,
1433    /// Xmlns.
1434    #[facet(html::attribute, default)]
1435    pub xmlns: Option<String>,
1436    /// Preserve aspect ratio.
1437    #[facet(html::attribute, default, rename = "preserveAspectRatio")]
1438    pub preserve_aspect_ratio: Option<String>,
1439}
1440
1441// =============================================================================
1442// Table Elements
1443// =============================================================================
1444
1445/// Table.
1446#[derive(Default, Facet)]
1447#[facet(rename = "table")]
1448pub struct Table {
1449    /// Global attributes.
1450    #[facet(flatten, default)]
1451    pub attrs: GlobalAttrs,
1452    /// Caption.
1453    #[facet(default)]
1454    pub caption: Option<Caption>,
1455    /// Column groups.
1456    #[facet(html::elements, default)]
1457    pub colgroup: Vec<Colgroup>,
1458    /// Table head.
1459    #[facet(default)]
1460    pub thead: Option<Thead>,
1461    /// Table body sections.
1462    #[facet(html::elements, default)]
1463    pub tbody: Vec<Tbody>,
1464    /// Table foot.
1465    #[facet(default)]
1466    pub tfoot: Option<Tfoot>,
1467    /// Direct rows (when no thead/tbody/tfoot).
1468    #[facet(html::elements, default)]
1469    pub tr: Vec<Tr>,
1470}
1471
1472/// Table caption.
1473#[derive(Default, Facet)]
1474#[facet(rename = "caption")]
1475pub struct Caption {
1476    /// Global attributes.
1477    #[facet(flatten, default)]
1478    pub attrs: GlobalAttrs,
1479    /// Child elements.
1480    #[facet(html::elements, default)]
1481    #[facet(recursive_type)]
1482    pub children: Vec<FlowContent>,
1483}
1484
1485/// Column group.
1486#[derive(Default, Facet)]
1487#[facet(rename = "colgroup")]
1488pub struct Colgroup {
1489    /// Global attributes.
1490    #[facet(flatten, default)]
1491    pub attrs: GlobalAttrs,
1492    /// Number of columns spanned.
1493    #[facet(html::attribute, default)]
1494    pub span: Option<String>,
1495    /// Column definitions.
1496    #[facet(html::elements, default)]
1497    pub col: Vec<Col>,
1498}
1499
1500/// Table column.
1501#[derive(Default, Facet)]
1502#[facet(rename = "col")]
1503pub struct Col {
1504    /// Global attributes.
1505    #[facet(flatten, default)]
1506    pub attrs: GlobalAttrs,
1507    /// Number of columns spanned.
1508    #[facet(html::attribute, default)]
1509    pub span: Option<String>,
1510}
1511
1512/// Table head.
1513#[derive(Default, Facet)]
1514#[facet(rename = "thead")]
1515pub struct Thead {
1516    /// Global attributes.
1517    #[facet(flatten, default)]
1518    pub attrs: GlobalAttrs,
1519    /// Rows.
1520    #[facet(html::elements, default)]
1521    pub tr: Vec<Tr>,
1522}
1523
1524/// Table body.
1525#[derive(Default, Facet)]
1526#[facet(rename = "tbody")]
1527pub struct Tbody {
1528    /// Global attributes.
1529    #[facet(flatten, default)]
1530    pub attrs: GlobalAttrs,
1531    /// Rows.
1532    #[facet(html::elements, default)]
1533    pub tr: Vec<Tr>,
1534}
1535
1536/// Table foot.
1537#[derive(Default, Facet)]
1538#[facet(rename = "tfoot")]
1539pub struct Tfoot {
1540    /// Global attributes.
1541    #[facet(flatten, default)]
1542    pub attrs: GlobalAttrs,
1543    /// Rows.
1544    #[facet(html::elements, default)]
1545    pub tr: Vec<Tr>,
1546}
1547
1548/// Table row.
1549#[derive(Default, Facet)]
1550#[facet(rename = "tr")]
1551pub struct Tr {
1552    /// Global attributes.
1553    #[facet(flatten, default)]
1554    pub attrs: GlobalAttrs,
1555    /// Header cells.
1556    #[facet(html::elements, default)]
1557    pub th: Vec<Th>,
1558    /// Data cells.
1559    #[facet(html::elements, default)]
1560    pub td: Vec<Td>,
1561}
1562
1563/// Table header cell.
1564#[derive(Default, Facet)]
1565#[facet(rename = "th")]
1566pub struct Th {
1567    /// Global attributes.
1568    #[facet(flatten, default)]
1569    pub attrs: GlobalAttrs,
1570    /// Number of columns spanned.
1571    #[facet(html::attribute, default)]
1572    pub colspan: Option<String>,
1573    /// Number of rows spanned.
1574    #[facet(html::attribute, default)]
1575    pub rowspan: Option<String>,
1576    /// Header scope.
1577    #[facet(html::attribute, default)]
1578    pub scope: Option<String>,
1579    /// Headers this cell relates to.
1580    #[facet(html::attribute, default)]
1581    pub headers: Option<String>,
1582    /// Abbreviation.
1583    #[facet(html::attribute, default)]
1584    pub abbr: Option<String>,
1585    /// Child elements.
1586    #[facet(html::elements, default)]
1587    #[facet(recursive_type)]
1588    pub children: Vec<FlowContent>,
1589}
1590
1591/// Table data cell.
1592#[derive(Default, Facet)]
1593#[facet(rename = "td")]
1594pub struct Td {
1595    /// Global attributes.
1596    #[facet(flatten, default)]
1597    pub attrs: GlobalAttrs,
1598    /// Number of columns spanned.
1599    #[facet(html::attribute, default)]
1600    pub colspan: Option<String>,
1601    /// Number of rows spanned.
1602    #[facet(html::attribute, default)]
1603    pub rowspan: Option<String>,
1604    /// Headers this cell relates to.
1605    #[facet(html::attribute, default)]
1606    pub headers: Option<String>,
1607    /// Child elements.
1608    #[facet(html::elements, default)]
1609    #[facet(recursive_type)]
1610    pub children: Vec<FlowContent>,
1611}
1612
1613// =============================================================================
1614// Form Elements
1615// =============================================================================
1616
1617/// Form.
1618#[derive(Default, Facet)]
1619#[facet(rename = "form")]
1620pub struct Form {
1621    /// Global attributes.
1622    #[facet(flatten, default)]
1623    pub attrs: GlobalAttrs,
1624    /// Form action URL.
1625    #[facet(html::attribute, default)]
1626    pub action: Option<String>,
1627    /// HTTP method.
1628    #[facet(html::attribute, default)]
1629    pub method: Option<String>,
1630    /// Encoding type.
1631    #[facet(html::attribute, default)]
1632    pub enctype: Option<String>,
1633    /// Target.
1634    #[facet(html::attribute, default)]
1635    pub target: Option<String>,
1636    /// Form name.
1637    #[facet(html::attribute, default)]
1638    pub name: Option<String>,
1639    /// Autocomplete.
1640    #[facet(html::attribute, default)]
1641    pub autocomplete: Option<String>,
1642    /// Disable validation.
1643    #[facet(html::attribute, default)]
1644    pub novalidate: Option<String>,
1645    /// Accept-charset.
1646    #[facet(html::attribute, default, rename = "accept-charset")]
1647    pub accept_charset: Option<String>,
1648    /// Child elements.
1649    #[facet(html::elements, default)]
1650    #[facet(recursive_type)]
1651    pub children: Vec<FlowContent>,
1652}
1653
1654/// Input control.
1655#[derive(Default, Facet)]
1656#[facet(rename = "input")]
1657pub struct Input {
1658    /// Global attributes.
1659    #[facet(flatten, default)]
1660    pub attrs: GlobalAttrs,
1661    /// Input type.
1662    #[facet(html::attribute, default, rename = "type")]
1663    pub type_: Option<String>,
1664    /// Name.
1665    #[facet(html::attribute, default)]
1666    pub name: Option<String>,
1667    /// Value.
1668    #[facet(html::attribute, default)]
1669    pub value: Option<String>,
1670    /// Placeholder.
1671    #[facet(html::attribute, default)]
1672    pub placeholder: Option<String>,
1673    /// Required.
1674    #[facet(html::attribute, default)]
1675    pub required: Option<String>,
1676    /// Disabled.
1677    #[facet(html::attribute, default)]
1678    pub disabled: Option<String>,
1679    /// Readonly.
1680    #[facet(html::attribute, default)]
1681    pub readonly: Option<String>,
1682    /// Checked (for checkboxes/radios).
1683    #[facet(html::attribute, default)]
1684    pub checked: Option<String>,
1685    /// Autocomplete.
1686    #[facet(html::attribute, default)]
1687    pub autocomplete: Option<String>,
1688    /// Autofocus.
1689    #[facet(html::attribute, default)]
1690    pub autofocus: Option<String>,
1691    /// Min value.
1692    #[facet(html::attribute, default)]
1693    pub min: Option<String>,
1694    /// Max value.
1695    #[facet(html::attribute, default)]
1696    pub max: Option<String>,
1697    /// Step.
1698    #[facet(html::attribute, default)]
1699    pub step: Option<String>,
1700    /// Pattern.
1701    #[facet(html::attribute, default)]
1702    pub pattern: Option<String>,
1703    /// Size.
1704    #[facet(html::attribute, default)]
1705    pub size: Option<String>,
1706    /// Maxlength.
1707    #[facet(html::attribute, default)]
1708    pub maxlength: Option<String>,
1709    /// Minlength.
1710    #[facet(html::attribute, default)]
1711    pub minlength: Option<String>,
1712    /// Multiple values allowed.
1713    #[facet(html::attribute, default)]
1714    pub multiple: Option<String>,
1715    /// Accept (for file inputs).
1716    #[facet(html::attribute, default)]
1717    pub accept: Option<String>,
1718    /// Alt text (for image inputs).
1719    #[facet(html::attribute, default)]
1720    pub alt: Option<String>,
1721    /// Src (for image inputs).
1722    #[facet(html::attribute, default)]
1723    pub src: Option<String>,
1724    /// Width (for image inputs).
1725    #[facet(html::attribute, default)]
1726    pub width: Option<String>,
1727    /// Height (for image inputs).
1728    #[facet(html::attribute, default)]
1729    pub height: Option<String>,
1730    /// List datalist reference.
1731    #[facet(html::attribute, default)]
1732    pub list: Option<String>,
1733    /// Form override.
1734    #[facet(html::attribute, default)]
1735    pub form: Option<String>,
1736    /// Form action override.
1737    #[facet(html::attribute, default)]
1738    pub formaction: Option<String>,
1739    /// Form method override.
1740    #[facet(html::attribute, default)]
1741    pub formmethod: Option<String>,
1742    /// Form enctype override.
1743    #[facet(html::attribute, default)]
1744    pub formenctype: Option<String>,
1745    /// Form target override.
1746    #[facet(html::attribute, default)]
1747    pub formtarget: Option<String>,
1748    /// Form novalidate override.
1749    #[facet(html::attribute, default)]
1750    pub formnovalidate: Option<String>,
1751}
1752
1753/// Button.
1754#[derive(Default, Facet)]
1755#[facet(rename = "button")]
1756pub struct Button {
1757    /// Global attributes.
1758    #[facet(flatten, default)]
1759    pub attrs: GlobalAttrs,
1760    /// Button type.
1761    #[facet(html::attribute, default, rename = "type")]
1762    pub type_: Option<String>,
1763    /// Name.
1764    #[facet(html::attribute, default)]
1765    pub name: Option<String>,
1766    /// Value.
1767    #[facet(html::attribute, default)]
1768    pub value: Option<String>,
1769    /// Disabled.
1770    #[facet(html::attribute, default)]
1771    pub disabled: Option<String>,
1772    /// Autofocus.
1773    #[facet(html::attribute, default)]
1774    pub autofocus: Option<String>,
1775    /// Form override.
1776    #[facet(html::attribute, default)]
1777    pub form: Option<String>,
1778    /// Form action override.
1779    #[facet(html::attribute, default)]
1780    pub formaction: Option<String>,
1781    /// Form method override.
1782    #[facet(html::attribute, default)]
1783    pub formmethod: Option<String>,
1784    /// Form enctype override.
1785    #[facet(html::attribute, default)]
1786    pub formenctype: Option<String>,
1787    /// Form target override.
1788    #[facet(html::attribute, default)]
1789    pub formtarget: Option<String>,
1790    /// Form novalidate override.
1791    #[facet(html::attribute, default)]
1792    pub formnovalidate: Option<String>,
1793    /// Child elements.
1794    #[facet(html::elements, default)]
1795    #[facet(recursive_type)]
1796    pub children: Vec<PhrasingContent>,
1797}
1798
1799/// Select dropdown.
1800#[derive(Default, Facet)]
1801#[facet(rename = "select")]
1802pub struct Select {
1803    /// Global attributes.
1804    #[facet(flatten, default)]
1805    pub attrs: GlobalAttrs,
1806    /// Name.
1807    #[facet(html::attribute, default)]
1808    pub name: Option<String>,
1809    /// Multiple selection.
1810    #[facet(html::attribute, default)]
1811    pub multiple: Option<String>,
1812    /// Size (visible options).
1813    #[facet(html::attribute, default)]
1814    pub size: Option<String>,
1815    /// Required.
1816    #[facet(html::attribute, default)]
1817    pub required: Option<String>,
1818    /// Disabled.
1819    #[facet(html::attribute, default)]
1820    pub disabled: Option<String>,
1821    /// Autofocus.
1822    #[facet(html::attribute, default)]
1823    pub autofocus: Option<String>,
1824    /// Autocomplete.
1825    #[facet(html::attribute, default)]
1826    pub autocomplete: Option<String>,
1827    /// Form override.
1828    #[facet(html::attribute, default)]
1829    pub form: Option<String>,
1830    /// Options.
1831    #[facet(html::elements, default)]
1832    pub option: Vec<OptionElement>,
1833    /// Option groups.
1834    #[facet(html::elements, default)]
1835    pub optgroup: Vec<Optgroup>,
1836}
1837
1838/// Option in a select.
1839#[derive(Default, Facet)]
1840#[facet(rename = "option")]
1841pub struct OptionElement {
1842    /// Global attributes.
1843    #[facet(flatten, default)]
1844    pub attrs: GlobalAttrs,
1845    /// Value.
1846    #[facet(html::attribute, default)]
1847    pub value: Option<String>,
1848    /// Selected.
1849    #[facet(html::attribute, default)]
1850    pub selected: Option<String>,
1851    /// Disabled.
1852    #[facet(html::attribute, default)]
1853    pub disabled: Option<String>,
1854    /// Label.
1855    #[facet(html::attribute, default)]
1856    pub label: Option<String>,
1857    /// Text content.
1858    #[facet(html::text, default)]
1859    pub text: String,
1860}
1861
1862/// Option group.
1863#[derive(Default, Facet)]
1864#[facet(rename = "optgroup")]
1865pub struct Optgroup {
1866    /// Global attributes.
1867    #[facet(flatten, default)]
1868    pub attrs: GlobalAttrs,
1869    /// Label.
1870    #[facet(html::attribute, default)]
1871    pub label: Option<String>,
1872    /// Disabled.
1873    #[facet(html::attribute, default)]
1874    pub disabled: Option<String>,
1875    /// Options.
1876    #[facet(html::elements, default)]
1877    pub option: Vec<OptionElement>,
1878}
1879
1880/// Textarea.
1881#[derive(Default, Facet)]
1882#[facet(rename = "textarea")]
1883pub struct Textarea {
1884    /// Global attributes.
1885    #[facet(flatten, default)]
1886    pub attrs: GlobalAttrs,
1887    /// Name.
1888    #[facet(html::attribute, default)]
1889    pub name: Option<String>,
1890    /// Rows.
1891    #[facet(html::attribute, default)]
1892    pub rows: Option<String>,
1893    /// Cols.
1894    #[facet(html::attribute, default)]
1895    pub cols: Option<String>,
1896    /// Placeholder.
1897    #[facet(html::attribute, default)]
1898    pub placeholder: Option<String>,
1899    /// Required.
1900    #[facet(html::attribute, default)]
1901    pub required: Option<String>,
1902    /// Disabled.
1903    #[facet(html::attribute, default)]
1904    pub disabled: Option<String>,
1905    /// Readonly.
1906    #[facet(html::attribute, default)]
1907    pub readonly: Option<String>,
1908    /// Autofocus.
1909    #[facet(html::attribute, default)]
1910    pub autofocus: Option<String>,
1911    /// Autocomplete.
1912    #[facet(html::attribute, default)]
1913    pub autocomplete: Option<String>,
1914    /// Maxlength.
1915    #[facet(html::attribute, default)]
1916    pub maxlength: Option<String>,
1917    /// Minlength.
1918    #[facet(html::attribute, default)]
1919    pub minlength: Option<String>,
1920    /// Wrap.
1921    #[facet(html::attribute, default)]
1922    pub wrap: Option<String>,
1923    /// Form override.
1924    #[facet(html::attribute, default)]
1925    pub form: Option<String>,
1926    /// Text content.
1927    #[facet(html::text, default)]
1928    pub text: String,
1929}
1930
1931/// Form label.
1932#[derive(Default, Facet)]
1933#[facet(rename = "label")]
1934pub struct Label {
1935    /// Global attributes.
1936    #[facet(flatten, default)]
1937    pub attrs: GlobalAttrs,
1938    /// Associated control ID.
1939    #[facet(html::attribute, default, rename = "for")]
1940    pub for_: Option<String>,
1941    /// Child elements.
1942    #[facet(html::elements, default)]
1943    #[facet(recursive_type)]
1944    pub children: Vec<PhrasingContent>,
1945}
1946
1947/// Fieldset grouping.
1948#[derive(Default, Facet)]
1949#[facet(rename = "fieldset")]
1950pub struct Fieldset {
1951    /// Global attributes.
1952    #[facet(flatten, default)]
1953    pub attrs: GlobalAttrs,
1954    /// Name.
1955    #[facet(html::attribute, default)]
1956    pub name: Option<String>,
1957    /// Disabled.
1958    #[facet(html::attribute, default)]
1959    pub disabled: Option<String>,
1960    /// Form override.
1961    #[facet(html::attribute, default)]
1962    pub form: Option<String>,
1963    /// Legend.
1964    #[facet(default)]
1965    pub legend: Option<Legend>,
1966    /// Child elements.
1967    #[facet(html::elements, default)]
1968    #[facet(recursive_type)]
1969    pub children: Vec<FlowContent>,
1970}
1971
1972/// Fieldset legend.
1973#[derive(Default, Facet)]
1974#[facet(rename = "legend")]
1975pub struct Legend {
1976    /// Global attributes.
1977    #[facet(flatten, default)]
1978    pub attrs: GlobalAttrs,
1979    /// Child elements.
1980    #[facet(html::elements, default)]
1981    #[facet(recursive_type)]
1982    pub children: Vec<PhrasingContent>,
1983}
1984
1985/// Datalist.
1986#[derive(Default, Facet)]
1987#[facet(rename = "datalist")]
1988pub struct Datalist {
1989    /// Global attributes.
1990    #[facet(flatten, default)]
1991    pub attrs: GlobalAttrs,
1992    /// Options.
1993    #[facet(html::elements, default)]
1994    pub option: Vec<OptionElement>,
1995}
1996
1997/// Output.
1998#[derive(Default, Facet)]
1999#[facet(rename = "output")]
2000pub struct Output {
2001    /// Global attributes.
2002    #[facet(flatten, default)]
2003    pub attrs: GlobalAttrs,
2004    /// Associated controls.
2005    #[facet(html::attribute, default, rename = "for")]
2006    pub for_: Option<String>,
2007    /// Name.
2008    #[facet(html::attribute, default)]
2009    pub name: Option<String>,
2010    /// Form override.
2011    #[facet(html::attribute, default)]
2012    pub form: Option<String>,
2013    /// Child elements.
2014    #[facet(html::elements, default)]
2015    #[facet(recursive_type)]
2016    pub children: Vec<PhrasingContent>,
2017}
2018
2019/// Progress indicator.
2020#[derive(Default, Facet)]
2021#[facet(rename = "progress")]
2022pub struct Progress {
2023    /// Global attributes.
2024    #[facet(flatten, default)]
2025    pub attrs: GlobalAttrs,
2026    /// Current value.
2027    #[facet(html::attribute, default)]
2028    pub value: Option<String>,
2029    /// Maximum value.
2030    #[facet(html::attribute, default)]
2031    pub max: Option<String>,
2032    /// Fallback content.
2033    #[facet(html::elements, default)]
2034    #[facet(recursive_type)]
2035    pub children: Vec<PhrasingContent>,
2036}
2037
2038/// Meter/gauge.
2039#[derive(Default, Facet)]
2040#[facet(rename = "meter")]
2041pub struct Meter {
2042    /// Global attributes.
2043    #[facet(flatten, default)]
2044    pub attrs: GlobalAttrs,
2045    /// Current value.
2046    #[facet(html::attribute, default)]
2047    pub value: Option<String>,
2048    /// Minimum value.
2049    #[facet(html::attribute, default)]
2050    pub min: Option<String>,
2051    /// Maximum value.
2052    #[facet(html::attribute, default)]
2053    pub max: Option<String>,
2054    /// Low threshold.
2055    #[facet(html::attribute, default)]
2056    pub low: Option<String>,
2057    /// High threshold.
2058    #[facet(html::attribute, default)]
2059    pub high: Option<String>,
2060    /// Optimum value.
2061    #[facet(html::attribute, default)]
2062    pub optimum: Option<String>,
2063    /// Fallback content.
2064    #[facet(html::elements, default)]
2065    #[facet(recursive_type)]
2066    pub children: Vec<PhrasingContent>,
2067}
2068
2069// =============================================================================
2070// Interactive Elements
2071// =============================================================================
2072
2073/// Details disclosure widget.
2074#[derive(Default, Facet)]
2075#[facet(rename = "details")]
2076pub struct Details {
2077    /// Global attributes.
2078    #[facet(flatten, default)]
2079    pub attrs: GlobalAttrs,
2080    /// Open state.
2081    #[facet(html::attribute, default)]
2082    pub open: Option<String>,
2083    /// Summary.
2084    #[facet(default)]
2085    pub summary: Option<Summary>,
2086    /// Child elements.
2087    #[facet(html::elements, default)]
2088    #[facet(recursive_type)]
2089    pub children: Vec<FlowContent>,
2090}
2091
2092/// Details summary.
2093#[derive(Default, Facet)]
2094#[facet(rename = "summary")]
2095pub struct Summary {
2096    /// Global attributes.
2097    #[facet(flatten, default)]
2098    pub attrs: GlobalAttrs,
2099    /// Child elements.
2100    #[facet(html::elements, default)]
2101    #[facet(recursive_type)]
2102    pub children: Vec<PhrasingContent>,
2103}
2104
2105/// Dialog box.
2106#[derive(Default, Facet)]
2107#[facet(rename = "dialog")]
2108pub struct Dialog {
2109    /// Global attributes.
2110    #[facet(flatten, default)]
2111    pub attrs: GlobalAttrs,
2112    /// Open state.
2113    #[facet(html::attribute, default)]
2114    pub open: Option<String>,
2115    /// Child elements.
2116    #[facet(html::elements, default)]
2117    #[facet(recursive_type)]
2118    pub children: Vec<FlowContent>,
2119}
2120
2121// =============================================================================
2122// Scripting Elements
2123// =============================================================================
2124
2125/// Script.
2126#[derive(Default, Facet)]
2127#[facet(rename = "script")]
2128pub struct Script {
2129    /// Global attributes.
2130    #[facet(flatten, default)]
2131    pub attrs: GlobalAttrs,
2132    /// Script URL.
2133    #[facet(html::attribute, default)]
2134    pub src: Option<String>,
2135    /// MIME type.
2136    #[facet(html::attribute, default, rename = "type")]
2137    pub type_: Option<String>,
2138    /// Async loading.
2139    #[facet(html::attribute, default, rename = "async")]
2140    pub async_: Option<String>,
2141    /// Defer loading.
2142    #[facet(html::attribute, default)]
2143    pub defer: Option<String>,
2144    /// Crossorigin.
2145    #[facet(html::attribute, default)]
2146    pub crossorigin: Option<String>,
2147    /// Integrity hash.
2148    #[facet(html::attribute, default)]
2149    pub integrity: Option<String>,
2150    /// Referrer policy.
2151    #[facet(html::attribute, default)]
2152    pub referrerpolicy: Option<String>,
2153    /// Nomodule flag.
2154    #[facet(html::attribute, default)]
2155    pub nomodule: Option<String>,
2156    /// Inline script content.
2157    #[facet(html::text, default)]
2158    pub text: String,
2159}
2160
2161/// Noscript fallback.
2162#[derive(Default, Facet)]
2163#[facet(rename = "noscript")]
2164pub struct Noscript {
2165    /// Global attributes.
2166    #[facet(flatten, default)]
2167    pub attrs: GlobalAttrs,
2168    /// Child elements.
2169    #[facet(html::elements, default)]
2170    #[facet(recursive_type)]
2171    pub children: Vec<FlowContent>,
2172}
2173
2174/// Template.
2175#[derive(Default, Facet)]
2176#[facet(rename = "template")]
2177pub struct Template {
2178    /// Global attributes.
2179    #[facet(flatten, default)]
2180    pub attrs: GlobalAttrs,
2181    /// Child elements.
2182    #[facet(html::elements, default)]
2183    #[facet(recursive_type)]
2184    pub children: Vec<FlowContent>,
2185}
2186
2187/// Slot for web components.
2188#[derive(Default, Facet)]
2189#[facet(rename = "slot")]
2190pub struct Slot {
2191    /// Global attributes.
2192    #[facet(flatten, default)]
2193    pub attrs: GlobalAttrs,
2194    /// Slot name.
2195    #[facet(html::attribute, default)]
2196    pub name: Option<String>,
2197    /// Child elements.
2198    #[facet(html::elements, default)]
2199    #[facet(recursive_type)]
2200    pub children: Vec<FlowContent>,
2201}
2202
2203// =============================================================================
2204// Custom Elements
2205// =============================================================================
2206
2207/// A custom HTML element with a dynamic tag name.
2208///
2209/// This type is used as a catch-all for unknown elements during HTML parsing.
2210/// Custom elements (like `<a-k>`, `<a-f>` from arborium syntax highlighting)
2211/// are preserved with their tag name, attributes, and children.
2212///
2213/// # Example
2214///
2215/// ```ignore
2216/// // Input: <a-k>fn</a-k>
2217/// // Parses as:
2218/// CustomElement {
2219///     tag: "a-k".to_string(),
2220///     attrs: GlobalAttrs::default(),
2221///     children: vec![FlowContent::Text("fn".to_string())],
2222/// }
2223/// ```
2224#[derive(Default, Facet)]
2225pub struct CustomElement {
2226    /// The tag name of the custom element (e.g., "a-k", "my-component").
2227    ///
2228    /// This field is marked with `#[facet(html::tag)]` to indicate it should
2229    /// receive the element's tag name during deserialization.
2230    #[facet(html::tag, default)]
2231    pub tag: String,
2232    /// Global attributes.
2233    #[facet(flatten, default)]
2234    pub attrs: GlobalAttrs,
2235    /// Child elements.
2236    #[facet(html::elements, default)]
2237    #[facet(recursive_type)]
2238    pub children: Vec<FlowContent>,
2239}
2240
2241/// A custom phrasing element with a dynamic tag name.
2242///
2243/// Similar to [`CustomElement`] but for inline/phrasing content contexts.
2244/// This allows custom elements to appear inside paragraphs, spans, etc.
2245#[derive(Default, Facet)]
2246pub struct CustomPhrasingElement {
2247    /// The tag name of the custom element.
2248    #[facet(html::tag, default)]
2249    pub tag: String,
2250    /// Global attributes.
2251    #[facet(flatten, default)]
2252    pub attrs: GlobalAttrs,
2253    /// Child elements.
2254    #[facet(html::elements, default)]
2255    #[facet(recursive_type)]
2256    pub children: Vec<PhrasingContent>,
2257}
2258
2259// =============================================================================
2260// Content Categories (Enums for mixed content)
2261// =============================================================================
2262
2263/// Flow content - most block and inline elements.
2264#[derive(Facet)]
2265#[repr(u8)]
2266#[allow(clippy::large_enum_variant)] // DOM-like structures naturally have large variants
2267pub enum FlowContent {
2268    /// Text node (for mixed content).
2269    #[facet(rename = "_text", html::text)]
2270    Text(String),
2271
2272    // Sections
2273    /// Header element.
2274    #[facet(rename = "header")]
2275    Header(Header),
2276    /// Footer element.
2277    #[facet(rename = "footer")]
2278    Footer(Footer),
2279    /// Main element.
2280    #[facet(rename = "main")]
2281    Main(Main),
2282    /// Article element.
2283    #[facet(rename = "article")]
2284    Article(Article),
2285    /// Section element.
2286    #[facet(rename = "section")]
2287    Section(Section),
2288    /// Nav element.
2289    #[facet(rename = "nav")]
2290    Nav(Nav),
2291    /// Aside element.
2292    #[facet(rename = "aside")]
2293    Aside(Aside),
2294    /// Address element.
2295    #[facet(rename = "address")]
2296    Address(Address),
2297
2298    // Headings
2299    /// H1 element.
2300    #[facet(rename = "h1")]
2301    H1(H1),
2302    /// H2 element.
2303    #[facet(rename = "h2")]
2304    H2(H2),
2305    /// H3 element.
2306    #[facet(rename = "h3")]
2307    H3(H3),
2308    /// H4 element.
2309    #[facet(rename = "h4")]
2310    H4(H4),
2311    /// H5 element.
2312    #[facet(rename = "h5")]
2313    H5(H5),
2314    /// H6 element.
2315    #[facet(rename = "h6")]
2316    H6(H6),
2317
2318    // Grouping
2319    /// P element.
2320    #[facet(rename = "p")]
2321    P(P),
2322    /// Div element.
2323    #[facet(rename = "div")]
2324    Div(Div),
2325    /// Pre element.
2326    #[facet(rename = "pre")]
2327    Pre(Pre),
2328    /// Blockquote element.
2329    #[facet(rename = "blockquote")]
2330    Blockquote(Blockquote),
2331    /// Ol element.
2332    #[facet(rename = "ol")]
2333    Ol(Ol),
2334    /// Ul element.
2335    #[facet(rename = "ul")]
2336    Ul(Ul),
2337    /// Dl element.
2338    #[facet(rename = "dl")]
2339    Dl(Dl),
2340    /// Figure element.
2341    #[facet(rename = "figure")]
2342    Figure(Figure),
2343    /// Hr element.
2344    #[facet(rename = "hr")]
2345    Hr(Hr),
2346
2347    // Phrasing (inline)
2348    /// A element.
2349    #[facet(rename = "a")]
2350    A(A),
2351    /// Span element.
2352    #[facet(rename = "span")]
2353    Span(Span),
2354    /// Em element.
2355    #[facet(rename = "em")]
2356    Em(Em),
2357    /// Strong element.
2358    #[facet(rename = "strong")]
2359    Strong(Strong),
2360    /// Code element.
2361    #[facet(rename = "code")]
2362    Code(Code),
2363    /// Img element.
2364    #[facet(rename = "img")]
2365    Img(Img),
2366    /// Br element.
2367    #[facet(rename = "br")]
2368    Br(Br),
2369
2370    // Tables
2371    /// Table element.
2372    #[facet(rename = "table")]
2373    Table(Table),
2374
2375    // Forms
2376    /// Form element.
2377    #[facet(rename = "form")]
2378    Form(Form),
2379    /// Input element.
2380    #[facet(rename = "input")]
2381    Input(Input),
2382    /// Button element.
2383    #[facet(rename = "button")]
2384    Button(Button),
2385    /// Select element.
2386    #[facet(rename = "select")]
2387    Select(Select),
2388    /// Textarea element.
2389    #[facet(rename = "textarea")]
2390    Textarea(Textarea),
2391    /// Label element.
2392    #[facet(rename = "label")]
2393    Label(Label),
2394    /// Fieldset element.
2395    #[facet(rename = "fieldset")]
2396    Fieldset(Fieldset),
2397
2398    // Interactive
2399    /// Details element.
2400    #[facet(rename = "details")]
2401    Details(Details),
2402    /// Dialog element.
2403    #[facet(rename = "dialog")]
2404    Dialog(Dialog),
2405
2406    // Embedded
2407    /// Iframe element.
2408    #[facet(rename = "iframe")]
2409    Iframe(Iframe),
2410    /// Video element.
2411    #[facet(rename = "video")]
2412    Video(Video),
2413    /// Audio element.
2414    #[facet(rename = "audio")]
2415    Audio(Audio),
2416    /// Picture element.
2417    #[facet(rename = "picture")]
2418    Picture(Picture),
2419    /// Canvas element.
2420    #[facet(rename = "canvas")]
2421    Canvas(Canvas),
2422    /// Svg element.
2423    #[facet(rename = "svg")]
2424    Svg(Svg),
2425
2426    // Scripting
2427    /// Script element.
2428    #[facet(rename = "script")]
2429    Script(Script),
2430    /// Noscript element.
2431    #[facet(rename = "noscript")]
2432    Noscript(Noscript),
2433    /// Template element.
2434    #[facet(rename = "template")]
2435    Template(Template),
2436
2437    // Custom elements (catch-all for unknown elements)
2438    /// Custom element (catch-all for unknown elements like `<a-k>`, `<my-component>`).
2439    #[facet(html::custom_element)]
2440    Custom(CustomElement),
2441}
2442
2443/// Phrasing content - inline elements and text.
2444#[derive(Facet)]
2445#[repr(u8)]
2446#[allow(clippy::large_enum_variant)] // DOM-like structures naturally have large variants
2447pub enum PhrasingContent {
2448    /// Text node (for mixed content).
2449    #[facet(rename = "_text", html::text)]
2450    Text(String),
2451    /// A element.
2452    #[facet(rename = "a")]
2453    A(A),
2454    /// Span element.
2455    #[facet(rename = "span")]
2456    Span(Span),
2457    /// Em element.
2458    #[facet(rename = "em")]
2459    Em(Em),
2460    /// Strong element.
2461    #[facet(rename = "strong")]
2462    Strong(Strong),
2463    /// Small element.
2464    #[facet(rename = "small")]
2465    Small(Small),
2466    /// S element.
2467    #[facet(rename = "s")]
2468    S(S),
2469    /// Cite element.
2470    #[facet(rename = "cite")]
2471    Cite(Cite),
2472    /// Q element.
2473    #[facet(rename = "q")]
2474    Q(Q),
2475    /// Dfn element.
2476    #[facet(rename = "dfn")]
2477    Dfn(Dfn),
2478    /// Abbr element.
2479    #[facet(rename = "abbr")]
2480    Abbr(Abbr),
2481    /// Data element.
2482    #[facet(rename = "data")]
2483    Data(Data),
2484    /// Time element.
2485    #[facet(rename = "time")]
2486    Time(Time),
2487    /// Code element.
2488    #[facet(rename = "code")]
2489    Code(Code),
2490    /// Var element.
2491    #[facet(rename = "var")]
2492    Var(Var),
2493    /// Samp element.
2494    #[facet(rename = "samp")]
2495    Samp(Samp),
2496    /// Kbd element.
2497    #[facet(rename = "kbd")]
2498    Kbd(Kbd),
2499    /// Sub element.
2500    #[facet(rename = "sub")]
2501    Sub(Sub),
2502    /// Sup element.
2503    #[facet(rename = "sup")]
2504    Sup(Sup),
2505    /// I element.
2506    #[facet(rename = "i")]
2507    I(I),
2508    /// B element.
2509    #[facet(rename = "b")]
2510    B(B),
2511    /// U element.
2512    #[facet(rename = "u")]
2513    U(U),
2514    /// Mark element.
2515    #[facet(rename = "mark")]
2516    Mark(Mark),
2517    /// Bdi element.
2518    #[facet(rename = "bdi")]
2519    Bdi(Bdi),
2520    /// Bdo element.
2521    #[facet(rename = "bdo")]
2522    Bdo(Bdo),
2523    /// Br element.
2524    #[facet(rename = "br")]
2525    Br(Br),
2526    /// Wbr element.
2527    #[facet(rename = "wbr")]
2528    Wbr(Wbr),
2529    /// Img element.
2530    #[facet(rename = "img")]
2531    Img(Img),
2532    /// Input element.
2533    #[facet(rename = "input")]
2534    Input(Input),
2535    /// Button element.
2536    #[facet(rename = "button")]
2537    Button(Button),
2538    /// Select element.
2539    #[facet(rename = "select")]
2540    Select(Select),
2541    /// Textarea element.
2542    #[facet(rename = "textarea")]
2543    Textarea(Textarea),
2544    /// Label element.
2545    #[facet(rename = "label")]
2546    Label(Label),
2547    /// Output element.
2548    #[facet(rename = "output")]
2549    Output(Output),
2550    /// Progress element.
2551    #[facet(rename = "progress")]
2552    Progress(Progress),
2553    /// Meter element.
2554    #[facet(rename = "meter")]
2555    Meter(Meter),
2556    /// Script element.
2557    #[facet(rename = "script")]
2558    Script(Script),
2559
2560    // Custom elements (catch-all for unknown elements)
2561    /// Custom element (catch-all for unknown elements like `<a-k>`, `<my-component>`).
2562    #[facet(html::custom_element)]
2563    Custom(CustomPhrasingElement),
2564}