1
2
3
4
5 package template
6
7 import (
8 "strings"
9 )
10
11
12
13
14
15
16
17
18
19 var attrTypeMap = map[string]contentType{
20 "accept": contentTypePlain,
21 "accept-charset": contentTypeUnsafe,
22 "action": contentTypeURL,
23 "alt": contentTypePlain,
24 "archive": contentTypeURL,
25 "async": contentTypeUnsafe,
26 "autocomplete": contentTypePlain,
27 "autofocus": contentTypePlain,
28 "autoplay": contentTypePlain,
29 "background": contentTypeURL,
30 "border": contentTypePlain,
31 "checked": contentTypePlain,
32 "cite": contentTypeURL,
33 "challenge": contentTypeUnsafe,
34 "charset": contentTypeUnsafe,
35 "class": contentTypePlain,
36 "classid": contentTypeURL,
37 "codebase": contentTypeURL,
38 "cols": contentTypePlain,
39 "colspan": contentTypePlain,
40 "content": contentTypeUnsafe,
41 "contenteditable": contentTypePlain,
42 "contextmenu": contentTypePlain,
43 "controls": contentTypePlain,
44 "coords": contentTypePlain,
45 "crossorigin": contentTypeUnsafe,
46 "data": contentTypeURL,
47 "datetime": contentTypePlain,
48 "default": contentTypePlain,
49 "defer": contentTypeUnsafe,
50 "dir": contentTypePlain,
51 "dirname": contentTypePlain,
52 "disabled": contentTypePlain,
53 "draggable": contentTypePlain,
54 "dropzone": contentTypePlain,
55 "enctype": contentTypeUnsafe,
56 "for": contentTypePlain,
57 "form": contentTypeUnsafe,
58 "formaction": contentTypeURL,
59 "formenctype": contentTypeUnsafe,
60 "formmethod": contentTypeUnsafe,
61 "formnovalidate": contentTypeUnsafe,
62 "formtarget": contentTypePlain,
63 "headers": contentTypePlain,
64 "height": contentTypePlain,
65 "hidden": contentTypePlain,
66 "high": contentTypePlain,
67 "href": contentTypeURL,
68 "hreflang": contentTypePlain,
69 "http-equiv": contentTypeUnsafe,
70 "icon": contentTypeURL,
71 "id": contentTypePlain,
72 "ismap": contentTypePlain,
73 "keytype": contentTypeUnsafe,
74 "kind": contentTypePlain,
75 "label": contentTypePlain,
76 "lang": contentTypePlain,
77 "language": contentTypeUnsafe,
78 "list": contentTypePlain,
79 "longdesc": contentTypeURL,
80 "loop": contentTypePlain,
81 "low": contentTypePlain,
82 "manifest": contentTypeURL,
83 "max": contentTypePlain,
84 "maxlength": contentTypePlain,
85 "media": contentTypePlain,
86 "mediagroup": contentTypePlain,
87 "method": contentTypeUnsafe,
88 "min": contentTypePlain,
89 "multiple": contentTypePlain,
90 "name": contentTypePlain,
91 "novalidate": contentTypeUnsafe,
92
93
94
95 "open": contentTypePlain,
96 "optimum": contentTypePlain,
97 "pattern": contentTypeUnsafe,
98 "placeholder": contentTypePlain,
99 "poster": contentTypeURL,
100 "profile": contentTypeURL,
101 "preload": contentTypePlain,
102 "pubdate": contentTypePlain,
103 "radiogroup": contentTypePlain,
104 "readonly": contentTypePlain,
105 "rel": contentTypeUnsafe,
106 "required": contentTypePlain,
107 "reversed": contentTypePlain,
108 "rows": contentTypePlain,
109 "rowspan": contentTypePlain,
110 "sandbox": contentTypeUnsafe,
111 "spellcheck": contentTypePlain,
112 "scope": contentTypePlain,
113 "scoped": contentTypePlain,
114 "seamless": contentTypePlain,
115 "selected": contentTypePlain,
116 "shape": contentTypePlain,
117 "size": contentTypePlain,
118 "sizes": contentTypePlain,
119 "span": contentTypePlain,
120 "src": contentTypeURL,
121 "srcdoc": contentTypeHTML,
122 "srclang": contentTypePlain,
123 "srcset": contentTypeSrcset,
124 "start": contentTypePlain,
125 "step": contentTypePlain,
126 "style": contentTypeCSS,
127 "tabindex": contentTypePlain,
128 "target": contentTypePlain,
129 "title": contentTypePlain,
130 "type": contentTypeUnsafe,
131 "usemap": contentTypeURL,
132 "value": contentTypeUnsafe,
133 "width": contentTypePlain,
134 "wrap": contentTypePlain,
135 "xmlns": contentTypeURL,
136 }
137
138
139
140 func attrType(name string) contentType {
141 if strings.HasPrefix(name, "data-") {
142
143
144
145 name = name[5:]
146 } else if prefix, short, ok := strings.Cut(name, ":"); ok {
147 if prefix == "xmlns" {
148 return contentTypeURL
149 }
150
151 name = short
152 }
153 if t, ok := attrTypeMap[name]; ok {
154 return t
155 }
156
157 if strings.HasPrefix(name, "on") {
158 return contentTypeJS
159 }
160
161
162
163
164
165
166
167
168
169 if strings.Contains(name, "src") ||
170 strings.Contains(name, "uri") ||
171 strings.Contains(name, "url") {
172 return contentTypeURL
173 }
174 return contentTypePlain
175 }
176
View as plain text