| /* |
| This is a machine generated file, do not edit directly. -jm |
| */ |
| |
| |
| |
| /* |
| * 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-2011, IBM Corporation |
| * Copyright (c) 2011, Microsoft 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 |
| * onPause User event fired to indicate a pause lifecycle event |
| * onDestroy Internal event fired when app is being destroyed (User should use window.onunload event, not this one). |
| * |
| * 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); |
| * document.addEventListener("pause", myPauseListener, false); |
| */ |
| |
| if (typeof(DeviceInfo) !== 'object') { |
| var DeviceInfo = {}; |
| } |
| |
| var PhoneGap = { |
| queue: { |
| ready: true, |
| commands: [], |
| timer: null |
| }, |
| available:false, |
| callbackId:0, |
| callbacks:{}, |
| resources:{} |
| }; |
| |
| 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 |
| }; |
| |
| /** |
| * Determine if resource has been loaded by PhoneGap |
| * |
| * @param name |
| * @return |
| */ |
| PhoneGap.hasResource = function(name) { |
| return PhoneGap.resources[name]; |
| }; |
| |
| /** |
| * Add a resource to list of loaded resources by PhoneGap |
| * |
| * @param name |
| */ |
| PhoneGap.addResource = function(name) { |
| PhoneGap.resources[name] = true; |
| }; |
| |
| PhoneGap.exec = function(success, fail, service, action, args) |
| { |
| |
| var callbackId = service + PhoneGap.callbackId++; |
| if (typeof success == "function" || typeof fail == "function") |
| { |
| PhoneGap.callbacks[callbackId] = {success:success, fail:fail}; |
| } |
| |
| // generate a new command string, ex. DebugConsole/log/DebugConsole23/{"message":"wtf dude?"} |
| var command = service + "/" + action + "/" + callbackId + "/" + JSON.stringify(args); |
| // pass it on to Notify |
| window.external.Notify(command); |
| }; |
| |
| PhoneGapCommandResult = function(status,callbackId,args,cast) |
| { |
| if(status === "backbutton") { |
| |
| PhoneGap.fireEvent(document,"backbutton"); |
| return "true"; |
| |
| } else if(status === "resume") { |
| |
| PhoneGap.onResume.fire(); |
| return "true"; |
| |
| } else if(status === "pause") { |
| |
| PhoneGap.onPause.fire(); |
| return "true"; |
| } |
| |
| var safeStatus = parseInt(status); |
| if(safeStatus === PhoneGap.callbackStatus.NO_RESULT || |
| safeStatus === PhoneGap.callbackStatus.OK) { |
| PhoneGap.CallbackSuccess(callbackId,args,cast); |
| } |
| else |
| { |
| PhoneGap.CallbackError(callbackId,args,cast); |
| } |
| }; |
| |
| /** |
| * Called by native code when returning successful result from an action. |
| * |
| * @param callbackId |
| * @param args |
| * @param cast |
| */ |
| PhoneGap.CallbackSuccess = function(callbackId, args, cast) |
| { |
| |
| var commandResult; |
| try |
| { |
| commandResult = JSON.parse(args); |
| |
| if (typeof cast !== 'undefined') |
| { |
| eval('commandResult = ' + cast + '(commandResult);'); |
| } |
| |
| } |
| catch(exception) |
| { |
| return exception.message; |
| } |
| |
| if (PhoneGap.callbacks[callbackId] ) { |
| |
| // If result is to be sent to callback |
| if (commandResult.status === PhoneGap.callbackStatus.OK) { |
| try { |
| if (PhoneGap.callbacks[callbackId].success) { |
| result = PhoneGap.callbacks[callbackId].success(commandResult.message); |
| } |
| } |
| catch (e) { |
| console.log("Error in success callback: "+callbackId+" = " + e.message); |
| } |
| } |
| |
| // Clear callback if not expecting any more results |
| if (!commandResult.keepCallback) { |
| delete PhoneGap.callbacks[callbackId]; |
| } |
| } |
| // Note that in WP7, this method can return a value to the native calling code |
| return ""; |
| }; |
| |
| /** |
| * Called by native code when returning error result from an action. |
| * |
| * @param callbackId |
| * @param args |
| * @param cast - not supported |
| */ |
| PhoneGap.CallbackError = function (callbackId, args, cast) { |
| |
| var commandResult; |
| try |
| { |
| commandResult = JSON.parse(args); |
| } |
| catch(exception) |
| { |
| return exception.message; |
| } |
| |
| if (PhoneGap.callbacks[callbackId]) { |
| try { |
| if (PhoneGap.callbacks[callbackId].fail) { |
| PhoneGap.callbacks[callbackId].fail(commandResult.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]; |
| } |
| } |
| }; |
| |
| /** |
| * Create a UUID |
| * |
| * @return {String} |
| */ |
| 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 = ""; |
| var i, uuidchar; |
| for (i=0; i<length; i++) { |
| uuidchar = parseInt((Math.random() * 256),0).toString(16); |
| if (uuidchar.length === 1) { |
| uuidchar = "0" + uuidchar; |
| } |
| uuidpart += uuidchar; |
| } |
| return uuidpart; |
| }; |
| |
| /** |
| * Does a deep clone of the object. |
| * |
| * @param obj |
| * @return {Object} |
| */ |
| PhoneGap.clone = function(obj) { |
| var i, retVal; |
| if(!obj) { |
| return obj; |
| } |
| |
| if(obj instanceof Array){ |
| retVal = []; |
| for(i = 0; i < obj.length; ++i){ |
| retVal.push(PhoneGap.clone(obj[i])); |
| } |
| return retVal; |
| } |
| |
| if (typeof obj === "function") { |
| return obj; |
| } |
| |
| if(!(obj instanceof Object)){ |
| return obj; |
| } |
| |
| if (obj instanceof Date) { |
| return obj; |
| } |
| |
| retVal = {}; |
| for(i in obj){ |
| if(!(i in retVal) || retVal[i] !== obj[i]) { |
| retVal[i] = PhoneGap.clone(obj[i]); |
| } |
| } |
| return retVal; |
| }; |
| |
| /*Clones object, but catches exception*/ |
| PhoneGap.safeClone = function(obj) |
| { |
| try |
| { |
| return PhoneGap.clone(obj); |
| } |
| catch(e) |
| { |
| console.log("CloneError::" + e.message); |
| } |
| return null; |
| }; |
| |
| |
| /** |
| * Custom pub-sub channel that can have functions subscribed to it |
| * @constructor |
| */ |
| 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" && typeof f === "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" && typeof f === "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 (typeof g === "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; |
| var item, handler, rv; |
| for (item in this.handlers) { |
| if (this.handlers.hasOwnProperty(item)) { |
| handler = this.handlers[item]; |
| if (typeof handler === "function") { |
| 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(); |
| } |
| }; |
| var len = i; |
| var j; |
| for (j=0; j<len; j++) { |
| if (!c[j].fired) { |
| c[j].subscribeOnce(f); |
| } |
| else { |
| i--; |
| } |
| } |
| if (!i) { |
| h(); |
| } |
| }; |
| |
| /** |
| * Boolean flag indicating if the PhoneGap API is available and initialized. |
| */ // TODO: Remove this, it is unused here ... -jm |
| PhoneGap.available = DeviceInfo.uuid !== undefined; |
| |
| /** |
| * Add an initialization function to a queue that ensures it will run and initialize |
| * application constructors only once PhoneGap has been initialized. |
| * @param {Function} func The function callback you want run once PhoneGap is initialized |
| */ |
| PhoneGap.addConstructor = function(func) |
| { |
| PhoneGap.onPhoneGapInit.subscribeOnce(function() { |
| try { |
| func(); |
| } catch(e) { |
| console.log("Failed to run constructor: " + e); |
| } |
| }); |
| }; |
| |
| /** |
| * Plugins object |
| */ |
| if (!window.plugins) { |
| window.plugins = {}; |
| }; |
| |
| /** |
| * Adds a plugin object to window.plugins. |
| * The plugin is accessed using window.plugins.<name> |
| * |
| * @param name The plugin name |
| * @param obj The plugin object |
| */ |
| PhoneGap.addPlugin = function(name, obj) { |
| if (!window.plugins[name]) { |
| window.plugins[name] = obj; |
| } |
| else { |
| console.log("Error: Plugin "+name+" already exists."); |
| } |
| }; |
| |
| /** |
| * onDOMContentLoaded channel is fired when the DOM content |
| * of the page has been parsed. |
| */ |
| PhoneGap.onDOMContentLoaded = new PhoneGap.Channel('onDOMContentLoaded'); |
| |
| /** |
| * onNativeReady channel is fired when the PhoneGap native code |
| * has been initialized. |
| */ |
| PhoneGap.onNativeReady = new PhoneGap.Channel('onNativeReady'); |
| |
| /** |
| * onPhoneGapInit channel is fired when the web page is fully loaded and |
| * PhoneGap native code has been initialized. |
| */ |
| PhoneGap.onPhoneGapInit = new PhoneGap.Channel('onPhoneGapInit'); |
| |
| /** |
| * onPhoneGapReady channel is fired when the JS PhoneGap objects have been created. |
| */ |
| PhoneGap.onPhoneGapReady = new PhoneGap.Channel('onPhoneGapReady'); |
| |
| /** |
| * onPhoneGapInfoReady channel is fired when the PhoneGap device properties |
| * has been set. |
| */ |
| PhoneGap.onPhoneGapInfoReady = new PhoneGap.Channel('onPhoneGapInfoReady'); |
| |
| /** |
| * onPhoneGapConnectionReady channel is fired when the PhoneGap connection properties |
| * has been set. |
| */ |
| PhoneGap.onPhoneGapConnectionReady = new PhoneGap.Channel('onPhoneGapConnectionReady'); |
| |
| /** |
| * onResume channel is fired when the PhoneGap native code |
| * resumes. |
| */ |
| PhoneGap.onResume = new PhoneGap.Channel('onResume'); |
| |
| /** |
| * onPause channel is fired when the PhoneGap native code |
| * pauses. |
| */ |
| PhoneGap.onPause = new PhoneGap.Channel('onPause'); |
| |
| /** |
| * onDestroy channel is fired when the PhoneGap native code |
| * is destroyed. It is used internally. |
| * Window.onunload should be used by the user. |
| */ |
| PhoneGap.onDestroy = new PhoneGap.Channel('onDestroy'); |
| PhoneGap.onDestroy.subscribeOnce(function() { |
| PhoneGap.shuttingDown = true; |
| }); |
| PhoneGap.shuttingDown = false; |
| |
| // _nativeReady is global variable that the native side can set |
| // to signify that the native code is ready. It is a global since |
| // it may be called before any PhoneGap JS is ready. |
| if (typeof _nativeReady !== 'undefined') { PhoneGap.onNativeReady.fire(); } |
| |
| /** |
| * onDeviceReady is fired only after all PhoneGap objects are created and |
| * the device properties are set. |
| */ |
| PhoneGap.onDeviceReady = new PhoneGap.Channel('onDeviceReady'); |
| |
| |
| // Array of channels that must fire before "deviceready" is fired |
| PhoneGap.deviceReadyChannelsArray = [ PhoneGap.onPhoneGapReady, PhoneGap.onPhoneGapInfoReady, PhoneGap.onPhoneGapConnectionReady]; |
| |
| // Hashtable of user defined channels that must also fire before "deviceready" is fired |
| PhoneGap.deviceReadyChannelsMap = {}; |
| |
| /** |
| * Indicate that a feature needs to be initialized before it is ready to be used. |
| * This holds up PhoneGap's "deviceready" event until the feature has been initialized |
| * and PhoneGap.initComplete(feature) is called. |
| * |
| * @param feature {String} The unique feature name |
| */ |
| PhoneGap.waitForInitialization = function(feature) { |
| if (feature) { |
| var channel = new PhoneGap.Channel(feature); |
| PhoneGap.deviceReadyChannelsMap[feature] = channel; |
| PhoneGap.deviceReadyChannelsArray.push(channel); |
| } |
| }; |
| |
| /** |
| * Indicate that initialization code has completed and the feature is ready to be used. |
| * |
| * @param feature {String} The unique feature name |
| */ |
| PhoneGap.initializationComplete = function(feature) { |
| var channel = PhoneGap.deviceReadyChannelsMap[feature]; |
| if (channel) { |
| channel.fire(); |
| } |
| }; |
| |
| /** |
| * Create all PhoneGap objects once page has fully loaded and native side is ready. |
| */ |
| PhoneGap.Channel.join( |
| function() |
| { |
| |
| setTimeout(function() |
| { |
| |
| PhoneGap.UsePolling = false; |
| //PhoneGap.JSCallback(); |
| },1); |
| |
| // Run PhoneGap constructors |
| PhoneGap.onPhoneGapInit.fire(); |
| |
| // Fire event to notify that all objects are created |
| PhoneGap.onPhoneGapReady.fire(); |
| |
| // Fire onDeviceReady event once all constructors have run and PhoneGap info has been |
| // received from native side, and any user defined initialization channels. |
| PhoneGap.Channel.join(function() { |
| PhoneGap.onDeviceReady.fire(); |
| |
| // Fire the onresume event, since first one happens before JavaScript is loaded |
| PhoneGap.onResume.fire(); |
| }, PhoneGap.deviceReadyChannelsArray); |
| |
| }, |
| [ PhoneGap.onDOMContentLoaded ]); |
| |
| |
| |
| // Listen for DOMContentLoaded and notify our channel subscribers |
| document.addEventListener('DOMContentLoaded', function() { |
| PhoneGap.onDOMContentLoaded.fire(); |
| }, false); |
| |
| PhoneGap.m_document_addEventListener = document.addEventListener; |
| document.addEventListener = function(evt, handler, capture) |
| { |
| console.log("document.addEventListener event named " + evt); |
| |
| var e = evt.toLowerCase(); |
| if (e === 'deviceready') |
| { |
| PhoneGap.onDeviceReady.subscribeOnce(handler); |
| } |
| else if (e === 'resume') |
| { |
| PhoneGap.onResume.subscribe(handler); |
| if (PhoneGap.onDeviceReady.fired) |
| { |
| PhoneGap.onResume.fire(); |
| } |
| } |
| else if (e === 'pause') |
| { |
| PhoneGap.onPause.subscribe(handler); |
| } |
| else |
| { |
| |
| if (e === 'backbutton') |
| { |
| PhoneGap.exec(null, null, "CoreEvents", "overrideBackbutton", [true]); |
| } |
| PhoneGap.m_document_addEventListener.call(document, evt, handler, capture); |
| } |
| }; |
| |
| PhoneGap.m_document_removeEventListener = document.removeEventListener; |
| document.removeEventListener = function(evt, handler, capture) |
| { |
| console.log("document.removeEventListener event named " + evt); |
| |
| var e = evt.toLowerCase(); |
| |
| if (e === 'backbutton') |
| { |
| PhoneGap.exec(null, null, "CoreEvents", "overrideBackbutton", [false]); |
| } |
| PhoneGap.m_document_removeEventListener.call(document, evt, handler, capture); |
| |
| } |
| |
| |
| PhoneGap.fireEvent = function(_targ,evtName) |
| { |
| var target = _targ || window; |
| var eventObj = document.createEvent('MouseEvents'); |
| eventObj.initEvent( evtName, true, false ); |
| target.dispatchEvent( eventObj ); |
| } |
| |
| |
| /* |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| if (!PhoneGap.hasResource("accelerometer")) |
| { |
| PhoneGap.addResource("accelerometer"); |
| |
| /** @constructor */ |
| var Acceleration = function(x, y, z) { |
| this.x = x; |
| this.y = y; |
| this.z = z; |
| this.timestamp = new Date().getTime(); |
| }; |
| |
| /** |
| * This class provides access to device accelerometer data. |
| * @constructor |
| */ |
| var Accelerometer = function() { |
| |
| /** |
| * The last known acceleration. type=Acceleration() |
| */ |
| this.lastAcceleration = null; |
| |
| /** |
| * List of accelerometer watch timers |
| */ |
| this.timers = {}; |
| }; |
| |
| Accelerometer.ERROR_MSG = ["Not running", "Starting", "", "Failed to start"]; |
| |
| /** |
| * 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. (OPTIONAL) |
| * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL) |
| */ |
| Accelerometer.prototype.getCurrentAcceleration = function(successCallback, errorCallback, options) { |
| |
| // successCallback required |
| if (typeof successCallback !== "function") { |
| console.log("Accelerometer Error: successCallback is not a function"); |
| return; |
| } |
| |
| // errorCallback optional |
| if (errorCallback && (typeof errorCallback !== "function")) { |
| console.log("Accelerometer Error: errorCallback is not a function"); |
| return; |
| } |
| |
| var self = this; |
| |
| var onSuccess = function(result) |
| { |
| var accResult = JSON.parse(result); |
| self.lastAcceleration = new Acceleration(accResult.x,accResult.y,accResult.z); |
| successCallback(self.lastAcceleration); |
| } |
| |
| var onError = function(err) |
| { |
| errorCallback(err); |
| } |
| |
| // Get acceleration |
| PhoneGap.exec(onSuccess, onError, "Accelerometer", "getAcceleration",options); |
| }; |
| |
| |
| /** |
| * 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. (OPTIONAL) |
| * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL) |
| * @return String The watch id that must be passed to #clearWatch to stop watching. |
| */ |
| Accelerometer.prototype.watchAcceleration = function(successCallback, errorCallback, options) |
| { |
| var self = this; |
| // successCallback required |
| if (typeof successCallback !== "function") { |
| console.log("Accelerometer Error: successCallback is not a function"); |
| return; |
| } |
| |
| // errorCallback optional |
| if (errorCallback && (typeof errorCallback !== "function")) { |
| console.log("Accelerometer Error: errorCallback is not a function"); |
| return; |
| } |
| |
| var onSuccess = function (result) { |
| var accResult = JSON.parse(result); |
| self.lastAcceleration = new Acceleration(accResult.x, accResult.y, accResult.z); |
| successCallback(self.lastAcceleration); |
| } |
| |
| var onError = function (err) { |
| errorCallback(err); |
| } |
| |
| var id = PhoneGap.createUUID(); |
| |
| var params = new Object(); |
| params.id = id; |
| // Default interval (10 sec) |
| params.frequency = (options && options.frequency) ? options.frequency : 10000; |
| |
| PhoneGap.exec(onSuccess, onError, "Accelerometer", "startWatch", params); |
| |
| return id; |
| }; |
| |
| /** |
| * Clears the specified accelerometer watch. |
| * |
| * @param {String} id The id of the watch returned from #watchAcceleration. |
| */ |
| Accelerometer.prototype.clearWatch = function(id) { |
| |
| PhoneGap.exec(null, null, "Accelerometer", "stopWatch", { id: id }); |
| }; |
| |
| PhoneGap.onPhoneGapInit.subscribeOnce( |
| function() |
| { |
| if (!navigator.accelerometer) |
| { |
| navigator.accelerometer = new Accelerometer(); |
| } |
| }); |
| } |
| |
| /* |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| if (!PhoneGap.hasResource("camera")) { |
| PhoneGap.addResource("camera"); |
| |
| /** |
| * This class provides access to the device camera. |
| * |
| * @constructor |
| */ |
| var 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; |
| |
| /** |
| * Encoding of image returned from getPicture. |
| * |
| * Example: navigator.camera.getPicture(success, fail, |
| * { quality: 80, |
| * destinationType: Camera.DestinationType.DATA_URL, |
| * sourceType: Camera.PictureSourceType.CAMERA, |
| * encodingType: Camera.EncodingType.PNG}) |
| */ |
| Camera.EncodingType = { |
| JPEG: 0, // Return JPEG encoded image |
| PNG: 1 // Return PNG encoded image |
| }; |
| Camera.prototype.EncodingType = Camera.EncodingType; |
| |
| /** |
| * 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) { |
| console.log("Camera.prototype.getPicture"); |
| // 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; |
| |
| // TODO: This is duplicate - default values initialization exists in native C# code |
| // var quality = 80; |
| // if (options.quality) { |
| // quality = this.options.quality; |
| // } |
| // |
| // var maxResolution = 0; |
| // if (options.maxResolution) { |
| // maxResolution = this.options.maxResolution; |
| // } |
| // |
| // 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; |
| // } |
| // var encodingType = Camera.EncodingType.JPEG; |
| // if (typeof options.encodingType == "number") { |
| // encodingType = this.options.encodingType; |
| // } |
| // |
| // var targetWidth = -1; |
| // if (typeof options.targetWidth == "number") { |
| // targetWidth = options.targetWidth; |
| // } else if (typeof options.targetWidth == "string") { |
| // var width = new Number(options.targetWidth); |
| // if (isNaN(width) === false) { |
| // targetWidth = width.valueOf(); |
| // } |
| // } |
| |
| // var targetHeight = -1; |
| // if (typeof options.targetHeight == "number") { |
| // targetHeight = options.targetHeight; |
| // } else if (typeof options.targetHeight == "string") { |
| // var height = new Number(options.targetHeight); |
| // if (isNaN(height) === false) { |
| // targetHeight = height.valueOf(); |
| // } |
| // } |
| |
| PhoneGap.exec(successCallback, errorCallback, "Camera", "getPicture", this.options); |
| }; |
| |
| PhoneGap.onPhoneGapInit.subscribeOnce(function() { |
| if (typeof navigator.camera === "undefined") { |
| navigator.camera = new Camera(); |
| } |
| }); |
| } |
| |
| /* |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| if (!PhoneGap.hasResource("capture")) { |
| PhoneGap.addResource("capture"); |
| |
| /** |
| * Represents a single file. |
| * |
| * name {DOMString} name of the file, without path information |
| * fullPath {DOMString} the full path of the file, including the name |
| * type {DOMString} mime type |
| * lastModifiedDate {Date} last modified date |
| * size {Number} size of the file in bytes |
| */ |
| var MediaFile = function(name, fullPath, type, lastModifiedDate, size){ |
| this.name = name || null; |
| this.fullPath = fullPath || null; |
| this.type = type || null; |
| this.lastModifiedDate = lastModifiedDate || null; |
| this.size = size || 0; |
| }; |
| |
| /** |
| * Get file meta information |
| * |
| * @param {Function} successCB |
| * @param {Function} errorCB |
| */ |
| MediaFile.prototype.getFormatData = function(successCallback, errorCallback){ |
| PhoneGap.exec(successCallback, errorCallback, "Capture", "getFormatData", {fullPath: this.fullPath, type: this.type}); |
| }; |
| |
| |
| /** |
| * Open file in device media player |
| * |
| * @param {Function} successCB |
| * @param {Function} errorCB |
| */ |
| MediaFile.prototype.play = function(successCallback, errorCallback){ |
| PhoneGap.exec(successCallback, errorCallback, "Capture", "play", this); |
| }; |
| |
| |
| /** |
| * MediaFileData encapsulates format information of a media file. |
| * |
| * @param {DOMString} codecs |
| * @param {long} bitrate |
| * @param {long} height |
| * @param {long} width |
| * @param {float} duration |
| */ |
| var MediaFileData = function(codecs, bitrate, height, width, duration){ |
| this.codecs = codecs || null; |
| this.bitrate = bitrate || 0; |
| this.height = height || 0; |
| this.width = width || 0; |
| this.duration = duration || 0; |
| }; |
| |
| /** |
| * The CaptureError interface encapsulates all errors in the Capture API. |
| */ |
| var CaptureError = function(){ |
| this.code = null; |
| }; |
| |
| // Capture error codes |
| CaptureError.CAPTURE_INTERNAL_ERR = 0; |
| CaptureError.CAPTURE_APPLICATION_BUSY = 1; |
| CaptureError.CAPTURE_INVALID_ARGUMENT = 2; |
| CaptureError.CAPTURE_NO_MEDIA_FILES = 3; |
| CaptureError.CAPTURE_NOT_SUPPORTED = 20; |
| |
| /** |
| * The Capture interface exposes an interface to the camera and microphone of the hosting device. |
| */ |
| var Capture = function(){ |
| this.supportedAudioModes = []; |
| this.supportedImageModes = []; |
| this.supportedVideoModes = []; |
| }; |
| |
| /** |
| * Launch audio recorder application for recording audio clip(s). |
| * |
| * @param {Function} successCB |
| * @param {Function} errorCB |
| * @param {CaptureAudioOptions} options |
| */ |
| Capture.prototype.captureAudio = function(successCallback, errorCallback, options){ |
| PhoneGap.exec(successCallback, errorCallback, "Capture", "captureAudio", options); |
| }; |
| |
| /** |
| * Launch camera application for taking image(s). |
| * |
| * @param {Function} successCB |
| * @param {Function} errorCB |
| * @param {CaptureImageOptions} options |
| */ |
| Capture.prototype.captureImage = function (successCallback, errorCallback, options) { |
| PhoneGap.exec(successCallback, errorCallback, "Capture", "captureImage", options); |
| }; |
| |
| /** |
| * Launch device camera application for recording video(s). |
| * |
| * @param {Function} successCB |
| * @param {Function} errorCB |
| * @param {CaptureVideoOptions} options |
| */ |
| Capture.prototype.captureVideo = function(successCallback, errorCallback, options){ |
| PhoneGap.exec(successCallback, errorCallback, "Capture", "captureVideo", options); |
| }; |
| |
| /** |
| * This function returns and array of MediaFiles. It is required as we need to convert raw |
| * JSON objects into MediaFile objects. |
| */ |
| Capture.prototype._castMediaFile = function(pluginResult){ |
| var mediaFiles = []; |
| var i; |
| for (i = 0; i < pluginResult.message.length; i++) { |
| var mediaFile = new MediaFile(); |
| mediaFile.name = pluginResult.message[i].name; |
| mediaFile.fullPath = pluginResult.message[i].fullPath; |
| mediaFile.type = pluginResult.message[i].type; |
| mediaFile.lastModifiedDate = pluginResult.message[i].lastModifiedDate; |
| mediaFile.size = pluginResult.message[i].size; |
| mediaFiles.push(mediaFile); |
| } |
| pluginResult.message = mediaFiles; |
| return pluginResult; |
| }; |
| |
| /** |
| * Encapsulates a set of parameters that the capture device supports. |
| */ |
| var ConfigurationData = function(){ |
| // The ASCII-encoded string in lower case representing the media type. |
| this.type = null; |
| // The height attribute represents height of the image or video in pixels. |
| // In the case of a sound clip this attribute has value 0. |
| this.height = 0; |
| // The width attribute represents width of the image or video in pixels. |
| // In the case of a sound clip this attribute has value 0 |
| this.width = 0; |
| }; |
| |
| /** |
| * Encapsulates all image capture operation configuration options. |
| */ |
| var CaptureImageOptions = function(){ |
| // Upper limit of images user can take. Value must be equal or greater than 1. |
| this.limit = 1; |
| // The selected image mode. Must match with one of the elements in supportedImageModes array. |
| this.mode = null; |
| }; |
| |
| /** |
| * Encapsulates all video capture operation configuration options. |
| */ |
| var CaptureVideoOptions = function(){ |
| // Upper limit of videos user can record. Value must be equal or greater than 1. |
| this.limit = 1; |
| // Maximum duration of a single video clip in seconds. |
| this.duration = 0; |
| // The selected video mode. Must match with one of the elements in supportedVideoModes array. |
| this.mode = null; |
| }; |
| |
| /** |
| * Encapsulates all audio capture operation configuration options. |
| */ |
| var CaptureAudioOptions = function(){ |
| // Upper limit of sound clips user can record. Value must be equal or greater than 1. |
| this.limit = 1; |
| // Maximum duration of a single sound clip in seconds. |
| this.duration = 0; |
| // The selected audio mode. Must match with one of the elements in supportedAudioModes array. |
| this.mode = null; |
| }; |
| PhoneGap.onPhoneGapInit.subscribeOnce(function () { |
| if (typeof navigator.device === "undefined") { |
| navigator.device = window.device = new Device(); |
| } |
| if (typeof navigator.device.capture === "undefined") { |
| console.log("Installing capture"); |
| navigator.device.capture = window.device.capture = new Capture(); |
| } |
| }); |
| } |
| |
| /* |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| if (!PhoneGap.hasResource("compass")) { |
| PhoneGap.addResource("compass"); |
| |
| /** |
| * This class provides access to device Compass data. |
| * @constructor |
| */ |
| var Compass = function() { |
| /** |
| * The last known Compass position. |
| */ |
| this.lastHeading = null; |
| this.isCompassSupported = true; // default assumption |
| }; |
| |
| // Capture error codes |
| CompassError = { |
| COMPASS_INTERNAL_ERR:0, |
| COMPASS_NOT_SUPPORTED:20 |
| } |
| |
| /** |
| * 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; |
| |
| errorCallback = function(){}; |
| } |
| |
| if(this.isCompassSupported) |
| { |
| var self = this; |
| var onSuccess = function(result) |
| { |
| var compassResult = JSON.parse(result); |
| //console.log("compassResult = " + result); |
| self.lastHeading = compassResult; |
| successCallback(self.lastHeading); |
| } |
| |
| var onError = function(err) |
| { |
| if(err == CompassError.COMPASS_NOT_SUPPORTED) |
| { |
| self.isCompassSupported = false; |
| } |
| errorCallback(err); |
| } |
| |
| // Get heading |
| PhoneGap.exec(onSuccess, onError, "Compass", "getHeading", []); |
| } |
| else |
| { |
| var funk = function() |
| { |
| errorCallback(CompassError.COMPASS_NOT_SUPPORTED); |
| }; |
| window.setTimeout(funk,0); // async |
| } |
| }; |
| |
| /** |
| * 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 self = this; |
| |
| // successCallback required |
| if (typeof successCallback !== "function") { |
| console.log("Compass Error: successCallback is not a function"); |
| return -1; // in case caller later calls clearWatch with this id |
| } |
| |
| // errorCallback optional |
| if (errorCallback && (typeof errorCallback !== "function")) { |
| console.log("Compass Error: errorCallback is not a function"); |
| return -1; // in case caller later calls clearWatch with this id |
| } |
| |
| if(this.isCompassSupported) |
| { |
| var onSuccess = function (result) { |
| var compassResult = JSON.parse(result); |
| self.lastHeading = compassResult; |
| successCallback(self.lastHeading); |
| } |
| |
| var onError = function (err) { |
| errorCallback(err); |
| } |
| |
| var id = PhoneGap.createUUID(); |
| |
| var params = {id:id, |
| frequency:((options && options.frequency) ? options.frequency : 100)}; |
| |
| |
| PhoneGap.exec(onSuccess, onError, "Compass", "startWatch", params); |
| |
| return id; |
| } |
| else |
| { |
| var funk = function() |
| { |
| errorCallback(CompassError.COMPASS_NOT_SUPPORTED); |
| }; |
| window.setTimeout(funk,0); // async |
| return -1; |
| } |
| |
| }; |
| |
| |
| /** |
| * Clears the specified heading watch. |
| * |
| * @param {String} id The ID of the watch returned from #watchHeading. |
| */ |
| Compass.prototype.clearWatch = function(id) { |
| |
| PhoneGap.exec(null, null, "Compass", "stopWatch", { id: id }); |
| |
| }; |
| |
| PhoneGap.onPhoneGapInit.subscribeOnce( |
| function() |
| { |
| if (!navigator.compass) |
| { |
| navigator.compass = new Compass(); |
| } |
| }); |
| } |
| |
| /* |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| if (!PhoneGap.hasResource("contact")) { |
| PhoneGap.addResource("contact"); |
| |
| /** |
| * Contains information about a single contact. |
| * @constructor |
| * @param {DOMString} id unique identifier |
| * @param {DOMString} displayName |
| * @param {ContactName} name |
| * @param {DOMString} nickname |
| * @param {Array.<ContactField>} phoneNumbers array of phone numbers |
| * @param {Array.<ContactField>} emails array of email addresses |
| * @param {Array.<ContactAddress>} addresses array of addresses |
| * @param {Array.<ContactField>} ims instant messaging user ids |
| * @param {Array.<ContactOrganization>} organizations |
| * @param {DOMString} birthday contact's birthday |
| * @param {DOMString} note user notes about contact |
| * @param {Array.<ContactField>} photos |
| * @param {Array.<ContactField>} categories |
| * @param {Array.<ContactField>} urls contact's web sites |
| */ |
| var Contact = function (id, displayName, name, nickname, phoneNumbers, emails, addresses, |
| ims, organizations, birthday, note, photos, categories, urls) { |
| this.id = id || null; |
| this.rawId = 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.birthday = birthday || null; |
| this.note = note || null; |
| this.photos = photos || null; // ContactField[] |
| this.categories = categories || null; // ContactField[] |
| this.urls = urls || null; // ContactField[] |
| }; |
| |
| /** |
| * ContactError. |
| * An error code assigned by an implementation when an error has occurreds |
| * @constructor |
| */ |
| var ContactError = function(errCode) { |
| this.code=errCode; |
| }; |
| |
| /** |
| * Error codes |
| */ |
| ContactError.UNKNOWN_ERROR = 0; |
| ContactError.INVALID_ARGUMENT_ERROR = 1; |
| ContactError.TIMEOUT_ERROR = 2; |
| ContactError.PENDING_OPERATION_ERROR = 3; |
| ContactError.IO_ERROR = 4; |
| ContactError.NOT_SUPPORTED_ERROR = 5; |
| ContactError.PERMISSION_DENIED_ERROR = 20; |
| |
| /** |
| * Removes contact from device storage. |
| * @param successCB success callback |
| * @param errorCB error callback |
| */ |
| Contact.prototype.remove = function(successCB, errorCB) |
| { |
| if (!this.id) |
| { |
| var errorObj = new ContactError(ContactError.UNKNOWN_ERROR); |
| setTimeout(function(){ |
| errorCB(errorObj); |
| },0); |
| return ContactError.UNKNOWN_ERROR; |
| } |
| else |
| { |
| 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.safeClone(this); |
| var i; |
| clonedContact.id = null; |
| clonedContact.rawId = null; |
| // Loop through and clear out any id's in phones, emails, etc. |
| var myArrayProps = ["phoneNumbers","emails","addresses","ims","organizations","tags","photos","urls"]; |
| |
| for(var n=0, pLen=myArrayProps.length;n < pLen; n++) |
| { |
| var arr = clonedContact[myArrayProps[n]]; |
| if (arr && arr.length) |
| { |
| for(var i=0,len=arr.length; i<len;i++) |
| { |
| arr[i].id = null; |
| } |
| } |
| } |
| return clonedContact; |
| }; |
| |
| /** |
| * Persists contact to device storage. |
| * @param successCB success callback |
| * @param errorCB error callback |
| */ |
| Contact.prototype.save = function(successCB, errorCB) |
| { |
| var self = this; |
| function onSuccess(res) |
| { |
| setTimeout(function() |
| { |
| successCB(self); |
| },0); |
| } |
| PhoneGap.exec(onSuccess, errorCB, "Contacts", "save", this); |
| }; |
| |
| /** |
| * Contact name. |
| * @constructor |
| * @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. |
| * @constructor |
| * @param {DOMString} id unique identifier, should only be set by native code |
| * @param type |
| * @param value |
| * @param pref |
| */ |
| var ContactField = function(type, value, pref) { |
| this.id = null; |
| this.type = type || null; |
| this.value = value || null; |
| this.pref = pref || null; |
| }; |
| |
| /** |
| * Contact address. |
| * @constructor |
| * @param {DOMString} id unique identifier, should only be set by native code |
| * @param formatted |
| * @param streetAddress |
| * @param locality |
| * @param region |
| * @param postalCode |
| * @param country |
| */ |
| var ContactAddress = function(pref, type, formatted, streetAddress, locality, region, postalCode, country) { |
| this.id = null; |
| this.pref = pref || null; |
| this.type = type || null; |
| 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. |
| * @constructor |
| * @param {DOMString} id unique identifier, should only be set by native code |
| * @param name |
| * @param dept |
| * @param title |
| * @param startDate |
| * @param endDate |
| * @param location |
| * @param desc |
| */ |
| var ContactOrganization = function(pref, type, name, dept, title) { |
| this.id = null; |
| this.pref = pref || null; |
| this.type = type || null; |
| this.name = name || null; |
| this.department = dept || null; |
| this.title = title || null; |
| }; |
| |
| /** |
| * Represents a group of Contacts. |
| * @constructor |
| */ |
| var Contacts = function() { |
| this.inProgress = false; |
| this.records = []; |
| }; |
| /** |
| * 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) { |
| if (successCB === null) { |
| throw new TypeError("You must specify a success callback for the find command."); |
| } |
| if (fields === null || fields === "undefined" || fields.length === "undefined" || fields.length <= 0) { |
| if (typeof errorCB === "function") |
| { |
| // escape this scope before we call the errorCB |
| setTimeout(function() { |
| errorCB({"code": ContactError.INVALID_ARGUMENT_ERROR}); |
| },0); |
| } |
| console.log("Contacts.find::ContactError::INVALID_ARGUMENT_ERROR"); |
| } |
| else |
| { |
| var onSuccess = function(res) |
| { |
| setTimeout(function() |
| { |
| successCB(res); |
| },0); |
| } |
| PhoneGap.exec(onSuccess, errorCB, "Contacts", "search", {"fields":fields,"options":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 i; |
| var contact = new Contact(); |
| for (i in properties) { |
| if (contact[i] !== 'undefined') { |
| contact[i] = properties[i]; |
| } |
| } |
| return contact; |
| }; |
| |
| /** |
| * This function returns and array of contacts. It is required as we need to convert raw |
| * JSON objects into concrete Contact objects. Currently this method is called after |
| * navigator.contacts.find but before the find methods success call back. |
| * |
| * @param jsonArray an array of JSON Objects that need to be converted to Contact objects. |
| * @returns an array of Contact objects |
| */ |
| Contacts.prototype.cast = function(pluginResult) { |
| var contacts = []; |
| var i; |
| for (i=0; i<pluginResult.message.length; i++) { |
| contacts.push(navigator.contacts.create(pluginResult.message[i])); |
| } |
| pluginResult.message = contacts; |
| return pluginResult; |
| }; |
| |
| /** |
| * ContactFindOptions. |
| * @constructor |
| * @param filter used to match contacts against |
| * @param multiple boolean used to determine if more than one contact should be returned |
| */ |
| var ContactFindOptions = function(filter, multiple) { |
| this.filter = filter || ''; |
| this.multiple = multiple || false; |
| }; |
| |
| /** |
| * Add the contact interface into the browser. |
| */ |
| PhoneGap.onPhoneGapInit.subscribeOnce(function() { |
| if(typeof navigator.contacts === "undefined") { |
| navigator.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-2011, IBM Corporation |
| * Copyright (c) 2011, Microsoft Corporation |
| */ |
| |
| if (!PhoneGap.hasResource("debugConsole")) { |
| PhoneGap.addResource("debugConsole"); |
| |
| var debugConsole = |
| { |
| log:function(msg){ |
| PhoneGap.exec(null,null,"DebugConsole","log",msg); |
| }, |
| warn:function(msg){ |
| PhoneGap.exec(null,null,"DebugConsole","warn",msg); |
| }, |
| error:function(msg){ |
| PhoneGap.exec(null,null,"DebugConsole","error",msg); |
| } |
| }; |
| |
| |
| if(typeof window.console == "undefined") |
| { |
| window.console = { |
| log:function(str){ |
| if(navigator.debugConsole){ |
| navigator.debugConsole.log(str); |
| } |
| else |
| {// In case log messages are received before device ready |
| window.external.Notify("Info:" + str); |
| } |
| } |
| }; |
| } |
| |
| // output any errors to console log, created above. |
| window.onerror=function(e) |
| { |
| if(navigator.debugConsole) |
| { |
| navigator.debugConsole.error(JSON.stringify(e)); |
| } |
| else |
| {// In case errors occur before device ready |
| window.external.Notify("Error:" + JSON.stringify(e)); |
| } |
| }; |
| |
| |
| |
| PhoneGap.onPhoneGapInit.subscribeOnce(function() { |
| navigator.debugConsole = debugConsole; |
| }); |
| |
| } |
| |
| /* |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| if (!PhoneGap.hasResource("device")) { |
| PhoneGap.addResource("device"); |
| |
| /** |
| * This represents the mobile device, and provides properties for inspecting the model, version, UUID of the |
| * phone, etc. |
| * @constructor |
| */ |
| var Device = function() { |
| 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 (res) { |
| var info = JSON.parse(res); |
| console.log("GotDeviceInfo :: " + info.version); |
| me.available = true; |
| me.platform = info.platform; |
| me.version = info.version; |
| me.name = info.name; |
| me.uuid = info.uuid; |
| me.phonegap = info.phonegap; |
| |
| PhoneGap.onPhoneGapInfoReady.fire(); |
| }, |
| function(e) { |
| me.available = false; |
| console.log("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", "Get"); |
| }; |
| |
| PhoneGap.onPhoneGapInit.subscribeOnce(function() { |
| if (typeof navigator.device === "undefined") { |
| navigator.device = window.device = new Device(); |
| } |
| }); |
| } |
| |
| /* |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| // this is a WP7 Only implementation of the Storage API for use in webpages loaded from the local file system |
| // inside phonegap application. |
| // there is a native implementation which is backing this and providing the persistance of values. |
| // webpages loaded from a domain will not need to use this as IE9 has support for WebStorage |
| // Javascript Interface is as defined here : http://dev.w3.org/html5/webstorage/#storage-0 |
| // |
| |
| if(!window.localStorage) |
| {(function() |
| { |
| "use strict"; |
| |
| var DOMStorage = function(type) |
| { |
| // default type is local |
| if(type == "sessionStorage") |
| { |
| this._type = type; |
| } |
| Object.defineProperty( this, "length", |
| { |
| configurable: true, |
| get: function(){ return this.getLength() } |
| }); |
| |
| }; |
| |
| DOMStorage.prototype = |
| { |
| _type:"localStorage", |
| _result:null, |
| keys:null, |
| |
| onResult:function(key,valueStr) |
| { |
| if(!this.keys) |
| { |
| this.keys = []; |
| } |
| this._result = valueStr; |
| }, |
| |
| onKeysChanged:function(jsonKeys) |
| { |
| this.keys = JSON.parse(jsonKeys); |
| |
| var key; |
| for(var n = 0,len =this.keys.length; n < len; n++) |
| { |
| key = this.keys[n]; |
| if(!this.hasOwnProperty(key)) |
| { |
| Object.defineProperty( this, key, |
| { |
| |
| configurable: true, |
| get: function(){ return this.getItem(key); }, |
| set: function(val){ return this.setItem(key,val); } |
| }); |
| } |
| } |
| |
| }, |
| |
| initialize:function() |
| { |
| window.external.Notify("DOMStorage/" + this._type + "/load/keys"); |
| }, |
| |
| /* |
| The length attribute must return the number of key/value pairs currently present in the list associated with the object. |
| */ |
| getLength:function() |
| { |
| if(!this.keys) |
| { |
| this.initialize(); |
| } |
| return this.keys.length; |
| }, |
| |
| /* |
| The key(n) method must return the name of the nth key in the list. |
| The order of keys is user-agent defined, but must be consistent within an object so long as the number of keys doesn't change. |
| (Thus, adding or removing a key may change the order of the keys, but merely changing the value of an existing key must not.) |
| If n is greater than or equal to the number of key/value pairs in the object, then this method must return null. |
| */ |
| key:function(n) |
| { |
| if(!this.keys) |
| { |
| this.initialize(); |
| } |
| |
| if(n >= this.keys.length) |
| { |
| return null; |
| } |
| else |
| { |
| return this.keys[n]; |
| } |
| }, |
| |
| /* |
| The getItem(key) method must return the current value associated with the given key. |
| If the given key does not exist in the list associated with the object then this method must return null. |
| */ |
| getItem:function(key) |
| { |
| if(!this.keys) |
| { |
| this.initialize(); |
| } |
| |
| var retVal = null; |
| if(this.keys.indexOf(key) > -1) |
| { |
| window.external.Notify("DOMStorage/" + this._type + "/get/" + key); |
| retVal = this._result; |
| this._result = null; |
| } |
| return retVal; |
| }, |
| /* |
| The setItem(key, value) method must first check if a key/value pair with the given key already exists |
| in the list associated with the object. |
| If it does not, then a new key/value pair must be added to the list, with the given key and with its value set to value. |
| If the given key does exist in the list, then it must have its value updated to value. |
| If it couldn't set the new value, the method must raise an QUOTA_EXCEEDED_ERR exception. |
| (Setting could fail if, e.g., the user has disabled storage for the site, or if the quota has been exceeded.) |
| */ |
| setItem:function(key,value) |
| { |
| if(!this.keys) |
| { |
| this.initialize(); |
| } |
| window.external.Notify("DOMStorage/" + this._type + "/set/" + key + "/" + value); |
| }, |
| |
| /* |
| The removeItem(key) method must cause the key/value pair with the given key to be removed from the list |
| associated with the object, if it exists. |
| If no item with that key exists, the method must do nothing. |
| */ |
| removeItem:function(key) |
| { |
| if(!this.keys) |
| { |
| this.initialize(); |
| } |
| var index = this.keys.indexOf(key); |
| if(index > -1) |
| { |
| this.keys.splice(index,1); |
| // TODO: need sanity check for keys ? like 'clear','setItem', ... |
| window.external.Notify("DOMStorage/" + this._type + "/remove/" + key); |
| delete this[key]; |
| } |
| |
| }, |
| |
| /* |
| The clear() method must atomically cause the list associated with the object to be emptied of all |
| key/value pairs, if there are any. |
| If there are none, then the method must do nothing. |
| */ |
| clear:function() |
| { |
| if(!this.keys) |
| { |
| this.initialize(); |
| } |
| |
| for(var n=0,len=this.keys.length; n < len;n++) |
| { |
| // TODO: do we need a sanity check for keys ? like 'clear','setItem', ... |
| delete this[this.keys[n]]; |
| } |
| this.keys = []; |
| window.external.Notify("DOMStorage/" + this._type + "/clear/"); |
| } |
| }; |
| |
| // initialize DOMStorage |
| |
| Object.defineProperty( window, "localStorage", |
| { |
| writable: false, |
| configurable: false, |
| value:new DOMStorage("localStorage") |
| }); |
| window.localStorage.initialize(); |
| |
| Object.defineProperty( window, "sessionStorage", |
| { |
| writable: false, |
| configurable: false, |
| value:new DOMStorage("sessionStorage") |
| }); |
| window.sessionStorage.initialize(); |
| |
| |
| })();}; |
| |
| |
| /* |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| if (!PhoneGap.hasResource("file")) { |
| PhoneGap.addResource("file"); |
| |
| /** |
| * Represents a single file. |
| * |
| * @constructor |
| * @param name {DOMString} name of the file, without path information |
| * @param fullPath {DOMString} the full path of the file, including the name |
| * @param type {DOMString} mime type |
| * @param lastModifiedDate {Date} last modified date |
| * @param size {Number} size of the file in bytes |
| */ |
| var File = function(name, fullPath, type, lastModifiedDate, size) { |
| this.name = name || null; |
| this.fullPath = fullPath || null; |
| this.type = type || null; |
| this.lastModifiedDate = lastModifiedDate || null; |
| this.size = size || 0; |
| }; |
| |
| /** @constructor */ |
| var FileError = function() { |
| this.code = null; |
| }; |
| |
| // File error codes |
| // Found in DOMException |
| FileError.NOT_FOUND_ERR = 1; |
| FileError.SECURITY_ERR = 2; |
| FileError.ABORT_ERR = 3; |
| |
| // Added by this specification |
| FileError.NOT_READABLE_ERR = 4; |
| FileError.ENCODING_ERR = 5; |
| FileError.NO_MODIFICATION_ALLOWED_ERR = 6; |
| FileError.INVALID_STATE_ERR = 7; |
| FileError.SYNTAX_ERR = 8; |
| FileError.INVALID_MODIFICATION_ERR = 9; |
| FileError.QUOTA_EXCEEDED_ERR = 10; |
| FileError.TYPE_MISMATCH_ERR = 11; |
| FileError.PATH_EXISTS_ERR = 12; |
| |
| //----------------------------------------------------------------------------- |
| // File manager |
| //----------------------------------------------------------------------------- |
| |
| /** @constructor */ |
| var FileMgr = function() { |
| }; |
| |
| FileMgr.prototype.getFileBasePaths = function() { |
| }; |
| |
| FileMgr.prototype.testFileExists = function(fileName, successCallback, errorCallback) { |
| return PhoneGap.exec(successCallback, errorCallback, "File", "testFileExists", {fileName: fileName}); |
| }; |
| |
| FileMgr.prototype.testDirectoryExists = function(dirName, successCallback, errorCallback) { |
| return PhoneGap.exec(successCallback, errorCallback, "File", "testDirectoryExists", {dirName: dirName}); |
| }; |
| |
| FileMgr.prototype.getFreeDiskSpace = function(successCallback, errorCallback) { |
| return PhoneGap.exec(successCallback, errorCallback, "File", "getFreeDiskSpace"); |
| }; |
| |
| FileMgr.prototype.write = function(fileName, data, position, successCallback, errorCallback) { |
| PhoneGap.exec(successCallback, errorCallback, "File", "write", {fileName: fileName, data: data, position: position}); |
| }; |
| |
| FileMgr.prototype.truncate = function(fileName, size, successCallback, errorCallback) { |
| PhoneGap.exec(successCallback, errorCallback, "File", "truncate", {fileName: fileName, size: size}); |
| }; |
| |
| FileMgr.prototype.readAsText = function(fileName, encoding, successCallback, errorCallback) { |
| PhoneGap.exec(successCallback, errorCallback, "File", "readAsText", {fileName: fileName, encoding: encoding}); |
| }; |
| |
| FileMgr.prototype.readAsDataURL = function(fileName, successCallback, errorCallback) { |
| PhoneGap.exec(successCallback, errorCallback, "File", "readAsDataURL", {fileName: 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" |
| * @constructor |
| */ |
| var FileReader = function() { |
| 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() { |
| var evt; |
| this.readyState = FileReader.DONE; |
| this.result = null; |
| |
| // set error |
| var error = new FileError(); |
| error.code = error.ABORT_ERR; |
| this.error = error; |
| |
| // If error callback |
| if (typeof this.onerror === "function") { |
| this.onerror({"type":"error", "target":this}); |
| } |
| // If abort callback |
| if (typeof this.onabort === "function") { |
| this.onabort({"type":"abort", "target":this}); |
| } |
| // If load end callback |
| if (typeof this.onloadend === "function") { |
| this.onloadend({"type":"loadend", "target":this}); |
| } |
| }; |
| |
| /** |
| * Read text file. |
| * |
| * @param file {File} File object containing file properties |
| * @param encoding [Optional] (see http://www.iana.org/assignments/character-sets) |
| */ |
| FileReader.prototype.readAsText = function(file, encoding) { |
| this.fileName = ""; |
| if (typeof file.fullPath === "undefined") { |
| this.fileName = file; |
| } else { |
| this.fileName = file.fullPath; |
| } |
| |
| // LOADING state |
| this.readyState = FileReader.LOADING; |
| |
| // If loadstart callback |
| if (typeof this.onloadstart === "function") { |
| this.onloadstart({"type":"loadstart", "target":this}); |
| } |
| |
| // Default encoding is UTF-8 |
| var enc = encoding ? encoding : "UTF-8"; |
| |
| var me = this; |
| |
| // Read file |
| navigator.fileMgr.readAsText(this.fileName, enc, |
| |
| // Success callback |
| function(r) { |
| var evt; |
| |
| // If DONE (cancelled), then don't do anything |
| if (me.readyState === FileReader.DONE) { |
| return; |
| } |
| |
| // Save result |
| me.result = r; |
| |
| // If onload callback |
| if (typeof me.onload === "function") { |
| me.onload({"type":"load", "target":me}); |
| } |
| |
| // DONE state |
| me.readyState = FileReader.DONE; |
| |
| // If onloadend callback |
| if (typeof me.onloadend === "function") { |
| me.onloadend({"type":"loadend", "target":me}); |
| } |
| }, |
| |
| // Error callback |
| function(e) { |
| var evt; |
| // If DONE (cancelled), then don't do anything |
| if (me.readyState === FileReader.DONE) { |
| return; |
| } |
| |
| // Save error |
| me.error = e; |
| |
| // If onerror callback |
| if (typeof me.onerror === "function") { |
| me.onerror({"type":"error", "target":me}); |
| } |
| |
| // DONE state |
| me.readyState = FileReader.DONE; |
| |
| // If onloadend callback |
| if (typeof me.onloadend === "function") { |
| me.onloadend({"type":"loadend", "target":me}); |
| } |
| } |
| ); |
| }; |
| |
| |
| /** |
| * Read file and return data as a base64 encoded data url. |
| * A data url is of the form: |
| * data:[<mediatype>][;base64],<data> |
| * |
| * @param file {File} File object containing file properties |
| */ |
| FileReader.prototype.readAsDataURL = function(file) { |
| this.fileName = ""; |
| if (typeof file.fullPath === "undefined") { |
| this.fileName = file; |
| } else { |
| this.fileName = file.fullPath; |
| } |
| |
| // LOADING state |
| this.readyState = FileReader.LOADING; |
| |
| // If loadstart callback |
| if (typeof this.onloadstart === "function") { |
| this.onloadstart({"type":"loadstart", "target":this}); |
| } |
| |
| var me = this; |
| |
| // Read file |
| navigator.fileMgr.readAsDataURL(this.fileName, |
| |
| // Success callback |
| function(r) { |
| var evt; |
| |
| // If DONE (cancelled), then don't do anything |
| if (me.readyState === FileReader.DONE) { |
| return; |
| } |
| |
| // Save result |
| me.result = r; |
| |
| // If onload callback |
| if (typeof me.onload === "function") { |
| me.onload({"type":"load", "target":me}); |
| } |
| |
| // DONE state |
| me.readyState = FileReader.DONE; |
| |
| // If onloadend callback |
| if (typeof me.onloadend === "function") { |
| me.onloadend({"type":"loadend", "target":me}); |
| } |
| }, |
| |
| // Error callback |
| function(e) { |
| var evt; |
| // If DONE (cancelled), then don't do anything |
| if (me.readyState === FileReader.DONE) { |
| return; |
| } |
| |
| // Save error |
| me.error = e; |
| |
| // If onerror callback |
| if (typeof me.onerror === "function") { |
| me.onerror({"type":"error", "target":me}); |
| } |
| |
| // DONE state |
| me.readyState = FileReader.DONE; |
| |
| // If onloadend callback |
| if (typeof me.onloadend === "function") { |
| me.onloadend({"type":"loadend", "target":me}); |
| } |
| } |
| ); |
| }; |
| |
| /** |
| * Read file and return data as a binary data. |
| * |
| * @param file {File} File object containing file properties |
| */ |
| 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 {File} File object containing file properties |
| */ |
| 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" |
| * |
| * @constructor |
| * @param file {File} File object containing file properties |
| * @param append if true write to the end of the file, otherwise overwrite the file |
| */ |
| var FileWriter = function (file) { |
| this.fileName = ""; |
| this.length = 0; |
| if (file) { |
| this.fileName = file.fullPath || file; |
| this.length = file.size || 0; |
| } |
| // default is to write at the beginning of the file |
| this.position = 0; |
| |
| 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() { |
| // check for invalid state |
| if (this.readyState === FileWriter.DONE || this.readyState === FileWriter.INIT) { |
| throw FileError.INVALID_STATE_ERR; |
| } |
| |
| // set error |
| var error = new FileError(), evt; |
| error.code = error.ABORT_ERR; |
| this.error = error; |
| |
| // If error callback |
| if (typeof this.onerror === "function") { |
| this.onerror({"type":"error", "target":this}); |
| } |
| // If abort callback |
| if (typeof this.onabort === "function") { |
| this.onabort({"type":"abort", "target":this}); |
| } |
| |
| this.readyState = FileWriter.DONE; |
| |
| // If write end callback |
| if (typeof this.onwriteend == "function") { |
| this.onwriteend({"type":"writeend", "target":this}); |
| } |
| }; |
| |
| /** |
| * Writes data to the file |
| * |
| * @param text to be written |
| */ |
| FileWriter.prototype.write = function (text) { |
| // Throw an exception if we are already writing a file |
| if (this.readyState === FileWriter.WRITING) { |
| throw FileError.INVALID_STATE_ERR; |
| } |
| |
| // WRITING state |
| this.readyState = FileWriter.WRITING; |
| |
| var me = this; |
| |
| // If onwritestart callback |
| if (typeof me.onwritestart === "function") { |
| me.onwritestart({ "type": "writestart", "target": me }); |
| } |
| |
| // Write file |
| navigator.fileMgr.write(this.fileName, text, this.position, |
| |
| // Success callback |
| function (r) { |
| var evt; |
| // If DONE (cancelled), then don't do anything |
| if (me.readyState === FileWriter.DONE) { |
| return; |
| } |
| |
| // position always increases by bytes written because file would be extended |
| me.position += r; |
| // The length of the file is now where we are done writing. |
| me.length = me.position; |
| |
| // If onwrite callback |
| if (typeof me.onwrite === "function") { |
| me.onwrite({ "type": "write", "target": me }); |
| } |
| |
| // DONE state |
| me.readyState = FileWriter.DONE; |
| |
| // If onwriteend callback |
| if (typeof me.onwriteend === "function") { |
| me.onwriteend({ "type": "writeend", "target": me }); |
| } |
| }, |
| |
| // Error callback |
| function (e) { |
| var evt; |
| |
| // 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") { |
| me.onerror({ "type": "error", "target": me }); |
| } |
| |
| // DONE state |
| me.readyState = FileWriter.DONE; |
| |
| // If onwriteend callback |
| if (typeof me.onwriteend === "function") { |
| me.onwriteend({ "type": "writeend", "target": me }); |
| } |
| } |
| ); |
| |
| }; |
| |
| /** |
| * Moves the file pointer to the location specified. |
| * |
| * If the offset is a negative number the position of the file |
| * pointer is rewound. If the offset is greater than the file |
| * size the position is set to the end of the file. |
| * |
| * @param offset is the location to move the file pointer to. |
| */ |
| FileWriter.prototype.seek = function(offset) { |
| // Throw an exception if we are already writing a file |
| if (this.readyState === FileWriter.WRITING) { |
| throw FileError.INVALID_STATE_ERR; |
| } |
| |
| if (!offset) { |
| return; |
| } |
| |
| // See back from end of file. |
| if (offset < 0) { |
| this.position = Math.max(offset + this.length, 0); |
| } |
| // Offset is bigger then file size so set position |
| // to the end of the file. |
| else if (offset > this.length) { |
| this.position = this.length; |
| } |
| // Offset is between 0 and file size so set the position |
| // to start writing. |
| else { |
| this.position = offset; |
| } |
| }; |
| |
| /** |
| * Truncates the file to the size specified. |
| * |
| * @param size to chop the file at. |
| */ |
| FileWriter.prototype.truncate = function(size) { |
| // Throw an exception if we are already writing a file |
| if (this.readyState === FileWriter.WRITING) { |
| throw FileError.INVALID_STATE_ERR; |
| } |
| |
| // WRITING state |
| this.readyState = FileWriter.WRITING; |
| |
| var me = this; |
| |
| // If onwritestart callback |
| if (typeof me.onwritestart === "function") { |
| me.onwritestart({"type":"writestart", "target":this}); |
| } |
| |
| // Write file |
| navigator.fileMgr.truncate(this.fileName, size, |
| |
| // Success callback |
| function(r) { |
| var evt; |
| // If DONE (cancelled), then don't do anything |
| if (me.readyState === FileWriter.DONE) { |
| return; |
| } |
| |
| // Update the length of the file |
| me.length = r; |
| me.position = Math.min(me.position, r); |
| |
| // If onwrite callback |
| if (typeof me.onwrite === "function") { |
| me.onwrite({"type":"write", "target":me}); |
| } |
| |
| // DONE state |
| me.readyState = FileWriter.DONE; |
| |
| // If onwriteend callback |
| if (typeof me.onwriteend === "function") { |
| me.onwriteend({"type":"writeend", "target":me}); |
| } |
| }, |
| |
| // Error callback |
| function(e) { |
| var evt; |
| // 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") { |
| me.onerror({"type":"error", "target":me}); |
| } |
| |
| // DONE state |
| me.readyState = FileWriter.DONE; |
| |
| // If onwriteend callback |
| if (typeof me.onwriteend === "function") { |
| me.onwriteend({"type":"writeend", "target":me}); |
| } |
| } |
| ); |
| }; |
| |
| /** |
| * Information about the state of the file or directory |
| * |
| * @constructor |
| * {Date} modificationTime (readonly) |
| */ |
| var Metadata = function() { |
| this.modificationTime=null; |
| }; |
| |
| /** |
| * Supplies arguments to methods that lookup or create files and directories |
| * |
| * @constructor |
| * @param {boolean} create file or directory if it doesn't exist |
| * @param {boolean} exclusive if true the command will fail if the file or directory exists |
| */ |
| var Flags = function(create, exclusive) { |
| this.create = create || false; |
| this.exclusive = exclusive || false; |
| }; |
| |
| /** |
| * An interface representing a file system |
| * |
| * @constructor |
| * {DOMString} name the unique name of the file system (readonly) |
| * {DirectoryEntry} root directory of the file system (readonly) |
| */ |
| var FileSystem = function() { |
| this.name = null; |
| this.root = null; |
| }; |
| |
| /** |
| * An interface that lists the files and directories in a directory. |
| * @constructor |
| */ |
| var DirectoryReader = function(fullPath){ |
| this.fullPath = fullPath || null; |
| }; |
| |
| /** |
| * Returns a list of entries from a directory. |
| * |
| * @param {Function} successCallback is called with a list of entries |
| * @param {Function} errorCallback is called with a FileError |
| */ |
| DirectoryReader.prototype.readEntries = function(successCallback, errorCallback) { |
| PhoneGap.exec(successCallback, errorCallback, "File", "readEntries", {fullPath: this.fullPath}); |
| }; |
| |
| /** |
| * An interface representing a directory on the file system. |
| * |
| * @constructor |
| * {boolean} isFile always false (readonly) |
| * {boolean} isDirectory always true (readonly) |
| * {DOMString} name of the directory, excluding the path leading to it (readonly) |
| * {DOMString} fullPath the absolute full path to the directory (readonly) |
| * {FileSystem} filesystem on which the directory resides (readonly) |
| */ |
| var DirectoryEntry = function() { |
| this.isFile = false; |
| this.isDirectory = true; |
| this.name = null; |
| this.fullPath = null; |
| this.filesystem = null; |
| }; |
| |
| /** |
| * Copies a directory to a new location |
| * |
| * @param {DirectoryEntry} parent the directory to which to copy the entry |
| * @param {DOMString} newName the new name of the entry, defaults to the current name |
| * @param {Function} successCallback is called with the new entry |
| * @param {Function} errorCallback is called with a FileError |
| */ |
| DirectoryEntry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) { |
| PhoneGap.exec(successCallback, errorCallback, "File", "copyTo", {fullPath: this.fullPath, parent:parent, newName: newName}); |
| }; |
| |
| /** |
| * Looks up the metadata of the entry |
| * |
| * @param {Function} successCallback is called with a Metadata object |
| * @param {Function} errorCallback is called with a FileError |
| */ |
| DirectoryEntry.prototype.getMetadata = function(successCallback, errorCallback) { |
| PhoneGap.exec(successCallback, errorCallback, "File", "getMetadata", {fullPath: this.fullPath}); |
| }; |
| |
| /** |
| * Gets the parent of the entry |
| * |
| * @param {Function} successCallback is called with a parent entry |
| * @param {Function} errorCallback is called with a FileError |
| */ |
| DirectoryEntry.prototype.getParent = function(successCallback, errorCallback) { |
| PhoneGap.exec(successCallback, errorCallback, "File", "getParent", {fullPath: this.fullPath}); |
| }; |
| |
| /** |
| * Moves a directory to a new location |
| * |
| * @param {DirectoryEntry} parent the directory to which to move the entry |
| * @param {DOMString} newName the new name of the entry, defaults to the current name |
| * @param {Function} successCallback is called with the new entry |
| * @param {Function} errorCallback is called with a FileError |
| */ |
| DirectoryEntry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) { |
| PhoneGap.exec(successCallback, errorCallback, "File", "moveTo", {fullPath: this.fullPath, parent: parent, newName: newName}); |
| }; |
| |
| /** |
| * Removes the entry |
| * |
| * @param {Function} successCallback is called with no parameters |
| * @param {Function} errorCallback is called with a FileError |
| */ |
| DirectoryEntry.prototype.remove = function(successCallback, errorCallback) { |
| PhoneGap.exec(successCallback, errorCallback, "File", "remove", {fullPath: this.fullPath}); |
| }; |
| |
| /** |
| * Returns a URI that can be used to identify this entry. |
| * |
| * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI. |
| * @return uri |
| */ |
| DirectoryEntry.prototype.toURI = function(mimeType) { |
| |
| return encodeURI("file://" + this.fullPath); |
| }; |
| |
| /** |
| * Creates a new DirectoryReader to read entries from this directory |
| */ |
| DirectoryEntry.prototype.createReader = function(successCallback, errorCallback) { |
| return new DirectoryReader(this.fullPath); |
| }; |
| |
| /** |
| * Creates or looks up a directory |
| * |
| * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory |
| * @param {Flags} options to create or excluively create the directory |
| * @param {Function} successCallback is called with the new entry |
| * @param {Function} errorCallback is called with a FileError |
| */ |
| DirectoryEntry.prototype.getDirectory = function (path, options, successCallback, errorCallback) { |
| PhoneGap.exec(successCallback, errorCallback, "File", "getDirectory", { fullPath: this.fullPath, path: path, options: options }); |
| }; |
| |
| /** |
| * Creates or looks up a file |
| * |
| * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file |
| * @param {Flags} options to create or excluively create the file |
| * @param {Function} successCallback is called with the new entry |
| * @param {Function} errorCallback is called with a FileError |
| */ |
| DirectoryEntry.prototype.getFile = function (path, options, successCallback, errorCallback) { |
| PhoneGap.exec(successCallback, errorCallback, "File", "getFile", { fullPath: this.fullPath, path: path, options: options }); |
| }; |
| |
| /** |
| * Deletes a directory and all of it's contents |
| * |
| * @param {Function} successCallback is called with no parameters |
| * @param {Function} errorCallback is called with a FileError |
| */ |
| DirectoryEntry.prototype.removeRecursively = function(successCallback, errorCallback) { |
| PhoneGap.exec(successCallback, errorCallback, "File", "removeRecursively", {fullPath: this.fullPath}); |
| }; |
| |
| /** |
| * An interface representing a directory on the file system. |
| * |
| * @constructor |
| * {boolean} isFile always true (readonly) |
| * {boolean} isDirectory always false (readonly) |
| * {DOMString} name of the file, excluding the path leading to it (readonly) |
| * {DOMString} fullPath the absolute full path to the file (readonly) |
| * {FileSystem} filesystem on which the directory resides (readonly) |
| */ |
| var FileEntry = function() { |
| this.isFile = true; |
| this.isDirectory = false; |
| this.name = null; |
| this.fullPath = null; |
| this.filesystem = null; |
| }; |
| |
| /** |
| * Copies a file to a new location |
| * |
| * @param {DirectoryEntry} parent the directory to which to copy the entry |
| * @param {DOMString} newName the new name of the entry, defaults to the current name |
| * @param {Function} successCallback is called with the new entry |
| * @param {Function} errorCallback is called with a FileError |
| */ |
| FileEntry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) { |
| PhoneGap.exec(successCallback, errorCallback, "File", "copyTo", {fullPath: this.fullPath, parent: parent, newName: newName}); |
| }; |
| |
| /** |
| * Looks up the metadata of the entry |
| * |
| * @param {Function} successCallback is called with a Metadata object |
| * @param {Function} errorCallback is called with a FileError |
| */ |
| FileEntry.prototype.getMetadata = function(successCallback, errorCallback) { |
| PhoneGap.exec(successCallback, errorCallback, "File", "getMetadata", {fullPath: this.fullPath}); |
| }; |
| |
| /** |
| * Gets the parent of the entry |
| * |
| * @param {Function} successCallback is called with a parent entry |
| * @param {Function} errorCallback is called with a FileError |
| */ |
| FileEntry.prototype.getParent = function(successCallback, errorCallback) { |
| PhoneGap.exec(successCallback, errorCallback, "File", "getParent", {fullPath: this.fullPath}); |
| }; |
| |
| /** |
| * Moves a directory to a new location |
| * |
| * @param {DirectoryEntry} parent the directory to which to move the entry |
| * @param {DOMString} newName the new name of the entry, defaults to the current name |
| * @param {Function} successCallback is called with the new entry |
| * @param {Function} errorCallback is called with a FileError |
| */ |
| FileEntry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) { |
| PhoneGap.exec(successCallback, errorCallback, "File", "moveTo", {fullPath: this.fullPath, parent: parent, newName: newName}); |
| }; |
| |
| /** |
| * Removes the entry |
| * |
| * @param {Function} successCallback is called with no parameters |
| * @param {Function} errorCallback is called with a FileError |
| */ |
| FileEntry.prototype.remove = function(successCallback, errorCallback) { |
| PhoneGap.exec(successCallback, errorCallback, "File", "remove", {fullPath: this.fullPath}); |
| }; |
| |
| /** |
| * Returns a URI that can be used to identify this entry. |
| * |
| * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI. |
| * @return uri |
| */ |
| FileEntry.prototype.toURI = function(mimeType) { |
| return encodeURI("file://" + this.fullPath); |
| }; |
| |
| /** |
| * Creates a new FileWriter associated with the file that this FileEntry represents. |
| * |
| * @param {Function} successCallback is called with the new FileWriter |
| * @param {Function} errorCallback is called with a FileError |
| */ |
| FileEntry.prototype.createWriter = function (successCallback, errorCallback) { |
| this.file(function (filePointer) { |
| var writer = new FileWriter(filePointer); |
| |
| if (writer.fileName === null || writer.fileName === "") { |
| if (typeof errorCallback == "function") { |
| errorCallback({ |
| "code": FileError.INVALID_STATE_ERR |
| }); |
| } |
| } |
| |
| if (typeof successCallback == "function") { |
| successCallback(writer); |
| } |
| }, errorCallback); |
| }; |
| |
| /** |
| * Returns a File that represents the current state of the file that this FileEntry represents. |
| * |
| * @param {Function} successCallback is called with the new File object |
| * @param {Function} errorCallback is called with a FileError |
| */ |
| FileEntry.prototype.file = function(successCallback, errorCallback) { |
| PhoneGap.exec(successCallback, errorCallback, "File", "getFileMetadata", {fullPath: this.fullPath}); |
| }; |
| |
| /** @constructor */ |
| var LocalFileSystem = function() { |
| }; |
| |
| // File error codes |
| LocalFileSystem.TEMPORARY = 0; |
| LocalFileSystem.PERSISTENT = 1; |
| LocalFileSystem.RESOURCE = 2; |
| LocalFileSystem.APPLICATION = 3; |
| |
| /** |
| * Requests a filesystem in which to store application data. |
| * |
| * @param {int} type of file system being requested |
| * @param {Function} successCallback is called with the new FileSystem |
| * @param {Function} errorCallback is called with a FileError |
| */ |
| LocalFileSystem.prototype.requestFileSystem = function(type, size, successCallback, errorCallback) { |
| if (type < 0 || type > 3) { |
| if (typeof errorCallback == "function") { |
| errorCallback({ |
| "code": FileError.SYNTAX_ERR |
| }); |
| } |
| } |
| else { |
| PhoneGap.exec(successCallback, errorCallback, "File", "requestFileSystem", {type: type, size: size}); |
| } |
| }; |
| |
| /** |
| * |
| * @param {DOMString} uri referring to a local file in a filesystem |
| * @param {Function} successCallback is called with the new entry |
| * @param {Function} errorCallback is called with a FileError |
| */ |
| LocalFileSystem.prototype.resolveLocalFileSystemURI = function(uri, successCallback, errorCallback) { |
| PhoneGap.exec(successCallback, errorCallback, "File", "resolveLocalFileSystemURI", {uri: uri}); |
| }; |
| |
| /** |
| * This function returns and array of contacts. It is required as we need to convert raw |
| * JSON objects into concrete Contact objects. Currently this method is called after |
| * navigator.service.contacts.find but before the find methods success call back. |
| * |
| * @param a JSON Objects that need to be converted to DirectoryEntry or FileEntry objects. |
| * @returns an entry |
| */ |
| LocalFileSystem.prototype._castFS = function (pluginResult) { |
| var entry = null; |
| entry = new DirectoryEntry(); |
| entry.isDirectory = pluginResult.message.root.isDirectory; |
| entry.isFile = pluginResult.message.root.isFile; |
| entry.name = pluginResult.message.root.name; |
| entry.fullPath = pluginResult.message.root.fullPath; |
| pluginResult.message.root = entry; |
| return pluginResult; |
| }; |
| |
| LocalFileSystem.prototype._castEntry = function(pluginResult) { |
| var entry = null; |
| if (pluginResult.message.isDirectory) { |
| console.log("This is a dir"); |
| entry = new DirectoryEntry(); |
| } |
| else if (pluginResult.message.isFile) { |
| console.log("This is a file"); |
| entry = new FileEntry(); |
| } |
| entry.isDirectory = pluginResult.message.isDirectory; |
| entry.isFile = pluginResult.message.isFile; |
| entry.name = pluginResult.message.name; |
| entry.fullPath = pluginResult.message.fullPath; |
| pluginResult.message = entry; |
| return pluginResult; |
| }; |
| |
| LocalFileSystem.prototype._castEntries = function(pluginResult) { |
| var entries = pluginResult.message; |
| var retVal = []; |
| for (var i=0; i<entries.length; i++) { |
| retVal.push(window.localFileSystem._createEntry(entries[i])); |
| } |
| pluginResult.message = retVal; |
| return pluginResult; |
| }; |
| |
| LocalFileSystem.prototype._createEntry = function(castMe) { |
| var entry = null; |
| if (castMe.isDirectory) { |
| console.log("This is a dir"); |
| entry = new DirectoryEntry(); |
| } |
| else if (castMe.isFile) { |
| console.log("This is a file"); |
| entry = new FileEntry(); |
| } |
| entry.isDirectory = castMe.isDirectory; |
| entry.isFile = castMe.isFile; |
| entry.name = castMe.name; |
| entry.fullPath = castMe.fullPath; |
| return entry; |
| }; |
| |
| LocalFileSystem.prototype._castDate = function (pluginResult) { |
| if (pluginResult.message.modificationTime) { |
| var modTime = new Date(pluginResult.message.modificationTime); |
| pluginResult.message.modificationTime = modTime; |
| } |
| else if (pluginResult.message.lastModifiedDate) { |
| var file = new File(); |
| file.size = pluginResult.message.size; |
| file.type = pluginResult.message.type; |
| file.name = pluginResult.message.name; |
| file.fullPath = pluginResult.message.fullPath; |
| file.lastModifiedDate = new Date(pluginResult.message.lastModifiedDate); |
| pluginResult.message = file; |
| } |
| return pluginResult; |
| }; |
| |
| /** |
| * Add the FileSystem interface into the browser. |
| */ |
| PhoneGap.onPhoneGapInit.subscribeOnce(function () { |
| var pgLocalFileSystem = new LocalFileSystem(); |
| // Needed for cast methods |
| if(typeof window.localFileSystem == "undefined") window.localFileSystem = pgLocalFileSystem; |
| if(typeof window.requestFileSystem == "undefined") window.requestFileSystem = pgLocalFileSystem.requestFileSystem; |
| if(typeof window.resolveLocalFileSystemURI == "undefined") window.resolveLocalFileSystemURI = pgLocalFileSystem.resolveLocalFileSystemURI; |
| }); |
| } |
| |
| /* |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| if (!PhoneGap.hasResource("filetransfer")) { |
| PhoneGap.addResource("filetransfer"); |
| |
| /** |
| * FileTransfer uploads a file to a remote server. |
| * @constructor |
| */ |
| var FileTransfer = function() {}; |
| |
| /** |
| * FileUploadResult |
| * @constructor |
| */ |
| var FileUploadResult = function() { |
| this.bytesSent = 0; |
| this.responseCode = null; |
| this.response = null; |
| }; |
| |
| /** |
| * FileTransferError |
| * @constructor |
| */ |
| var FileTransferError = function() { |
| this.code = null; |
| }; |
| |
| FileTransferError.FILE_NOT_FOUND_ERR = 1; |
| FileTransferError.INVALID_URL_ERR = 2; |
| FileTransferError.CONNECTION_ERR = 3; |
| |
| /** |
| * Given an absolute file path, uploads a file on the device to a remote server |
| * using a multipart HTTP request. |
| * @param filePath {String} Full path of the file on the device |
| * @param server {String} URL of the server to receive the file |
| * @param successCallback (Function} Callback to be invoked when upload has completed |
| * @param errorCallback {Function} Callback to be invoked upon error |
| * @param options {FileUploadOptions} Optional parameters such as file name and mimetype |
| */ |
| FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, debug) { |
| |
| // check for options |
| var params = null; |
| if (options) { |
| if (options.params) { |
| var dict=new Array(); |
| var idx = 0; |
| |
| for (var key in options.params) { |
| if (options.params.hasOwnProperty(key)) { |
| var value = options.params[key]; |
| var item = new Object(); |
| item.Key = key; |
| item.Value = value; |
| dict[idx] = item; |
| idx++; |
| } |
| } |
| |
| options.params = dict; |
| } |
| } else { |
| options = new FileUploadOptions(); |
| } |
| |
| options.filePath = filePath; |
| options.server = server; |
| |
| PhoneGap.exec(successCallback, errorCallback, 'FileTransfer', 'upload', options); |
| }; |
| |
| /** |
| * Options to customize the HTTP request used to upload files. |
| * @constructor |
| * @param fileKey {String} Name of file request parameter. |
| * @param fileName {String} Filename to be used by the server. Defaults to image.jpg. |
| * @param mimeType {String} Mimetype of the uploaded file. Defaults to image/jpeg. |
| * @param params {Object} Object with key: value params to send to the server. |
| */ |
| var FileUploadOptions = function(fileKey, fileName, mimeType, params) { |
| this.fileKey = fileKey || null; |
| this.fileName = fileName || null; |
| this.mimeType = mimeType || null; |
| this.params = params || null; |
| }; |
| } |
| |
| /* |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| if (!PhoneGap.hasResource("media")) { |
| PhoneGap.addResource("media"); |
| |
| /** |
| * This class provides access to the device media, interfaces to both sound and video |
| * |
| * @constructor |
| * @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 |
| */ |
| var 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_POSITION = 3; |
| 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 |
| */ |
| var MediaError = function() { |
| this.code = null; |
| this.message = ""; |
| }; |
| |
| MediaError.MEDIA_ERR_PLAY_MODE_SET = 1; |
| MediaError.MEDIA_ERR_ALREADY_RECORDING = 2; |
| MediaError.MEDIA_ERR_STARTING_RECORDING = 3; |
| MediaError.MEDIA_ERR_RECORD_MODE_SET = 4; |
| MediaError.MEDIA_ERR_STARTING_PLAYBACK = 5; |
| MediaError.MEDIA_ERR_RESUME_STATE = 6; |
| MediaError.MEDIA_ERR_PAUSE_STATE = 7; |
| MediaError.MEDIA_ERR_STOP_STATE = 8; |
| |
| /** |
| * Start or resume playing audio file. |
| */ |
| Media.prototype.play = function() { |
| PhoneGap.exec(null, null, "Media", "startPlayingAudio", {id: this.id, src: this.src}); |
| }; |
| |
| /** |
| * Stop playing audio file. |
| */ |
| Media.prototype.stop = function() { |
| return PhoneGap.exec(null, null, "Media", "stopPlayingAudio", {id: this.id}); |
| }; |
| |
| /** |
| * Seek or jump to a new time in the track.. |
| */ |
| Media.prototype.seekTo = function(milliseconds) { |
| PhoneGap.exec(null, null, "Media", "seekToAudio", {id: this.id, milliseconds: milliseconds}); |
| }; |
| |
| /** |
| * Pause playing audio file. |
| */ |
| Media.prototype.pause = function() { |
| PhoneGap.exec(null, null, "Media", "pausePlayingAudio", {id: 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. |
| */ |
| Media.prototype.getCurrentPosition = function(success, fail) { |
| PhoneGap.exec(success, fail, "Media", "getCurrentPositionAudio", {id: this.id}); |
| }; |
| |
| /** |
| * Start recording audio file. |
| */ |
| Media.prototype.startRecord = function() { |
| PhoneGap.exec(null, null, "Media", "startRecordingAudio", {id: this.id, src: this.src}); |
| }; |
| |
| /** |
| * Stop recording audio file. |
| */ |
| Media.prototype.stopRecord = function() { |
| PhoneGap.exec(null, null, "Media", "stopRecordingAudio", {id: this.id}); |
| }; |
| |
| /** |
| * Release the resources. |
| */ |
| Media.prototype.release = function() { |
| PhoneGap.exec(null, null, "Media", "release", {id: this.id}); |
| }; |
| |
| /** |
| * List of media objects. |
| * PRIVATE |
| */ |
| PhoneGap.mediaObjects = {}; |
| |
| /** |
| * Object that receives native callbacks. |
| * PRIVATE |
| * @constructor |
| */ |
| 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); |
| } |
| } |
| else if (msg == Media.MEDIA_POSITION) { |
| media._position = value; |
| } |
| }; |
| |
| // We need special proxy to invoke PhoneGap.Media.onStatus (method is not visible in other case) |
| // http://stackoverflow.com/questions/7322420/calling-javascript-object-method-using-webbrowser-document-invokescript |
| PhoneGapMediaonStatus = function (args) { |
| var res = JSON.parse(args); |
| PhoneGap.Media.onStatus(res.id, res.msg, res.value); |
| } |
| |
| } |
| |
| /* |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| if (!PhoneGap.hasResource("network")) { |
| PhoneGap.addResource("network"); |
| |
| /** |
| * This class contains information about the current network Connection. |
| * @constructor |
| */ |
| var Connection = function() |
| { |
| this.type = null; |
| this._firstRun = true; |
| this._timer = null; |
| this.timeout = 500; |
| |
| var me = this; |
| this.getInfo( |
| function(type) { |
| //console.log("getInfo result" + type); |
| // Need to send events if we are on or offline |
| if (type == "none") { |
| // set a timer if still offline at the end of timer send the offline event |
| me._timer = setTimeout(function(){ |
| me.type = type; |
| //console.log("PhoneGap.fireEvent::offline"); |
| PhoneGap.fireEvent(document,'offline'); |
| me._timer = null; |
| }, me.timeout); |
| } else { |
| // If there is a current offline event pending clear it |
| if (me._timer != null) { |
| clearTimeout(me._timer); |
| me._timer = null; |
| } |
| me.type = type; |
| //console.log("PhoneGap.fireEvent::online " + me.type); |
| PhoneGap.fireEvent(document,'online'); |
| } |
| |
| // should only fire this once |
| if (me._firstRun) |
| { |
| me._firstRun = false; |
| //console.log("onPhoneGapConnectionReady"); |
| PhoneGap.onPhoneGapConnectionReady.fire(); |
| } |
| }, |
| function(e) { |
| console.log("Error initializing Network Connection: " + e); |
| }); |
| }; |
| |
| Connection.UNKNOWN = "unknown"; |
| Connection.ETHERNET = "ethernet"; |
| Connection.WIFI = "wifi"; |
| Connection.CELL_2G = "2g"; |
| Connection.CELL_3G = "3g"; |
| Connection.CELL_4G = "4g"; |
| Connection.NONE = "none"; |
| Connection.CELL = "cellular"; |
| |
| /** |
| * Get connection info |
| * |
| * @param {Function} successCallback The function to call when the Connection data is available |
| * @param {Function} errorCallback The function to call when there is an error getting the Connection data. (OPTIONAL) |
| */ |
| Connection.prototype.getInfo = function(successCallback, errorCallback) { |
| // Get info |
| PhoneGap.exec(successCallback, errorCallback, "Connection", "getConnectionInfo", []); |
| }; |
| |
| |
| PhoneGap.onPhoneGapInit.subscribeOnce(function() { |
| |
| navigator.network = navigator.network || {}; |
| if (typeof navigator.network.connection === "undefined") { |
| navigator.network.connection = new Connection(); |
| } |
| }); |
| } |
| |
| /* |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| if (!PhoneGap.hasResource("notification")) { |
| PhoneGap.addResource("notification"); |
| |
| /** |
| * This class provides access to notifications on the device. |
| * @constructor |
| */ |
| var Notification = function() { |
| }; |
| |
| /** |
| * 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 _buttonLabels = (buttonLabel || "OK"); |
| PhoneGap.exec(completeCallback, null, "Notification", "alert",{"message":message,"title":_title,"buttonLabels":_buttonLabels}); |
| }; |
| |
| /** |
| * 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':message,"title":_title,"buttonLabels":_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", {duration:mills}); |
| }; |
| |
| /** |
| * Causes the device to beep. |
| * A packaged resource is played "repeatCount" times. |
| * |
| * @param {Integer} repeatCount The number of beeps. default 1 |
| */ |
| Notification.prototype.beep = function(repeatCount) |
| { |
| var count = repeatCount|| 1; |
| PhoneGap.exec(null, null, "Notification", "beep", count); |
| }; |
| |
| PhoneGap.onPhoneGapInit.subscribeOnce(function() { |
| if (typeof navigator.notification === "undefined") { |
| navigator.notification = new Notification(); |
| } |
| }); |
| } |
| |
| /* |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| /** |
| * @author purplecabbage |
| */ |
| |
| (function(win,doc){ |
| |
| |
| doc.addEventListener("DOMContentLoaded",function() |
| { |
| var docDomain = null; |
| try |
| { |
| docDomain = doc.domain; |
| } |
| catch(err) |
| { |
| //console.log("caught exception trying to access document.domain"); |
| } |
| |
| if(!docDomain || docDomain.length == 0) |
| { |
| //console.log("adding our own Local XHR shim "); |
| var aliasXHR = win.XMLHttpRequest; |
| |
| win.XMLHttpRequest = function(){}; |
| |
| win.XMLHttpRequest.UNSENT = 0; |
| win.XMLHttpRequest.OPENED = 1; |
| win.XMLHttpRequest.HEADERS_RECEIVED = 2; |
| win.XMLHttpRequest.LOADING = 3; |
| win.XMLHttpRequest.DONE = 4; |
| |
| win.XMLHttpRequest.prototype = |
| { |
| UNSENT:0, |
| OPENED:1, |
| HEADERS_RECEIVED:2, |
| LOADING:3, |
| DONE:4, |
| |
| isAsync:false, |
| onreadystatechange:null, |
| readyState:0, |
| _url:"", |
| open:function(reqType,uri,isAsync,user,password) |
| { |
| console.log("XMLHttpRequest.open " + uri); |
| if(uri && uri.indexOf("http") == 0) |
| { |
| if(!this.wrappedXHR) |
| { |
| this.wrappedXHR = new aliasXHR(); |
| var self = this; |
| |
| Object.defineProperty( this, "status", { get: function() { |
| return this.wrappedXHR.status; |
| }}); |
| Object.defineProperty( this, "responseText", { get: function() { |
| return this.wrappedXHR.responseText; |
| }}); |
| Object.defineProperty( this, "statusText", { get: function() { |
| return this.wrappedXHR.statusText; |
| }}); |
| |
| Object.defineProperty( this, "responseXML", { get: function() { |
| return this.wrappedXHR.responseXML; |
| }}); |
| |
| this.getResponseHeader = function(header) { |
| return this.wrappedXHR.getResponseHeader(header); |
| }; |
| this.getAllResponseHeaders = function() { |
| return this.wrappedXHR.getAllResponseHeaders(); |
| }; |
| |
| this.wrappedXHR.onreadystatechange = function() |
| { |
| self.changeReadyState(self.wrappedXHR.readyState); |
| }; |
| } |
| return this.wrappedXHR.open(reqType,uri,isAsync,user,password); |
| } |
| else |
| { |
| // x-wmapp1://app/www/page2.html |
| // need to work some magic on the actual url/filepath |
| var newUrl = uri; |
| if(newUrl.indexOf(":/") > -1) |
| { |
| newUrl = newUrl.split(":/")[1]; |
| } |
| |
| if(newUrl.lastIndexOf("/") === newUrl.length - 1) |
| { |
| newUrl += "index.html"; // default page is index.html, when call is to a dir/ ( why not ...? ) |
| } |
| this._url = newUrl; |
| } |
| }, |
| statusText:"", |
| changeReadyState:function(newState) |
| { |
| this.readyState = newState; |
| if(this.onreadystatechange) |
| { |
| this.onreadystatechange(); |
| } |
| }, |
| getResponseHeader:function(header) |
| { |
| return this.wrappedXHR ? this.wrappedXHR.getResponseHeader(header) : ""; |
| }, |
| getAllResponseHeaders:function() |
| { |
| return this.wrappedXHR ? this.wrappedXHR.getAllResponseHeaders() : ""; |
| }, |
| responseText:"", |
| responseXML:"", |
| onResult:function(res) |
| { |
| this.status = 200; |
| this.responseText = res; |
| |
| Object.defineProperty( this, "responseXML", { get: function() { |
| var parser = new DOMParser(); |
| return parser.parseFromString(this.responseText,"text/xml"); |
| }}); |
| this.changeReadyState(this.DONE); |
| }, |
| onError:function(err) |
| { |
| console.log("Wrapped XHR received Error from FileAPI :: " + err); |
| this.status = 404; |
| this.changeReadyState(this.DONE); |
| }, |
| |
| abort:function() |
| { |
| if(this.wrappedXHR) |
| { |
| return this.wrappedXHR.abort(); |
| } |
| }, |
| |
| send:function(data) |
| { |
| if(this.wrappedXHR) |
| { |
| return this.wrappedXHR.send(data); |
| } |
| else |
| { |
| this.changeReadyState(this.OPENED); |
| navigator.fileMgr.readAsText(this._url,"UTF-8",this.onResult.bind(this),this.onError.bind(this)); |
| } |
| }, |
| status:404 |
| }; |
| } // if doc domain |
| |
| },false);// addEventListener |
| |
| |
| })(window,document); |
| |