 I'll be talking about using Uno in JavaScript with a LibreOfficeWebAssembly in browser LibreOffice. Okay, kind of weird, went weird with the title there. So basically what I mean there is, there is LibreOfficeWebAssembly, which is this allotropial-led initiative, which parts LibreOffice to the web. But it's not like the one, you know, the LibreOffice online-over-online type of way. This one is natively client-sided running in the browser. Right now, it runs natively in all modern web browsers. It uses Wasm, which is WebAssembly. And to make that happen, there is a toolchain called Msecrypton. And Msecrypton is basically an C++ to Wasm toolchain with all of its bells and whistles. And right now, LibreOfficeWebAssembly utilizes the Qt UI on the web to make it happen. There are lots of talks about it previously from various people. So I'm not going into much detail there. That's just a recap. This talk is about giving LibreOfficeWebAssembly a direct interface in the browser with JavaScript. And this kind of as a prototype right now working. And to make making this happen in the end should enable us to do many new things. For starters, just like you can do macros in basic, you could do that in a JavaScript console in the browser next to the LibreOfficeWebAssembly. And also, like for instance right now, LibreOfficeWebAssembly is using the Qt UI to display stuff altogether. You could tie the JavaScript-based UI framework to all of these you-know-goodness and make your own app that actually utilizes LibreOffice. It could be LibreOffice's own UI too, just that it's now shiny and uses React or some kind of other nice thing that works nicely on the web. Maybe you can put it in the grids, kind of resizes nicely. So lots of things to gain there. Other than that, of course you can take LibreOfficeWebAssembly as some kind of in a headless state or partially rendering stuff state and do your own app that is built with JavaScript, making it all of its calls with JavaScript and natively runs on the web. It could do a conversion of various file types. It could extract lots of different data. You could give people, I don't know, JavaScript forms and when they interact with those forms, it's real-time, it appears with all of LibreOffice's goodness. So people use the forms as they are already accustomed to through a browser with just a few fields and they get immediate preview or you could do some PDF editor, I don't know, I'm just rambling about here and likely you have some ideas yourself too when you have LibreOffice on the web that you can do anything with. So before actually going about how did this actually exactly happen, I want to show you that it works kind of to wet your appetite about it and also show, even though it's quirks, like, even though it has its quirks right now, it is usable. Okay, I can't see nothing, but so I'll just copy some lines over here and talk through them. Okay, this is some scary-looking JavaScript interface to the LibreOffice WebAssembly here. On the left you can see LibreOffice WebAssembly there in the browser and I have just JavaScript console on the right. Let me just zoom out a bit. At the start, this is kind of a hack because not all of the interfaces are bound yet. To get stuff rolling, this is a custom function, getCurrentModel from VeevShell and it just gives us the current model then we can do anything we want with it. We are getting the model and then we are, as if we are doing its own, using C++, doing a UNO query or UNO query. Here it's quite modful, but essentially what's going on is we are creating a text document ref, which is a reference to a text document from C++ and we are just making a UNO call to it, so we are getting the text document, then we are getting the text from it. Right now there is some limitations of the implementation that's hopefully soon begun, that we have to actually query everything like we can't get from derived classes, have derived classes right now, can't really access to its base classes functions directly, so we need to do some additional UNO queries just to make it happen. So from text we are getting simple text and then creating a text cursor from that simple text, creating a text range from it, and finally setting some string there, so I have randomly typed our string here and if you look on the left, hopefully what's going to happen when I run this is before what is the interface there will be string here and that didn't happen. Likely I wasn't able to copy it nicely, there is something there, because it takes a lot of input. Can anyone see anything? Let me just get rid of these, those shouldn't need it. Is there something open that doesn't close? Okay, so there are no new lines here, right? Let me try that again. I'll just press up a couple of times. I tried this many times, it should be there. You should have a working one, or I can just show you another example, because I found this one while going up. Sorry about that. And this one does a similar thing, goes through a while loop, gets all of the paragraphs and assigns a random character color to each of them. It's kind of more fun than that. So on the left you can see all of the paragraphs, changing colors. I don't know what syntax error there for the first time, but I can't really see the screen, sorry about that. So it's basically less to use, uno comments, the interfaces from JavaScript in a quite hefty way. It's not really nice yet. Let me check the time. So how did this happen? There were multiple pathways that could have been taken for binding C++ with JavaScript using M-secrept and Stoolchain. And EM-bind, or M-bind, comes with this toolchain, so that was the natural way to go. But also WebIDL is a kind of interface, definition language, that does stuff more simply. And after looking at these, what I have realized myself was WebIDL implementations actually use M-bind in the end. Under that also WebIDL doesn't support lots of stuff like exceptions like we need. And so that was out of the way. M-bind was a nice option because it gave us Type-secrept bindings, but now EM-bind, or M-bind, they sound so similar, sorry about that. M-bind actually gives us Type-secrept bindings itself too in its new version, so we went with M-bind. And M-bind kind of gives us a boost python like bind semantics. It's relatively popular, M-bind, and it lets us do lots of advanced stuff with our bindings, so it was a nice choice. Also, I haven't really tested this performance myself or any other options, because it wasn't really trivial for me, but according to their documents, the call overhead for simple functions has been measured at about 200 nanoseconds. M-bind actually comes with its own built-in type conversions for trivial stuff from C++, so void is undefined, and boole comes through our fault from char to double, everything is a number, and it also supports different string types itself too. How does the M-bind bindings actually work? So this is a real simple example of how can we bind a C++ function to JavaScript. Basically, this linear lerp function here takes in three floats and returns a float. To bind it, all we have to do is use this M-script in bindings, give our module a name and name the function in quotes. This becomes the JavaScript's call to it, and then we give the reference to lerp. Then on JavaScript, we can just do a module.lerp with some parameters, since M-bind itself handles all types of floats, it is done. If we go a bit further, M-bind also lets us do some classes where we can also create derived classes, but one thing to note here is we can't really do double drives, I mean diamond-style derived classes or multiply-derived, that's the word, multiply-derived classes are not permitted. There are actually types that basically implement this in JavaScript, but at M-bind, they chose not to. So this is kind of a problem for us because in Uno, there are lots of things that are multiply-derived. I'm kind of hoping over it in time. So what do we do with the ideal bindings to make them actually appear in JavaScript? Instead of talking over ideal, I'll directly go to HDR because what we are doing with E-M-bind is we are taking the C++ interface and just translating the JavaScript simply. And so directly looking at the HDL there, and let's just focus on getText for now so that it's not as much on the screen. And you can see that getText takes no parameter and X text range appears to drive from X interface. And how do we bind this? At first, we do class. We give the X text range there, the whole name. We kind of do this with $science.com.store so that there are no name clashes. Hopefully that will not be there soon in the future. And then we bind the method. And just like we see with LERP, we just say that function, name it and give it the reference. And additionally, we don't really use Uno interfaces without wrapping them in references normally, so we need to handle that too. To handle that, what we do is we create a template specialization of that reference and we bind that, we name that the same name as C++, blah, blah, text range, but this time just add a ref at the end so that we know that it's the reference. And we can give some specialized constructors there so that we can use Uno query to get that. And so bind the function there, we use a lambda that actually reaches inside the reference and calls the function itself. We have to give M bind to all of our pointers for this to correctly work. And moving on to make all of these actually work and be accessible to be converted to each other to make Uno reference queries work. We have to do some primary bindings that is kind of prerequisite for all the other ones and we need to, some of them just need a name because we need to know that if something's right from them we can handle them the same way. Like base reference, we don't actually do any implementation inside it. We just say that there's a class called base reference. You should know that we will call it base reference. And for Uno query specialization we use usually enums to just specify the type of query we are doing. We need to kind of do that using this enum under scroll thing. And for anys which we use for setting lots of parameters or handing lots of return types we need to do lots of different handling stuff inside which I redacted here. But we basically can get a JavaScript object inside and depending on the given type class we can try to cast it to that and put it inside and any. This is kind of a special constructor that's kind of hacked there. And this kind of makes it work and also for stuff like always string we do some constructors and hopefully soon sequences and stuff too. And our interface definition language has in out and in out parameters which means they could change for these. And mind actually doesn't really support references into the functions that can change. So we kind of do a hack here. Sorry about that. We kind of do a hack here that we just wrap it in a lambda we just take in their pointers instead of references and bind is okay with raw pointers because it wants stuff to be explicit there and we can just pass it inside with the wrapper function. There's kind of a work around that. So that's one of the things to be used for web ideas references too. So the current state is implemented like this. What's the future plans or ideas? What will this interface will be in the future? So right now even though there was an effort on exceptions don't really work because uno exceptions are not really dynamic so there's a way to catch exceptions from wasm but it directly gives you a pointer and since our uno exceptions are not polymorphic they don't have any attached runtime type information and we can't really get that from that but turns out on the newer versions of embind that we are not using yet there's this possibility to use this recently introduced web assembly features called a tag and we can use this get a cpp exception tag cpp exception thrown value and gets exception message to utilize those to actually handle these I'm not entirely sure how does tag work but as far as I know it appears to be a new section in the wasm binary that defines not only exceptions but special kinds of stuff that kind of coincide with some types so moving on what could we do all of these nasty any conversions that I've shown you and likewise all your string needed its own constructor hopefully all of them could be removed by using this specialized template specializations inside internal and scripted namespace we can do some custom marshalling there and make our types convert to and from JavaScript to C++ on the fly just seamlessly and if you don't want that we can also do the other way we can also make it not do any custom marshalling there and also typescript bindings I kind of mentioned is at the start starting from version 3.144 there are types script binding generations for and bind and we are kind of using an older version of msecrypton so we don't really have that and as far as I as far as I remember Balas said it's kind of trivial to actually bump up to 3.1 so that's good news hopefully we will have some typescript bindings there so we don't need to do lots of gross JavaScript not knowing types business and lastly we need to make the API more JavaScript-ish right now it looks like some kind of C++ interface directly just being called in JavaScript and it is just that hopefully just with more attitude and more opinionated views we can just make that happen and we can make this look like JavaScript, act like JavaScript and do stuff as intended just need some work to do that we can use custom marshalling get rid of those gross naming use type script and generally don't give anything and exposed non-reference stuff just wrap everything in a reference so that's about it from me if you have any questions I guess no time okay thank you