1use crate::core::{CanAddChildren, CanAddText, HasAttributes, Node, Open, Void};
2
3pub trait HasGlobalAttributes: HasAttributes + Sized {
8 fn accesskey(self, value: impl AsRef<str>) -> Self {
11 let key = "accesskey";
12 self.attr(key, value)
13 }
14
15 fn class(self, value: impl AsRef<str>) -> Self {
17 let key = "class";
18 self.attr(key, value)
19 }
20
21 fn id(self, value: impl AsRef<str>) -> Self {
23 let key = "id";
24 self.attr(key, value)
25 }
26
27 fn lang(self, value: impl AsRef<str>) -> Self {
29 let key = "lang";
30 self.attr(key, value)
31 }
32
33 fn title(self, value: impl AsRef<str>) -> Self {
35 let key = "title";
36 self.attr(key, value)
37 }
38
39 fn draggable(self) -> Self {
41 self.flag("draggable")
42 }
43
44 fn spellcheck(self) -> Self {
46 self.flag("spellcheck")
47 }
48
49 fn autofocus(self) -> Self {
51 self.flag("autofocus")
52 }
53
54 fn contenteditable(self) -> Self {
56 self.flag("contenteditable")
57 }
58
59 fn tabindex(self, value: i32) -> Self {
61 self.attr("tabindex", value.to_string())
62 }
63
64 fn hidden(self) -> Self {
66 self.flag("hidden")
67 }
68
69 fn autocapitalize(self, value: impl AsRef<str>) -> Self {
71 self.attr("autocapitalize", value)
72 }
73
74 fn data(self, key: &'static str, value: impl AsRef<str>) -> Self
79 where
80 Self: Sized + HasAttributes,
81 {
82 self.attr(format!("data-{}", key).as_str(), value)
83 }
84}
85
86impl<Tag> HasGlobalAttributes for Node<Tag, Open> {}
87impl<Tag> HasGlobalAttributes for Node<Tag, Void> {}
88
89pub trait HasHref: HasAttributes + Sized {
90 fn href(self, value: impl AsRef<str>) -> Self {
92 self.attr("href", value)
93 }
94}
95
96#[derive(Clone, Copy, PartialEq, Eq)]
97pub enum Rel {
98 Alternate,
100
101 Author,
103
104 Bookmark,
106
107 Canonical,
109
110 DnsPrefetch,
112
113 External,
115
116 Help,
118
119 Icon,
121
122 License,
125
126 Manifest,
128
129 Next,
132
133 NoFollow,
135
136 NoOpener,
139
140 NoReferrer,
142
143 Opener,
146
147 Prefetch,
150
151 Preload,
155
156 Prev,
159
160 Search,
162
163 Stylesheet,
165
166 Tag,
168}
169
170pub trait HasRel: HasAttributes + Sized {
171 fn rel(self, rel: Rel) -> Self {
172 let value = match rel {
173 Rel::Alternate => "alternate",
174 Rel::Author => "author",
175 Rel::Bookmark => "bookmark",
176 Rel::Canonical => "canonical",
177 Rel::DnsPrefetch => "dns-prefetch",
178 Rel::External => "external",
179 Rel::Help => "help",
180 Rel::Icon => "icon",
181 Rel::License => "license",
182 Rel::Manifest => "manifest",
183 Rel::Next => "next",
184 Rel::NoFollow => "nofollow",
185 Rel::NoOpener => "noopener",
186 Rel::NoReferrer => "noreferrer",
187 Rel::Opener => "opener",
188 Rel::Prefetch => "prefetch",
189 Rel::Preload => "preload",
190 Rel::Prev => "prev",
191 Rel::Search => "search",
192 Rel::Stylesheet => "stylesheet",
193 Rel::Tag => "tag",
194 };
195 self.attr("rel", value)
196 }
197}
198
199pub trait HasSrc: HasAttributes + Sized {
200 fn src(self, value: impl AsRef<str>) -> Self {
202 self.attr("src", value)
203 }
204}
205
206pub enum InputType {
207 Text,
208 Password,
209 Checkbox,
210 Radio,
211 File,
212 Submit,
213 Reset,
214 Button,
215 Hidden,
216 Email,
217 Number,
218 Date,
219}
220
221pub trait HasInputType: HasAttributes + Sized {
222 fn input_type(self, value: impl Into<InputType>) -> Self {
223 let value = match value.into() {
224 InputType::Text => "text",
225 InputType::Password => "password",
226 InputType::Checkbox => "checkbox",
227 InputType::Radio => "radio",
228 InputType::File => "file",
229 InputType::Submit => "submit",
230 InputType::Reset => "reset",
231 InputType::Button => "button",
232 InputType::Hidden => "hidden",
233 InputType::Email => "email",
234 InputType::Number => "number",
235 InputType::Date => "date",
236 };
237 self.attr("type", value)
238 }
239}
240
241pub enum Target {
242 Self_,
243 Blank,
244 Parent,
245 Top,
246}
247
248pub trait HasTarget: HasAttributes + Sized {
249 fn target(self, target: Target) -> Self {
250 let value = match target {
251 Target::Self_ => "_self",
252 Target::Blank => "_blank",
253 Target::Parent => "_parent",
254 Target::Top => "_top",
255 };
256 self.attr("target", value)
257 }
258}
259
260pub enum FormMethod {
261 Get,
262 Post,
263 Dialog,
264}
265
266pub struct Html;
272
273pub fn html() -> Node<Html, Open> {
275 let mut buf = Vec::with_capacity(2048);
277 buf.extend_from_slice(b"<!DOCTYPE html>");
278 Node::with_buffer("html", buf)
279}
280
281impl CanAddChildren for Html {}
282
283pub struct Head;
285
286pub fn head() -> Node<Head, Open> {
288 Node::new("head")
289}
290
291impl CanAddChildren for Head {}
292
293pub struct Link;
295
296pub fn link() -> Node<Link, Void> {
298 Node::new_self_closing("link")
299}
300
301impl HasHref for Node<Link, Void> {}
302impl HasRel for Node<Link, Void> {}
303
304impl Node<Link, Void> {
305 pub fn integrity(self, value: impl AsRef<str>) -> Self {
307 self.attr("integrity", value)
308 }
309}
310
311pub struct Meta;
313
314pub fn meta() -> Node<Meta, Void> {
316 Node::new_self_closing("meta")
317}
318
319impl Node<Meta, Void> {
320 pub fn charset(self, value: impl AsRef<str>) -> Self {
321 self.attr("charset", value)
322 }
323 pub fn content(self, value: impl AsRef<str>) -> Self {
324 self.attr("content", value)
325 }
326 pub fn http_equiv(self, value: impl AsRef<str>) -> Self {
327 self.attr("http-equiv", value)
328 }
329 pub fn media(self, value: impl AsRef<str>) -> Self {
330 self.attr("media", value)
331 }
332 pub fn name(self, value: impl AsRef<str>) -> Self {
333 self.attr("name", value)
334 }
335}
336
337pub struct Style;
339
340pub fn style() -> Node<Style, Open> {
342 Node::new("style")
343}
344
345impl CanAddText for Style {}
346impl CanAddChildren for Style {}
347
348pub struct Title;
350
351pub fn title() -> Node<Title, Open> {
353 Node::new("title")
354}
355
356impl CanAddText for Title {}
357
358pub struct Body;
360
361pub fn body() -> Node<Body, Open> {
363 Node::new("body")
364}
365
366impl CanAddChildren for Body {}
367
368pub struct Div;
370
371pub fn div() -> Node<Div, Open> {
373 Node::new("div")
374}
375
376impl CanAddChildren for Div {}
377impl CanAddText for Div {}
378
379pub struct Span;
381
382pub fn span() -> Node<Span, Open> {
384 Node::new("span")
385}
386
387impl CanAddChildren for Span {}
388impl CanAddText for Span {}
389
390pub struct H1;
392
393pub fn h1() -> Node<H1, Open> {
394 Node::new("h1")
395}
396
397impl CanAddChildren for H1 {}
398impl CanAddText for H1 {}
399
400pub struct H2;
402
403pub fn h2() -> Node<H2, Open> {
404 Node::new("h2")
405}
406
407impl CanAddChildren for H2 {}
408impl CanAddText for H2 {}
409
410pub struct H3;
412
413pub fn h3() -> Node<H3, Open> {
414 Node::new("h3")
415}
416
417impl CanAddChildren for H3 {}
418impl CanAddText for H3 {}
419
420pub struct H4;
422
423pub fn h4() -> Node<H4, Open> {
424 Node::new("h4")
425}
426
427impl CanAddChildren for H4 {}
428impl CanAddText for H4 {}
429
430pub struct H5;
432
433pub fn h5() -> Node<H5, Open> {
434 Node::new("h5")
435}
436
437impl CanAddChildren for H5 {}
438impl CanAddText for H5 {}
439
440pub struct H6;
442
443pub fn h6() -> Node<H6, Open> {
444 Node::new("h6")
445}
446
447impl CanAddChildren for H6 {}
448impl CanAddText for H6 {}
449
450pub struct Paragraph;
452
453pub fn p() -> Node<Paragraph, Open> {
455 Node::new("p")
456}
457
458impl CanAddChildren for Paragraph {}
459impl CanAddText for Paragraph {}
460
461pub struct Img;
463
464pub fn img() -> Node<Img, Void> {
466 Node::new_self_closing("img")
467}
468
469impl HasSrc for Node<Img, Void> {}
470
471impl Node<Img, Void> {
472 pub fn alt(self, value: impl AsRef<str>) -> Self {
474 self.attr("alt", value)
475 }
476
477 pub fn width(self, value: i32) -> Self {
479 self.attr("width", value.to_string())
480 }
481
482 pub fn height(self, value: i32) -> Self {
484 self.attr("height", value.to_string())
485 }
486}
487
488pub struct Form;
490
491pub fn form() -> Node<Form, Open> {
493 Node::new("form")
494}
495
496impl CanAddChildren for Form {}
497
498impl Node<Form, Open> {
499 pub fn action(self, value: impl AsRef<str>) -> Self {
501 self.attr("action", value)
502 }
503
504 pub fn method(self, method: FormMethod) -> Self {
506 self.attr(
507 "method",
508 match method {
509 FormMethod::Get => "GET",
510 FormMethod::Post => "POST",
511 FormMethod::Dialog => "dialog",
512 },
513 )
514 }
515
516 pub fn accept_charset(self, value: impl AsRef<str>) -> Self {
518 self.attr("accept-charset", value)
519 }
520
521 pub fn autocomplete(self, value: bool) -> Self {
523 self.attr("autocomplete", if value { "on" } else { "off" })
524 }
525}
526
527pub struct Input;
529
530pub fn input() -> Node<Input, Void> {
532 Node::new_self_closing("input")
533}
534
535impl HasInputType for Node<Input, Void> {}
536
537impl Node<Input, Void> {
538 pub fn name(self, value: impl AsRef<str>) -> Self {
540 self.attr("name", value)
541 }
542
543 pub fn value(self, value: impl AsRef<str>) -> Self {
545 self.attr("value", value)
546 }
547
548 pub fn checked(self) -> Self {
550 self.flag("checked")
551 }
552
553 pub fn accept(self, value: impl AsRef<str>) -> Self {
555 self.attr("accept", value)
556 }
557
558 pub fn capture(self) -> Self {
560 self.flag("capture")
561 }
562
563 pub fn autocomplete(self, value: bool) -> Self {
565 self.attr("autocomplete", if value { "on" } else { "off" })
566 }
567}
568
569pub struct Button;
571
572pub fn button() -> Node<Button, Open> {
574 Node::new("button")
575}
576
577impl CanAddChildren for Button {}
578impl CanAddText for Button {}
579
580impl Node<Button, Open> {
581 pub fn type_(self, value: impl AsRef<str>) -> Self {
583 self.attr("type", value)
584 }
585
586 pub fn name(self, value: impl AsRef<str>) -> Self {
588 self.attr("name", value)
589 }
590
591 pub fn value(self, value: impl AsRef<str>) -> Self {
593 self.attr("value", value)
594 }
595
596 pub fn disabled(self) -> Self {
598 self.flag("disabled")
599 }
600}
601
602pub struct Textarea;
604
605pub fn textarea() -> Node<Textarea, Open> {
607 Node::new("textarea")
608}
609
610impl CanAddText for Textarea {}
611
612impl Node<Textarea, Open> {
613 pub fn name(self, value: impl AsRef<str>) -> Self {
615 self.attr("name", value)
616 }
617
618 pub fn value(self, value: impl AsRef<str>) -> Self {
620 self.attr("value", value)
621 }
622
623 pub fn rows(self, value: i32) -> Self {
625 self.attr("rows", value.to_string())
626 }
627
628 pub fn cols(self, value: i32) -> Self {
630 self.attr("cols", value.to_string())
631 }
632
633 pub fn disabled(self) -> Self {
635 self.flag("disabled")
636 }
637
638 pub fn autocomplete(self, value: bool) -> Self {
640 self.attr("autocomplete", if value { "on" } else { "off" })
641 }
642}
643
644pub struct Select;
646
647pub fn select() -> Node<Select, Open> {
649 Node::new("select")
650}
651
652impl CanAddChildren for Select {}
653
654impl Node<Select, Open> {
655 pub fn name(self, value: impl AsRef<str>) -> Self {
657 self.attr("name", value)
658 }
659
660 pub fn disabled(self) -> Self {
662 self.flag("disabled")
663 }
664
665 pub fn multiple(self) -> Self {
667 self.flag("multiple")
668 }
669
670 pub fn autocomplete(self, value: bool) -> Self {
672 self.attr("autocomplete", if value { "on" } else { "off" })
673 }
674}
675
676pub struct OptionElement;
678
679pub fn option() -> Node<OptionElement, Open> {
681 Node::new("option")
682}
683
684impl CanAddText for OptionElement {}
685
686impl Node<OptionElement, Open> {
687 pub fn value(self, value: impl AsRef<str>) -> Self {
689 self.attr("value", value)
690 }
691
692 pub fn selected(self) -> Self {
694 self.flag("selected")
695 }
696
697 pub fn disabled(self) -> Self {
699 self.flag("disabled")
700 }
701}
702
703pub struct Header;
705
706pub fn header() -> Node<Header, Open> {
708 Node::new("header")
709}
710
711impl CanAddChildren for Header {}
712impl CanAddText for Header {}
713
714pub struct Footer;
716
717pub fn footer() -> Node<Footer, Open> {
719 Node::new("footer")
720}
721
722impl CanAddChildren for Footer {}
723impl CanAddText for Footer {}
724
725pub struct Nav;
727
728pub fn nav() -> Node<Nav, Open> {
730 Node::new("nav")
731}
732
733impl CanAddChildren for Nav {}
734impl CanAddText for Nav {}
735
736pub struct Section;
738
739pub fn section() -> Node<Section, Open> {
741 Node::new("section")
742}
743
744impl CanAddChildren for Section {}
745impl CanAddText for Section {}
746
747pub struct Article;
749
750pub fn article() -> Node<Article, Open> {
752 Node::new("article")
753}
754
755impl CanAddChildren for Article {}
756impl CanAddText for Article {}
757
758pub struct Aside;
760
761pub fn aside() -> Node<Aside, Open> {
763 Node::new("aside")
764}
765
766impl CanAddChildren for Aside {}
767impl CanAddText for Aside {}
768
769pub struct Main;
771
772pub fn main() -> Node<Main, Open> {
774 Node::new("main")
775}
776
777impl CanAddChildren for Main {}
778impl CanAddText for Main {}
779
780pub struct Code;
782
783pub fn code() -> Node<Code, Open> {
785 Node::new("code")
786}
787
788impl CanAddChildren for Code {}
789impl CanAddText for Code {}
790
791pub struct Pre;
793
794pub fn pre() -> Node<Pre, Open> {
796 Node::new("pre")
797}
798
799impl CanAddChildren for Pre {}
800impl CanAddText for Pre {}
801
802pub struct A;
804
805pub fn a() -> Node<A, Open> {
808 Node::new("a")
809}
810
811impl CanAddChildren for A {}
812impl CanAddText for A {}
813impl HasHref for Node<A, Open> {}
814
815impl Node<A, Open> {
816 pub fn download(self) -> Self {
818 self.flag("download")
819 }
820}
821
822pub struct B;
824
825pub fn b() -> Node<B, Open> {
827 Node::new("b")
828}
829
830impl CanAddChildren for B {}
831impl CanAddText for B {}
832
833pub struct I;
835
836pub fn i() -> Node<I, Open> {
838 Node::new("i")
839}
840
841impl CanAddChildren for I {}
842impl CanAddText for I {}
843
844pub struct U;
846
847pub fn u() -> Node<U, Open> {
849 Node::new("u")
850}
851
852impl CanAddChildren for U {}
853impl CanAddText for U {}
854
855pub struct Strong;
857
858pub fn strong() -> Node<Strong, Open> {
860 Node::new("strong")
861}
862
863impl CanAddChildren for Strong {}
864impl CanAddText for Strong {}
865
866pub struct Small;
868
869pub fn small() -> Node<Small, Open> {
871 Node::new("small")
872}
873
874impl CanAddChildren for Small {}
875impl CanAddText for Small {}
876
877pub struct Label;
879
880pub fn label() -> Node<Label, Open> {
882 Node::new("label")
883}
884
885impl CanAddChildren for Label {}
886impl CanAddText for Label {}
887
888impl Node<Label, Open> {
889 pub fn for_(self, value: impl AsRef<str>) -> Self {
891 self.attr("for", value)
892 }
893}
894
895pub struct Details;
897
898pub fn details() -> Node<Details, Open> {
900 Node::new("details")
901}
902
903impl CanAddChildren for Details {}
904impl CanAddText for Details {}
905
906impl Node<Details, Open> {
907 pub fn open(self) -> Self {
909 self.flag("open")
910 }
911}
912
913pub struct Summary;
915
916pub fn summary() -> Node<Summary, Open> {
918 Node::new("summary")
919}
920
921impl CanAddChildren for Summary {}
922impl CanAddText for Summary {}
923
924pub struct Dialog;
926
927pub fn dialog() -> Node<Dialog, Open> {
929 Node::new("dialog")
930}
931
932impl CanAddChildren for Dialog {}
933impl CanAddText for Dialog {}
934
935impl Node<Dialog, Open> {
936 pub fn open(self) -> Self {
938 self.flag("open")
939 }
940}
941
942pub struct Hr;
944
945pub fn hr() -> Node<Hr, Void> {
947 Node::new_self_closing("hr")
948}
949
950pub struct Base;
952
953pub fn base() -> Node<Base, Void> {
955 Node::new_self_closing("base")
956}
957
958impl HasHref for Node<Base, Void> {}
959impl HasTarget for Node<Base, Void> {}
960
961pub struct Script;
963
964pub fn script() -> Node<Script, Open> {
965 Node::new("script")
966}
967
968impl CanAddText for Script {}
969impl HasSrc for Node<Script, Open> {}
970
971impl Node<Script, Open> {
972 pub fn async_(self) -> Self {
974 self.flag("async")
975 }
976
977 pub fn defer(self) -> Self {
979 self.flag("defer")
980 }
981
982 pub fn integrity(self, value: impl AsRef<str>) -> Self {
984 self.attr("integrity", value)
985 }
986
987 pub fn type_(self, value: impl AsRef<str>) -> Self {
989 self.attr("type", value)
990 }
991}
992
993pub struct Ul;
995
996pub fn ul() -> Node<Ul, Open> {
997 Node::new("ul")
998}
999
1000impl CanAddChildren for Ul {}
1001
1002pub struct Ol;
1004
1005pub fn ol() -> Node<Ol, Open> {
1006 Node::new("ol")
1007}
1008
1009impl CanAddChildren for Ol {}
1010
1011pub struct Li;
1013
1014pub fn li() -> Node<Li, Open> {
1015 Node::new("li")
1016}
1017
1018impl CanAddChildren for Li {}
1019impl CanAddText for Li {}
1020
1021pub struct Table;
1023
1024pub fn table() -> Node<Table, Open> {
1025 Node::new("table")
1026}
1027
1028impl CanAddChildren for Table {}
1029
1030pub struct THead;
1032
1033pub fn thead() -> Node<THead, Open> {
1034 Node::new("thead")
1035}
1036
1037impl CanAddChildren for THead {}
1038
1039pub struct TBody;
1041
1042pub fn tbody() -> Node<TBody, Open> {
1043 Node::new("tbody")
1044}
1045
1046impl CanAddChildren for TBody {}
1047
1048pub struct TFoot;
1050
1051pub fn tfoot() -> Node<TFoot, Open> {
1052 Node::new("tfoot")
1053}
1054
1055impl CanAddChildren for TFoot {}
1056
1057pub struct Tr;
1059
1060pub fn tr() -> Node<Tr, Open> {
1061 Node::new("tr")
1062}
1063
1064impl CanAddChildren for Tr {}
1065
1066pub struct Th;
1068
1069pub fn th() -> Node<Th, Open> {
1070 Node::new("th")
1071}
1072
1073impl CanAddChildren for Th {}
1074impl CanAddText for Th {}
1075
1076pub struct Td;
1078
1079pub fn td() -> Node<Td, Open> {
1080 Node::new("td")
1081}
1082
1083impl CanAddChildren for Td {}
1084impl CanAddText for Td {}