### Install Dependencies and Start Development Server Source: https://github.com/allotropia/zetajs/blob/main/examples/convertpdf/README.md Run these commands to install project dependencies and start the local development server. ```bash npm install npm start ``` -------------------------------- ### Install Dependencies and Build for Production Source: https://github.com/allotropia/zetajs/blob/main/examples/convertpdf/README.md Execute these commands to install dependencies and build the project for production deployment. ```bash npm install npm run dist ``` -------------------------------- ### Run ZetaJS Example with emrun Source: https://github.com/allotropia/zetajs/blob/main/examples/simple-examples/README.md Use the emrun command to run ZetaJS examples. Replace 'rainbow_writer.html' with the desired example. ```bash $ emrun rainbow_writer.html ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/allotropia/zetajs/blob/main/examples/letter-address-vuejs3/README.md Run this command to install all necessary project dependencies using npm. ```sh npm install ``` -------------------------------- ### Start Development Server Source: https://github.com/allotropia/zetajs/blob/main/examples/letter-address-vuejs3/README.md Use this command to compile and run the project with hot-reloading enabled for development. ```sh npm start ``` -------------------------------- ### Include ZetaJS and Example Scripts Source: https://github.com/allotropia/zetajs/blob/main/examples/simple-examples/README.md Configure include.js to load ZetaJS and example scripts when building LOWA with Emscripten. ```javascript Module.uno_scripts = [ 'zetajs/source/zeta.js', 'zetajs/examples/rainbow_writer.js']; ``` -------------------------------- ### Running the WebSocket to POSIX Proxy Source: https://github.com/allotropia/zetajs/blob/main/docs/network.md Start the compiled proxy executable to handle network requests from LOWA. ```bash $ websocket_to_posix_proxy 6932 ``` -------------------------------- ### Running Websockify Proxy Source: https://github.com/allotropia/zetajs/blob/main/docs/network.md Example command to run websockify as a proxy, forwarding local WebSocket connections to a remote HTTPS server. ```bash $ websockify 127.0.0.1:6932 freetestdata.com:443 ``` -------------------------------- ### Define ZetaJS Module Configuration Source: https://github.com/allotropia/zetajs/blob/main/examples/web-office/index.html Configures the ZetaJS module, specifying the canvas element, script paths, and file locating function. This setup is essential for initializing the web office application. ```javascript 'use strict'; // Set base URL to the soffice.* files. // Use an empty string if those files are in the same directory. let soffice_base_url = ''; const canvas = document.getElementById('qtcanvas'); const loadingInfo = document.getElementById('loadingInfo'); const btnUploadFile = document.getElementById('btnUploadFile'); const btnDownloadFile = document.getElementById('btnDownloadFile'); let filename; var Module = { canvas, uno_scripts: ['./assets/vendor/zetajs/zeta.js', './office_thread.js'], locateFile: function(path, prefix) { return (prefix || soffice_base_url) + path; }, }; if (soffice_base_url !== '') { // Must not be set when soffice.js is in the same directory. Module.mainScriptUrlOrBlob = new Blob([ "importScripts('" + soffice_base_url + "soffice.js');" ], {type: 'text/javascript'}); } ``` -------------------------------- ### Configure ZetaJS with Key Handler Source: https://github.com/allotropia/zetajs/blob/main/examples/simple-examples/simple_key_handler.html Sets up the ZetaJS environment by defining the base URL for soffice files, specifying Uno scripts, and configuring the locateFile function. This snippet is essential for initializing ZetaJS applications. ```javascript let soffice_base_url = 'https://cdn.zetaoffice.net/zetaoffice_latest/'; const canvas = document.getElementById('qtcanvas'); var Module = { canvas, uno_scripts: ['./zeta.js', './simple_key_handler.js'], locateFile: function(path, prefix) { return (prefix || soffice_base_url) + path; }, }; if (soffice_base_url !== '') { Module.mainScriptUrlOrBlob = new Blob([ "importScripts('" + soffice_base_url + "soffice.js');" ], { type: 'text/javascript' }); } ``` -------------------------------- ### Initialize ZetaJS with Find and Replace Source: https://github.com/allotropia/zetajs/blob/main/examples/simple-examples/find_and_replace.html Configures the ZetaJS module, specifies Uno scripts, and sets up the locateFile function to load WASM binaries. Use an empty string for soffice_base_url if soffice.js is in the same directory. ```javascript 'use strict'; let soffice_base_url = 'https://cdn.zetaoffice.net/zetaoffice_latest/'; const canvas = document.getElementById('qtcanvas'); var Module = { canvas, uno_scripts: ['./zeta.js', './find_and_replace.js'], locateFile: function(path, prefix) { return (prefix || soffice_base_url) + path; }, }; if (soffice_base_url !== '') { Module.mainScriptUrlOrBlob = new Blob([ "importScripts('" + soffice_base_url + "soffice.js');" ], { type: 'text/javascript' }); } ``` -------------------------------- ### Build for Production Source: https://github.com/allotropia/zetajs/blob/main/examples/letter-address-vuejs3/README.md Execute this command to compile and minify the project for production deployment. ```sh npm run build ``` -------------------------------- ### Initialize ZetaHelperMain and Handle File Conversion Source: https://github.com/allotropia/zetajs/blob/main/examples/convertpdf/index.html This snippet initializes ZetaHelperMain for PDF conversion. It sets up an event listener for file input, reads the file, writes it to the virtual file system, and posts a message to the worker thread to perform the conversion. It also handles the response, creating a Blob from the converted PDF, opening it in an iframe, and optionally triggering a download. ```javascript import { ZetaHelperMain } from './assets/vendor/zetajs/zetaHelper.js'; const canvas = document.getElementById('qtcanvas'); const input = document.getElementById('input'); let wasmPkg = ''; wasmPkg = wasmPkg !== null ? 'url:' + wasmPkg : null; const zHM = new ZetaHelperMain('office_thread.js', {threadJsType: 'module', wasmPkg}); input.onchange = () => { input.disabled = true; const file = input.files[0]; let name = file.name; let from = '/tmp/input'; const n = name.lastIndexOf('.'); if (n > 0) { from += name.substring(n); name = name.substring(0, n); } file.arrayBuffer().then(data => { FS.writeFile(from, new Uint8Array(data)); zHM.thrPort.postMessage({cmd: 'convert', name, from, to: '/tmp/output'}); }); }; zHM.start(() => { zHM.thrPort.onmessage = (e) => { switch (e.data.cmd) { case 'converted': try { FS.unlink(e.data.from); } catch {} const data = FS.readFile(e.data.to); const blob = new Blob([data], {type: 'application/pdf'}); const url = URL.createObjectURL(blob); document.getElementById('frame').contentWindow.open(url, '_self'); if (document.getElementById("download").checked) { window.open(url); } try { FS.unlink(e.data.to); } catch {} URL.revokeObjectURL(url); case 'start': input.disabled = false; break; default: throw Error('Unknown message command: ' + e.data.cmd); } }; }); ``` -------------------------------- ### Initialize ZetaHelperMain and Ping Source: https://github.com/allotropia/zetajs/blob/main/examples/ping-monitor/index.html Sets up the ZetaHelperMain instance for inter-thread communication and initializes the Ping object. It configures the helper with the thread script and options, and retrieves the initial ping target URL from the input field. ```javascript const canvas = document.getElementById('qtcanvas'); const pingTarget = document.getElementById('pingTarget'); const loadingInfo = document.getElementById('loadingInfo'); // Set base URL to the soffice.\* files. // Use an empty string if those files are in the same directory. let wasmPkg = ''; wasmPkg = wasmPkg !== null ? 'url:' + wasmPkg : null; const zHM = new ZetaHelperMain('office\_thread.js', { blockPageScroll: false, threadJsType: 'module', wasmPkg}); const pingInst = new Ping(); let url = pingTarget.value; let lastDevicePixelRatio = window.devicePixelRatio; ``` -------------------------------- ### Basic Network Argument Specification Source: https://github.com/allotropia/zetajs/blob/main/docs/network.md This demonstrates how to specify a network resource as an argument. Direct access will fail without further configuration. ```javascript Module.arguments = ['https://freetestdata.com/wp-content/uploads/2021/09/Free_Test_Data_100KB_ODT.odt']; ``` -------------------------------- ### Initialize ZetaHelperMain Source: https://github.com/allotropia/zetajs/blob/main/examples/letter-address-tool/index.html Initializes the ZetaHelperMain class with the path to the office thread script and Wasm package. The Wasm package path can be an empty string if the files are in the same directory. ```javascript import { ZetaHelperMain } from './assets/vendor/zetajs/zetaHelper.js'; const addrName = document.getElementById('addrName'); const loadingInfo = document.getElementById('loadingInfo'); const canvas = document.getElementById('qtcanvas'); const btnNamedAry = { Bold: document.getElementById('btnBold'), Italic: document.getElementById('btnItalic'), Underline: document.getElementById('btnUnderline'), Odt: document.getElementById('btnOdt'), Pdf: document.getElementById('btnPdf'), Insert: document.getElementById('btnInsert'), Reload: document.getElementById('btnReload'), }; // Set base URL to the soffice.* // Use an empty string if those files are in the same directory. let wasmPkg = ''; wasmPkg = wasmPkg !== null ? 'url:' + wasmPkg : null; const zHM = new ZetaHelperMain('office_thread.js', {wasmPkg}); ``` -------------------------------- ### Load and Initialize ZetaJS Module Source: https://github.com/allotropia/zetajs/blob/main/examples/web-office/index.html Dynamically loads the soffice.js script and configures the ZetaJS Module. It establishes communication with the office thread and handles initial UI states. ```javascript const soffice_js = document.createElement("script"); soffice_js.src = soffice_base_url + "soffice.js"; // "onload" runs after the loaded script has run. soffice_js.onload = function() { console.log('PLUS: Configuring Module'); Module.uno_main.then(function(pThrPort) { thrPort = pThrPort; thrPort.onmessage = function(e) { switch (e.data.cmd) { case 'thr_running': loadingInfo.style.display = 'none'; btnUploadFile.disabled = false; break; case 'ui_ready': // user uploaded a file // Trigger resize of the embedded window to match the canvas size. // May somewhen be obsoleted by: // https://gerrit.libreoffice.org/c/core/+/174040 window.dispatchEvent(new Eve ``` -------------------------------- ### Handle UI and Download Messages Source: https://github.com/allotropia/zetajs/blob/main/examples/letter-address-tool/index.html Sets up a message listener for the 'zHM' library to handle UI readiness, file downloads, and format changes. It triggers UI updates and initiates file downloads based on received commands. ```javascript zHM.start(function() { zHM.thrPort.onmessage = function(e) { switch (e.data.cmd) { case 'ui_ready': // Trigger resize of the embedded window to match the canvas size. // May somewhen be obsoleted by: // https://gerrit.libreoffice.org/c/core/+/174040 window.dispatchEvent(new Event('resize')); setTimeout(function() { // display Office UI properly loadingInfo.style.display = 'none'; canvas.style.visibility = null; for (const [_ , btn] of Object.entries(btnNamedAry)) btn.disabled = false; }, 1000); // milliseconds break; case 'download': const bytes = zHM.FS.readFile('/tmp/output'); const format = e.data.id === 'btnOdt' ? 'odt' : 'pdf'; const blob = new Blob([bytes], {type: 'application/' + format}); const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = 'letter.' + format; link.style = 'display:none'; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(link.href); break; case 'setFormat': btnNamedAry[e.data.id].style.borderStyle = e.data.state ? 'inset' : ''; break; default: throw Error('Unknown message command: ' + e.data.cmd); } }; load_business_letter_sans().then(function(aryBuf) { zHM.FS.writeFile('/tmp/Modern_business_letter_sans_serif.ott', new Uint8Array(aryBuf)); }); }); ``` -------------------------------- ### JavaScript for ZetaJS Initialization and Event Handling Source: https://github.com/allotropia/zetajs/blob/main/examples/standalone/index.html Initializes the ZetaJS Writer canvas, sets up the base URL for soffice.js, and configures event listeners for formatting buttons and window resizing. This script is crucial for loading and interacting with the office document. ```javascript 'use strict'; // Set base URL to the soffice.* files. // Use an empty string if those files are in the same directory. const soffice_base_url = ''; const canvasContainer = document.getElementById('qtcanvas'); const canvas = document.getElementById('qtcanvas'); const loadingInfo = document.getElementById('loadingInfo'); const fmtBtnsList = Object.fromEntries(Array.from(document.querySelectorAll('div[role="group"] input')).map(b=>[b.id,b])); // {Bold: , Italic: ...} var Module = { canvas, uno_scripts: ['./assets/vendor/zetajs/zeta.js', './office_thread.js'], locateFile: function(path, prefix) { return (prefix || soffice_base_url) + path; }, }; if (soffice_base_url !== '') { // Must not be set when soffice.js is in the same directory. Module.mainScriptUrlOrBlob = new Blob([ "importScripts('" + soffice_base_url + "soffice.js');" ], {type: 'text/javascript'}); } let lastDevicePixelRatio = window.devicePixelRatio; // Scroll only the canvas while the mouse cursor is above it. canvas.addEventListener('wheel', (event) => { event.preventDefault(); }, {passive: false}); window.onresize = function() { // Workaround to inform Qt5 about changed browser zoom. setTimeout(function() { if (lastDevicePixelRatio) { if (lastDevicePixelRatio != window.devicePixelRatio) { lastDevicePixelRatio = false; canvas.style.width = parseInt(canvas.style.width) + 1 + 'px'; window.dispatchEvent(new Event('resize')); } } else { lastDevicePixelRatio = window.devicePixelRatio canvas.style.width = parseInt(canvas.style.width) - 1 + 'px'; window.dispatchEvent(new Event('resize')); } }, 100); }; const soffice_js = document.createElement("script"); soffice_js.src = soffice_base_url + "soffice.js"; // "onload" runs after the loaded script has run. soffice_js.onload = function() { Module.uno_main.then(function(port) { for (const id of Object.keys(fmtBtnsList)) { const btn = document.getElementById(id); btn.onchange = function() { port.postMessage({cmd: 'toggleFormatting', id}); // Give focus to the LO canvas to avoid issues with // // "Setting Bold is // undone when clicking into non-empty document" // when the user would need to click // into the canvas to give back focus to it: canvas.focus(); } fmtBtnsList[id] = btn; } port.onmessage = function(e) { switch (e.data.cmd) { case 'ui_ready': // Trigger resize of the embedded window to match the canvas size. // May somewhen be obsoleted by: // https://gerrit.libreoffice.org/c/core/+/174040 window.dispatchEvent(new Event('resize')); setTimeout(function() { // display Office UI properly loadingInfo.style.display = 'none'; canvas.style.visibility = null; for (const btn of Object.values(fmtBtnsList)) btn.disabled = false; }, 1000); // milliseconds break; case 'setFormat': fmtBtnsList[e.data.id].checked = e.data.state; break; default: throw Error('Unknown message command: ' + e.data.cmd); } }; }); }; console.log('Loading WASM binaries for ZetaJS from: ' + soffice_base_url); // Hint: The global objects "canvas" and "Module" must exist before the next line. document.body.appendChild(soffice_js); ``` -------------------------------- ### Initiate File Download Source: https://github.com/allotropia/zetajs/blob/main/examples/web-office/index.html Triggers the file download process by sending a 'download' command to the office thread. This function prepares the application to receive file data for saving. ```javascript function btnDownloadFileFunc() { thrPort.postMessage({ cmd: 'download' }); } ``` -------------------------------- ### Building the WebSocket to POSIX Proxy Source: https://github.com/allotropia/zetajs/blob/main/docs/network.md Compile the Emscripten provided proxy executable for enabling network access through POSIX sockets. ```bash $ g++ ${EMSCRIPTEN-${EMSDK?}/upstream/emscripten}/tools/websocket_to_posix_proxy/src/*.{c,cpp} -o websocket_to_posix_proxy ``` -------------------------------- ### ZetaJS Initialization and WASM Loading Source: https://github.com/allotropia/zetajs/blob/main/examples/simple-examples/rainbow_writer.html Configures ZetaJS by setting the base URL for SOFFICE files, specifying Uno scripts, and defining how to locate WASM binaries. This script must be executed after the canvas element is available. ```javascript 'use strict'; // IMPORTANT: // Set base URL to the soffice.* files. // Use an empty string if those files are in the same directory. let soffice_base_url = 'https://cdn.zetaoffice.net/zetaoffice_latest/'; const canvas = document.getElementById('qtcanvas'); var Module = { canvas, uno_scripts: ['./zeta.js', './rainbow_writer.js'], locateFile: function(path, prefix) { return (prefix || soffice_base_url) + path; }, }; if (soffice_base_url !== '') { // Must not be set when soffice.js is in the same directory. Module.mainScriptUrlOrBlob = new Blob([ "importScripts('"+soffice_base_url+"soffice.js');" ], {type: 'text/javascript'}); } // adjust window size setInterval(function() { window.dispatchEvent(new Event('resize')); }, 1000); const soffice_js = document.createElement("script"); soffice_js.src = soffice_base_url + "soffice.js"; console.log('Loading WASM binaries for ZetaJS from: ' + soffice_base_url); // Hint: The global objects "canvas" and "Module" must exist before the next line. document.body.appendChild(soffice_js); ``` -------------------------------- ### ZetaJS Initialization and Script Loading Source: https://github.com/allotropia/zetajs/blob/main/examples/simple-examples/simple.html Configures ZetaJS by setting the base URL for WASM binaries, defining the canvas element, and dynamically loading the soffice.js script. The `locateFile` function is crucial for correctly resolving the paths to WASM modules. ```javascript 'use strict'; let soffice_base_url = 'https://cdn.zetaoffice.net/zetaoffice_latest/'; const canvas = document.getElementById('qtcanvas'); var Module = { canvas, uno_scripts: ['./zeta.js', './simple.js'], locateFile: function(path, prefix) { return (prefix || soffice_base_url) + path; }, }; if (soffice_base_url !== '') { Module.mainScriptUrlOrBlob = new Blob([ "importScripts('"+soffice_base_url+"soffice.js');" ], {type: 'text/javascript'}); } setInterval(function() { window.dispatchEvent(new Event('resize')); }, 1000); const soffice_js = document.createElement("script"); soffice_js.src = soffice_base_url + "soffice.js"; console.log('Loading WASM binaries for ZetaJS from: ' + soffice_base_url); document.body.appendChild(soffice_js); ``` -------------------------------- ### Lint Project Code Source: https://github.com/allotropia/zetajs/blob/main/examples/letter-address-vuejs3/README.md Run this command to lint the project code using ESLint. ```sh npm run lint ``` -------------------------------- ### Load ZetaJS WASM Binaries Source: https://github.com/allotropia/zetajs/blob/main/examples/simple-examples/find_and_replace.html Appends the soffice.js script to the document body to load ZetaJS WASM binaries. Ensure the global objects 'canvas' and 'Module' exist before this script is appended. ```javascript const soffice_js = document.createElement("script"); soffice_js.src = soffice_base_url + "soffice.js"; console.log('Loading WASM binaries for ZetaJS from: ' + soffice_base_url); document.body.appendChild(soffice_js); ``` -------------------------------- ### Packaging Certificate for HTTPS Support Source: https://github.com/allotropia/zetajs/blob/main/docs/network.md Use file_packager.py to embed a CA certificate bundle into LOWA's virtual file system, enabling HTTPS support. ```bash $ ${EMSCRIPTEN-${EMSDK?}/upstream/emscripten}/tools/file_packager.py include.data --js-output=cert.js --embed /etc/pki/tls/certs/ca-bundle.crt@/etc/pki/tls/certs/ca-bundle.crt ``` -------------------------------- ### Load a Writer Document with zetajs Source: https://github.com/allotropia/zetajs/blob/main/README.md Loads a Writer document using the zetajs library. If the current document is not a text document, it attempts to load 'example.odt' from the 'android/default-document' path. ```javascript const css = zetajs.uno.com.sun.star; const desktop = css.frame.Desktop.create(zetajs.getUnoComponentContext()); let xModel = desktop.getCurrentFrame().getController().getModel(); if (!xModel?.queryInterface(zetajs.type.interface(css.text.XTextDocument))) { xModel = desktop.loadComponentFromURL( 'file:///android/default-document/example.odt', '_default', 0, []); } ``` -------------------------------- ### Implement File Upload using File System Access API Source: https://github.com/allotropia/zetajs/blob/main/examples/web-office/index.html Handles file uploads using the modern File System Access API. It prompts the user to select a file, reads its content, and sends it to the office thread. Includes a fallback for browsers that do not support this API. ```javascript async function btnUploadFileFunc() { if (useFSAPI) { // File System Access API [fileHandle] = await window.showOpenFilePicker(); const fileData = await fileHandle.getFile(); filename = fileData.name; let arrayBuffer = await fileData.arrayBuffer(); try { FS.mkdir('/tmp/office/'); } catch {} await FS.writeFile('/tmp/office/' + filename, new Uint8Array(arrayBuffer)); await thrPort.postMessage({ cmd: 'upload', filename }); } else { // Fallback for unsupported browsers const fileInput = document.createElement("input"); fileInput.type = "file"; fileInput.onchange = async (event) => { const file = event.target.files[0]; filename = file.name; const arrayBuffer = await file.arrayBuffer(); try { FS.mkdir('/tmp/office/'); } catch {} await FS.writeFile('/tmp/office/' + filename, new Uint8Array(arrayBuffer)); await thrPort.postMessage({ cmd: 'upload', filename }); }; fileInput.click(); } loadingInfo.style.display = null; btnUploadFile.disabled = "disabled"; } ``` -------------------------------- ### HTML and CSS for ZetaJS Canvas Source: https://github.com/allotropia/zetajs/blob/main/examples/simple-examples/rainbow_writer.html Sets up the HTML body to cover the viewport and styles the canvas element for ZetaJS applications. Ensure the canvas element with id 'qtcanvas' exists in your HTML. ```html ZetaJS Rainbow Writer ``` -------------------------------- ### ZetaJS Main Thread Message Handling and UI Initialization Source: https://github.com/allotropia/zetajs/blob/main/examples/ping-monitor/index.html Handles messages from the worker thread, specifically the 'ui_ready' command to hide loading indicators and make the canvas visible. It also sets up a recurring call to `doPing` after an initial delay and a first ping attempt. ```javascript zHM.start(() => { zHM.thrPort.onmessage = (e) => { switch (e.data.cmd) { case 'ui_ready': // Trigger resize of the embedded window to match the canvas size. // May somewhen be obsoleted by: // https://gerrit.libreoffice.org/c/core/+/174040 window.dispatchEvent(new Event('resize')); setTimeout(function() { // display Office UI properly loadingInfo.style.display = 'none'; canvas.style.visibility = null; // Using Ping callback interface. // 'Cross-Origin-Embedder-Policy': Ping seems to work with 'require-corp' without // acutally having CORP on foreign origins. // Also 'credentialless' isn't supported by Safari-18 as of 2024-09. pingInst.ping(pingTarget, function() { // Continue after first ping, which is often exceptionally slow. setInterval(function() { doPing(); }, 1000); // milliseconds }); }, 1000); // milliseconds break; default: throw Error('Unknown message command: ' + e.data.cmd); } }; }); ``` -------------------------------- ### Handle URL Path for Web Server Compatibility Source: https://github.com/allotropia/zetajs/blob/main/examples/web-office/index.html Ensures correct URL routing by appending a trailing slash or .html extension if missing. This is useful for web servers that do not automatically handle directory requests. ```javascript if (!location.pathname.endsWith('/') && !location.pathname.endsWith('.html')) { location.replace(location.pathname + '/' + location.search + location.hash); } ``` -------------------------------- ### Handle Browser Resize and Zoom Events Source: https://github.com/allotropia/zetajs/blob/main/examples/web-office/index.html Responds to browser window resize events to inform the embedded Qt5 application about changes in the browser's zoom level. This is a workaround to ensure proper rendering and scaling. ```javascript window.onresize = function() { // Workaround to inform Qt5 about changed browser zoom. setTimeout(function() { if (lastDevicePixelRatio) { if (lastDevicePixelRatio != window.devicePixelRatio) { lastDevicePixelRatio = false; window.dispatchEvent(new Event('resize')); } } else { lastDevicePixelRatio = window.devicePixelRatio window.dispatchEvent(new Event('resize')); } }, 100); }; ``` -------------------------------- ### Include zetajs Scripts in Emscripten Build Source: https://github.com/allotropia/zetajs/blob/main/test/README.md Provide a JavaScript file to `EMSCRIPTEN_EXTRA_SOFFICE_PRE_JS` during the Emscripten build process. This file specifies which scripts to include, ensuring `zeta.js` is loaded before `smoketest.js`. ```javascript Module.uno_scripts = [ 'zetajs/source/zeta.js', 'zetajs/test/smoketest.js']; ``` -------------------------------- ### Fetch and Write Ping Monitor ODS Data Source: https://github.com/allotropia/zetajs/blob/main/examples/ping-monitor/index.html Asynchronously fetches the 'ping_monitor.ods' file as an ArrayBuffer and writes it to the '/tmp/ping_monitor.ods' path in the file system. This is likely used to load configuration or data for the monitor. ```javascript async function load_ping_monitor_ods() { const response = await fetch("./assets/ping_monitor.ods"); return response.arrayBuffer(); } let ping_monitor_ods; load_ping_monitor_ods().then(function(aryBuf) { ping_monitor_ods = aryBuf; FS.writeFile('/tmp/ping_monitor.ods', new Uint8Array(ping_monitor_ods)); }); ``` -------------------------------- ### CSS for W3 Theme Source: https://github.com/allotropia/zetajs/blob/main/examples/letter-address-tool/index.html Applies ZetaOffice brand colors to text and background for elements with the 'w3-theme' class. Uses !important to ensure styles are applied. ```css .w3-theme { color: #1F2937 !important; /* ZetaOffice brand color */ background-color: #059669 !important; /* ZetaOffice brand color */ } ``` -------------------------------- ### Handle Office UI Messages in JavaScript Source: https://github.com/allotropia/zetajs/blob/main/examples/web-office/index.html Processes incoming messages for office commands like 'resize' and 'download'. Ensures the UI is displayed correctly after loading and handles file saving logic. ```javascript nt('resize')); setTimeout(function() { // display Office UI properly loadingInfo.style.display = 'none'; canvas.style.visibility = null; btnDownloadFile.disabled = false; }, 1000); break; case 'download': const bytes = FS.readFile('/tmp/office/' + filename); const blob = new Blob([bytes], {}); if (useFSAPI) { saveFile(blob); } else { downloadFile(blob); } break; default: throw Error('Unknown message command: ' + e.data.cmd); } }; }); }; console.log('Loading WASM binaries for ZetaJS from: ' + soffice_base_url); // Hint: The global objects "canvas" and "Module" must exist before the next line. document.body.appendChild(soffice_js); ``` -------------------------------- ### WebSocket Emulation for Network Access Source: https://github.com/allotropia/zetajs/blob/main/docs/network.md Configure Emscripten to emulate HTTP/HTTPS over WebSockets. This requires a WebSocket server or proxy like websockify. ```javascript Module.websocket = {url: 'ws://127.0.0.1:6932', subprotocol: 'binary'}; Module.arguments = ['https://freetestdata.com/wp-content/uploads/2021/09/Free_Test_Data_100KB_ODT.odt']; ``` -------------------------------- ### Download File using Blob URL (Fallback) Source: https://github.com/allotropia/zetajs/blob/main/examples/web-office/index.html Provides a fallback mechanism for downloading files in browsers that do not support the File System Access API. It creates a temporary URL for the blob data and initiates a download. ```javascript function downloadFile(blob) { // Fallback for unsupported browsers const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = filename; link.style = 'display:none'; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(link.href); } ``` -------------------------------- ### Load Business Letter Template Source: https://github.com/allotropia/zetajs/blob/main/examples/letter-address-tool/index.html Fetches the 'Modern_business_letter_sans_serif.ott' template as an ArrayBuffer. This is used to load the document template. ```javascript async function load_business_letter_sans() { const response = await fetch("./assets/Modern_business_letter_sans_serif.ott"); return response.arrayBuffer(); } ``` -------------------------------- ### Download Button Functionality Source: https://github.com/allotropia/zetajs/blob/main/examples/letter-address-tool/index.html Handles the download of documents in ODT or PDF format. This function is triggered when the ODT or PDF download buttons are clicked. ```javascript function btnDownloadFunc(btnObj) { zHM.thrPort.postMessage({cmd: 'download', id: btnObj.id}); } btnOdt.onclick = function(){ btnDownloadFunc(btnOdt) }; btnPdf.onclick = function(){ btnDownloadFunc(btnPdf) }; ``` -------------------------------- ### Adjust Window Size for ZetaJS Source: https://github.com/allotropia/zetajs/blob/main/examples/simple-examples/simple_key_handler.html Periodically dispatches a resize event to adjust the window size for ZetaJS. This is useful for ensuring the application correctly handles viewport changes. ```javascript setInterval(function() { window.dispatchEvent(new Event('resize')); }, 1000); ``` -------------------------------- ### Required HTTP Headers for Web Server Source: https://github.com/allotropia/zetajs/blob/main/examples/convertpdf/README.md These HTTP headers must be configured in your web server to ensure proper functionality, especially for cross-origin resource handling. ```http Cross-Origin-Opener-Policy "same-origin" Cross-Origin-Embedder-Policy "require-corp" ``` -------------------------------- ### Adjust Window Size for ZetaJS Source: https://github.com/allotropia/zetajs/blob/main/examples/simple-examples/find_and_replace.html Periodically dispatches a resize event to adjust the window size for ZetaJS. This is useful for ensuring the canvas covers the entire viewport. ```javascript setInterval(function() { window.dispatchEvent(new Event('resize')); }, 1000); ``` -------------------------------- ### Handle Ping Target Input and Trigger Ping Source: https://github.com/allotropia/zetajs/blob/main/examples/ping-monitor/index.html Provides functions to update the target URL and listen for 'Enter' key presses on the input field to trigger a ping. These functions are typically accessed from a Vue.js context. ```javascript // Functions stored below window.* are usually accessed from vue.js. window.btnPing = () => { url = pingTarget.value; } window.pingTarget.addEventListener ('keyup', (evt) => { if(evt.key === 'Enter') btnPing(); }); ``` -------------------------------- ### CSS for ZetaJS Viewport Source: https://github.com/allotropia/zetajs/blob/main/examples/simple-examples/simple_key_handler.html Styles the HTML body to cover the entire visual viewport without scroll bars, setting padding, margin, and overflow properties. This ensures the ZetaJS application occupies the full screen. ```css html, body { padding: 0; margin: 0; overflow: hidden; height: 100vh } ``` -------------------------------- ### Proxy POSIX Sockets for Network Access Source: https://github.com/allotropia/zetajs/blob/main/docs/network.md Configure LOWA to use a proxy executable for low-level network access via POSIX sockets. This requires a specific Emscripten build configuration. ```javascript Module.uno_websocket_to_posix_socket_url = 'ws://127.0.0.1:6932'; Module.arguments = ['https://freetestdata.com/wp-content/uploads/2021/09/Free_Test_Data_100KB_ODT.odt']; ``` -------------------------------- ### CSS for Spinner Animation Source: https://github.com/allotropia/zetajs/blob/main/examples/standalone/index.html Defines styles for a loading spinner, including its appearance and a keyframe animation for rotation. Used to indicate that the application is loading. ```css .spinner { border: 16px solid #1F2937; /* ZetaOffice brand color */ border-top: 16px solid #059669; /* ZetaOffice brand color */ border-radius: 50%; width: 120px; height: 120px; position: relative; left: 120px; /* adjust to center */ animation: spin 2s linear 30; /* 60 seconds */ } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } ``` -------------------------------- ### HTML and Body Styling Source: https://github.com/allotropia/zetajs/blob/main/examples/simple-examples/simple.html Ensures the HTML body covers the entire viewport without scrollbars. This is essential for applications that need to occupy the full screen. ```css html, body { padding: 0; margin: 0; overflow:hidden; height: 100vh } ``` -------------------------------- ### CSS for Spinner Animation Source: https://github.com/allotropia/zetajs/blob/main/examples/letter-address-tool/index.html Defines the styles for a loading spinner, including its size, border, and animation. The animation spins the element for 60 seconds. ```css .spinner { border: 16px solid #1F2937; /* ZetaOffice brand color */ border-top: 16px solid #059669; /* ZetaOffice brand color */ border-radius: 50%; width: 120px; height: 120px; position: relative; left: 100px; /* adjust to center */ animation: spin 2s linear 30; /* 60 seconds */ } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } ``` -------------------------------- ### Developer Certificate of Origin Sign-off Source: https://github.com/allotropia/zetajs/blob/main/README.md When submitting a pull request, include this sign-off line in your commits to certify your contribution under the MIT license. Use your real name. ```text Signed-off-by: Random J Developer ``` -------------------------------- ### Perform Ping Operation and Post Result Source: https://github.com/allotropia/zetajs/blob/main/examples/ping-monitor/index.html Executes the ping operation to a given URL. If an error occurs, it logs the URL and ping value, and posts the result back to the main thread via `zHM.thrPort.postMessage`. This function is called periodically. ```javascript async function doPing() { if (url != '') { pingInst.ping(url, function(err, ping_value) { // err: In /favicon.ico can't be loaded the result still represents the response time. console.log({url, ping_value}); zHM.thrPort.postMessage({cmd: 'ping_result', url, ping_value}); }); } } ``` -------------------------------- ### JavaScript for URL Path Normalization Source: https://github.com/allotropia/zetajs/blob/main/examples/standalone/index.html Ensures that relative URLs function correctly by appending a trailing slash to the current path if it doesn't end with a slash or '.html'. This is important for web servers that might not automatically handle directory URLs. ```javascript // Relative URLs break if the main URL's last directory has no slash. // Some web servers don't add that / as "Apache DirectorySlash" does. if (!location.pathname.endsWith('/') && !location.pathname.endsWith('.html')) { location.replace(location.pathname + '/' + location.search + location.hash); } ``` -------------------------------- ### Populate Recipient Dropdown Source: https://github.com/allotropia/zetajs/blob/main/examples/letter-address-tool/index.html Populates a dropdown menu with recipient names from a data array. Each recipient's name is added as an option to the 'addrName' element. ```javascript const data = [ { title: "", name: "Odo, Mr.", street: "Level 42", postal_code: "DS9", city: "Deep Space 9", state: "Bajoran Republic", }, { title: "Mrs.", name: "Rand, Janice", street: "Deck 42", postal_code: "NCC-1701", city: "USS Enterprise", state: "United Federation of Planets", }, { title: "Mr.", name: "Scott, Montgomery", street: "Deck 42", postal_code: "NCC-1701", city: "USS Enterprise", state: "United Federation of Planets", }, { title: "Mr.", name: "Sisko, Benjamin Lafayette", street: "Level 42", postal_code: "DS9", city: "Deep Space 9", state: "Bajoran Republic", }, { title: "Mr.", name: "Sulu, Hikaru", street: "Deck 42", postal_code: "NCC-1701", city: "USS Enterprise", state: "United Federation of Planets", }, { title: "Mrs.", name: "Uhura, Nyota", street: "Deck 42", postal_code: "NCC-1701", city: "USS Enterprise", state: "United Federation of Planets", }, { title: "", name: "Worf, Mr.", street: "Level 3, Section 27, Room 9", postal_code: "DS9", city: "Deep Space 9", state: "Bajoran Republic", }, { title: "Mrs.", name: "Yates-Sisko, Kasidy Danielle", street: "Deck B", postal_code: "ECV-197", city: "The Orville", state: "Planetary Union", }, ]; for (const recipient of data) { const option = document.createElement('option'); option.innerHTML = recipient.name; addrName.appendChild(option); } ``` -------------------------------- ### Save File using File System Access API Source: https://github.com/allotropia/zetajs/blob/main/examples/web-office/index.html Saves a blob of data to a file using the File System Access API. This function is called when the office application is ready to save the current document. ```javascript async function saveFile(blob) { const writable = await fileHandle.createWritable(); await writable.write(blob); await writable.close(); } ``` -------------------------------- ### Insert Address Functionality Source: https://github.com/allotropia/zetajs/blob/main/examples/letter-address-tool/index.html Inserts the selected address into the document. It checks if an address is selected before sending the recipient data to the ZetaHelperMain. ```javascript btnInsert.onclick = function() { if (addrName.selectedIndex != -1) { const recipient = data[addrName.selectedIndex]; zHM.thrPort.postMessage({cmd: 'insert_address', recipient}); } }; ``` -------------------------------- ### CSS for Select Option Spacing Source: https://github.com/allotropia/zetajs/blob/main/examples/letter-address-tool/index.html Ensures consistent spacing for options within select lists across different browser versions. This is particularly useful for Firefox and Chromium. ```css select option { /* Same spacing in select lists for Firefox-128 as for Chromium-130. */ padding: 0; height: 18px; } ``` -------------------------------- ### Change Paragraph Colors in Writer Document Source: https://github.com/allotropia/zetajs/blob/main/README.md Iterates through all paragraphs of a Writer document and sets each to a random color using zetajs. Requires a loaded text document model. ```javascript const xText = xModel.getText(); const xParaEnumeration = xText.createEnumeration(); for (const xParagraph of xParaEnumeration) { const color = Math.floor(Math.random() * 0xFFFFFF); xParagraph.setPropertyValue("CharColor", color); } ``` -------------------------------- ### Address Data Source: https://github.com/allotropia/zetajs/blob/main/examples/letter-address-tool/index.html An array of address objects, each containing details like title, name, street, postal code, city, and state. This data is used for populating the address selection list. ```javascript const data = [ { title: "Dr.", name: "Bashir, Julian Subatoi", street: "Level 42", postal_code: "DS9", city: "Deep Space 9", state: "Bajoran Republic", }, { title: "Dr.", name: "Chapel, Christine", street: "Deck 42", postal_code: "NCC-1701", city: "USS Enterprise", state: "United Federation of Planets", }, { title: "Mr.", name: "Chekov, Pavel", street: "Deck 42", postal_code: "NCC-1701", city: "USS Enterprise", state: "United Federation of Planets", }, { title: "Mrs.", name: "Dax, Jadzia", street: "Section 25 Alpha", postal_code: "DS9", city: "Deep Space 9", state: "Bajoran Republic", }, { title: "Mr.", name: "de Monti, Mario", street: "Mariosstreet", postal_code: "1B 1B1B", city: "Deepseabase 104", state: "Earth", }, { title: "Mr.", name: "Sigbjörnson, Hasso", street: "Hassosstreet", postal_code: "1B 1B1B", city: "Deepseabase 104", state: "Earth", }, { title: "Mrs.", name: "Jagellovsk, Tamara", street: "Tamarasstreet", postal_code: "1B 1B1B", city: "Deepseabase 104", state: "Earth", }, { title: "Mr.", name: "Kirk, James T.", street: "Deck 5", postal_code: "NCC-1701", city: "USS Enterprise", state: "United Federation of Planets", }, { title: "Mrs.", name: "Legrelle, Helga", street: "Helgasstreet", postal_code: "1B 1B1B", city: "Deepseabase 104", state: "Earth", }, { title: "Dr.", name: "McCoy, Leonard", street: "Deck 9, Section 2, 3F 127", postal_code: "NCC-1701", city: "USS Enterprise", state: "United Federation of Planets", }, { title: "Mr.", name: "McLane, Cliff Allister", street: "Cliffsstreet", postal_code: "1B 1B1B", city: "Deepseabase 104", state: "Earth", }, { title: "Mrs.", name: "Nerys, Kira", street: "Level 42", postal_code: "DS9", city: "Deep Space 9", state: "Bajoran Republic", }, { title: "Mr.", name: "O'Brien, Miles Edward", street: "Level 5", postal_code: "DS9", city: "Deep Space 9", state: "Bajoran Republic", }, { title: "Mrs.", name: "O'Brien, Keiko", st ``` -------------------------------- ### URL Path Normalization Source: https://github.com/allotropia/zetajs/blob/main/examples/simple-examples/simple.html Adjusts the browser's URL to ensure a trailing slash if the current path does not end with a slash or '.html'. This prevents issues with relative URL resolution on certain web servers. ```javascript if (!location.pathname.endsWith('/') && !location.pathname.endsWith('.html')) { location.replace(location.pathname + '/' + location.search + location.hash); } ``` -------------------------------- ### Format Button Functionality Source: https://github.com/allotropia/zetajs/blob/main/examples/letter-address-tool/index.html Toggles text formatting (bold, italic, underline) and updates the button's border style. This function is called when a formatting button is clicked. ```javascript function formatBtnFunc(btnObj) { zHM.thrPort.postMessage({ cmd: 'toggleFormat', id: btnObj.id.substring(3), }); btnObj.style.borderStyle = btnObj.style.borderStyle === 'inset' ? '' : 'inset'; } btnBold.onclick = function(){ formatBtnFunc(btnBold) }; btnItalic.onclick = function(){ formatBtnFunc(btnItalic) }; btnUnderline.onclick = function(){ formatBtnFunc(btnUnderline) }; ``` -------------------------------- ### Reload Data Functionality Source: https://github.com/allotropia/zetajs/blob/main/examples/letter-address-tool/index.html Disables all buttons and reloads the data. This is typically used to refresh the address list or document content. ```javascript btnReload.onclick = function() { for (const [_, btn] of Object.entries(btnNamedAry)) btn.disabled = true; zHM.thrPort.postMessage({cmd: 'reload'}); } ``` -------------------------------- ### URL Path Correction Logic Source: https://github.com/allotropia/zetajs/blob/main/examples/letter-address-tool/index.html Corrects relative URLs by ensuring the pathname ends with a slash if it doesn't already end with a slash or '.html'. This prevents issues with web servers that don't automatically append the trailing slash. ```javascript // Relative URLs break if the main URL's last directory has no slash. // Some web servers don't add that / as "Apache DirectorySlash" does. if (!location.pathname.endsWith('/') && !location.pathname.endsWith('.html')) { location.replace(location.pathname + '/' + location.search + location.hash); } ``` -------------------------------- ### Prevent Canvas Scrolling with Wheel Event Source: https://github.com/allotropia/zetajs/blob/main/examples/web-office/index.html Attaches a wheel event listener to the canvas to prevent default scrolling behavior. This ensures that mouse wheel events are handled specifically by the application, not the browser's default scroll. ```javascript canvas.addEventListener('wheel', (event) => { event.preventDefault(); }, {passive: false}); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.