| if (typeof(DeviceInfo) != 'object') |
| DeviceInfo = {}; |
| |
| function Cordova() { |
| ready = true; |
| available = true; |
| sceneController = null; |
| }; |
| |
| |
| Cordova.exec = function(win, fail, clazz, action, args) { |
| |
| setTimeout(function() { |
| Cordova.plugins[clazz].execute(action, args, win, fail); |
| }, 0); |
| |
| } |
| |
| Cordova.checkArgs = function(args, func) { |
| if (typeof args == 'object') |
| func.apply(null, args); |
| else |
| func(args); |
| } |
| |
| Cordova.callback = function(success, win, fail) { |
| if (success) |
| win(); |
| else |
| fail(); |
| } |
| |
| // translates the action into an API call |
| accelerometerAPI = { |
| execute: function(action, args, win, fail) { |
| var actionFound = false; |
| switch(action) { |
| case 'setFastAccelerometer': |
| Cordova.checkArgs(args, navigator.accelerometer.setFastAccelerometer); |
| actionFound = true; |
| break; |
| case 'getCurrentAcceleration': |
| Cordova.checkArgs(args, navigator.accelerometer.getCurrentAcceleration); |
| actionFound = true; |
| break; |
| case 'watchAcceleration': |
| Cordova.checkArgs(args, navigator.accelerometer.watchAcceleration); |
| actionFound = true; |
| break; |
| case 'clearWatch': |
| Cordova.checkArgs(args, navigator.accelerometer.clearWatch); |
| actionFound = true; |
| break; |
| case 'start': |
| Cordova.checkArgs(args, navigator.accelerometer.start); |
| actionFound = true; |
| break; |
| } |
| |
| Cordova.callback(actionFound, win, fail); |
| } |
| } |
| |
| applicationAPI = { |
| execute: function(action, args, win, fail) { |
| var actionFound = false; |
| switch(action) { |
| case 'activate': |
| Cordova.checkArgs(args, navigator.application.activate); |
| actionFound = true; |
| break; |
| case 'deactivate': |
| Cordova.checkArgs(args, navigator.application.deactivate); |
| actionFound = true; |
| break; |
| case 'getIdentifier': |
| Cordova.checkArgs(args, navigator.application.getIdentifier); |
| actionFound = true; |
| break; |
| } |
| |
| Cordova.callback(actionFound, win, fail); |
| } |
| } |
| |
| cameraAPI = { |
| execute: function(action, args, win, fail) { |
| var actionFound = false; |
| switch(action) { |
| case 'getPicture': |
| console.log("in here"); |
| Cordova.checkArgs(args, navigator.camera.getPicture); |
| actionFound = true; |
| break; |
| } |
| |
| Cordova.callback(actionFound, win, fail); |
| } |
| } |
| |
| // translates the action into an API call |
| compassAPI = { |
| execute: function(action, args, win, fail) { |
| var actionFound = false; |
| switch(action) { |
| case 'getCurrentHeading': |
| Cordova.checkArgs(args, navigator.compass.getCurrentHeading); |
| actionFound = true; |
| break; |
| case 'watchHeading': |
| Cordova.checkArgs(args, navigator.compass.watchHeading); |
| actionFound = true; |
| break; |
| case 'clearWatch': |
| Cordova.checkArgs(args, navigator.compass.clearWatch); |
| actionFound = true; |
| break; |
| case 'start': |
| Cordova.checkArgs(args, navigator.compass.start); |
| actionFound = true; |
| break; |
| } |
| |
| Cordova.callback(actionFound, win, fail); |
| } |
| } |
| |
| debugAPI = { |
| execute: function(action, args, win, fail) { |
| var actionFound = false; |
| switch(action) { |
| case 'log': |
| Cordova.checkArgs(args, window.debug.log); |
| actionFound = true; |
| break; |
| case 'warn': |
| Cordova.checkArgs(args, window.debug.warn); |
| actionFound = true; |
| break; |
| case 'error': |
| Cordova.checkArgs(args, window.debug.error); |
| actionFound = true; |
| break; |
| } |
| |
| Cordova.callback(actionFound, win, fail); |
| } |
| } |
| |
| deviceAPI = { |
| execute: function(action, args, win, fail) { |
| var actionFound = false; |
| switch(action) { |
| case 'getDeviceInfo': |
| Cordova.checkArgs(args, navigator.device.getDeviceInfo); |
| actionFound = true; |
| break; |
| } |
| |
| Cordova.callback(actionFound, win, fail); |
| } |
| } |
| |
| geolocationAPI = { |
| execute: function(action, args, win, fail) { |
| var actionFound = false; |
| switch(action) { |
| case 'getCurrentPosition': |
| Cordova.checkArgs(args, navigator.geolocation.getCurrentPosition); |
| actionFound = true; |
| break; |
| case 'watchPosition': |
| Cordova.checkArgs(args, navigator.geolocation.watchPosition); |
| actionFound = true; |
| break; |
| case 'clearWatch': |
| Cordova.checkArgs(args, navigator.geolocation.clearWatch); |
| actionFound = true; |
| break; |
| case 'start': |
| Cordova.checkArgs(args, navigator.geolocation.start); |
| actionFound = true; |
| break; |
| case 'stop': |
| Cordova.checkArgs(args, navigator.geolocation.stop); |
| actionFound = true; |
| break; |
| } |
| |
| Cordova.callback(actionFound, win, fail); |
| } |
| } |
| |
| mapAPI = { |
| execute: function(action, args, win, fail) { |
| var actionFound = false; |
| switch(action) { |
| case 'show': |
| Cordova.checkArgs(args, navigator.map.show); |
| actionFound = true; |
| break; |
| } |
| |
| Cordova.callback(actionFound, win, fail); |
| } |
| } |
| |
| mouseAPI = { |
| execute: function(action, args, win, fail) { |
| var actionFound = false; |
| switch(action) { |
| case 'simulateMouseClick': |
| Cordova.checkArgs(args, navigator.mouse.simulateMouseClick); |
| actionFound = true; |
| break; |
| } |
| |
| Cordova.callback(actionFound, win, fail); |
| } |
| } |
| |
| networkAPI = { |
| execute: function(action, args, win, fail) { |
| var actionFound = false; |
| switch(action) { |
| case 'isReachable': |
| Cordova.checkArgs(args, navigator.network.isReachable); |
| actionFound = true; |
| break; |
| } |
| |
| Cordova.callback(actionFound, win, fail); |
| } |
| } |
| |
| notificationAPI = { |
| execute: function(action, args, win, fail) { |
| var actionFound = false; |
| switch(action) { |
| case 'alert': |
| Cordova.checkArgs(args, navigator.notification.alert); |
| actionFound = true; |
| break; |
| case 'showBanner': |
| Cordova.checkArgs(args, navigator.notification.showBanner); |
| actionFound = true; |
| break; |
| case 'newDashboard': |
| Cordova.checkArgs(args, navigator.notification.newDashboard); |
| actionFound = true; |
| break; |
| case 'removeBannerMessage': |
| Cordova.checkArgs(args, navigator.notification.removeBannerMessage); |
| actionFound = true; |
| break; |
| case 'clearBannerMessage': |
| Cordova.checkArgs(args, navigator.notification.clearBannerMessage); |
| actionFound = true; |
| break; |
| case 'vibrate': |
| Cordova.checkArgs(args, navigator.notification.vibrate); |
| actionFound = true; |
| break; |
| case 'beep': |
| Cordova.checkArgs(args, navigator.notification.beep); |
| actionFound = true; |
| break; |
| } |
| |
| Cordova.callback(actionFound, win, fail); |
| } |
| } |
| |
| orientationAPI = { |
| execute: function(action, args, win, fail) { |
| var actionFound = false; |
| switch(action) { |
| case 'setOrientation': |
| Cordova.checkArgs(args, navigator.orientation.setOrientation); |
| actionFound = true; |
| break; |
| case 'getOrientation': |
| Cordova.checkArgs(args, navigator.orientation.getOrientation); |
| actionFound = true; |
| break; |
| case 'start': |
| Cordova.checkArgs(args, navigator.orientation.start); |
| actionFound = true; |
| break; |
| case 'watchOrientation': |
| Cordova.checkArgs(args, navigator.orientation.watchOrientation); |
| actionFound = true; |
| break; |
| case 'clearWatch': |
| Cordova.checkArgs(args, navigator.orientation.clearWatch); |
| actionFound = true; |
| break; |
| } |
| |
| Cordova.callback(actionFound, win, fail); |
| } |
| } |
| |
| smsAPI = { |
| execute: function(action, args, win, fail) { |
| var actionFound = false; |
| switch(action) { |
| case 'send': |
| Cordova.checkArgs(args, navigator.sms.send); |
| actionFound = true; |
| break; |
| } |
| |
| Cordova.callback(actionFound, win, fail); |
| } |
| } |
| |
| telephonyAPI = { |
| execute: function(action, args, win, fail) { |
| var actionFound = false; |
| switch(action) { |
| case 'send': |
| Cordova.checkArgs(args, navigator.telephony.send); |
| actionFound = true; |
| break; |
| } |
| |
| Cordova.callback(actionFound, win, fail); |
| } |
| } |
| |
| windowAPI = { |
| execute: function(action, args, win, fail) { |
| var actionFound = false; |
| switch(action) { |
| case 'newCard': |
| Cordova.checkArgs(args, navigator.window.newCard); |
| actionFound = true; |
| break; |
| case 'setFullScreen': |
| Cordova.checkArgs(args, navigator.window.setFullScreen); |
| actionFound = true; |
| break; |
| case 'setWindowProperties': |
| Cordova.checkArgs(args, navigator.window.setWindowProperties); |
| actionFound = true; |
| break; |
| case 'blockScreenTimeout': |
| Cordova.checkArgs(args, navigator.window.blockScreenTimeout); |
| actionFound = true; |
| break; |
| case 'setSubtleLightbar': |
| Cordova.checkArgs(args, navigator.window.setSubtleLightbar); |
| actionFound = true; |
| break; |
| |
| } |
| |
| Cordova.callback(actionFound, win, fail); |
| } |
| } |
| |
| // this mapping acts as a shim to the webOS APIs |
| Cordova.plugins = {}; |
| Cordova.plugins['navigator.accelerometer'] = accelerometerAPI; |
| Cordova.plugins['navigator.application'] = applicationAPI; |
| Cordova.plugins['navigator.camera'] = cameraAPI; |
| Cordova.plugins['navigator.compass'] = compassAPI; |
| Cordova.plugins['window.debug'] = debugAPI; |
| Cordova.plugins['navigator.device'] = deviceAPI; |
| Cordova.plugins['navigator.geolocation'] = geolocationAPI; |
| Cordova.plugins['navigator.map'] = mapAPI; |
| Cordova.plugins['navigator.mouse'] = mouseAPI; |
| Cordova.plugins['navigator.network'] = networkAPI; |
| Cordova.plugins['navigator.notification'] = notificationAPI; |
| Cordova.plugins['navigator.orientation'] = orientationAPI; |
| Cordova.plugins['navigator.sms'] = smsAPI; |
| Cordova.plugins['navigator.telephony'] = telephonyAPI; |
| Cordova.plugins['navigator.window'] = windowAPI; |
| |
| document.addEventListener('DOMContentLoaded', function () { |
| window.cordova = new Cordova(); |
| navigator.device.deviceReady(); |
| }); |
| /* |
| * This class contains acceleration information |
| * @constructor |
| * @param {Number} x The force applied by the device in the x-axis. |
| * @param {Number} y The force applied by the device in the y-axis. |
| * @param {Number} z The force applied by the device in the z-axis. |
| */ |
| function Acceleration(x, y, z) { |
| /* |
| * The force applied by the device in the x-axis. |
| */ |
| this.x = x; |
| /* |
| * The force applied by the device in the y-axis. |
| */ |
| this.y = y; |
| /* |
| * The force applied by the device in the z-axis. |
| */ |
| this.z = z; |
| /* |
| * The time that the acceleration was obtained. |
| */ |
| this.timestamp = new Date().getTime(); |
| }; |
| |
| /* |
| * This class specifies the options for requesting acceleration data. |
| * @constructor |
| */ |
| function AccelerationOptions() { |
| /* |
| * The timeout after which if acceleration data cannot be obtained the errorCallback |
| * is called. |
| */ |
| this.timeout = 10000; |
| }; |
| |
| /* |
| * This class provides access to device accelerometer data. |
| * @constructor |
| */ |
| function Accelerometer() { |
| /* |
| * The last known acceleration. |
| */ |
| this.lastAcceleration = null; |
| }; |
| |
| /* |
| * Tells WebOS to put higher priority on accelerometer resolution. Also relaxes the internal garbage collection events. |
| * @param {Boolean} state |
| * Dependencies: Mojo.windowProperties |
| * Example: |
| * navigator.accelerometer.setFastAccelerometer(true) |
| */ |
| Accelerometer.prototype.setFastAccelerometer = function(state) { |
| navigator.windowProperties.fastAccelerometer = state; |
| navigator.window.setWindowProperties(); |
| }; |
| |
| /* |
| * Asynchronously aquires the current acceleration. |
| * @param {Function} successCallback The function to call when the acceleration |
| * data is available |
| * @param {Function} errorCallback The function to call when there is an error |
| * getting the acceleration data. |
| * @param {AccelerationOptions} options The options for getting the accelerometer data |
| * such as timeout. |
| */ |
| |
| Accelerometer.prototype.getCurrentAcceleration = function(successCallback, errorCallback, options) { |
| |
| var referenceTime = 0; |
| if (this.lastAcceleration) |
| referenceTime = this.lastAcceleration.timestamp; |
| else |
| this.start(); |
| |
| var timeout = 20000; |
| var interval = 500; |
| if (typeof(options) == 'object' && options.interval) |
| interval = options.interval; |
| |
| if (typeof(successCallback) != 'function') |
| successCallback = function() {}; |
| if (typeof(errorCallback) != 'function') |
| errorCallback = function() {}; |
| |
| var dis = this; |
| var delay = 0; |
| var timer = setInterval(function() { |
| delay += interval; |
| |
| //if we have a new acceleration, call success and cancel the timer |
| if (typeof(dis.lastAcceleration) == 'object' && dis.lastAcceleration != null && dis.lastAcceleration.timestamp > referenceTime) { |
| successCallback(dis.lastAcceleration); |
| clearInterval(timer); |
| } else if (delay >= timeout) { //else if timeout has occured then call error and cancel the timer |
| errorCallback(); |
| clearInterval(timer); |
| } |
| //else the interval gets called again |
| }, interval); |
| }; |
| |
| |
| /* |
| * Asynchronously aquires the acceleration repeatedly at a given interval. |
| * @param {Function} successCallback The function to call each time the acceleration |
| * data is available |
| * @param {Function} errorCallback The function to call when there is an error |
| * getting the acceleration data. |
| * @param {AccelerationOptions} options The options for getting the accelerometer data |
| * such as timeout. |
| */ |
| |
| Accelerometer.prototype.watchAcceleration = function(successCallback, errorCallback, options) { |
| this.getCurrentAcceleration(successCallback, errorCallback, options); |
| // TODO: add the interval id to a list so we can clear all watches |
| var frequency = (options != undefined)? options.frequency : 10000; |
| var that = this; |
| return setInterval(function() { |
| that.getCurrentAcceleration(successCallback, errorCallback, options); |
| }, frequency); |
| }; |
| |
| /* |
| * Clears the specified accelerometer watch. |
| * @param {String} watchId The ID of the watch returned from #watchAcceleration. |
| */ |
| Accelerometer.prototype.clearWatch = function(watchId) { |
| clearInterval(watchId); |
| }; |
| |
| /* |
| * Starts the native acceleration listener. |
| */ |
| |
| Accelerometer.prototype.start = function() { |
| var that = this; |
| //Mojo.Event.listen(document, "acceleration", function(event) { |
| document.addEventListener("acceleration", function(event) { |
| var accel = new Acceleration(event.accelX, event.accelY, event.accelZ); |
| that.lastAcceleration = accel; |
| }); |
| }; |
| |
| if (typeof navigator.accelerometer == "undefined") navigator.accelerometer = new Accelerometer(); |
| |
| function Application() { |
| |
| }; |
| |
| /* |
| * Tell webOS to activate the current page of your app, bringing it into focus. |
| * Example: |
| * navigator.application.activate(); |
| */ |
| Application.prototype.activate = function() { |
| PalmSystem.activate(); |
| }; |
| |
| /* |
| * Tell webOS to deactivate your app. |
| * Example: |
| * navigator.application.deactivate(); |
| */ |
| Application.prototype.deactivate = function() { |
| PalmSystem.deactivate(); |
| }; |
| |
| /* |
| * Returns the identifier of the current running application (e.g. com.yourdomain.yourapp). |
| * Example: |
| * navigator.application.getIdentifier(); |
| */ |
| Application.prototype.getIdentifier = function() { |
| return PalmSystem.identifier; |
| }; |
| |
| if (typeof navigator.application == "undefined") navigator.application = new Application(); |
| |
| /* |
| * This class provides access to the device audio |
| * @constructor |
| */ |
| |
| Cordova.overrideAudio = function() { |
| |
| Cordova.MojoAudio = Audio; |
| |
| Audio = function(src) { |
| this.src = src; |
| }; |
| |
| Audio.prototype.play = function() { |
| // this.src = src; |
| // The 'end' event listener doesn't seem to work, so we have to call stop before playing |
| // otherwise, we'll never be able to play again |
| if (this.paused && !this.stopped) { |
| this.paused = false; |
| this.playing = true; |
| this.audioPlayer.play(); |
| } else { |
| if (this.audioPlayer) |
| this.stop(); |
| if (!this.playing) { |
| this.paused = false; |
| this.playing = true; |
| this.stopped = false; |
| this.audioPlayer = new Cordova.MojoAudio(); |
| var file = Mojo.appPath + this.src; |
| if (this.audioPlayer.palm) { |
| this.audioPlayer.mojo.audioClass = "media"; |
| } |
| this.audioPlayer.src = file; |
| |
| //event doesn't work, see above |
| this.audioPlayer.addEventListener('end', this.endHandler, false); |
| this.audioPlayer.play(); |
| } |
| } |
| }; |
| |
| Audio.prototype.pause = function() { |
| if (this.stopped) |
| return; |
| this.paused = true; |
| if (this.playing) { |
| this.playing = false; |
| this.stopped = false; |
| this.audioPlayer.pause(); |
| } else { |
| this.playing = false; |
| this.paused = false; |
| this.stopped = true; |
| } |
| }; |
| |
| Audio.prototype.stop = function() { |
| this.audioPlayer.pause(); |
| this.audioPlayer.src = null; |
| this.playing = false; |
| this.paused = false; |
| this.stopped = true; |
| }; |
| |
| // End event handler not working (see comment in Audio.prototype.play) |
| Audio.prototype.endHandler = function () { |
| this.audioPlayer.removeEventListener('end', endHandler, false); |
| this.audioPlayer.pause(); |
| this.audioPlayer.src = null; |
| this.paused = false; |
| this.stopped = true; |
| }; |
| |
| /* |
| * This class contains information about any Media errors. |
| * @constructor |
| */ |
| MediaError = function() { |
| 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; |
| |
| } |
| |
| document.addEventListener("deviceready", Cordova.overrideAudio, false); |
| |
| /* |
| * This class provides access to the device camera. |
| * @constructor |
| */ |
| function Camera() { |
| |
| }; |
| |
| /* |
| * @param {Function} successCallback |
| * @param {Function} errorCallback |
| * @param {Object} options |
| */ |
| Camera.prototype.getPicture = function(successCallback, errorCallback, options) { |
| |
| var filename = ""; |
| |
| if (typeof options != 'undefined' && typeof options.filename != 'undefined') { |
| filename = options.filename; |
| } |
| |
| this.service = navigator.service.Request('palm://com.palm.applicationManager', { |
| method: 'launch', |
| parameters: { |
| id: 'com.palm.app.camera', |
| params: { |
| appId: 'com.palm.app.camera', |
| name: 'capture', |
| sublaunch: true, |
| filename: filename |
| } |
| }, |
| onSuccess: successCallback, |
| onFailure: errorCallback |
| }); |
| }; |
| |
| if (typeof navigator.camera == 'undefined') navigator.camera = new Camera(); |
| |
| /* |
| * This class provides access to the device contacts. |
| * @constructor |
| */ |
| |
| function Contacts() { |
| |
| }; |
| |
| function Contact() { |
| this.phones = []; |
| this.emails = []; |
| this.name = { |
| givenName: "", |
| familyName: "", |
| formatted: "" |
| }; |
| this.id = ""; |
| }; |
| |
| Contact.prototype.displayName = function() |
| { |
| // TODO: can be tuned according to prefs |
| return this.givenName + " " + this.familyName; |
| }; |
| |
| function ContactsFilter(name) { |
| if (name) |
| this.name = name; |
| else |
| this.name = ""; |
| }; |
| |
| /* |
| * @param {ContactsFilter} filter Object with filter properties. filter.name only for now. |
| * @param {function} successCallback Callback function on success |
| * @param {function} errorCallback Callback function on failure |
| * @param {object} options Object with properties .page and .limit for paging |
| */ |
| |
| Contacts.prototype.find = function(filter, successCallback, errorCallback, options) { |
| errorCallback({ name: "ContactsError", message: "Cordova Palm contacts not implemented" }); |
| }; |
| |
| Contacts.prototype.success_callback = function(contacts_iterator) { |
| }; |
| |
| if (typeof navigator.contacts == "undefined") navigator.contacts = new Contacts(); |
| /* |
| * This class provides access to device compass data. |
| * @constructor |
| */ |
| function Compass() { |
| /* |
| * The last known heading. |
| */ |
| this.lastHeading = null; |
| }; |
| |
| /* |
| * Asynchronously aquires the current compass heading. |
| * @param {Function} successCallback The function to call when the compass |
| * data is available |
| * @param {Function} errorCallback The function to call when there is an error |
| * getting the compass data. |
| * @param {CompassOptions} options The options for getting the compass data |
| * such as timeout. |
| */ |
| |
| Compass.prototype.getCurrentHeading = function(successCallback, errorCallback, options) { |
| |
| var referenceTime = 0; |
| if (this.lastHeading) |
| referenceTime = this.lastHeading.timestamp; |
| else |
| this.start(); |
| |
| var timeout = 20000; |
| var interval = 500; |
| if (typeof(options) == 'object' && options.interval) |
| interval = options.interval; |
| |
| if (typeof(successCallback) != 'function') |
| successCallback = function() {}; |
| if (typeof(errorCallback) != 'function') |
| errorCallback = function() {}; |
| |
| var dis = this; |
| var delay = 0; |
| var timer = setInterval(function() { |
| delay += interval; |
| |
| //if we have a new compass heading, call success and cancel the timer |
| if (typeof(dis.lastHeading) == 'object' && dis.lastHeading != null && dis.lastHeading.timestamp > referenceTime) { |
| successCallback(dis.lastHeading.magHeading); |
| clearInterval(timer); |
| } else if (delay >= timeout) { //else if timeout has occured then call error and cancel the timer |
| errorCallback(); |
| clearInterval(timer); |
| } |
| //else the interval gets called again |
| }, interval); |
| }; |
| |
| |
| /* |
| * Asynchronously aquires the compass heading repeatedly at a given interval. |
| * @param {Function} successCallback The function to call each time the acceleration |
| * data is available |
| * @param {Function} errorCallback The function to call when there is an error |
| * getting the compass data. |
| * @param {CompassOptions} options The options for getting the compass data |
| * such as timeout. |
| */ |
| |
| Compass.prototype.watchHeading = function(successCallback, errorCallback, options) { |
| this.getCurrentHeading(successCallback, errorCallback, options); |
| // TODO: add the interval id to a list so we can clear all watches |
| var frequency = (options != undefined)? options.frequency : 10000; |
| var that = this; |
| return setInterval(function() { |
| that.getCurrentHeading(successCallback, errorCallback, options); |
| }, frequency); |
| }; |
| |
| /* |
| * Clears the specified heading watch. |
| * @param {String} watchId The ID of the watch returned from #watchHeading. |
| */ |
| Compass.prototype.clearWatch = function(watchId) { |
| clearInterval(watchId); |
| }; |
| |
| /* |
| * Starts the native compass listener. |
| */ |
| |
| Compass.prototype.start = function() { |
| var that = this; |
| //Mojo.Event.listen(document, "acceleration", function(event) { |
| document.addEventListener("compass", function(event) { |
| var heading={}; |
| heading.trueHeading=event.trueHeading; |
| heading.magHeading=event.magHeading; |
| heading.timestamp = new Date().getTime(); |
| that.lastHeading = heading; |
| }); |
| }; |
| |
| if (typeof navigator.compass == "undefined") navigator.compass = new Compass(); |
| /* |
| * This class provides access to the debugging console. |
| * @constructor |
| */ |
| function DebugConsole() { |
| }; |
| |
| /* |
| * Print a normal log message to the console |
| * @param {Object|String} message Message or object to print to the console |
| */ |
| DebugConsole.prototype.log = function(message) { |
| if (typeof message == 'object') |
| message = Object.toJSON(message); |
| |
| this.error(message); |
| }; |
| |
| /* |
| * Print a warning message to the console |
| * @param {Object|String} message Message or object to print to the console |
| */ |
| DebugConsole.prototype.warn = function(message) { |
| if (typeof message == 'object') |
| message = Object.toJSON(message); |
| |
| this.error(message); |
| }; |
| |
| /** |
| * Print an error message to the console |
| * @param {Object|String} message Message or object to print to the console |
| */ |
| DebugConsole.prototype.error = function(message) { |
| if (typeof message == 'object') |
| message = Object.toJSON(message); |
| |
| console.log(JSON.stringify(message)); |
| }; |
| |
| if (typeof window.debug == "undefined") window.debug = new DebugConsole(); |
| /* |
| * this represents the mobile device, and provides properties for inspecting the model, version, UUID of the |
| * phone, etc. |
| * @constructor |
| */ |
| function Device() { |
| this.platform = "palm"; |
| this.version = null; |
| this.name = null; |
| this.uuid = null; |
| this.deviceInfo = null; |
| }; |
| |
| /* |
| * A direct call to return device information. |
| * Example: |
| * var deviceinfo = JSON.stringify(navigator.device.getDeviceInfo()).replace(/,/g, ', '); |
| */ |
| Device.prototype.getDeviceInfo = function() { |
| return this.deviceInfo;//JSON.parse(PalmSystem.deviceInfo); |
| }; |
| |
| /* |
| * needs to be invoked in a <script> nested within the <body> it tells WebOS that the app is ready |
| TODO: see if we can get this added as in a document.write so that the user doesn't have to explicitly call this method |
| * Dependencies: Mojo.onKeyUp |
| * Example: |
| * navigator.device.deviceReady(); |
| */ |
| Device.prototype.deviceReady = function() { |
| |
| // tell webOS this app is ready to show |
| if (window.PalmSystem) { |
| // setup keystroke events for forward and back gestures |
| document.body.addEventListener("keyup", Mojo.onKeyUp, true); |
| |
| setTimeout(function() { PalmSystem.stageReady(); PalmSystem.activate(); }, 1); |
| alert = this.showBanner; |
| } |
| |
| // fire deviceready event; taken straight from phonegap-iphone |
| // put on a different stack so it always fires after DOMContentLoaded |
| window.setTimeout(function () { |
| var e = document.createEvent('Events'); |
| e.initEvent('deviceready'); |
| document.dispatchEvent(e); |
| }, 10); |
| |
| this.setUUID(); |
| this.setDeviceInfo(); |
| }; |
| |
| Device.prototype.setDeviceInfo = function() { |
| var parsedData = JSON.parse(PalmSystem.deviceInfo); |
| |
| this.deviceInfo = parsedData; |
| this.version = parsedData.platformVersion; |
| this.name = parsedData.modelName; |
| }; |
| |
| Device.prototype.setUUID = function() { |
| //this is the only system property webos provides (may change?) |
| var that = this; |
| this.service = navigator.service.Request('palm://com.palm.preferences/systemProperties', { |
| method:"Get", |
| parameters:{"key": "com.palm.properties.nduid" }, |
| onSuccess: function(result) { |
| that.uuid = result["com.palm.properties.nduid"]; |
| } |
| }); |
| |
| |
| }; |
| |
| |
| if (typeof window.device == 'undefined') window.device = navigator.device = new Device(); |
| |
| /* |
| * This class provides generic read and write access to the mobile device file system. |
| */ |
| function File() { |
| /** |
| * The data of a file. |
| */ |
| this.data = ""; |
| /** |
| * The name of the file. |
| */ |
| this.name = ""; |
| }; |
| |
| /* |
| * Reads a file from the mobile device. This function is asyncronous. |
| * @param {String} fileName The name (including the path) to the file on the mobile device. |
| * The file name will likely be device dependant. |
| * @param {Function} successCallback The function to call when the file is successfully read. |
| * @param {Function} errorCallback The function to call when there is an error reading the file from the device. |
| */ |
| File.prototype.read = function(fileName, successCallback, errorCallback) { |
| //Mojo has no file i/o yet, so we use an xhr. very limited |
| var path = fileName; //incomplete |
| //Mojo.Log.error(path); |
| navigator.debug.error(path); |
| |
| if (typeof successCallback != 'function') |
| successCallback = function () {}; |
| if (typeof errorCallback != 'function') |
| errorCallback = function () {}; |
| |
| var xhr = new XMLHttpRequest(); |
| xhr.onreadystatechange = function() { |
| if (xhr.readyState == 4) { |
| if (xhr.status == 200 && xhr.responseText != null) { |
| this.data = xhr.responseText; |
| this.name = path; |
| successCallback(this.data); |
| } else { |
| errorCallback({ name: xhr.status, message: "could not read file: " + path }); |
| } |
| } |
| }; |
| xhr.open("GET", path, true); |
| xhr.send(); |
| }; |
| |
| /* |
| * Writes a file to the mobile device. |
| * @param {File} file The file to write to the device. |
| */ |
| File.prototype.write = function(file) { |
| //Palm does not provide file i/o |
| }; |
| |
| if (typeof navigator.file == "undefined") navigator.file = new File(); |
| |
| /* |
| * This class provides access to device GPS data. |
| * @constructor |
| */ |
| function Geolocation() { |
| /** |
| * The last known GPS position. |
| */ |
| this.lastPosition = null; |
| this.lastError = null; |
| this.callbacks = { |
| onLocationChanged: [], |
| onError: [] |
| }; |
| }; |
| |
| /* |
| * 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 position data. |
| * @param {PositionOptions} options The options for getting the position data |
| * such as timeout. |
| */ |
| Geolocation.prototype.getCurrentPosition = function(successCallback, errorCallback, options) { |
| /* |
| var referenceTime = 0; |
| if (this.lastPosition) |
| referenceTime = this.lastPosition.timestamp; |
| else |
| this.start(options); |
| */ |
| |
| var timeout = 20000; |
| if (typeof(options) == 'object' && options.timeout) |
| timeout = options.timeout; |
| |
| if (typeof(successCallback) != 'function') |
| successCallback = function() {}; |
| if (typeof(errorCallback) != 'function') |
| errorCallback = function() {}; |
| |
| /* |
| var dis = this; |
| var delay = 0; |
| var timer = setInterval(function() { |
| delay += interval; |
| |
| //if we have a new position, call success and cancel the timer |
| if (dis.lastPosition && typeof(dis.lastPosition) == 'object' && dis.lastPosition.timestamp > referenceTime) { |
| successCallback(dis.lastPosition); |
| clearInterval(timer); |
| } else if (delay >= timeout) { //else if timeout has occured then call error and cancel the timer |
| errorCallback(); |
| clearInterval(timer); |
| } |
| //else the interval gets called again |
| }, interval); |
| */ |
| |
| var responseTime; |
| if (timeout <= 5000) |
| responseTime = 1; |
| else if (5000 < timeout <= 20000) |
| responseTime = 2; |
| else |
| responseTime = 3; |
| |
| var timer = setTimeout(function() { |
| errorCallback({ |
| message: "timeout" |
| }); |
| }, |
| timeout); |
| |
| var startTime = (new Date()).getTime(); |
| |
| var alias = this; |
| |
| // It may be that getCurrentPosition is less reliable than startTracking ... but |
| // not sure if we want to be starting and stopping the tracker if we're not watching. |
| //new Mojo.Service.Request('palm://com.palm.location', { |
| navigator.service.Request('palm://com.palm.location', { |
| method: "getCurrentPosition", |
| parameters: { |
| responseTime: responseTime |
| }, |
| onSuccess: function(event) { |
| alias.lastPosition = { |
| coords: { |
| latitude: event.latitude, |
| longitude: event.longitude, |
| altitude: (event.altitude >= 0 ? event.altitude: null), |
| speed: (event.velocity >= 0 ? event.velocity: null), |
| heading: (event.heading >= 0 ? event.heading: null), |
| accuracy: (event.horizAccuracy >= 0 ? event.horizAccuracy: null), |
| altitudeAccuracy: (event.vertAccuracy >= 0 ? event.vertAccuracy: null) |
| }, |
| timestamp: new Date().getTime() |
| }; |
| |
| var responseTime = alias.lastPosition.timestamp - startTime; |
| if (responseTime <= timeout) |
| { |
| clearTimeout(timer); |
| successCallback(alias.lastPosition); |
| } |
| }, |
| onFailure: function() { |
| errorCallback(); |
| } |
| }); |
| |
| }; |
| |
| /* |
| * Asynchronously aquires the position repeatedly at a given interval. |
| * @param {Function} successCallback The function to call each time the position |
| * data is available |
| * @param {Function} errorCallback The function to call when there is an error |
| * getting the position data. |
| * @param {PositionOptions} options The options for getting the position data |
| * such as timeout and the frequency of the watch. |
| */ |
| Geolocation.prototype.watchPosition = function(successCallback, errorCallback, options) { |
| // Invoke the appropriate callback with a new Position object every time the implementation |
| // determines that the position of the hosting device has changed. |
| var frequency = 10000; |
| if (typeof(options) == 'object' && options.frequency) |
| frequency = options.frequency; |
| |
| this.start(options, errorCallback); |
| |
| var referenceTime = 0; |
| if (this.lastPosition) |
| referenceTime = this.lastPosition.timestamp; |
| |
| var alias = this; |
| return setInterval(function() { |
| // check if we have a new position, if so call our successcallback |
| if (!alias.lastPosition) |
| return; |
| |
| if (alias.lastPosition.timestamp > referenceTime) |
| successCallback(alias.lastPosition); |
| }, |
| frequency); |
| }; |
| |
| |
| /* |
| * Clears the specified position watch. |
| * @param {String} watchId The ID of the watch returned from #watchPosition. |
| */ |
| Geolocation.prototype.clearWatch = function(watchId) { |
| clearInterval(watchId); |
| this.stop(); |
| }; |
| |
| Geolocation.prototype.start = function(options, errorCallback) { |
| //options.timeout; |
| //options.interval; |
| if (typeof(errorCallback) != 'function') |
| errorCallback = function() {}; |
| |
| var that = this; |
| var frequency = 10000; |
| if (typeof(options) == 'object' && options.frequency) |
| frequency = options.frequency; |
| |
| var responseTime; |
| if (frequency <= 5000) |
| responseTime = 1; |
| else if (5000 < frequency <= 20000) |
| responseTime = 2; |
| else |
| responseTime = 3; |
| |
| //location tracking does not support setting a custom interval :P |
| this.trackingHandle = navigator.service.Request('palm://com.palm.location', { |
| method: 'startTracking', |
| parameters: { |
| subscribe: true |
| }, |
| onSuccess: function(event) { |
| that.lastPosition = { |
| coords: { |
| latitude: event.latitude, |
| longitude: event.longitude, |
| altitude: (event.altitude >= 0 ? event.altitude: null), |
| speed: (event.velocity >= 0 ? event.velocity: null), |
| heading: (event.heading >= 0 ? event.heading: null), |
| accuracy: (event.horizAccuracy >= 0 ? event.horizAccuracy: null), |
| altitudeAccuracy: (event.vertAccuracy >= 0 ? event.vertAccuracy: null) |
| }, |
| timestamp: new Date().getTime() |
| }; |
| }, |
| onFailure: function() { |
| errorCallback(); |
| } |
| }); |
| }; |
| |
| Geolocation.prototype.stop = function() { |
| this.trackingHandle.cancel(); |
| }; |
| |
| if (typeof navigator.geolocation == "undefined") navigator.geolocation = new Geolocation(); |
| |
| /* |
| * This class provides access to native mapping applications on the device. |
| */ |
| function Map() { |
| |
| }; |
| |
| /* |
| * Shows a native map on the device with pins at the given positions. |
| * @param {Array} positions |
| */ |
| Map.prototype.show = function(positions) { |
| |
| var jsonPos = {}; |
| var pos = null; |
| if (typeof positions == 'object') { |
| // If positions is an array, then get the first only, since google's query |
| // can't take more than one marker (believe it or not). |
| // Otherwise we assume its a single position object. |
| if (positions.length) { |
| pos = positions[0]; |
| } else { |
| pos = positions; |
| } |
| } |
| else if (navigator.geolocation.lastPosition) { |
| pos = navigator.geolocation.lastPosition; |
| } else { |
| // If we don't have a position, lets use nitobi! |
| pos = { coords: { latitude: 49.28305, longitude: -123.10689 } }; |
| } |
| |
| this.service = navigator.service.Request('palm://com.palm.applicationManager', { |
| method: 'open', |
| parameters: { |
| id: 'com.palm.app.maps', |
| params: { |
| query: "@" + pos.coords.latitude + "," + pos.coords.longitude |
| } |
| } |
| }); |
| |
| }; |
| |
| if (typeof navigator.map == "undefined") navigator.map = new Map(); |
| |
| //=========================== |
| // Mojo Dependencies - we still need to rely on these minimal parts of the Mojo framework - should try to find if we can get access to lower level APIs |
| // so that we can remove dependence of Mojo |
| //=========================== |
| |
| Mojo = { |
| contentIndicator: false, |
| |
| // called by webOS in certain cases |
| relaunch: function() { |
| var launch = JSON.parse(PalmSystem.launchParams); |
| |
| if (launch['palm-command'] && launch['palm-command'] == 'open-app-menu') |
| this.fireEvent(window, "appmenuopen"); |
| else |
| this.fireEvent(window, "palmsystem", launch); |
| }, |
| |
| // called by webOS when your app gets focus |
| stageActivated: function() { |
| this.fireEvent(window, "activate"); |
| }, |
| |
| // called by webOS when your app loses focus |
| stageDeactivated: function() { |
| this.fireEvent(window, "deactivate"); |
| }, |
| |
| // this is a stub -- called by webOS when orientation changes |
| // but the preferred method is to use the orientationchanged |
| // DOM event |
| screenOrientationChanged: function(dir) { |
| }, |
| |
| // used to redirect keyboard events to DOM event "back" |
| onKeyUp: function(e) { |
| if (e.keyCode == 27) |
| this.fireEvent(window, "back"); |
| }, |
| |
| // private method, used to fire off DOM events |
| fireEvent: function(element, event, data) { |
| var e = document.createEvent("Event"); |
| e.initEvent(event, false, true); |
| |
| if (data) |
| e.data = data; |
| |
| element.dispatchEvent(e); |
| }, |
| |
| /* |
| not sure if these stubs are still needed since the Log object is encapsulated in debugconsole class |
| and the Service object is encapsulated in the Service class |
| */ |
| // stubs to make v8 happier |
| Service: {}, |
| Log: {} |
| |
| };function Mouse() { |
| |
| }; |
| |
| /* |
| * Possibly useful for automated testing, this call to PalmSystem triggers a mouse click (i.e. touch event). |
| * x coordinate & y coordinate of where the screen was touched and also a true/false flag to tell WebOS if it should simulate the mouse click |
| * @param {Number} x |
| * @param {Number} y |
| * @param {Boolean} state |
| * Example: |
| * navigator.mouse.simulateMouseClick(10, 10, true); |
| */ |
| Mouse.prototype.simulateMouseClick = function(x, y, state) { |
| PalmSystem.simulateMouseClick(x, y, state || true); |
| }; |
| |
| if (typeof navigator.mouse == "undefined") navigator.mouse = new Mouse(); |
| |
| function Network() { |
| /* |
| * The last known Network status. |
| */ |
| this.lastReachability = null; |
| }; |
| |
| Network.prototype.isReachable = function(hostName, successCallback, options) { |
| this.request = navigator.service.Request('palm://com.palm.connectionmanager', { |
| method: 'getstatus', |
| parameters: {}, |
| onSuccess: function(result) { |
| var status = NetworkStatus.NOT_REACHABLE; |
| if (result.isInternetConnectionAvailable == true) |
| { |
| // don't know whether its via wifi or carrier ... so return the worst case |
| status = NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK; |
| } |
| successCallback(status); |
| }, |
| onFailure: function() {} |
| }); |
| |
| }; |
| |
| /* |
| * 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; |
| |
| if (typeof navigator.network == "undefined") navigator.network = new Network(); |
| |
| /* |
| * This class provides access to notifications on the device. |
| */ |
| function Notification() { |
| |
| }; |
| |
| /* |
| * adds a dashboard to the WebOS app |
| * @param {String} url |
| * @param {String} html |
| * Example: |
| * navigator.notification.newDashboard("dashboard.html"); |
| */ |
| Notification.prototype.newDashboard = function(url, html) { |
| var win = window.open(url, "_blank", "attributes={\"window\":\"dashboard\"}"); |
| html && win.document.write(html); |
| win.PalmSystem.stageReady(); |
| }; |
| |
| /* |
| * Displays a banner notification. If specified, will send your 'response' object as data via the 'palmsystem' DOM event. |
| * If no 'icon' filename is specified, will use a small version of your application icon. |
| * @param {String} message |
| * @param {Object} response |
| * @param {String} icon |
| * @param {String} soundClass class of the sound; supported classes are: "ringtones", "alerts", "alarm", "calendar", "notification" |
| * @param {String} soundFile partial or full path to the sound file |
| * @param {String} soundDurationMs of sound in ms |
| * Example: |
| * navigator.notification.showBanner('test message'); |
| */ |
| Notification.prototype.showBanner = function(message, response, icon, soundClass, soundFile, soundDurationMs) { |
| var response = response || { |
| banner: true |
| }; |
| PalmSystem.addBannerMessage(message, JSON.stringify(response), icon, soundClass, soundFile, soundDurationMs); |
| }; |
| |
| /** |
| * Remove a banner from the banner area. The category parameter defaults to 'banner'. Will not remove |
| * messages that are already displayed. |
| * @param {String} category |
| Value defined by the application and usually same one used in {@link showBanner}. |
| It is used if you have more than one kind of banner message. |
| */ |
| Notification.prototype.removeBannerMessage = function(category) { |
| var bannerKey = category || 'banner'; |
| var bannerId = this.banners.get(bannerKey); |
| if (bannerId) { |
| try { |
| PalmSystem.removeBannerMessage(bannerId); |
| } catch(removeBannerException) { |
| window.debug.error(removeBannerException.toString()); |
| } |
| } |
| }; |
| |
| /* |
| * Remove all pending banner messages from the banner area. Will not remove messages that are already displayed. |
| */ |
| Notification.prototype.clearBannerMessage = function() { |
| PalmSystem.clearBannerMessage(); |
| }; |
| |
| /* |
| * This function vibrates the device |
| * @param {number} duration The duration in ms to vibrate for. |
| * @param {number} intensity The intensity of the vibration |
| */ |
| Notification.prototype.vibrate = function(duration, intensity) { |
| //the intensity for palm is inverted; 0=high intensity, 100=low intensity |
| //this is opposite from our api, so we invert |
| if (isNaN(intensity) || intensity > 100 || intensity <= 0) |
| intensity = 0; |
| else |
| intensity = 100 - intensity; |
| |
| // if the app id does not have the namespace "com.palm.", an error will be thrown here |
| //this.vibhandle = new Mojo.Service.Request("palm://com.palm.vibrate", { |
| this.vibhandle = navigator.service.Request("palm://com.palm.vibrate", { |
| method: 'vibrate', |
| parameters: { |
| 'period': intensity, |
| 'duration': duration |
| } |
| }, |
| false); |
| }; |
| |
| /* |
| * Plays the specified sound |
| * @param {String} soundClass class of the sound; supported classes are: "ringtones", "alerts", "alarm", "calendar", "notification" |
| * @param {String} soundFile partial or full path to the sound file |
| * @param {String} soundDurationMs of sound in ms |
| */ |
| Notification.prototype.beep = function(soundClass, soundFile, soundDurationMs) { |
| PalmSystem.playSoundNotification(soundClass, soundFile, soundDurationMs); |
| }; |
| |
| /* |
| * displays a notification |
| * @param {String} message |
| * @param {Object} response |
| * @param {String} icon |
| */ |
| Notification.prototype.alert = function(message, response, icon) { |
| var response = response || { |
| banner: true |
| }; |
| navigator.notification.showBanner(message, response, icon); |
| }; |
| |
| if (typeof navigator.notification == 'undefined') { |
| navigator.notification = new Notification(); |
| alert = navigator.notification.alert; |
| } |
| |
| /* |
| * This class provides access to the device orientation. |
| * @constructor |
| */ |
| function Orientation() { |
| this.started = false; |
| }; |
| |
| /* |
| * Manually sets the orientation of the application window. |
| * 'up', 'down', 'left' or 'right' used to specify fixed window orientation |
| * 'free' WebOS will change the window orientation to match the device orientation |
| * @param {String} orientation |
| * Example: |
| * navigator.orientation.setOrientation('up'); |
| */ |
| Orientation.prototype.setOrientation = function(orientation) { |
| PalmSystem.setWindowOrientation(orientation); |
| }; |
| |
| /* |
| * Returns the current window orientation |
| */ |
| Orientation.prototype.getCurrentOrientation = function() { |
| return PalmSystem.windowOrientation; |
| }; |
| |
| /* |
| * Starts the native orientationchange event listener. |
| */ |
| Orientation.prototype.start = function (successCallback) { |
| var that = this; |
| // This subscribes the callback once for the successCallback function |
| that.callback = function (e) { |
| document.removeEventListener("orientationChanged", that.callback); |
| successCallback(e.orientation); |
| } |
| |
| document.addEventListener("orientationChanged", that.callback); |
| |
| // This subscribes setOrientation to be constantly updating the currentOrientation property |
| document.addEventListener("orientationchange", function(event) { |
| var orient = null; |
| switch (event.position) { |
| case 0: orient = DisplayOrientation.FACE_UP; break; |
| case 1: orient = DisplayOrientation.FACE_DOWN; break; |
| case 2: orient = DisplayOrientation.PORTRAIT; break; |
| case 3: orient = DisplayOrientation.REVERSE_PORTRAIT; break; |
| case 4: orient = DisplayOrientation.LANDSCAPE_RIGHT_UP; break; |
| case 5: orient = DisplayOrientation.LANDSCAPE_LEFT_UP; break; |
| default: return; //orientationchange event seems to get thrown sometimes with a null event position |
| } |
| that.setOrientation(orient); |
| }); |
| this.started = true; |
| }; |
| |
| /* |
| * Asynchronously aquires the orientation repeatedly at a given interval. |
| * @param {Function} successCallback The function to call each time the orientation |
| * data is available. |
| * @param {Function} errorCallback The function to call when there is an error |
| * getting the orientation data. |
| */ |
| Orientation.prototype.watchOrientation = function(successCallback, errorCallback, options) { |
| // Invoke the appropriate callback with a new Position object every time the implementation |
| // determines that the position of the hosting device has changed. |
| this.getCurrentOrientation(successCallback, errorCallback); |
| var interval = 1000; |
| if (options && !isNaN(options.interval)) |
| interval = options.interval; |
| var that = this; |
| return setInterval(function() { |
| that.getCurrentOrientation(successCallback, errorCallback); |
| }, interval); |
| }; |
| |
| /* |
| * Clears the specified orientation watch. |
| * @param {String} watchId The ID of the watch returned from #watchOrientation. |
| */ |
| Orientation.prototype.clearWatch = function(watchId) { |
| clearInterval(watchId); |
| }; |
| |
| /* |
| * This class encapsulates the possible orientation values. |
| * @constructor |
| */ |
| function DisplayOrientation() { |
| this.code = null; |
| this.message = ""; |
| }; |
| |
| DisplayOrientation.PORTRAIT = 0; |
| DisplayOrientation.REVERSE_PORTRAIT = 1; |
| DisplayOrientation.LANDSCAPE_LEFT_UP = 2; |
| DisplayOrientation.LANDSCAPE_RIGHT_UP = 3; |
| DisplayOrientation.FACE_UP = 4; |
| DisplayOrientation.FACE_DOWN = 5; |
| |
| if (typeof navigator.orientation == "undefined") navigator.orientation = new Orientation(); |
| |
| function Position(coords) { |
| this.coords = coords; |
| this.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 = (typeof(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; |
| |
| function Service() { |
| |
| }; |
| |
| Service.prototype.Request = function (uri, params) { |
| var req = new PalmServiceBridge(); |
| var url = uri + "/" + (params.method || ""); |
| req.url = url; |
| |
| this.req = req; |
| this.url = url; |
| this.params = params || {}; |
| |
| this.call(params); |
| |
| return this; |
| }; |
| |
| Service.prototype.call = function(params) { |
| var onsuccess = null; |
| var onfailure = null; |
| var oncomplete = null; |
| |
| if (typeof params.onSuccess === 'function') |
| onsuccess = params.onSuccess; |
| |
| if (typeof params.onFailure === 'function') |
| onerror = params.onFailure; |
| |
| if (typeof params.onComplete === 'function') |
| oncomplete = params.onComplete; |
| |
| this.req.onservicecallback = callback; |
| |
| function callback(msg) { |
| var response = JSON.parse(msg); |
| |
| if ((response.errorCode) && onfailure) |
| onfailure(response); |
| else if (onsuccess) |
| onsuccess(response); |
| |
| if (oncomplete) |
| oncomplete(response); |
| } |
| |
| this.data = (typeof params.parameters === 'object') ? JSON.stringify(params.parameters) : '{}'; |
| |
| this.req.call(this.url, this.data); |
| } |
| |
| if (typeof navigator.service == "undefined") navigator.service = new Service(); |
| |
| /* |
| * This class provides access to the device SMS functionality. |
| * @constructor |
| */ |
| function Sms() { |
| |
| }; |
| |
| /* |
| * Sends an SMS message. |
| * @param {Integer} number The phone number to send the message to. |
| * @param {String} message The contents of the SMS message to send. |
| * @param {Function} successCallback The function to call when the SMS message is sent. |
| * @param {Function} errorCallback The function to call when there is an error sending the SMS message. |
| * @param {PositionOptions} options The options for accessing the GPS location such as timeout and accuracy. |
| */ |
| Sms.prototype.send = function(number, message, successCallback, errorCallback, options) { |
| try { |
| this.service = navigator.service.Request('palm://com.palm.applicationManager', { |
| method: 'launch', |
| parameters: { |
| id: "com.palm.app.messaging", |
| params: { |
| composeAddress: number, |
| messageText: message |
| } |
| } |
| }); |
| successCallback(); |
| } catch(ex) { |
| errorCallback({ |
| name: "SMSerror", |
| message: ex.name + ": " + ex.message |
| }); |
| } |
| }; |
| |
| if (typeof navigator.sms == "undefined") navigator.sms = new Sms(); |
| |
| /* |
| * This class provides access to the telephony features of the device. |
| * @constructor |
| */ |
| function Telephony() { |
| this.number = ""; |
| }; |
| |
| /* |
| * Calls the specifed number. |
| * @param {Integer} number The number to be called. |
| */ |
| Telephony.prototype.send = function(number) { |
| this.number = number; |
| this.service = navigator.service.Request('palm://com.palm.applicationManager', { |
| method: 'open', |
| parameters: { |
| target: "tel://" + number |
| } |
| }); |
| }; |
| |
| if (typeof navigator.telephony == "undefined") navigator.telephony = new Telephony(); |
| |
| function Window() { |
| |
| }; |
| |
| /* |
| * This is a thin wrapper for 'window.open()' which optionally sets document contents to 'html', and calls 'PalmSystem.stageReady()' |
| * on your new card. Note that this new card will not come with your framework (if any) or anything for that matter. |
| * @param {String} url |
| * @param {String} html |
| * Example: |
| * navigator.window.newCard('about:blank', '<html><body>Hello again!</body></html>'); |
| */ |
| Window.prototype.newCard = function(url, html) { |
| var win = window.open(url || ""); |
| if (html) |
| win.document.write(html); |
| win.PalmSystem.stageReady(); |
| }; |
| |
| /* |
| * Enable or disable full screen display (full screen removes the app menu bar and the rounded corners of the screen). |
| * @param {Boolean} state |
| * Example: |
| * navigator.window.setFullScreen(true); |
| */ |
| Window.prototype.setFullScreen = function(state) { |
| // valid state values are: true or false |
| PalmSystem.enableFullScreenMode(state); |
| }; |
| |
| /* |
| * used to set the window properties of the WebOS app |
| * @param {Object} props |
| * Example: |
| * private method used by other member functions - ideally we shouldn't call this method |
| */ |
| Window.prototype.setWindowProperties = function(props) { |
| if (typeof props === 'object') |
| navigator.windowProperties = props; |
| |
| PalmSystem.setWindowProperties(props || this.windowProperties); |
| }; |
| |
| /* |
| * Enable or disable screen timeout. When enabled, the device screen will not dim. This is useful for navigation, clocks or other "dock" apps. |
| * @param {Boolean} state |
| * Example: |
| * navigator.window.blockScreenTimeout(true); |
| */ |
| Window.prototype.blockScreenTimeout = function(state) { |
| navigator.windowProperties.blockScreenTimeout = state; |
| this.setWindowProperties(); |
| }; |
| |
| /* |
| * Sets the lightbar to be a little dimmer for screen locked notifications. |
| * @param {Boolean} state |
| * Example: |
| * navigator.window.setSubtleLightbar(true); |
| */ |
| Window.prototype.setSubtleLightbar = function(state) { |
| navigator.windowProperties.setSubtleLightbar = state; |
| this.setWindowProperties(); |
| }; |
| |
| if (typeof navigator.window == 'undefined') navigator.window = new Window(); |
| |
| /* |
| * Object for storing WebOS window properties |
| */ |
| function WindowProperties() { |
| blockScreenTimeout = false; |
| setSubtleLightbar = false; |
| fastAccelerometer = false; |
| }; |
| |
| if (typeof navigator.windowProperties == 'undefined') navigator.windowProperties = new WindowProperties();(function(window) { |
| |
| /** |
| * Do not use thumbs.js on touch-enabled devices |
| * |
| * Thanks to Jesse MacFadyen (purplecabbage): |
| * https://gist.github.com/850593#gistcomment-22484 |
| */ |
| try { |
| document.createEvent('TouchEvent'); |
| return; |
| } |
| catch(e) { |
| } |
| |
| /** |
| * Map touch events to mouse events |
| */ |
| var eventMap = { |
| 'mousedown': 'touchstart', |
| 'mouseup': 'touchend', |
| 'mousemove': 'touchmove' |
| }; |
| |
| /** |
| * Fire touch events |
| * |
| * Monitor mouse events and fire a touch event on the |
| * object broadcasting the mouse event. This approach |
| * likely has poorer performance than hijacking addEventListener |
| * but it is a little more browser friendly. |
| */ |
| window.addEventListener('load', function() { |
| for (var key in eventMap) { |
| document.body.addEventListener(key, function(e) { |
| // Supports: |
| // - addEventListener |
| // - setAttribute |
| var event = createTouchEvent(eventMap[e.type], e); |
| e.target.dispatchEvent(event); |
| |
| // Supports: |
| // - element.ontouchstart |
| var fn = e.target['on' + eventMap[e.type]]; |
| if (typeof fn === 'function') fn(e); |
| }, false); |
| } |
| }, false); |
| |
| /** |
| * Utility function to create a touch event. |
| * |
| * @param name {String} of the event |
| * @return event {Object} |
| */ |
| var createTouchEvent = function(name, e) { |
| var event = document.createEvent('MouseEvents'); |
| |
| event.initMouseEvent( |
| name, |
| e.bubbles, |
| e.cancelable, |
| e.view, |
| e.detail, |
| e.screenX, |
| e.screenY, |
| e.clientX, |
| e.clientY, |
| e.ctrlKey, |
| e.altKey, |
| e.shiftKey, |
| e.metaKey, |
| e.button, |
| e.relatedTarget |
| ); |
| |
| return event; |
| }; |
| |
| })(window); |