They wanted to implement a typing system first so they could transfer complex types with a strict contract first, as large parts of DOM management would benefit enormously from that, and it would be far better to design an API around. This system has been stuck in different iterations for years.
Because it's already solved from day one and people keep repeating that it's a problem anyways.
Anything you can do in JavaScript, including access to the DOM, can be put into a JavaScript function. You can import that function into a WebAssembly Module, and you can use WebAssembly Memory to transfer large or complicated data as an efficient side channel. It all works.
Could you link an ergonomic example? I have cemented in my memory that DOM access in WebAssembly is not trivial and I suspect others too.
This is what StackOverflow tells me (2020):
> Unfortunately, the DOM can only be accessed within the browser's main JavaScript thread. Service Workers, Web Workers, and Web Assembly modules would not have DOM access. The closest manipulation you'll get from WASM is to manipulate state objects that are passed to and rendered by the main thread with state-based UI components like Preact/React.
> JSON serialization is most often used to pass state with postMessage() or Broadcast Channels. Bitpacking or binary objects could be used with Transferrable ArrayBuffers for more performant messages that avoid the JSON serialization/deserialization overhead.
This feels like "we can have DOM access at home" meme.
Web Workers can't directly access the DOM in JavaScript either. This is not a WebAssembly problem. If you want a Web Worker to manipulate your document, you're going to post events back and forth to the main thread, and Web Assembly could call imported functions to do that too.
I don't even know what he's on about with Preact/React...
Save the following as "ergonomic.html" and you'll see that WebAssembly is manipulating the DOM.
That `easy(arg)` function could do much more elaborate things, and you could pass lots of data in and out using the memory export.
I'd like to believe a simple standalone example like this would be enough to get people to shutup about the DOM thing, but I know better. It'll be the same people who think you need to link with all of SDL in an Emscripten project in order to draw a line on a canvas.
> This feels like "we can have DOM access at home" meme.
And I'm sure somebody (maybe you) will try to move the goal posts and claim some other meme applies.
> I don't even know what he's on about with Preact/React...
Around 10 years ago, I was having lunch in a food court and overheard "Luckily I don't have to use javascript, just jquery".
Around 5 years ago, a co-worker admitted he still had issues distinguishing what functionality was python and what came from Django (web framework), despite having used them both daily for years. He thought it was because he learned both at the same time.
I wouldn't be surprised if this was more of the same, and just getting worse as we pile more and more abstractions on top.
but what bothers me a bit is that this example still uses custom javascript code.
i tried to find and answer but essentially what appears to be missing is the ability to access js objects from wasm. to access the document object it looks like i need a wrapper function in js:
jsdocument(prop, arg){
document[prop](arg)
}
so far so good, i can import this jsdocument() function and use it to all any property on the document object, but if document[fun](arg) returns another DOM object, then what?
i can call this function with the arguments ("getElementById", "foo", "append", "<div>more foo</div>") in any WASM language and it will result in calling document.getElementById("foo").append("<div>more foo</div>"); which allows some basic DOM manipulation already. but then i want to continue with that object so maybe i can do this:
getDOMobj(prop, arg){
var len = objlist.push(document[prop](arg))
return len-1;
}
callDOMobj(pos, prop, arg){
objlist[pos]["prop"](arg)
}
can you see what i am getting at here? building up some kind of API that allows me to access and manipulate any DOM object via a set of functions that i can import into WASM to work around the fact that i can't access document and other objects directly. it looks like this is similar to this answer here: https://stackoverflow.com/a/53958939
solving this problem is what i mean when i ask for direct access to the DOM. i believe such an interface should be written only once so that everyone can use it without having to reinvent it like it appears to be necessary at the moment.
> i'd also like to thank you for patiently answering all the questions
It's nice of you to say so. Thank you.
> can you see what i am getting at here?
I mostly can, but I'm not sure we're clear what we're talking about yet.
I see a lot of people who repeat something about "WebAssembly isn't usable because it can't manipulate the DOM". Ok, so I show an example of WebAssembly manipulating the DOM. That should put that to rest, right? If not, I'm curious what they meant.
> building up some kind of API that allows me to access and manipulate any DOM object via a set of functions that i can import into WASM to work around the fact that i can't access document and other objects directly,
This is a shortcoming in the language implementation, or the library for the language. The machinery is already there at the WebAssembly level. If your language is low level (Rust, C, or C++), and doesn't have what you want, you could roll your own. If your language is high level (Python or Lua), you're at the mercy of the person who built your version of Python.
The core of WebAssembly is a lot like a CPU. It's analogous to AMD64 or AArch64. It'd be weird to say you need changes to your CPU just to use a function called `getElementByName()` or `setAttribute()`. Some WebAssembly extensions have added features to make that "CPU" more like a Java style virtual machine. There are (or will be) garbage collected references to strings, arrays, and structs. This might make it better for implementing Go and Java style languages, and it could help with a fresh implementation of Python or Pike too. And maybe some of those changes will give controlled access to JavaScript style objects.
There's a last discussion to be had about performance. Maybe the bridge between WebAssembly imports and exports is too slow for intensive use. That's a debate that should be backed up with benchmarks of creative solutions. Maybe accessing JavaScript strings is so common, so important, and so slow that it really does require an enhancement to the standard.
i am talking about a js library of generic functions that can be imported from wasm to make DOM access easier. handling of string arguments still needs to be solved (i am guessing the shared memory access is the right place for that) and the respective functions on the wasm side need to be implemented for each target language so that DOM access in the target language becomes natural and easy to use.
Thanks for confirming that WebAssembly still cannot manipulate DOM in 2024.
It can only call custom javascript functions that manipulate DOM AND I need to write some arcane function signature language for every DOM manipulating function I want to call.
I'll give another 4 years and see if they fixed this.
The current active proposal for it is the Component Model: https://component-model.bytecodealliance.org/design/why-comp....