HTMLViewer, JavaScript line endings and semicolons

I have a Xojo app which has some complicated Javascript/HTML/CSS which it runs inside a HTMLViewer. For testing, all of this javascript is written so I can run it directly in Safari (so I can use Safari’s excellent JS debugger).

When I build my Xojo app, I pack up the HTML, JavaScript and CSS into a single file. At runtime it gets sent to the HTMLViewer.

All was fine, until it wasn’t. The HTML would run fine under Safari, but would mysteriously die when run under Xojo’s HTMLviewer.

After much cursing and adding a bunch of logging statements - I figured it out. It was a missing semicolon on one line in a javscript object definition. (Note: Apprarently Javascript is kind of permissive about semicolons, and you often don’t need them)

But this raises the question - why did it work in Safari but not Xojo?

Ideas:

  • could this be a unix/mac/linux EndOfLine character issue? So that when run in Safari the Javascript compiler was able to figure out where to insert the semicolon, but under Xojo that didn’t work?
  • I believe Xojo is using the older WebView control. Safari is (probably) using WKWebView. Perhaps an engine difference?
  • Gremlins?

I go for option #3, always a safe-bet and no need to try and explain it… :slight_smile:

While it’s related to your second option (Safari now uses the JavaScript Nitro engine), Safari isn’t technically a WKWebView. You can see this on iOS where we have upgraded to WKWebView and there are still behavior differences with mobile Safari.

Right at the top of my javascript I’ve got:

window.onerror = function (errmess, url, linenum) // Make JavaScript errors more visible { msgCount++; document.title = "Error (" + msgCount + ") JavaScript error at line " + linenum + " - " + errmess; }
As it’s at the top, there’s some chance it is available to generate a TitleChanged event if there’s a javascript error further down. The msgCount business is needed to ensure that your title does actually change from whatever it was before, otherwise you don’t get a TitleChanged event.

Error recovery methods.

No.

Safari, a fully implemented web browser, was able to recover from the error in some way that Xojo was not. HTMLViewer is missing other standard web browser features, as the developers are meant to implement them. We don’t have access to all of them in Xojo. For example, Javascript alert(); will do nothing in an HTMLViewer.

If you consider syntax errors gremlins.

Semicolons in Javascript aren’t super permissive, there’s just some exceptions. It’s better to always use one and let an optimizer decide what things can be removed.

@Tim S: thanks I’ll have to try that out and report back.

@Tim P: interesting - is this anything that’s documented?

Mostly this hasn’t been a problem - when my JavaScript broke in Xojo, I’d just run it in Safari and it was also broken there, too.

This was the first case I’ve had where it was not working identically in the two engines.

[quote=416530:@Michael Diehr]@Tim S: thanks I’ll have to try that out and report back.

@Tim P: interesting - is this anything that’s documented?

Mostly this hasn’t been a problem - when my JavaScript broke in Xojo, I’d just run it in Safari and it was also broken there, too.

This was the first case I’ve had where it was not working identically in the two engines.[/quote]

Trying it in a browser or three is a good way to go. I keep copies of FireFox, Opera, iCab, and Chrome around for the purpose in addition to Safari.

Update - it’s actually more complicated than I initially realized.

  • First, I switched from using a HTMLViewer to using the WKWebViewControlMBS control
  • This uses the WKWebKit engine which is more similar to Safari.
  • Next, set WKWebViewControlMBS.developerExtrasEnabled = true in the control’s Open event.
  • This allows you, at runtime, to right-click and choose “Inspect Object” which gives you the full Safari-like developer window while running your Xojo app.
  • From this you can open the Javascript debugger and see the exact error(s).

From this I learned that it’s…complicated.

I found some code which will run fine in Safari the app, but will fail when run inside a HTMLViewer (or WKWebViewControlMBS) with
the error: SyntaxError: Cannot declare a let variable twice

Here’s an example:

function (e,t) {
   var x = 0;
   for (let e = 1; e < t.length; e++)
      x += t;
  return x;
}

This code works in Safari but fails in a HMTLViewer.

My conclusion is that the underlying javascript engine used by Safari and WebViews are not identical. See https://github.com/mishoo/UglifyJS2/issues/1753

The bottom line however is that WKWebViewControlMBS.developerExtrasEnabled makes it much easier to debug and figure out what’s going on.