fixed up things so that deviceready now uses DOMContentLoaded and if DCL fires before something is attached to deviceready the function will be called immediately

This commit is contained in:
Dave Johnson 2010-07-20 11:25:55 -07:00
parent 27c4de6aa0
commit f7a4a0aef8
6 changed files with 325 additions and 143 deletions

View File

@ -7,6 +7,7 @@ class Build
def initialize(*a) def initialize(*a)
@android_sdk_path, @name, @pkg, @www, @path = a @android_sdk_path, @name, @pkg, @www, @path = a
@android_sdk_path = "/Users/davejohnson/Sdk/android-sdk-mac_86"
@android_dir = File.expand_path(File.dirname(__FILE__)) @android_dir = File.expand_path(File.dirname(__FILE__))
@framework_dir = File.join(@android_dir, "framework") @framework_dir = File.join(@android_dir, "framework")
end end

View File

@ -12,8 +12,6 @@
document.getElementById("platform").innerHTML = device.platform; document.getElementById("platform").innerHTML = device.platform;
document.getElementById("version").innerHTML = device.version; document.getElementById("version").innerHTML = device.version;
document.getElementById("uuid").innerHTML = device.uuid; document.getElementById("uuid").innerHTML = device.uuid;
console.log("Height:" + window.innerHeight);
console.log("Width:" + window.innerWidth);
} }
var getLocation = function() { var getLocation = function() {
@ -114,9 +112,7 @@
function init(){ function init(){
document.addEventListener("touchmove", preventBehavior, false); document.addEventListener("touchmove", preventBehavior, false);
document.addEventListener("deviceready", deviceInfo, true); document.addEventListener("deviceready", deviceInfo, true);
} }
</script> </script>
</head> </head>

View File

@ -37,44 +37,25 @@ PhoneGap.addConstructor = function(func) {
} }
}; };
(function() document.addEventListener('DOMContentLoaded', function() {
{ // run our constructors list
var timer = setInterval(function() while (PhoneGap._constructors.length > 0) {
{ var constructor = PhoneGap._constructors.shift();
try {
var state = document.readyState; constructor();
} catch(e) {
if ( state == 'loaded' || state == 'complete' ) if (typeof(debug['log']) == 'function') {
{ debug.log("Failed to run constructor: " + debug.processMessage(e));
clearInterval(timer); // stop looking } else {
// run our constructors list alert("Failed to run constructor: " + e.message);
while (PhoneGap._constructors.length > 0)
{
var constructor = PhoneGap._constructors.shift();
try
{
constructor();
}
catch(e)
{
if (typeof(debug['log']) == 'function')
{
debug.log("Failed to run constructor: " + debug.processMessage(e));
}
else
{
alert("Failed to run constructor: " + e.message);
}
}
} }
// all constructors run, now fire the deviceready event }
var e = document.createEvent('Events'); }
e.initEvent('deviceready'); // all constructors run, now fire the deviceready event
document.dispatchEvent(e); var e = document.createEvent('Events');
} e.initEvent('deviceready');
}, 5); document.dispatchEvent(e);
})(); });
/** /**
* Execute a PhoneGap command in a queued fashion, to ensure commands do not * Execute a PhoneGap command in a queued fashion, to ensure commands do not
@ -139,20 +120,11 @@ function Acceleration(x, y, z)
this.y = y; this.y = y;
this.z = z; this.z = z;
this.timestamp = new Date().getTime(); this.timestamp = new Date().getTime();
this.win = null;
this.fail = null;
} }
// Need to define these for android var accelListeners = [];
_accel = {};
_accel.x = 0;
_accel.y = 0;
_accel.z = 0;
function gotAccel(x, y, z)
{
_accel.x = x;
_accel.y = y;
_accel.z = z;
}
/** /**
* This class provides access to device accelerometer data. * This class provides access to device accelerometer data.
@ -180,12 +152,33 @@ Accelerometer.prototype.getCurrentAcceleration = function(successCallback, error
// Created for iPhone, Iphone passes back _accel obj litteral // Created for iPhone, Iphone passes back _accel obj litteral
if (typeof successCallback == "function") { if (typeof successCallback == "function") {
var accel = new Acceleration(_accel.x,_accel.y,_accel.z); if(this.lastAcceleration)
Accelerometer.lastAcceleration = accel; successCallback(accel);
successCallback(accel); else
{
watchAcceleration(this.gotCurrentAcceleration, this.fail);
}
} }
} }
Accelerometer.prototype.gotCurrentAcceleration = function(key, x, y, z)
{
var a = new Acceleration(x,y,z);
a.x = x;
a.y = y;
a.z = z;
a.win = accelListeners[key].win;
a.fail = accelListeners[key].fail;
this.timestamp = new Date().getTime();
this.lastAcceleration = a;
accelListeners[key] = a;
if (typeof a.win == "function") {
a.win(a);
}
}
/** /**
* Asynchronously aquires the acceleration repeatedly at a given interval. * Asynchronously aquires the acceleration repeatedly at a given interval.
* @param {Function} successCallback The function to call each time the acceleration * @param {Function} successCallback The function to call each time the acceleration
@ -198,12 +191,13 @@ Accelerometer.prototype.getCurrentAcceleration = function(successCallback, error
Accelerometer.prototype.watchAcceleration = function(successCallback, errorCallback, options) { Accelerometer.prototype.watchAcceleration = function(successCallback, errorCallback, options) {
// TODO: add the interval id to a list so we can clear all watches // TODO: add the interval id to a list so we can clear all watches
var frequency = (options != undefined)? options.frequency : 10000; var frequency = (options != undefined)? options.frequency : 10000;
var accel = Acceleration(0,0,0);
Accel.start(frequency); accel.win = successCallback;
return setInterval(function() { accel.fail = errorCallback;
navigator.accelerometer.getCurrentAcceleration(successCallback, errorCallback, options); accel.opts = options;
}, frequency); var key = accelListeners.push( accel ) - 1;
Accel.start(frequency, key);
} }
/** /**
@ -211,8 +205,11 @@ Accelerometer.prototype.watchAcceleration = function(successCallback, errorCallb
* @param {String} watchId The ID of the watch returned from #watchAcceleration. * @param {String} watchId The ID of the watch returned from #watchAcceleration.
*/ */
Accelerometer.prototype.clearWatch = function(watchId) { Accelerometer.prototype.clearWatch = function(watchId) {
Accel.stop(); Accel.stop(watchId);
clearInterval(watchId); }
Accelerometer.prototype.epicFail = function(watchId, message) {
accelWatcher[key].fail();
} }
PhoneGap.addConstructor(function() { PhoneGap.addConstructor(function() {
@ -259,7 +256,87 @@ Camera.prototype.fail = function(err)
PhoneGap.addConstructor(function() { PhoneGap.addConstructor(function() {
if (typeof navigator.camera == "undefined") navigator.camera = new Camera(); if (typeof navigator.camera == "undefined") navigator.camera = new Camera();
}); });
/** PhoneGap.Channel = function(type)
{
this.type = type;
this.handlers = {};
this.guid = 0;
this.fired = false;
this.enabled = true;
};
PhoneGap.Channel.prototype.sub = function(f, c, g)
{
// need a function to call
if (f == null)
return;
var func = f;
if (typeof c == "object" && f instanceof Function)
func = PhoneGap.close(c, f);
g = g || func.observer_guid || f.observer_guid || this.guid++;
func.observer_guid = g;
f.observer_guid = g;
this.handlers[g] = func;
return g;
};
PhoneGap.Channel.prototype.sob = function(f, c)
{
var g = null;
var _this = this;
var m = function() {
f.apply(c || null, arguments);
_this.dub(g);
}
if (this.fired) {
if (typeof c == "object" && f instanceof Function)
f = PhoneGap.close(c, f);
f.apply(this, this.fireArgs);
} else {
g = this.sub(m);
}
return g;
};
PhoneGap.Channel.prototype.dub = function(g)
{
if (g instanceof Function)
g = g.observer_guid;
this.handlers[g] = null;
delete this.handlers[g];
};
PhoneGap.Channel.prototype.fire = function(e)
{
if (this.enabled)
{
var fail = false;
for (var item in this.handlers) {
var handler = this.handlers[item];
if (handler instanceof Function) {
var rv = (handler.apply(this, arguments)==false);
fail = fail || rv;
}
}
this.fired = true;
this.fireArgs = arguments;
return !fail;
}
return true;
};
PhoneGap.Channel.merge = function(h, e) {
var i = e.length;
var f = function() {
if (!(--i)) h();
}
for (var j=0; j<i; j++) {
(!e[j].fired?e[j].sob(f):i--);
}
if (!i) h();
}/**
* This class provides access to device Compass data. * This class provides access to device Compass data.
* @constructor * @constructor
*/ */
@ -286,7 +363,7 @@ function Compass() {
*/ */
Compass.prototype.getCurrentHeading = function(successCallback, errorCallback, options) { Compass.prototype.getCurrentHeading = function(successCallback, errorCallback, options) {
if (this.lastHeading == null) { if (this.lastHeading == null) {
this.start(options); CompassHook.start();
} }
else else
if (typeof successCallback == "function") { if (typeof successCallback == "function") {
@ -488,18 +565,64 @@ function Device() {
this.version = window.DroidGap.getOSVersion(); this.version = window.DroidGap.getOSVersion();
this.gapVersion = window.DroidGap.getVersion(); this.gapVersion = window.DroidGap.getVersion();
this.platform = window.DroidGap.getPlatform(); this.platform = window.DroidGap.getPlatform();
this.name = window.DroidGap.getProductName(); this.name = window.DroidGap.getProductName();
this.line1Number = window.DroidGap.getLine1Number();
this.deviceId = window.DroidGap.getDeviceId();
this.simSerialNumber = window.DroidGap.getSimSerialNumber();
this.subscriberId = window.DroidGap.getSubscriberId();
} }
} catch(e) { } catch(e) {
this.available = false; this.available = false;
} }
} }
/*
* You must explicitly override the back button.
*/
Device.prototype.overrideBackButton = function()
{
BackButton.override();
}
/*
* This resets the back button to the default behaviour
*/
Device.prototype.resetBackButton = function()
{
BackButton.reset();
}
/*
* This terminates the activity!
*/
Device.prototype.exitApp = function()
{
BackButton.exitApp();
}
PhoneGap.addConstructor(function() { PhoneGap.addConstructor(function() {
navigator.device = window.device = new Device(); navigator.device = window.device = new Device();
}); });
PhoneGap.onDeviceReady = new PhoneGap.Channel();
PhoneGap.__document_addEventListener = document.addEventListener;
document.addEventListener = function(evt, handler, capture) {
if (evt.toLowerCase() == 'deviceready') {
PhoneGap.onDeviceReady.sob(handler);
} else {
PhoneGap.__document_addEventListener.call(document, evt, handler);
}
}
document.addEventListener('DOMContentLoaded', function() {
PhoneGap.onDeviceReady.fire();
})
PhoneGap.addConstructor(function() { if (typeof navigator.fileMgr == "undefined") navigator.fileMgr = new FileMgr();}); PhoneGap.addConstructor(function() { if (typeof navigator.fileMgr == "undefined") navigator.fileMgr = new FileMgr();});
@ -628,7 +751,7 @@ FileMgr.prototype.createDirectory = function(dirName, successCallback, errorCall
{ {
this.successCallback = successCallback; this.successCallback = successCallback;
this.errorCallback = errorCallback; this.errorCallback = errorCallback;
var test = FileUtils.createDirectory(dirName); var test = FileUtil.createDirectory(dirName);
test ? successCallback() : errorCallback(); test ? successCallback() : errorCallback();
} }
@ -636,7 +759,7 @@ FileMgr.prototype.deleteDirectory = function(dirName, successCallback, errorCall
{ {
this.successCallback = successCallback; this.successCallback = successCallback;
this.errorCallback = errorCallback; this.errorCallback = errorCallback;
var test = FileUtils.deleteDirectory(dirName); var test = FileUtil.deleteDirectory(dirName);
test ? successCallback() : errorCallback(); test ? successCallback() : errorCallback();
} }
@ -644,7 +767,7 @@ FileMgr.prototype.deleteFile = function(fileName, successCallback, errorCallback
{ {
this.successCallback = successCallback; this.successCallback = successCallback;
this.errorCallback = errorCallback; this.errorCallback = errorCallback;
FileUtils.deleteFile(fileName); FileUtil.deleteFile(fileName);
test ? successCallback() : errorCallback(); test ? successCallback() : errorCallback();
} }
@ -658,7 +781,7 @@ FileMgr.prototype.getFreeDiskSpace = function(successCallback, errorCallback)
{ {
this.successCallback = successCallback; this.successCallback = successCallback;
this.errorCallback = errorCallback; this.errorCallback = errorCallback;
this.freeDiskSpace = FileUtils.getFreeDiskSpace(); this.freeDiskSpace = FileUtil.getFreeDiskSpace();
(this.freeDiskSpace > 0) ? successCallback() : errorCallback(); (this.freeDiskSpace > 0) ? successCallback() : errorCallback();
} }
} }
@ -799,33 +922,28 @@ Geolocation.prototype.clearWatch = function(watchId)
Geo.stop(watchId); Geo.stop(watchId);
} }
// Taken from Jesse's geo fix (similar problem) in PhoneGap iPhone. Go figure, same browser!
function __proxyObj(origObj, proxyObj, funkList) {
for (var v in funkList) {
origObj[funkList[v]] = proxyObj[funkList[v]];
}
}
PhoneGap.addConstructor(function() { PhoneGap.addConstructor(function() {
navigator._geo = new Geolocation(); // Taken from Jesse's geo fix (similar problem) in PhoneGap iPhone. Go figure, same browser!
__proxyObj(navigator.geolocation, navigator._geo, function __proxyObj(origObj, proxyObj, funkList) {
["setLocation", "getCurrentPosition", "watchPosition", for (var v in funkList) {
"clearWatch", "setError", "start", "stop", "gotCurrentPosition"] origObj[funkList[v]] = proxyObj[funkList[v]];
); }
}
// In case a native geolocation object exists, proxy the native one over to a diff object so that we can overwrite the native implementation.
if (typeof navigator.geolocation != 'undefined') {
navigator._geo = new Geolocation();
__proxyObj(navigator.geolocation, navigator._geo, ["setLocation", "getCurrentPosition", "watchPosition", "clearWatch", "setError", "start", "stop", "gotCurrentPosition"]);
} else {
navigator.geolocation = new Geolocation();
}
});function KeyEvent() });function KeyEvent()
{ {
} }
KeyEvent.prototype.menuTrigger = function() KeyEvent.prototype.backTrigger = function()
{ {
var e = document.createEvent('Events'); var e = document.createEvent('Events');
e.initEvent('menuKeyDown'); e.initEvent('backKeyDown');
document.dispatchEvent(e);
}
KeyEvent.prototype.searchTrigger= function()
{
var e = document.createEvent('Events');
e.initEvent('searchKeyDown');
document.dispatchEvent(e); document.dispatchEvent(e);
} }
@ -879,19 +997,19 @@ MediaError.MEDIA_ERR_NONE_SUPPORTED = 4;
*/ */
Media.prototype.play = function() { Media.prototype.play = function() {
DroidGap.startPlayingAudio(this.src); GapAudio.startPlayingAudio(this.src);
} }
Media.prototype.stop = function() { Media.prototype.stop = function() {
DroidGap.stopPlayingAudio(); GapAudio.stopPlayingAudio();
} }
Media.prototype.startRecord = function() { Media.prototype.startRecord = function() {
DroidGap.startRecordingAudio(this.src); GapAudio.startRecordingAudio(this.src);
} }
Media.prototype.stopRecordingAudio = function() { Media.prototype.stopRecordingAudio = function() {
DroidGap.stopRecordingAudio(); GapAudio.stopRecordingAudio();
} }
@ -1179,10 +1297,10 @@ var dbSetup = function(name, version, display_name, size)
} }
PhoneGap.addConstructor(function() { PhoneGap.addConstructor(function() {
if (typeof navigator.openDatabase == "undefined") if (typeof window.openDatabase == "undefined")
{ {
navigator.openDatabase = window.openDatabase = dbSetup; navigator.openDatabase = window.openDatabase = dbSetup;
window.droiddb = new DroidDB(); window.droiddb = new DroidDB();
} }
}); });

View File

@ -0,0 +1,81 @@
PhoneGap.Channel = function(type)
{
this.type = type;
this.handlers = {};
this.guid = 0;
this.fired = false;
this.enabled = true;
};
PhoneGap.Channel.prototype.sub = function(f, c, g)
{
// need a function to call
if (f == null)
return;
var func = f;
if (typeof c == "object" && f instanceof Function)
func = PhoneGap.close(c, f);
g = g || func.observer_guid || f.observer_guid || this.guid++;
func.observer_guid = g;
f.observer_guid = g;
this.handlers[g] = func;
return g;
};
PhoneGap.Channel.prototype.sob = function(f, c)
{
var g = null;
var _this = this;
var m = function() {
f.apply(c || null, arguments);
_this.dub(g);
}
if (this.fired) {
if (typeof c == "object" && f instanceof Function)
f = PhoneGap.close(c, f);
f.apply(this, this.fireArgs);
} else {
g = this.sub(m);
}
return g;
};
PhoneGap.Channel.prototype.dub = function(g)
{
if (g instanceof Function)
g = g.observer_guid;
this.handlers[g] = null;
delete this.handlers[g];
};
PhoneGap.Channel.prototype.fire = function(e)
{
if (this.enabled)
{
var fail = false;
for (var item in this.handlers) {
var handler = this.handlers[item];
if (handler instanceof Function) {
var rv = (handler.apply(this, arguments)==false);
fail = fail || rv;
}
}
this.fired = true;
this.fireArgs = arguments;
return !fail;
}
return true;
};
PhoneGap.Channel.merge = function(h, e) {
var i = e.length;
var f = function() {
if (!(--i)) h();
}
for (var j=0; j<i; j++) {
(!e[j].fired?e[j].sob(f):i--);
}
if (!i) h();
}

View File

@ -57,3 +57,20 @@ Device.prototype.exitApp = function()
PhoneGap.addConstructor(function() { PhoneGap.addConstructor(function() {
navigator.device = window.device = new Device(); navigator.device = window.device = new Device();
}); });
PhoneGap.onDeviceReady = new PhoneGap.Channel();
PhoneGap.__document_addEventListener = document.addEventListener;
document.addEventListener = function(evt, handler, capture) {
if (evt.toLowerCase() == 'deviceready') {
PhoneGap.onDeviceReady.sob(handler);
} else {
PhoneGap.__document_addEventListener.call(document, evt, handler);
}
}
document.addEventListener('DOMContentLoaded', function() {
PhoneGap.onDeviceReady.fire();
})

View File

@ -37,52 +37,21 @@ PhoneGap.addConstructor = function(func) {
} }
}; };
(function() document.addEventListener('DOMContentLoaded', function() {
{ // run our constructors list
var timer = setInterval(function() while (PhoneGap._constructors.length > 0) {
{ var constructor = PhoneGap._constructors.shift();
try {
var state = document.readyState; constructor();
} catch(e) {
if ( state == 'loaded' || state == 'complete' ) if (typeof(debug['log']) == 'function') {
{ debug.log("Failed to run constructor: " + debug.processMessage(e));
clearInterval(timer); // stop looking } else {
// run our constructors list alert("Failed to run constructor: " + e.message);
while (PhoneGap._constructors.length > 0)
{
var constructor = PhoneGap._constructors.shift();
try
{
constructor();
}
catch(e)
{
if (typeof(debug['log']) == 'function')
{
debug.log("Failed to run constructor: " + debug.processMessage(e));
}
else
{
alert("Failed to run constructor: " + e.message);
}
}
} }
// Start listening for callbacks from Java }
PhoneGap.JSCallback(); }
});
// all constructors run, now fire the deviceready event
var e = document.createEvent('Events');
e.initEvent('deviceready');
document.dispatchEvent(e);
// Fire the onresume event, since first one happens before we are inited
var e = document.createEvent('Events');
e.initEvent('onresume');
document.dispatchEvent(e);
}
}, 5);
})();
/** /**
* Execute a PhoneGap command in a queued fashion, to ensure commands do not * Execute a PhoneGap command in a queued fashion, to ensure commands do not