OCaml HTML5 parser/serialiser based on Python's JustHTML
1(*---------------------------------------------------------------------------
2 Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3 SPDX-License-Identifier: MIT
4 ---------------------------------------------------------------------------*)
5
6(** JavaScript API for HTML5 validation in the browser.
7
8 This module provides the main entry points for validating HTML in a
9 browser environment. It wraps the core {!Htmlrw_check} validator and
10 adds browser-specific functionality for element mapping and annotation.
11
12 {2 JavaScript Usage}
13
14 After loading the compiled JavaScript, the API is available on [window]:
15
16 {v
17 // Validate an element (recommended)
18 const result = html5rw.validateElement(document.body);
19 console.log(result.errorCount, "errors found");
20
21 // Validate with annotation
22 html5rw.validateAndAnnotate(document.body, {
23 showTooltips: true,
24 showPanel: true
25 });
26
27 // Validate a raw HTML string
28 const result = html5rw.validateString("<div><p>Hello</div>");
29 result.warnings.forEach(w => console.log(w.message));
30 v}
31
32 {2 OCaml Usage}
33
34 {[
35 let result = Htmlrw_js.validate_element (Brr.Document.body G.document) in
36 List.iter (fun bm ->
37 Brr.Console.log [Jstr.v bm.Htmlrw_js_types.message.text]
38 ) result.messages
39 ]} *)
40
41
42open Htmlrw_js_types
43
44
45(** {1 Validation} *)
46
47(** Validate an HTML string.
48
49 This is the simplest form of validation. Since there's no source element,
50 the returned messages will not have element references.
51
52 {[
53 let result = validate_string "<html><body><img></body></html>" in
54 if Htmlrw_check.has_errors result.core_result then
55 (* handle errors *)
56 ]} *)
57val validate_string : string -> result
58
59(** Validate a DOM element's HTML.
60
61 Serializes the element to HTML, validates it, and maps the results
62 back to the live DOM elements.
63
64 {[
65 let result = validate_element (Document.body G.document) in
66 List.iter (fun bm ->
67 match bm.element_ref with
68 | Some { element = Some el; _ } ->
69 El.set_class (Jstr.v "has-error") true el
70 | _ -> ()
71 ) result.messages
72 ]} *)
73val validate_element : Brr.El.t -> result
74
75
76(** {1 Validation with Annotation}
77
78 These functions validate and immediately annotate the DOM with results. *)
79
80(** Validate and annotate an element.
81
82 This combines validation with DOM annotation. The element and its
83 descendants are annotated with data attributes, classes, and optionally
84 tooltips based on the validation results.
85
86 @param config Annotation configuration. Defaults to
87 [Htmlrw_js_types.default_annotation_config]. *)
88val validate_and_annotate :
89 ?config:annotation_config -> Brr.El.t -> result
90
91(** Validate, annotate, and show the warning panel.
92
93 The all-in-one function for browser validation with full UI.
94
95 @param annotation_config How to annotate elements.
96 @param panel_config How to display the warning panel. *)
97val validate_and_show_panel :
98 ?annotation_config:annotation_config ->
99 ?panel_config:panel_config ->
100 Brr.El.t ->
101 result
102
103
104(** {1 Result Inspection} *)
105
106(** Get messages filtered by severity. *)
107val errors : result -> browser_message list
108val warnings_only : result -> browser_message list
109val infos : result -> browser_message list
110
111(** Check if there are any errors. *)
112val has_errors : result -> bool
113
114(** Check if there are any warnings or errors. *)
115val has_issues : result -> bool
116
117(** Get total count of all messages. *)
118val message_count : result -> int
119
120
121(** {1 JavaScript Export}
122
123 These functions register the API on the JavaScript global object. *)
124
125(** Register the validation API on [window.html5rw].
126
127 Call this from your main entry point to expose the JavaScript API:
128
129 {[
130 let () = Htmlrw_js.register_global_api ()
131 ]}
132
133 This exposes:
134 - [html5rw.validateString(html)] -> result object
135 - [html5rw.validateElement(el)] -> result object
136 - [html5rw.validateAndAnnotate(el, config?)] -> result object
137 - [html5rw.validateAndShowPanel(el, config?)] -> result object
138 - [html5rw.clearAnnotations(el)] -> void
139 - [html5rw.hidePanel()] -> void *)
140val register_global_api : unit -> unit
141
142(** Register the API on a custom object instead of [window.html5rw].
143
144 Useful for module bundlers or when you want to control the namespace. *)
145val register_api_on : Jv.t -> unit
146
147
148(** {1 Low-level Access} *)
149
150(** Access the element map from a validation result.
151
152 Useful for custom element lookup logic. Returns [None] if the result
153 was from {!validate_string} (no source element). *)
154val element_map : result -> Htmlrw_js_dom.t option