123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133(**************************************************************************)(* This file is part of the Codex semantics library. *)(* *)(* Copyright (C) 2013-2025 *)(* CEA (Commissariat à l'énergie atomique et aux énergies *)(* alternatives) *)(* *)(* you can redistribute it and/or modify it under the terms of the GNU *)(* Lesser General Public License as published by the Free Software *)(* Foundation, version 2.1. *)(* *)(* It is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)(* GNU Lesser General Public License for more details. *)(* *)(* See the GNU Lesser General Public License version 2.1 *)(* for more details (enclosed in the file LICENSE). *)(* *)(**************************************************************************)(* TODO: Bundle also depenendencies. *)(* A string with the binsec contents. *)letbinsec_webapp=Binsec_webapp_string.binsec_webapp_dot_bc_dot_jslettailwindcss=Tailwindcss_string.tailwind4_dot_1_dot_5_dot_cssletgraphvizjs=Graphviz_string.graphviz_dot_umd_dot_js(* let d3js = D3_string.d3_dot_v7_dot_min_dot_js *)(* let d3graphvizjs = D3_graphviz_string.d3_graphviz_dot_min_dot_js *)letbundlejs=Bundle_string.bundle_output_dot_jsletwith_generate_filesmarshalledf=letfilename,outc=Filename.open_temp_file~mode:[Open_binary]"dump""bin"inMarshal.to_channeloutcmarshalled[];close_outoutc;ffilename;Unix.unlinkfilename(* Inline dependencies, so that the file can be viewed without a network connection. *)letinline_deps=true;;(* If true and we inline the deps, we also include worker code. This
is faster but make the javascript a bit larger (as especially, we
already include this in the bundle). *)letincluded_inlined_worker=true;;letprint_html_webappoutc(marshalled:Interface.marshalled)=with_generate_filesmarshalled(funfilename->Printf.fprintfoutc{|
<!DOCTYPE html>
<html>
<head>
<style>
@keyframes mymount { from { transform: translateX(0) } to { transform: translateX(0) } }
.tree-controls {
display: flex;
flex-direction: column;
font-size: 0.8em;
}
</style>|};(* For some unknown reason, only d3.graphviz works when we inline
dependencies, and only d3.select().graphviz work when we don't.
So, we generate a d3_graphviz function to use instead of d3.graphviz. *)Printf.fprintfoutc{|
<script>function d3_graphviz(selector){ return %s; }</script>
|}(ifnotinline_depsthen"d3.select(selector).graphviz()"else"d3.graphviz(selector)");ifnotinline_depsthenPrintf.fprintfoutc{|
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.1.5"></script>
<script src="https://d3js.org/d3.v7.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/d3-graphviz@5.6.0/build/d3-graphviz.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@hpcc-js/wasm@2.22.4/dist/graphviz.umd.js"></script>
|}elsebeginPrintf.fprintfoutc"<script>%s</script>"tailwindcss;(* We pre-bundle everyting; directly loading the js does not work. *)Printf.fprintfoutc"<script>%s</script>"bundlejs;(* If we want to have a worker (i.e., having graphviz perform
computation on a separate thread), d3-graphviz requires
graphiz.umd.js to be loaded in a script with special type
"javascript/worker". This normally requires a URL; to circumvant
that, we use base64 as the URL. If this fails, d3-graphviz displays
this messages in the console:
No script tag of type "javascript/worker" was found and "useWorker"
is true. Not using web worker.
Otherwise, it succeeded. *)ifincluded_inlined_workerthenPrintf.fprintfoutc(* NB: The simple version seems to suffice. *)(iftruethen{|
<script type = "javascript/worker" src="data:application/javascript;base64,%s"></script> |}else{|
<script>
const base64Worker = '%s';
const dataUrl = `data:application/javascript;base64,${base64Worker}`;
const workerScript = document.createElement("script");
workerScript.type = "javascript/worker";
workerScript.src = dataUrl;
document.head.appendChild(workerScript);
</script>|})(Base64.encode_stringgraphvizjs)else();end;Printf.fprintfoutc"%s"File_to_html.preamble;File_to_html.file_to_htmloutc~filename~varid:"dataArray";Printf.fprintfoutc"<script>%s</script>"binsec_webapp;(* Better handling of errors thanks to source map when
debugging; also we need only to recompile the ocaml, not to
re-run the main program.. *)(* Printf.fprintf outc "<script src=\"/home/matthieu/git/codex-webapp/_build/default/utils/gui/js/binsec_webapp.bc.js\"></script>"; *)Printf.fprintfoutc{|
</head><body></body>
</html>
|});;(* SMall test to check dependencies: *)(* <!-- <body><div id="graph" style="width: 100%%; height: 500px;"></div> *)(* <script> *)(* window.onload = function() { *)(* console.log("ICI");d3.graphviz("#graph").renderDot('digraph {a -> b}');console.log("ICI2");}</script> *)(* </body>--> *)