Pages

Tuesday, January 14, 2014

Workaround for timeout issue in Titanium's WebView.evalJS method

First of all, yes, I'm using Titanium because I want to save time writing code for each platform and I like JavaScript.

I'm writing an app that uses WebView and came across this bug. At first I thought I would have to either wait or write my own Android module, but this hack gave me the hint I needed: bookmarklets! If you don't remember, a bookmarklet is just a JavaScript code that runs when your browser tries to open a URL that starts with javascript: instead of http://.

The only thing that was needed was to prepend any JavaScript code with javascript: and remove any "junk" as suggested here:

  1. comment lines
  2. convert tabs into spaces
  3. convert multiple spaces in a single space
  4. remove leading and trailing spaces
  5. remove line breaks
After the "cleanup" above, I also thought that it would be necessary to URL-encode the result, but it's NOT necessary to do so with Titanium WebView because somebody else (other then myself) is URL-encoding it under the hood.

So, putting everything together:

var jsCode = "" +

// this line starts with TAB and ends with line break
"\t\t// this is a sample comment line that should be deleted\n" + 

// this line has multiple spaces between "body" and "="
"\t\tvar body                = document.body;\n" +

// this line has leading spaces
"        var contentLength = body.innerHTML.length;\n" +

// this line has trailing spaces
"\t\talert( 'Your BODY tag has ' + contentLength + ' characters!' );    \n";

// remove comment lines
jsCode = jsCode.replace(new RegExp("^[\s\t]*//[^\n]+[\n]","gm"),"");

// convert tabs into spaces
jsCode = jsCode.replace(new RegExp("[\t]","g")," ");

// multiple spaces as single space
jsCode = jsCode.replace(new RegExp("[ ]{2,}","g")," ");

// remove leading and trailing spaces
jsCode = jsCode.replace(new RegExp("^[ ]*|[ ]*$","gm"),"");

// remove line breaks
jsCode = jsCode.replace(new RegExp("[\n]","gm"),"");

var prefix = "javascript:(function(){";
var suffix = "})();";
var finalCode = prefix + jsCode + suffix;

Ti.API.debug(finalCode);

var myWebView = Titanium.UI.createWebView({url:'https://www.google.com'});
myWebView.addEventListener('load', function(){
 myWebView.setUrl(finalCode);
});

var myWindow = Titanium.UI.createWindow();
myWindow.add(myWebView);
myWindow.open();

Cheers!

No comments:

Post a Comment

Your feedback is very welcome! No spam please.