-
-
Notifications
You must be signed in to change notification settings - Fork 139
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WebAssembly API for JavaScript #208
Comments
First things I saw that block this process is this issue from |
Yes, this is known and I have a feature |
Ha nice 👍 |
Never mind. By the way, if you are interested in a WebAssembly/JavaScript API for handlebars, feel free to discuss here. Things I have been thinking about:
|
In recent days I have tried to wrap Here is the code: use handlebars::{
Context, Handlebars as Registry, Helper, HelperDef, HelperResult, Output, RenderContext,
RenderError,
};
use js_sys::Function;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub struct HelperOptions {
template_ctx: JsValue,
inverse_ctx: JsValue,
}
#[allow(clippy::new_without_default)]
#[wasm_bindgen]
impl HelperOptions {
pub fn new() -> Self {
HelperOptions {
template_ctx: JsValue::undefined(),
inverse_ctx: JsValue::undefined(),
}
}
pub fn template(&mut self, ctx: JsValue) -> String {
self.template_ctx = ctx;
"$$TEMPLATE$$".to_string()
}
pub fn inverse(&mut self, ctx: JsValue) -> String {
self.inverse_ctx = ctx;
"$$INVERSE$$".to_string()
}
}
pub struct JsHelper {
pub js_fn_tpl: String,
}
impl HelperDef for JsHelper {
fn call<'reg: 'rc, 'rc>(
&self,
h: &Helper<'reg, 'rc>,
_: &'reg Registry<'reg>,
_: &'rc Context,
_: &mut RenderContext<'reg, 'rc>,
out: &mut dyn Output,
) -> HelperResult {
// Change function template to actual js function
let js_fn = Function::new_no_args(&self.js_fn_tpl);
let js_helper = Function::from(js_fn.call0(&JsValue::null()).unwrap());
let value = h
.param(0)
.ok_or_else(|| RenderError::new("Param not found in js helper"))
.unwrap();
let data = JsValue::from_serde(value.value()).unwrap();
let options = HelperOptions::new();
let result = js_helper
.call2(&JsValue::null(), &data, &options.into())
.unwrap();
let result = result.as_string().unwrap();
out.write(result.as_str())?;
Ok(())
}
} And we can hack the js callback param 😂 Not sure if it is the "best practices" or just a “trick”. Do y'all have a suggested workaround for this? |
Perhaps we can use |
🤔 Ah, I have tried but it does not work, because the Maybe we can use a static to hold that information, but for me it is another complicated workaround. Is it possible to ask you to provide more details about it? |
I see. The data exchange between js and webassembly still requires some hack. I would prefer some result string/code for |
Yep, if you have plans to add this feature, let me know if you need a hand. |
Thank you! This feature is welcomed. Do you have a full example of your current usage of this library via wasm and javascript? I'm just wondering the scenario of defining helpers via javascript. |
Not yet. But I think the first step is to do some performance test for the |
We are also considering using this library as a (wasm) replacement for handlebars.js, as handlebars.js requires unsafe-eval and therefore will not be possible to use in MV3 extensions at least on firefox. But we need to have as-close-as-possible support for existing users and all their handlebars scripts, so cannot easily drop in another library. This would require being able to use our existing JS helpers, or reimplementing all of those in Rust, which might be difficult/impossible. |
Finally we have (wasm-bindgen)[https://github.com/alexcrichton/wasm-bindgen] to expose Rust struct to JavaScript, so we should be able to create
Handlebars
instance from JavaScript, and call any API from it.This has made it possible to create a JavaScript interface for handlebars-rust. The next step will be allowing JavaScript implemented helpers and directives being registered in handlebars-rust.
The text was updated successfully, but these errors were encountered: