Finally I got it working without using any external library.
THE PROBLEM
For a multiplatform Phonegap project, two are the parts that differ from one platform to another:
- The encapsulating project
- The Javacript Phonegap file.
Those encapsulating projects typically do not change much over the course of the project. It would be desirable to have a single HTML5 codebase that one could directly paste (or using build scripts) onto the platform-dependent projects. Since the javascript phonegap library is inside the set of web files, it's really painfull to replace the correct file each time.
MY SOLUTION
In my project I have several cordova files, one for each target platform:
- cordova.android.js
- cordova.ios.js
- cordoba.bb.js
...
(Notice how every one of these files is included in the app even if it is not used. For me it's not a problem, since the scripts are bundled in the app and only the one for the correct platform is loaded to memory).
In my pages, instead of a script tag for phonegap, I placed the loader module:
<script src="phonegap-loader.js"></script>
And this would be the phonegap-loader.js script. I make use of user-agent detection to dynamically and synchronously load the script:
(function(){
var useragent = navigator.userAgent;
if(/Android/i.test(useragent)){
loadScript('cordova.android.js');
} else if((/iPhone/i.test(useragent)) || (/iPad/i.test(useragent))){
loadScript('cordova.ios.js');
}
...
// Else desktop browser is assumed and no phonegap js is loaded
function loadScript(url){
// synchronous load by @Sean Kinsey
// https://stackoverflow.com/a/2880147/813951
var xhrObj = new XMLHttpRequest();
xhrObj.open('GET', url, false);
xhrObj.send('');
var se = document.createElement('script');
se.text = xhrObj.responseText;
document.getElementsByTagName('head')[0].appendChild(se);
}
})();
Its really important to load the script SYNCHRONOUSLY. This gave me innumerable headaches. Before realising this I tried adding scripts tags at the bottom of the head, and using $.getScript, but none worked, since ondeviceReady
was not fired. Looks like the only valid approach to ensure the Phonegap script is executed when loaded dynamically is the one shown in this amazing answer by @Sean Kinsey (all kudos to him).
The only drawback is that the script is inlined, but for me is a cheap price to pay for having the core HTML5 app finally isolated from the containers.