1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
use super::{Attr, AttributeValue};
use crate::renderer::Renderer;
use std::{fmt::Debug, marker::PhantomData};

pub trait AttributeKey: Clone + Send + 'static {
    const KEY: &'static str;
}

macro_rules! attributes {
	($($key:ident $html:literal),* $(,)?) => {
        paste::paste! {
            $(
                pub fn $key<V, Rndr>(value: V) -> Attr<[<$key:camel>], V, Rndr>
				where V: AttributeValue<Rndr>,
                  Rndr: Renderer
                {
                    Attr([<$key:camel>], value, PhantomData)
                }

				#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
				pub struct [<$key:camel>];

				impl AttributeKey for [<$key:camel>] {
					const KEY: &'static str = $html;
				}
            )*
		}
    }
}

// TODO attribute names with underscores should be kebab-cased
attributes! {
    // HTML
    abbr "abbr", // [],
    accept_charset "accept-charset", // [],
    accept "accept", // [],
    accesskey "accesskey", // [], // [GlobalAttribute]
    action "action", // [],
    align "align", // [],
    allow "allow", // [],
    allowfullscreen "allowfullscreen", // [],
    allowpaymentrequest "allowpaymentrequest", // [],
    alt "alt", // [],
    aria_atomic "aria-atomic", // [], // [GlobalAttribute] // [AriaAttribute],
    aria_busy "aria-busy", // [], // [GlobalAttribute] // [AriaAttribute],
    aria_controls "aria-controls", // [], // [GlobalAttribute] // [AriaAttribute],
    aria_current "aria-current", // [], // [GlobalAttribute] // [AriaAttribute],
    aria_describedby "aria-describedby", // [], // [GlobalAttribute] // [AriaAttribute],
    aria_description "aria-description", // [], // [GlobalAttribute] // [AriaAttribute],
    aria_details "aria-details", // [], // [GlobalAttribute] // [AriaAttribute],
    aria_disabled "aria-disabled", // [], // [GlobalAttribute] // [AriaAttribute],
    aria_dropeffect "aria-dropeffect", // [], // [GlobalAttribute] // [AriaAttribute],
    aria_errormessage "aria-errormessage", // [], // [GlobalAttribute] // [AriaAttribute],
    aria_flowto "aria-flowto", // [], // [GlobalAttribute] // [AriaAttribute],
    aria_grabbed "aria-grabbed", // [], // [GlobalAttribute] // [AriaAttribute],
    aria_haspopup "aria-haspopup", // [], // [GlobalAttribute] // [AriaAttribute],
    aria_hidden "aria-hidden", // [], // [GlobalAttribute] // [AriaAttribute],
    aria_invalid "aria-invalid", // [], // [GlobalAttribute] // [AriaAttribute],
    aria_keyshortcuts "aria-keyshortcuts", // [], // [GlobalAttribute] // [AriaAttribute],
    aria_label "aria-label", // [], // [GlobalAttribute] // [AriaAttribute],
    aria_labelledby "aria-labelledby", // [], // [GlobalAttribute] // [AriaAttribute],
    aria_live "aria-live", // [], // [GlobalAttribute] // [AriaAttribute],
    aria_owns "aria-owns", // [], // [GlobalAttribute] // [AriaAttribute],
    aria_relevant "aria-relevant", // [], // [GlobalAttribute] // [AriaAttribute],
    aria_roledescription "aria-roledescription", // [], // [GlobalAttribute] // [AriaAttribute],
    r#as "as", // [],
    r#async "async", // [],
    autocapitalize "autocapitalize", // [], // [GlobalAttribute]
    autocomplete "autocomplete", // [],
    autofocus "autofocus", // [], // [GlobalAttribute]
    autoplay "autoplay", // [],
    background "background", // [],
    bgcolor "bgcolor", // [],
    blocking "blocking", // [],
    border "border", // [],
    buffered "buffered", // [],
    capture "capture", // [],
    challenge "challenge", // [],
    charset "charset", // [],
    checked "checked", // [],
    cite "cite", // [],
    // class is handled in ../class.rs instead
    //class "class", // [],
    code "code", // [],
    color "color", // [],
    cols "cols", // [],
    colspan "colspan", // [],
    content "content", // [],
    contenteditable "contenteditable", // [], // [GlobalAttribute]
    contextmenu "contextmenu", // [], // [GlobalAttribute]
    controls "controls", // [],
    controlslist "controlslist", // [],
    coords "coords", // [],
    crossorigin "crossorigin", // [],
    csp "csp", // [],
    data "data", // [],
    datetime "datetime", // [],
    decoding "decoding", // [],
    default "default", // [],
    defer "defer", // [],
    dir "dir", // [], // [GlobalAttribute]
    dirname "dirname", // [],
    disabled "disabled", // [],
    disablepictureinpicture "disablepictureinpicture", // [],
    disableremoteplayback "disableremoteplayback", // [],
    download "download", // [],
    draggable "draggable", // [], // [GlobalAttribute]
    enctype "enctype", // [],
    enterkeyhint "enterkeyhint", // [], // [GlobalAttribute]
    exportparts "exportparts", // [], // [GlobalAttribute]
    fetchpriority "fetchprioty", // [],
    r#for "for", // [],
    form "form", // [],
    formaction "formaction", // [],
    formenctype "formenctype", // [],
    formmethod "formmethod", // [],
    formnovalidate "formnovalidate", // [],
    formtarget "formtarget", // [],
    headers "headers", // [],
    height "height", // [],
    hidden "hidden", // [], // [GlobalAttribute]
    high "high", // [],
    href "href", // [],
    hreflang "hreflang", // [],
    http_equiv "http-equiv", // [],
    icon "icon", // [],
    id "id", // [], // [GlobalAttribute]
    imagesizes "imagesizes",
    imagesrcset "imagesrcset",
    importance "importance", // [],
    inert "inert", // [], // [GlobalAttribute]
    inputmode "inputmode", // [], // [GlobalAttribute]
    integrity "integrity", // [],
    intrinsicsize "intrinsicsize", // [],
    is "is", // [], // [GlobalAttribute]
    ismap "ismap", // [],
    itemid "itemid", // [], // [GlobalAttribute]
    itemprop "itemprop", // [], // [GlobalAttribute]
    itemref "itemref", // [], // [GlobalAttribute]
    itemscope "itemscope", // [], // [GlobalAttribute]
    itemtype "itemtype", // [], // [GlobalAttribute]
    keytype "keytype", // [],
    kind "kind", // [],
    label "label", // [],
    lang "lang", // [], // [GlobalAttribute]
    language "language", // [],
    list "list", // [],
    loading "loading", // [],
    r#loop "loop", // [],
    low "low", // [],
    manifest "manifest", // [],
    max "max", // [],
    maxlength "maxlength", // [],
    media "media", // [],
    method "method", // [],
    min "min", // [],
    minlength "minlength", // [],
    multiple "multiple", // [],
    muted "muted", // [],
    name "name", // [],
    nomodule "nomodule", // [],
    nonce "nonce", // [], // [GlobalAttribute]
    novalidate "novalidate", // [],
    open "open", // [],
    optimum "optimum", // [],
    part "part", // [], // [GlobalAttribute]
    pattern "pattern", // [],
    ping "ping", // [],
    placeholder "placeholder", // [],
    playsinline "playsinline", // [],
    popover "popover", // [], // [GlobalAttribute]
    popovertarget "popovertarget",
    popovertargetaction "popovertargetaction",
    poster "poster", // [],
    preload "preload", // [],
    radiogroup "radiogroup", // [],
    readonly "readonly", // [],
    referrerpolicy "referrerpolicy", // [],
    rel "rel", // [],
    required "required", // [],
    reversed "reversed", // [],
    role "role", // [], // [GlobalAttribute] // [AriaAttribute],
    rows "rows", // [],
    rowspan "rowspan", // [],
    sandbox "sandbox", // [],
    scope "scope", // [],
    scoped "scoped", // [],
    selected "selected", // [],
    shape "shape", // [],
    size "size", // [],
    sizes "sizes", // [],
    slot "slot", // [], // [GlobalAttribute]
    span "span", // [],
    spellcheck "spellcheck", // [], // [GlobalAttribute]
    src "src", // [],
    srcdoc "srcdoc", // [],
    srclang "srclang", // [],
    srcset "srcset", // [],
    start "start", // [],
    step "step", // [],
    // style is handled in ../style.rs instead
    // style "style", // [],
    summary "summary", // [],
    tabindex "tabindex", // [], // [GlobalAttribute]
    target "target", // [],
    title "title", // [], // [GlobalAttribute]
    translate "translate", // [], // [GlobalAttribute]
    r#type "type", // [],
    usemap "usemap", // [],
    value "value", // [],
    virtualkeyboardpolicy "virtualkeyboardpolicy", // [], // [GlobalAttribute]
    width "width", // [],
    wrap "wrap", // [],
    // Event Handler Attributes
    onabort "onabort", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onautocomplete "onautocomplete", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onautocompleteerror "onautocompleteerror", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onblur "onblur", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    oncancel "oncancel", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    oncanplay "oncanplay", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    oncanplaythrough "oncanplaythrough", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onchange "onchange", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onclick "onclick", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onclose "onclose", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    oncontextmenu "oncontextmenu", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    oncuechange "oncuechange", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    ondblclick "ondblclick", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    ondrag "ondrag", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    ondragend "ondragend", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    ondragenter "ondragenter", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    ondragleave "ondragleave", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    ondragover "ondragover", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    ondragstart "ondragstart", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    ondrop "ondrop", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    ondurationchange "ondurationchange", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onemptied "onemptied", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onended "onended", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onerror "onerror", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onfocus "onfocus", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    oninput "oninput", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    oninvalid "oninvalid", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onkeydown "onkeydown", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onkeypress "onkeypress", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onkeyup "onkeyup", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onload "onload", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onloadeddata "onloadeddata", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onloadedmetadata "onloadedmetadata", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onloadstart "onloadstart", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onmousedown "onmousedown", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onmouseenter "onmouseenter", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onmouseleave "onmouseleave", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onmousemove "onmousemove", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onmouseout "onmouseout", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onmouseover "onmouseover", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onmouseup "onmouseup", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onmousewheel "onmousewheel", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onpause "onpause", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onplay "onplay", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onplaying "onplaying", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onprogress "onprogress", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onratechange "onratechange", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onreset "onreset", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onresize "onresize", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onscroll "onscroll", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onseeked "onseeked", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onseeking "onseeking", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onselect "onselect", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onshow "onshow", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onsort "onsort", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onstalled "onstalled", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onsubmit "onsubmit", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onsuspend "onsuspend", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    ontimeupdate "ontimeupdate", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    ontoggle "ontoggle", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onvolumechange "onvolumechange", // [], // [GlobalAttribute] // [EventHandlerAttribute],
    onwaiting "onwaiting", // [], // [GlobalAttribute] // [EventHandlerAttribute],

    // MathML attributes that aren't in HTML
    accent "accent",
    accentunder "accentunder",
    columnalign "columnalign",
    columnlines "columnlines",
    columnspacing "columnspacing",
    columnspan "columnspan",
    depth "depth",
    display "display",
    displaystyle "displaystyle",
    fence "fence",
    frame "frame",
    framespacing "framespacing",
    linethickness "linethickness",
    lspace "lspace",
    mathbackground "mathbackground",
    mathcolor "mathcolor",
    mathsize "mathsize",
    mathvariant "mathvariant",
    maxsize "maxsize",
    minsize "minsize",
    movablelimits "movablelimits",
    notation "notation",
    rowalign "rowalign",
    rowlines "rowlines",
    rowspacing "rowspacing",
    rspace "rspace",
    scriptlevel "scriptlevel",
    separator "separator",
    stretchy "stretchy",
    symmetric "symmetric",
    voffset "voffset",
    xmlns "xmlns",
}