OCaml HTML5 parser/serialiser based on Python's JustHTML
1open Content_category
2open Content_model
3open Attr_spec
4
5let picture =
6 Element_spec.make ~name:"picture"
7 ~categories:[ Flow; Phrasing; Embedded; Palpable ]
8 ~content_model:
9 (Sequence
10 [
11 Zero_or_more (Elements [ "source" ]);
12 Elements [ "img" ];
13 Zero_or_more (Elements [ "script"; "template" ]);
14 ])
15 ~attrs:[] ()
16
17let source =
18 Element_spec.make ~name:"source" ~void:true
19 ~categories:[]
20 ~content_model:Nothing
21 ~attrs:
22 [
23 make "type" ~datatype:"mime" ();
24 make "media" ~datatype:"media_query" ();
25 make "src" ~datatype:"url" ();
26 make "srcset" ~datatype:"srcset" ();
27 make "sizes" ();
28 make "width" ~datatype:"integer" ();
29 make "height" ~datatype:"integer" ();
30 ]
31 ()
32
33let img =
34 (* Note: img is only Interactive when it has usemap attribute;
35 we omit Interactive from static categories since usemap is rare *)
36 Element_spec.make ~name:"img" ~void:true
37 ~categories:[ Flow; Phrasing; Embedded; Palpable ]
38 ~content_model:Nothing
39 ~attrs:
40 [
41 make "src" ~required:true ~datatype:"url" ();
42 make "alt" ();
43 make "srcset" ~datatype:"srcset" ();
44 make "sizes" ();
45 make "crossorigin" ~datatype:"crossorigin" ();
46 make "usemap" ~datatype:"hash" ();
47 make "ismap" ~datatype:"boolean" ();
48 make "width" ~datatype:"integer" ();
49 make "height" ~datatype:"integer" ();
50 make "referrerpolicy" ~datatype:"referrer" ();
51 make "decoding" ~datatype:"decoding" ();
52 make "loading" ~datatype:"loading" ();
53 make "fetchpriority" ~datatype:"fetchpriority" ();
54 ]
55 ~implicit_aria_role:"img" ()
56
57let iframe =
58 Element_spec.make ~name:"iframe"
59 ~categories:[ Flow; Phrasing; Embedded; Interactive; Palpable ]
60 ~content_model:Nothing
61 ~attrs:
62 [
63 make "src" ~datatype:"url" ();
64 make "srcdoc" ();
65 make "name" ~datatype:"target" ();
66 make "sandbox" ~datatype:"sandbox" ();
67 make "allow" ();
68 make "allowfullscreen" ~datatype:"boolean" ();
69 make "width" ~datatype:"integer" ();
70 make "height" ~datatype:"integer" ();
71 make "referrerpolicy" ~datatype:"referrer" ();
72 make "loading" ~datatype:"loading" ();
73 ]
74 ()
75
76let embed =
77 Element_spec.make ~name:"embed" ~void:true
78 ~categories:[ Flow; Phrasing; Embedded; Interactive; Palpable ]
79 ~content_model:Nothing
80 ~attrs:
81 [
82 make "src" ~required:true ~datatype:"url" ();
83 make "type" ~datatype:"mime" ();
84 make "width" ~datatype:"integer" ();
85 make "height" ~datatype:"integer" ();
86 ]
87 ()
88
89let object_ =
90 Element_spec.make ~name:"object"
91 ~categories:[ Flow; Phrasing; Embedded; Palpable; Interactive ]
92 ~content_model:(Mixed [ Flow ])
93 ~attrs:
94 [
95 make "data" ~datatype:"url" ();
96 make "type" ~datatype:"mime" ();
97 make "name" ~datatype:"target" ();
98 make "form" ~datatype:"id" ();
99 make "width" ~datatype:"integer" ();
100 make "height" ~datatype:"integer" ();
101 ]
102 ()
103
104let param =
105 Element_spec.make ~name:"param" ~void:true
106 ~categories:[]
107 ~content_model:Nothing
108 ~attrs:[ make "name" ~required:true (); make "value" ~required:true () ]
109 ()
110
111let video =
112 Element_spec.make ~name:"video"
113 ~categories:[ Flow; Phrasing; Embedded; Palpable; Interactive ]
114 ~content_model:
115 (Choice
116 [
117 Sequence
118 [
119 Zero_or_more (Elements [ "source" ]);
120 Zero_or_more (Elements [ "track" ]);
121 Zero_or_more Transparent;
122 ];
123 Sequence [ Zero_or_more Transparent; Zero_or_more (Elements [ "track" ]) ];
124 ])
125 ~prohibited_ancestors:[ "audio"; "video" ]
126 ~attrs:
127 [
128 make "src" ~datatype:"url" ();
129 make "crossorigin" ~datatype:"crossorigin" ();
130 make "poster" ~datatype:"url" ();
131 make "preload" ~datatype:"preload" ();
132 make "autoplay" ~datatype:"boolean" ();
133 make "playsinline" ~datatype:"boolean" ();
134 make "loop" ~datatype:"boolean" ();
135 make "muted" ~datatype:"boolean" ();
136 make "controls" ~datatype:"boolean" ();
137 make "width" ~datatype:"integer" ();
138 make "height" ~datatype:"integer" ();
139 ]
140 ()
141
142let audio =
143 Element_spec.make ~name:"audio"
144 ~categories:[ Flow; Phrasing; Embedded; Palpable; Interactive ]
145 ~content_model:
146 (Choice
147 [
148 Sequence
149 [
150 Zero_or_more (Elements [ "source" ]);
151 Zero_or_more (Elements [ "track" ]);
152 Zero_or_more Transparent;
153 ];
154 Sequence [ Zero_or_more Transparent; Zero_or_more (Elements [ "track" ]) ];
155 ])
156 ~prohibited_ancestors:[ "audio"; "video" ]
157 ~attrs:
158 [
159 make "src" ~datatype:"url" ();
160 make "crossorigin" ~datatype:"crossorigin" ();
161 make "preload" ~datatype:"preload" ();
162 make "autoplay" ~datatype:"boolean" ();
163 make "loop" ~datatype:"boolean" ();
164 make "muted" ~datatype:"boolean" ();
165 make "controls" ~datatype:"boolean" ();
166 ]
167 ()
168
169let track =
170 Element_spec.make ~name:"track" ~void:true
171 ~categories:[]
172 ~content_model:Nothing
173 ~permitted_parents:[ "audio"; "video" ]
174 ~attrs:
175 [
176 make "kind" ~datatype:"kind" ();
177 make "src" ~required:true ~datatype:"url" ();
178 make "srclang" ~datatype:"language" ();
179 make "label" ();
180 make "default" ~datatype:"boolean" ();
181 ]
182 ()
183
184let map =
185 Element_spec.make ~name:"map"
186 ~categories:[ Flow; Phrasing; Palpable ]
187 ~content_model:Transparent
188 ~attrs:[ make "name" ~required:true () ] ()
189
190let area =
191 Element_spec.make ~name:"area" ~void:true
192 ~categories:[ Flow; Phrasing ]
193 ~content_model:Nothing
194 ~attrs:
195 [
196 make "alt" ();
197 make "coords" ~datatype:"coords" ();
198 make "shape" ~datatype:"shape" ();
199 make "href" ~datatype:"url" ();
200 make "target" ~datatype:"target" ();
201 make "download" ();
202 make "ping" ();
203 make "rel" ~datatype:"link_type" ();
204 make "referrerpolicy" ~datatype:"referrer" ();
205 ]
206 ~implicit_aria_role:"link" ()
207
208let all =
209 [
210 picture;
211 source;
212 img;
213 iframe;
214 embed;
215 object_;
216 param;
217 video;
218 audio;
219 track;
220 map;
221 area;
222 ]