I’m a new juce developer, I added a WebBrowserComponent in my Windows Juce project and loaded html files. I want my app run a javascript function in html file and get the return value. This function is similar to IOS [UIWebView stringByEvaluatingJavaScriptFromString] function, but I don’t know how Juce can support this? Anyone who can give me some suggestion? Thanks
I’m also interested on this, I created a WebBrowserComponent to show a pdf and I’d like to trigger with two juce buttons the funcs “next page” “previous page”
@Ayra You can put it inside JUCE’s HWNDComponent (Windows) / NSViewComponent (Mac) / UIViewComponent (iOS).
And then call setHWND(webView.getViewHandle()) on Windows, and setView(webView.getViewHandle()) on Mac and iOS.
It’s a native view inside a JUCE component hierarchy, so things like transparency and z-layering won’t work. But you would have those limitations with WebBrowserComponent, too.
Ok, all works, really thankyou! only last thing … I’d like to pass, as said before, javascript (the only thing i want to do are get num of pages of pdf, get height and width of pdf and set current page of a pdf loaded in), how can I pass variables to javascript and get values in return? I see that I need to call bind and after call evaluateJavascript, I’m on the right road? I don’t really understand how it works… here the code I wrote up to now…
On constructor:
webView.bind ("getNumOfPages", [this] (const choc::value::ValueView& args) -> choc::value::Value
{
//what to do here ??
return {};
});
webView.bind ("getWidthOfPDF", [this] (const choc::value::ValueView& args) -> choc::value::Value
{
//what to do here ??
return {};
});
webView.bind ("getHeightOfPDF", [this] (const choc::value::ValueView& args) -> choc::value::Value
{
//what to do here ??
return {};
});
webView.bind ("setCurrentPage", [this] (const choc::value::ValueView& args) -> choc::value::Value
{
//what to do here ??
return {};
});
and an example of func:
void PdfViewer::setCurrentPage(int newPageNumber)
{
//is it right this ?
webView.evaluateJavascript(R"xxx(
<script>
setCurrentPage(newPageNumber);
</script>
)xxx");
}
This is a little more complicated. In your JavaScript, instead of returning a value, you need to call back to a C++ function that you’ve bound using WebView’s bind. Pass the value you want to return to C++ as a parameter to that function. Then in C++, your C++ lambda gets called, and the choc::value::ValueView args is the “returned” value from JavaScript.
Note that this will be asynchronous Meaning: When your call to evaluateJavascript() returns, your C++ lambda (from bind()) hasn’t yet been called, so the “return” value isn’t there yet. Adjust your code to be async and continue inside your lambda, once that gets called.
if I use navigate(“”) I cannot have the structure of document to call from javascript functions on it …
while if I use for example pdf is not shown in view :
The WebView probably can’t access local files like that, because that would be “cross-origin”. (Google it if you need more info )
Instead, set the WebView config’s fetchResource callback. Now whenever your HTML loads a file (e.g. .css, .js or .pdf), this C++ callback gets called. So your C++ code needs to return the data (in your case, the PDF as bytes) as well as the MIME type such as application/pdf
You can set a breakpoint in your fetchResource callback, to check that it’s being called for the PDF.