//go:build wasm //:build wasm package dom import ( "git.smesh.lol/smesh/web/common/jsbridge/callback" "unsafe" ) // --- Element creation/query --- //:wasmimport bridge dom_body func wasmBody() (n int32) //:wasmimport bridge dom_create_element func wasmCreateElement(ptr *byte, len int32, cap int32) (n int32) //:wasmimport bridge dom_create_text_node func wasmCreateTextNode(ptr *byte, len int32, cap int32) (n int32) //:wasmimport bridge dom_get_element_by_id func wasmGetElementById(ptr *byte, len int32, cap int32) (n int32) //:wasmimport bridge dom_query_selector func wasmQuerySelector(ptr *byte, len int32, cap int32) (n int32) //:wasmimport bridge dom_query_selector_from func wasmQuerySelectorFrom(root int32, ptr *byte, len int32, cap int32) (n int32) func Body() (e Element) { return Element(wasmBody()) } func CreateElement(tag string) (e Element) { return Element(wasmCreateElement(unsafe.StringData(tag), int32(len(tag)), int32(len(tag)))) } func CreateTextNode(text string) (e Element) { return Element(wasmCreateTextNode(unsafe.StringData(text), int32(len(text)), int32(len(text)))) } func GetElementById(id string) (e Element) { return Element(wasmGetElementById(unsafe.StringData(id), int32(len(id)), int32(len(id)))) } func QuerySelector(sel string) (e Element) { return Element(wasmQuerySelector(unsafe.StringData(sel), int32(len(sel)), int32(len(sel)))) } func QuerySelectorFrom(root Element, sel string) (e Element) { return Element(wasmQuerySelectorFrom(int32(root), unsafe.StringData(sel), int32(len(sel)), int32(len(sel)))) } // --- Tree manipulation --- //:wasmimport bridge dom_append_child func wasmAppendChild(parent int32, child int32) //:wasmimport bridge dom_remove_child func wasmRemoveChild(parent int32, child int32) //:wasmimport bridge dom_remove func wasmRemove(el int32) //:wasmimport bridge dom_insert_before func wasmInsertBefore(parent int32, newChild int32, refChild int32) //:wasmimport bridge dom_first_child func wasmFirstChild(el int32) (n int32) //:wasmimport bridge dom_first_element_child func wasmFirstElementChild(el int32) (n int32) //:wasmimport bridge dom_next_sibling func wasmNextSibling(el int32) (n int32) //:wasmimport bridge dom_release_element func wasmReleaseElement(el int32) //:wasmimport bridge dom_release_all func wasmReleaseAll(ptr *int32, len int32) func AppendChild(parent, child Element) { wasmAppendChild(int32(parent), int32(child)) } func RemoveChild(parent, child Element) { wasmRemoveChild(int32(parent), int32(child)) } func Remove(el Element) { wasmRemove(int32(el)) } func InsertBefore(parent, newChild, refChild Element) { wasmInsertBefore(int32(parent), int32(newChild), int32(refChild)) } func FirstChild(el Element) (e Element) { return Element(wasmFirstChild(int32(el))) } func FirstElementChild(el Element) (e Element) { return Element(wasmFirstElementChild(int32(el))) } func NextSibling(el Element) (e Element) { return Element(wasmNextSibling(int32(el))) } func ReleaseElement(el Element) { wasmReleaseElement(int32(el)) } func ReleaseAll(ids []int32) { if len(ids) > 0 { wasmReleaseAll(&ids[0], int32(len(ids))) } } //:wasmimport bridge dom_release_children func wasmReleaseChildren(el int32) func ReleaseChildren(el Element) { wasmReleaseChildren(int32(el)) } // --- Attributes and content --- //:wasmimport bridge dom_set_attribute func wasmSetAttribute(el int32, nPtr *byte, nLen int32, nCap int32, vPtr *byte, vLen int32, vCap int32) //:wasmimport bridge dom_remove_attribute func wasmRemoveAttribute(el int32, nPtr *byte, nLen int32, nCap int32) //:wasmimport bridge dom_get_attribute func wasmGetAttribute(el int32, nPtr *byte, nLen int32, nCap int32, outPtr *int32, outLen *int32) //:wasmimport bridge dom_set_text_content func wasmSetTextContent(el int32, ptr *byte, len int32, cap int32) //:wasmimport bridge dom_set_inner_html func wasmSetInnerHTML(el int32, ptr *byte, len int32, cap int32) //:wasmimport bridge dom_set_style func wasmSetStyle(el int32, pPtr *byte, pLen int32, pCap int32, vPtr *byte, vLen int32, vCap int32) //:wasmimport bridge dom_add_class func wasmAddClass(el int32, ptr *byte, len int32, cap int32) //:wasmimport bridge dom_remove_class func wasmRemoveClass(el int32, ptr *byte, len int32, cap int32) //:wasmimport bridge dom_focus func wasmFocus(el int32) //:wasmimport bridge dom_set_property func wasmSetProperty(el int32, pPtr *byte, pLen int32, pCap int32, vPtr *byte, vLen int32, vCap int32) //:wasmimport bridge dom_get_property func wasmGetProperty(el int32, pPtr *byte, pLen int32, pCap int32, outPtr *int32, outLen *int32) func SetAttribute(el Element, name, value string) { wasmSetAttribute(int32(el), unsafe.StringData(name), int32(len(name)), int32(len(name)), unsafe.StringData(value), int32(len(value)), int32(len(value))) } func RemoveAttribute(el Element, name string) { wasmRemoveAttribute(int32(el), unsafe.StringData(name), int32(len(name)), int32(len(name))) } func GetAttribute(el Element, name string) (s string) { var rPtr, rLen int32 wasmGetAttribute(int32(el), unsafe.StringData(name), int32(len(name)), int32(len(name)), &rPtr, &rLen) return ptrToString(rPtr, rLen) } func SetTextContent(el Element, text string) { wasmSetTextContent(int32(el), unsafe.StringData(text), int32(len(text)), int32(len(text))) } func SetInnerHTML(el Element, html string) { wasmSetInnerHTML(int32(el), unsafe.StringData(html), int32(len(html)), int32(len(html))) } func SetStyle(el Element, prop, value string) { wasmSetStyle(int32(el), unsafe.StringData(prop), int32(len(prop)), int32(len(prop)), unsafe.StringData(value), int32(len(value)), int32(len(value))) } func AddClass(el Element, cls string) { wasmAddClass(int32(el), unsafe.StringData(cls), int32(len(cls)), int32(len(cls))) } func RemoveClass(el Element, cls string) { wasmRemoveClass(int32(el), unsafe.StringData(cls), int32(len(cls)), int32(len(cls))) } func Focus(el Element) { wasmFocus(int32(el)) } func SetProperty(el Element, prop, value string) { wasmSetProperty(int32(el), unsafe.StringData(prop), int32(len(prop)), int32(len(prop)), unsafe.StringData(value), int32(len(value)), int32(len(value))) } func GetProperty(el Element, prop string) (s string) { var rPtr, rLen int32 wasmGetProperty(int32(el), unsafe.StringData(prop), int32(len(prop)), int32(len(prop)), &rPtr, &rLen) return ptrToString(rPtr, rLen) } // --- Geometry --- //:wasmimport bridge dom_bounding_client_left func wasmBoundingClientLeft(el int32) (n int32) //:wasmimport bridge dom_get_bounding_rect func wasmGetBoundingRect(el int32, cbID int32) //:wasmimport bridge dom_get_viewport_height func wasmGetViewportHeight() (n int32) //:wasmimport bridge dom_get_viewport_width func wasmGetViewportWidth() (n int32) func BoundingClientLeft(el Element) (n int32) { return wasmBoundingClientLeft(int32(el)) } func GetBoundingRect(el Element, fn func(int32, int32, int32, int32, int32, int32)) { wasmGetBoundingRect(int32(el), callback.Register6IOnce(fn)) } func GetViewportHeight() (n int32) { return wasmGetViewportHeight() } func GetViewportWidth() (n int32) { return wasmGetViewportWidth() } // --- Callbacks and events --- //:wasmimport bridge dom_add_event_listener func wasmAddEventListener(el int32, evPtr *byte, evLen int32, evCap int32, cbID int32) //:wasmimport bridge dom_add_self_event_listener func wasmAddSelfEventListener(el int32, evPtr *byte, evLen int32, evCap int32, cbID int32) //:wasmimport bridge dom_add_enter_key_listener func wasmAddEnterKeyListener(el int32, cbID int32) //:wasmimport bridge dom_remove_event_listener func wasmRemoveEventListener(el int32, evPtr *byte, evLen int32, evCap int32, cbID int32) //:wasmimport bridge dom_observe_resize func wasmObserveResize(el int32, cbID int32) //:wasmimport bridge dom_unobserve_resize func wasmUnobserveResize(el int32) //:wasmimport bridge dom_request_animation_frame func wasmRequestAnimationFrame(cbID int32) func RegisterCallback(fn func()) (n int32) { return callback.Register0(fn) } func ReleaseCallback(id int32) { callback.Release(id) } func AddEventListener(el Element, event string, callbackId int32) { wasmAddEventListener(int32(el), unsafe.StringData(event), int32(len(event)), int32(len(event)), callbackId) } func AddSelfEventListener(el Element, event string, callbackId int32) { wasmAddSelfEventListener(int32(el), unsafe.StringData(event), int32(len(event)), int32(len(event)), callbackId) } func AddEnterKeyListener(el Element, callbackId int32) { wasmAddEnterKeyListener(int32(el), callbackId) } func RemoveEventListener(el Element, event string, callbackId int32) { wasmRemoveEventListener(int32(el), unsafe.StringData(event), int32(len(event)), int32(len(event)), callbackId) } func ObserveResize(el Element, callbackId int32) { wasmObserveResize(int32(el), callbackId) } func UnobserveResize(el Element) { wasmUnobserveResize(int32(el)) } func RequestAnimationFrame(fn func()) { wasmRequestAnimationFrame(callback.Register0Once(fn)) } // OnKeydown has a nested callback: fn(key, preventDefault). // Uses a custom hook so preventDefault can be signaled synchronously. var keydownHandlers = map[int32]func(string, func()){} var keydownNextID int32 = 1 //:wasmimport bridge dom_on_keydown func wasmOnKeydown(el int32, handlerID int32) func OnKeydown(el Element, fn func(string, func())) { id := keydownNextID keydownNextID++ keydownHandlers[id] = fn wasmOnKeydown(int32(el), id) } //:wasmexport __hook_keydown func hookKeydown(handlerID int32, keyPtr *byte, keyLen int32) (n int32) { fn, ok := keydownHandlers[handlerID] if !ok { return 0 } key := ptrToStringLocal(keyPtr, keyLen) prevented := int32(0) fn(key, func() { prevented = 1 }) return prevented } // --- Mention chips --- //:wasmimport bridge dom_insert_mention_chip func wasmInsertMentionChip(el int32, charCount int32, npubPtr *byte, npubLen int32, npubCap int32, namePtr *byte, nameLen int32, nameCap int32, picPtr *byte, picLen int32, picCap int32) func InsertMentionChip(el Element, charCount int32, npub, name, pic string) { wasmInsertMentionChip(int32(el), int32(charCount), unsafe.StringData(npub), int32(len(npub)), int32(len(npub)), unsafe.StringData(name), int32(len(name)), int32(len(name)), unsafe.StringData(pic), int32(len(pic)), int32(len(pic))) } // --- Timers --- //:wasmimport bridge dom_set_timeout func wasmSetTimeout(cbID int32, ms int32) (n int32) //:wasmimport bridge dom_clear_timeout func wasmClearTimeout(id int32) func SetTimeout(fn func(), ms int32) (n int32) { return wasmSetTimeout(callback.Register0Once(fn), ms) } func ClearTimeout(id int32) { wasmClearTimeout(id) } // --- Fetch --- //:wasmimport bridge dom_fetch_text func wasmFetchText(ptr *byte, len int32, cap int32, cbID int32) //:wasmimport bridge dom_fetch_relay_info func wasmFetchRelayInfo(ptr *byte, len int32, cap int32, cbID int32) //:wasmimport bridge dom_fetch_put_blob_base64 func wasmFetchPutBlobBase64(urlPtr *byte, urlLen int32, urlCap int32, dataPtr *byte, dataLen int32, dataCap int32, ctPtr *byte, ctLen int32, ctCap int32, authPtr *byte, authLen int32, authCap int32, cbID int32) func FetchText(url string, fn func(string)) { wasmFetchText(unsafe.StringData(url), int32(len(url)), int32(len(url)), callback.RegisterSOnce(fn)) } func FetchRelayInfo(url string, fn func(string)) { wasmFetchRelayInfo(unsafe.StringData(url), int32(len(url)), int32(len(url)), callback.RegisterSOnce(fn)) } func FetchPutBlobBase64(url, base64data, contentType, authHeader string, fn func(string)) { wasmFetchPutBlobBase64( unsafe.StringData(url), int32(len(url)), int32(len(url)), unsafe.StringData(base64data), int32(len(base64data)), int32(len(base64data)), unsafe.StringData(contentType), int32(len(contentType)), int32(len(contentType)), unsafe.StringData(authHeader), int32(len(authHeader)), int32(len(authHeader)), callback.RegisterSOnce(fn)) } // --- IDB --- //:wasmimport bridge dom_idb_set_enc_key func wasmIDBSetEncKey(ptr *byte, len int32, cap int32) //:wasmimport bridge dom_idb_get func wasmIDBGet(storePtr *byte, storeLen int32, storeCap int32, keyPtr *byte, keyLen int32, keyCap int32, cbID int32) //:wasmimport bridge dom_idb_put func wasmIDBPut(storePtr *byte, storeLen int32, storeCap int32, keyPtr *byte, keyLen int32, keyCap int32, valPtr *byte, valLen int32, valCap int32) //:wasmimport bridge dom_idb_get_all func wasmIDBGetAll(storePtr *byte, storeLen int32, storeCap int32, fnID int32, doneID int32) func IDBSetEncKey(hexKey string) { wasmIDBSetEncKey(unsafe.StringData(hexKey), int32(len(hexKey)), int32(len(hexKey))) } func IDBGet(store, key string, fn func(string)) { wasmIDBGet( unsafe.StringData(store), int32(len(store)), int32(len(store)), unsafe.StringData(key), int32(len(key)), int32(len(key)), callback.RegisterSOnce(fn)) } func IDBPut(store, key, value string) { wasmIDBPut( unsafe.StringData(store), int32(len(store)), int32(len(store)), unsafe.StringData(key), int32(len(key)), int32(len(key)), unsafe.StringData(value), int32(len(value)), int32(len(value))) } func IDBGetAll(store string, fn func(string, string), done func()) { fnID := callback.RegisterSS(fn) doneID := callback.Register0Once(func() { callback.Release(fnID) done() }) wasmIDBGetAll(unsafe.StringData(store), int32(len(store)), int32(len(store)), fnID, doneID) } // --- Browser state --- //:wasmimport bridge dom_prefers_dark func wasmPrefersDark() (n int32) //:wasmimport bridge dom_console_log func wasmConsoleLog(ptr *byte, len int32, cap int32) //:wasmimport bridge dom_confirm func wasmConfirm(ptr *byte, len int32, cap int32) (n int32) //:wasmimport bridge dom_post_to_sw func wasmPostToSW(ptr *byte, len int32, cap int32) //:wasmimport bridge dom_on_sw_message func wasmOnSWMessage(cbID int32) //:wasmimport bridge dom_push_state func wasmPushState(ptr *byte, len int32, cap int32) //:wasmimport bridge dom_replace_state func wasmReplaceState(ptr *byte, len int32, cap int32) //:wasmimport bridge dom_back func wasmBack() //:wasmimport bridge dom_location_reload func wasmLocationReload() //:wasmimport bridge dom_location_assign func wasmLocationAssign(ptr *byte, len int32, cap int32) //:wasmimport bridge dom_hard_refresh func wasmHardRefresh() //:wasmimport bridge dom_clear_storage_prefix func wasmClearStoragePrefix(ptr *byte, len int32, cap int32) //:wasmimport bridge dom_timezone_offset_seconds func wasmTimezoneOffsetSeconds() (n int32) //:wasmimport bridge dom_read_clipboard func wasmReadClipboard(cbID int32) //:wasmimport bridge dom_write_clipboard func wasmWriteClipboard(ptr *byte, len int32, cap int32, cbID int32) //:wasmimport bridge dom_get_path func wasmGetPath(outPtr *int32, outLen *int32) //:wasmimport bridge dom_get_hash func wasmGetHash(outPtr *int32, outLen *int32) //:wasmimport bridge dom_hostname func wasmHostname(outPtr *int32, outLen *int32) //:wasmimport bridge dom_port func wasmPort(outPtr *int32, outLen *int32) //:wasmimport bridge dom_user_agent func wasmUserAgent(outPtr *int32, outLen *int32) //:wasmimport bridge dom_on_pop_state func wasmOnPopState(cbID int32) //:wasmimport bridge dom_intercept_internal_links func wasmInterceptInternalLinks(cbID int32) //:wasmimport bridge dom_pick_file_text func wasmPickFileText(ptr *byte, len int32, cap int32, cbID int32) //:wasmimport bridge dom_download_text func wasmDownloadText(fnPtr *byte, fnLen int32, fnCap int32, ctPtr *byte, ctLen int32, ctCap int32, mtPtr *byte, mtLen int32, mtCap int32) //:wasmimport bridge dom_on_pull_refresh func wasmOnPullRefresh(el int32, indicator int32, cbID int32) //:wasmimport bridge dom_now_seconds func wasmNowSeconds() (n int64) //:wasmimport bridge dom_pick_file_base64 func wasmPickFileBase64(ptr *byte, len int32, cap int32, cbID int32) //:wasmimport bridge dom_on_paste_image func wasmOnPasteImage(el int32, cbID int32) //:wasmimport bridge dom_on_drop_image func wasmOnDropImage(el int32, cbID int32) func PrefersDark() (ok bool) { return wasmPrefersDark() != 0 } func ConsoleLog(msg string) { wasmConsoleLog(unsafe.StringData(msg), int32(len(msg)), int32(len(msg))) } func Confirm(msg string) (ok bool) { return wasmConfirm(unsafe.StringData(msg), int32(len(msg)), int32(len(msg))) != 0 } func PostToSW(msg string) { wasmPostToSW(unsafe.StringData(msg), int32(len(msg)), int32(len(msg))) } func OnSWMessage(fn func(string)) { wasmOnSWMessage(callback.RegisterS(fn)) } func PushState(path string) { wasmPushState(unsafe.StringData(path), int32(len(path)), int32(len(path))) } func ReplaceState(path string) { wasmReplaceState(unsafe.StringData(path), int32(len(path)), int32(len(path))) } func Back() { wasmBack() } func LocationReload() { wasmLocationReload() } func LocationAssign(url string) { wasmLocationAssign(unsafe.StringData(url), int32(len(url)), int32(len(url))) } func HardRefresh() { wasmHardRefresh() } func ClearStoragePrefix(prefix string) { wasmClearStoragePrefix(unsafe.StringData(prefix), int32(len(prefix)), int32(len(prefix))) } func TimezoneOffsetSeconds() (n int32) { return wasmTimezoneOffsetSeconds() } func ReadClipboard(fn func(string)) { wasmReadClipboard(callback.RegisterSOnce(fn)) } func WriteClipboard(text string, fn func(bool)) { wasmWriteClipboard(unsafe.StringData(text), int32(len(text)), int32(len(text)), callback.RegisterBOnce(fn)) } //:wasmimport bridge dom_write_primary_selection func wasmWritePrimarySelection(ptr *byte, len int32, cap int32) func WritePrimarySelection(text string) { wasmWritePrimarySelection(unsafe.StringData(text), int32(len(text)), int32(len(text))) } //:wasmimport bridge dom_copy_image_to_clipboard func wasmCopyImageToClipboard(el int32, cbID int32) func CopyImageToClipboard(el Element, fn func(bool)) { wasmCopyImageToClipboard(int32(el), callback.RegisterBOnce(fn)) } //:wasmimport bridge dom_window_open func wasmWindowOpen(ptr *byte, len int32, cap int32) func WindowOpen(url string) { wasmWindowOpen(unsafe.StringData(url), int32(len(url)), int32(len(url))) } //:wasmimport bridge dom_encode_uri_component func wasmEncodeURIComponent(ptr *byte, len int32, cap int32, rPtr *int32, rLen *int32) func EncodeURIComponent(s string) (sv string) { var rPtr, rLen int32 wasmEncodeURIComponent(unsafe.StringData(s), int32(len(s)), int32(len(s)), &rPtr, &rLen) return ptrToString(rPtr, rLen) } func GetPath() (s string) { var rPtr, rLen int32 wasmGetPath(&rPtr, &rLen) return ptrToString(rPtr, rLen) } func GetHash() (s string) { var rPtr, rLen int32 wasmGetHash(&rPtr, &rLen) return ptrToString(rPtr, rLen) } func Hostname() (s string) { var rPtr, rLen int32 wasmHostname(&rPtr, &rLen) return ptrToString(rPtr, rLen) } func Port() (s string) { var rPtr, rLen int32 wasmPort(&rPtr, &rLen) return ptrToString(rPtr, rLen) } func UserAgent() (s string) { var rPtr, rLen int32 wasmUserAgent(&rPtr, &rLen) return ptrToString(rPtr, rLen) } func OnPopState(fn func(string)) { wasmOnPopState(callback.RegisterS(fn)) } func InterceptInternalLinks(fn func(string)) { wasmInterceptInternalLinks(callback.RegisterS(fn)) } func PickFileText(accept string, fn func(string)) { wasmPickFileText(unsafe.StringData(accept), int32(len(accept)), int32(len(accept)), callback.RegisterSOnce(fn)) } func DownloadText(filename, content, mimeType string) { wasmDownloadText( unsafe.StringData(filename), int32(len(filename)), int32(len(filename)), unsafe.StringData(content), int32(len(content)), int32(len(content)), unsafe.StringData(mimeType), int32(len(mimeType)), int32(len(mimeType))) } func OnPullRefresh(el Element, indicator Element, fn func()) { wasmOnPullRefresh(int32(el), int32(indicator), callback.Register0(fn)) } func NowSeconds() (n int64) { return wasmNowSeconds() } func PickFileBase64(accept string, fn func(string, string)) { wasmPickFileBase64(unsafe.StringData(accept), int32(len(accept)), int32(len(accept)), callback.RegisterSSOnce(fn)) } func OnPasteImage(el Element, fn func(string, string)) { wasmOnPasteImage(int32(el), callback.RegisterSS(fn)) } func OnDropImage(el Element, fn func(string, string)) { wasmOnDropImage(int32(el), callback.RegisterSS(fn)) } func ptrToString(ptr int32, length int32) (s string) { if length <= 0 { return "" } return unsafe.String((*byte)(unsafe.Pointer(uintptr(ptr))), length) } func ptrToStringLocal(ptr *byte, length int32) (s string) { if ptr == nil || length <= 0 { return "" } return unsafe.String(ptr, length) }