1use crate::{
2 html::{
3 attribute::{Attr, Attribute, AttributeValue, NextAttribute},
4 element::{ElementType, ElementWithChildren, HtmlElement},
5 },
6 view::Render,
7};
8use std::fmt::Debug;
9
10macro_rules! mathml_global {
11 ($tag:ty, $attr:ty) => {
12 paste::paste! {
13 pub fn $attr<V>(self, value: V) -> HtmlElement <
15 [<$tag:camel>],
16 <At as NextAttribute>::Output<Attr<$crate::html::attribute::[<$attr:camel>], V>>,
17 Ch
18 >
19 where
20 V: AttributeValue,
21 At: NextAttribute,
22 <At as NextAttribute>::Output<Attr<$crate::html::attribute::[<$attr:camel>], V>>: Attribute,
23 {
24 let HtmlElement {
25 #[cfg(any(debug_assertions, leptos_debuginfo))]
26 defined_at,
27 tag,
28 children,
29 attributes
30 } = self;
31 HtmlElement {
32 #[cfg(any(debug_assertions, leptos_debuginfo))]
33 defined_at,
34 tag,
35 children,
36 attributes: attributes.add_any_attr($crate::html::attribute::$attr(value)),
37 }
38 }
39 }
40 }
41}
42
43macro_rules! mathml_elements {
44 ($($tag:ident [$($attr:ty),*]),* $(,)?) => {
45 paste::paste! {
46 $(
47 #[track_caller]
50 pub fn $tag() -> HtmlElement<[<$tag:camel>], (), ()>
51 where
52
53 {
54 HtmlElement {
55 #[cfg(any(debug_assertions, leptos_debuginfo))]
56 defined_at: std::panic::Location::caller(),
57 tag: [<$tag:camel>],
58 attributes: (),
59 children: (),
60 }
61 }
62
63 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
65 pub struct [<$tag:camel>];
66
67 impl<At, Ch> HtmlElement<[<$tag:camel>], At, Ch>
68 where
69 At: Attribute,
70 Ch: Render,
71
72 {
73 mathml_global!($tag, displaystyle);
74 mathml_global!($tag, href);
75 mathml_global!($tag, id);
76 mathml_global!($tag, mathbackground);
77 mathml_global!($tag, mathcolor);
78 mathml_global!($tag, mathsize);
79 mathml_global!($tag, mathvariant);
80 mathml_global!($tag, scriptlevel);
81
82 $(
83 pub fn $attr<V>(self, value: V) -> HtmlElement <
85 [<$tag:camel>],
86 <At as NextAttribute>::Output<Attr<$crate::html::attribute::[<$attr:camel>], V>>,
87 Ch
88 >
89 where
90 V: AttributeValue,
91 At: NextAttribute,
92 <At as NextAttribute>::Output<Attr<$crate::html::attribute::[<$attr:camel>], V>>: Attribute,
93 {
94 let HtmlElement {
95 #[cfg(any(debug_assertions, leptos_debuginfo))]
96 defined_at,
97 tag,
98 children,
99 attributes
100 } = self;
101 HtmlElement {
102 #[cfg(any(debug_assertions, leptos_debuginfo))]
103 defined_at,
104 tag,
105 children,
106 attributes: attributes.add_any_attr($crate::html::attribute::$attr(value)),
107 }
108 }
109 )*
110 }
111
112 impl ElementType for [<$tag:camel>] {
113 type Output = web_sys::Element;
114
115 const TAG: &'static str = stringify!($tag);
116 const SELF_CLOSING: bool = false;
117 const ESCAPE_CHILDREN: bool = true;
118 const NAMESPACE: Option<&'static str> = Some("http://www.w3.org/1998/Math/MathML");
119
120 #[inline(always)]
121 fn tag(&self) -> &str {
122 Self::TAG
123 }
124 }
125
126 impl ElementWithChildren for [<$tag:camel>] {}
127 )*
128 }
129 }
130}
131
132mathml_elements![
133 math [display, xmlns],
134 mi [],
135 mn [],
136 mo [
137 accent, fence, lspace, maxsize, minsize, movablelimits,
138 rspace, separator, stretchy, symmetric, form
139 ],
140 ms [],
141 mspace [height, width],
142 mtext [],
143 menclose [notation],
144 merror [],
145 mfenced [],
146 mfrac [linethickness],
147 mpadded [depth, height, voffset, width],
148 mphantom [],
149 mroot [],
150 mrow [],
151 msqrt [],
152 mstyle [],
153 mmultiscripts [],
154 mover [accent],
155 mprescripts [],
156 msub [],
157 msubsup [],
158 msup [],
159 munder [accentunder],
160 munderover [accent, accentunder],
161 mtable [
162 align, columnalign, columnlines, columnspacing, frame,
163 framespacing, rowalign, rowlines, rowspacing, width
164 ],
165 mtd [columnalign, columnspan, rowalign, rowspan],
166 mtr [columnalign, rowalign],
167 maction [],
168 annotation [],
169 semantics [],
170];