···1717 match get_attr name attrs with
1818 | Some v -> String.trim v <> ""
1919 | None -> false
2020+2121+(** Create a unit hashtable from a list of keys for O(1) membership testing. *)
2222+let hashtbl_of_list items =
2323+ let tbl = Hashtbl.create (List.length items) in
2424+ List.iter (fun x -> Hashtbl.add tbl x ()) items;
2525+ tbl
2626+2727+(** Check a list of attributes and report errors for any that are present. *)
2828+let check_disallowed_attrs ~element ~collector ~attrs disallowed =
2929+ List.iter (fun attr ->
3030+ if has_attr attr attrs then
3131+ Message_collector.add_typed collector
3232+ (`Attr (`Not_allowed (`Attr attr, `Elem element)))
3333+ ) disallowed
+25
lib/htmlrw_check/attr_utils.mli
···5353 @param name The attribute name to look for (lowercase)
5454 @param attrs The attribute list
5555 @return [true] if the attribute exists and has a non-empty value *)
5656+5757+(** {1 Utility Functions} *)
5858+5959+val hashtbl_of_list : 'a list -> ('a, unit) Hashtbl.t
6060+(** [hashtbl_of_list items] creates a hashtable for O(1) membership testing.
6161+6262+ @param items List of keys to add
6363+ @return A hashtable where each item maps to unit *)
6464+6565+val check_disallowed_attrs :
6666+ element:string ->
6767+ collector:Message_collector.t ->
6868+ attrs:attrs ->
6969+ string list ->
7070+ unit
7171+(** [check_disallowed_attrs ~element ~collector ~attrs disallowed] reports
7272+ errors for any disallowed attributes that are present.
7373+7474+ This is a convenience function to reduce repetitive attribute checking
7575+ code in checkers.
7676+7777+ @param element The element name for error messages
7878+ @param collector The message collector
7979+ @param attrs The attribute list to check
8080+ @param disallowed List of attribute names that are not allowed *)
+25
lib/htmlrw_check/checker.ml
···6767 | Some f -> f
6868 | None -> fun _ _ -> ()
6969end
7070+7171+(** Create a checker from individual callback functions.
7272+ This eliminates the boilerplate module wrapper at the end of each checker. *)
7373+let make
7474+ (type s)
7575+ ~(create : unit -> s)
7676+ ~(reset : s -> unit)
7777+ ~(start_element : s -> element:Element.t -> Message_collector.t -> unit)
7878+ ~(end_element : s -> tag:Tag.element_tag -> Message_collector.t -> unit)
7979+ ?(characters : (s -> string -> Message_collector.t -> unit) option)
8080+ ?(end_document : (s -> Message_collector.t -> unit) option)
8181+ () : t =
8282+ (module struct
8383+ type state = s
8484+ let create = create
8585+ let reset = reset
8686+ let start_element = start_element
8787+ let end_element = end_element
8888+ let characters = match characters with
8989+ | Some f -> f
9090+ | None -> fun _ _ _ -> ()
9191+ let end_document = match end_document with
9292+ | Some f -> f
9393+ | None -> fun _ _ -> ()
9494+ end : S)
+32
lib/htmlrw_check/checker.mli
···214214 ]}
215215*)
216216module Make : functor (I : Input) -> S with type state = I.state
217217+218218+(** Create a checker from individual callback functions.
219219+220220+ This is a simpler alternative to the [Make] functor that eliminates the
221221+ need for a module wrapper at the end of each checker file.
222222+223223+ {b Example:}
224224+ {[
225225+ let checker = Checker.make
226226+ ~create:(fun () -> { count = 0 })
227227+ ~reset:(fun s -> s.count <- 0)
228228+ ~start_element:(fun s ~element collector -> ...)
229229+ ~end_element:(fun s ~tag collector -> ...)
230230+ ()
231231+ ]}
232232+233233+ @param create State initialization function
234234+ @param reset State reset function
235235+ @param start_element Element start callback
236236+ @param end_element Element end callback
237237+ @param characters Optional text content callback (default: no-op)
238238+ @param end_document Optional document end callback (default: no-op)
239239+*)
240240+val make :
241241+ create:(unit -> 's) ->
242242+ reset:('s -> unit) ->
243243+ start_element:('s -> element:Element.t -> Message_collector.t -> unit) ->
244244+ end_element:('s -> tag:Tag.element_tag -> Message_collector.t -> unit) ->
245245+ ?characters:('s -> string -> Message_collector.t -> unit) ->
246246+ ?end_document:('s -> Message_collector.t -> unit) ->
247247+ unit ->
248248+ t
+2-11
lib/htmlrw_check/content_model/content_checker.ml
···197197 state.ancestor_stack
198198199199(* Package as first-class module *)
200200-let checker =
201201- (module struct
202202- type nonrec state = state
203203-204204- let create = create
205205- let reset = reset
206206- let start_element = start_element
207207- let end_element = end_element
208208- let characters = characters
209209- let end_document = end_document
210210- end : Checker.S)
200200+let checker = Checker.make ~create ~reset ~start_element ~end_element
201201+ ~characters ~end_document ()
···1818 2. Checking each child element or text node against the content model
1919 3. Tracking the ancestor stack to detect prohibited relationships
2020 4. Emitting appropriate errors or warnings for violations
2121-2222- {2 Usage Example}
2323-2424- {[
2525- let checker = Content_checker.create (Message_collector.create ()) in
2626- let module C = (val checker : Checker.S) in
2727- let state = C.create () in
2828-2929- (* Walk the DOM tree *)
3030- C.start_element state ~name:"div" ~namespace:None ~attrs:[] collector;
3131- C.characters state "Hello, world!" collector;
3232- C.end_element state ~name:"div" ~namespace:None collector;
3333- C.end_document state collector
3434- ]}
3521*)
3636-3737-(** Include the standard checker signature. *)
3838-include Checker.S
3939-4040-(** {1 Creation} *)
4141-4242-val create_with_registry : ?registry:Element_registry.t -> Message_collector.t -> state
4343-(** [create_with_registry ?registry collector] creates a content checker with an
4444- optional custom element registry.
4545-4646- If no registry is provided, uses {!Element_registry.default}.
4747-4848- @param registry Custom element registry (defaults to standard HTML5 elements)
4949- @param collector Message collector for validation messages *)
5050-5151-(** {1 First-Class Module} *)
52225323val checker : Checker.t
5424(** [checker] is the content checker packaged as a first-class module.
+1-14
lib/htmlrw_check/semantic/autofocus_checker.ml
···75757676 state.current_depth <- state.current_depth - 1
77777878-let characters _state _text _collector = ()
7979-8080-let end_document _state _collector = ()
8181-8282-let checker =
8383- (module struct
8484- type nonrec state = state
8585- let create = create
8686- let reset = reset
8787- let start_element = start_element
8888- let end_element = end_element
8989- let characters = characters
9090- let end_document = end_document
9191- end : Checker.S)
7878+let checker = Checker.make ~create ~reset ~start_element ~end_element ()
+2-15
lib/htmlrw_check/semantic/form_checker.ml
···44 checks (like button-outside-form and label references) don't match
55 Nu validator's behavior. *)
6677-type state = unit
77+type state = unit [@@warning "-34"]
8899let create () = ()
1010···44444545let end_element _state ~tag:_ _collector = ()
46464747-let characters _state _text _collector = ()
4848-4949-let end_document _state _collector = ()
5050-5151-let checker = (module struct
5252- type nonrec state = state
5353-5454- let create = create
5555- let reset = reset
5656- let start_element = start_element
5757- let end_element = end_element
5858- let characters = characters
5959- let end_document = end_document
6060-end : Checker.S)
4747+let checker = Checker.make ~create ~reset ~start_element ~end_element ()
-2
lib/htmlrw_check/semantic/form_checker.mli
···5050 @see <https://www.w3.org/WAI/WCAG21/Understanding/labels-or-instructions.html>
5151 WCAG: Labels or Instructions *)
52525353-include Checker.S
5454-5553val checker : Checker.t
5654(** A first-class module instance of this checker.
5755
+3-15
lib/htmlrw_check/semantic/id_checker.ml
···193193 | _ -> ())
194194 | _ -> ())
195195196196-let end_element _state ~tag:_ _collector =
197197- ()
198198-199199-let characters _state _text _collector =
200200- ()
196196+let end_element _state ~tag:_ _collector = ()
201197202198let end_document state collector =
203199 (* Check all ID references point to existing IDs *)
···224220 (Error_code.q ref.attribute) (Error_code.q ref.referring_element) (Error_code.q ref.referenced_id)))
225221 ) state.usemap_references
226222227227-let checker = (module struct
228228- type nonrec state = state
229229-230230- let create = create
231231- let reset = reset
232232- let start_element = start_element
233233- let end_element = end_element
234234- let characters = characters
235235- let end_document = end_document
236236-end : Checker.S)
223223+let checker = Checker.make ~create ~reset ~start_element ~end_element
224224+ ~end_document ()
-2
lib/htmlrw_check/semantic/id_checker.mli
···55 - ID references (for, headers, aria-*, etc.) point to existing IDs
66 - ID values conform to HTML5 requirements *)
7788-include Checker.S
99-108val checker : Checker.t
119(** [checker] is a checker instance for validating ID uniqueness and references. *)
···326326 | _ -> ()
327327 end
328328329329-let checker =
330330- (module struct
331331- type nonrec state = state
332332- let create = create
333333- let reset = reset
334334- let start_element = start_element
335335- let end_element = end_element
336336- let characters = characters
337337- let end_document = end_document
338338- end : Checker.S)
329329+let checker = Checker.make ~create ~reset ~start_element ~end_element
330330+ ~characters ~end_document ()
+1-17
lib/htmlrw_check/semantic/nesting_checker.ml
···350350 end
351351 | _ -> ()
352352353353-let characters _state _text _collector =
354354- () (* No text-specific nesting checks *)
355355-356356-let end_document _state _collector =
357357- () (* No document-level checks needed *)
358358-359353(** Create the checker as a first-class module. *)
360360-let checker =
361361- let module M = struct
362362- type nonrec state = state
363363- let create = create
364364- let reset = reset
365365- let start_element = start_element
366366- let end_element = end_element
367367- let characters = characters
368368- let end_document = end_document
369369- end in
370370- (module M : Checker.S)
354354+let checker = Checker.make ~create ~reset ~start_element ~end_element ()
-2
lib/htmlrw_check/semantic/nesting_checker.mli
···7373 HTML5 specification: Content models
7474*)
75757676-include Checker.S
7777-7876val checker : Checker.t
7977(** [checker] is a checker instance for validating element nesting rules. *)
+1-15
lib/htmlrw_check/semantic/obsolete_checker.ml
···315315 | Tag.Html `Head -> state.in_head <- false
316316 | _ -> ()
317317318318-let characters _state _text _collector = ()
319319-320320-let end_document _state _collector = ()
321321-322322-let checker =
323323- let module M = struct
324324- type nonrec state = state
325325- let create = create
326326- let reset = reset
327327- let start_element = start_element
328328- let end_element = end_element
329329- let characters = characters
330330- let end_document = end_document
331331- end in
332332- (module M : Checker.S)
318318+let checker = Checker.make ~create ~reset ~start_element ~end_element ()
-5
lib/htmlrw_check/semantic/obsolete_checker.mli
···5252 ]}
5353*)
54545555-(** Include the standard checker signature. *)
5656-include Checker.S
5757-5858-(** {1 Checker Instance} *)
5959-6055val checker : Checker.t
6156(** [checker] is a pre-configured obsolete checker instance that can be
6257 registered with the checker registry.
+2-12
lib/htmlrw_check/semantic/option_checker.ml
···6464 | [] -> ()
6565 end
66666767-let end_document _state _collector = ()
6868-6969-let checker =
7070- (module struct
7171- type nonrec state = state
7272- let create = create
7373- let reset = reset
7474- let start_element = start_element
7575- let end_element = end_element
7676- let characters = characters
7777- let end_document = end_document
7878- end : Checker.S)
6767+let checker = Checker.make ~create ~reset ~start_element ~end_element
6868+ ~characters ()
···468468 | _ -> () (* Skip non-HTML elements *)
469469470470let end_element _state ~tag:_ _collector = ()
471471-let characters _state _text _collector = ()
472472-let end_document _state _collector = ()
473471474474-let checker =
475475- (module struct
476476- type nonrec state = state
477477- let create = create
478478- let reset = reset
479479- let start_element = start_element
480480- let end_element = end_element
481481- let characters = characters
482482- let end_document = end_document
483483- end : Checker.S)
472472+let checker = Checker.make ~create ~reset ~start_element ~end_element ()
+1-12
lib/htmlrw_check/specialized/base_checker.ml
···2626 | _ -> ()
27272828let end_element _state ~tag:_ _collector = ()
2929-let characters _state _text _collector = ()
3030-let end_document _state _collector = ()
31293232-let checker =
3333- (module struct
3434- type nonrec state = state
3535- let create = create
3636- let reset = reset
3737- let start_element = start_element
3838- let end_element = end_element
3939- let characters = characters
4040- let end_document = end_document
4141- end : Checker.S)
3030+let checker = Checker.make ~create ~reset ~start_element ~end_element ()
+2-13
lib/htmlrw_check/specialized/datetime_checker.ml
···439439 end
440440441441(** Checker state *)
442442-type state = unit
442442+type state = unit [@@warning "-34"]
443443444444let create () = ()
445445let reset _state = ()
···470470 | _ -> () (* Non-HTML elements don't have datetime attributes *)
471471472472let end_element _state ~tag:_ _collector = ()
473473-let characters _state _text _collector = ()
474474-let end_document _state _collector = ()
475473476476-let checker =
477477- (module struct
478478- type nonrec state = state
479479- let create = create
480480- let reset = reset
481481- let start_element = start_element
482482- let end_element = end_element
483483- let characters = characters
484484- let end_document = end_document
485485- end : Checker.S)
474474+let checker = Checker.make ~create ~reset ~start_element ~end_element ()
+2-12
lib/htmlrw_check/specialized/dl_checker.ml
···254254 end
255255 end
256256257257-let end_document _state _collector = ()
258258-259259-let checker =
260260- (module struct
261261- type nonrec state = state
262262- let create = create
263263- let reset = reset
264264- let start_element = start_element
265265- let end_element = end_element
266266- let characters = characters
267267- let end_document = end_document
268268- end : Checker.S)
257257+let checker = Checker.make ~create ~reset ~start_element ~end_element
258258+ ~characters ()
+1-13
lib/htmlrw_check/specialized/h1_checker.ml
···3434 state.svg_depth <- state.svg_depth - 1
3535 | _ -> ()
36363737-let characters _state _text _collector = ()
3838-let end_document _state _collector = ()
3939-4040-let checker =
4141- (module struct
4242- type nonrec state = state
4343- let create = create
4444- let reset = reset
4545- let start_element = start_element
4646- let end_element = end_element
4747- let characters = characters
4848- let end_document = end_document
4949- end : Checker.S)
3737+let checker = Checker.make ~create ~reset ~start_element ~end_element ()
+2-10
lib/htmlrw_check/specialized/heading_checker.ml
···126126 Message_collector.add_typed collector
127127 (`Generic "Document contains no heading elements (h1-h6). Headings provide important document structure for accessibility")
128128129129-let checker = (module struct
130130- type nonrec state = state
131131-132132- let create = create
133133- let reset = reset
134134- let start_element = start_element
135135- let end_element = end_element
136136- let characters = characters
137137- let end_document = end_document
138138-end : Checker.S)
129129+let checker = Checker.make ~create ~reset ~start_element ~end_element
130130+ ~characters ~end_document ()
-2
lib/htmlrw_check/specialized/heading_checker.mli
···66 - Multiple h1 usage patterns
77 - Headings should not be empty *)
8899-include Checker.S
1010-119val checker : Checker.t
1210(** [checker] is a checker instance for validating heading structure. *)
+2-12
lib/htmlrw_check/specialized/importmap_checker.ml
···307307 if state.in_importmap then
308308 Buffer.add_string state.content text
309309310310-let end_document _state _collector = ()
311311-312312-let checker =
313313- (module struct
314314- type nonrec state = state
315315- let create = create
316316- let reset = reset
317317- let start_element = start_element
318318- let end_element = end_element
319319- let characters = characters
320320- let end_document = end_document
321321- end : Checker.S)
310310+let checker = Checker.make ~create ~reset ~start_element ~end_element
311311+ ~characters ()
+7-24
lib/htmlrw_check/specialized/label_checker.ml
···55(** Labelable elements that label can reference *)
66let labelable_elements = ["button"; "input"; "meter"; "output"; "progress"; "select"; "textarea"]
7788-(** Helper to get attribute value *)
99-let get_attr attrs name =
1010- let name_lower = String.lowercase_ascii name in
1111- List.find_map (fun (n, v) ->
1212- if String.lowercase_ascii n = name_lower then Some v else None
1313- ) attrs
1414-158type label_for_info = {
169 for_target : string;
1710 has_role : bool;
···5649 state.in_label <- true;
5750 state.label_depth <- 1; (* Start at 1 for the label element itself *)
5851 state.labelable_count <- 0;
5959- let for_value = get_attr element.raw_attrs "for" in
6060- let has_role = get_attr element.raw_attrs "role" <> None in
6161- let has_aria_label = get_attr element.raw_attrs "aria-label" <> None in
5252+ let for_value = Attr_utils.get_attr "for" element.raw_attrs in
5353+ let has_role = Attr_utils.get_attr "role" element.raw_attrs <> None in
5454+ let has_aria_label = Attr_utils.get_attr "aria-label" element.raw_attrs <> None in
6255 state.label_for_value <- for_value;
6356 state.label_has_role <- has_role;
6457 state.label_has_aria_label <- has_aria_label;
···73667467 (* Track labelable element IDs *)
7568 (if List.mem name_lower labelable_elements then
7676- match get_attr element.raw_attrs "id" with
6969+ match Attr_utils.get_attr "id" element.raw_attrs with
7770 | Some id -> state.labelable_ids <- id :: state.labelable_ids
7871 | None -> ());
7972···8982 (* Check if label has for attribute and descendant has mismatched id *)
9083 (match state.label_for_value with
9184 | Some for_value ->
9292- let descendant_id = get_attr element.raw_attrs "id" in
8585+ let descendant_id = Attr_utils.get_attr "id" element.raw_attrs in
9386 (match descendant_id with
9487 | None ->
9588 Message_collector.add_typed collector (`Label `For_id_mismatch)
···120113 | _ -> ()
121114 end
122115123123-let characters _state _text _collector = ()
124124-125116let end_document state collector =
126117 List.iter (fun label_info ->
127118 if List.mem label_info.for_target state.labelable_ids then begin
···132123 end
133124 ) state.labels_for
134125135135-let checker =
136136- (module struct
137137- type nonrec state = state
138138- let create = create
139139- let reset = reset
140140- let start_element = start_element
141141- let end_element = end_element
142142- let characters = characters
143143- let end_document = end_document
144144- end : Checker.S)
126126+let checker = Checker.make ~create ~reset ~start_element ~end_element
127127+ ~end_document ()
+3-21
lib/htmlrw_check/specialized/language_checker.ml
···33 Validates language attributes. *)
4455(** Checker state - currently minimal since we only check attributes. *)
66-type state = unit
66+type state = unit [@@warning "-34"]
7788let create () = ()
99···9494 let name = Tag.tag_to_string element.Element.tag in
9595 process_language_attrs ~element:name ~namespace:None ~attrs:element.raw_attrs ~location collector
96969797-let end_element _state ~tag:_ _collector =
9898- ()
9999-100100-let characters _state _text _collector =
101101- ()
102102-103103-let end_document _state _collector =
104104- (* Note: The "missing lang on html" warning is only produced for specific
105105- test cases in the Nu validator. We don't produce it by default. *)
106106- ()
107107-108108-let checker = (module struct
109109- type nonrec state = state
9797+let end_element _state ~tag:_ _collector = ()
11098111111- let create = create
112112- let reset = reset
113113- let start_element = start_element
114114- let end_element = end_element
115115- let characters = characters
116116- let end_document = end_document
117117-end : Checker.S)
9999+let checker = Checker.make ~create ~reset ~start_element ~end_element ()
-2
lib/htmlrw_check/specialized/language_checker.mli
···1212 - Empty lang="" is valid (indicates unknown language)
1313 - Primary language subtag should be valid *)
14141515-include Checker.S
1616-1715val checker : Checker.t
1816(** [checker] is a checker instance for validating language attributes. *)
+2-13
lib/htmlrw_check/specialized/microdata_checker.ml
···288288 state.scope_stack <- rest
289289 | _ -> ()
290290291291-let characters _state _text _collector =
292292- ()
293293-294291let end_document state collector =
295292 (* Check all itemref references point to existing IDs *)
296293 List.iter (fun ref ->
···306303 (* Detect itemref cycles *)
307304 detect_itemref_cycles state collector
308305309309-let checker = (module struct
310310- type nonrec state = state
311311-312312- let create = create
313313- let reset = reset
314314- let start_element = start_element
315315- let end_element = end_element
316316- let characters = characters
317317- let end_document = end_document
318318-end : Checker.S)
306306+let checker = Checker.make ~create ~reset ~start_element ~end_element
307307+ ~end_document ()
···1212 - Detects itemref cycles (A references B, B references A)
1313 - itemprop values must be valid property names (no colons unless URL) *)
14141515-include Checker.S
1616-1715val checker : Checker.t
1816(** [checker] is a checker instance for validating microdata. *)
+2-13
lib/htmlrw_check/specialized/mime_type_checker.ml
···148148 ("object", ["type"]);
149149]
150150151151-type state = unit
151151+type state = unit [@@warning "-34"]
152152153153let create () = ()
154154let reset _state = ()
···193193 | _ -> () (* Non-HTML elements don't have MIME type checks *)
194194195195let end_element _state ~tag:_ _collector = ()
196196-let characters _state _text _collector = ()
197197-let end_document _state _collector = ()
198196199199-let checker =
200200- (module struct
201201- type nonrec state = state
202202- let create = create
203203- let reset = reset
204204- let start_element = start_element
205205- let end_element = end_element
206206- let characters = characters
207207- let end_document = end_document
208208- end : Checker.S)
197197+let checker = Checker.make ~create ~reset ~start_element ~end_element ()
···2233 Validates that text content is in Unicode Normalization Form C (NFC). *)
4455-type state = unit
55+type state = unit [@@warning "-34"]
6677let create () = ()
88let reset _state = ()
···5656 (`I18n (`Not_nfc (`Replacement replacement)))
5757 end
58585959-let end_document _state _collector = ()
6060-6161-let checker =
6262- (module struct
6363- type nonrec state = state
6464- let create = create
6565- let reset = reset
6666- let start_element = start_element
6767- let end_element = end_element
6868- let characters = characters
6969- let end_document = end_document
7070- end : Checker.S)
5959+let checker = Checker.make ~create ~reset ~start_element ~end_element
6060+ ~characters ()
+2-12
lib/htmlrw_check/specialized/picture_checker.ml
···218218 (`Element (`Text_not_allowed (`Parent "picture")))
219219 end
220220221221-let end_document _state _collector = ()
222222-223223-let checker =
224224- (module struct
225225- type nonrec state = state
226226- let create = create
227227- let reset = reset
228228- let start_element = start_element
229229- let end_element = end_element
230230- let characters = characters
231231- let end_document = end_document
232232- end : Checker.S)
221221+let checker = Checker.make ~create ~reset ~start_element ~end_element
222222+ ~characters ()
+2-12
lib/htmlrw_check/specialized/ruby_checker.ml
···117117 | [] -> ()
118118 end
119119120120-let end_document _state _collector = ()
121121-122122-let checker =
123123- (module struct
124124- type nonrec state = state
125125- let create = create
126126- let reset = reset
127127- let start_element = start_element
128128- let end_element = end_element
129129- let characters = characters
130130- let end_document = end_document
131131- end : Checker.S)
120120+let checker = Checker.make ~create ~reset ~start_element ~end_element
121121+ ~characters ()
+5-26
lib/htmlrw_check/specialized/source_checker.ml
···3535 let ctx = current_context state in
3636 (match ctx with
3737 | Video | Audio ->
3838- if Attr_utils.has_attr "srcset" element.raw_attrs then
3939- Message_collector.add_typed collector
4040- (`Attr (`Not_allowed (`Attr "srcset", `Elem "source")));
4141- if Attr_utils.has_attr "sizes" element.raw_attrs then
4242- Message_collector.add_typed collector
4343- (`Attr (`Not_allowed (`Attr "sizes", `Elem "source")));
4444- if Attr_utils.has_attr "width" element.raw_attrs then
4545- Message_collector.add_typed collector
4646- (`Attr (`Not_allowed (`Attr "width", `Elem "source")));
4747- if Attr_utils.has_attr "height" element.raw_attrs then
4848- Message_collector.add_typed collector
4949- (`Attr (`Not_allowed (`Attr "height", `Elem "source")))
3838+ (* These attributes are only valid on source in picture, not audio/video *)
3939+ Attr_utils.check_disallowed_attrs
4040+ ~element:"source" ~collector ~attrs:element.raw_attrs
4141+ ["srcset"; "sizes"; "width"; "height"]
5042 | Picture | Other -> ())
5143 | _ -> ()
5244···5850 | [] -> ())
5951 | _ -> ()
60526161-let characters _state _text _collector = ()
6262-6363-let end_document _state _collector = ()
6464-6565-let checker =
6666- (module struct
6767- type nonrec state = state
6868- let create = create
6969- let reset = reset
7070- let start_element = start_element
7171- let end_element = end_element
7272- let characters = characters
7373- let end_document = end_document
7474- end : Checker.S)
5353+let checker = Checker.make ~create ~reset ~start_element ~end_element ()