diff --git a/packages/wasm-api-dom/package.json b/packages/wasm-api-dom/package.json index 57147745b2..05bbf20e7b 100644 --- a/packages/wasm-api-dom/package.json +++ b/packages/wasm-api-dom/package.json @@ -25,7 +25,7 @@ "license": "Apache-2.0", "scripts": { "build": "yarn clean && tsc --declaration", - "build:types": "npx wasm-api -a analytics.json --lang ts -o src/generated/api.ts --lang zig -o zig/api.zig src/typedefs.json", + "build:types": "npx wasm-api -a analytics.json --string ptr --lang ts -o src/generated/api.ts --lang zig -o zig/api.zig src/typedefs.json", "clean": "rimraf '*.js' '*.d.ts' '*.map' doc", "doc": "typedoc --excludePrivate --excludeInternal --out doc src/index.ts", "doc:ae": "mkdir -p .ae/doc .ae/temp && api-extractor run --local --verbose", diff --git a/packages/wasm-api-dom/src/api.ts b/packages/wasm-api-dom/src/api.ts index 5a5f6f35ad..4fc70fd527 100644 --- a/packages/wasm-api-dom/src/api.ts +++ b/packages/wasm-api-dom/src/api.ts @@ -29,7 +29,7 @@ export interface DOMImports extends WebAssembly.ModuleImports { * * @param nameAddr */ - _getElementByID(nameAddr: number): number; + getElementByID(nameAddr: number): number; /** * Takes a {@link CreateElementOpts} pointer and creates a new DOM element @@ -86,26 +86,38 @@ export interface DOMImports extends WebAssembly.ModuleImports { dpr: number ): void; + /** + * Sets `.innerHTML` property of a DOM element to provided `body` string. + * + * @param elementID + * @param body + */ + setInnerHtml(elementID: number, body: number): void; + + /** + * Sets `.innerText` property of a DOM element to provided `body` string. + * + * @param elementID + * @param body + */ + setInnerText(elementID: number, body: number): void; + /** * Sets attribute for given element to new string value. Both `nameAddr` and * `valAddr` are pointers to zero-terminated u8 arrays (or standard Zig - * `[]u8` slices). + * string literals). * * @param elementID * @param nameAddr * @param valAddr */ - _setStringAttrib( - elementID: number, - nameAddr: number, - valAddr: number - ): void; + setStringAttrib(elementID: number, nameAddr: number, valAddr: number): void; /** * Reads a string attribute value from DOM element, encodes it as UTF-8 and * writes zero-terminated bytes to char pointer `valAddr`. Only `maxBytes` - * are written. Returns actual number of bytes written (excluding the - * sentinel). + * are written (incl. any sentinel). Returns actual number of bytes written + * (excluding the sentinel). * * @param elementID * @param nameAddr @@ -143,27 +155,27 @@ export interface DOMImports extends WebAssembly.ModuleImports { * @param nameAddr * @param val */ - _setNumericAttrib(elementID: number, nameAddr: number, val: number): void; + setNumericAttrib(elementID: number, nameAddr: number, val: number): void; /** - * Sets (or removes) boolean attribute for given element. `nameAddr` is a - * pointer to a zero-terminated u8 array (or standard Zig `[]u8` slice). If - * `state` is non-zero, the attrib will be created/ensured, if zero it will - * be removed. + * Reads a numeric attribute value from DOM element and returns it as f64. * * @param elementID * @param nameAddr - * @param state */ - _setBooleanAttrib(elementID: number, nameAddr: number, state: number): void; + getNumericAttrib(elementID: number, nameAddr: number): number; /** - * Reads a numeric attribute value from DOM element and returns it as f64. + * Sets (or removes) boolean attribute for given element. `nameAddr` is a + * pointer to a zero-terminated u8 array (or standard Zig `[]u8` slice). If + * `state` is non-zero, the attrib will be created/ensured, if zero it will + * be removed. * * @param elementID * @param nameAddr + * @param state */ - _getNumericAttrib(elementID: number, nameAddr: number): number; + _setBooleanAttrib(elementID: number, nameAddr: number, state: number): void; /** * Check if the DOM element has given attribute and returns 1 if so, else 0. @@ -173,9 +185,9 @@ export interface DOMImports extends WebAssembly.ModuleImports { */ _getBooleanAttrib(elementID: number, nameAddr: number): number; - _addClass(elementID: number, nameAddr: number): void; + addClass(elementID: number, nameAddr: number): void; - _removeClass(elementID: number, nameAddr: number): void; + removeClass(elementID: number, nameAddr: number): void; /** * Attaches a new DOM event listener for given event name to element (or @@ -200,9 +212,6 @@ export interface DOMImports extends WebAssembly.ModuleImports { */ _removeListener(listenerID: number): void; - _setInnerHtml(elementID: number, body: number): void; - _setInnerText(elementID: number, body: number): void; - _requestAnimationFrame(rafID: number): void; _requestFullscreen(elementID: number): Promise; diff --git a/packages/wasm-api-dom/src/dom.ts b/packages/wasm-api-dom/src/dom.ts index 9488405544..67e29106a6 100644 --- a/packages/wasm-api-dom/src/dom.ts +++ b/packages/wasm-api-dom/src/dom.ts @@ -118,7 +118,7 @@ export class WasmDom implements IWasmAPI { : 0); }, - _getElementByID: (nameAddr: number) => { + getElementByID: (nameAddr: number) => { const name = this.parent.getString(nameAddr); let id = this.elements.find((el) => el.id === name); if (id === undefined) { @@ -203,10 +203,10 @@ export class WasmDom implements IWasmAPI { dpr ), - _setStringAttrib: (elementID: number, name: number, val: number) => + setStringAttrib: (elementID: number, name: number, val: number) => this.setAttrib(elementID, name, this.parent.getString(val)), - _setNumericAttrib: (elementID: number, name: number, val: number) => + setNumericAttrib: (elementID: number, name: number, val: number) => this.setAttrib(elementID, name, val), _setBooleanAttrib: ( @@ -244,21 +244,21 @@ export class WasmDom implements IWasmAPI { ) => new WasmStringSlice(this.parent, slice).setAlloc( String(this.getAttrib(elementID, nameAddr) || ""), - false + true ), - _getNumericAttrib: (elementID: number, nameAddr: number) => + getNumericAttrib: (elementID: number, nameAddr: number) => Number(this.getAttrib(elementID, nameAddr) || ""), _getBooleanAttrib: (elementID: number, nameAddr: number) => ~~(this.getAttrib(elementID, nameAddr) != null), - _addClass: (elementID: number, name: number) => + addClass: (elementID: number, name: number) => this.elements .get(elementID) .classList.add(this.parent.getString(name)), - _removeClass: (elementID: number, name: number) => + removeClass: (elementID: number, name: number) => this.elements .get(elementID) .classList.remove(this.parent.getString(name)), @@ -352,12 +352,12 @@ export class WasmDom implements IWasmAPI { } }, - _setInnerHtml: (elementID: number, body: number) => { + setInnerHtml: (elementID: number, body: number) => { this.elements.get(elementID).innerHTML = this.parent.getString(body); }, - _setInnerText: (elementID: number, body: number) => { + setInnerText: (elementID: number, body: number) => { (this.elements.get(elementID)).innerText = this.parent.getString(body); }, diff --git a/packages/wasm-api-dom/src/generated/api.ts b/packages/wasm-api-dom/src/generated/api.ts index f3b4133a3e..015f447c8a 100644 --- a/packages/wasm-api-dom/src/generated/api.ts +++ b/packages/wasm-api-dom/src/generated/api.ts @@ -1,9 +1,9 @@ /** - * Generated by @thi.ng/wasm-api at 2022-11-06T13:00:00.501Z - DO NOT EDIT! + * Generated by @thi.ng/wasm-api at 2022-11-07T16:57:42.720Z - DO NOT EDIT! */ // @ts-ignore possibly includes unused imports -import { MemorySlice, Pointer, WasmStringSlice, WasmTypeBase, WasmTypeConstructor } from "@thi.ng/wasm-api"; +import { MemorySlice, Pointer, WasmStringPtr, WasmTypeBase, WasmTypeConstructor } from "@thi.ng/wasm-api"; export enum EventType { UNKOWN = -1, @@ -44,6 +44,9 @@ export enum KeyModifier { META = 8, } +/** + * Various browser window related information [TODO] + */ export interface WindowInfo extends WasmTypeBase { /** * WASM type: u16 @@ -246,10 +249,16 @@ export const $DragEvent: WasmTypeConstructor = (mem) => ({ export interface InputEvent extends WasmTypeBase { /** * Value of the targeted input element. - * The memory is owned by the DOM API and will be freed immediatedly after the + * The memory is owned by the DOM API and will be freed immediately after the * event handler has returned. */ - value: WasmStringSlice; + value: WasmStringPtr; + /** + * Length of the value string + * + * WASM type: u32 + */ + len: number; /** * Encoded bitmask of currently pressed modifier keys, see `KeyModifier` enum * @@ -268,7 +277,7 @@ export const $InputEvent: WasmTypeConstructor = (mem) => ({ return 12; }, instance: (base) => { - let $value: WasmStringSlice | null = null; + let $value: WasmStringPtr | null = null; return { get __base() { return base; @@ -276,8 +285,14 @@ export const $InputEvent: WasmTypeConstructor = (mem) => ({ get __bytes() { return mem.u8.subarray(base, base + 12); }, - get value(): WasmStringSlice { - return $value || ($value = new WasmStringSlice(mem, base, true)); + get value(): WasmStringPtr { + return $value || ($value = new WasmStringPtr(mem, base, true)); + }, + get len(): number { + return mem.u32[(base + 4) >>> 2]; + }, + set len(x: number) { + mem.u32[(base + 4) >>> 2] = x; }, get modifiers(): number { return mem.u8[(base + 8)]; @@ -289,7 +304,9 @@ export const $InputEvent: WasmTypeConstructor = (mem) => ({ fromEvent(e: globalThis.InputEvent) { const el = e.target; const value = el.type === "checkbox" ? el.checked ? "on" : "off" : el.value; - return this.value.setAlloc(value, false); + const slice = this.value.setAlloc(value); + this.len = slice[1] - 1; + return slice; } }; @@ -490,7 +507,7 @@ export interface PointerEvent extends WasmTypeBase { */ pressure: number; /** - * The plane angle (in degrees, in the range of -90 to 90) between the Y–Z plane + * The plane angle (in degrees, in the range of -90 to 90) between the Y-Z plane * and the plane containing both the pointer (e.g. pen stylus) axis and the Y * axis. * @@ -498,7 +515,7 @@ export interface PointerEvent extends WasmTypeBase { */ tiltX: number; /** - * The plane angle (in degrees, in the range of -90 to 90) between the X–Z plane + * The plane angle (in degrees, in the range of -90 to 90) between the X-Z plane * and the plane containing both the pointer (e.g. pen stylus) axis and the X * axis. * @@ -1072,27 +1089,27 @@ export interface CreateElementOpts extends WasmTypeBase { /** * DOM element name */ - tag: WasmStringSlice; + tag: WasmStringPtr; /** * Namespace URI or wellknown registered alias (e.g. svg, xlink, xmlns) */ - ns: WasmStringSlice; + ns: WasmStringPtr; /** * ID attrib */ - id: WasmStringSlice; + id: WasmStringPtr; /** * Element class attrib */ - class: WasmStringSlice; + class: WasmStringPtr; /** * Element inner text body */ - text: WasmStringSlice; + text: WasmStringPtr; /** * Element inner HTML body */ - html: WasmStringSlice; + html: WasmStringPtr; /** * Parent element ID. If >=0 the new element will be attached to that parent * element. Set to -1 to leave new element unattached (default unless nested) @@ -1123,63 +1140,63 @@ export const $CreateElementOpts: WasmTypeConstructor = (mem) return 4; }, get size() { - return 72; + return 48; }, instance: (base) => { - let $tag: WasmStringSlice | null = null; - let $ns: WasmStringSlice | null = null; - let $id: WasmStringSlice | null = null; - let $class: WasmStringSlice | null = null; - let $text: WasmStringSlice | null = null; - let $html: WasmStringSlice | null = null; + let $tag: WasmStringPtr | null = null; + let $ns: WasmStringPtr | null = null; + let $id: WasmStringPtr | null = null; + let $class: WasmStringPtr | null = null; + let $text: WasmStringPtr | null = null; + let $html: WasmStringPtr | null = null; return { get __base() { return base; }, get __bytes() { - return mem.u8.subarray(base, base + 72); + return mem.u8.subarray(base, base + 48); }, - get tag(): WasmStringSlice { - return $tag || ($tag = new WasmStringSlice(mem, base, true)); + get tag(): WasmStringPtr { + return $tag || ($tag = new WasmStringPtr(mem, base, true)); }, - get ns(): WasmStringSlice { - return $ns || ($ns = new WasmStringSlice(mem, (base + 8), true)); + get ns(): WasmStringPtr { + return $ns || ($ns = new WasmStringPtr(mem, (base + 4), true)); }, - get id(): WasmStringSlice { - return $id || ($id = new WasmStringSlice(mem, (base + 16), true)); + get id(): WasmStringPtr { + return $id || ($id = new WasmStringPtr(mem, (base + 8), true)); }, - get class(): WasmStringSlice { - return $class || ($class = new WasmStringSlice(mem, (base + 24), true)); + get class(): WasmStringPtr { + return $class || ($class = new WasmStringPtr(mem, (base + 12), true)); }, - get text(): WasmStringSlice { - return $text || ($text = new WasmStringSlice(mem, (base + 32), true)); + get text(): WasmStringPtr { + return $text || ($text = new WasmStringPtr(mem, (base + 16), true)); }, - get html(): WasmStringSlice { - return $html || ($html = new WasmStringSlice(mem, (base + 40), true)); + get html(): WasmStringPtr { + return $html || ($html = new WasmStringPtr(mem, (base + 20), true)); }, get parent(): number { - return mem.i32[(base + 48) >>> 2]; + return mem.i32[(base + 24) >>> 2]; }, set parent(x: number) { - mem.i32[(base + 48) >>> 2] = x; + mem.i32[(base + 24) >>> 2] = x; }, get index(): number { - return mem.i32[(base + 52) >>> 2]; + return mem.i32[(base + 28) >>> 2]; }, set index(x: number) { - mem.i32[(base + 52) >>> 2] = x; + mem.i32[(base + 28) >>> 2] = x; }, get children(): CreateElementOpts[] { - const len = mem.u32[(base + 60) >>> 2]; - const addr = mem.u32[(base + 56) >>> 2]; + const len = mem.u32[(base + 36) >>> 2]; + const addr = mem.u32[(base + 32) >>> 2]; const inst = $CreateElementOpts(mem); const slice: CreateElementOpts[] = []; - for(let i = 0; i < len; i++) slice.push(inst.instance(addr + i * 72)); + for(let i = 0; i < len; i++) slice.push(inst.instance(addr + i * 48)); return slice; }, get attribs(): Attrib[] { - const len = mem.u32[(base + 68) >>> 2]; - const addr = mem.u32[(base + 64) >>> 2]; + const len = mem.u32[(base + 44) >>> 2]; + const addr = mem.u32[(base + 40) >>> 2]; const inst = $Attrib(mem); const slice: Attrib[] = []; for(let i = 0; i < len; i++) slice.push(inst.instance(addr + i * 24)); @@ -1190,7 +1207,7 @@ export const $CreateElementOpts: WasmTypeConstructor = (mem) }); export interface Attrib extends WasmTypeBase { - name: WasmStringSlice; + name: WasmStringPtr; value: AttribValue; kind: AttribType; } @@ -1203,7 +1220,7 @@ export const $Attrib: WasmTypeConstructor = (mem) => ({ return 24; }, instance: (base) => { - let $name: WasmStringSlice | null = null; + let $name: WasmStringPtr | null = null; return { get __base() { return base; @@ -1211,8 +1228,8 @@ export const $Attrib: WasmTypeConstructor = (mem) => ({ get __bytes() { return mem.u8.subarray(base, base + 24); }, - get name(): WasmStringSlice { - return $name || ($name = new WasmStringSlice(mem, base, true)); + get name(): WasmStringPtr { + return $name || ($name = new WasmStringPtr(mem, base, true)); }, get value(): AttribValue { return $AttribValue(mem).instance((base + 8)); @@ -1240,7 +1257,7 @@ export interface AttribValue extends WasmTypeBase { * WASM type: f64 */ num: number; - str: WasmStringSlice; + str: WasmStringPtr; } export const $AttribValue: WasmTypeConstructor = (mem) => ({ @@ -1251,7 +1268,7 @@ export const $AttribValue: WasmTypeConstructor = (mem) => ({ return 8; }, instance: (base) => { - let $str: WasmStringSlice | null = null; + let $str: WasmStringPtr | null = null; return { get __base() { return base; @@ -1277,8 +1294,8 @@ export const $AttribValue: WasmTypeConstructor = (mem) => ({ set num(x: number) { mem.f64[base >>> 3] = x; }, - get str(): WasmStringSlice { - return $str || ($str = new WasmStringSlice(mem, base, true)); + get str(): WasmStringPtr { + return $str || ($str = new WasmStringPtr(mem, base, true)); }, }; } @@ -1307,11 +1324,11 @@ export interface CreateCanvasOpts extends WasmTypeBase { /** * Element ID attrib */ - id: WasmStringSlice; + id: WasmStringPtr; /** * Element class attrib */ - class: WasmStringSlice; + class: WasmStringPtr; /** * Same as CreateElementOpts.parent * @@ -1343,17 +1360,17 @@ export const $CreateCanvasOpts: WasmTypeConstructor = (mem) => return 4; }, get size() { - return 40; + return 32; }, instance: (base) => { - let $id: WasmStringSlice | null = null; - let $class: WasmStringSlice | null = null; + let $id: WasmStringPtr | null = null; + let $class: WasmStringPtr | null = null; return { get __base() { return base; }, get __bytes() { - return mem.u8.subarray(base, base + 40); + return mem.u8.subarray(base, base + 32); }, get width(): number { return mem.u16[base >>> 1]; @@ -1367,33 +1384,33 @@ export const $CreateCanvasOpts: WasmTypeConstructor = (mem) => set height(x: number) { mem.u16[(base + 2) >>> 1] = x; }, - get id(): WasmStringSlice { - return $id || ($id = new WasmStringSlice(mem, (base + 4), true)); + get id(): WasmStringPtr { + return $id || ($id = new WasmStringPtr(mem, (base + 4), true)); }, - get class(): WasmStringSlice { - return $class || ($class = new WasmStringSlice(mem, (base + 12), true)); + get class(): WasmStringPtr { + return $class || ($class = new WasmStringPtr(mem, (base + 8), true)); }, get parent(): number { - return mem.i32[(base + 20) >>> 2]; + return mem.i32[(base + 12) >>> 2]; }, set parent(x: number) { - mem.i32[(base + 20) >>> 2] = x; + mem.i32[(base + 12) >>> 2] = x; }, get index(): number { - return mem.i32[(base + 24) >>> 2]; + return mem.i32[(base + 16) >>> 2]; }, set index(x: number) { - mem.i32[(base + 24) >>> 2] = x; + mem.i32[(base + 16) >>> 2] = x; }, get dpr(): number { - return mem.u8[(base + 28)]; + return mem.u8[(base + 20)]; }, set dpr(x: number) { - mem.u8[(base + 28)] = x; + mem.u8[(base + 20)] = x; }, get attribs(): Attrib[] { - const len = mem.u32[(base + 36) >>> 2]; - const addr = mem.u32[(base + 32) >>> 2]; + const len = mem.u32[(base + 28) >>> 2]; + const addr = mem.u32[(base + 24) >>> 2]; const inst = $Attrib(mem); const slice: Attrib[] = []; for(let i = 0; i < len; i++) slice.push(inst.instance(addr + i * 24)); diff --git a/packages/wasm-api-dom/src/typedefs.json b/packages/wasm-api-dom/src/typedefs.json index a56884cdd3..cfa07380e0 100644 --- a/packages/wasm-api-dom/src/typedefs.json +++ b/packages/wasm-api-dom/src/typedefs.json @@ -53,6 +53,8 @@ { "name": "WindowInfo", "type": "struct", + "tag": "extern", + "doc": "Various browser window related information [TODO]", "fields": [ { "name": "innerWidth", "type": "u16" }, { "name": "innerHeight", "type": "u16" }, @@ -98,6 +100,7 @@ { "name": "DragEvent", "type": "struct", + "tag": "extern", "fields": [ { "name": "clientX", @@ -154,15 +157,21 @@ { "name": "InputEvent", "type": "struct", + "tag": "extern", "fields": [ { "name": "value", "type": "string", "doc": [ "Value of the targeted input element.", - "The memory is owned by the DOM API and will be freed immediatedly after the event handler has returned." + "The memory is owned by the DOM API and will be freed immediately after the event handler has returned." ] }, + { + "name": "len", + "type": "usize", + "doc": "Length of the value string" + }, { "name": "modifiers", "type": "u8", @@ -177,15 +186,23 @@ "fromEvent(e: globalThis.InputEvent) {", "const el = e.target;", "const value = el.type === \"checkbox\" ? el.checked ? \"on\" : \"off\" : el.value;", - "return this.value.setAlloc(value, false);", + "const slice = this.value.setAlloc(value);", + "this.len = slice[1] - 1;", + "return slice;", "}" ] - } + }, + "zig": [ + "pub inline fn getValue(self: *const InputEvent) [:0]const u8 {", + "return self.value[0..self.len :0];", + "}" + ] } }, { "name": "KeyEvent", "type": "struct", + "tag": "extern", "fields": [ { "name": "key", @@ -224,8 +241,8 @@ ] }, "zig": [ - "pub inline fn getKey(self: *const KeyEvent) []const u8 {", - "return self.key[0..@as(usize, self.len)];", + "pub inline fn getKey(self: *const KeyEvent) [:0]const u8 {", + "return self.key[0..@as(usize, self.len) :0];", "}", "", "pub inline fn hasModifier(self: *const KeyEvent, mod: KeyModifier) bool {", @@ -237,6 +254,7 @@ { "name": "MouseEvent", "type": "struct", + "tag": "extern", "fields": [ { "name": "clientX", @@ -286,6 +304,7 @@ { "name": "PointerEvent", "type": "struct", + "tag": "extern", "fields": [ { "name": "clientX", @@ -314,13 +333,13 @@ { "name": "tiltX", "type": "i8", - "doc": "The plane angle (in degrees, in the range of -90 to 90) between the Y–Z plane and the plane containing both the pointer (e.g. pen stylus) axis and the Y axis.", + "doc": "The plane angle (in degrees, in the range of -90 to 90) between the Y-Z plane and the plane containing both the pointer (e.g. pen stylus) axis and the Y axis.", "default": 0 }, { "name": "tiltY", "type": "i8", - "doc": "The plane angle (in degrees, in the range of -90 to 90) between the X–Z plane and the plane containing both the pointer (e.g. pen stylus) axis and the X axis.", + "doc": "The plane angle (in degrees, in the range of -90 to 90) between the X-Z plane and the plane containing both the pointer (e.g. pen stylus) axis and the X axis.", "default": 0 }, { @@ -379,6 +398,7 @@ { "name": "ScrollEvent", "type": "struct", + "tag": "extern", "fields": [ { "name": "scrollX", @@ -407,6 +427,7 @@ { "name": "TouchEvent", "type": "struct", + "tag": "extern", "fields": [ { "name": "clientX", @@ -443,6 +464,7 @@ { "name": "WheelEvent", "type": "struct", + "tag": "extern", "fields": [ { "name": "deltaX", @@ -498,6 +520,7 @@ { "name": "EventBody", "type": "union", + "tag": "extern", "fields": [ { "name": "drag", "type": "DragEvent" }, { "name": "input", "type": "InputEvent" }, @@ -512,6 +535,7 @@ { "name": "Event", "type": "struct", + "tag": "extern", "fields": [ { "name": "id", "type": "EventType" }, { @@ -557,6 +581,7 @@ { "name": "RAFCallback", "type": "funcptr", + "doc": "Function signature for RAF (requestAnimationFrame) event handler", "rtype": "void", "args": [ { "name": "time", "type": "f64" }, @@ -567,6 +592,7 @@ { "name": "EventListener", "type": "struct", + "tag": "extern", "doc": "DOM event listener", "fields": [ { @@ -590,6 +616,7 @@ { "name": "RAFListener", "type": "struct", + "tag": "extern", "doc": "RAF event listener", "fields": [ { @@ -679,6 +706,7 @@ { "name": "Attrib", "type": "struct", + "tag": "extern", "fields": [ { "name": "name", "type": "string" }, { "name": "value", "type": "AttribValue" }, @@ -686,19 +714,19 @@ ], "body": { "zig": [ - "pub fn event(name: []const u8, val: EventListener) Attrib {", + "pub fn event(name: [*:0]const u8, val: EventListener) Attrib {", "return Attrib{ .name = name, .kind = .event, .value = .{ .event = val } };", "}", "", - "pub fn flag(name: []const u8, val: bool) Attrib {", + "pub fn flag(name: [*:0]const u8, val: bool) Attrib {", "return Attrib{ .name = name, .kind = .flag, .value = .{ .flag = if (val) 1 else 0 } };", "}", "", - "pub fn number(name: []const u8, val: f64) Attrib {", + "pub fn number(name: [*:0]const u8, val: f64) Attrib {", "return Attrib{ .name = name, .kind = .num, .value = .{ .num = val } };", "}", "", - "pub fn string(name: []const u8, val: []const u8) Attrib {", + "pub fn string(name: [*:0]const u8, val: [*:0]const u8) Attrib {", "return Attrib{ .name = name, .kind = .str, .value = .{ .str = val } };", "}" ] @@ -707,6 +735,7 @@ { "name": "AttribValue", "type": "union", + "tag": "extern", "fields": [ { "name": "event", "type": "EventListener" }, { "name": "flag", "type": "u8" }, diff --git a/packages/wasm-api-dom/zig/api.zig b/packages/wasm-api-dom/zig/api.zig index 2f88adfcb1..b1d2961e6d 100644 --- a/packages/wasm-api-dom/zig/api.zig +++ b/packages/wasm-api-dom/zig/api.zig @@ -1,4 +1,4 @@ -//! Generated by @thi.ng/wasm-api at 2022-11-06T13:00:00.505Z - DO NOT EDIT! +//! Generated by @thi.ng/wasm-api at 2022-11-07T16:57:42.724Z - DO NOT EDIT! const std = @import("std"); @@ -41,7 +41,8 @@ pub const KeyModifier = enum(u8) { meta = 8, }; -pub const WindowInfo = struct { +/// Various browser window related information [TODO] +pub const WindowInfo = extern struct { innerWidth: u16, innerHeight: u16, /// Horizontal scroll offset in fractional CSS pixels @@ -67,7 +68,7 @@ pub const WindowInfo = struct { }; -pub const DragEvent = struct { +pub const DragEvent = extern struct { /// Mouse X position in the local space of the element's bounding rect clientX: i16 = 0, /// Mouse Y position in the local space of the element's bounding rect @@ -85,16 +86,23 @@ pub const DragEvent = struct { button: MouseButton, }; -pub const InputEvent = struct { +pub const InputEvent = extern struct { /// Value of the targeted input element. - /// The memory is owned by the DOM API and will be freed immediatedly after the + /// The memory is owned by the DOM API and will be freed immediately after the /// event handler has returned. - value: []const u8, + value: [*:0]const u8, + /// Length of the value string + len: u32, /// Encoded bitmask of currently pressed modifier keys, see `KeyModifier` enum modifiers: u8 = 0, + + pub inline fn getValue(self: *const InputEvent) [:0]const u8 { + return self.value[0..self.len :0]; + } + }; -pub const KeyEvent = struct { +pub const KeyEvent = extern struct { /// Value/name of the key pressed key: [15:0]u8, /// Number of characters of the `key` string @@ -105,8 +113,8 @@ pub const KeyEvent = struct { /// repeating repeat: u8 = 0, - pub inline fn getKey(self: *const KeyEvent) []const u8 { - return self.key[0..@as(usize, self.len)]; + pub inline fn getKey(self: *const KeyEvent) [:0]const u8 { + return self.key[0..@as(usize, self.len) :0]; } pub inline fn hasModifier(self: *const KeyEvent, mod: KeyModifier) bool { @@ -115,7 +123,7 @@ pub const KeyEvent = struct { }; -pub const MouseEvent = struct { +pub const MouseEvent = extern struct { /// Mouse X position in the local space of the element's bounding rect clientX: i16 = 0, /// Mouse Y position in the local space of the element's bounding rect @@ -129,7 +137,7 @@ pub const MouseEvent = struct { button: MouseButton, }; -pub const PointerEvent = struct { +pub const PointerEvent = extern struct { /// Mouse X position in the local space of the element's bounding rect clientX: i16 = 0, /// Mouse Y position in the local space of the element's bounding rect @@ -138,11 +146,11 @@ pub const PointerEvent = struct { id: u32 = 0, /// Normalized pressure value 0..1 pressure: f32 = 0, - /// The plane angle (in degrees, in the range of -90 to 90) between the Y–Z + /// The plane angle (in degrees, in the range of -90 to 90) between the Y-Z /// plane and the plane containing both the pointer (e.g. pen stylus) axis and /// the Y axis. tiltX: i8 = 0, - /// The plane angle (in degrees, in the range of -90 to 90) between the X–Z + /// The plane angle (in degrees, in the range of -90 to 90) between the X-Z /// plane and the plane containing both the pointer (e.g. pen stylus) axis and /// the X axis. tiltY: i8 = 0, @@ -162,14 +170,14 @@ pub const PointerEvent = struct { button: MouseButton, }; -pub const ScrollEvent = struct { +pub const ScrollEvent = extern struct { /// Horizontal scroll offset in fractional CSS pixels. scrollX: f32, /// Vertical scroll offset in fractional CSS pixels. scrollY: f32, }; -pub const TouchEvent = struct { +pub const TouchEvent = extern struct { /// Touch X position in the local space of the element's bounding rect clientX: i16 = 0, /// Touch Y position in the local space of the element's bounding rect @@ -178,7 +186,7 @@ pub const TouchEvent = struct { modifiers: u8 = 0, }; -pub const WheelEvent = struct { +pub const WheelEvent = extern struct { /// Scroll X delta deltaX: i16 = 0, /// Scroll Y delta @@ -193,7 +201,7 @@ pub const WheelEvent = struct { buttons: u8 = 0, }; -pub const EventBody = union { +pub const EventBody = extern union { drag: DragEvent, input: InputEvent, key: KeyEvent, @@ -204,7 +212,7 @@ pub const EventBody = union { wheel: WheelEvent, }; -pub const Event = struct { +pub const Event = extern struct { id: EventType, /// Target element ID, > 1 if a known (WASM created) element, otherwise: /// @@ -229,10 +237,11 @@ pub const Event = struct { pub const EventCallback = *const fn(event: *const Event, ctx: ?*anyopaque) void; +/// Function signature for RAF (requestAnimationFrame) event handler pub const RAFCallback = *const fn(time: f64, ctx: ?*anyopaque) void; /// DOM event listener -pub const EventListener = struct { +pub const EventListener = extern struct { /// Event listener function. Takes an event and optional pointer to user /// supplied arbitrary context data provided when registering the handler via /// `addListener()` @@ -245,7 +254,7 @@ pub const EventListener = struct { }; /// RAF event listener -pub const RAFListener = struct { +pub const RAFListener = extern struct { /// Animation frame listener function. Takes an hires timestamp and optional /// pointer to user supplied arbitrary context data provided when registering /// the handler via `requestAnimationFrame()` @@ -259,17 +268,17 @@ pub const RAFListener = struct { pub const CreateElementOpts = struct { /// DOM element name - tag: []const u8, + tag: [*:0]const u8, /// Namespace URI or wellknown registered alias (e.g. svg, xlink, xmlns) - ns: []const u8 = "", + ns: [*:0]const u8 = "", /// ID attrib - id: []const u8 = "", + id: [*:0]const u8 = "", /// Element class attrib - class: []const u8 = "", + class: [*:0]const u8 = "", /// Element inner text body - text: []const u8 = "", + text: [*:0]const u8 = "", /// Element inner HTML body - html: []const u8 = "", + html: [*:0]const u8 = "", /// Parent element ID. If >=0 the new element will be attached to that parent /// element. Set to -1 to leave new element unattached (default unless nested) parent: i32 = -1, @@ -283,34 +292,34 @@ pub const CreateElementOpts = struct { attribs: []const Attrib = &.{}, }; -pub const Attrib = struct { - name: []const u8, +pub const Attrib = extern struct { + name: [*:0]const u8, value: AttribValue, kind: AttribType, - pub fn event(name: []const u8, val: EventListener) Attrib { + pub fn event(name: [*:0]const u8, val: EventListener) Attrib { return Attrib{ .name = name, .kind = .event, .value = .{ .event = val } }; } - pub fn flag(name: []const u8, val: bool) Attrib { + pub fn flag(name: [*:0]const u8, val: bool) Attrib { return Attrib{ .name = name, .kind = .flag, .value = .{ .flag = if (val) 1 else 0 } }; } - pub fn number(name: []const u8, val: f64) Attrib { + pub fn number(name: [*:0]const u8, val: f64) Attrib { return Attrib{ .name = name, .kind = .num, .value = .{ .num = val } }; } - pub fn string(name: []const u8, val: []const u8) Attrib { + pub fn string(name: [*:0]const u8, val: [*:0]const u8) Attrib { return Attrib{ .name = name, .kind = .str, .value = .{ .str = val } }; } }; -pub const AttribValue = union { +pub const AttribValue = extern union { event: EventListener, flag: u8, num: f64, - str: []const u8, + str: [*:0]const u8, }; pub const AttribType = enum(u8) { @@ -326,9 +335,9 @@ pub const CreateCanvasOpts = struct { /// Canvas height (in CSS pixels) height: u16, /// Element ID attrib - id: []const u8 = "", + id: [*:0]const u8 = "", /// Element class attrib - class: []const u8 = "", + class: [*:0]const u8 = "", /// Same as CreateElementOpts.parent parent: i32, /// Same as CreateElementOpts.index diff --git a/packages/wasm-api-dom/zig/events.zig b/packages/wasm-api-dom/zig/events.zig index d433087a81..d510267dfc 100644 --- a/packages/wasm-api-dom/zig/events.zig +++ b/packages/wasm-api-dom/zig/events.zig @@ -21,13 +21,13 @@ export fn _dom_callListener(listenerID: u16, event: *const dom.Event) void { if (eventListeners.get(listenerID)) |listener| listener.callback(event, listener.ctx); } -pub extern "dom" fn _addListener(elementID: i32, name: [*]const u8, listenerID: u16) void; +pub extern "dom" fn _addListener(elementID: i32, name: [*:0]const u8, listenerID: u16) void; /// Adds given listener to a DOM element for event `name`. /// Returns an unique listener ID. -pub fn addListener(elementID: i32, name: []const u8, listener: *const dom.EventListener) !u16 { +pub fn addListener(elementID: i32, name: [*:0]const u8, listener: *const dom.EventListener) !u16 { const listenerID = try eventListeners.add(listener.*); - _addListener(elementID, name.ptr, listenerID); + _addListener(elementID, name, listenerID); return listenerID; } diff --git a/packages/wasm-api-dom/zig/lib.zig b/packages/wasm-api-dom/zig/lib.zig index 174171e039..0a487ef85c 100644 --- a/packages/wasm-api-dom/zig/lib.zig +++ b/packages/wasm-api-dom/zig/lib.zig @@ -27,11 +27,7 @@ export fn _dom_init() void { pub extern "dom" fn getWindowInfo(desc: *dom.WindowInfo) void; -pub extern "dom" fn _getElementByID(id: [*]const u8) i32; - -pub fn getElementByID(id: []const u8) i32 { - return _getElementByID(id.ptr); -} +pub extern "dom" fn getElementByID(id: [*:0]const u8) i32; pub extern "dom" fn createElement(opts: *const dom.CreateElementOpts) i32; @@ -41,80 +37,52 @@ pub extern "dom" fn createCanvas(opts: *const dom.CreateCanvasOpts) i32; pub extern "dom" fn setCanvasSize(elementID: i32, width: u16, height: u16, dpr: u8) void; -pub extern "dom" fn _setStringAttrib(elementID: i32, name: [*]const u8, val: [*]const u8) void; - /// Sets attrib for given name to string val -pub fn setStringAttrib(elementID: i32, name: []const u8, val: []const u8) void { - _setStringAttrib(elementID, name.ptr, val.ptr); -} +pub extern "dom" fn setStringAttrib(elementID: i32, name: [*:0]const u8, val: [*:0]const u8) void; -pub extern "dom" fn _getStringAttrib(elementID: i32, name: [*]const u8, val: [*]u8, maxBytes: usize) usize; +pub extern "dom" fn _getStringAttrib(elementID: i32, name: [*:0]const u8, val: [*:0]u8, maxBytes: usize) usize; /// Returns string value of attrib for given name -pub fn getStringAttrib(elementID: i32, name: []const u8, val: []u8) []u8 { - return val[0.._getStringAttrib(elementID, name.ptr, val.ptr, val.len)]; +pub fn getStringAttrib(elementID: i32, name: [*:0]const u8, val: [:0]u8) [:0]u8 { + return val[0.._getStringAttrib(elementID, name, val.ptr, val.len + 1)]; } -pub extern "dom" fn _getStringAttribAlloc(elementID: i32, name: [*]const u8, slice: *[]u8) void; +pub extern "dom" fn _getStringAttribAlloc(elementID: i32, name: [*:0]const u8, slice: *[:0]u8) void; /// Returns string value of attrib for given name and allocates memory for that string /// Caller owns memory -pub fn getStringAttribAlloc(elementID: i32, name: []const u8) []u8 { - var addr: []u8 = undefined; - _getStringAttribAlloc(elementID, name.ptr, &addr); +pub fn getStringAttribAlloc(elementID: i32, name: [*:0]const u8) [:0]u8 { + var addr: [:0]u8 = undefined; + _getStringAttribAlloc(elementID, name, &addr); return addr; } -pub extern "dom" fn _setNumericAttrib(elementID: i32, name: [*]const u8, val: f64) void; - /// Sets attrib for given name to numeric val -pub fn setNumericAttrib(elementID: i32, name: []const u8, val: f64) void { - _setNumericAttrib(elementID, name.ptr, val); -} - -pub extern "dom" fn _getNumericAttrib(elementID: i32, name: [*]const u8) f64; +pub extern "dom" fn setNumericAttrib(elementID: i32, name: [*:0]const u8, val: f64) void; /// Returns numeric value of attrib for given name -pub fn getNumericAttrib(elementID: i32, name: []const u8) f64 { - return _getNumericAttrib(elementID, name.ptr); -} +pub extern "dom" fn getNumericAttrib(elementID: i32, name: [*:0]const u8) f64; -pub extern "dom" fn _setBooleanAttrib(elementID: i32, name: [*]const u8, state: u8) void; +pub extern "dom" fn _setBooleanAttrib(elementID: i32, name: [*:0]const u8, state: u8) void; /// Returns numeric value of attrib for given name -pub fn setBooleanAttrib(elementID: i32, name: []const u8, state: bool) void { - return _setBooleanAttrib(elementID, name.ptr, if (state) 1 else 0); +pub fn setBooleanAttrib(elementID: i32, name: [*:0]const u8, state: bool) void { + return _setBooleanAttrib(elementID, name, if (state) 1 else 0); } -pub extern "dom" fn _getBooleanAttrib(elementID: i32, name: [*]const u8) u8; +pub extern "dom" fn _getBooleanAttrib(elementID: i32, name: [*:0]const u8) u8; /// Returns boolean value of attrib for given name -pub fn getBooleanAttrib(elementID: i32, name: []const u8) bool { - return if (_getBooleanAttrib(elementID, name.ptr) != 0) true else false; +pub fn getBooleanAttrib(elementID: i32, name: [*:0]const u8) bool { + return if (_getBooleanAttrib(elementID, name) != 0) true else false; } -pub extern "dom" fn _addClass(elementID: i32, name: [*]const u8) void; +pub extern "dom" fn addClass(elementID: i32, name: [*:0]const u8) void; -pub fn addClass(elementID: i32, name: []const u8) void { - _addClass(elementID, name.ptr); -} - -pub extern "dom" fn _removeClass(elementID: i32, name: [*]const u8) void; - -pub fn removeClass(elementID: i32, name: []const u8) void { - _removeClass(elementID, name.ptr); -} +pub extern "dom" fn removeClass(elementID: i32, name: [*:0]const u8) void; -pub extern "dom" fn _setInnerHtml(elementID: i32, html: [*]const u8) void; +// Sets the `.innerHTML` property of a DOM element to given string +pub extern "dom" fn setInnerHtml(elementID: i32, html: [*:0]const u8) void; -/// Sets the `.innerHTML` property of a DOM element to given string -pub fn setInnerHtml(elementID: i32, html: []const u8) void { - _setInnerHtml(elementID, html.ptr); -} - -pub extern "dom" fn _setInnerText(elementID: i32, text: [*]const u8) void; - -/// Sets the `.innerText` property of a DOM element to given string -pub fn setInnerText(elementID: i32, text: []const u8) void { - _setInnerText(elementID, text.ptr); -} +// Sets the `.innerText` property of a DOM element to given string +pub extern "dom" fn setInnerText(elementID: i32, text: [*:0]const u8) void; diff --git a/packages/wasm-api/zig/lib.zig b/packages/wasm-api/zig/lib.zig index 32b127f64a..993b814f35 100644 --- a/packages/wasm-api/zig/lib.zig +++ b/packages/wasm-api/zig/lib.zig @@ -5,7 +5,7 @@ const root = @import("root"); pub const ManagedIndex = @import("managed-index.zig").ManagedIndex; -/// Higher-order slice wrapper for extern struct use cases +/// Higher-order generic slice wrapper for extern struct use cases /// S = slice type /// P = pointer type /// default = point default value