HTMLViewer titleChanged issue with Xojo >= 2020 and BigSur 11.4

Hi there,

I’m facing a severe issue with HTMLViewer and TitleChanged event.

The TitleChanged event is firing but the data is truncated (workaround is to split the data in chunks and send multiple events), this was working fine up to BigSur 11.2.

Running BigSur 11.4 the TitleChanged is not always firing.
My javascript function runs a loop and send every chunk in sequence
Extract of js script:

document.title = 'chunkInit=';
for (var c = 0; c < chunks.length; c++) {
         document.title = 'chunk=' + chunks[c];               
}
document.title = 'chunkSent=' + chunks.length;

Neither ‘chunkInit’, nor ‘chunk=’ are firing TitleChanged event.
Only the last one, ‘chunkSent’, is firing the TitleChanged event.

I tried using small timeouts but it doesn’t help.

The problem is not limited to my js scripts. I’m using js libraries that are handling multiple events, which I handle by changing document.title, but some of them are not firing anymore since BigSur 11.4 (again, it works fine with 11.2)

Remarks:

  • the HTMLViewer renderer is WebKit and must stay so
  • from Xojo 2020r1 and following, StatusChanged event is not firing anymore so using window.status is not an option
  • the same app works fine on all macOS versions when compiled with Xojo 2019r3.1
  • I need a pure Xojo solution, no add-ons or plugins permitted

I have no way to debug what’s going on in HTMLViewer, I can’t send debug info to the app using document.title/window.status … I’m stuck.
I don’t even know what WebKit versions are used with the different Xojo versions, I didn’t find this information in the release notes.

I need to find a reliable way to send messages from the javascript inside the HTMLViewer page to the app.

Any help or hint appreciated !

Thanks !

There is now built-in functionality for communicating between a page loaded in the HTMLViewer and the Xojo host app.
JavaScriptRequest Event
ExecuteJavaScript Method
ExecuteJavaScriptSync Method

You can find the example project I wrote when this functionality was implemented in Example Projects/Desktop/Controls/HTMLViewer-Exec.xojo_binary_project

1 Like

Hi Anthony,

Thanks. I know about these, but I think it doesn’t help in my case.
I have elements in the DOM with event handlers, calling js functions.
I need to know that these functions are called…
AFAIK ExecuteJavascript(Sync) is initiated by the app, not by the html/js side.

If you look at the example, you’ll see that you can call executeInXojo from your JavaScript code, which will raise the JavaScriptRequest event. Directly from the example project:

htmTest.ExecuteJavaScript("executeInXojo('pageTitle', document.title );")

Or, if you want to respond to a mouse click using a jQuery click handler:

$('#myControl').click(function(e) {
  executeInXojo('buttonClick', 'some data');
});

Then you can handle that in the JavaScriptRequest event:

Function JavaScriptRequest(method As String, parameters() as Variant) Handles JavaScriptRequest as String
  Select Case method
  Case "buttonClick"
    MessageBox( "Button Clicked" )
  End Select
End Function

This is also outlined in the HTMLViewer docs:

Exchanging Data With JavaScript

A JavaScript executed via ExecuteJavaScript or ExecuteJavaScriptSync can call executeInXojo() or executeInXojoSync() to pass data back to the HTMLViewer via the JavaScriptRequest event. Both can be passed any number of parameters though the first parameter must be a string. For all subsequent parameters, only strings and numbers are supported. The executeInXojo() method is asynchronous and thus will not receive a value returned by the JavaScriptRequest event. The executeInXojoSync() method is synchronous and thus should be called as a function as it will receive the value returned by the JavaScriptRequest event.

On Windows you need to use the WebKit rendering engine for executeInXojo() or executeInXojoSync() to work.

I have opened case 65273 requesting a change to clarify in the documentation that these JavaScript functions can be called anywhere and at (almost) any time, not only from the HTMLViewer’s Execute* methods.

<https://xojo.com/issue/65273>

Thanks for clarifying Anthony,
I trust you’re right. It’s a lifesaver if working.
I’ll try this.
This should let me replace the document.title changes.
Thanks again !

1 Like

Happy to help!

What is the TitleChanged length limit that you experience?

I had some macOS config with a limit of 512 with BigSur 11.2 This is easily solved by creating chunks of data. I’m using chunks of 500 bytes.
The problem with 11.4 is that all document.title changes are not firing TitleChanged events.

OK thanks. That should still be enough for me. But that the event is not firing I’ll have to look at. Hmmm, means moving one of my Macs to Big Sur. I can’t use @Anthony_G_Cyphers 's solution as those methods require WebKit and I am x-platform.

It works on macOS and Linux out-of-the-box. The renderer setting only applies to Windows.

This is a cross-platform solution.

Problem with using executeInXojo is that it requires the JavaScriptRequest event which is new in 2020r1, so the app doesn’t compile in Xojo prior to 2020 (you cannot implement a nonexistent event).

Is there a way to have JavaScriptRequest conditional based on XojoVersion or to ignore this error ?

I use Target #If with AddHandler to support both old and new versions of Xojo. Both paths call a function to handle the response, so the code is common.

1 Like

Sure, but that then adds 100Mbyte to the app.

My solution for transfers that would be of indeterminate length was to implement a WebSocker server in the app, and use a websocket to communicate in both directions. Works a treat.

I still use TitleChanged for short messages.

Have you tried to help with MBS Xojo Plugins?

See WKWebViewMBS class, where you could run some JavaScript with EvaluateJavaScript to query the data you need.

1 Like

Hi Christian, I’m using your plugins in other apps but this one must stay pure vanilla Xojo.
Thanks anyway !