/* #################### */ /* # ./scripts/xui.js # */ /* #################### */ /* XUI 1.0 Minified */ (function(){function H(a){return a.firstChild===null?{UL:"LI",DL:"DT",TR:"TD"}[a.tagName]||a.tagName:a.firstChild.tagName}function t(a,b){return typeof a==x?I(a,H(b)):a}function I(a,b){var c={},d=/^<([A-Z][A-Z0-9]*)([^>]*)>(.*)<\/\1>/i,e,g;g=0;if(d.test(a)){result=d.exec(a);b=result[1];if(result[2]!=="")for(a=result[2].split(/([A-Z]*\s*=\s*['|"][A-Z0-9:;#\s]*['|"])/i);g255?255:m)}return"rgb("+v.join(",")+")"}function g(f){var n=parseFloat(f);f=f.replace(/^[\-\d\.]+/,"");return isNaN(n)?{v:f,f:e,u:""}:{v:n,f:c,u:f}}function k(f){var n={},l=s.length,m;r.innerHTML='
';for(f=r.childNodes[0].style;l--;)if(m=f[s[l]])n[s[l]]=g(m);return n}var r=o.createElement("div"),s="backgroundColor borderBottomColor borderBottomWidth borderLeftColor borderLeftWidth borderRightColor borderRightWidth borderSpacing borderTopColor borderTopWidth bottom color fontSize fontWeight height left letterSpacing lineHeight marginBottom marginLeft marginRight marginTop maxHeight maxWidth minHeight minWidth opacity outlineColor outlineOffset outlineWidth paddingBottom paddingLeft paddingRight paddingTop right textIndent top width wordSpacing zIndex".split(" "); b[a]=function(f,n,l){f=typeof f=="string"?o.getElementById(f):f;l=l||{};var m=k(n);n=f.currentStyle?f.currentStyle:getComputedStyle(f,null);var h,j={},q=+new Date,v=l.duration||200,F=q+v,G,R=l.easing||function(w){return-Math.cos(w*Math.PI)/2+0.5};for(h in m)j[h]=g(n[h]);G=setInterval(function(){var w=+new Date,S=w>F?1:(w-q)/v;for(h in m)f.style[h]=m[h].f(j[h].v,m[h].v,R(S))+m[h].u;if(w>F){clearInterval(G);l.after&&l.after()}},10)}})("emile",this)})(); /* XUI More 1.0 Minified */ (function(){function J(a){return a.firstChild===null?{UL:"LI",DL:"DT",TR:"TD"}[a.tagName]||a.tagName:a.firstChild.tagName}function v(a,b){return typeof a==y?K(a,J(b)):a}function K(a,b){var c={},d=/^<([A-Z][A-Z0-9]*)([^>]*)>(.*)<\/\1>/i,e,f;f=0;if(d.test(a)){result=d.exec(a);b=result[1];if(result[2]!=="")for(a=result[2].split(/([A-Z]*\s*=\s*['|"][A-Z0-9:;#\s]*['|"])/i);fb&&j.innerWidtha&&j.innerHeightj.innerHeight;if(c||d){j.orientation= c?0:90;$("body").fire("orientationchange");a=j.innerWidth;b=j.innerHeight}})}();h.extend({_toQueryString:function(a){var b="",c="",d="",e=a.length,f;for(f=0;f255?255:n)}return"rgb("+w.join(",")+")"}function f(g){var o=parseFloat(g);g=g.replace(/^[\-\d\.]+/,"");return isNaN(o)?{v:g,f:e,u:""}:{v:o,f:c,u:g}}function i(g){var o={},m=r.length,n;q.innerHTML='
';for(g=q.childNodes[0].style;m--;)if(n=g[r[m]])o[r[m]]=f(n);return o}var q=p.createElement("div"),r="backgroundColor borderBottomColor borderBottomWidth borderLeftColor borderLeftWidth borderRightColor borderRightWidth borderSpacing borderTopColor borderTopWidth bottom color fontSize fontWeight height left letterSpacing lineHeight marginBottom marginLeft marginRight marginTop maxHeight maxWidth minHeight minWidth opacity outlineColor outlineOffset outlineWidth paddingBottom paddingLeft paddingRight paddingTop right textIndent top width wordSpacing zIndex".split(" "); b[a]=function(g,o,m){g=typeof g=="string"?p.getElementById(g):g;m=m||{};var n=i(o);o=g.currentStyle?g.currentStyle:getComputedStyle(g,null);var k,l={},u=+new Date,w=m.duration||200,H=u+w,I,S=m.easing||function(x){return-Math.cos(x*Math.PI)/2+0.5};for(k in n)l[k]=f(o[k]);I=setInterval(function(){var x=+new Date,T=x>H?1:(x-u)/w;for(k in n)g.style[k]=n[k].f(l[k].v,n[k].v,S(T))+n[k].u;if(x>H){clearInterval(I);m.after&&m.after()}},10)}})("emile",this)})(); /* ######################### */ /* # ./scripts/phonegap.js # */ /* ######################### */ /* * PhoneGap is available under *either* the terms of the modified BSD license *or* the * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. * * Copyright (c) 2005-2010, Nitobi Software Inc. * Copyright (c) 2010, IBM Corporation */ /** * The order of events during page load and PhoneGap startup is as follows: * * onDOMContentLoaded Internal event that is received when the web page is loaded and parsed. * window.onload Body onload event. * onNativeReady Internal event that indicates the PhoneGap native side is ready. * onPhoneGapInit Internal event that kicks off creation of all PhoneGap JavaScript objects (runs constructors). * onPhoneGapReady Internal event fired when all PhoneGap JavaScript objects have been created * onPhoneGapInfoReady Internal event fired when device properties are available * onDeviceReady User event fired to indicate that PhoneGap is ready * onResume User event fired to indicate a start/resume lifecycle event * * The only PhoneGap events that user code should register for are: * onDeviceReady * onResume * * Listeners can be registered as: * document.addEventListener("deviceready", myDeviceReadyListener, false); * document.addEventListener("resume", myResumeListener, false); */ if (typeof(DeviceInfo) != 'object') DeviceInfo = {}; /** * This represents the PhoneGap API itself, and provides a global namespace for accessing * information about the state of PhoneGap. * @class */ var PhoneGap = { queue: { ready: true, commands: [], timer: null } }; /** * Custom pub-sub channel that can have functions subscribed to it */ PhoneGap.Channel = function(type) { this.type = type; this.handlers = {}; this.guid = 0; this.fired = false; this.enabled = true; }; /** * Subscribes the given function to the channel. Any time that * Channel.fire is called so too will the function. * Optionally specify an execution context for the function * and a guid that can be used to stop subscribing to the channel. * Returns the guid. */ PhoneGap.Channel.prototype.subscribe = 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; }; /** * Like subscribe but the function is only called once and then it * auto-unsubscribes itself. */ PhoneGap.Channel.prototype.subscribeOnce = function(f, c) { var g = null; var _this = this; var m = function() { f.apply(c || null, arguments); _this.unsubscribe(g); } if (this.fired) { if (typeof c == "object" && f instanceof Function) { f = PhoneGap.close(c, f); } f.apply(this, this.fireArgs); } else { g = this.subscribe(m); } return g; }; /** * Unsubscribes the function with the given guid from the channel. */ PhoneGap.Channel.prototype.unsubscribe = function(g) { if (g instanceof Function) { g = g.observer_guid; } this.handlers[g] = null; delete this.handlers[g]; }; /** * Calls all functions subscribed to this channel. */ 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; }; /** * Calls the provided function only after all of the channels specified * have been fired. */ PhoneGap.Channel.join = function(h, c) { var i = c.length; var f = function() { if (!(--i)) h(); } for (var j=0; j 0) { s = s + ","; } var type = typeof args[i]; if ((type == "number") || (type == "boolean")) { s = s + args[i]; } else if (args[i] instanceof Array) { s = s + "[" + args[i] + "]"; } else if (args[i] instanceof Object) { var start = true; s = s + '{'; for (var name in args[i]) { if (!start) { s = s + ','; } s = s + '"' + name + '":'; var nameType = typeof args[i][name]; if ((nameType == "number") || (nameType == "boolean")) { s = s + args[i][name]; } else { s = s + '"' + args[i][name] + '"'; } start=false; } s = s + '}'; } else { var a = args[i].replace(/\\/g, '\\\\'); a = a.replace(/"/g, '\\"'); s = s + '"' + a + '"'; } } s = s + "]"; return s; } else { return JSON.stringify(args); } }; /** * Does a deep clone of the object. * * @param obj * @return */ PhoneGap.clone = function(obj) { if(!obj) { return obj; } if(obj instanceof Array){ var retVal = new Array(); for(var i = 0; i < obj.length; ++i){ retVal.push(PhoneGap.clone(obj[i])); } return retVal; } if (obj instanceof Function) { return obj; } if(!(obj instanceof Object)){ return obj; } retVal = new Object(); for(i in obj){ if(!(i in retVal) || retVal[i] != obj[i]) { retVal[i] = PhoneGap.clone(obj[i]); } } return retVal; }; PhoneGap.callbackId = 0; PhoneGap.callbacks = {}; PhoneGap.callbackStatus = { NO_RESULT: 0, OK: 1, CLASS_NOT_FOUND_EXCEPTION: 2, ILLEGAL_ACCESS_EXCEPTION: 3, INSTANTIATION_EXCEPTION: 4, MALFORMED_URL_EXCEPTION: 5, IO_EXCEPTION: 6, INVALID_ACTION: 7, JSON_EXCEPTION: 8, ERROR: 9 }; /** * Execute a PhoneGap command. It is up to the native side whether this action is synch or async. * The native side can return: * Synchronous: PluginResult object as a JSON string * Asynchrounous: Empty string "" * If async, the native side will PhoneGap.callbackSuccess or PhoneGap.callbackError, * depending upon the result of the action. * * @param {Function} success The success callback * @param {Function} fail The fail callback * @param {String} service The name of the service to use * @param {String} action Action to be run in PhoneGap * @param {String[]} [args] Zero or more arguments to pass to the method */ PhoneGap.exec = function(success, fail, service, action, args) { try { var callbackId = service + PhoneGap.callbackId++; if (success || fail) { PhoneGap.callbacks[callbackId] = {success:success, fail:fail}; } // Note: Device returns string, but for some reason emulator returns object - so convert to string. var r = ""+PluginManager.exec(service, action, callbackId, this.stringify(args), true); // If a result was returned if (r.length > 0) { eval("var v="+r+";"); // If status is OK, then return value back to caller if (v.status == PhoneGap.callbackStatus.OK) { // If there is a success callback, then call it now with returned value if (success) { try { success(v.message); } catch (e) { console.log("Error in success callback: "+callbackId+" = "+e); } // Clear callback if not expecting any more results if (!v.keepCallback) { delete PhoneGap.callbacks[callbackId]; } } return v.message; } // If no result else if (v.status == PhoneGap.callbackStatus.NO_RESULT) { // Clear callback if not expecting any more results if (!v.keepCallback) { delete PhoneGap.callbacks[callbackId]; } } // If error, then display error else { console.log("Error: Status="+r.status+" Message="+v.message); // If there is a fail callback, then call it now with returned value if (fail) { try { fail(v.message); } catch (e) { console.log("Error in error callback: "+callbackId+" = "+e); } // Clear callback if not expecting any more results if (!v.keepCallback) { delete PhoneGap.callbacks[callbackId]; } } return null; } } } catch (e) { console.log("Error: "+e); } }; /** * Called by native code when returning successful result from an action. * * @param callbackId * @param args */ PhoneGap.callbackSuccess = function(callbackId, args) { if (PhoneGap.callbacks[callbackId]) { // If result is to be sent to callback if (args.status == PhoneGap.callbackStatus.OK) { try { if (PhoneGap.callbacks[callbackId].success) { PhoneGap.callbacks[callbackId].success(args.message); } } catch (e) { console.log("Error in success callback: "+callbackId+" = "+e); } } // Clear callback if not expecting any more results if (!args.keepCallback) { delete PhoneGap.callbacks[callbackId]; } } }; /** * Called by native code when returning error result from an action. * * @param callbackId * @param args */ PhoneGap.callbackError = function(callbackId, args) { if (PhoneGap.callbacks[callbackId]) { try { if (PhoneGap.callbacks[callbackId].fail) { PhoneGap.callbacks[callbackId].fail(args.message); } } catch (e) { console.log("Error in error callback: "+callbackId+" = "+e); } // Clear callback if not expecting any more results if (!args.keepCallback) { delete PhoneGap.callbacks[callbackId]; } } }; /** * Internal function used to dispatch the request to PhoneGap. It processes the * command queue and executes the next command on the list. If one of the * arguments is a JavaScript object, it will be passed on the QueryString of the * url, which will be turned into a dictionary on the other end. * @private */ // TODO: Is this used? PhoneGap.run_command = function() { if (!PhoneGap.available || !PhoneGap.queue.ready) return; PhoneGap.queue.ready = false; var args = PhoneGap.queue.commands.shift(); if (PhoneGap.queue.commands.length == 0) { clearInterval(PhoneGap.queue.timer); PhoneGap.queue.timer = null; } var uri = []; var dict = null; for (var i = 1; i < args.length; i++) { var arg = args[i]; if (arg == undefined || arg == null) arg = ''; if (typeof(arg) == 'object') dict = arg; else uri.push(encodeURIComponent(arg)); } var url = "gap://" + args[0] + "/" + uri.join("/"); if (dict != null) { var query_args = []; for (var name in dict) { if (typeof(name) != 'string') continue; query_args.push(encodeURIComponent(name) + "=" + encodeURIComponent(dict[name])); } if (query_args.length > 0) url += "?" + query_args.join("&"); } document.location = url; }; PhoneGap.JSCallbackPort = CallbackServer.getPort(); PhoneGap.JSCallbackToken = CallbackServer.getToken(); /** * This is only for Android. * * Internal function that uses XHR to call into PhoneGap Java code and retrieve * any JavaScript code that needs to be run. This is used for callbacks from * Java to JavaScript. */ PhoneGap.JSCallback = function() { var xmlhttp = new XMLHttpRequest(); // Callback function when XMLHttpRequest is ready xmlhttp.onreadystatechange=function(){ if(xmlhttp.readyState == 4){ // If callback has JavaScript statement to execute if (xmlhttp.status == 200) { var msg = xmlhttp.responseText; setTimeout(function() { try { var t = eval(msg); } catch (e) { // If we're getting an error here, seeing the message will help in debugging console.log("Message from Server: " + msg); console.log("JSCallback Error: "+e); } }, 1); setTimeout(PhoneGap.JSCallback, 1); } // If callback ping (used to keep XHR request from timing out) else if (xmlhttp.status == 404) { setTimeout(PhoneGap.JSCallback, 10); } // If error, restart callback server else { console.log("JSCallback Error: Request failed."); CallbackServer.restartServer(); setTimeout(PhoneGap.JSCallback, 100); } } } xmlhttp.open("GET", "http://127.0.0.1:"+PhoneGap.JSCallbackPort+"/"+PhoneGap.JSCallbackToken , true); xmlhttp.send(); }; /** * The polling period to use with JSCallbackPolling. * This can be changed by the application. The default is 50ms. */ PhoneGap.JSCallbackPollingPeriod = 50; /** * This is only for Android. * * Internal function that uses polling to call into PhoneGap Java code and retrieve * any JavaScript code that needs to be run. This is used for callbacks from * Java to JavaScript. */ PhoneGap.JSCallbackPolling = function() { var msg = CallbackServer.getJavascript(); if (msg) { setTimeout(function() { try { var t = eval(""+msg); } catch (e) { console.log("JSCallbackPolling Error: "+e); } }, 1); setTimeout(PhoneGap.JSCallbackPolling, 1); } else { setTimeout(PhoneGap.JSCallbackPolling, PhoneGap.JSCallbackPollingPeriod); } }; /** * Create a UUID * * @return */ PhoneGap.createUUID = function() { return PhoneGap.UUIDcreatePart(4) + '-' + PhoneGap.UUIDcreatePart(2) + '-' + PhoneGap.UUIDcreatePart(2) + '-' + PhoneGap.UUIDcreatePart(2) + '-' + PhoneGap.UUIDcreatePart(6); }; PhoneGap.UUIDcreatePart = function(length) { var uuidpart = ""; for (var i=0; i frequency + 10 sec PhoneGap.exec( function(timeout) { if (timeout < (frequency + 10000)) { PhoneGap.exec(null, null, "Accelerometer", "setTimeout", [frequency + 10000]); } }, function(e) { }, "Accelerometer", "getTimeout", []); // Start watch timer var id = PhoneGap.createUUID(); navigator.accelerometer.timers[id] = setInterval(function() { PhoneGap.exec(successCallback, errorCallback, "Accelerometer", "getAcceleration", []); }, (frequency ? frequency : 1)); return id; }; /** * Clears the specified accelerometer watch. * * @param {String} id The id of the watch returned from #watchAcceleration. */ Accelerometer.prototype.clearWatch = function(id) { // Stop javascript timer & remove from timer list if (id && navigator.accelerometer.timers[id] != undefined) { clearInterval(navigator.accelerometer.timers[id]); delete navigator.accelerometer.timers[id]; } }; PhoneGap.addConstructor(function() { if (typeof navigator.accelerometer == "undefined") navigator.accelerometer = new Accelerometer(); }); /* * PhoneGap is available under *either* the terms of the modified BSD license *or* the * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. * * Copyright (c) 2005-2010, Nitobi Software Inc. * Copyright (c) 2010, IBM Corporation */ /** * This class provides access to the device camera. * * @constructor */ Camera = function() { this.successCallback = null; this.errorCallback = null; this.options = null; }; /** * Format of image that returned from getPicture. * * Example: navigator.camera.getPicture(success, fail, * { quality: 80, * destinationType: Camera.DestinationType.DATA_URL, * sourceType: Camera.PictureSourceType.PHOTOLIBRARY}) */ Camera.DestinationType = { DATA_URL: 0, // Return base64 encoded string FILE_URI: 1 // Return file uri (content://media/external/images/media/2 for Android) }; Camera.prototype.DestinationType = Camera.DestinationType; /** * Source to getPicture from. * * Example: navigator.camera.getPicture(success, fail, * { quality: 80, * destinationType: Camera.DestinationType.DATA_URL, * sourceType: Camera.PictureSourceType.PHOTOLIBRARY}) */ Camera.PictureSourceType = { PHOTOLIBRARY : 0, // Choose image from picture library (same as SAVEDPHOTOALBUM for Android) CAMERA : 1, // Take picture from camera SAVEDPHOTOALBUM : 2 // Choose image from picture library (same as PHOTOLIBRARY for Android) }; Camera.prototype.PictureSourceType = Camera.PictureSourceType; /** * Gets a picture from source defined by "options.sourceType", and returns the * image as defined by the "options.destinationType" option. * The defaults are sourceType=CAMERA and destinationType=DATA_URL. * * @param {Function} successCallback * @param {Function} errorCallback * @param {Object} options */ Camera.prototype.getPicture = function(successCallback, errorCallback, options) { // successCallback required if (typeof successCallback != "function") { console.log("Camera Error: successCallback is not a function"); return; } // errorCallback optional if (errorCallback && (typeof errorCallback != "function")) { console.log("Camera Error: errorCallback is not a function"); return; } this.options = options; var quality = 80; if (options.quality) { quality = this.options.quality; } var destinationType = Camera.DestinationType.DATA_URL; if (this.options.destinationType) { destinationType = this.options.destinationType; } var sourceType = Camera.PictureSourceType.CAMERA; if (typeof this.options.sourceType == "number") { sourceType = this.options.sourceType; } PhoneGap.exec(successCallback, errorCallback, "Camera", "takePicture", [quality, destinationType, sourceType]); }; PhoneGap.addConstructor(function() { if (typeof navigator.camera == "undefined") navigator.camera = new Camera(); }); /* * PhoneGap is available under *either* the terms of the modified BSD license *or* the * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. * * Copyright (c) 2005-2010, Nitobi Software Inc. * Copyright (c) 2010, IBM Corporation */ /** * This class provides access to device Compass data. * @constructor */ function Compass() { /** * The last known Compass position. */ this.lastHeading = null; /** * List of compass watch timers */ this.timers = {}; }; Compass.ERROR_MSG = ["Not running", "Starting", "", "Failed to start"]; /** * Asynchronously aquires the current heading. * * @param {Function} successCallback The function to call when the heading data is available * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL) * @param {PositionOptions} options The options for getting the heading data such as timeout. (OPTIONAL) */ Compass.prototype.getCurrentHeading = function(successCallback, errorCallback, options) { // successCallback required if (typeof successCallback != "function") { console.log("Compass Error: successCallback is not a function"); return; } // errorCallback optional if (errorCallback && (typeof errorCallback != "function")) { console.log("Compass Error: errorCallback is not a function"); return; } // Get heading PhoneGap.exec(successCallback, errorCallback, "Compass", "getHeading", []); }; /** * Asynchronously aquires the heading repeatedly at a given interval. * * @param {Function} successCallback The function to call each time the heading data is available * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL) * @param {HeadingOptions} options The options for getting the heading data such as timeout and the frequency of the watch. (OPTIONAL) * @return String The watch id that must be passed to #clearWatch to stop watching. */ Compass.prototype.watchHeading= function(successCallback, errorCallback, options) { // Default interval (100 msec) var frequency = (options != undefined) ? options.frequency : 100; // successCallback required if (typeof successCallback != "function") { console.log("Compass Error: successCallback is not a function"); return; } // errorCallback optional if (errorCallback && (typeof errorCallback != "function")) { console.log("Compass Error: errorCallback is not a function"); return; } // Make sure compass timeout > frequency + 10 sec PhoneGap.exec( function(timeout) { if (timeout < (frequency + 10000)) { PhoneGap.exec(null, null, "Compass", "setTimeout", [frequency + 10000]); } }, function(e) { }, "Compass", "getTimeout", []); // Start watch timer to get headings var id = PhoneGap.createUUID(); navigator.compass.timers[id] = setInterval( function() { PhoneGap.exec(successCallback, errorCallback, "Compass", "getHeading", []); }, (frequency ? frequency : 1)); return id; }; /** * Clears the specified heading watch. * * @param {String} id The ID of the watch returned from #watchHeading. */ Compass.prototype.clearWatch = function(id) { // Stop javascript timer & remove from timer list if (id && navigator.compass.timers[id]) { clearInterval(navigator.compass.timers[id]); delete navigator.compass.timers[id]; } }; PhoneGap.addConstructor(function() { if (typeof navigator.compass == "undefined") navigator.compass = new Compass(); }); /* * PhoneGap is available under *either* the terms of the modified BSD license *or* the * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. * * Copyright (c) 2005-2010, Nitobi Software Inc. * Copyright (c) 2010, IBM Corporation */ /** * Contains information about a single contact. * @param {DOMString} id unique identifier * @param {DOMString} displayName * @param {ContactName} name * @param {DOMString} nickname * @param {ContactField[]} phoneNumbers array of phone numbers * @param {ContactField[]} emails array of email addresses * @param {ContactAddress[]} addresses array of addresses * @param {ContactField[]} ims instant messaging user ids * @param {ContactOrganization[]} organizations * @param {DOMString} published date contact was first created * @param {DOMString} updated date contact was last updated * @param {DOMString} birthday contact's birthday * @param (DOMString} anniversary contact's anniversary * @param {DOMString} gender contact's gender * @param {DOMString} note user notes about contact * @param {DOMString} preferredUsername * @param {ContactField[]} photos * @param {ContactField[]} tags * @param {ContactField[]} relationships * @param {ContactField[]} urls contact's web sites * @param {ContactAccounts[]} accounts contact's online accounts * @param {DOMString} utcOffset UTC time zone offset * @param {DOMString} connected */ var Contact = function(id, displayName, name, nickname, phoneNumbers, emails, addresses, ims, organizations, published, updated, birthday, anniversary, gender, note, preferredUsername, photos, tags, relationships, urls, accounts, utcOffset, connected) { this.id = id || null; this.displayName = displayName || null; this.name = name || null; // ContactName this.nickname = nickname || null; this.phoneNumbers = phoneNumbers || null; // ContactField[] this.emails = emails || null; // ContactField[] this.addresses = addresses || null; // ContactAddress[] this.ims = ims || null; // ContactField[] this.organizations = organizations || null; // ContactOrganization[] this.published = published || null; this.updated = updated || null; this.birthday = birthday || null; this.anniversary = anniversary || null; this.gender = gender || null; this.note = note || null; this.preferredUsername = preferredUsername || null; this.photos = photos || null; // ContactField[] this.tags = tags || null; // ContactField[] this.relationships = relationships || null; // ContactField[] this.urls = urls || null; // ContactField[] this.accounts = accounts || null; // ContactAccount[] this.utcOffset = utcOffset || null; this.connected = connected || null; }; /** * Removes contact from device storage. * @param successCB success callback * @param errorCB error callback */ Contact.prototype.remove = function(successCB, errorCB) { if (this.id == null) { var errorObj = new ContactError(); errorObj.code = ContactError.NOT_FOUND_ERROR; errorCB(errorObj); } PhoneGap.exec(successCB, errorCB, "Contacts", "remove", [this.id]); }; /** * Creates a deep copy of this Contact. * With the contact ID set to null. * @return copy of this Contact */ Contact.prototype.clone = function() { var clonedContact = PhoneGap.clone(this); clonedContact.id = null; return clonedContact; }; /** * Persists contact to device storage. * @param successCB success callback * @param errorCB error callback */ Contact.prototype.save = function(successCB, errorCB) { }; /** * Contact name. * @param formatted * @param familyName * @param givenName * @param middle * @param prefix * @param suffix */ var ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) { this.formatted = formatted || null; this.familyName = familyName || null; this.givenName = givenName || null; this.middleName = middle || null; this.honorificPrefix = prefix || null; this.honorificSuffix = suffix || null; }; /** * Generic contact field. * @param type * @param value * @param primary */ var ContactField = function(type, value, primary) { this.type = type || null; this.value = value || null; this.primary = primary || null; }; /** * Contact address. * @param formatted * @param streetAddress * @param locality * @param region * @param postalCode * @param country */ var ContactAddress = function(formatted, streetAddress, locality, region, postalCode, country) { this.formatted = formatted || null; this.streetAddress = streetAddress || null; this.locality = locality || null; this.region = region || null; this.postalCode = postalCode || null; this.country = country || null; }; /** * Contact organization. * @param name * @param dept * @param title * @param startDate * @param endDate * @param location * @param desc */ var ContactOrganization = function(name, dept, title, startDate, endDate, location, desc) { this.name = name || null; this.department = dept || null; this.title = title || null; this.startDate = startDate || null; this.endDate = endDate || null; this.location = location || null; this.description = desc || null; }; /** * Contact account. * @param domain * @param username * @param userid */ var ContactAccount = function(domain, username, userid) { this.domain = domain || null; this.username = username || null; this.userid = userid || null; } /** * Represents a group of Contacts. */ var Contacts = function() { this.inProgress = false; this.records = new Array(); } /** * Returns an array of Contacts matching the search criteria. * @param fields that should be searched * @param successCB success callback * @param errorCB error callback * @param {ContactFindOptions} options that can be applied to contact searching * @return array of Contacts matching search criteria */ Contacts.prototype.find = function(fields, successCB, errorCB, options) { PhoneGap.exec(successCB, errorCB, "Contacts", "search", [fields, options]); }; /** * This function creates a new contact, but it does not persist the contact * to device storage. To persist the contact to device storage, invoke * contact.save(). * @param properties an object who's properties will be examined to create a new Contact * @returns new Contact object */ Contacts.prototype.create = function(properties) { var contact = new Contact(); for (i in properties) { if (contact[i]!='undefined') { contact[i]=properties[i]; } } return contact; }; /** * ContactFindOptions. * @param filter used to match contacts against * @param multiple boolean used to determine if more than one contact should be returned * @param limit maximum number of results to return from the contacts search * @param updatedSince return only contact records that have been updated on or after the given time */ var ContactFindOptions = function(filter, multiple, limit, updatedSince) { this.filter = filter || ''; this.multiple = multiple || false; this.limit = limit || 1; this.updatedSince = updatedSince || ''; }; /** * ContactError. * An error code assigned by an implementation when an error has occurred */ var ContactError = function() { this.code=null; }; /** * Error codes */ ContactError.UNKNOWN_ERROR = 0; ContactError.INVALID_ARGUMENT_ERROR = 1; ContactError.NOT_FOUND_ERROR = 2; ContactError.TIMEOUT_ERROR = 3; ContactError.PENDING_OPERATION_ERROR = 4; ContactError.IO_ERROR = 5; ContactError.NOT_SUPPORTED_ERROR = 6; ContactError.PERMISSION_DENIED_ERROR = 20; /** * Add the contact interface into the browser. */ PhoneGap.addConstructor(function() { if(typeof navigator.service == "undefined") navigator.service = new Object(); if(typeof navigator.service.contacts == "undefined") navigator.service.contacts = new Contacts(); }); /* * PhoneGap is available under *either* the terms of the modified BSD license *or* the * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. * * Copyright (c) 2005-2010, Nitobi Software Inc. * Copyright (c) 2010, IBM Corporation */ // TODO: Needs to be commented var Crypto = function() { }; Crypto.prototype.encrypt = function(seed, string, callback) { this.encryptWin = callback; PhoneGap.exec(null, null, "Crypto", "encrypt", [seed, string]); }; Crypto.prototype.decrypt = function(seed, string, callback) { this.decryptWin = callback; PhoneGap.exec(null, null, "Crypto", "decrypt", [seed, string]); }; Crypto.prototype.gotCryptedString = function(string) { this.encryptWin(string); }; Crypto.prototype.getPlainString = function(string) { this.decryptWin(string); }; PhoneGap.addConstructor(function() { if (typeof navigator.Crypto == "undefined") navigator.Crypto = new Crypto(); }); /* * PhoneGap is available under *either* the terms of the modified BSD license *or* the * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. * * Copyright (c) 2005-2010, Nitobi Software Inc. * Copyright (c) 2010, IBM Corporation */ /** * This represents the mobile device, and provides properties for inspecting the model, version, UUID of the * phone, etc. * @constructor */ function Device() { this.available = PhoneGap.available; this.platform = null; this.version = null; this.name = null; this.uuid = null; this.phonegap = null; var me = this; this.getInfo( function(info) { me.available = true; me.platform = info.platform; me.version = info.version; me.uuid = info.uuid; me.phonegap = info.phonegap; PhoneGap.onPhoneGapInfoReady.fire(); }, function(e) { me.available = false; console.log("Error initializing PhoneGap: " + e); alert("Error initializing PhoneGap: "+e); }); } /** * Get device info * * @param {Function} successCallback The function to call when the heading data is available * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL) */ Device.prototype.getInfo = function(successCallback, errorCallback) { // successCallback required if (typeof successCallback != "function") { console.log("Device Error: successCallback is not a function"); return; } // errorCallback optional if (errorCallback && (typeof errorCallback != "function")) { console.log("Device Error: errorCallback is not a function"); return; } // Get info PhoneGap.exec(successCallback, errorCallback, "Device", "getDeviceInfo", []); }; /* * This is only for Android. * * You must explicitly override the back button. */ Device.prototype.overrideBackButton = function() { BackButton.override(); } /* * This is only for Android. * * This resets the back button to the default behaviour */ Device.prototype.resetBackButton = function() { BackButton.reset(); } /* * This is only for Android. * * This terminates the activity! */ Device.prototype.exitApp = function() { BackButton.exitApp(); } PhoneGap.addConstructor(function() { navigator.device = window.device = new Device(); }); /* * PhoneGap is available under *either* the terms of the modified BSD license *or* the * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. * * Copyright (c) 2005-2010, Nitobi Software Inc. * Copyright (c) 2010, IBM Corporation */ /** * This class provides generic read and write access to the mobile device file system. * They are not used to read files from a server. */ /** * List of files */ function FileList() { this.files = {}; }; /** * Describes a single file in a FileList */ function File() { this.name = null; this.type = null; this.urn = null; }; /** * Create an event object since we can't set target on DOM event. * * @param type * @param target * */ File._createEvent = function(type, target) { // Can't create event object, since we can't set target (its readonly) //var evt = document.createEvent('Events'); //evt.initEvent("onload", false, false); var evt = {"type": type}; evt.target = target; return evt; }; function FileError() { // File error codes // Found in DOMException this.NOT_FOUND_ERR = 1; this.SECURITY_ERR = 2; this.ABORT_ERR = 3; // Added by this specification this.NOT_READABLE_ERR = 4; this.ENCODING_ERR = 5; this.NO_MODIFICATION_ALLOWED_ERR = 6; this.INVALID_STATE_ERR = 7; this.SYNTAX_ERR = 8; this.code = null; }; //----------------------------------------------------------------------------- // File manager //----------------------------------------------------------------------------- function FileMgr() { }; FileMgr.prototype.getFileBasePaths = function() { }; FileMgr.prototype.testSaveLocationExists = function(successCallback, errorCallback) { PhoneGap.exec(successCallback, errorCallback, "File", "testSaveLocationExists", []); }; FileMgr.prototype.testFileExists = function(fileName, successCallback, errorCallback) { PhoneGap.exec(successCallback, errorCallback, "File", "testFileExists", [fileName]); }; FileMgr.prototype.testDirectoryExists = function(dirName, successCallback, errorCallback) { PhoneGap.exec(successCallback, errorCallback, "File", "testDirectoryExists", [dirName]); }; FileMgr.prototype.createDirectory = function(dirName, successCallback, errorCallback) { PhoneGap.exec(successCallback, errorCallback, "File", "createDirectory", [dirName]); }; FileMgr.prototype.deleteDirectory = function(dirName, successCallback, errorCallback) { PhoneGap.exec(successCallback, errorCallback, "File", "deleteDirectory", [dirName]); }; FileMgr.prototype.deleteFile = function(fileName, successCallback, errorCallback) { PhoneGap.exec(successCallback, errorCallback, "File", "deleteFile", [fileName]); }; FileMgr.prototype.getFreeDiskSpace = function(successCallback, errorCallback) { PhoneGap.exec(successCallback, errorCallback, "File", "getFreeDiskSpace", []); }; FileMgr.prototype.writeAsText = function(fileName, data, append, successCallback, errorCallback) { PhoneGap.exec(successCallback, errorCallback, "File", "writeAsText", [fileName, data, append]); }; FileMgr.prototype.truncate = function(fileName, size, successCallback, errorCallback) { PhoneGap.exec(successCallback, errorCallback, "File", "truncate", [fileName, size]); }; FileMgr.prototype.readAsText = function(fileName, encoding, successCallback, errorCallback) { PhoneGap.exec(successCallback, errorCallback, "File", "readAsText", [fileName, encoding]); }; FileMgr.prototype.readAsDataURL = function(fileName, successCallback, errorCallback) { PhoneGap.exec(successCallback, errorCallback, "File", "readAsDataURL", [fileName]); }; PhoneGap.addConstructor(function() { if (typeof navigator.fileMgr == "undefined") navigator.fileMgr = new FileMgr(); }); //----------------------------------------------------------------------------- // File Reader //----------------------------------------------------------------------------- // TODO: All other FileMgr function operate on the SD card as root. However, // for FileReader & FileWriter the root is not SD card. Should this be changed? /** * This class reads the mobile device file system. * * For Android: * The root directory is the root of the file system. * To read from the SD card, the file name is "sdcard/my_file.txt" */ function FileReader() { this.fileName = ""; this.readyState = 0; // File data this.result = null; // Error this.error = null; // Event handlers this.onloadstart = null; // When the read starts. this.onprogress = null; // While reading (and decoding) file or fileBlob data, and reporting partial file data (progess.loaded/progress.total) this.onload = null; // When the read has successfully completed. this.onerror = null; // When the read has failed (see errors). this.onloadend = null; // When the request has completed (either in success or failure). this.onabort = null; // When the read has been aborted. For instance, by invoking the abort() method. }; // States FileReader.EMPTY = 0; FileReader.LOADING = 1; FileReader.DONE = 2; /** * Abort reading file. */ FileReader.prototype.abort = function() { this.readyState = FileReader.DONE; // If abort callback if (typeof this.onabort == "function") { var evt = File._createEvent("abort", this); this.onabort(evt); } // TODO: Anything else to do? Maybe sent to native? }; /** * Read text file. * * @param file The name of the file * @param encoding [Optional] (see http://www.iana.org/assignments/character-sets) */ FileReader.prototype.readAsText = function(file, encoding) { this.fileName = file; // LOADING state this.readyState = FileReader.LOADING; // If loadstart callback if (typeof this.onloadstart == "function") { var evt = File._createEvent("loadstart", this); this.onloadstart(evt); } // Default encoding is UTF-8 var enc = encoding ? encoding : "UTF-8"; var me = this; // Read file navigator.fileMgr.readAsText(file, enc, // Success callback function(r) { // If DONE (cancelled), then don't do anything if (me.readyState == FileReader.DONE) { return; } // Save result me.result = r; // DONE state me.readyState = FileReader.DONE; // If onload callback if (typeof me.onload == "function") { var evt = File._createEvent("load", me); me.onload(evt); } // If onloadend callback if (typeof me.onloadend == "function") { var evt = File._createEvent("loadend", me); me.onloadend(evt); } }, // Error callback function(e) { // If DONE (cancelled), then don't do anything if (me.readyState == FileReader.DONE) { return; } // Save error me.error = e; // DONE state me.readyState = FileReader.DONE; // If onerror callback if (typeof me.onerror == "function") { var evt = File._createEvent("error", me); me.onerror(evt); } // If onloadend callback if (typeof me.onloadend == "function") { var evt = File._createEvent("loadend", me); me.onloadend(evt); } } ); }; /** * Read file and return data as a base64 encoded data url. * A data url is of the form: * data:[][;base64], * * @param file The name of the file */ FileReader.prototype.readAsDataURL = function(file) { this.fileName = file; // LOADING state this.readyState = FileReader.LOADING; // If loadstart callback if (typeof this.onloadstart == "function") { var evt = File._createEvent("loadstart", this); this.onloadstart(evt); } var me = this; // Read file navigator.fileMgr.readAsDataURL(file, // Success callback function(r) { // If DONE (cancelled), then don't do anything if (me.readyState == FileReader.DONE) { return; } // Save result me.result = r; // DONE state me.readyState = FileReader.DONE; // If onload callback if (typeof me.onload == "function") { var evt = File._createEvent("load", me); me.onload(evt); } // If onloadend callback if (typeof me.onloadend == "function") { var evt = File._createEvent("loadend", me); me.onloadend(evt); } }, // Error callback function(e) { // If DONE (cancelled), then don't do anything if (me.readyState == FileReader.DONE) { return; } // Save error me.error = e; // DONE state me.readyState = FileReader.DONE; // If onerror callback if (typeof me.onerror == "function") { var evt = File._createEvent("error", me); me.onerror(evt); } // If onloadend callback if (typeof me.onloadend == "function") { var evt = File._createEvent("loadend", me); me.onloadend(evt); } } ); }; /** * Read file and return data as a binary data. * * @param file The name of the file */ FileReader.prototype.readAsBinaryString = function(file) { // TODO - Can't return binary data to browser. this.fileName = file; }; /** * Read file and return data as a binary data. * * @param file The name of the file */ FileReader.prototype.readAsArrayBuffer = function(file) { // TODO - Can't return binary data to browser. this.fileName = file; }; //----------------------------------------------------------------------------- // File Writer //----------------------------------------------------------------------------- /** * This class writes to the mobile device file system. * * For Android: * The root directory is the root of the file system. * To write to the SD card, the file name is "sdcard/my_file.txt" */ function FileWriter() { this.fileName = ""; this.readyState = 0; // EMPTY this.result = null; // Error this.error = null; // Event handlers this.onwritestart = null; // When writing starts this.onprogress = null; // While writing the file, and reporting partial file data this.onwrite = null; // When the write has successfully completed. this.onwriteend = null; // When the request has completed (either in success or failure). this.onabort = null; // When the write has been aborted. For instance, by invoking the abort() method. this.onerror = null; // When the write has failed (see errors). }; // States FileWriter.INIT = 0; FileWriter.WRITING = 1; FileWriter.DONE = 2; /** * Abort writing file. */ FileWriter.prototype.abort = function() { this.readyState = FileWriter.DONE; // If abort callback if (typeof this.onabort == "function") { var evt = File._createEvent("abort", this); this.onabort(evt); } // TODO: Anything else to do? Maybe sent to native? }; FileWriter.prototype.writeAsText = function(file, text, bAppend) { // Throw an exception if we are already writing a file if (this.readyState == FileWriter.WRITING) { throw FileError.INVALID_STATE_ERR; } if (bAppend != true) { bAppend = false; // for null values } this.fileName = file; // WRITING state this.readyState = FileWriter.WRITING; var me = this; // If onwritestart callback if (typeof me.onwritestart == "function") { var evt = File._createEvent("writestart", me); me.onwritestart(evt); } // Write file navigator.fileMgr.writeAsText(file, text, bAppend, // Success callback function(r) { // If DONE (cancelled), then don't do anything if (me.readyState == FileWriter.DONE) { return; } // Save result me.result = r; // If onwrite callback if (typeof me.onwrite == "function") { var evt = File._createEvent("write", me); me.onwrite(evt); } // DONE state me.readyState = FileWriter.DONE; // If onwriteend callback if (typeof me.onwriteend == "function") { var evt = File._createEvent("writeend", me); me.onwriteend(evt); } }, // Error callback function(e) { // If DONE (cancelled), then don't do anything if (me.readyState == FileWriter.DONE) { return; } // Save error me.error = e; // If onerror callback if (typeof me.onerror == "function") { var evt = File._createEvent("error", me); me.onerror(evt); } // DONE state me.readyState = FileWriter.DONE; // If onwriteend callback if (typeof me.onwriteend == "function") { var evt = File._createEvent("writeend", me); me.onwriteend(evt); } } ); }; FileWriter.prototype.truncate = function(file, size) { // Throw an exception if we are already writing a file if (this.readyState == FileWriter.WRITING) { throw FileError.INVALID_STATE_ERR; } this.fileName = file; // WRITING state this.readyState = FileWriter.WRITING; var me = this; // If onwritestart callback if (typeof me.onwritestart == "function") { var evt = File._createEvent("writestart", me); me.onwritestart(evt); } // Write file navigator.fileMgr.truncate(file, size, // Success callback function(r) { // If DONE (cancelled), then don't do anything if (me.readyState == FileWriter.DONE) { return; } // Save result me.result = r; // If onwrite callback if (typeof me.onwrite == "function") { var evt = File._createEvent("write", me); me.onwrite(evt); } // DONE state me.readyState = FileWriter.DONE; // If onwriteend callback if (typeof me.onwriteend == "function") { var evt = File._createEvent("writeend", me); me.onwriteend(evt); } }, // Error callback function(e) { // If DONE (cancelled), then don't do anything if (me.readyState == FileWriter.DONE) { return; } // Save error me.error = e; // If onerror callback if (typeof me.onerror == "function") { var evt = File._createEvent("error", me); me.onerror(evt); } // DONE state me.readyState = FileWriter.DONE; // If onwriteend callback if (typeof me.onwriteend == "function") { var evt = File._createEvent("writeend", me); me.onwriteend(evt); } } ); }; /* * PhoneGap is available under *either* the terms of the modified BSD license *or* the * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. * * Copyright (c) 2005-2010, Nitobi Software Inc. * Copyright (c) 2010, IBM Corporation */ /** * This class provides access to device GPS data. * @constructor */ function Geolocation() { // The last known GPS position. this.lastPosition = null; // Geolocation listeners this.listeners = {}; }; /** * Position error object * * @param code * @param message */ function PositionError(code, message) { this.code = code; this.message = message; }; PositionError.PERMISSION_DENIED = 1; PositionError.POSITION_UNAVAILABLE = 2; PositionError.TIMEOUT = 3; /** * Asynchronously aquires the current position. * * @param {Function} successCallback The function to call when the position data is available * @param {Function} errorCallback The function to call when there is an error getting the heading position. (OPTIONAL) * @param {PositionOptions} options The options for getting the position data. (OPTIONAL) */ Geolocation.prototype.getCurrentPosition = function(successCallback, errorCallback, options) { if (navigator._geo.listeners["global"]) { console.log("Geolocation Error: Still waiting for previous getCurrentPosition() request."); try { errorCallback(new PositionError(PositionError.TIMEOUT, "Geolocation Error: Still waiting for previous getCurrentPosition() request.")); } catch (e) { } return; } var maximumAge = 10000; var enableHighAccuracy = false; var timeout = 10000; if (typeof options != "undefined") { if (typeof options.maximumAge != "undefined") { maximumAge = options.maximumAge; } if (typeof options.enableHighAccuracy != "undefined") { enableHighAccuracy = options.enableHighAccuracy; } if (typeof options.timeout != "undefined") { timeout = options.timeout; } } navigator._geo.listeners["global"] = {"success" : successCallback, "fail" : errorCallback }; PhoneGap.exec(null, null, "Geolocation", "getCurrentLocation", [enableHighAccuracy, timeout, maximumAge]); } /** * Asynchronously watches the geolocation for changes to geolocation. When a change occurs, * the successCallback is called with the new location. * * @param {Function} successCallback The function to call each time the location data is available * @param {Function} errorCallback The function to call when there is an error getting the location data. (OPTIONAL) * @param {PositionOptions} options The options for getting the location data such as frequency. (OPTIONAL) * @return String The watch id that must be passed to #clearWatch to stop watching. */ Geolocation.prototype.watchPosition = function(successCallback, errorCallback, options) { var maximumAge = 10000; var enableHighAccuracy = false; var timeout = 10000; if (typeof options != "undefined") { if (typeof options.frequency != "undefined") { maximumAge = options.frequency; } if (typeof options.maximumAge != "undefined") { maximumAge = options.maximumAge; } if (typeof options.enableHighAccuracy != "undefined") { enableHighAccuracy = options.enableHighAccuracy; } if (typeof options.timeout != "undefined") { timeout = options.timeout; } } var id = PhoneGap.createUUID(); navigator._geo.listeners[id] = {"success" : successCallback, "fail" : errorCallback }; PhoneGap.exec(null, null, "Geolocation", "start", [id, enableHighAccuracy, timeout, maximumAge]); return id; }; /* * Native callback when watch position has a new position. * PRIVATE METHOD * * @param {String} id * @param {Number} lat * @param {Number} lng * @param {Number} alt * @param {Number} altacc * @param {Number} head * @param {Number} vel * @param {Number} stamp */ Geolocation.prototype.success = function(id, lat, lng, alt, altacc, head, vel, stamp) { var coords = new Coordinates(lat, lng, alt, altacc, head, vel); var loc = new Position(coords, stamp); try { if (lat == "undefined" || lng == "undefined") { navigator._geo.listeners[id].fail(new PositionError(PositionError.POSITION_UNAVAILABLE, "Lat/Lng are undefined.")); } else { navigator._geo.lastPosition = loc; navigator._geo.listeners[id].success(loc); } } catch (e) { console.log("Geolocation Error: Error calling success callback function."); } if (id == "global") { delete navigator._geo.listeners["global"]; } }; /** * Native callback when watch position has an error. * PRIVATE METHOD * * @param {String} id The ID of the watch * @param {Number} code The error code * @param {String} msg The error message */ Geolocation.prototype.fail = function(id, code, msg) { try { navigator._geo.listeners[id].fail(new PositionError(code, msg)); } catch (e) { console.log("Geolocation Error: Error calling error callback function."); } }; /** * Clears the specified heading watch. * * @param {String} id The ID of the watch returned from #watchPosition */ Geolocation.prototype.clearWatch = function(id) { PhoneGap.exec(null, null, "Geolocation", "stop", [id]); delete navigator._geo.listeners[id]; }; /** * Force the PhoneGap geolocation to be used instead of built-in. */ Geolocation.usingPhoneGap = false; Geolocation.usePhoneGap = function() { if (Geolocation.usingPhoneGap) { return; } Geolocation.usingPhoneGap = true; // Set built-in geolocation methods to our own implementations // (Cannot replace entire geolocation, but can replace individual methods) navigator.geolocation.setLocation = navigator._geo.setLocation; navigator.geolocation.getCurrentPosition = navigator._geo.getCurrentPosition; navigator.geolocation.watchPosition = navigator._geo.watchPosition; navigator.geolocation.clearWatch = navigator._geo.clearWatch; navigator.geolocation.start = navigator._geo.start; navigator.geolocation.stop = navigator._geo.stop; }; PhoneGap.addConstructor(function() { navigator._geo = new Geolocation(); // No native geolocation object for Android 1.x, so use PhoneGap geolocation if (typeof navigator.geolocation == 'undefined') { navigator.geolocation = navigator._geo; Geolocation.usingPhoneGap = true; } }); /* * PhoneGap is available under *either* the terms of the modified BSD license *or* the * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. * * Copyright (c) 2005-2010, Nitobi Software Inc. * Copyright (c) 2010, IBM Corporation */ function KeyEvent() { } KeyEvent.prototype.backTrigger = function() { var e = document.createEvent('Events'); e.initEvent('backKeyDown'); document.dispatchEvent(e); } if (document.keyEvent == null || typeof document.keyEvent == 'undefined') { window.keyEvent = document.keyEvent = new KeyEvent(); } /* * PhoneGap is available under *either* the terms of the modified BSD license *or* the * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. * * Copyright (c) 2005-2010, Nitobi Software Inc. * Copyright (c) 2010, IBM Corporation */ /** * List of media objects. * PRIVATE */ PhoneGap.mediaObjects = {}; /** * Object that receives native callbacks. * PRIVATE */ PhoneGap.Media = function() {}; /** * Get the media object. * PRIVATE * * @param id The media object id (string) */ PhoneGap.Media.getMediaObject = function(id) { return PhoneGap.mediaObjects[id]; }; /** * Audio has status update. * PRIVATE * * @param id The media object id (string) * @param status The status code (int) * @param msg The status message (string) */ PhoneGap.Media.onStatus = function(id, msg, value) { var media = PhoneGap.mediaObjects[id]; // If state update if (msg == Media.MEDIA_STATE) { if (value == Media.MEDIA_STOPPED) { if (media.successCallback) { media.successCallback(); } } if (media.statusCallback) { media.statusCallback(value); } } else if (msg == Media.MEDIA_DURATION) { media._duration = value; } else if (msg == Media.MEDIA_ERROR) { if (media.errorCallback) { media.errorCallback(value); } } }; /** * This class provides access to the device media, interfaces to both sound and video * * @param src The file name or url to play * @param successCallback The callback to be called when the file is done playing or recording. * successCallback() - OPTIONAL * @param errorCallback The callback to be called if there is an error. * errorCallback(int errorCode) - OPTIONAL * @param statusCallback The callback to be called when media status has changed. * statusCallback(int statusCode) - OPTIONAL * @param positionCallback The callback to be called when media position has changed. * positionCallback(long position) - OPTIONAL */ Media = function(src, successCallback, errorCallback, statusCallback, positionCallback) { // successCallback optional if (successCallback && (typeof successCallback != "function")) { console.log("Media Error: successCallback is not a function"); return; } // errorCallback optional if (errorCallback && (typeof errorCallback != "function")) { console.log("Media Error: errorCallback is not a function"); return; } // statusCallback optional if (statusCallback && (typeof statusCallback != "function")) { console.log("Media Error: statusCallback is not a function"); return; } // statusCallback optional if (positionCallback && (typeof positionCallback != "function")) { console.log("Media Error: positionCallback is not a function"); return; } this.id = PhoneGap.createUUID(); PhoneGap.mediaObjects[this.id] = this; this.src = src; this.successCallback = successCallback; this.errorCallback = errorCallback; this.statusCallback = statusCallback; this.positionCallback = positionCallback; this._duration = -1; this._position = -1; }; // Media messages Media.MEDIA_STATE = 1; Media.MEDIA_DURATION = 2; Media.MEDIA_ERROR = 9; // Media states Media.MEDIA_NONE = 0; Media.MEDIA_STARTING = 1; Media.MEDIA_RUNNING = 2; Media.MEDIA_PAUSED = 3; Media.MEDIA_STOPPED = 4; Media.MEDIA_MSG = ["None", "Starting", "Running", "Paused", "Stopped"]; // TODO: Will MediaError be used? /** * This class contains information about any Media errors. * @constructor */ function MediaError() { this.code = null, this.message = ""; }; MediaError.MEDIA_ERR_ABORTED = 1; MediaError.MEDIA_ERR_NETWORK = 2; MediaError.MEDIA_ERR_DECODE = 3; MediaError.MEDIA_ERR_NONE_SUPPORTED = 4; /** * Start or resume playing audio file. */ Media.prototype.play = function() { PhoneGap.exec(null, null, "Media", "startPlayingAudio", [this.id, this.src]); }; /** * Stop playing audio file. */ Media.prototype.stop = function() { return PhoneGap.exec(null, null, "Media", "stopPlayingAudio", [this.id]); }; /** * Pause playing audio file. */ Media.prototype.pause = function() { PhoneGap.exec(null, null, "Media", "pausePlayingAudio", [this.id]); }; /** * Get duration of an audio file. * The duration is only set for audio that is playing, paused or stopped. * * @return duration or -1 if not known. */ Media.prototype.getDuration = function() { return this._duration; }; /** * Get position of audio. * * @return */ Media.prototype.getCurrentPosition = function(success, fail) { PhoneGap.exec(success, fail, "Media", "getCurrentPositionAudio", [this.id]); }; /** * Start recording audio file. */ Media.prototype.startRecord = function() { PhoneGap.exec(null, null, "Media", "startRecordingAudio", [this.id, this.src]); }; /** * Stop recording audio file. */ Media.prototype.stopRecord = function() { PhoneGap.exec(null, null, "Media", "stopRecordingAudio", [this.id]); }; /* * PhoneGap is available under *either* the terms of the modified BSD license *or* the * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. * * Copyright (c) 2005-2010, Nitobi Software Inc. * Copyright (c) 2010, IBM Corporation */ /** * This class contains information about any NetworkStatus. * @constructor */ function NetworkStatus() { //this.code = null; //this.message = ""; }; NetworkStatus.NOT_REACHABLE = 0; NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK = 1; NetworkStatus.REACHABLE_VIA_WIFI_NETWORK = 2; /** * This class provides access to device Network data (reachability). * @constructor */ function Network() { /** * The last known Network status. * { hostName: string, ipAddress: string, remoteHostStatus: int(0/1/2), internetConnectionStatus: int(0/1/2), localWiFiConnectionStatus: int (0/2) } */ this.lastReachability = null; }; /** * Called by the geolocation framework when the reachability status has changed. * @param {Reachibility} reachability The current reachability status. */ // TODO: Callback from native code not implemented for Android Network.prototype.updateReachability = function(reachability) { this.lastReachability = reachability; }; /** * Determine if a URI is reachable over the network. * @param {Object} uri * @param {Function} callback * @param {Object} options (isIpAddress:boolean) */ Network.prototype.isReachable = function(uri, callback, options) { var isIpAddress = false; if (options && options.isIpAddress) { isIpAddress = options.isIpAddress; } PhoneGap.exec(callback, null, "Network Status", "isReachable", [uri, isIpAddress]); }; PhoneGap.addConstructor(function() { if (typeof navigator.network == "undefined") navigator.network = new Network(); }); /* * PhoneGap is available under *either* the terms of the modified BSD license *or* the * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. * * Copyright (c) 2005-2010, Nitobi Software Inc. * Copyright (c) 2010, IBM Corporation */ /** * This class provides access to notifications on the device. */ function Notification() { } /** * Open a native alert dialog, with a customizable title and button text. * * @param {String} message Message to print in the body of the alert * @param {Function} completeCallback The callback that is called when user clicks on a button. * @param {String} title Title of the alert dialog (default: Alert) * @param {String} buttonLabel Label of the close button (default: OK) */ Notification.prototype.alert = function(message, completeCallback, title, buttonLabel) { var _title = (title || "Alert"); var _buttonLabel = (buttonLabel || "OK"); PhoneGap.exec(completeCallback, null, "Notification", "alert", [message,_title,_buttonLabel]); }; /** * Open a native confirm dialog, with a customizable title and button text. * The result that the user selects is returned to the result callback. * * @param {String} message Message to print in the body of the alert * @param {Function} resultCallback The callback that is called when user clicks on a button. * @param {String} title Title of the alert dialog (default: Confirm) * @param {String} buttonLabels Comma separated list of the labels of the buttons (default: 'OK,Cancel') */ Notification.prototype.confirm = function(message, resultCallback, title, buttonLabels) { var _title = (title || "Confirm"); var _buttonLabels = (buttonLabels || "OK,Cancel"); PhoneGap.exec(resultCallback, null, "Notification", "confirm", [message,_title,_buttonLabels]); }; /** * Start spinning the activity indicator on the statusbar */ Notification.prototype.activityStart = function() { PhoneGap.exec(null, null, "Notification", "activityStart", ["Busy","Please wait..."]); }; /** * Stop spinning the activity indicator on the statusbar, if it's currently spinning */ Notification.prototype.activityStop = function() { PhoneGap.exec(null, null, "Notification", "activityStop", []); }; /** * Display a progress dialog with progress bar that goes from 0 to 100. * * @param {String} title Title of the progress dialog. * @param {String} message Message to display in the dialog. */ Notification.prototype.progressStart = function(title, message) { PhoneGap.exec(null, null, "Notification", "progressStart", [title, message]); }; /** * Set the progress dialog value. * * @param {Number} value 0-100 */ Notification.prototype.progressValue = function(value) { PhoneGap.exec(null, null, "Notification", "progressValue", [value]); }; /** * Close the progress dialog. */ Notification.prototype.progressStop = function() { PhoneGap.exec(null, null, "Notification", "progressStop", []); }; /** * Causes the device to blink a status LED. * * @param {Integer} count The number of blinks. * @param {String} colour The colour of the light. */ Notification.prototype.blink = function(count, colour) { // NOT IMPLEMENTED }; /** * Causes the device to vibrate. * * @param {Integer} mills The number of milliseconds to vibrate for. */ Notification.prototype.vibrate = function(mills) { PhoneGap.exec(null, null, "Notification", "vibrate", [mills]); }; /** * Causes the device to beep. * On Android, the default notification ringtone is played "count" times. * * @param {Integer} count The number of beeps. */ Notification.prototype.beep = function(count) { PhoneGap.exec(null, null, "Notification", "beep", [count]); }; PhoneGap.addConstructor(function() { if (typeof navigator.notification == "undefined") navigator.notification = new Notification(); }); /* * PhoneGap is available under *either* the terms of the modified BSD license *or* the * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. * * Copyright (c) 2005-2010, Nitobi Software Inc. * Copyright (c) 2010, IBM Corporation */ /** * This class contains position information. * @param {Object} lat * @param {Object} lng * @param {Object} acc * @param {Object} alt * @param {Object} altacc * @param {Object} head * @param {Object} vel * @constructor */ function Position(coords, timestamp) { this.coords = coords; this.timestamp = (timestamp != 'undefined') ? timestamp : new Date().getTime(); } function Coordinates(lat, lng, alt, acc, head, vel, altacc) { /** * The latitude of the position. */ this.latitude = lat; /** * The longitude of the position, */ this.longitude = lng; /** * The accuracy of the position. */ this.accuracy = acc; /** * The altitude of the position. */ this.altitude = alt; /** * The direction the device is moving at the position. */ this.heading = head; /** * The velocity with which the device is moving at the position. */ this.speed = vel; /** * The altitude accuracy of the position. */ this.altitudeAccuracy = (altacc != 'undefined') ? altacc : null; } /** * This class specifies the options for requesting position data. * @constructor */ function PositionOptions() { /** * Specifies the desired position accuracy. */ this.enableHighAccuracy = true; /** * The timeout after which if position data cannot be obtained the errorCallback * is called. */ this.timeout = 10000; } /** * This class contains information about any GSP errors. * @constructor */ function PositionError() { this.code = null; this.message = ""; } PositionError.UNKNOWN_ERROR = 0; PositionError.PERMISSION_DENIED = 1; PositionError.POSITION_UNAVAILABLE = 2; PositionError.TIMEOUT = 3; /* * PhoneGap is available under *either* the terms of the modified BSD license *or* the * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. * * Copyright (c) 2005-2010, Nitobi Software Inc. * Copyright (c) 2010, IBM Corporation */ PhoneGap.addConstructor(function() { if (typeof navigator.splashScreen == "undefined") { navigator.splashScreen = SplashScreen; // SplashScreen object come from native side through addJavaScriptInterface } });/* * PhoneGap is available under *either* the terms of the modified BSD license *or* the * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. * * Copyright (c) 2005-2010, Nitobi Software Inc. * Copyright (c) 2010, IBM Corporation */ /* * This is purely for the Android 1.5/1.6 HTML 5 Storage * I was hoping that Android 2.0 would deprecate this, but given the fact that * most manufacturers ship with Android 1.5 and do not do OTA Updates, this is required */ /** * Storage object that is called by native code when performing queries. * PRIVATE METHOD */ var DroidDB = function() { this.queryQueue = {}; }; /** * Callback from native code when result from a query is available. * PRIVATE METHOD * * @param rawdata JSON string of the row data * @param id Query id */ DroidDB.prototype.addResult = function(rawdata, id) { try { eval("var data = " + rawdata + ";"); var query = this.queryQueue[id]; query.resultSet.push(data); } catch (e) { console.log("DroidDB.addResult(): Error="+e); } }; /** * Callback from native code when query is complete. * PRIVATE METHOD * * @param id Query id */ DroidDB.prototype.completeQuery = function(id) { var query = this.queryQueue[id]; if (query) { try { delete this.queryQueue[id]; // Get transaction var tx = query.tx; // If transaction hasn't failed // Note: We ignore all query results if previous query // in the same transaction failed. if (tx && tx.queryList[id]) { // Save query results var r = new DroidDB_Result(); r.rows.resultSet = query.resultSet; r.rows.length = query.resultSet.length; try { if (typeof query.successCallback == 'function') { query.successCallback(query.tx, r); } } catch (ex) { console.log("executeSql error calling user success callback: "+ex); } tx.queryComplete(id); } } catch (e) { console.log("executeSql error: "+e); } } }; /** * Callback from native code when query fails * PRIVATE METHOD * * @param reason Error message * @param id Query id */ DroidDB.prototype.fail = function(reason, id) { var query = this.queryQueue[id]; if (query) { try { delete this.queryQueue[id]; // Get transaction var tx = query.tx; // If transaction hasn't failed // Note: We ignore all query results if previous query // in the same transaction failed. if (tx && tx.queryList[id]) { tx.queryList = {}; try { if (typeof query.errorCallback == 'function') { query.errorCallback(query.tx, reason); } } catch (ex) { console.log("executeSql error calling user error callback: "+ex); } tx.queryFailed(id, reason); } } catch (e) { console.log("executeSql error: "+e); } } }; var DatabaseShell = function() { }; /** * Start a transaction. * Does not support rollback in event of failure. * * @param process {Function} The transaction function * @param successCallback {Function} * @param errorCallback {Function} */ DatabaseShell.prototype.transaction = function(process, successCallback, errorCallback) { var tx = new DroidDB_Tx(); tx.successCallback = successCallback; tx.errorCallback = errorCallback; try { process(tx); } catch (e) { console.log("Transaction error: "+e); if (tx.errorCallback) { try { tx.errorCallback(e); } catch (ex) { console.log("Transaction error calling user error callback: "+e); } } } }; /** * Transaction object * PRIVATE METHOD */ var DroidDB_Tx = function() { // Set the id of the transaction this.id = PhoneGap.createUUID(); // Callbacks this.successCallback = null; this.errorCallback = null; // Query list this.queryList = {}; }; /** * Mark query in transaction as complete. * If all queries are complete, call the user's transaction success callback. * * @param id Query id */ DroidDB_Tx.prototype.queryComplete = function(id) { delete this.queryList[id]; // If no more outstanding queries, then fire transaction success if (this.successCallback) { var count = 0; for (var i in this.queryList) { count++; } if (count == 0) { try { this.successCallback(); } catch(e) { console.log("Transaction error calling user success callback: " + e); } } } }; /** * Mark query in transaction as failed. * * @param id Query id * @param reason Error message */ DroidDB_Tx.prototype.queryFailed = function(id, reason) { // The sql queries in this transaction have already been run, since // we really don't have a real transaction implemented in native code. // However, the user callbacks for the remaining sql queries in transaction // will not be called. this.queryList = {}; if (this.errorCallback) { try { this.errorCallback(reason); } catch(e) { console.log("Transaction error calling user error callback: " + e); } } }; /** * SQL query object * PRIVATE METHOD * * @param tx The transaction object that this query belongs to */ var DroidDB_Query = function(tx) { // Set the id of the query this.id = PhoneGap.createUUID(); // Add this query to the queue droiddb.queryQueue[this.id] = this; // Init result this.resultSet = []; // Set transaction that this query belongs to this.tx = tx; // Add this query to transaction list this.tx.queryList[this.id] = this; // Callbacks this.successCallback = null; this.errorCallback = null; } /** * Execute SQL statement * * @param sql SQL statement to execute * @param params Statement parameters * @param successCallback Success callback * @param errorCallback Error callback */ DroidDB_Tx.prototype.executeSql = function(sql, params, successCallback, errorCallback) { // Init params array if (typeof params == 'undefined') { params = []; } // Create query and add to queue var query = new DroidDB_Query(this); droiddb.queryQueue[query.id] = query; // Save callbacks query.successCallback = successCallback; query.errorCallback = errorCallback; // Call native code PhoneGap.exec(null, null, "Storage", "executeSql", [sql, params, query.id]); }; /** * SQL result set that is returned to user. * PRIVATE METHOD */ DroidDB_Result = function() { this.rows = new DroidDB_Rows(); }; /** * SQL result set object * PRIVATE METHOD */ DroidDB_Rows = function() { this.resultSet = []; // results array this.length = 0; // number of rows }; /** * Get item from SQL result set * * @param row The row number to return * @return The row object */ DroidDB_Rows.prototype.item = function(row) { return this.resultSet[row]; }; /** * Open database * * @param name Database name * @param version Database version * @param display_name Database display name * @param size Database size in bytes * @return Database object */ DroidDB_openDatabase = function(name, version, display_name, size) { PhoneGap.exec(null, null, "Storage", "openDatabase", [name, version, display_name, size]); var db = new DatabaseShell(); return db; }; PhoneGap.addConstructor(function() { if (typeof window.openDatabase == "undefined") { navigator.openDatabase = window.openDatabase = DroidDB_openDatabase; window.droiddb = new DroidDB(); } }); /* ########################## */ /* # ./scripts/html5shiv.js # */ /* ########################## */ if(/*@cc_on!@*/false){ (function(){ var html5elmeents = "address|article|aside|audio|canvas|command|datalist|details| dialog|figure|figcaption|footer|header|hgroup|keygen|mark|meter|menu|nav| progress|ruby|section|time|video".split('|'); for(var i = 0; i < html5elmeents.length; i++){ document.createElement(html5elmeents[i]); } } )(); }