+46
-13
lib/js/htmlrw_js_ui.ml
+46
-13
lib/js/htmlrw_js_ui.ml
···
6
open Brr
7
open Htmlrw_js_types
8
9
module Css_class = struct
10
let panel = Jstr.v "html5rw-panel"
11
let panel_header = Jstr.v "html5rw-panel-header"
···
71
let highlighted_element t = t.highlighted
72
73
let clear_highlight t =
74
match t.highlighted with
75
| Some el ->
76
Htmlrw_js_annotate.unhighlight_element el;
77
-
t.highlighted <- None
78
-
| None -> ()
79
80
let navigate_to_element t bm =
81
clear_highlight t;
···
190
El.set_inline_style (Jstr.v "display") (Jstr.v "none") t.root
191
192
let destroy t =
193
El.remove t.root;
194
-
if !_current_panel = Some t then _current_panel := None
195
196
let hide_current () =
197
-
match !_current_panel with Some t -> destroy t | None -> ()
198
199
let create ~config result =
200
hide_current ();
201
202
let _doc = G.document in
203
204
let title = El.v (Jstr.v "span") [El.txt' "HTML5 Validation"] in
205
206
-
let collapse_btn = El.v (Jstr.v "button") ~at:[At.class' Css_class.collapse_btn] [
207
-
El.txt' "_"
208
-
] in
209
-
210
let close_btn = El.v (Jstr.v "button") ~at:[At.class' Css_class.close_btn] [
211
El.txt' "x"
212
] in
213
214
let header = El.v (Jstr.v "div") ~at:[At.class' Css_class.panel_header] [
215
-
title; collapse_btn; close_btn
216
] in
217
218
let error_count = List.length (List.filter (fun bm ->
···
268
269
update t result;
270
271
-
ignore (Ev.listen Ev.click (fun _ -> toggle_collapsed t) (El.as_target collapse_btn));
272
273
-
ignore (Ev.listen Ev.click (fun _ ->
274
destroy t;
275
-
match t.on_close with Some f -> f () | None -> ()
276
) (El.as_target close_btn));
277
278
if config.draggable then begin
···
307
if config.start_collapsed then
308
El.set_class Css_class.panel_collapsed true root;
309
310
El.append_children (Document.body G.document) [root];
311
312
_current_panel := Some t;
313
t
314
315
let on_warning_click t f = t.on_warning_click <- Some f
···
381
width: 24px; height: 24px; margin-left: 8px;
382
border: none; border-radius: 4px;
383
background: transparent; color: var(--html5rw-panel-text);
384
-
cursor: pointer; font-size: 14px; line-height: 1;
385
}
386
387
.html5rw-panel-header button:hover { background: rgba(0, 0, 0, 0.1); }
···
6
open Brr
7
open Htmlrw_js_types
8
9
+
let console_log msg =
10
+
ignore (Jv.call (Jv.get Jv.global "console") "log" [| Jv.of_string ("[html5rw-ui] " ^ msg) |])
11
+
12
module Css_class = struct
13
let panel = Jstr.v "html5rw-panel"
14
let panel_header = Jstr.v "html5rw-panel-header"
···
74
let highlighted_element t = t.highlighted
75
76
let clear_highlight t =
77
+
console_log (Printf.sprintf "clear_highlight: highlighted is %s"
78
+
(if t.highlighted = None then "None" else "Some"));
79
match t.highlighted with
80
| Some el ->
81
+
console_log "clear_highlight: unhighlighting element";
82
Htmlrw_js_annotate.unhighlight_element el;
83
+
t.highlighted <- None;
84
+
console_log "clear_highlight: done"
85
+
| None ->
86
+
console_log "clear_highlight: nothing to clear"
87
88
let navigate_to_element t bm =
89
clear_highlight t;
···
198
El.set_inline_style (Jstr.v "display") (Jstr.v "none") t.root
199
200
let destroy t =
201
+
console_log "destroy: starting";
202
+
clear_highlight t;
203
+
console_log "destroy: cleared highlight";
204
+
(* Clear _current_panel before removing element to avoid comparison issues *)
205
+
(match !_current_panel with
206
+
| Some p when p.root == t.root -> _current_panel := None
207
+
| _ -> ());
208
+
console_log "destroy: cleared current_panel ref";
209
El.remove t.root;
210
+
console_log "destroy: removed root element, done"
211
212
let hide_current () =
213
+
console_log (Printf.sprintf "hide_current: current_panel is %s"
214
+
(if !_current_panel = None then "None" else "Some"));
215
+
match !_current_panel with
216
+
| Some t ->
217
+
console_log "hide_current: destroying existing panel";
218
+
destroy t
219
+
| None ->
220
+
console_log "hide_current: no panel to destroy"
221
222
let create ~config result =
223
+
console_log (Printf.sprintf "create: starting with %d messages" (List.length result.messages));
224
hide_current ();
225
+
console_log "create: hide_current done";
226
227
let _doc = G.document in
228
229
let title = El.v (Jstr.v "span") [El.txt' "HTML5 Validation"] in
230
231
let close_btn = El.v (Jstr.v "button") ~at:[At.class' Css_class.close_btn] [
232
El.txt' "x"
233
] in
234
235
let header = El.v (Jstr.v "div") ~at:[At.class' Css_class.panel_header] [
236
+
title; close_btn
237
] in
238
239
let error_count = List.length (List.filter (fun bm ->
···
289
290
update t result;
291
292
+
(* Stop mousedown from bubbling to header (prevents drag interference) *)
293
+
ignore (Ev.listen Ev.mousedown (fun ev ->
294
+
console_log "close_btn: mousedown, stopping propagation";
295
+
Ev.stop_propagation ev
296
+
) (El.as_target close_btn));
297
298
+
ignore (Ev.listen Ev.click (fun ev ->
299
+
console_log "close_btn: click handler starting";
300
+
Ev.stop_propagation ev;
301
+
console_log "close_btn: stopped propagation, calling destroy";
302
destroy t;
303
+
console_log "close_btn: destroy done, checking on_close callback";
304
+
(match t.on_close with Some f -> f () | None -> ());
305
+
console_log "close_btn: click handler done"
306
) (El.as_target close_btn));
307
308
if config.draggable then begin
···
337
if config.start_collapsed then
338
El.set_class Css_class.panel_collapsed true root;
339
340
+
console_log "create: appending panel to document body";
341
El.append_children (Document.body G.document) [root];
342
343
_current_panel := Some t;
344
+
console_log "create: panel creation complete";
345
t
346
347
let on_warning_click t f = t.on_warning_click <- Some f
···
413
width: 24px; height: 24px; margin-left: 8px;
414
border: none; border-radius: 4px;
415
background: transparent; color: var(--html5rw-panel-text);
416
+
cursor: pointer; font-size: 14px;
417
+
display: flex; align-items: center; justify-content: center;
418
}
419
420
.html5rw-panel-header button:hover { background: rgba(0, 0, 0, 0.1); }