General info on the DOM: https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model
examples/ that shows off working with the DOMNot sure if anyone else has run into this problem, but it looks like the webidl crate has issues parsing declarations like interface InterfaceNameHere;
e.g., in Node.webidl:
https://github.com/rustwasm/wasm-bindgen/blob/3578a83fe2a4c2ad9be8bfaa26258a8a646e05ab/crates/web-sys/webidls/available/Node.webidl#L13-L14
Trying to build the web-sys crate with this IDL file in the enabled directory gives an error similar to:
--- stderr
Error: compiling WebIDL into wasm-bindgen bindings
caused by parsing WebIDL source text
caused by Unrecognized token `Semicolon` found at 52348:52349
Expected one of ":" or "{"
I looked in the webidl repo and it seems like it is a known issue, and since these types of declarations don't seem to be officially part of the grammar, the issue is marked as "Won't Fix": https://github.com/sgodwincs/webidl-rs/issues/3
Is there a recommended workaround? (I'm not too familiar with webidl)
@walfie it is fine to just comment it out and leave a comment about why it is commented out.
Node.webidl also has C pre-processor #ifdefs, so we will want to remove those too -- in this particular case, I think we want to assume that the #ifdef's condition is false and remove the things within it as well.
@walfie : The same error occurs when adding WebSocket.webidl to available folder
--- stderr
Error: compiling WebIDL into wasm-bindgen bindings
caused by parsing WebIDL source text
caused by Unrecognized token `Semicolon` found at 3052:3053
Expected one of ":" or "{"
I think there are dependencies on #246 and #241 until those are fixed I don't think many in this list will be possible. For example Element seems possible now, without having tests but to use it and test it needs Document.
it is fine to just comment it out and leave a comment about why it is commented out.
Ah great, this fixes building Document.
However I see that returning DOMString's from functions like Element.getAttribute doesn't work.
crates/webidl/src/util.rs states that return position DOMString doesn't work.
Commenting this out panics:
"thread 'main' panicked at 'procedural macro API is used outside of a procedural macro', libproc_macro/lib.rs:1469:13
...
thread 'main' panicked at 'cannot return references in imports yet`, crates/backend/src/codegen.rs:736:17
from crates/backend/src/codegen.rs.
When I remove this also, I get lifetime issues:
"return type references an anonymous lifetime which is not constrained by the fn input types
--> /.../wasm-bindgen/target/wasm32-unknown-unknown/debug/build/web-sys-439efa030d0a9b16/out/bindings.rs:37:6687"
and according to https://github.com/rustwasm/wasm-bindgen/issues/248#issue-330760118 this seems intended they don't work.
@alexcrichton I see you did the initial work for preventing return DOMStrings, is this considered unsafe or is it just not implemented yet? Some pointers on the issue would be great, I would love to look into it so I can replace a personal project code to use websys.
Oh @fitzgen may have been the one that actually did that work, but for returning a DOMString nowadays I think we have one of two choices: String or JsString. The former is immediately useful within Rust (it's just a plain ol' Rust type!) but the latter can be more efficient in some circumstances by avoiding copying. I'd personally lean towards just returning a bare String, personally. (but yes, returning &str is a no-go)
I think we actually want to switch to using JsString and let users decide whether they want to make a copy or not. We shouldn't be doing potentially expensive operations implicitly behind the scenes.
This fits with the philosophy of web-sys being thin, zero-cost bindings that don't attempt to push ergonomics or conventions that we've been talking about in https://github.com/rustwasm/rfcs/pull/2
preventing return DOMStrings, is this considered unsafe or is it just not implemented yet?
FWIW, returning String was not implemented at the time that code was written, nor was JsString.
Oh so one thing I just remembered is this possible feature in the host bindings proposal which means that we shouldn't be using anyref for these APIs (the equivalent of JsValue or JsString) and should instead be using String, because that way when we call into the C++ engine it directly has the pointer/length.
In that sense if we use &str for arguments there's already no copying in Rust and it just copies in to JS on the JS side of things (currently). Eventually with host bindings that wouldn't be the case (in theory) I believe
Rust strings are al;ways UTF-8, but JS strings (and I thought DOMStrings, but I am less sure) are UCS-2-with-mismatched-surrogates. It seems like we would need a new Rust String type (or re-use OsString?) that matches what the DOM expects. Which also sounds like a bit of a mess.
True, but it looks like host bindings account for this in that they define strings as utf-8.
It naively looks like host bindings are enabling functionality that's fundamentally not possible in JS today (like calling things with utf-8 trings), which would be nice! I'm not sure how much of that host bindings proposal is slated for inclusion though.
@alexcrichton + @fitzgen - I was trying to get this to work and I finally got it to compile and run tests (I barely understand how wasm-bindgen works tbh) and got the following methods working on Element:
get_attribute, get_attribute_ns, toggle_attribute, set_attribute, set_attribute_ns, remove_attribute, remove_attribute_ns, has_attribute, has_attribute_ns, has_attributes
https://github.com/jonathanKingston/wasm-bindgen/commit/6d6a87bbcbf6e139700a17959afab32c9749351a#diff-36286bf7018525389e71dc45dc3ea135
Partial interfaces don't work and returning DOMString from getters also doesn't work either so there is still a lot of important missing features like tag_name, query_selector and closest.
Is the utils modifications in the right direction to what you were both suggesting?
@jonathanKingston I think that's close yeah! Whether we choose JsValue or String I think we'll want to be consistent (make sure to use one or the other in various cases). I think you've also bound optional strings, right? Should those be wrapped in Option?
Cool, I just implemented the Option wrapper I wasn't sure how Result worked at the time. https://github.com/jonathanKingston/wasm-bindgen/commit/1e0c24f912572193f78435ddd44b3656cf8992b0#diff-36286bf7018525389e71dc45dc3ea135 Although I think additional work is likely required for solving #14 and more tests etc.
This now outputs:
pub fn get_attribute_ns(
聽聽聽聽&self,
聽聽聽聽namespace: Option<&str>,
聽聽聽聽local_name: &str) -> Option<JsValue>
Are you suggesting the return type and parameter types should match (or just the nullable match the non-nullable)?
Thanks
Oh nah I was mostly suggesting in the sense that on one path it'd return Option<JsValue> whereas on the other path it'd return String. It's ok to not expect an argument &str to match a return of String!
I should also point out that optional arguments largely aren't implemented today so that may want to hold off a bit for now
I removed the Optional changes in the current PR but it looks like #507 adds the code to make this actually work. I can try this out once both get landed.
Ah so I was motivated to start working on Option as it looked like it was showing up in return values in a few places, but I think it's still a viable alternative to generate different versions of functions for optional arguments. We can also explore both to see which is preferred!
@alexcrichton that might be nice, I dunno how you would name the functions though. Also there are a few namespace functions that take optional arguments halfway in the function that you likely would want to avoid this process for.
There is dom example in the guide: https://rustwasm.github.io/docs/wasm-bindgen/examples/dom.html
Does it solve this issue?
Yep! Thanks @ibaryshnikov :)