Detecting if PhoneGap application is run under Ripple Emulator

As of writing this, Ripple Emulator itself is old, long-time not updated. But, what is much more wrong, it has very, very old version of PhoneGap behind. Currently it is based on version 2.0.0, while we already have version 3.0.0 in local PhoneGap building and 2.9.0 in PhoneGap Build. If you compare PhoneGap API reference from version 2.9.0 with the one inside Ripple Emulator, you’ll see that changes are dramatic. That’s why being able to detect, when your application is running in debug mode (i.e. under Ripple Emulator) is essential.

Detecting, whether your application is running in Ripple Emulator or under real mobile device is necessary to block Ripple from executing pieces of code it doesn’t recognize (due to too old PhoneGap). And to stop you from vomiting each time you see stupid and annoying “I Has Cheesburger” message.

Introduction

Before we go to the main topic, for PhoneGap Build users: Keep in mind, that you have to have phonegap.js or cordova.js file really placed in your project structure! It has to be the one from version 2.0.0 of PhoneGap / Cordova (for above mentioned reasons), but it really have to exists there. Or else Ripple Emulator will fail at all. If you’re building in the cloud, through PhoneGap Build, you most likely was instructed to remove this file from your project assets and only leave reference to it in your HTML file. As PhoneGap Build will detect current version of PhoneGap and inject proper file, when building your project. This is fine for PhoneGap Build, but absolutely wrong for Ripple Emulator! See this issue on Apache JIRA for more details.

OK, let’s go back to the main topic. Ripple defines itself as an function, but for some reason, it is only available in the console. In other words, if you run your mobile application under Ripple Emulator, open console and type typeof(ripple), you’ll get "function". But, if you place it in your own Javascript code (alert(typeof(ripple));), you’ll end up with undefined. This path leads us to nowhere.

The secret word — tinyHippos

While browsing the net, I found this cool Gist: Detecting PhoneGap/Ripple emulator via JavaScript. It’s author says to use something like that:

[code language=”javascript”]
if(window.tinyHippos != undefined)
{
//Do something special for Ripple Emulator only.
}
[/code]

This works fine under newest (as of writing this) version of Ripple Emulator. Which is old enough itself. If — for the reasons beyond my imagination — you’re still using older version of Ripple, and above code fails, you can use tip from the same gist:

[code language=”javascript”]
if(!!document.getElementById("tinyhippos-injected") && !!window.top.require)
{

}
[/code]

If you’re used to clean Javascript code, where everything is placed on objects, you can define main application object with a special field for this reason:

[code language=”javascript”]
var app =
{
debugMode: window.tinyHippos != undefined,

init: function()
{
document.addEventListener(‘deviceready’, app.deviceReadyHandler, false);
},

deviceReadyHandler: function()
{

}
}

app.init();
[/code]

This way, you can use simple if(app.debugMode) to execute piece of code only under Ripple Emulator.

Check, if running under mobile browser

There’s a bit different approach to solve this problem, presented in this Stack Overflow answer:

[code language=”javascript”]
if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry|IEMobile)/))
{
//We’re on real mobile!
document.addEventListener("deviceready", onDeviceReady, false);
}
else onDeviceReady();
[/code]

You may safely ignore comments given below this answer. We’re talking about PhoneGap application here, which is always run under webview and where user cannot change user-agent string. All these comments are related to opening website with above code on mobile browser, which is not the case here.

However, keep in mind, that, that this will only be useful in case of firing deviceready event (or other one), that may not be fired properly by Ripple Emulator. But for the code, that you have to “secure” to not let Ripple die on, this solution won’t work (won’t detect Ripple) in this cases, you should fallback to previous one.

This one is, however fine, for detecting mobile browser at all. The only problem, is that it detects not to much browsers. A solution for this problem is here. This is a long, long piece of regular expression code, that is said to cover 97% of all, even most weird mobile browsers. Original link leads to PHP code. I tired to make it work in Javascript (this JS fiddle), but I failed and abandoned it. Try to fix it, if you’re still interested.

Leave a Reply