Return-Path: X-Original-To: apmail-incubator-callback-commits-archive@minotaur.apache.org Delivered-To: apmail-incubator-callback-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id B7FB39C08 for ; Thu, 23 Feb 2012 22:30:17 +0000 (UTC) Received: (qmail 62818 invoked by uid 500); 23 Feb 2012 22:30:17 -0000 Delivered-To: apmail-incubator-callback-commits-archive@incubator.apache.org Received: (qmail 62801 invoked by uid 500); 23 Feb 2012 22:30:17 -0000 Mailing-List: contact callback-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: callback-dev@incubator.apache.org Delivered-To: mailing list callback-commits@incubator.apache.org Received: (qmail 62794 invoked by uid 99); 23 Feb 2012 22:30:17 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 23 Feb 2012 22:30:17 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.114] (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 23 Feb 2012 22:30:13 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 10AD68128C0; Thu, 23 Feb 2012 22:29:31 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: purplecabbage@apache.org To: callback-commits@incubator.apache.org X-Mailer: ASF-Git Admin Mailer Subject: [11/50] [abbrv] update 1.4.1 references to 1.5.0 Message-Id: <20120223222931.10AD68128C0@tyr.zones.apache.org> Date: Thu, 23 Feb 2012 22:29:31 +0000 (UTC) http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/a9056cc7/example/www/cordova-1.5.0.js ---------------------------------------------------------------------- diff --git a/example/www/cordova-1.5.0.js b/example/www/cordova-1.5.0.js new file mode 100644 index 0000000..b3d8e37 --- /dev/null +++ b/example/www/cordova-1.5.0.js @@ -0,0 +1,3832 @@ +/* + This is a machine generated file, do not edit directly. -jm +*/ + + + + +/** + * The order of events during page load and Cordova 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 Cordova native side is ready. + * onCordovaInit Internal event that kicks off creation of all Cordova JavaScript objects (runs constructors). + * onCordovaReady Internal event fired when all Cordova JavaScript objects have been created + * onCordovaInfoReady Internal event fired when device properties are available + * onDeviceReady User event fired to indicate that Cordova 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 Cordova 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 Cordova = { + queue: { + ready: true, + commands: [], + timer: null + }, + available:false, + callbackId:0, + callbacks:{}, + resources:{} +}; + +Cordova.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 Cordova + * + * @param name + * @return + */ +Cordova.hasResource = function(name) { + return Cordova.resources[name]; +}; + +/** + * Add a resource to list of loaded resources by Cordova + * + * @param name + */ +Cordova.addResource = function(name) { + Cordova.resources[name] = true; +}; + +Cordova.exec = function(success, fail, service, action, args) +{ + + var callbackId = service + Cordova.callbackId++; + if (typeof success == "function" || typeof fail == "function") + { + Cordova.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); +}; + +CordovaCommandResult = function(status,callbackId,args,cast) +{ + if(status === "backbutton") { + + Cordova.fireEvent(document,"backbutton"); + return "true"; + + } else if(status === "resume") { + + Cordova.onResume.fire(); + return "true"; + + } else if(status === "pause") { + + Cordova.onPause.fire(); + return "true"; + } + + var safeStatus = parseInt(status); + if(safeStatus === Cordova.callbackStatus.NO_RESULT || + safeStatus === Cordova.callbackStatus.OK) { + Cordova.CallbackSuccess(callbackId,args,cast); + } + else + { + Cordova.CallbackError(callbackId,args,cast); + } +}; + +/** + * Called by native code when returning successful result from an action. + * + * @param callbackId + * @param args + * @param cast + */ +Cordova.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 (Cordova.callbacks[callbackId] ) { + + // If result is to be sent to callback + if (commandResult.status === Cordova.callbackStatus.OK) { + try { + if (Cordova.callbacks[callbackId].success) { + result = Cordova.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 Cordova.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 + */ +Cordova.CallbackError = function (callbackId, args, cast) { + + var commandResult; + try + { + commandResult = JSON.parse(args); + } + catch(exception) + { + return exception.message; + } + + if (Cordova.callbacks[callbackId]) { + try { + if (Cordova.callbacks[callbackId].fail) { + Cordova.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 Cordova.callbacks[callbackId]; + } + } +}; + +/** + * Create a UUID + * + * @return {String} + */ +Cordova.createUUID = function() { + return Cordova.UUIDcreatePart(4) + '-' + + Cordova.UUIDcreatePart(2) + '-' + + Cordova.UUIDcreatePart(2) + '-' + + Cordova.UUIDcreatePart(2) + '-' + + Cordova.UUIDcreatePart(6); +}; + +Cordova.UUIDcreatePart = function(length) { + var uuidpart = ""; + var i, uuidchar; + for (i=0; i + * + * @param name The plugin name + * @param obj The plugin object + */ +Cordova.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. + */ +Cordova.onDOMContentLoaded = new Cordova.Channel('onDOMContentLoaded'); + +/** + * onNativeReady channel is fired when the Cordova native code + * has been initialized. + */ +Cordova.onNativeReady = new Cordova.Channel('onNativeReady'); + +/** + * onCordovaInit channel is fired when the web page is fully loaded and + * Cordova native code has been initialized. + */ +Cordova.onCordovaInit = new Cordova.Channel('onCordovaInit'); + +/** + * onCordovaReady channel is fired when the JS Cordova objects have been created. + */ +Cordova.onCordovaReady = new Cordova.Channel('onCordovaReady'); + +/** + * onCordovaInfoReady channel is fired when the Cordova device properties + * has been set. + */ +Cordova.onCordovaInfoReady = new Cordova.Channel('onCordovaInfoReady'); + +/** + * onCordovaConnectionReady channel is fired when the Cordova connection properties + * has been set. + */ +Cordova.onCordovaConnectionReady = new Cordova.Channel('onCordovaConnectionReady'); + +/** + * onResume channel is fired when the Cordova native code + * resumes. + */ +Cordova.onResume = new Cordova.Channel('onResume'); + +/** + * onPause channel is fired when the Cordova native code + * pauses. + */ +Cordova.onPause = new Cordova.Channel('onPause'); + +/** + * onDestroy channel is fired when the Cordova native code + * is destroyed. It is used internally. + * Window.onunload should be used by the user. + */ +Cordova.onDestroy = new Cordova.Channel('onDestroy'); +Cordova.onDestroy.subscribeOnce(function() { + Cordova.shuttingDown = true; +}); +Cordova.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 Cordova JS is ready. +if (typeof _nativeReady !== 'undefined') { Cordova.onNativeReady.fire(); } + +/** + * onDeviceReady is fired only after all Cordova objects are created and + * the device properties are set. + */ +Cordova.onDeviceReady = new Cordova.Channel('onDeviceReady'); + + +// Array of channels that must fire before "deviceready" is fired +Cordova.deviceReadyChannelsArray = [ Cordova.onCordovaReady, Cordova.onCordovaInfoReady, Cordova.onCordovaConnectionReady]; + +// Hashtable of user defined channels that must also fire before "deviceready" is fired +Cordova.deviceReadyChannelsMap = {}; + +/** + * Indicate that a feature needs to be initialized before it is ready to be used. + * This holds up Cordova's "deviceready" event until the feature has been initialized + * and Cordova.initComplete(feature) is called. + * + * @param feature {String} The unique feature name + */ +Cordova.waitForInitialization = function(feature) { + if (feature) { + var channel = new Cordova.Channel(feature); + Cordova.deviceReadyChannelsMap[feature] = channel; + Cordova.deviceReadyChannelsArray.push(channel); + } +}; + +/** + * Indicate that initialization code has completed and the feature is ready to be used. + * + * @param feature {String} The unique feature name + */ +Cordova.initializationComplete = function(feature) { + var channel = Cordova.deviceReadyChannelsMap[feature]; + if (channel) { + channel.fire(); + } +}; + +/** + * Create all Cordova objects once page has fully loaded and native side is ready. + */ +Cordova.Channel.join( + function() + { + + setTimeout(function() + { + + Cordova.UsePolling = false; + //Cordova.JSCallback(); + },1); + + // Run Cordova constructors + Cordova.onCordovaInit.fire(); + + // Fire event to notify that all objects are created + Cordova.onCordovaReady.fire(); + + // Fire onDeviceReady event once all constructors have run and Cordova info has been + // received from native side, and any user defined initialization channels. + Cordova.Channel.join(function() { + Cordova.onDeviceReady.fire(); + + // Fire the onresume event, since first one happens before JavaScript is loaded + Cordova.onResume.fire(); + }, Cordova.deviceReadyChannelsArray); + + }, + [ Cordova.onDOMContentLoaded ]); + + + +// Listen for DOMContentLoaded and notify our channel subscribers +document.addEventListener('DOMContentLoaded', function() { + Cordova.onDOMContentLoaded.fire(); +}, false); + +Cordova.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') + { + Cordova.onDeviceReady.subscribeOnce(handler); + } + else if (e === 'resume') + { + Cordova.onResume.subscribe(handler); + if (Cordova.onDeviceReady.fired) + { + Cordova.onResume.fire(); + } + } + else if (e === 'pause') + { + Cordova.onPause.subscribe(handler); + } + else + { + + if (e === 'backbutton') + { + Cordova.exec(null, null, "CoreEvents", "overrideBackbutton", [true]); + } + Cordova.m_document_addEventListener.call(document, evt, handler, capture); + } +}; + +Cordova.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') + { + Cordova.exec(null, null, "CoreEvents", "overrideBackbutton", [false]); + } + Cordova.m_document_removeEventListener.call(document, evt, handler, capture); + +} + + +Cordova.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 (!Cordova.hasResource("accelerometer")) +{ +Cordova.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 + Cordova.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 = Cordova.createUUID(); + + var params = new Object(); + params.id = id; + // Default interval (10 sec) + params.frequency = (options && options.frequency) ? options.frequency : 10000; + + Cordova.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) { + + Cordova.exec(null, null, "Accelerometer", "stopWatch", { id: id }); +}; + +Cordova.onCordovaInit.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 (!Cordova.hasResource("camera")) { +Cordova.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(); +// } +// } + + Cordova.exec(successCallback, errorCallback, "Camera", "getPicture", this.options); +}; + +Cordova.onCordovaInit.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 (!Cordova.hasResource("capture")) { +Cordova.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){ + Cordova.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){ + Cordova.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){ + Cordova.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) { + Cordova.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){ + Cordova.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; +}; +Cordova.onCordovaInit.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 (!Cordova.hasResource("compass")) { +Cordova.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(res) + { + var err = JSON.parse(res); + if(err.code == CompassError.COMPASS_NOT_SUPPORTED) + { + self.isCompassSupported = false; + } + errorCallback(err); + } + + // Get heading + Cordova.exec(onSuccess, onError, "Compass", "getHeading", []); + } + else + { + var funk = function() + { + errorCallback({code: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 (res) { + var err = JSON.parse(res); + if(err.code == CompassError.COMPASS_NOT_SUPPORTED) + { + self.isCompassSupported = false; + } + + errorCallback(err); + } + + var id = Cordova.createUUID(); + + var params = {id:id,frequency:((options && options.frequency) ? options.frequency : 100)}; + + Cordova.exec(onSuccess, onError, "Compass", "startWatch", params); + + return id; + } + else + { + var funk = function() + { + errorCallback({code: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) { + + Cordova.exec(null, null, "Compass", "stopWatch", { id: id }); + +}; + +Cordova.onCordovaInit.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 (!Cordova.hasResource("contact")) { +Cordova.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.} phoneNumbers array of phone numbers +* @param {Array.} emails array of email addresses +* @param {Array.} addresses array of addresses +* @param {Array.} ims instant messaging user ids +* @param {Array.} organizations +* @param {DOMString} birthday contact's birthday +* @param {DOMString} note user notes about contact +* @param {Array.} photos +* @param {Array.} categories +* @param {Array.} 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 + { + Cordova.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 = Cordova.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= 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 (!Cordova.hasResource("file")) { +Cordova.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 Cordova.exec(successCallback, errorCallback, "File", "testFileExists", {fileName: fileName}); +}; + +FileMgr.prototype.testDirectoryExists = function(dirName, successCallback, errorCallback) { + return Cordova.exec(successCallback, errorCallback, "File", "testDirectoryExists", {dirName: dirName}); +}; + +FileMgr.prototype.getFreeDiskSpace = function(successCallback, errorCallback) { + return Cordova.exec(successCallback, errorCallback, "File", "getFreeDiskSpace"); +}; + +FileMgr.prototype.write = function(fileName, data, position, successCallback, errorCallback) { + Cordova.exec(successCallback, errorCallback, "File", "write", {fileName: fileName, data: data, position: position}); +}; + +FileMgr.prototype.truncate = function(fileName, size, successCallback, errorCallback) { + Cordova.exec(successCallback, errorCallback, "File", "truncate", {fileName: fileName, size: size}); +}; + +FileMgr.prototype.readAsText = function(fileName, encoding, successCallback, errorCallback) { + Cordova.exec(successCallback, errorCallback, "File", "readAsText", {fileName: fileName, encoding: encoding}); +}; + +FileMgr.prototype.readAsDataURL = function(fileName, successCallback, errorCallback) { + Cordova.exec(successCallback, errorCallback, "File", "readAsDataURL", {fileName: fileName}); +}; + +Cordova.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:[][;base64], + * + * @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) { + Cordova.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) { + Cordova.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) { + Cordova.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) { + Cordova.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) { + Cordova.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) { + Cordova.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) { + Cordova.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) { + Cordova.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) { + Cordova.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) { + Cordova.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) { + Cordova.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) { + Cordova.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) { + Cordova.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) { + Cordova.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) { + Cordova.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 + */ +Local