diff --git a/vendor/wasm/js/events.odin b/vendor/wasm/js/events.odin index dd9524adb..136c0610d 100644 --- a/vendor/wasm/js/events.odin +++ b/vendor/wasm/js/events.odin @@ -79,6 +79,8 @@ Event_Kind :: enum u32 { Context_Menu, + Custom, + } event_kind_string := [Event_Kind]string{ .Invalid = "", @@ -155,6 +157,8 @@ event_kind_string := [Event_Kind]string{ .Touch_Start = "touchstart", .Context_Menu = "contextmenu", + + .Custom = "?custom?", } Delta_Mode :: enum u32 { @@ -186,6 +190,13 @@ Event_Phase :: enum u8 { Bubbling_Phase = 3, } +Event_Option :: enum u8 { + Bubbles = 0, + Cancelable = 1, + Composed = 2, +} +Event_Options :: distinct bit_set[Event_Option; u8] + Event :: struct { kind: Event_Kind, target_kind: Event_Target_Kind, @@ -194,9 +205,7 @@ Event :: struct { timestamp: f64, phase: Event_Phase, - bubbles: bool, - cancelable: bool, - composed: bool, + options: Event_Options, is_composing: bool, is_trusted: bool, @@ -255,6 +264,7 @@ foreign dom_lib { event_stop_propagation :: proc() --- event_stop_immediate_propagation :: proc() --- event_prevent_default :: proc() --- + dispatch_custom_event :: proc(id: string, name: string, options := Event_Options{}) -> bool --- } add_event_listener :: proc(id: string, kind: Event_Kind, user_data: rawptr, callback: proc(e: Event), use_capture := false) -> bool { @@ -301,6 +311,23 @@ remove_event_listener_from_event :: proc(e: Event) -> bool { return remove_event_listener(e.id, e.kind, e.user_data, e.callback) } +add_custom_event_listener :: proc(id: string, name: string, user_data: rawptr, callback: proc(e: Event), use_capture := false) -> bool { + @(default_calling_convention="contextless") + foreign dom_lib { + @(link_name="add_event_listener") + _add_event_listener :: proc(id: string, name: string, name_code: Event_Kind, user_data: rawptr, callback: proc "odin" (Event), use_capture: bool) -> bool --- + } + return _add_event_listener(id, name, .Custom, user_data, callback, use_capture) +} +remove_custom_event_listener :: proc(id: string, name: string, user_data: rawptr, callback: proc(e: Event)) -> bool { + @(default_calling_convention="contextless") + foreign dom_lib { + @(link_name="remove_event_listener") + _remove_event_listener :: proc(id: string, name: string, user_data: rawptr, callback: proc "odin" (Event)) -> bool --- + } + return _remove_event_listener(id, name, user_data, callback) +} + diff --git a/vendor/wasm/js/runtime.js b/vendor/wasm/js/runtime.js index 424a9a4db..60d114506 100644 --- a/vendor/wasm/js/runtime.js +++ b/vendor/wasm/js/runtime.js @@ -1,6 +1,14 @@ "use strict"; (function() { + +function getElement(name) { + if (name) { + return document.getElementById(name); + } + return undefined; +} + class WasmMemoryInterface { constructor() { this.memory = null; @@ -204,12 +212,12 @@ class WebGLInterface { return { SetCurrentContextById: (name_ptr, name_len) => { let name = this.mem.loadString(name_ptr, name_len); - let element = document.getElementById(name); + let element = getElement(name); return this.setCurrentContext(element, {alpha: true, antialias: true, depth: true, premultipliedAlpha: true}); }, CreateCurrentContextById: (name_ptr, name_len, attributes) => { let name = this.mem.loadString(name_ptr, name_len); - let element = document.getElementById(name); + let element = getElement(name); let contextSettings = { alpha: !(attributes & (1<<0)), @@ -1380,9 +1388,11 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) { wmi.storeF64(off(8), e.timeStamp*1e-3); wmi.storeU8(off(1), e.eventPhase); - wmi.storeU8(off(1), !!e.bubbles); - wmi.storeU8(off(1), !!e.cancelable); - wmi.storeU8(off(1), !!e.composed); + let options = 0; + if (!!e.bubbles) { options |= 1<<0; } + if (!!e.cancelable) { options |= 1<<1; } + if (!!e.composed) { options |= 1<<2; } + wmi.storeU8(off(1), options); wmi.storeU8(off(1), !!e.isComposing); wmi.storeU8(off(1), !!e.isTrusted); @@ -1433,7 +1443,7 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) { add_event_listener: (id_ptr, id_len, name_ptr, name_len, name_code, data, callback, use_capture) => { let id = wasmMemoryInterface.loadString(id_ptr, id_len); let name = wasmMemoryInterface.loadString(name_ptr, name_len); - let element = document.getElementById(id); + let element = getElement(id); if (element == undefined) { return false; } @@ -1454,7 +1464,7 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) { remove_event_listener: (id_ptr, id_len, name_ptr, name_len, data, callback) => { let id = wasmMemoryInterface.loadString(id_ptr, id_len); let name = wasmMemoryInterface.loadString(name_ptr, name_len); - let element = document.getElementById(id); + let element = getElement(id); if (element == undefined) { return false; } @@ -1514,14 +1524,31 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) { } }, + dispatch_custom_event: (id_ptr, id_len, name_ptr, name_len, options_bits) => { + let id = wasmMemoryInterface.loadString(id_ptr, id_len); + let name = wasmMemoryInterface.loadString(name_ptr, name_len); + let options = { + bubbles: (options_bits & (1<<0)) !== 0, + cancelabe: (options_bits & (1<<1)) !== 0, + composed: (options_bits & (1<<2)) !== 0, + }; + + let element = getElement(id); + if (element) { + element.dispatchEvent(new Event(name, options)); + return true; + } + return false; + }, + get_element_value_f64: (id_ptr, id_len) => { let id = wasmMemoryInterface.loadString(id_ptr, id_len); - let element = document.getElementById(id); + let element = getElement(id); return element ? element.value : 0; }, get_element_value_string: (id_ptr, id_len, buf_ptr, buf_len) => { let id = wasmMemoryInterface.loadString(id_ptr, id_len); - let element = document.getElementById(id); + let element = getElement(id); if (element) { let str = element.value; if (buf_len > 0 && buf_ptr) { @@ -1535,7 +1562,7 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) { }, get_element_value_string_length: (id_ptr, id_len) => { let id = wasmMemoryInterface.loadString(id_ptr, id_len); - let element = document.getElementById(id); + let element = getElement(id); if (element) { return element.value.length; } @@ -1543,7 +1570,7 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) { }, get_element_min_max: (ptr_array2_f64, id_ptr, id_len) => { let id = wasmMemoryInterface.loadString(id_ptr, id_len); - let element = document.getElementById(id); + let element = getElement(id); if (element) { let values = wasmMemoryInterface.loadF64Array(ptr_array2_f64, 2); values[0] = element.min; @@ -1552,7 +1579,7 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) { }, set_element_value_f64: (id_ptr, id_len, value) => { let id = wasmMemoryInterface.loadString(id_ptr, id_len); - let element = document.getElementById(id); + let element = getElement(id); if (element) { element.value = value; } @@ -1560,7 +1587,7 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) { set_element_value_string: (id_ptr, id_len, value_ptr, value_id) => { let id = wasmMemoryInterface.loadString(id_ptr, id_len); let value = wasmMemoryInterface.loadString(value_ptr, value_len); - let element = document.getElementById(id); + let element = getElement(id); if (element) { element.value = value; } @@ -1569,7 +1596,7 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) { get_bounding_client_rect: (rect_ptr, id_ptr, id_len) => { let id = wasmMemoryInterface.loadString(id_ptr, id_len); - let element = document.getElementById(id); + let element = getElement(id); if (element) { let values = wasmMemoryInterface.loadF64Array(rect_ptr, 4); let rect = element.getBoundingClientRect();