/* Cordova v1.5.0 */ /* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you 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. */ /* * Some base contributions * Copyright (c) 2011, Proyectos Equis Ka, S.L. */ if (typeof Cordova === "undefined") { if (typeof(DeviceInfo) !== 'object'){ DeviceInfo = {}; } /** * This represents the Cordova API itself, and provides a global namespace for accessing * information about the state of Cordova. * @class */ Cordova = { // This queue holds the currently executing command and all pending // commands executed with Cordova.exec(). commandQueue: [], // Indicates if we're currently in the middle of flushing the command // queue on the native side. commandQueueFlushing: false, _constructors: [], documentEventHandler: {}, // Collection of custom document event handlers windowEventHandler: {} }; /** * List of resource files loaded by Cordova. * This is used to ensure JS and other files are loaded only once. */ Cordova.resources = {base: true}; /** * 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; }; /** * Boolean flag indicating if the Cordova API is available and initialized. */ // TODO: Remove this, it is unused here ... -jm Cordova.available = DeviceInfo.uuid != undefined; /** * Add an initialization function to a queue that ensures it will run and initialize * application constructors only once Cordova has been initialized. * @param {Function} func The function callback you want run once Cordova is initialized */ Cordova.addConstructor = function(func) { var state = document.readyState; if ( ( state == 'loaded' || state == 'complete' ) && DeviceInfo.uuid != null ) { func(); } else { Cordova._constructors.push(func); } }; (function() { var timer = setInterval(function() { var state = document.readyState; if ( ( state == 'loaded' || state == 'complete' ) && DeviceInfo.uuid != null ) { clearInterval(timer); // stop looking // run our constructors list while (Cordova._constructors.length > 0) { var constructor = Cordova._constructors.shift(); try { constructor(); } catch(e) { if (typeof(console['log']) == 'function') { console.log("Failed to run constructor: " + console.processMessage(e)); } else { alert("Failed to run constructor: " + e.message); } } } // all constructors run, now fire the deviceready event var e = document.createEvent('Events'); e.initEvent('deviceready'); document.dispatchEvent(e); } }, 1); })(); // session id for calls Cordova.sessionKey = 0; // centralized callbacks Cordova.callbackId = 0; Cordova.callbacks = {}; 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 }; /** * Creates a gap bridge iframe used to notify the native code about queued * commands. * * @private */ Cordova.createGapBridge = function() { gapBridge = document.createElement("iframe"); gapBridge.setAttribute("style", "display:none;"); gapBridge.setAttribute("height","0px"); gapBridge.setAttribute("width","0px"); gapBridge.setAttribute("frameborder","0"); document.documentElement.appendChild(gapBridge); return gapBridge; } /** * Execute a Cordova command by queuing it and letting the native side know * there are queued commands. The native side will then request all of the * queued commands and execute them. * * Arguments may be in one of two formats: * * FORMAT ONE (preferable) * The native side will call Cordova.callbackSuccess or * Cordova.callbackError, depending upon the result of the action. * * @param {Function} success The success callback * @param {Function} fail The fail callback * @param {String} service The name of the service to use * @param {String} action The name of the action to use * @param {String[]} [args] Zero or more arguments to pass to the method * * FORMAT TWO * @param {String} command Command to be run in Cordova, e.g. * "ClassName.method" * @param {String[]} [args] Zero or more arguments to pass to the method * object parameters are passed as an array object * [object1, object2] each object will be passed as * JSON strings */ Cordova.exec = function() { if (!Cordova.available) { alert("ERROR: Attempting to call Cordova.exec()" +" before 'deviceready'. Ignoring."); return; } var successCallback, failCallback, service, action, actionArgs; var callbackId = null; if (typeof arguments[0] !== "string") { // FORMAT ONE successCallback = arguments[0]; failCallback = arguments[1]; service = arguments[2]; action = arguments[3]; actionArgs = arguments[4]; // Since we need to maintain backwards compatibility, we have to pass // an invalid callbackId even if no callback was provided since plugins // will be expecting it. The Cordova.exec() implementation allocates // an invalid callbackId and passes it even if no callbacks were given. callbackId = 'INVALID'; } else { // FORMAT TWO splitCommand = arguments[0].split("."); action = splitCommand.pop(); service = splitCommand.join("."); actionArgs = Array.prototype.splice.call(arguments, 1); } // Start building the command object. var command = { className: service, methodName: action, arguments: [] }; // Register the callbacks and add the callbackId to the positional // arguments if given. if (successCallback || failCallback) { callbackId = service + Cordova.callbackId++; Cordova.callbacks[callbackId] = {success:successCallback, fail:failCallback}; } if (callbackId != null) { command.arguments.push(callbackId); } for (var i = 0; i < actionArgs.length; ++i) { var arg = actionArgs[i]; if (arg == undefined || arg == null) { continue; } else if (typeof(arg) == 'object') { command.options = arg; } else { command.arguments.push(arg); } } // Stringify and queue the command. We stringify to command now to // effectively clone the command arguments in case they are mutated before // the command is executed. Cordova.commandQueue.push(JSON.stringify(command)); // If the queue length is 1, then that means it was empty before we queued // the given command, so let the native side know that we have some // commands to execute, unless the queue is currently being flushed, in // which case the command will be picked up without notification. if (Cordova.commandQueue.length == 1 && !Cordova.commandQueueFlushing) { if (!Cordova.gapBridge) { Cordova.gapBridge = Cordova.createGapBridge(); } Cordova.gapBridge.src = "gap://ready"; } } /** * Called by native code to retrieve all queued commands and clear the queue. */ Cordova.getAndClearQueuedCommands = function() { json = JSON.stringify(Cordova.commandQueue); Cordova.commandQueue = []; return json; } /** * Called by native code when returning successful result from an action. * * @param callbackId * @param args * args.status - Cordova.callbackStatus * args.message - return value * args.keepCallback - 0 to remove callback, 1 to keep callback in Cordova.callbacks[] */ Cordova.callbackSuccess = function(callbackId, args) { if (Cordova.callbacks[callbackId]) { // If result is to be sent to callback if (args.status == Cordova.callbackStatus.OK) { try { if (Cordova.callbacks[callbackId].success) { Cordova.callbacks[callbackId].success(args.message); } } catch (e) { console.log("Error in success callback: "+callbackId+" = "+e); } } // Clear callback if not expecting any more results if (!args.keepCallback) { delete Cordova.callbacks[callbackId]; } } }; /** * Called by native code when returning error result from an action. * * @param callbackId * @param args */ Cordova.callbackError = function(callbackId, args) { if (Cordova.callbacks[callbackId]) { try { if (Cordova.callbacks[callbackId].fail) { Cordova.callbacks[callbackId].fail(args.message); } } catch (e) { console.log("Error in error callback: "+callbackId+" = "+e); } // Clear callback if not expecting any more results if (!args.keepCallback) { delete Cordova.callbacks[callbackId]; } } }; /** * Does a deep clone of the object. * * @param obj * @return */ Cordova.clone = function(obj) { if(!obj) { return obj; } if(obj instanceof Array){ var retVal = new Array(); for(var i = 0; i < obj.length; ++i){ retVal.push(Cordova.clone(obj[i])); } return retVal; } if (obj instanceof Function) { return obj; } if(!(obj instanceof Object)){ return obj; } if (obj instanceof Date) { return obj; } retVal = new Object(); for(i in obj){ if(!(i in retVal) || retVal[i] != obj[i]) { retVal[i] = Cordova.clone(obj[i]); } } return retVal; }; // Intercept calls to document.addEventListener Cordova.m_document_addEventListener = document.addEventListener; // Intercept calls to window.addEventListener Cordova.m_window_addEventListener = window.addEventListener; /** * Add a custom window event handler. * * @param {String} event The event name that callback handles * @param {Function} callback The event handler */ Cordova.addWindowEventHandler = function(event, callback) { Cordova.windowEventHandler[event] = callback; } /** * Add a custom document event handler. * * @param {String} event The event name that callback handles * @param {Function} callback The event handler */ Cordova.addDocumentEventHandler = function(event, callback) { Cordova.documentEventHandler[event] = callback; } /** * Intercept adding document event listeners and handle our own * * @param {Object} evt * @param {Function} handler * @param capture */ document.addEventListener = function(evt, handler, capture) { var e = evt.toLowerCase(); // If subscribing to an event that is handled by a plugin if (typeof Cordova.documentEventHandler[e] !== "undefined") { if (Cordova.documentEventHandler[e](e, handler, true)) { return; // Stop default behavior } } Cordova.m_document_addEventListener.call(document, evt, handler, capture); }; /** * Intercept adding window event listeners and handle our own * * @param {Object} evt * @param {Function} handler * @param capture */ window.addEventListener = function(evt, handler, capture) { var e = evt.toLowerCase(); // If subscribing to an event that is handled by a plugin if (typeof Cordova.windowEventHandler[e] !== "undefined") { if (Cordova.windowEventHandler[e](e, handler, true)) { return; // Stop default behavior } } Cordova.m_window_addEventListener.call(window, evt, handler, capture); }; // Intercept calls to document.removeEventListener and watch for events that // are generated by Cordova native code Cordova.m_document_removeEventListener = document.removeEventListener; // Intercept calls to window.removeEventListener Cordova.m_window_removeEventListener = window.removeEventListener; /** * Intercept removing document event listeners and handle our own * * @param {Object} evt * @param {Function} handler * @param capture */ document.removeEventListener = function(evt, handler, capture) { var e = evt.toLowerCase(); // If unsubcribing from an event that is handled by a plugin if (typeof Cordova.documentEventHandler[e] !== "undefined") { if (Cordova.documentEventHandler[e](e, handler, false)) { return; // Stop default behavior } } Cordova.m_document_removeEventListener.call(document, evt, handler, capture); }; /** * Intercept removing window event listeners and handle our own * * @param {Object} evt * @param {Function} handler * @param capture */ window.removeEventListener = function(evt, handler, capture) { var e = evt.toLowerCase(); // If unsubcribing from an event that is handled by a plugin if (typeof Cordova.windowEventHandler[e] !== "undefined") { if (Cordova.windowEventHandler[e](e, handler, false)) { return; // Stop default behavior } } Cordova.m_window_removeEventListener.call(window, evt, handler, capture); }; /** * Method to fire document event * * @param {String} type The event type to fire * @param {Object} data Data to send with event */ Cordova.fireDocumentEvent = function(type, data) { var e = document.createEvent('Events'); e.initEvent(type); if (data) { for (var i in data) { e[i] = data[i]; } } document.dispatchEvent(e); }; /** * Method to fire window event * * @param {String} type The event type to fire * @param {Object} data Data to send with event */ Cordova.fireWindowEvent = function(type, data) { var e = document.createEvent('Events'); e.initEvent(type); if (data) { for (var i in data) { e[i] = data[i]; } } window.dispatchEvent(e); }; /** * Method to fire event from native code * Leaving this generic version to handle problems with iOS 3.x. Is currently used by orientation and battery events * Remove when iOS 3.x no longer supported and call fireWindowEvent or fireDocumentEvent directly */ Cordova.fireEvent = function(type, target, data) { var e = document.createEvent('Events'); e.initEvent(type); if (data) { for (var i in data) { e[i] = data[i]; } } target = target || document; if (target.dispatchEvent === undefined) { // ie window.dispatchEvent is undefined in iOS 3.x target = document; } target.dispatchEvent(e); }; /** * Create a UUID * * @return */ 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 = ""; for (var i=0; i -1) { me._batteryListener.splice(pos, 1); } } else if (eventType === "batterylow") { var pos = me._lowListener.indexOf(handler); if (pos > -1) { me._lowListener.splice(pos, 1); } } else if (eventType === "batterycritical") { var pos = me._criticalListener.indexOf(handler); if (pos > -1) { me._criticalListener.splice(pos, 1); } } // If there are no more registered event listeners stop the battery listener on native side. if (me._batteryListener.length === 0 && me._lowListener.length === 0 && me._criticalListener.length === 0) { Cordova.exec(null, null, "org.apache.cordova.battery", "stop", []); } } }; /** * Callback for battery status * * @param {Object} info keys: level, isPlugged */ Battery.prototype._status = function(info) { if (info) { var me = this; if (me._level != info.level || me._isPlugged != info.isPlugged) { // Fire batterystatus event //Cordova.fireWindowEvent("batterystatus", info); // use this workaround since iOS 3.x does have window.dispatchEvent Cordova.fireEvent("batterystatus", window, info); // Fire low battery event if (info.level == 20 || info.level == 5) { if (info.level == 20) { //Cordova.fireWindowEvent("batterylow", info); // use this workaround since iOS 3.x does not have window.dispatchEvent Cordova.fireEvent("batterylow", window, info); } else { //Cordova.fireWindowEvent("batterycritical", info); // use this workaround since iOS 3.x does not have window.dispatchEvent Cordova.fireEvent("batterycritical", window, info); } } } me._level = info.level; me._isPlugged = info.isPlugged; } }; /** * Error callback for battery start */ Battery.prototype._error = function(e) { console.log("Error initializing Battery: " + e); }; Cordova.addConstructor(function() { if (typeof navigator.battery === "undefined") { navigator.battery = new Battery(); Cordova.addWindowEventHandler("batterystatus", navigator.battery.eventHandler); Cordova.addWindowEventHandler("batterylow", navigator.battery.eventHandler); Cordova.addWindowEventHandler("batterycritical", navigator.battery.eventHandler); } }); }if (!Cordova.hasResource("camera")) { Cordova.addResource("camera"); /** * This class provides access to the device camera. * @constructor */ Camera = function() { } /** * Available Camera Options * {boolean} allowEdit - true to allow editing image, default = false * {number} quality 0-100 (low to high) default = 100 * {Camera.DestinationType} destinationType default = DATA_URL * {Camera.PictureSourceType} sourceType default = CAMERA * {number} targetWidth - width in pixels to scale image default = 0 (no scaling) * {number} targetHeight - height in pixels to scale image default = 0 (no scaling) * {Camera.EncodingType} - encodingType default = JPEG * {boolean} correctOrientation - Rotate the image to correct for the orientation of the device during capture (iOS only) * {boolean} saveToPhotoAlbum - Save the image to the photo album on the device after capture (iOS only) */ /** * Format of image that is 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 }; Camera.prototype.DestinationType = Camera.DestinationType; /** * Source to getPicture from. * * Example: navigator.camera.getPicture(success, fail, * { quality: 80, * destinationType: Camera.DestinationType.DATA_URL, * sourceType: Camera.PictureSourceType.PHOTOLIBRARY}) */ Camera.PictureSourceType = { PHOTOLIBRARY : 0, // Choose image from picture library CAMERA : 1, // Take picture from camera SAVEDPHOTOALBUM : 2 // Choose image from picture library }; Camera.prototype.PictureSourceType = Camera.PictureSourceType; /** * 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; /** * Type of pictures to select from. Only applicable when * PictureSourceType is PHOTOLIBRARY or SAVEDPHOTOALBUM * * Example: navigator.camera.getPicture(success, fail, * { quality: 80, * destinationType: Camera.DestinationType.DATA_URL, * sourceType: Camera.PictureSourceType.PHOTOLIBRARY, * mediaType: Camera.MediaType.PICTURE}) */ Camera.MediaType = { PICTURE: 0, // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType VIDEO: 1, // allow selection of video only, ONLY RETURNS URL ALLMEDIA : 2 // allow selection from all media types }; Camera.prototype.MediaType = Camera.MediaType; /** * Gets a picture from source defined by "options.sourceType", and returns the * image as defined by the "options.destinationType" option. * The defaults are sourceType=CAMERA and destinationType=DATA_URL. * * @param {Function} successCallback * @param {Function} errorCallback * @param {Object} options */ Camera.prototype.getPicture = function(successCallback, errorCallback, options) { // successCallback required if (typeof successCallback != "function") { console.log("Camera Error: successCallback is not a function"); return; } // errorCallback optional if (errorCallback && (typeof errorCallback != "function")) { console.log("Camera Error: errorCallback is not a function"); return; } Cordova.exec(successCallback, errorCallback, "org.apache.cordova.camera","getPicture",[options]); }; Cordova.addConstructor(function() { if (typeof navigator.camera == "undefined") navigator.camera = new Camera(); }); }; if (!Cordova.hasResource("device")) { Cordova.addResource("device"); /** * this represents the mobile device, and provides properties for inspecting the model, version, UUID of the * phone, etc. * @constructor */ Device = function() { this.platform = null; this.version = null; this.name = null; this.cordova = null; this.uuid = null; try { this.platform = DeviceInfo.platform; this.version = DeviceInfo.version; this.name = DeviceInfo.name; this.cordova = DeviceInfo.gap; this.uuid = DeviceInfo.uuid; } catch(e) { // TODO: } this.available = Cordova.available = this.uuid != null; } Cordova.addConstructor(function() { if (typeof navigator.device === "undefined") { navigator.device = window.device = new Device(); } }); }; if (!Cordova.hasResource("capture")) { Cordova.addResource("capture"); /** * The CaptureError interface encapsulates all errors in the Capture API. */ function CaptureError() { 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. */ function Capture() { this.supportedAudioModes = []; this.supportedImageModes = []; this.supportedVideoModes = []; }; /** * Launch audio recorder application for recording audio clip(s). * * @param {Function} successCB * @param {Function} errorCB * @param {CaptureAudioOptions} options * * No audio recorder to launch for iOS - return CAPTURE_NOT_SUPPORTED */ Capture.prototype.captureAudio = function(successCallback, errorCallback, options) { /*if (errorCallback && typeof errorCallback === "function") { errorCallback({ "code": CaptureError.CAPTURE_NOT_SUPPORTED }); }*/ Cordova.exec(successCallback, errorCallback, "org.apache.cordova.mediacapture", "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, "org.apache.cordova.mediacapture", "captureImage", [options]); }; /** * Casts a PluginResult message property (array of objects) to an array of MediaFile objects * (used in Objective-C) * * @param {PluginResult} pluginResult */ Capture.prototype._castMediaFile = function(pluginResult) { var mediaFiles = []; var i; for (i=0; i} categories * @param {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.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; // JS Date this.note = note || null; this.photos = photos || null; // ContactField[] this.categories = categories || null; this.urls = urls || null; // ContactField[] }; /** * Converts Dates to milliseconds before sending to iOS */ Contact.prototype.convertDatesOut = function() { var dates = new Array("birthday"); for (var i=0; i][;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") { var evt = File._createEvent("loadstart", this); this.onloadstart(evt); } 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") { evt = File._createEvent("load", me); me.onload(evt); } // DONE state me.readyState = FileReader.DONE; // If onloadend callback if (typeof me.onloadend === "function") { evt = File._createEvent("loadend", me); me.onloadend(evt); } }, // 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") { evt = File._createEvent("error", me); me.onerror(evt); } // DONE state me.readyState = FileReader.DONE; // If onloadend callback if (typeof me.onloadend === "function") { evt = File._createEvent("loadend", me); me.onloadend(evt); } } ); }; /** * Read file and return data as a binary data. * * @param file The name of the file */ FileReader.prototype.readAsBinaryString = function(file) { // TODO - Can't return binary data to browser. this.fileName = file; }; /** * Read file and return data as a binary data. * * @param file The name of the file */ FileReader.prototype.readAsArrayBuffer = function(file) { // TODO - Can't return binary data to browser. this.fileName = file; }; //----------------------------------------------------------------------------- // File Writer //----------------------------------------------------------------------------- /** * This class writes to the mobile device file system. * @param file {File} a File object representing a file on the file system */ 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") { evt = File._createEvent("error", this); this.onerror(evt); } // If abort callback if (typeof this.onabort === "function") { evt = File._createEvent("abort", this); this.onabort(evt); } this.readyState = FileWriter.DONE; // If write end callback if (typeof this.onwriteend == "function") { evt = File._createEvent("writeend", this); this.onwriteend(evt); } }; /** * @Deprecated: use write instead * * @param file to write the data to * @param text to be written * @param bAppend if true write to end of file, otherwise overwrite the file */ FileWriter.prototype.writeAsText = function(file, text, bAppend) { // Throw an exception if we are already writing a file if (this.readyState === FileWriter.WRITING) { throw FileError.INVALID_STATE_ERR; } if (bAppend !== true) { bAppend = false; // for null values } this.fileName = file; // WRITING state this.readyState = FileWriter.WRITING; var me = this; // If onwritestart callback if (typeof me.onwritestart === "function") { var evt = File._createEvent("writestart", me); me.onwritestart(evt); } // Write file navigator.fileMgr.writeAsText(file, text, bAppend, // Success callback function(r) { var evt; // If DONE (cancelled), then don't do anything if (me.readyState === FileWriter.DONE) { return; } // Save result me.result = r; // If onwrite callback if (typeof me.onwrite === "function") { evt = File._createEvent("write", me); me.onwrite(evt); } // DONE state me.readyState = FileWriter.DONE; // If onwriteend callback if (typeof me.onwriteend === "function") { evt = File._createEvent("writeend", me); me.onwriteend(evt); } }, // 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") { evt = File._createEvent("error", me); me.onerror(evt); } // DONE state me.readyState = FileWriter.DONE; // If onwriteend callback if (typeof me.onwriteend === "function") { evt = File._createEvent("writeend", me); me.onwriteend(evt); } } ); }; /** * 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") { var evt = File._createEvent("writestart", me); me.onwritestart(evt); } // 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") { evt = File._createEvent("write", me); me.onwrite(evt); } // DONE state me.readyState = FileWriter.DONE; // If onwriteend callback if (typeof me.onwriteend === "function") { evt = File._createEvent("writeend", me); me.onwriteend(evt); } }, // 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") { evt = File._createEvent("error", me); me.onerror(evt); } // DONE state me.readyState = FileWriter.DONE; // If onwriteend callback if (typeof me.onwriteend === "function") { evt = File._createEvent("writeend", me); me.onwriteend(evt); } } ); }; /** * 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; } // what if no size specified? // WRITING state this.readyState = FileWriter.WRITING; var me = this; // If onwritestart callback if (typeof me.onwritestart === "function") { var evt = File._createEvent("writestart", me); me.onwritestart(evt); } // Write file navigator.fileMgr.truncate(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") { evt = File._createEvent("write", me); me.onwrite(evt); } // DONE state me.readyState = FileWriter.DONE; // If onwriteend callback if (typeof me.onwriteend === "function") { evt = File._createEvent("writeend", me); me.onwriteend(evt); } }, // 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") { evt = File._createEvent("error", me); me.onerror(evt); } // DONE state me.readyState = FileWriter.DONE; // If onwriteend callback if (typeof me.onwriteend === "function") { evt = File._createEvent("writeend", me); me.onwriteend(evt); } } ); }; 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 { Cordova.exec(successCallback, errorCallback, "org.apache.cordova.file", "requestFileSystem", [type, 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) { Cordova.exec(successCallback, errorCallback, "org.apache.cordova.file", "resolveLocalFileSystemURI", [uri]); }; /** * This function is required as we need to convert raw * JSON objects into concrete File and Directory objects. * * @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) { entry = new DirectoryEntry(); } else if (pluginResult.message.isFile) { 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 (i=0; i