mirror of
				https://github.com/ArthurSonzogni/FTXUI.git
				synced 2025-10-31 10:38:09 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			175 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			175 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!DOCTYPE html> <html lang="en">
 | |
|   <head>
 | |
|     <meta charset="utf-8">
 | |
|     <title>FTXUI examples WebAssembly</title>
 | |
|     <script src="https://cdn.jsdelivr.net/npm/xterm@4.18.0/lib/xterm.min.js"></script>
 | |
|     <script src="https://cdn.jsdelivr.net/npm/xterm-addon-webgl@0.11.4/lib/xterm-addon-webgl.min.js"></script>
 | |
|     <script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.5.0/lib/xterm-addon-fit.min.js"></script>
 | |
|     <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@4.11.0/css/xterm.css"></link>
 | |
|     <!--Add COOP/COEP via a ServiceWorker to use SharedArrayBuffer-->
 | |
|     <script>
 | |
|       if ("serviceWorker" in navigator && !window.crossOriginIsolated) {
 | |
|         navigator.serviceWorker.register(new URL("./sw.js", location.href)).then(
 | |
|           registration => {
 | |
|             if (registration.active && !navigator.serviceWorker.controller) {
 | |
|               window.location.reload();
 | |
|             }
 | |
|           },
 | |
|         );
 | |
|       } 
 | |
|     </script>
 | |
|   </head>
 | |
|   <body>
 | |
|     <script id="example_script"></script>
 | |
|     <div class="page">
 | |
|       <h1>FTXUI WebAssembly Example </h1>
 | |
|       <p>
 | |
|         <a href="https://github.com/ArthurSonzogni/FTXUI">FTXUI</a> is a simple
 | |
|         functional C++ library for terminal user interface. <br/>
 | |
|         This showcases the: <a href="https://github.com/ArthurSonzogni/FTXUI/tree/master/examples">./example/</a> folder. <br/>
 | |
|       </p>
 | |
|       <p>
 | |
|         On this page, you can try all the examples contained in: <a
 | |
|         href="https://github.com/ArthurSonzogni/FTXUI/tree/master/examples">./example/</a>
 | |
|         Those are compiled using WebAssembly.
 | |
|       </p>
 | |
|       <select id="selectExample"></select>
 | |
|       <div id="terminal"></div>
 | |
|     </div>
 | |
|   </body>
 | |
|   <script>
 | |
|     const example_list = "@EXAMPLES@".split(";");
 | |
| 
 | |
|     const url_search_params = new URLSearchParams(window.location.search);
 | |
|     const example = url_search_params.get("file") || "dom/color_gallery";
 | |
|     const select = document.getElementById("selectExample"); 
 | |
| 
 | |
|     for(var i = 0; i < example_list.length; i++) {
 | |
|         var opt = example_list[i];
 | |
|         var el = document.createElement("option");
 | |
|         el.textContent = opt;
 | |
|         el.value = opt;
 | |
|         select.appendChild(el);
 | |
|     }
 | |
|     select.selectedIndex = example_list.findIndex(path => path == example) || 0;
 | |
|     select.addEventListener("change", () => {
 | |
|       location.href = (location.href).split('?')[0] + "?file=" +
 | |
|             example_list[select.selectedIndex];
 | |
|     });
 | |
| 
 | |
|     let stdin_buffer = [];
 | |
|     const stdin = () => {
 | |
|       return stdin_buffer.shift() || 0;
 | |
|     }
 | |
| 
 | |
|     let stdout_buffer = [];
 | |
|     const stdout = code => {
 | |
|       if (code == 0) {
 | |
|         term.write(new Uint8Array(stdout_buffer));
 | |
|         stdout_buffer = [];
 | |
|       } else {
 | |
|         stdout_buffer.push(code)
 | |
|       }
 | |
|     }
 | |
|     let stderrbuffer = [];
 | |
|     const stderr = code => {
 | |
|       if (code == 0 || code == 10) {
 | |
|         console.error(String.fromCodePoint(...stderrbuffer));
 | |
|         stderrbuffer = [];
 | |
|       } else {
 | |
|         stderrbuffer.push(code)
 | |
|       }
 | |
|     }
 | |
|     const term = new Terminal();
 | |
|     const term_element = document.querySelector('#terminal');
 | |
|     term.open(term_element);
 | |
| 
 | |
|     const webgl_addon = new (WebglAddon.WebglAddon)();
 | |
|     term.loadAddon(webgl_addon);
 | |
| 
 | |
|     const onBinary = e => {
 | |
|       for(c of e)
 | |
|         stdin_buffer.push(c.charCodeAt(0));
 | |
|     }
 | |
|     term.onBinary(onBinary);
 | |
|     term.onData(onBinary)
 | |
|     term.resize(140,43);
 | |
|     window.Module = {
 | |
|       preRun: () => {
 | |
|         FS.init(stdin, stdout, stderr);
 | |
|       },
 | |
|       postRun: [],
 | |
|       onRuntimeInitialized: () => {
 | |
|         if (window.Module._ftxui_on_resize == undefined)
 | |
|           return;
 | |
| 
 | |
|         const fit_addon = new (FitAddon.FitAddon)();
 | |
|         term.loadAddon(fit_addon);
 | |
|         fit_addon.fit();
 | |
|         const resize_handler = () => {
 | |
|           const {cols, rows} = fit_addon.proposeDimensions();
 | |
|           term.resize(cols, rows);
 | |
|           window.Module._ftxui_on_resize(cols, rows);
 | |
|         };
 | |
|         const resize_observer = new ResizeObserver(resize_handler);
 | |
|         resize_observer.observe(term_element);
 | |
|         resize_handler();
 | |
| 
 | |
|         // Disable scrollbar
 | |
|         term.write('\x1b[?47h')
 | |
|       },
 | |
|     };
 | |
| 
 | |
|     const words = example.split('/')
 | |
|     words[1] = "ftxui_example_" + words[1] + ".js"
 | |
|     document.querySelector("#example_script").src = words.join('/');
 | |
|   </script>
 | |
| 
 | |
|   <style>
 | |
| 
 | |
|     body {
 | |
|       background-color:#EEE;
 | |
|       padding:20px;
 | |
|       font-family: Helvetica, sans-serif;
 | |
|       font-size: 130%;
 | |
|     }
 | |
| 
 | |
|     .page {
 | |
|       max-width:1300px;
 | |
|       margin: auto;
 | |
|     }
 | |
| 
 | |
|     h1 {
 | |
|       text-decoration: underline;
 | |
|     }
 | |
| 
 | |
|     select {
 | |
|       display:block;
 | |
|       padding: .6em 1.4em .5em .8em;
 | |
|       border-radius: 20px 20px 0px 0px;
 | |
|       font-size: 16px;
 | |
|       font-family: sans-serif;
 | |
|       font-weight: 700;
 | |
| 
 | |
|       color: #444;
 | |
|       line-height: 1.3;
 | |
|       background-color:black;
 | |
|       border:0px;
 | |
|       color:white;
 | |
|       transition: color 0.2s linear;
 | |
|       transition: background-color 0.2s linear;
 | |
|     }
 | |
| 
 | |
|     #terminal {
 | |
|       width:100%;
 | |
|       height: 500px;
 | |
|       height: calc(clamp(200px, 100vh - 300px, 900px));
 | |
|       overflow: hidden;
 | |
|       border:none;
 | |
|       padding:auto;
 | |
|     }
 | |
| 
 | |
|   </style>
 | |
| 
 | |
| </html>
 | 
