ironhtml_attributes/
lib.rs

1//! # ironhtml-attributes
2//!
3//! Type-safe HTML5 attributes following the
4//! [WHATWG HTML Living Standard](https://html.spec.whatwg.org/).
5//!
6//! This crate provides traits for global and element-specific attributes,
7//! with type-safe enums for constrained attribute values.
8//!
9//! ## Example
10//!
11//! ```rust
12//! use ironhtml_attributes::{AttributeValue, InputType, Target, Loading, Method};
13//!
14//! // Use type-safe enums for attribute values
15//! let input_type = InputType::Email;
16//! assert_eq!(input_type.to_attr_value(), "email");
17//!
18//! let target = Target::Blank;
19//! assert_eq!(target.to_attr_value(), "_blank");
20//!
21//! // Access attribute names as constants
22//! use ironhtml_attributes::{global, anchor, img};
23//! assert_eq!(global::CLASS, "class");
24//! assert_eq!(anchor::HREF, "href");
25//! assert_eq!(img::LOADING, "loading");
26//! ```
27//!
28//! ## Specification References
29//!
30//! - [Global attributes](https://html.spec.whatwg.org/multipage/dom.html#global-attributes)
31//! - [The `a` element](https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-a-element)
32//! - [The `img` element](https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-element)
33//! - [The `input` element](https://html.spec.whatwg.org/multipage/input.html#the-input-element)
34//! - [The `form` element](https://html.spec.whatwg.org/multipage/forms.html#the-form-element)
35
36#![no_std]
37
38extern crate alloc;
39
40use alloc::borrow::Cow;
41use alloc::string::String;
42
43// =============================================================================
44// Attribute Value Types
45// =============================================================================
46
47/// A trait for types that can be converted to an attribute value string.
48pub trait AttributeValue {
49    /// Convert to the attribute value string.
50    fn to_attr_value(&self) -> Cow<'static, str>;
51}
52
53impl AttributeValue for &'static str {
54    fn to_attr_value(&self) -> Cow<'static, str> {
55        Cow::Borrowed(self)
56    }
57}
58
59impl AttributeValue for String {
60    fn to_attr_value(&self) -> Cow<'static, str> {
61        Cow::Owned(self.clone())
62    }
63}
64
65impl AttributeValue for Cow<'static, str> {
66    fn to_attr_value(&self) -> Cow<'static, str> {
67        self.clone()
68    }
69}
70
71impl AttributeValue for u32 {
72    fn to_attr_value(&self) -> Cow<'static, str> {
73        use alloc::string::ToString;
74        Cow::Owned(self.to_string())
75    }
76}
77
78impl AttributeValue for i32 {
79    fn to_attr_value(&self) -> Cow<'static, str> {
80        use alloc::string::ToString;
81        Cow::Owned(self.to_string())
82    }
83}
84
85impl AttributeValue for bool {
86    fn to_attr_value(&self) -> Cow<'static, str> {
87        if *self {
88            Cow::Borrowed("true")
89        } else {
90            Cow::Borrowed("false")
91        }
92    }
93}
94
95// =============================================================================
96// Global Attribute Enums
97// =============================================================================
98
99/// The `dir` attribute values for text directionality.
100///
101/// # Purpose
102/// Controls the text directionality of an element's content, which is critical
103/// for proper rendering of multilingual content and right-to-left languages.
104///
105/// # Usage Context
106/// - Used with: All HTML elements (global attribute)
107/// - Affects: Text rendering direction, visual layout, and text alignment
108///
109/// # Valid Values
110/// - `Ltr`: Left-to-right text direction (default for most languages)
111/// - `Rtl`: Right-to-left text direction (for languages like Arabic, Hebrew)
112/// - `Auto`: Browser determines direction based on content
113///
114/// # Example
115/// ```rust
116/// use ironhtml_attributes::{AttributeValue, Dir};
117/// let direction = Dir::Rtl;
118/// assert_eq!(direction.to_attr_value(), "rtl");
119/// ```
120///
121/// ```html
122/// <p dir="rtl">مرحبا بك</p>
123/// <p dir="ltr">Hello world</p>
124/// <p dir="auto">Auto-detected text</p>
125/// ```
126///
127/// # WHATWG Specification
128/// - [The `dir` attribute](https://html.spec.whatwg.org/multipage/dom.html#the-dir-attribute)
129#[derive(Debug, Clone, Copy, PartialEq, Eq)]
130pub enum Dir {
131    /// Left-to-right text direction, used for most Western languages
132    /// (English, Spanish, French, etc.).
133    Ltr,
134    /// Right-to-left text direction, used for languages like Arabic,
135    /// Hebrew, Persian, and Urdu.
136    Rtl,
137    /// Automatically determines text direction based on the first
138    /// strongly-typed directional character in the content.
139    Auto,
140}
141
142impl AttributeValue for Dir {
143    fn to_attr_value(&self) -> Cow<'static, str> {
144        Cow::Borrowed(match self {
145            Self::Ltr => "ltr",
146            Self::Rtl => "rtl",
147            Self::Auto => "auto",
148        })
149    }
150}
151
152/// The `contenteditable` attribute values.
153///
154/// # Purpose
155/// Controls whether an element's content can be edited by the user, enabling
156/// rich text editing and in-place content modification in web applications.
157///
158/// # Usage Context
159/// - Used with: All HTML elements (global attribute)
160/// - Common use: Rich text editors, inline editing, CMS interfaces
161///
162/// # Valid Values
163/// - `True`: Element content is editable by the user
164/// - `False`: Element content is not editable
165/// - `Inherit`: Inherits editability from parent element
166///
167/// # Example
168/// ```rust
169/// use ironhtml_attributes::{AttributeValue, ContentEditable};
170/// let editable = ContentEditable::True;
171/// assert_eq!(editable.to_attr_value(), "true");
172/// ```
173///
174/// ```html
175/// <div contenteditable="true">Edit this text directly!</div>
176/// <div contenteditable="false">This cannot be edited</div>
177/// <span contenteditable="inherit">Inherits from parent</span>
178/// ```
179///
180/// # WHATWG Specification
181/// - [The `contenteditable` attribute](https://html.spec.whatwg.org/multipage/interaction.html#attr-contenteditable)
182#[derive(Debug, Clone, Copy, PartialEq, Eq)]
183pub enum ContentEditable {
184    /// Content is editable by the user. The element becomes a rich text
185    /// editing host.
186    True,
187    /// Content is explicitly not editable. This overrides any inherited
188    /// editability.
189    False,
190    /// Inherits the `contenteditable` state from the parent element.
191    Inherit,
192}
193
194impl AttributeValue for ContentEditable {
195    fn to_attr_value(&self) -> Cow<'static, str> {
196        Cow::Borrowed(match self {
197            Self::True => "true",
198            Self::False => "false",
199            Self::Inherit => "inherit",
200        })
201    }
202}
203
204/// The `draggable` attribute values.
205///
206/// # Purpose
207/// Indicates whether an element can be dragged using the HTML5 drag-and-drop
208/// API, enabling rich drag-and-drop interactions in web applications.
209///
210/// # Usage Context
211/// - Used with: All HTML elements (global attribute)
212/// - Default: Links and images are draggable by default; other elements are not
213/// - Common use: File upload interfaces, sortable lists, drag-and-drop games
214///
215/// # Valid Values
216/// - `True`: Element is draggable
217/// - `False`: Element is not draggable (overrides default behavior)
218///
219/// # Example
220/// ```rust
221/// use ironhtml_attributes::{AttributeValue, Draggable};
222/// let draggable = Draggable::True;
223/// assert_eq!(draggable.to_attr_value(), "true");
224/// ```
225///
226/// ```html
227/// <div draggable="true">Drag me!</div>
228/// <img src="photo.jpg" draggable="false" alt="Cannot drag this image">
229/// ```
230///
231/// # WHATWG Specification
232/// - [The `draggable` attribute](https://html.spec.whatwg.org/multipage/dnd.html#the-draggable-attribute)
233#[derive(Debug, Clone, Copy, PartialEq, Eq)]
234pub enum Draggable {
235    /// Element is draggable and can be used with the drag-and-drop API.
236    True,
237    /// Element is not draggable, overriding any default draggable behavior.
238    False,
239}
240
241impl AttributeValue for Draggable {
242    fn to_attr_value(&self) -> Cow<'static, str> {
243        Cow::Borrowed(match self {
244            Self::True => "true",
245            Self::False => "false",
246        })
247    }
248}
249
250/// The `hidden` attribute values.
251///
252/// # Purpose
253/// Controls element visibility and search-in-page behavior, allowing elements
254/// to be hidden from rendering while remaining in the DOM.
255///
256/// # Usage Context
257/// - Used with: All HTML elements (global attribute)
258/// - Effect: Hides element from rendering and accessibility tree
259/// - Note: Can be overridden by CSS `display` property
260///
261/// # Valid Values
262/// - `UntilFound`: Element is hidden but searchable and will be revealed when found
263/// - `Hidden`: Element is completely hidden (boolean attribute style)
264///
265/// # Example
266/// ```rust
267/// use ironhtml_attributes::{AttributeValue, Hidden};
268/// let hidden = Hidden::UntilFound;
269/// assert_eq!(hidden.to_attr_value(), "until-found");
270/// ```
271///
272/// ```html
273/// <div hidden="until-found">Search will reveal this content</div>
274/// <div hidden>Completely hidden content</div>
275/// ```
276///
277/// # WHATWG Specification
278/// - [The `hidden` attribute](https://html.spec.whatwg.org/multipage/interaction.html#the-hidden-attribute)
279#[derive(Debug, Clone, Copy, PartialEq, Eq)]
280pub enum Hidden {
281    /// Element is hidden but can be revealed by browser find-in-page or
282    /// fragment navigation. The element remains hidden until found.
283    UntilFound,
284    /// Element is completely hidden from rendering and the accessibility tree.
285    /// Used as a boolean attribute.
286    Hidden,
287}
288
289impl AttributeValue for Hidden {
290    fn to_attr_value(&self) -> Cow<'static, str> {
291        Cow::Borrowed(match self {
292            Self::UntilFound => "until-found",
293            Self::Hidden => "hidden",
294        })
295    }
296}
297
298/// The `spellcheck` attribute values.
299///
300/// # Purpose
301/// Controls whether the browser's spell-checking feature is enabled for
302/// editable elements, helping users catch typing errors.
303///
304/// # Usage Context
305/// - Used with: All HTML elements (global attribute)
306/// - Primarily useful for: Editable elements (`contenteditable`, `<input>`, `<textarea>`)
307/// - Default: Browser-dependent, typically enabled for editable text
308///
309/// # Valid Values
310/// - `True`: Enable spell-checking for this element
311/// - `False`: Disable spell-checking for this element
312///
313/// # Example
314/// ```rust
315/// use ironhtml_attributes::{AttributeValue, Spellcheck};
316/// let check = Spellcheck::False;
317/// assert_eq!(check.to_attr_value(), "false");
318/// ```
319///
320/// ```html
321/// <textarea spellcheck="true">Enable spell-checking here</textarea>
322/// <input type="text" spellcheck="false" placeholder="Code (no spellcheck)">
323/// ```
324///
325/// # WHATWG Specification
326/// - [The `spellcheck` attribute](https://html.spec.whatwg.org/multipage/interaction.html#attr-spellcheck)
327#[derive(Debug, Clone, Copy, PartialEq, Eq)]
328pub enum Spellcheck {
329    /// Enable spell-checking for this element. The browser will check
330    /// spelling and mark errors.
331    True,
332    /// Disable spell-checking for this element. Useful for code editors,
333    /// usernames, and technical content.
334    False,
335}
336
337impl AttributeValue for Spellcheck {
338    fn to_attr_value(&self) -> Cow<'static, str> {
339        Cow::Borrowed(match self {
340            Self::True => "true",
341            Self::False => "false",
342        })
343    }
344}
345
346/// The `translate` attribute values.
347///
348/// # Purpose
349/// Indicates whether an element's text content and attribute values should be
350/// translated when the page is localized, useful for multilingual applications.
351///
352/// # Usage Context
353/// - Used with: All HTML elements (global attribute)
354/// - Common use: Marking technical terms, brand names, or code that shouldn't be translated
355/// - Default: `yes` (content is translatable)
356///
357/// # Valid Values
358/// - `Yes`: Content should be translated when localizing the page
359/// - `No`: Content should not be translated (e.g., brand names, code)
360///
361/// # Example
362/// ```rust
363/// use ironhtml_attributes::{AttributeValue, Translate};
364/// let trans = Translate::No;
365/// assert_eq!(trans.to_attr_value(), "no");
366/// ```
367///
368/// ```html
369/// <p>Welcome to <span translate="no">GitHub</span>!</p>
370/// <code translate="no">const x = 42;</code>
371/// <p translate="yes">This text can be translated</p>
372/// ```
373///
374/// # WHATWG Specification
375/// - [The `translate` attribute](https://html.spec.whatwg.org/multipage/dom.html#attr-translate)
376#[derive(Debug, Clone, Copy, PartialEq, Eq)]
377pub enum Translate {
378    /// Element's text and attributes should be translated when the page
379    /// is localized.
380    Yes,
381    /// Element's text and attributes should not be translated. Use for
382    /// brand names, code samples, or technical terms.
383    No,
384}
385
386impl AttributeValue for Translate {
387    fn to_attr_value(&self) -> Cow<'static, str> {
388        Cow::Borrowed(match self {
389            Self::Yes => "yes",
390            Self::No => "no",
391        })
392    }
393}
394
395// =============================================================================
396// Element-Specific Attribute Enums
397// =============================================================================
398
399/// The `target` attribute values for hyperlinks and forms.
400///
401/// # Purpose
402/// Specifies where to display the linked URL or form response, controlling
403/// whether content opens in a new window, the same frame, or a specific context.
404///
405/// # Usage Context
406/// - Used with: `<a>`, `<area>`, `<form>`, `<base>` elements
407/// - Security: Use with `rel="noopener"` when opening in new window
408///
409/// # Valid Values
410/// - `Self_`: Open in the same browsing context (default)
411/// - `Blank`: Open in a new window or tab
412/// - `Parent`: Open in the parent browsing context
413/// - `Top`: Open in the top-most browsing context
414///
415/// # Example
416/// ```rust
417/// use ironhtml_attributes::{AttributeValue, Target};
418/// let target = Target::Blank;
419/// assert_eq!(target.to_attr_value(), "_blank");
420/// ```
421///
422/// ```html
423/// <a href="https://example.com" target="_blank">Open in new tab</a>
424/// <a href="/page" target="_self">Open in same tab</a>
425/// <form action="/submit" target="_parent" method="post">...</form>
426/// ```
427///
428/// # WHATWG Specification
429/// - [Browsing context names](https://html.spec.whatwg.org/multipage/browsers.html#valid-browsing-context-name-or-keyword)
430/// - [The `target` attribute](https://html.spec.whatwg.org/multipage/links.html#attr-hyperlink-target)
431#[derive(Debug, Clone, Copy, PartialEq, Eq)]
432pub enum Target {
433    /// Open in the same browsing context (frame/tab). This is the default
434    /// behavior when target is not specified.
435    Self_,
436    /// Open in a new, unnamed browsing context (typically a new tab or window).
437    /// For security, use with `rel="noopener noreferrer"`.
438    Blank,
439    /// Open in the parent browsing context. If no parent exists, behaves
440    /// like `_self`.
441    Parent,
442    /// Open in the top-level browsing context (the highest-level ancestor).
443    /// If no ancestors exist, behaves like `_self`.
444    Top,
445}
446
447impl AttributeValue for Target {
448    fn to_attr_value(&self) -> Cow<'static, str> {
449        Cow::Borrowed(match self {
450            Self::Self_ => "_self",
451            Self::Blank => "_blank",
452            Self::Parent => "_parent",
453            Self::Top => "_top",
454        })
455    }
456}
457
458/// The `rel` attribute values for link relationships.
459///
460/// # Purpose
461/// Defines the relationship between the current document and the linked resource,
462/// providing semantic meaning for links and enabling special browser behaviors.
463///
464/// # Usage Context
465/// - Used with: `<a>`, `<area>`, `<link>`, `<form>` elements
466/// - Multiple values: Can be space-separated (e.g., "noopener noreferrer")
467/// - SEO impact: Values like `nofollow` affect search engine crawling
468///
469/// # Valid Values
470/// - `Alternate`: Alternate representation of the document
471/// - `Author`: Link to the document's author
472/// - `Bookmark`: Permalink for the nearest ancestor section
473/// - `External`: Link to a different website
474/// - `Help`: Link to context-sensitive help
475/// - `License`: Link to copyright/license information
476/// - `Next`: Next document in a sequence
477/// - `Nofollow`: Do not follow this link for SEO purposes
478/// - `Noopener`: Prevents window.opener access (security)
479/// - `Noreferrer`: Don't send referer header (privacy)
480/// - `Prev`: Previous document in a sequence
481/// - `Search`: Link to a search tool
482/// - `Tag`: Tag/keyword for the current document
483///
484/// # Example
485/// ```rust
486/// use ironhtml_attributes::{AttributeValue, Rel};
487/// let rel = Rel::Noopener;
488/// assert_eq!(rel.to_attr_value(), "noopener");
489/// ```
490///
491/// ```html
492/// <a href="https://external.com" rel="external nofollow">External Site</a>
493/// <a href="/help" rel="help">Help Documentation</a>
494/// <link rel="alternate" href="/feed.xml" type="application/rss+xml">
495/// <a href="https://example.com" target="_blank" rel="noopener noreferrer">Safe Link</a>
496/// ```
497///
498/// # WHATWG Specification
499/// - [Link types](https://html.spec.whatwg.org/multipage/links.html#linkTypes)
500/// - [The `rel` attribute](https://html.spec.whatwg.org/multipage/links.html#attr-hyperlink-rel)
501#[derive(Debug, Clone, Copy, PartialEq, Eq)]
502pub enum Rel {
503    /// Indicates an alternate representation of the current document,
504    /// such as translations, RSS feeds, or print versions.
505    Alternate,
506    /// Link to information about the author of the document.
507    Author,
508    /// Provides a permalink to the nearest ancestor section.
509    Bookmark,
510    /// Indicates the link references a resource on a different site.
511    External,
512    /// Link to context-sensitive help information.
513    Help,
514    /// Link to copyright, license, or legal information for the document.
515    License,
516    /// Indicates the next document in a sequence (pagination, slideshows).
517    Next,
518    /// Instructs search engines not to follow this link for ranking purposes.
519    Nofollow,
520    /// Prevents the new browsing context from accessing `window.opener`.
521    /// Critical security feature for `target="_blank"` links.
522    Noopener,
523    /// Prevents the browser from sending the Referer header. Enhances privacy.
524    Noreferrer,
525    /// Indicates the previous document in a sequence (pagination, slideshows).
526    Prev,
527    /// Link to a search tool or interface for the current document.
528    Search,
529    /// Indicates the link represents a tag or keyword for the current document.
530    Tag,
531}
532
533impl AttributeValue for Rel {
534    fn to_attr_value(&self) -> Cow<'static, str> {
535        Cow::Borrowed(match self {
536            Self::Alternate => "alternate",
537            Self::Author => "author",
538            Self::Bookmark => "bookmark",
539            Self::External => "external",
540            Self::Help => "help",
541            Self::License => "license",
542            Self::Next => "next",
543            Self::Nofollow => "nofollow",
544            Self::Noopener => "noopener",
545            Self::Noreferrer => "noreferrer",
546            Self::Prev => "prev",
547            Self::Search => "search",
548            Self::Tag => "tag",
549        })
550    }
551}
552
553/// The `loading` attribute values for lazy-loading resources.
554///
555/// # Purpose
556/// Controls when the browser should load images and iframes, enabling
557/// performance optimization through lazy loading of off-screen content.
558///
559/// # Usage Context
560/// - Used with: `<img>`, `<iframe>` elements
561/// - Performance: Lazy loading can significantly improve initial page load
562/// - Default: Browser-dependent (typically `eager`)
563///
564/// # Valid Values
565/// - `Eager`: Load the resource immediately, regardless of viewport position
566/// - `Lazy`: Defer loading until the resource is near the viewport
567///
568/// # Example
569/// ```rust
570/// use ironhtml_attributes::{AttributeValue, Loading};
571/// let loading = Loading::Lazy;
572/// assert_eq!(loading.to_attr_value(), "lazy");
573/// ```
574///
575/// ```html
576/// <img src="above-fold.jpg" loading="eager" alt="Loads immediately">
577/// <img src="below-fold.jpg" loading="lazy" alt="Loads when near viewport">
578/// <iframe src="widget.html" loading="lazy"></iframe>
579/// ```
580///
581/// # WHATWG Specification
582/// - [The `loading` attribute](https://html.spec.whatwg.org/multipage/urls-and-fetching.html#lazy-loading-attributes)
583#[derive(Debug, Clone, Copy, PartialEq, Eq)]
584pub enum Loading {
585    /// Load the resource immediately, without deferring. Use for
586    /// above-the-fold or critical content.
587    Eager,
588    /// Defer loading the resource until it is calculated to be near the
589    /// viewport. Improves performance for below-the-fold content.
590    Lazy,
591}
592
593impl AttributeValue for Loading {
594    fn to_attr_value(&self) -> Cow<'static, str> {
595        Cow::Borrowed(match self {
596            Self::Eager => "eager",
597            Self::Lazy => "lazy",
598        })
599    }
600}
601
602/// The `decoding` attribute values for image decoding.
603///
604/// # Purpose
605/// Provides a hint to the browser about how to decode the image, allowing
606/// optimization of the decoding strategy for better user experience.
607///
608/// # Usage Context
609/// - Used with: `<img>` elements
610/// - Performance: Affects when/how images are decoded relative to page rendering
611/// - Default: Browser-dependent
612///
613/// # Valid Values
614/// - `Sync`: Decode the image synchronously for atomic presentation with other content
615/// - `Async`: Decode the image asynchronously to avoid delaying other content
616/// - `Auto`: Let the browser decide the optimal decoding mode
617///
618/// # Example
619/// ```rust
620/// use ironhtml_attributes::{AttributeValue, Decoding};
621/// let decoding = Decoding::Async;
622/// assert_eq!(decoding.to_attr_value(), "async");
623/// ```
624///
625/// ```html
626/// <img src="hero.jpg" decoding="sync" alt="Decode with page content">
627/// <img src="gallery.jpg" decoding="async" alt="Decode asynchronously">
628/// <img src="photo.jpg" decoding="auto" alt="Browser decides">
629/// ```
630///
631/// # WHATWG Specification
632/// - [The `decoding` attribute](https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-decoding)
633#[derive(Debug, Clone, Copy, PartialEq, Eq)]
634pub enum Decoding {
635    /// Decode the image synchronously along with other page content for
636    /// atomic presentation. May delay rendering.
637    Sync,
638    /// Decode the image asynchronously to reduce delay in presenting other
639    /// content. Image may render after initial page load.
640    Async,
641    /// Allow the browser to choose the decoding strategy. This is the
642    /// recommended default.
643    Auto,
644}
645
646impl AttributeValue for Decoding {
647    fn to_attr_value(&self) -> Cow<'static, str> {
648        Cow::Borrowed(match self {
649            Self::Sync => "sync",
650            Self::Async => "async",
651            Self::Auto => "auto",
652        })
653    }
654}
655
656/// The `crossorigin` attribute values for CORS requests.
657///
658/// # Purpose
659/// Controls how cross-origin requests are made for resources, determining
660/// whether credentials are sent and enabling CORS validation.
661///
662/// # Usage Context
663/// - Used with: `<img>`, `<script>`, `<link>`, `<audio>`, `<video>` elements
664/// - Security: Required for accessing cross-origin resources with canvas/WebGL
665/// - CORS: Server must send appropriate Access-Control headers
666///
667/// # Valid Values
668/// - `Anonymous`: CORS request without credentials
669/// - `UseCredentials`: CORS request with credentials (cookies, certificates)
670///
671/// # Example
672/// ```rust
673/// use ironhtml_attributes::{AttributeValue, CrossOrigin};
674/// let cors = CrossOrigin::Anonymous;
675/// assert_eq!(cors.to_attr_value(), "anonymous");
676/// ```
677///
678/// ```html
679/// <img src="https://cdn.example.com/image.jpg" crossorigin="anonymous">
680/// <script src="https://cdn.example.com/lib.js" crossorigin="use-credentials"></script>
681/// <link rel="stylesheet" href="https://cdn.example.com/style.css" crossorigin="anonymous">
682/// ```
683///
684/// # WHATWG Specification
685/// - [CORS settings attributes](https://html.spec.whatwg.org/multipage/urls-and-fetching.html#cors-settings-attributes)
686#[derive(Debug, Clone, Copy, PartialEq, Eq)]
687pub enum CrossOrigin {
688    /// Request uses CORS without credentials. Cookies and client certificates
689    /// are not sent. This is the most common value.
690    Anonymous,
691    /// Request uses CORS with credentials. Cookies, client certificates, and
692    /// authorization headers are included in the request.
693    UseCredentials,
694}
695
696impl AttributeValue for CrossOrigin {
697    fn to_attr_value(&self) -> Cow<'static, str> {
698        Cow::Borrowed(match self {
699            Self::Anonymous => "anonymous",
700            Self::UseCredentials => "use-credentials",
701        })
702    }
703}
704
705/// The `referrerpolicy` attribute values.
706///
707/// # Purpose
708/// Controls how much referrer information is sent with requests, enabling
709/// privacy control over what information is shared with linked resources.
710///
711/// # Usage Context
712/// - Used with: `<a>`, `<area>`, `<img>`, `<iframe>`, `<link>`, `<script>` elements
713/// - Privacy: Determines what URL information is sent in the Referer header
714/// - Security: Prevents leaking sensitive URLs to third parties
715///
716/// # Valid Values
717/// - `NoReferrer`: Never send referrer information
718/// - `NoReferrerWhenDowngrade`: Send referrer only on same security level
719/// - `Origin`: Send only the origin (scheme, host, port)
720/// - `OriginWhenCrossOrigin`: Send full URL for same-origin, origin for cross-origin
721/// - `SameOrigin`: Send referrer only for same-origin requests
722/// - `StrictOrigin`: Send origin, but not when downgrading HTTPS→HTTP
723/// - `StrictOriginWhenCrossOrigin`: Full URL same-origin, origin cross-origin, none on downgrade
724/// - `UnsafeUrl`: Always send the full URL (not recommended)
725///
726/// # Example
727/// ```rust
728/// use ironhtml_attributes::{AttributeValue, ReferrerPolicy};
729/// let policy = ReferrerPolicy::NoReferrer;
730/// assert_eq!(policy.to_attr_value(), "no-referrer");
731/// ```
732///
733/// ```html
734/// <a href="https://example.com" referrerpolicy="no-referrer">Private Link</a>
735/// <img src="https://example.com/img.jpg" referrerpolicy="origin">
736/// <iframe src="https://example.com" referrerpolicy="strict-origin-when-cross-origin"></iframe>
737/// ```
738///
739/// # WHATWG Specification
740/// - [Referrer policy](https://w3c.github.io/webappsec-referrer-policy/)
741/// - [The `referrerpolicy` attribute](https://html.spec.whatwg.org/multipage/urls-and-fetching.html#referrer-policy-attributes)
742#[derive(Debug, Clone, Copy, PartialEq, Eq)]
743pub enum ReferrerPolicy {
744    /// Never send referrer information. Maximum privacy.
745    NoReferrer,
746    /// Send referrer only when not downgrading from HTTPS to HTTP.
747    /// This is often the browser default.
748    NoReferrerWhenDowngrade,
749    /// Send only the origin (no path or query string).
750    Origin,
751    /// Send full URL for same-origin requests, only origin for cross-origin.
752    OriginWhenCrossOrigin,
753    /// Send referrer only for same-origin requests, nothing for cross-origin.
754    SameOrigin,
755    /// Send only origin, and not when downgrading from HTTPS to HTTP.
756    StrictOrigin,
757    /// Send full URL for same-origin, origin for cross-origin, nothing when
758    /// downgrading. Recommended for most use cases.
759    StrictOriginWhenCrossOrigin,
760    /// Always send the full URL as referrer. Not recommended due to privacy
761    /// and security concerns.
762    UnsafeUrl,
763}
764
765impl AttributeValue for ReferrerPolicy {
766    fn to_attr_value(&self) -> Cow<'static, str> {
767        Cow::Borrowed(match self {
768            Self::NoReferrer => "no-referrer",
769            Self::NoReferrerWhenDowngrade => "no-referrer-when-downgrade",
770            Self::Origin => "origin",
771            Self::OriginWhenCrossOrigin => "origin-when-cross-origin",
772            Self::SameOrigin => "same-origin",
773            Self::StrictOrigin => "strict-origin",
774            Self::StrictOriginWhenCrossOrigin => "strict-origin-when-cross-origin",
775            Self::UnsafeUrl => "unsafe-url",
776        })
777    }
778}
779
780/// The `type` attribute values for `<input>` elements.
781///
782/// # Purpose
783/// Defines the type of input control, determining the behavior, validation,
784/// and user interface for collecting user input in forms.
785///
786/// # Usage Context
787/// - Used with: `<input>` elements only
788/// - Default: `text` if not specified
789/// - Validation: Many types provide built-in validation (email, url, number)
790/// - Mobile UX: Types affect virtual keyboard layout on mobile devices
791///
792/// # Valid Values
793/// - `Text`: Single-line text input
794/// - `Password`: Password input (characters obscured)
795/// - `Email`: Email address with validation
796/// - `Url`: URL with validation
797/// - `Tel`: Telephone number
798/// - `Number`: Numeric input with spinner controls
799/// - `Range`: Slider control for numeric range
800/// - `Date`: Date picker
801/// - `Time`: Time picker
802/// - `DatetimeLocal`: Date and time picker (no timezone)
803/// - `Month`: Month and year picker
804/// - `Week`: Week and year picker
805/// - `Color`: Color picker
806/// - `Checkbox`: Checkbox for boolean values
807/// - `Radio`: Radio button for single selection from group
808/// - `File`: File upload control
809/// - `Submit`: Submit button for forms
810/// - `Reset`: Reset button to clear form
811/// - `Button`: Generic button (no default behavior)
812/// - `Image`: Graphical submit button
813/// - `Hidden`: Hidden input (not displayed)
814/// - `Search`: Search input with platform-specific styling
815///
816/// # Example
817/// ```rust
818/// use ironhtml_attributes::{AttributeValue, InputType};
819/// let input_type = InputType::Email;
820/// assert_eq!(input_type.to_attr_value(), "email");
821/// ```
822///
823/// ```html
824/// <input type="text" placeholder="Name">
825/// <input type="email" placeholder="user@example.com">
826/// <input type="password" placeholder="Password">
827/// <input type="number" min="0" max="100">
828/// <input type="date">
829/// <input type="checkbox" id="agree">
830/// <input type="submit" value="Submit">
831/// ```
832///
833/// # WHATWG Specification
834/// - [The `input` element](https://html.spec.whatwg.org/multipage/input.html#the-input-element)
835/// - [Input types](https://html.spec.whatwg.org/multipage/input.html#attr-input-type)
836#[derive(Debug, Clone, Copy, PartialEq, Eq)]
837pub enum InputType {
838    /// Single-line text input. Default type if not specified.
839    Text,
840    /// Password input where characters are obscured for security.
841    Password,
842    /// Email address input with built-in validation.
843    Email,
844    /// URL input with validation for proper URL format.
845    Url,
846    /// Telephone number input. Mobile devices show numeric keyboard.
847    Tel,
848    /// Numeric input with optional min, max, and step constraints.
849    Number,
850    /// Slider control for selecting from a numeric range.
851    Range,
852    /// Date picker control (year, month, day).
853    Date,
854    /// Time picker control (hours and minutes).
855    Time,
856    /// Date and time picker without timezone information.
857    DatetimeLocal,
858    /// Month and year picker control.
859    Month,
860    /// Week and year picker control.
861    Week,
862    /// Color picker returning a hex color value.
863    Color,
864    /// Checkbox for boolean or multi-selection inputs.
865    Checkbox,
866    /// Radio button for single selection from a group.
867    Radio,
868    /// File upload control with optional accept and multiple attributes.
869    File,
870    /// Submit button that submits the form.
871    Submit,
872    /// Reset button that clears the form to default values.
873    Reset,
874    /// Generic button with no default behavior (use with JavaScript).
875    Button,
876    /// Image-based submit button with click coordinates.
877    Image,
878    /// Hidden input not displayed to users but submitted with form.
879    Hidden,
880    /// Search input with platform-specific search styling.
881    Search,
882}
883
884impl AttributeValue for InputType {
885    fn to_attr_value(&self) -> Cow<'static, str> {
886        Cow::Borrowed(match self {
887            Self::Text => "text",
888            Self::Password => "password",
889            Self::Email => "email",
890            Self::Url => "url",
891            Self::Tel => "tel",
892            Self::Number => "number",
893            Self::Range => "range",
894            Self::Date => "date",
895            Self::Time => "time",
896            Self::DatetimeLocal => "datetime-local",
897            Self::Month => "month",
898            Self::Week => "week",
899            Self::Color => "color",
900            Self::Checkbox => "checkbox",
901            Self::Radio => "radio",
902            Self::File => "file",
903            Self::Submit => "submit",
904            Self::Reset => "reset",
905            Self::Button => "button",
906            Self::Image => "image",
907            Self::Hidden => "hidden",
908            Self::Search => "search",
909        })
910    }
911}
912
913/// The `type` attribute values for `<button>` elements.
914///
915/// # Purpose
916/// Defines the behavior of a button element, determining how it interacts
917/// with forms and what action it performs when activated.
918///
919/// # Usage Context
920/// - Used with: `<button>` elements only
921/// - Default: `submit` if not specified and button is in a form
922/// - Form association: Submit and reset affect the associated form
923///
924/// # Valid Values
925/// - `Submit`: Submits the form when clicked
926/// - `Reset`: Resets the form to default values
927/// - `Button`: No default behavior (for custom JavaScript)
928///
929/// # Example
930/// ```rust
931/// use ironhtml_attributes::{AttributeValue, ButtonType};
932/// let btn_type = ButtonType::Submit;
933/// assert_eq!(btn_type.to_attr_value(), "submit");
934/// ```
935///
936/// ```html
937/// <button type="submit">Submit Form</button>
938/// <button type="reset">Reset Form</button>
939/// <button type="button" onclick="handleClick()">Custom Action</button>
940/// ```
941///
942/// # WHATWG Specification
943/// - [The `button` element](https://html.spec.whatwg.org/multipage/form-elements.html#the-button-element)
944/// - [Button type attribute](https://html.spec.whatwg.org/multipage/form-elements.html#attr-button-type)
945#[derive(Debug, Clone, Copy, PartialEq, Eq)]
946pub enum ButtonType {
947    /// Submit button that submits the form when activated. This is the
948    /// default if the button is within a form.
949    Submit,
950    /// Reset button that resets all form controls to their initial values.
951    Reset,
952    /// Regular button with no default behavior. Use with JavaScript event
953    /// handlers for custom functionality.
954    Button,
955}
956
957impl AttributeValue for ButtonType {
958    fn to_attr_value(&self) -> Cow<'static, str> {
959        Cow::Borrowed(match self {
960            Self::Submit => "submit",
961            Self::Reset => "reset",
962            Self::Button => "button",
963        })
964    }
965}
966
967/// The `autocomplete` attribute values.
968///
969/// # Purpose
970/// Controls browser autofill behavior for form fields, specifying what type
971/// of data the browser should suggest based on the user's stored information.
972///
973/// # Usage Context
974/// - Used with: `<input>`, `<textarea>`, `<select>`, `<form>` elements
975/// - Privacy: Users control what data is stored for autofill
976/// - UX: Improves form completion speed and accuracy
977///
978/// # Valid Values
979/// - `On`: Enable autofill with browser's default heuristics
980/// - `Off`: Disable autofill for this field
981/// - `Name`: Full name
982/// - `Email`: Email address
983/// - `Username`: Username or account name
984/// - `NewPassword`: New password (e.g., registration, password change)
985/// - `CurrentPassword`: Current password for login
986/// - `OneTimeCode`: One-time verification code (2FA, SMS)
987/// - `Organization`: Organization or company name
988/// - `StreetAddress`: Full street address
989/// - `Country`: Country or region code
990/// - `PostalCode`: ZIP or postal code
991/// - `CcNumber`: Credit card number
992/// - `CcExp`: Credit card expiration date
993/// - `CcCsc`: Credit card security code (CVV/CVC)
994/// - `Tel`: Telephone number
995/// - `Url`: URL or website address
996///
997/// # Example
998/// ```rust
999/// use ironhtml_attributes::{AttributeValue, Autocomplete};
1000/// let autocomplete = Autocomplete::Email;
1001/// assert_eq!(autocomplete.to_attr_value(), "email");
1002/// ```
1003///
1004/// ```html
1005/// <input type="email" autocomplete="email">
1006/// <input type="password" autocomplete="current-password">
1007/// <input type="text" autocomplete="name">
1008/// <input type="tel" autocomplete="tel">
1009/// <input type="text" autocomplete="street-address">
1010/// <input type="text" autocomplete="off">
1011/// ```
1012///
1013/// # WHATWG Specification
1014/// - [Autofill](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill)
1015/// - [Autocomplete attribute](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-autocomplete)
1016#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1017pub enum Autocomplete {
1018    /// Enable autofill with browser's default behavior.
1019    On,
1020    /// Disable autofill for this field (sensitive data, unique IDs).
1021    Off,
1022    /// Full name (combined given and family names).
1023    Name,
1024    /// Email address.
1025    Email,
1026    /// Username or account identifier.
1027    Username,
1028    /// New password being set (registration or password change forms).
1029    NewPassword,
1030    /// Current password for authentication (login forms).
1031    CurrentPassword,
1032    /// One-time code for two-factor authentication (SMS, authenticator app).
1033    OneTimeCode,
1034    /// Company or organization name.
1035    Organization,
1036    /// Full street address (may include multiple lines).
1037    StreetAddress,
1038    /// Country or region name/code.
1039    Country,
1040    /// Postal code or ZIP code.
1041    PostalCode,
1042    /// Credit card number.
1043    CcNumber,
1044    /// Credit card expiration date (month and year).
1045    CcExp,
1046    /// Credit card security code (CVV, CVC, CVV2).
1047    CcCsc,
1048    /// Telephone number including country code.
1049    Tel,
1050    /// URL or website address.
1051    Url,
1052}
1053
1054impl AttributeValue for Autocomplete {
1055    fn to_attr_value(&self) -> Cow<'static, str> {
1056        Cow::Borrowed(match self {
1057            Self::On => "on",
1058            Self::Off => "off",
1059            Self::Name => "name",
1060            Self::Email => "email",
1061            Self::Username => "username",
1062            Self::NewPassword => "new-password",
1063            Self::CurrentPassword => "current-password",
1064            Self::OneTimeCode => "one-time-code",
1065            Self::Organization => "organization",
1066            Self::StreetAddress => "street-address",
1067            Self::Country => "country",
1068            Self::PostalCode => "postal-code",
1069            Self::CcNumber => "cc-number",
1070            Self::CcExp => "cc-exp",
1071            Self::CcCsc => "cc-csc",
1072            Self::Tel => "tel",
1073            Self::Url => "url",
1074        })
1075    }
1076}
1077
1078/// The `method` attribute values for `<form>` elements.
1079///
1080/// # Purpose
1081/// Specifies the HTTP method used to submit the form data to the server,
1082/// controlling how data is sent and how it affects server state.
1083///
1084/// # Usage Context
1085/// - Used with: `<form>` elements
1086/// - Default: `get` if not specified
1087/// - Security: Use `post` for sensitive data or state-changing operations
1088///
1089/// # Valid Values
1090/// - `Get`: Submit data as URL query parameters (idempotent, cacheable)
1091/// - `Post`: Submit data in request body (for state changes, sensitive data)
1092/// - `Dialog`: Close dialog and submit without HTTP request
1093///
1094/// # Example
1095/// ```rust
1096/// use ironhtml_attributes::{AttributeValue, Method};
1097/// let method = Method::Post;
1098/// assert_eq!(method.to_attr_value(), "post");
1099/// ```
1100///
1101/// ```html
1102/// <form action="/search" method="get">...</form>
1103/// <form action="/login" method="post">...</form>
1104/// <form method="dialog">...</form>
1105/// ```
1106///
1107/// # WHATWG Specification
1108/// - [Form submission](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#form-submission-algorithm)
1109/// - [The `method` attribute](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fs-method)
1110#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1111pub enum Method {
1112    /// HTTP GET method. Data is appended to URL as query parameters.
1113    /// Use for searches, filters, and read-only operations.
1114    Get,
1115    /// HTTP POST method. Data is sent in request body. Use for creating
1116    /// or modifying data, and for sensitive information.
1117    Post,
1118    /// Dialog method. Closes the dialog containing the form without
1119    /// sending an HTTP request.
1120    Dialog,
1121}
1122
1123impl AttributeValue for Method {
1124    fn to_attr_value(&self) -> Cow<'static, str> {
1125        Cow::Borrowed(match self {
1126            Self::Get => "get",
1127            Self::Post => "post",
1128            Self::Dialog => "dialog",
1129        })
1130    }
1131}
1132
1133/// The `enctype` attribute values for form encoding.
1134///
1135/// # Purpose
1136/// Specifies how form data should be encoded before sending to the server,
1137/// which is critical for proper handling of different types of form content.
1138///
1139/// # Usage Context
1140/// - Used with: `<form>` elements (and `<input>`/`<button>` with `formenctype`)
1141/// - Only relevant: When `method="post"`
1142/// - Default: `application/x-www-form-urlencoded`
1143///
1144/// # Valid Values
1145/// - `UrlEncoded`: Standard URL-encoded format (default)
1146/// - `Multipart`: Multipart form data (required for file uploads)
1147/// - `Plain`: Plain text format (rarely used, debugging only)
1148///
1149/// # Example
1150/// ```rust
1151/// use ironhtml_attributes::{AttributeValue, Enctype};
1152/// let enctype = Enctype::Multipart;
1153/// assert_eq!(enctype.to_attr_value(), "multipart/form-data");
1154/// ```
1155///
1156/// ```html
1157/// <form action="/submit" method="post" enctype="application/x-www-form-urlencoded">...</form>
1158/// <form action="/upload" method="post" enctype="multipart/form-data">
1159///   <input type="file" name="document">
1160/// </form>
1161/// <form action="/feedback" method="post" enctype="text/plain">...</form>
1162/// ```
1163///
1164/// # WHATWG Specification
1165/// - [Form submission](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#form-submission-algorithm)
1166/// - [The `enctype` attribute](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fs-enctype)
1167#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1168pub enum Enctype {
1169    /// URL-encoded format: `application/x-www-form-urlencoded`.
1170    /// Default encoding for forms. Key-value pairs are URL-encoded.
1171    UrlEncoded,
1172    /// Multipart format: `multipart/form-data`.
1173    /// Required for forms containing file uploads (`<input type="file">`).
1174    Multipart,
1175    /// Plain text format: `text/plain`.
1176    /// Data sent as plain text. Rarely used except for debugging.
1177    Plain,
1178}
1179
1180impl AttributeValue for Enctype {
1181    fn to_attr_value(&self) -> Cow<'static, str> {
1182        Cow::Borrowed(match self {
1183            Self::UrlEncoded => "application/x-www-form-urlencoded",
1184            Self::Multipart => "multipart/form-data",
1185            Self::Plain => "text/plain",
1186        })
1187    }
1188}
1189
1190/// The `wrap` attribute values for `<textarea>` elements.
1191///
1192/// # Purpose
1193/// Controls how text wrapping is handled when submitting textarea content,
1194/// determining whether hard line breaks are inserted at wrap points.
1195///
1196/// # Usage Context
1197/// - Used with: `<textarea>` elements only
1198/// - Default: `soft` if not specified
1199/// - Form submission: Affects submitted text formatting
1200///
1201/// # Valid Values
1202/// - `Hard`: Insert newlines at wrap points when submitting
1203/// - `Soft`: No newlines inserted (visual wrapping only)
1204/// - `Off`: Disable wrapping entirely
1205///
1206/// # Example
1207/// ```rust
1208/// use ironhtml_attributes::{AttributeValue, Wrap};
1209/// let wrap = Wrap::Hard;
1210/// assert_eq!(wrap.to_attr_value(), "hard");
1211/// ```
1212///
1213/// ```html
1214/// <textarea wrap="soft" cols="40">Visual wrapping only</textarea>
1215/// <textarea wrap="hard" cols="40">Newlines inserted at wrap</textarea>
1216/// <textarea wrap="off">No wrapping</textarea>
1217/// ```
1218///
1219/// # WHATWG Specification
1220/// - [The `textarea` element](https://html.spec.whatwg.org/multipage/form-elements.html#the-textarea-element)
1221/// - [The `wrap` attribute](https://html.spec.whatwg.org/multipage/form-elements.html#attr-textarea-wrap)
1222#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1223pub enum Wrap {
1224    /// Hard wrapping. Browser inserts newline characters (CR+LF) at line
1225    /// wrap points when submitting the form. Requires `cols` attribute.
1226    Hard,
1227    /// Soft wrapping (default). Text wraps visually but no newlines are
1228    /// inserted in the submitted value.
1229    Soft,
1230    /// No wrapping. Text does not wrap; horizontal scrolling may occur.
1231    Off,
1232}
1233
1234impl AttributeValue for Wrap {
1235    fn to_attr_value(&self) -> Cow<'static, str> {
1236        Cow::Borrowed(match self {
1237            Self::Hard => "hard",
1238            Self::Soft => "soft",
1239            Self::Off => "off",
1240        })
1241    }
1242}
1243
1244/// The `scope` attribute values for table header cells.
1245///
1246/// # Purpose
1247/// Specifies which cells a header (`<th>`) element applies to, improving
1248/// table accessibility by defining the relationship between headers and data.
1249///
1250/// # Usage Context
1251/// - Used with: `<th>` elements only
1252/// - Accessibility: Critical for screen readers to understand table structure
1253/// - Required: For complex tables with multiple header levels
1254///
1255/// # Valid Values
1256/// - `Row`: Header applies to all cells in the same row
1257/// - `Col`: Header applies to all cells in the same column
1258/// - `Rowgroup`: Header applies to row group (`<tbody>`, `<thead>`, `<tfoot>`)
1259/// - `Colgroup`: Header applies to column group (`<colgroup>`)
1260///
1261/// # Example
1262/// ```rust
1263/// use ironhtml_attributes::{AttributeValue, Scope};
1264/// let scope = Scope::Col;
1265/// assert_eq!(scope.to_attr_value(), "col");
1266/// ```
1267///
1268/// ```html
1269/// <table>
1270///   <thead>
1271///     <tr>
1272///       <th scope="col">Name</th>
1273///       <th scope="col">Age</th>
1274///     </tr>
1275///   </thead>
1276///   <tbody>
1277///     <tr>
1278///       <th scope="row">John</th>
1279///       <td>30</td>
1280///     </tr>
1281///   </tbody>
1282/// </table>
1283/// ```
1284///
1285/// # WHATWG Specification
1286/// - [The `th` element](https://html.spec.whatwg.org/multipage/tables.html#the-th-element)
1287/// - [The `scope` attribute](https://html.spec.whatwg.org/multipage/tables.html#attr-th-scope)
1288#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1289pub enum Scope {
1290    /// Header applies to all cells in the same row.
1291    Row,
1292    /// Header applies to all cells in the same column.
1293    Col,
1294    /// Header applies to all cells in the row group (`<tbody>`, `<thead>`,
1295    /// or `<tfoot>`).
1296    Rowgroup,
1297    /// Header applies to all cells in the column group (`<colgroup>`).
1298    Colgroup,
1299}
1300
1301impl AttributeValue for Scope {
1302    fn to_attr_value(&self) -> Cow<'static, str> {
1303        Cow::Borrowed(match self {
1304            Self::Row => "row",
1305            Self::Col => "col",
1306            Self::Rowgroup => "rowgroup",
1307            Self::Colgroup => "colgroup",
1308        })
1309    }
1310}
1311
1312/// The `preload` attribute values for media elements.
1313///
1314/// # Purpose
1315/// Provides a hint to the browser about what media data to preload, balancing
1316/// user experience with bandwidth and resource consumption.
1317///
1318/// # Usage Context
1319/// - Used with: `<audio>`, `<video>` elements
1320/// - Performance: Controls bandwidth usage and buffering behavior
1321/// - Default: Browser-dependent (typically `metadata`)
1322///
1323/// # Valid Values
1324/// - `None`: Don't preload any data
1325/// - `Metadata`: Preload only metadata (duration, dimensions, first frame)
1326/// - `Auto`: Browser decides how much to preload (may load entire file)
1327///
1328/// # Example
1329/// ```rust
1330/// use ironhtml_attributes::{AttributeValue, Preload};
1331/// let preload = Preload::Metadata;
1332/// assert_eq!(preload.to_attr_value(), "metadata");
1333/// ```
1334///
1335/// ```html
1336/// <video src="movie.mp4" preload="none" controls></video>
1337/// <video src="tutorial.mp4" preload="metadata" controls></video>
1338/// <audio src="music.mp3" preload="auto" controls></audio>
1339/// ```
1340///
1341/// # WHATWG Specification
1342/// - [Media elements](https://html.spec.whatwg.org/multipage/media.html#media-elements)
1343/// - [The `preload` attribute](https://html.spec.whatwg.org/multipage/media.html#attr-media-preload)
1344#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1345pub enum Preload {
1346    /// Don't preload any data. Minimizes bandwidth usage. User must
1347    /// explicitly start playback.
1348    None,
1349    /// Preload only metadata (duration, dimensions, track list, first frame).
1350    /// Good balance between UX and bandwidth.
1351    Metadata,
1352    /// Browser decides whether to preload data. May download the entire
1353    /// resource. Optimizes for user experience.
1354    Auto,
1355}
1356
1357impl AttributeValue for Preload {
1358    fn to_attr_value(&self) -> Cow<'static, str> {
1359        Cow::Borrowed(match self {
1360            Self::None => "none",
1361            Self::Metadata => "metadata",
1362            Self::Auto => "auto",
1363        })
1364    }
1365}
1366
1367/// The `kind` attribute values for `<track>` elements.
1368///
1369/// # Purpose
1370/// Specifies the type of text track, defining how the track content should
1371/// be interpreted and displayed for media accessibility and enhancement.
1372///
1373/// # Usage Context
1374/// - Used with: `<track>` elements (within `<audio>` or `<video>`)
1375/// - Accessibility: Subtitles and captions are crucial for accessibility
1376/// - Format: Tracks typically use `WebVTT` format
1377///
1378/// # Valid Values
1379/// - `Subtitles`: Transcription or translation for dialogue
1380/// - `Captions`: Transcription including sound effects (for hearing impaired)
1381/// - `Descriptions`: Text descriptions of visual content (for visually impaired)
1382/// - `Chapters`: Chapter titles for media navigation
1383/// - `Metadata`: Track for scripts (not displayed to user)
1384///
1385/// # Example
1386/// ```rust
1387/// use ironhtml_attributes::{AttributeValue, TrackKind};
1388/// let kind = TrackKind::Subtitles;
1389/// assert_eq!(kind.to_attr_value(), "subtitles");
1390/// ```
1391///
1392/// ```html
1393/// <video src="movie.mp4" controls>
1394///   <track kind="subtitles" src="subs-en.vtt" srclang="en" label="English">
1395///   <track kind="captions" src="caps-en.vtt" srclang="en" label="English CC">
1396///   <track kind="descriptions" src="desc.vtt" srclang="en">
1397///   <track kind="chapters" src="chapters.vtt" srclang="en">
1398/// </video>
1399/// ```
1400///
1401/// # WHATWG Specification
1402/// - [The `track` element](https://html.spec.whatwg.org/multipage/media.html#the-track-element)
1403/// - [Text track kind](https://html.spec.whatwg.org/multipage/media.html#attr-track-kind)
1404#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1405pub enum TrackKind {
1406    /// Subtitles provide translation of dialogue and text for users who
1407    /// understand the audio but need translation.
1408    Subtitles,
1409    /// Captions provide transcription and possibly translation of audio,
1410    /// including sound effects, music, and other audio information.
1411    Captions,
1412    /// Descriptions provide textual descriptions of video content for
1413    /// visually impaired users.
1414    Descriptions,
1415    /// Chapters provide chapter titles for media navigation and structure.
1416    Chapters,
1417    /// Metadata tracks are not displayed but used by scripts for enhanced
1418    /// interactivity.
1419    Metadata,
1420}
1421
1422impl AttributeValue for TrackKind {
1423    fn to_attr_value(&self) -> Cow<'static, str> {
1424        Cow::Borrowed(match self {
1425            Self::Subtitles => "subtitles",
1426            Self::Captions => "captions",
1427            Self::Descriptions => "descriptions",
1428            Self::Chapters => "chapters",
1429            Self::Metadata => "metadata",
1430        })
1431    }
1432}
1433
1434/// The `sandbox` attribute values for `<iframe>` elements.
1435///
1436/// # Purpose
1437/// Enables extra restrictions on iframe content for security, allowing fine-grained
1438/// control over what capabilities the embedded content has access to.
1439///
1440/// # Usage Context
1441/// - Used with: `<iframe>` elements
1442/// - Security: Applies strict sandbox by default; flags allow specific capabilities
1443/// - Multiple values: Space-separated list of allowed capabilities
1444/// - Default: Empty sandbox (most restrictive)
1445///
1446/// # Valid Values
1447/// - `AllowForms`: Allow form submission
1448/// - `AllowModals`: Allow opening modal windows (alert, confirm, print)
1449/// - `AllowOrientationLock`: Allow screen orientation lock
1450/// - `AllowPointerLock`: Allow Pointer Lock API
1451/// - `AllowPopups`: Allow popups (window.open, target="_blank")
1452/// - `AllowPopupsToEscapeSandbox`: Allow popups without sandbox restrictions
1453/// - `AllowPresentation`: Allow Presentation API
1454/// - `AllowSameOrigin`: Treat content as same-origin (use with caution)
1455/// - `AllowScripts`: Allow JavaScript execution
1456/// - `AllowTopNavigation`: Allow navigating top-level browsing context
1457/// - `AllowTopNavigationByUserActivation`: Allow top navigation only from user gesture
1458///
1459/// # Example
1460/// ```rust
1461/// use ironhtml_attributes::{AttributeValue, Sandbox};
1462/// let sandbox = Sandbox::AllowScripts;
1463/// assert_eq!(sandbox.to_attr_value(), "allow-scripts");
1464/// ```
1465///
1466/// ```html
1467/// <iframe src="untrusted.html" sandbox></iframe>
1468/// <iframe src="widget.html" sandbox="allow-scripts allow-same-origin"></iframe>
1469/// <iframe src="game.html" sandbox="allow-scripts allow-pointer-lock"></iframe>
1470/// ```
1471///
1472/// # WHATWG Specification
1473/// - [The `iframe` element](https://html.spec.whatwg.org/multipage/iframe-embed-object.html#the-iframe-element)
1474/// - [The `sandbox` attribute](https://html.spec.whatwg.org/multipage/iframe-embed-object.html#attr-iframe-sandbox)
1475#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1476pub enum Sandbox {
1477    /// Allow form submission from the sandboxed content.
1478    AllowForms,
1479    /// Allow the sandboxed content to open modal windows (alert, confirm,
1480    /// print, etc.).
1481    AllowModals,
1482    /// Allow the sandboxed content to lock the screen orientation.
1483    AllowOrientationLock,
1484    /// Allow the sandboxed content to use the Pointer Lock API.
1485    AllowPointerLock,
1486    /// Allow the sandboxed content to open popup windows.
1487    AllowPopups,
1488    /// Allow popups opened by the sandboxed content to not inherit the
1489    /// sandbox restrictions.
1490    AllowPopupsToEscapeSandbox,
1491    /// Allow the sandboxed content to use the Presentation API.
1492    AllowPresentation,
1493    /// Allow the content to be treated as being from its normal origin.
1494    /// WARNING: Dangerous when combined with `allow-scripts`.
1495    AllowSameOrigin,
1496    /// Allow the sandboxed content to run scripts (but not create popups).
1497    AllowScripts,
1498    /// Allow the sandboxed content to navigate the top-level browsing
1499    /// context (the full window).
1500    AllowTopNavigation,
1501    /// Allow top-level navigation only when triggered by user activation
1502    /// (safer than `allow-top-navigation`).
1503    AllowTopNavigationByUserActivation,
1504}
1505
1506impl AttributeValue for Sandbox {
1507    fn to_attr_value(&self) -> Cow<'static, str> {
1508        Cow::Borrowed(match self {
1509            Self::AllowForms => "allow-forms",
1510            Self::AllowModals => "allow-modals",
1511            Self::AllowOrientationLock => "allow-orientation-lock",
1512            Self::AllowPointerLock => "allow-pointer-lock",
1513            Self::AllowPopups => "allow-popups",
1514            Self::AllowPopupsToEscapeSandbox => "allow-popups-to-escape-sandbox",
1515            Self::AllowPresentation => "allow-presentation",
1516            Self::AllowSameOrigin => "allow-same-origin",
1517            Self::AllowScripts => "allow-scripts",
1518            Self::AllowTopNavigation => "allow-top-navigation",
1519            Self::AllowTopNavigationByUserActivation => "allow-top-navigation-by-user-activation",
1520        })
1521    }
1522}
1523
1524// =============================================================================
1525// Global Attributes
1526// =============================================================================
1527
1528/// Attribute names for global HTML attributes.
1529///
1530/// # Purpose
1531/// Global attributes can be used on any HTML element, providing common
1532/// functionality like styling, identification, accessibility, and interaction
1533/// control across all elements.
1534///
1535/// # Common Attributes
1536/// - `class`: Space-separated CSS class names for styling
1537/// - `id`: Unique identifier for the element
1538/// - `style`: Inline CSS styles
1539/// - `title`: Advisory information (tooltip text)
1540/// - `lang`: Language of the element's content
1541/// - `dir`: Text directionality (ltr, rtl, auto)
1542/// - `tabindex`: Tab order for keyboard navigation
1543/// - `hidden`: Hides element from rendering
1544/// - `contenteditable`: Makes element content editable
1545/// - `draggable`: Enables drag-and-drop
1546/// - `role`: ARIA role for accessibility
1547///
1548/// # Example
1549/// ```html
1550/// <div class="container" id="main" lang="en" dir="ltr">
1551///   <p class="text" title="Helpful tooltip" tabindex="0">Content</p>
1552///   <span role="button" draggable="true">Drag me</span>
1553/// </div>
1554/// ```
1555///
1556/// # WHATWG Specification
1557/// - [Global attributes](https://html.spec.whatwg.org/multipage/dom.html#global-attributes)
1558pub mod global {
1559    /// The `class` attribute.
1560    ///
1561    /// Space-separated list of CSS class names for styling and JavaScript selection.
1562    pub const CLASS: &str = "class";
1563
1564    /// The `id` attribute.
1565    ///
1566    /// Unique identifier for the element within the document.
1567    pub const ID: &str = "id";
1568
1569    /// The `style` attribute.
1570    ///
1571    /// Inline CSS style declarations for the element.
1572    pub const STYLE: &str = "style";
1573
1574    /// The `title` attribute.
1575    ///
1576    /// Advisory information displayed as a tooltip on hover.
1577    pub const TITLE: &str = "title";
1578
1579    /// The `lang` attribute.
1580    ///
1581    /// Language of the element's content (e.g., "en", "es", "fr").
1582    pub const LANG: &str = "lang";
1583
1584    /// The `dir` attribute.
1585    ///
1586    /// Text directionality: "ltr" (left-to-right), "rtl" (right-to-left), or "auto".
1587    pub const DIR: &str = "dir";
1588
1589    /// The `tabindex` attribute.
1590    ///
1591    /// Controls tab order for keyboard navigation. Values: positive (explicit order),
1592    /// 0 (natural order), -1 (programmatically focusable only).
1593    pub const TABINDEX: &str = "tabindex";
1594
1595    /// The `accesskey` attribute.
1596    ///
1597    /// Keyboard shortcut to activate or focus the element.
1598    pub const ACCESSKEY: &str = "accesskey";
1599
1600    /// The `contenteditable` attribute.
1601    ///
1602    /// Indicates whether the element's content is editable: "true", "false", or "inherit".
1603    pub const CONTENTEDITABLE: &str = "contenteditable";
1604
1605    /// The `draggable` attribute.
1606    ///
1607    /// Indicates whether the element can be dragged: "true" or "false".
1608    pub const DRAGGABLE: &str = "draggable";
1609
1610    /// The `hidden` attribute.
1611    ///
1612    /// Boolean attribute that hides the element from rendering and accessibility tree.
1613    /// Can also use "until-found" for searchable hidden content.
1614    pub const HIDDEN: &str = "hidden";
1615
1616    /// The `spellcheck` attribute.
1617    ///
1618    /// Controls spell-checking for editable content: "true" or "false".
1619    pub const SPELLCHECK: &str = "spellcheck";
1620
1621    /// The `translate` attribute.
1622    ///
1623    /// Indicates whether content should be translated: "yes" or "no".
1624    pub const TRANSLATE: &str = "translate";
1625
1626    /// The `role` attribute.
1627    ///
1628    /// ARIA role for accessibility, defining the element's purpose for assistive technologies.
1629    pub const ROLE: &str = "role";
1630
1631    /// The `slot` attribute.
1632    ///
1633    /// Assigns the element to a named slot in a shadow DOM template.
1634    pub const SLOT: &str = "slot";
1635}
1636
1637// =============================================================================
1638// Element-Specific Attribute Names
1639// =============================================================================
1640
1641/// Attribute names for anchor (`<a>`) elements.
1642///
1643/// # Purpose
1644/// The `<a>` element creates hyperlinks to other pages, locations within the
1645/// same page, files, email addresses, or any other URL.
1646///
1647/// # Common Attributes
1648/// - `href`: The URL that the hyperlink points to
1649/// - `target`: Where to display the linked URL (_blank, _self, _parent, _top)
1650/// - `rel`: Relationship between current and linked document
1651/// - `download`: Suggests downloading the linked resource
1652/// - `referrerpolicy`: Controls referrer information sent with requests
1653///
1654/// # Example
1655/// ```html
1656/// <a href="https://example.com" target="_blank" rel="noopener noreferrer">
1657///   External Link
1658/// </a>
1659/// <a href="/page" hreflang="en">Internal Link</a>
1660/// <a href="document.pdf" download="filename.pdf">Download PDF</a>
1661/// ```
1662///
1663/// # WHATWG Specification
1664/// - [The `a` element](https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-a-element)
1665pub mod anchor {
1666    /// The `href` attribute.
1667    ///
1668    /// URL or URL fragment that the hyperlink points to.
1669    pub const HREF: &str = "href";
1670
1671    /// The `target` attribute.
1672    ///
1673    /// Browsing context for link navigation: "_blank", "_self", "_parent", "_top",
1674    /// or a named context.
1675    pub const TARGET: &str = "target";
1676
1677    /// The `rel` attribute.
1678    ///
1679    /// Relationship between current document and linked resource (e.g., "noopener",
1680    /// "noreferrer", "nofollow").
1681    pub const REL: &str = "rel";
1682
1683    /// The `download` attribute.
1684    ///
1685    /// Prompts to download the linked resource. Value suggests the filename.
1686    pub const DOWNLOAD: &str = "download";
1687
1688    /// The `hreflang` attribute.
1689    ///
1690    /// Language of the linked resource (e.g., "en", "es", "fr").
1691    pub const HREFLANG: &str = "hreflang";
1692
1693    /// The `type` attribute.
1694    ///
1695    /// MIME type hint for the linked resource (e.g., "application/pdf").
1696    pub const TYPE: &str = "type";
1697
1698    /// The `referrerpolicy` attribute.
1699    ///
1700    /// Controls how much referrer information is sent when following the link.
1701    pub const REFERRERPOLICY: &str = "referrerpolicy";
1702}
1703
1704/// Attribute names for image (`<img>`) elements.
1705///
1706/// # Purpose
1707/// The `<img>` element embeds images into documents. It supports responsive
1708/// images, lazy loading, and various performance optimization features.
1709///
1710/// # Common Attributes
1711/// - `src`: Image source URL (required)
1712/// - `alt`: Alternative text for accessibility (required)
1713/// - `width`/`height`: Dimensions to prevent layout shift
1714/// - `loading`: Lazy loading behavior (eager/lazy)
1715/// - `srcset`: Responsive image sources
1716/// - `sizes`: Image sizes for different viewport widths
1717///
1718/// # Example
1719/// ```html
1720/// <img src="photo.jpg" alt="A beautiful sunset" width="800" height="600">
1721/// <img src="hero.jpg" alt="Hero" loading="eager">
1722/// <img src="gallery.jpg" alt="Gallery" loading="lazy"
1723///      srcset="small.jpg 480w, large.jpg 1024w" sizes="(max-width: 600px) 480px, 1024px">
1724/// ```
1725///
1726/// # WHATWG Specification
1727/// - [The `img` element](https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-element)
1728pub mod img {
1729    /// The `src` attribute.
1730    ///
1731    /// URL of the image resource. Required unless `srcset` is used.
1732    pub const SRC: &str = "src";
1733
1734    /// The `alt` attribute.
1735    ///
1736    /// Alternative text description for accessibility. Required for valid HTML.
1737    pub const ALT: &str = "alt";
1738
1739    /// The `width` attribute.
1740    ///
1741    /// Intrinsic width of the image in pixels. Helps prevent layout shift.
1742    pub const WIDTH: &str = "width";
1743
1744    /// The `height` attribute.
1745    ///
1746    /// Intrinsic height of the image in pixels. Helps prevent layout shift.
1747    pub const HEIGHT: &str = "height";
1748
1749    /// The `loading` attribute.
1750    ///
1751    /// Loading behavior: "eager" (immediate) or "lazy" (when near viewport).
1752    pub const LOADING: &str = "loading";
1753
1754    /// The `decoding` attribute.
1755    ///
1756    /// Image decoding hint: "sync", "async", or "auto".
1757    pub const DECODING: &str = "decoding";
1758
1759    /// The `crossorigin` attribute.
1760    ///
1761    /// CORS settings: "anonymous" or "use-credentials".
1762    pub const CROSSORIGIN: &str = "crossorigin";
1763
1764    /// The `referrerpolicy` attribute.
1765    ///
1766    /// Controls referrer information sent when fetching the image.
1767    pub const REFERRERPOLICY: &str = "referrerpolicy";
1768
1769    /// The `srcset` attribute.
1770    ///
1771    /// Comma-separated list of image sources with width or pixel density descriptors
1772    /// for responsive images.
1773    pub const SRCSET: &str = "srcset";
1774
1775    /// The `sizes` attribute.
1776    ///
1777    /// Media conditions and image sizes for responsive images (used with `srcset`).
1778    pub const SIZES: &str = "sizes";
1779
1780    /// The `usemap` attribute.
1781    ///
1782    /// Associates the image with an image map (`<map>` element).
1783    pub const USEMAP: &str = "usemap";
1784
1785    /// The `ismap` attribute.
1786    ///
1787    /// Boolean attribute indicating server-side image map.
1788    pub const ISMAP: &str = "ismap";
1789}
1790
1791/// Attribute names for input (`<input>`) elements.
1792///
1793/// # Purpose
1794/// The `<input>` element creates interactive form controls for collecting user
1795/// data. It supports numerous input types from text to files, with extensive
1796/// validation and constraint capabilities.
1797///
1798/// # Common Attributes
1799/// - `type`: Input control type (text, email, password, etc.)
1800/// - `name`: Form control name for submission
1801/// - `value`: Current value of the control
1802/// - `placeholder`: Hint text displayed when empty
1803/// - `required`: Boolean indicating required field
1804/// - `pattern`: Regular expression for validation
1805/// - `min`/`max`: Range constraints for numeric/date inputs
1806///
1807/// # Example
1808/// ```html
1809/// <input type="text" name="username" placeholder="Enter username" required>
1810/// <input type="email" name="email" autocomplete="email">
1811/// <input type="password" name="pass" minlength="8" autocomplete="current-password">
1812/// <input type="number" name="age" min="0" max="120" step="1">
1813/// <input type="file" name="upload" accept="image/*" multiple>
1814/// ```
1815///
1816/// # WHATWG Specification
1817/// - [The `input` element](https://html.spec.whatwg.org/multipage/input.html#the-input-element)
1818pub mod input {
1819    /// The `type` attribute.
1820    ///
1821    /// Specifies the input control type (text, email, password, number, etc.).
1822    pub const TYPE: &str = "type";
1823
1824    /// The `name` attribute.
1825    ///
1826    /// Name of the form control, submitted with the form data.
1827    pub const NAME: &str = "name";
1828
1829    /// The `value` attribute.
1830    ///
1831    /// Current value of the form control.
1832    pub const VALUE: &str = "value";
1833
1834    /// The `placeholder` attribute.
1835    ///
1836    /// Hint text displayed when the input is empty.
1837    pub const PLACEHOLDER: &str = "placeholder";
1838
1839    /// The `required` attribute.
1840    ///
1841    /// Boolean indicating the field must be filled before form submission.
1842    pub const REQUIRED: &str = "required";
1843
1844    /// The `disabled` attribute.
1845    ///
1846    /// Boolean disabling the input (not submitted, not editable).
1847    pub const DISABLED: &str = "disabled";
1848
1849    /// The `readonly` attribute.
1850    ///
1851    /// Boolean making the input read-only (submitted but not editable).
1852    pub const READONLY: &str = "readonly";
1853
1854    /// The `checked` attribute.
1855    ///
1856    /// Boolean for checkbox/radio inputs indicating checked state.
1857    pub const CHECKED: &str = "checked";
1858
1859    /// The `autocomplete` attribute.
1860    ///
1861    /// Controls autofill behavior (on, off, email, username, etc.).
1862    pub const AUTOCOMPLETE: &str = "autocomplete";
1863
1864    /// The `autofocus` attribute.
1865    ///
1866    /// Boolean to automatically focus this input when page loads.
1867    pub const AUTOFOCUS: &str = "autofocus";
1868
1869    /// The `min` attribute.
1870    ///
1871    /// Minimum value for numeric, date, or time inputs.
1872    pub const MIN: &str = "min";
1873
1874    /// The `max` attribute.
1875    ///
1876    /// Maximum value for numeric, date, or time inputs.
1877    pub const MAX: &str = "max";
1878
1879    /// The `step` attribute.
1880    ///
1881    /// Increment step for numeric or date/time inputs.
1882    pub const STEP: &str = "step";
1883
1884    /// The `minlength` attribute.
1885    ///
1886    /// Minimum character length for text inputs.
1887    pub const MINLENGTH: &str = "minlength";
1888
1889    /// The `maxlength` attribute.
1890    ///
1891    /// Maximum character length for text inputs.
1892    pub const MAXLENGTH: &str = "maxlength";
1893
1894    /// The `pattern` attribute.
1895    ///
1896    /// Regular expression for input validation.
1897    pub const PATTERN: &str = "pattern";
1898
1899    /// The `size` attribute.
1900    ///
1901    /// Visual width of the input in characters.
1902    pub const SIZE: &str = "size";
1903
1904    /// The `accept` attribute.
1905    ///
1906    /// File types accepted by file inputs (MIME types or extensions).
1907    pub const ACCEPT: &str = "accept";
1908
1909    /// The `multiple` attribute.
1910    ///
1911    /// Boolean allowing multiple values (for file or email inputs).
1912    pub const MULTIPLE: &str = "multiple";
1913
1914    /// The `list` attribute.
1915    ///
1916    /// ID of a `<datalist>` element providing autocomplete suggestions.
1917    pub const LIST: &str = "list";
1918
1919    /// The `form` attribute.
1920    ///
1921    /// ID of the form this input belongs to (if outside the form element).
1922    pub const FORM: &str = "form";
1923}
1924
1925/// Attribute names for button (`<button>`) elements.
1926///
1927/// # Purpose
1928/// The `<button>` element represents a clickable button that can submit forms,
1929/// reset forms, or trigger custom JavaScript actions.
1930///
1931/// # Common Attributes
1932/// - `type`: Button behavior (submit, reset, button)
1933/// - `name`: Form control name for submission
1934/// - `value`: Value submitted with form
1935/// - `disabled`: Disables the button
1936/// - `form`: Associates button with a form by ID
1937///
1938/// # Example
1939/// ```html
1940/// <button type="submit" name="action" value="save">Save</button>
1941/// <button type="reset">Reset Form</button>
1942/// <button type="button" onclick="handleClick()">Click Me</button>
1943/// <button type="submit" formaction="/alt" formmethod="post">Alternative Submit</button>
1944/// ```
1945///
1946/// # WHATWG Specification
1947/// - [The `button` element](https://html.spec.whatwg.org/multipage/form-elements.html#the-button-element)
1948pub mod button {
1949    /// The `type` attribute.
1950    ///
1951    /// Button behavior: "submit", "reset", or "button".
1952    pub const TYPE: &str = "type";
1953
1954    /// The `name` attribute.
1955    ///
1956    /// Name of the button, submitted with form data when clicked.
1957    pub const NAME: &str = "name";
1958
1959    /// The `value` attribute.
1960    ///
1961    /// Value submitted with the form when this button is clicked.
1962    pub const VALUE: &str = "value";
1963
1964    /// The `disabled` attribute.
1965    ///
1966    /// Boolean disabling the button (not interactive, not submitted).
1967    pub const DISABLED: &str = "disabled";
1968
1969    /// The `autofocus` attribute.
1970    ///
1971    /// Boolean to automatically focus this button when page loads.
1972    pub const AUTOFOCUS: &str = "autofocus";
1973
1974    /// The `form` attribute.
1975    ///
1976    /// ID of the form this button is associated with.
1977    pub const FORM: &str = "form";
1978
1979    /// The `formaction` attribute.
1980    ///
1981    /// URL to submit the form to (overrides form's action).
1982    pub const FORMACTION: &str = "formaction";
1983
1984    /// The `formmethod` attribute.
1985    ///
1986    /// HTTP method for form submission (overrides form's method).
1987    pub const FORMMETHOD: &str = "formmethod";
1988
1989    /// The `formenctype` attribute.
1990    ///
1991    /// Form encoding type (overrides form's enctype).
1992    pub const FORMENCTYPE: &str = "formenctype";
1993
1994    /// The `formnovalidate` attribute.
1995    ///
1996    /// Boolean to skip form validation when submitting.
1997    pub const FORMNOVALIDATE: &str = "formnovalidate";
1998
1999    /// The `formtarget` attribute.
2000    ///
2001    /// Browsing context for form submission (overrides form's target).
2002    pub const FORMTARGET: &str = "formtarget";
2003}
2004
2005/// Attribute names for form (`<form>`) elements.
2006///
2007/// # Purpose
2008/// The `<form>` element represents a document section containing interactive
2009/// controls for submitting information to a server.
2010///
2011/// # Common Attributes
2012/// - `action`: URL to submit the form data to
2013/// - `method`: HTTP method (GET or POST)
2014/// - `enctype`: Encoding type for form data
2015/// - `novalidate`: Skip browser validation
2016/// - `autocomplete`: Controls autofill for all form fields
2017///
2018/// # Example
2019/// ```html
2020/// <form action="/submit" method="post" enctype="multipart/form-data">
2021///   <input type="file" name="upload">
2022///   <button type="submit">Upload</button>
2023/// </form>
2024/// <form action="/search" method="get" autocomplete="off">
2025///   <input type="text" name="q">
2026/// </form>
2027/// ```
2028///
2029/// # WHATWG Specification
2030/// - [The `form` element](https://html.spec.whatwg.org/multipage/forms.html#the-form-element)
2031pub mod form {
2032    /// The `action` attribute.
2033    ///
2034    /// URL where the form data will be submitted.
2035    pub const ACTION: &str = "action";
2036
2037    /// The `method` attribute.
2038    ///
2039    /// HTTP method for form submission: "get", "post", or "dialog".
2040    pub const METHOD: &str = "method";
2041
2042    /// The `enctype` attribute.
2043    ///
2044    /// Encoding type for form data: "application/x-www-form-urlencoded",
2045    /// "multipart/form-data", or "text/plain".
2046    pub const ENCTYPE: &str = "enctype";
2047
2048    /// The `target` attribute.
2049    ///
2050    /// Browsing context for displaying the response (_blank, _self, etc.).
2051    pub const TARGET: &str = "target";
2052
2053    /// The `novalidate` attribute.
2054    ///
2055    /// Boolean to skip HTML5 form validation on submission.
2056    pub const NOVALIDATE: &str = "novalidate";
2057
2058    /// The `autocomplete` attribute.
2059    ///
2060    /// Controls autofill for all form controls: "on" or "off".
2061    pub const AUTOCOMPLETE: &str = "autocomplete";
2062
2063    /// The `name` attribute.
2064    ///
2065    /// Name of the form for document.forms collection.
2066    pub const NAME: &str = "name";
2067
2068    /// The `accept-charset` attribute.
2069    ///
2070    /// Character encodings accepted for form submission.
2071    pub const ACCEPTCHARSET: &str = "accept-charset";
2072}
2073
2074/// Attribute names for textarea (`<textarea>`) elements.
2075///
2076/// # Purpose
2077/// The `<textarea>` element represents a multi-line plain text editing control,
2078/// useful for collecting longer text input from users.
2079///
2080/// # Common Attributes
2081/// - `name`: Form control name for submission
2082/// - `rows`/`cols`: Visual dimensions in characters
2083/// - `placeholder`: Hint text when empty
2084/// - `maxlength`: Maximum character limit
2085/// - `wrap`: Text wrapping behavior (soft, hard, off)
2086/// - `required`: Makes the field mandatory
2087///
2088/// # Example
2089/// ```html
2090/// <textarea name="comments" rows="4" cols="50" placeholder="Enter comments"
2091///           maxlength="500" required></textarea>
2092/// <textarea name="code" wrap="off" spellcheck="false"></textarea>
2093/// ```
2094///
2095/// # WHATWG Specification
2096/// - [The `textarea` element](https://html.spec.whatwg.org/multipage/form-elements.html#the-textarea-element)
2097pub mod textarea {
2098    /// The `name` attribute.
2099    ///
2100    /// Name of the form control, submitted with the form data.
2101    pub const NAME: &str = "name";
2102
2103    /// The `placeholder` attribute.
2104    ///
2105    /// Hint text displayed when the textarea is empty.
2106    pub const PLACEHOLDER: &str = "placeholder";
2107
2108    /// The `required` attribute.
2109    ///
2110    /// Boolean indicating the field must be filled before form submission.
2111    pub const REQUIRED: &str = "required";
2112
2113    /// The `disabled` attribute.
2114    ///
2115    /// Boolean disabling the textarea (not submitted, not editable).
2116    pub const DISABLED: &str = "disabled";
2117
2118    /// The `readonly` attribute.
2119    ///
2120    /// Boolean making the textarea read-only (submitted but not editable).
2121    pub const READONLY: &str = "readonly";
2122
2123    /// The `autocomplete` attribute.
2124    ///
2125    /// Controls autofill behavior for the textarea.
2126    pub const AUTOCOMPLETE: &str = "autocomplete";
2127
2128    /// The `autofocus` attribute.
2129    ///
2130    /// Boolean to automatically focus this textarea when page loads.
2131    pub const AUTOFOCUS: &str = "autofocus";
2132
2133    /// The `rows` attribute.
2134    ///
2135    /// Number of visible text lines (height).
2136    pub const ROWS: &str = "rows";
2137
2138    /// The `cols` attribute.
2139    ///
2140    /// Visible width of the textarea in average character widths.
2141    pub const COLS: &str = "cols";
2142
2143    /// The `minlength` attribute.
2144    ///
2145    /// Minimum character length for validation.
2146    pub const MINLENGTH: &str = "minlength";
2147
2148    /// The `maxlength` attribute.
2149    ///
2150    /// Maximum character length allowed.
2151    pub const MAXLENGTH: &str = "maxlength";
2152
2153    /// The `wrap` attribute.
2154    ///
2155    /// Text wrapping behavior: "soft", "hard", or "off".
2156    pub const WRAP: &str = "wrap";
2157
2158    /// The `form` attribute.
2159    ///
2160    /// ID of the form this textarea belongs to.
2161    pub const FORM: &str = "form";
2162}
2163
2164/// Attribute names for select (`<select>`) elements.
2165///
2166/// # Purpose
2167/// The `<select>` element represents a control for selecting from a set of
2168/// options, displayed as a dropdown menu or list box.
2169///
2170/// # Common Attributes
2171/// - `name`: Form control name for submission
2172/// - `multiple`: Allows selecting multiple options
2173/// - `size`: Number of visible options (list vs dropdown)
2174/// - `required`: Makes selection mandatory
2175/// - `disabled`: Disables the control
2176///
2177/// # Example
2178/// ```html
2179/// <select name="country" required>
2180///   <option value="">Select a country</option>
2181///   <option value="us">United States</option>
2182///   <option value="uk">United Kingdom</option>
2183/// </select>
2184/// <select name="tags" multiple size="5">
2185///   <option>JavaScript</option>
2186///   <option>Python</option>
2187///   <option>Rust</option>
2188/// </select>
2189/// ```
2190///
2191/// # WHATWG Specification
2192/// - [The `select` element](https://html.spec.whatwg.org/multipage/form-elements.html#the-select-element)
2193pub mod select {
2194    /// The `name` attribute.
2195    ///
2196    /// Name of the form control, submitted with the form data.
2197    pub const NAME: &str = "name";
2198
2199    /// The `required` attribute.
2200    ///
2201    /// Boolean indicating an option must be selected before form submission.
2202    pub const REQUIRED: &str = "required";
2203
2204    /// The `disabled` attribute.
2205    ///
2206    /// Boolean disabling the select control (not submitted, not interactive).
2207    pub const DISABLED: &str = "disabled";
2208
2209    /// The `autofocus` attribute.
2210    ///
2211    /// Boolean to automatically focus this select when page loads.
2212    pub const AUTOFOCUS: &str = "autofocus";
2213
2214    /// The `multiple` attribute.
2215    ///
2216    /// Boolean allowing multiple option selection.
2217    pub const MULTIPLE: &str = "multiple";
2218
2219    /// The `size` attribute.
2220    ///
2221    /// Number of visible options. Values > 1 show as list box instead of dropdown.
2222    pub const SIZE: &str = "size";
2223
2224    /// The `form` attribute.
2225    ///
2226    /// ID of the form this select belongs to.
2227    pub const FORM: &str = "form";
2228
2229    /// The `autocomplete` attribute.
2230    ///
2231    /// Controls autofill behavior for the select control.
2232    pub const AUTOCOMPLETE: &str = "autocomplete";
2233}
2234
2235/// Attribute names for option (`<option>`) elements.
2236///
2237/// # Purpose
2238/// The `<option>` element defines an option in a `<select>`, `<optgroup>`,
2239/// or `<datalist>` element, representing a choice available to the user.
2240///
2241/// # Common Attributes
2242/// - `value`: Value submitted when option is selected
2243/// - `selected`: Pre-selects the option
2244/// - `disabled`: Disables the option
2245/// - `label`: Text label (defaults to element content)
2246///
2247/// # Example
2248/// ```html
2249/// <select name="size">
2250///   <option value="">Choose size</option>
2251///   <option value="s">Small</option>
2252///   <option value="m" selected>Medium</option>
2253///   <option value="l">Large</option>
2254///   <option value="xl" disabled>Extra Large (Out of stock)</option>
2255/// </select>
2256/// ```
2257///
2258/// # WHATWG Specification
2259/// - [The `option` element](https://html.spec.whatwg.org/multipage/form-elements.html#the-option-element)
2260pub mod option {
2261    /// The `value` attribute.
2262    ///
2263    /// Value submitted with the form when this option is selected.
2264    /// If omitted, the text content is used.
2265    pub const VALUE: &str = "value";
2266
2267    /// The `selected` attribute.
2268    ///
2269    /// Boolean indicating the option is initially selected.
2270    pub const SELECTED: &str = "selected";
2271
2272    /// The `disabled` attribute.
2273    ///
2274    /// Boolean disabling the option (cannot be selected).
2275    pub const DISABLED: &str = "disabled";
2276
2277    /// The `label` attribute.
2278    ///
2279    /// Label text for the option. If omitted, element content is used.
2280    pub const LABEL: &str = "label";
2281}
2282
2283/// Attribute names for label (`<label>`) elements.
2284///
2285/// # Purpose
2286/// The `<label>` element represents a caption for a form control, improving
2287/// accessibility and usability by associating descriptive text with inputs.
2288///
2289/// # Common Attributes
2290/// - `for`: ID of the associated form control
2291///
2292/// # Example
2293/// ```html
2294/// <label for="email">Email Address:</label>
2295/// <input type="email" id="email" name="email">
2296///
2297/// <label>
2298///   Username:
2299///   <input type="text" name="username">
2300/// </label>
2301/// ```
2302///
2303/// # WHATWG Specification
2304/// - [The `label` element](https://html.spec.whatwg.org/multipage/forms.html#the-label-element)
2305pub mod label {
2306    /// The `for` attribute.
2307    ///
2308    /// ID of the form control this label is associated with. Clicking the
2309    /// label activates the control. Alternative: nest the control inside the label.
2310    pub const FOR: &str = "for";
2311}
2312
2313/// Attribute names for table (`<table>`) elements.
2314///
2315/// # Purpose
2316/// The `<table>` element represents tabular data displayed in a grid of rows
2317/// and columns. Use semantic table elements for proper structure.
2318///
2319/// # Common Attributes
2320/// - `border`: Border width (deprecated, use CSS instead)
2321///
2322/// # Example
2323/// ```html
2324/// <table>
2325///   <thead>
2326///     <tr>
2327///       <th>Name</th>
2328///       <th>Age</th>
2329///     </tr>
2330///   </thead>
2331///   <tbody>
2332///     <tr>
2333///       <td>Alice</td>
2334///       <td>30</td>
2335///     </tr>
2336///   </tbody>
2337/// </table>
2338/// ```
2339///
2340/// # WHATWG Specification
2341/// - [The `table` element](https://html.spec.whatwg.org/multipage/tables.html#the-table-element)
2342pub mod table {
2343    /// The `border` attribute.
2344    ///
2345    /// Deprecated. Specifies border width. Use CSS `border` property instead.
2346    pub const BORDER: &str = "border";
2347}
2348
2349/// Attribute names for table cell (`<td>`, `<th>`) elements.
2350///
2351/// # Purpose
2352/// Table data (`<td>`) and header (`<th>`) cells can span multiple rows or
2353/// columns and be associated with headers for accessibility.
2354///
2355/// # Common Attributes
2356/// - `colspan`: Number of columns the cell spans
2357/// - `rowspan`: Number of rows the cell spans
2358/// - `headers`: Space-separated list of header cell IDs
2359/// - `scope`: Scope of header cell (row, col, rowgroup, colgroup)
2360///
2361/// # Example
2362/// ```html
2363/// <table>
2364///   <tr>
2365///     <th id="name" scope="col">Name</th>
2366///     <th id="age" scope="col">Age</th>
2367///   </tr>
2368///   <tr>
2369///     <td headers="name">Alice</td>
2370///     <td headers="age">30</td>
2371///   </tr>
2372///   <tr>
2373///     <td colspan="2">Merged cell across two columns</td>
2374///   </tr>
2375/// </table>
2376/// ```
2377///
2378/// # WHATWG Specification
2379/// - [The `td` element](https://html.spec.whatwg.org/multipage/tables.html#the-td-element)
2380/// - [The `th` element](https://html.spec.whatwg.org/multipage/tables.html#the-th-element)
2381pub mod tablecell {
2382    /// The `colspan` attribute.
2383    ///
2384    /// Number of columns the cell spans. Default is 1.
2385    pub const COLSPAN: &str = "colspan";
2386
2387    /// The `rowspan` attribute.
2388    ///
2389    /// Number of rows the cell spans. Default is 1.
2390    pub const ROWSPAN: &str = "rowspan";
2391
2392    /// The `headers` attribute.
2393    ///
2394    /// Space-separated list of header cell IDs this cell is associated with.
2395    /// Improves accessibility for complex tables.
2396    pub const HEADERS: &str = "headers";
2397
2398    /// The `scope` attribute.
2399    ///
2400    /// For `<th>` elements: specifies which cells the header applies to
2401    /// ("row", "col", "rowgroup", "colgroup").
2402    pub const SCOPE: &str = "scope";
2403}
2404
2405/// Attribute names for media (`<audio>`, `<video>`) elements.
2406///
2407/// # Purpose
2408/// Media elements embed audio or video content with built-in playback controls.
2409/// They support multiple sources, captions, and extensive playback control.
2410///
2411/// # Common Attributes
2412/// - `src`: Media resource URL
2413/// - `controls`: Show browser's default playback controls
2414/// - `autoplay`: Automatically start playback (often restricted by browsers)
2415/// - `loop`: Restart playback when finished
2416/// - `muted`: Start muted (required for autoplay in many browsers)
2417/// - `preload`: How much to preload (none, metadata, auto)
2418///
2419/// # Example
2420/// ```html
2421/// <video src="movie.mp4" controls width="640" height="360" poster="thumb.jpg">
2422///   Your browser doesn't support video.
2423/// </video>
2424/// <audio src="music.mp3" controls loop preload="metadata"></audio>
2425/// <video controls autoplay muted loop>
2426///   <source src="video.webm" type="video/webm">
2427///   <source src="video.mp4" type="video/mp4">
2428/// </video>
2429/// ```
2430///
2431/// # WHATWG Specification
2432/// - [The `video` element](https://html.spec.whatwg.org/multipage/media.html#the-video-element)
2433/// - [The `audio` element](https://html.spec.whatwg.org/multipage/media.html#the-audio-element)
2434pub mod media {
2435    /// The `src` attribute.
2436    ///
2437    /// URL of the media resource. Alternative: use `<source>` child elements.
2438    pub const SRC: &str = "src";
2439
2440    /// The `controls` attribute.
2441    ///
2442    /// Boolean to display browser's default playback controls.
2443    pub const CONTROLS: &str = "controls";
2444
2445    /// The `autoplay` attribute.
2446    ///
2447    /// Boolean to automatically start playback. Many browsers require `muted`
2448    /// for autoplay to work.
2449    pub const AUTOPLAY: &str = "autoplay";
2450
2451    /// The `loop` attribute.
2452    ///
2453    /// Boolean to restart playback from the beginning when finished.
2454    pub const LOOP: &str = "loop";
2455
2456    /// The `muted` attribute.
2457    ///
2458    /// Boolean to start with audio muted. Required for autoplay in many browsers.
2459    pub const MUTED: &str = "muted";
2460
2461    /// The `preload` attribute.
2462    ///
2463    /// Hint for how much to preload: "none", "metadata", or "auto".
2464    pub const PRELOAD: &str = "preload";
2465
2466    /// The `poster` attribute.
2467    ///
2468    /// For `<video>`: URL of an image to show before playback starts.
2469    pub const POSTER: &str = "poster";
2470
2471    /// The `width` attribute.
2472    ///
2473    /// For `<video>`: display width in pixels.
2474    pub const WIDTH: &str = "width";
2475
2476    /// The `height` attribute.
2477    ///
2478    /// For `<video>`: display height in pixels.
2479    pub const HEIGHT: &str = "height";
2480
2481    /// The `crossorigin` attribute.
2482    ///
2483    /// CORS settings for fetching the media: "anonymous" or "use-credentials".
2484    pub const CROSSORIGIN: &str = "crossorigin";
2485}
2486
2487/// Attribute names for source (`<source>`) elements.
2488///
2489/// # Purpose
2490/// The `<source>` element specifies multiple media resources for `<picture>`,
2491/// `<audio>`, or `<video>` elements, enabling responsive images and fallback
2492/// media formats.
2493///
2494/// # Common Attributes
2495/// - `src`: Resource URL
2496/// - `type`: MIME type of the resource
2497/// - `srcset`: Responsive image sources (for `<picture>`)
2498/// - `sizes`: Image sizes for different viewports (for `<picture>`)
2499/// - `media`: Media query for when this source applies
2500///
2501/// # Example
2502/// ```html
2503/// <video controls>
2504///   <source src="video.webm" type="video/webm">
2505///   <source src="video.mp4" type="video/mp4">
2506/// </video>
2507/// <picture>
2508///   <source srcset="large.jpg" media="(min-width: 800px)">
2509///   <source srcset="small.jpg" media="(max-width: 799px)">
2510///   <img src="fallback.jpg" alt="Image">
2511/// </picture>
2512/// ```
2513///
2514/// # WHATWG Specification
2515/// - [The `source` element](https://html.spec.whatwg.org/multipage/embedded-content.html#the-source-element)
2516pub mod source {
2517    /// The `src` attribute.
2518    ///
2519    /// URL of the media resource (for media elements).
2520    pub const SRC: &str = "src";
2521
2522    /// The `type` attribute.
2523    ///
2524    /// MIME type of the resource, helping the browser choose appropriate format.
2525    pub const TYPE: &str = "type";
2526
2527    /// The `srcset` attribute.
2528    ///
2529    /// For `<picture>`: comma-separated list of image URLs with width/density descriptors.
2530    pub const SRCSET: &str = "srcset";
2531
2532    /// The `sizes` attribute.
2533    ///
2534    /// For `<picture>`: media conditions and image sizes for responsive images.
2535    pub const SIZES: &str = "sizes";
2536
2537    /// The `media` attribute.
2538    ///
2539    /// Media query determining when this source should be used.
2540    pub const MEDIA: &str = "media";
2541}
2542
2543/// Attribute names for track (`<track>`) elements.
2544///
2545/// # Purpose
2546/// The `<track>` element provides timed text tracks (like subtitles, captions,
2547/// or chapters) for `<audio>` and `<video>` elements, improving accessibility
2548/// and user experience.
2549///
2550/// # Common Attributes
2551/// - `src`: URL of the track file (`WebVTT` format)
2552/// - `kind`: Type of track (subtitles, captions, descriptions, chapters, metadata)
2553/// - `srclang`: Language of the track text
2554/// - `label`: User-visible label for the track
2555/// - `default`: Marks this track as default
2556///
2557/// # Example
2558/// ```html
2559/// <video src="movie.mp4" controls>
2560///   <track kind="subtitles" src="en.vtt" srclang="en" label="English" default>
2561///   <track kind="subtitles" src="es.vtt" srclang="es" label="Español">
2562///   <track kind="captions" src="en-cc.vtt" srclang="en" label="English CC">
2563///   <track kind="chapters" src="chapters.vtt" srclang="en">
2564/// </video>
2565/// ```
2566///
2567/// # WHATWG Specification
2568/// - [The `track` element](https://html.spec.whatwg.org/multipage/media.html#the-track-element)
2569pub mod track {
2570    /// The `src` attribute.
2571    ///
2572    /// URL of the track file, typically in `WebVTT` format.
2573    pub const SRC: &str = "src";
2574
2575    /// The `kind` attribute.
2576    ///
2577    /// Type of text track: "subtitles", "captions", "descriptions",
2578    /// "chapters", or "metadata".
2579    pub const KIND: &str = "kind";
2580
2581    /// The `srclang` attribute.
2582    ///
2583    /// Language of the track text data (BCP 47 language tag, e.g., "en", "es").
2584    pub const SRCLANG: &str = "srclang";
2585
2586    /// The `label` attribute.
2587    ///
2588    /// User-visible title for the track, shown in the track selection menu.
2589    pub const LABEL: &str = "label";
2590
2591    /// The `default` attribute.
2592    ///
2593    /// Boolean indicating this track should be enabled by default unless
2594    /// user preferences indicate otherwise.
2595    pub const DEFAULT: &str = "default";
2596}
2597
2598/// Attribute names for iframe (`<iframe>`) elements.
2599///
2600/// # Purpose
2601/// The `<iframe>` element embeds another HTML document within the current page,
2602/// commonly used for third-party widgets, embedded content, or sandboxed applications.
2603///
2604/// # Common Attributes
2605/// - `src`: URL of the document to embed
2606/// - `width`/`height`: Dimensions of the iframe
2607/// - `sandbox`: Security restrictions for the embedded content
2608/// - `loading`: Lazy loading behavior
2609/// - `allow`: Feature policy permissions
2610///
2611/// # Example
2612/// ```html
2613/// <iframe src="https://example.com/widget" width="600" height="400"
2614///         sandbox="allow-scripts allow-same-origin"
2615///         loading="lazy"></iframe>
2616/// <iframe src="untrusted.html" sandbox></iframe>
2617/// <iframe srcdoc="<p>Inline HTML content</p>" sandbox="allow-scripts"></iframe>
2618/// ```
2619///
2620/// # WHATWG Specification
2621/// - [The `iframe` element](https://html.spec.whatwg.org/multipage/iframe-embed-object.html#the-iframe-element)
2622pub mod iframe {
2623    /// The `src` attribute.
2624    ///
2625    /// URL of the page to embed in the iframe.
2626    pub const SRC: &str = "src";
2627
2628    /// The `srcdoc` attribute.
2629    ///
2630    /// Inline HTML content to display in the iframe (overrides `src`).
2631    pub const SRCDOC: &str = "srcdoc";
2632
2633    /// The `name` attribute.
2634    ///
2635    /// Name of the browsing context, can be used as target for links/forms.
2636    pub const NAME: &str = "name";
2637
2638    /// The `width` attribute.
2639    ///
2640    /// Width of the iframe in pixels.
2641    pub const WIDTH: &str = "width";
2642
2643    /// The `height` attribute.
2644    ///
2645    /// Height of the iframe in pixels.
2646    pub const HEIGHT: &str = "height";
2647
2648    /// The `loading` attribute.
2649    ///
2650    /// Loading behavior: "eager" (immediate) or "lazy" (when near viewport).
2651    pub const LOADING: &str = "loading";
2652
2653    /// The `sandbox` attribute.
2654    ///
2655    /// Space-separated security restrictions. Empty value applies all restrictions.
2656    /// Values: "allow-forms", "allow-scripts", "allow-same-origin", etc.
2657    pub const SANDBOX: &str = "sandbox";
2658
2659    /// The `allow` attribute.
2660    ///
2661    /// Feature policy for the iframe (e.g., "camera; microphone; geolocation").
2662    pub const ALLOW: &str = "allow";
2663
2664    /// The `referrerpolicy` attribute.
2665    ///
2666    /// Controls referrer information sent when loading the iframe.
2667    pub const REFERRERPOLICY: &str = "referrerpolicy";
2668}
2669
2670/// Attribute names for meta (`<meta>`) elements.
2671///
2672/// # Purpose
2673/// The `<meta>` element represents metadata that cannot be represented by
2674/// other HTML meta elements, such as character encoding, viewport settings,
2675/// and document metadata.
2676///
2677/// # Common Attributes
2678/// - `charset`: Character encoding declaration (e.g., "utf-8")
2679/// - `name`: Metadata name (e.g., "viewport", "description", "keywords")
2680/// - `content`: Metadata value (used with `name` or `http-equiv`)
2681/// - `http-equiv`: HTTP header to emulate
2682///
2683/// # Example
2684/// ```html
2685/// <meta charset="utf-8">
2686/// <meta name="viewport" content="width=device-width, initial-scale=1">
2687/// <meta name="description" content="Page description for SEO">
2688/// <meta name="keywords" content="html, css, javascript">
2689/// <meta http-equiv="X-UA-Compatible" content="IE=edge">
2690/// ```
2691///
2692/// # WHATWG Specification
2693/// - [The `meta` element](https://html.spec.whatwg.org/multipage/semantics.html#the-meta-element)
2694pub mod meta {
2695    /// The `charset` attribute.
2696    ///
2697    /// Character encoding declaration for the document. Should be "utf-8" in
2698    /// modern HTML documents.
2699    pub const CHARSET: &str = "charset";
2700
2701    /// The `name` attribute.
2702    ///
2703    /// Name of the metadata property (e.g., "viewport", "description", "author",
2704    /// "keywords", "theme-color").
2705    pub const NAME: &str = "name";
2706
2707    /// The `content` attribute.
2708    ///
2709    /// Value of the metadata property specified by `name` or `http-equiv`.
2710    pub const CONTENT: &str = "content";
2711
2712    /// The `http-equiv` attribute.
2713    ///
2714    /// Pragma directive, emulating an HTTP response header (e.g., "refresh",
2715    /// "X-UA-Compatible", "Content-Security-Policy").
2716    pub const HTTPEQUIV: &str = "http-equiv";
2717}
2718
2719/// Attribute names for link (`<link>`) elements.
2720///
2721/// # Purpose
2722/// The `<link>` element specifies relationships between the current document
2723/// and external resources, most commonly used to link stylesheets, icons,
2724/// and web app manifests.
2725///
2726/// # Common Attributes
2727/// - `href`: URL of the linked resource
2728/// - `rel`: Relationship type (stylesheet, icon, preload, etc.)
2729/// - `type`: MIME type hint for the resource
2730/// - `media`: Media query for when the resource applies
2731/// - `integrity`: Subresource integrity hash for security
2732///
2733/// # Example
2734/// ```html
2735/// <link rel="stylesheet" href="styles.css">
2736/// <link rel="icon" href="favicon.ico" type="image/x-icon">
2737/// <link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>
2738/// <link rel="manifest" href="manifest.json">
2739/// <link rel="stylesheet" href="print.css" media="print">
2740/// ```
2741///
2742/// # WHATWG Specification
2743/// - [The `link` element](https://html.spec.whatwg.org/multipage/semantics.html#the-link-element)
2744pub mod link {
2745    /// The `href` attribute.
2746    ///
2747    /// URL of the linked resource.
2748    pub const HREF: &str = "href";
2749
2750    /// The `rel` attribute.
2751    ///
2752    /// Relationship type: "stylesheet", "icon", "preload", "prefetch",
2753    /// "dns-prefetch", "manifest", "alternate", etc.
2754    pub const REL: &str = "rel";
2755
2756    /// The `type` attribute.
2757    ///
2758    /// MIME type hint for the linked resource (e.g., "text/css", "image/png").
2759    pub const TYPE: &str = "type";
2760
2761    /// The `media` attribute.
2762    ///
2763    /// Media query specifying when the resource applies (e.g., "print",
2764    /// "(max-width: 600px)").
2765    pub const MEDIA: &str = "media";
2766
2767    /// The `crossorigin` attribute.
2768    ///
2769    /// CORS settings for fetching the resource: "anonymous" or "use-credentials".
2770    pub const CROSSORIGIN: &str = "crossorigin";
2771
2772    /// The `integrity` attribute.
2773    ///
2774    /// Subresource Integrity (SRI) hash for verifying resource integrity.
2775    pub const INTEGRITY: &str = "integrity";
2776
2777    /// The `referrerpolicy` attribute.
2778    ///
2779    /// Controls referrer information sent when fetching the resource.
2780    pub const REFERRERPOLICY: &str = "referrerpolicy";
2781
2782    /// The `sizes` attribute.
2783    ///
2784    /// For `rel="icon"`: icon sizes (e.g., "16x16", "32x32", "any").
2785    pub const SIZES: &str = "sizes";
2786
2787    /// The `as` attribute.
2788    ///
2789    /// For `rel="preload"`: type of content being loaded (e.g., "script",
2790    /// "style", "font", "image").
2791    pub const AS: &str = "as";
2792}
2793
2794/// Attribute names for script (`<script>`) elements.
2795///
2796/// # Purpose
2797/// The `<script>` element embeds or references executable JavaScript code,
2798/// enabling client-side scripting and dynamic behavior in web pages.
2799///
2800/// # Common Attributes
2801/// - `src`: URL of external script file
2802/// - `type`: MIME type or module type ("text/javascript", "module")
2803/// - `async`: Load and execute asynchronously
2804/// - `defer`: Defer execution until document is parsed
2805/// - `integrity`: Subresource integrity hash for security
2806/// - `crossorigin`: CORS settings for external scripts
2807///
2808/// # Example
2809/// ```html
2810/// <script src="script.js"></script>
2811/// <script src="script.js" defer></script>
2812/// <script src="script.js" async></script>
2813/// <script type="module" src="app.js"></script>
2814/// <script src="https://cdn.example.com/lib.js"
2815///         integrity="sha384-..."
2816///         crossorigin="anonymous"></script>
2817/// <script>
2818///   console.log('Inline JavaScript');
2819/// </script>
2820/// ```
2821///
2822/// # WHATWG Specification
2823/// - [The `script` element](https://html.spec.whatwg.org/multipage/scripting.html#the-script-element)
2824pub mod script {
2825    /// The `src` attribute.
2826    ///
2827    /// URL of an external script file. If present, element content is ignored.
2828    pub const SRC: &str = "src";
2829
2830    /// The `type` attribute.
2831    ///
2832    /// MIME type of the script. Use "module" for ES6 modules. Default is
2833    /// JavaScript if omitted.
2834    pub const TYPE: &str = "type";
2835
2836    /// The `async` attribute.
2837    ///
2838    /// Boolean to load and execute the script asynchronously. Script executes
2839    /// as soon as it's available, potentially before DOM is ready.
2840    pub const ASYNC: &str = "async";
2841
2842    /// The `defer` attribute.
2843    ///
2844    /// Boolean to defer script execution until after document parsing. Scripts
2845    /// execute in order. Ignored for inline scripts.
2846    pub const DEFER: &str = "defer";
2847
2848    /// The `crossorigin` attribute.
2849    ///
2850    /// CORS settings for fetching external scripts: "anonymous" or "use-credentials".
2851    pub const CROSSORIGIN: &str = "crossorigin";
2852
2853    /// The `integrity` attribute.
2854    ///
2855    /// Subresource Integrity (SRI) hash for verifying script integrity.
2856    pub const INTEGRITY: &str = "integrity";
2857
2858    /// The `nomodule` attribute.
2859    ///
2860    /// Boolean to prevent execution in browsers that support ES6 modules.
2861    /// Used for legacy fallback scripts.
2862    pub const NOMODULE: &str = "nomodule";
2863
2864    /// The `referrerpolicy` attribute.
2865    ///
2866    /// Controls referrer information sent when fetching the script.
2867    pub const REFERRERPOLICY: &str = "referrerpolicy";
2868}
2869
2870/// Attribute names for style (`<style>`) elements.
2871///
2872/// # Purpose
2873/// The `<style>` element contains CSS style information for the document,
2874/// allowing inline stylesheet definitions within HTML.
2875///
2876/// # Common Attributes
2877/// - `media`: Media query for when the styles apply
2878///
2879/// # Example
2880/// ```html
2881/// <style>
2882///   body { font-family: sans-serif; }
2883///   .container { max-width: 1200px; margin: 0 auto; }
2884/// </style>
2885/// <style media="print">
2886///   body { font-size: 12pt; }
2887///   .no-print { display: none; }
2888/// </style>
2889/// <style media="(max-width: 600px)">
2890///   .mobile-hidden { display: none; }
2891/// </style>
2892/// ```
2893///
2894/// # WHATWG Specification
2895/// - [The `style` element](https://html.spec.whatwg.org/multipage/semantics.html#the-style-element)
2896pub mod style {
2897    /// The `media` attribute.
2898    ///
2899    /// Media query specifying when the styles should apply (e.g., "print",
2900    /// "screen", "(max-width: 600px)").
2901    pub const MEDIA: &str = "media";
2902}
2903
2904// =============================================================================
2905// Tests
2906// =============================================================================
2907
2908#[cfg(test)]
2909mod tests {
2910    use super::*;
2911
2912    #[test]
2913    fn test_attribute_values() {
2914        assert_eq!(Dir::Ltr.to_attr_value(), "ltr");
2915        assert_eq!(Dir::Rtl.to_attr_value(), "rtl");
2916        assert_eq!(Dir::Auto.to_attr_value(), "auto");
2917    }
2918
2919    #[test]
2920    fn test_target_values() {
2921        assert_eq!(Target::Self_.to_attr_value(), "_self");
2922        assert_eq!(Target::Blank.to_attr_value(), "_blank");
2923        assert_eq!(Target::Parent.to_attr_value(), "_parent");
2924        assert_eq!(Target::Top.to_attr_value(), "_top");
2925    }
2926
2927    #[test]
2928    fn test_input_type_values() {
2929        assert_eq!(InputType::Text.to_attr_value(), "text");
2930        assert_eq!(InputType::Password.to_attr_value(), "password");
2931        assert_eq!(InputType::Email.to_attr_value(), "email");
2932        assert_eq!(InputType::Checkbox.to_attr_value(), "checkbox");
2933        assert_eq!(InputType::Submit.to_attr_value(), "submit");
2934    }
2935
2936    #[test]
2937    fn test_loading_values() {
2938        assert_eq!(Loading::Eager.to_attr_value(), "eager");
2939        assert_eq!(Loading::Lazy.to_attr_value(), "lazy");
2940    }
2941
2942    #[test]
2943    fn test_method_values() {
2944        assert_eq!(Method::Get.to_attr_value(), "get");
2945        assert_eq!(Method::Post.to_attr_value(), "post");
2946        assert_eq!(Method::Dialog.to_attr_value(), "dialog");
2947    }
2948
2949    #[test]
2950    fn test_numeric_attribute_values() {
2951        assert_eq!(42u32.to_attr_value(), "42");
2952        assert_eq!((-10i32).to_attr_value(), "-10");
2953    }
2954
2955    #[test]
2956    fn test_global_attribute_names() {
2957        assert_eq!(global::CLASS, "class");
2958        assert_eq!(global::ID, "id");
2959        assert_eq!(global::STYLE, "style");
2960    }
2961
2962    #[test]
2963    fn test_element_attribute_names() {
2964        assert_eq!(anchor::HREF, "href");
2965        assert_eq!(img::SRC, "src");
2966        assert_eq!(img::ALT, "alt");
2967        assert_eq!(input::TYPE, "type");
2968        assert_eq!(form::METHOD, "method");
2969    }
2970}