/* Crafter.CppDOM Copyright (C) 2025 Catcrafts Catcrafts.net This library is free software; 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; either version 3.0 of the License, or (at your option) any later version. This library 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. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ const decoder = new TextDecoder(); const encoder = new TextEncoder(); let memorycounter = -1; const jsmemory = new Map(); const eventHandlers = new Map(); function freeJs(ptr) { jsmemory.delete(ptr); } function getElementById(id, idLenght) { const obj = document.getElementById(decoder.decode(new Int8Array(window.crafter_webbuild_wasi.instance.exports.memory.buffer, id, idLenght))); jsmemory.set(++memorycounter, obj); return memorycounter; } function setInnerHTML(ptr, html, htmlLenght) { jsmemory.get(ptr).innerHTML = decoder.decode(new Int8Array(window.crafter_webbuild_wasi.instance.exports.memory.buffer, html, htmlLenght)); } // Event handler registration functions function addClickListener(ptr, handlerID) { const element = jsmemory.get(ptr); // Create a handler that will trigger a notification to C++ const handler = function(event) { const { ExecuteClickHandler } = window.crafter_webbuild_wasi.instance.exports; ExecuteClickHandler(handlerID); }; eventHandlers.set(`${ptr}-${handlerID}`, handler); element.addEventListener("click", handler); } function removeClickListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = eventHandlers.get(`${ptr}-${handlerID}`); element.removeEventListener("click", handler); eventHandlers.delete(`${ptr}-${handlerID}`); } // Add more event handlers for modern websites function addMouseOverListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = function(event) { const { ExecuteMouseOverHandler } = window.crafter_webbuild_wasi.instance.exports; ExecuteMouseOverHandler(handlerID); }; eventHandlers.set(`${ptr}-${handlerID}-mouseover`, handler); element.addEventListener("mouseover", handler); } function removeMouseOverListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = eventHandlers.get(`${ptr}-${handlerID}-mouseover`); element.removeEventListener("mouseover", handler); eventHandlers.delete(`${ptr}-${handlerID}-mouseover`); } function addMouseOutListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = function(event) { const { ExecuteMouseOutHandler } = window.crafter_webbuild_wasi.instance.exports; ExecuteMouseOutHandler(handlerID); }; eventHandlers.set(`${ptr}-${handlerID}-mouseout`, handler); element.addEventListener("mouseout", handler); } function removeMouseOutListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = eventHandlers.get(`${ptr}-${handlerID}-mouseout`); element.removeEventListener("mouseout", handler); eventHandlers.delete(`${ptr}-${handlerID}-mouseout`); } function addMouseMoveListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = function(event) { const { ExecuteMouseMoveHandler } = window.crafter_webbuild_wasi.instance.exports; ExecuteMouseMoveHandler(handlerID); }; eventHandlers.set(`${ptr}-${handlerID}-mousemove`, handler); element.addEventListener("mousemove", handler); } function removeMouseMoveListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = eventHandlers.get(`${ptr}-${handlerID}-mousemove`); element.removeEventListener("mousemove", handler); eventHandlers.delete(`${ptr}-${handlerID}-mousemove`); } function addFocusListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = function(event) { const { ExecuteFocusHandler } = window.crafter_webbuild_wasi.instance.exports; ExecuteFocusHandler(handlerID); }; eventHandlers.set(`${ptr}-${handlerID}-focus`, handler); element.addEventListener("focus", handler); } function removeFocusListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = eventHandlers.get(`${ptr}-${handlerID}-focus`); element.removeEventListener("focus", handler); eventHandlers.delete(`${ptr}-${handlerID}-focus`); } function addBlurListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = function(event) { const { ExecuteBlurHandler } = window.crafter_webbuild_wasi.instance.exports; ExecuteBlurHandler(handlerID); }; eventHandlers.set(`${ptr}-${handlerID}-blur`, handler); element.addEventListener("blur", handler); } function removeBlurListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = eventHandlers.get(`${ptr}-${handlerID}-blur`); element.removeEventListener("blur", handler); eventHandlers.delete(`${ptr}-${handlerID}-blur`); } function addKeyDownListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = function(event) { const { ExecuteKeyDownHandler } = window.crafter_webbuild_wasi.instance.exports; ExecuteKeyDownHandler(handlerID, event.key, event.code, event.keyCode); }; eventHandlers.set(`${ptr}-${handlerID}-keydown`, handler); element.addEventListener("keydown", handler); } function removeKeyDownListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = eventHandlers.get(`${ptr}-${handlerID}-keydown`); element.removeEventListener("keydown", handler); eventHandlers.delete(`${ptr}-${handlerID}-keydown`); } function addKeyUpListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = function(event) { const { ExecuteKeyUpHandler } = window.crafter_webbuild_wasi.instance.exports; ExecuteKeyUpHandler(handlerID, event.key, event.code, event.keyCode); }; eventHandlers.set(`${ptr}-${handlerID}-keyup`, handler); element.addEventListener("keyup", handler); } function removeKeyUpListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = eventHandlers.get(`${ptr}-${handlerID}-keyup`); element.removeEventListener("keyup", handler); eventHandlers.delete(`${ptr}-${handlerID}-keyup`); } function addKeyPressListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = function(event) { const { ExecuteKeyPressHandler } = window.crafter_webbuild_wasi.instance.exports; ExecuteKeyPressHandler(handlerID, event.key, event.code, event.keyCode); }; eventHandlers.set(`${ptr}-${handlerID}-keypress`, handler); element.addEventListener("keypress", handler); } function removeKeyPressListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = eventHandlers.get(`${ptr}-${handlerID}-keypress`); element.removeEventListener("keypress", handler); eventHandlers.delete(`${ptr}-${handlerID}-keypress`); } function addChangeListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = function(event) { const { ExecuteChangeHandler } = window.crafter_webbuild_wasi.instance.exports; ExecuteChangeHandler(handlerID); }; eventHandlers.set(`${ptr}-${handlerID}-change`, handler); element.addEventListener("change", handler); } function removeChangeListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = eventHandlers.get(`${ptr}-${handlerID}-change`); element.removeEventListener("change", handler); eventHandlers.delete(`${ptr}-${handlerID}-change`); } function addSubmitListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = function(event) { const { ExecuteSubmitHandler } = window.crafter_webbuild_wasi.instance.exports; ExecuteSubmitHandler(handlerID); }; eventHandlers.set(`${ptr}-${handlerID}-submit`, handler); element.addEventListener("submit", handler); } function removeSubmitListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = eventHandlers.get(`${ptr}-${handlerID}-submit`); element.removeEventListener("submit", handler); eventHandlers.delete(`${ptr}-${handlerID}-submit`); } function addInputListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = function(event) { const { ExecuteInputHandler } = window.crafter_webbuild_wasi.instance.exports; ExecuteInputHandler(handlerID); }; eventHandlers.set(`${ptr}-${handlerID}-input`, handler); element.addEventListener("input", handler); } function removeInputListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = eventHandlers.get(`${ptr}-${handlerID}-input`); element.removeEventListener("input", handler); eventHandlers.delete(`${ptr}-${handlerID}-input`); } function addLoadListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = function(event) { const { ExecuteLoadHandler } = window.crafter_webbuild_wasi.instance.exports; ExecuteLoadHandler(handlerID); }; eventHandlers.set(`${ptr}-${handlerID}-load`, handler); element.addEventListener("load", handler); } function removeLoadListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = eventHandlers.get(`${ptr}-${handlerID}-load`); element.removeEventListener("load", handler); eventHandlers.delete(`${ptr}-${handlerID}-load`); } function addErrorListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = function(event) { const { ExecuteErrorHandler } = window.crafter_webbuild_wasi.instance.exports; ExecuteErrorHandler(handlerID); }; eventHandlers.set(`${ptr}-${handlerID}-error`, handler); element.addEventListener("error", handler); } function removeErrorListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = eventHandlers.get(`${ptr}-${handlerID}-error`); element.removeEventListener("error", handler); eventHandlers.delete(`${ptr}-${handlerID}-error`); } function addResizeListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = function(event) { const { ExecuteResizeHandler } = window.crafter_webbuild_wasi.instance.exports; ExecuteResizeHandler(handlerID); }; eventHandlers.set(`${ptr}-${handlerID}-resize`, handler); element.addEventListener("resize", handler); } function removeResizeListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = eventHandlers.get(`${ptr}-${handlerID}-resize`); element.removeEventListener("resize", handler); eventHandlers.delete(`${ptr}-${handlerID}-resize`); } function addScrollListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = function(event) { const { ExecuteScrollHandler } = window.crafter_webbuild_wasi.instance.exports; ExecuteScrollHandler(handlerID); }; eventHandlers.set(`${ptr}-${handlerID}-scroll`, handler); element.addEventListener("scroll", handler); } function removeScrollListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = eventHandlers.get(`${ptr}-${handlerID}-scroll`); element.removeEventListener("scroll", handler); eventHandlers.delete(`${ptr}-${handlerID}-scroll`); } function addContextMenuListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = function(event) { const { ExecuteContextMenuHandler } = window.crafter_webbuild_wasi.instance.exports; ExecuteContextMenuHandler(handlerID); }; eventHandlers.set(`${ptr}-${handlerID}-contextmenu`, handler); element.addEventListener("contextmenu", handler); } function removeContextMenuListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = eventHandlers.get(`${ptr}-${handlerID}-contextmenu`); element.removeEventListener("contextmenu", handler); eventHandlers.delete(`${ptr}-${handlerID}-contextmenu`); } function addDragStartListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = function(event) { const { ExecuteDragStartHandler } = window.crafter_webbuild_wasi.instance.exports; ExecuteDragStartHandler(handlerID); }; eventHandlers.set(`${ptr}-${handlerID}-dragstart`, handler); element.addEventListener("dragstart", handler); } function removeDragStartListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = eventHandlers.get(`${ptr}-${handlerID}-dragstart`); element.removeEventListener("dragstart", handler); eventHandlers.delete(`${ptr}-${handlerID}-dragstart`); } function addDragEndListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = function(event) { const { ExecuteDragEndHandler } = window.crafter_webbuild_wasi.instance.exports; ExecuteDragEndHandler(handlerID); }; eventHandlers.set(`${ptr}-${handlerID}-dragend`, handler); element.addEventListener("dragend", handler); } function removeDragEndListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = eventHandlers.get(`${ptr}-${handlerID}-dragend`); element.removeEventListener("dragend", handler); eventHandlers.delete(`${ptr}-${handlerID}-dragend`); } function addDropListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = function(event) { const { ExecuteDropHandler } = window.crafter_webbuild_wasi.instance.exports; ExecuteDropHandler(handlerID); }; eventHandlers.set(`${ptr}-${handlerID}-drop`, handler); element.addEventListener("drop", handler); } function removeDropListener(ptr, handlerID) { const element = jsmemory.get(ptr); const handler = eventHandlers.get(`${ptr}-${handlerID}-drop`); element.removeEventListener("drop", handler); eventHandlers.delete(`${ptr}-${handlerID}-drop`); } let env = { freeJs: freeJs, getElementById: getElementById, setInnerHTML: setInnerHTML, addClickListener: addClickListener, removeClickListener: removeClickListener, addMouseOverListener: addMouseOverListener, removeMouseOverListener: removeMouseOverListener, addMouseOutListener: addMouseOutListener, removeMouseOutListener: removeMouseOutListener, addMouseMoveListener: addMouseMoveListener, removeMouseMoveListener: removeMouseMoveListener, addFocusListener: addFocusListener, removeFocusListener: removeFocusListener, addBlurListener: addBlurListener, removeBlurListener: removeBlurListener, addKeyDownListener: addKeyDownListener, removeKeyDownListener: removeKeyDownListener, addKeyUpListener: addKeyUpListener, removeKeyUpListener: removeKeyUpListener, addKeyPressListener: addKeyPressListener, removeKeyPressListener: removeKeyPressListener, addChangeListener: addChangeListener, removeChangeListener: removeChangeListener, addSubmitListener: addSubmitListener, removeSubmitListener: removeSubmitListener, addInputListener: addInputListener, removeInputListener: removeInputListener, addLoadListener: addLoadListener, removeLoadListener: removeLoadListener, addErrorListener: addErrorListener, removeErrorListener: removeErrorListener, addResizeListener: addResizeListener, removeResizeListener: removeResizeListener, addScrollListener: addScrollListener, removeScrollListener: removeScrollListener, addContextMenuListener: addContextMenuListener, removeContextMenuListener: removeContextMenuListener, addDragStartListener: addDragStartListener, removeDragStartListener: removeDragStartListener, addDragEndListener: addDragEndListener, removeDragEndListener: removeDragEndListener, addDropListener: addDropListener, removeDropListener: removeDropListener, } window.crafter_webbuild_env = env;