You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by pm...@apache.org on 2012/03/22 13:50:23 UTC
[11/12] 2nd try at file refactoring
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/FileUploadOptions.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/FileUploadOptions.js b/lib0/plugin/FileUploadOptions.js
new file mode 100644
index 0000000..ff16661
--- /dev/null
+++ b/lib0/plugin/FileUploadOptions.js
@@ -0,0 +1,16 @@
+/**
+ * Options to customize the HTTP request used to upload files.
+ * @constructor
+ * @param fileKey {String} Name of file request parameter.
+ * @param fileName {String} Filename to be used by the server. Defaults to image.jpg.
+ * @param mimeType {String} Mimetype of the uploaded file. Defaults to image/jpeg.
+ * @param params {Object} Object with key: value params to send to the server.
+ */
+var FileUploadOptions = function(fileKey, fileName, mimeType, params) {
+ this.fileKey = fileKey || null;
+ this.fileName = fileName || null;
+ this.mimeType = mimeType || null;
+ this.params = params || null;
+};
+
+module.exports = FileUploadOptions;
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/FileUploadResult.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/FileUploadResult.js b/lib0/plugin/FileUploadResult.js
new file mode 100644
index 0000000..740babd
--- /dev/null
+++ b/lib0/plugin/FileUploadResult.js
@@ -0,0 +1,11 @@
+/**
+ * FileUploadResult
+ * @constructor
+ */
+var FileUploadResult = function() {
+ this.bytesSent = 0;
+ this.responseCode = null;
+ this.response = null;
+};
+
+module.exports = FileUploadResult;
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/FileWriter.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/FileWriter.js b/lib0/plugin/FileWriter.js
new file mode 100644
index 0000000..e0e5626
--- /dev/null
+++ b/lib0/plugin/FileWriter.js
@@ -0,0 +1,253 @@
+var exec = require('cordova/exec'),
+ FileError = require('cordova/plugin/FileError');
+ ProgressEvent = require('cordova/plugin/ProgressEvent');
+
+/**
+ * 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 new FileError(FileError.INVALID_STATE_ERR);
+ }
+
+ // set error
+ this.error = new FileError(FileError.ABORT_ERR);
+
+ this.readyState = FileWriter.DONE;
+
+ // If abort callback
+ if (typeof this.onabort === "function") {
+ this.onabort(new ProgressEvent("abort", {"target":this}));
+ }
+
+ // If write end callback
+ if (typeof this.onwriteend === "function") {
+ this.onwriteend(new ProgressEvent("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 new FileError(FileError.INVALID_STATE_ERR);
+ }
+
+ // WRITING state
+ this.readyState = FileWriter.WRITING;
+
+ var me = this;
+
+ // If onwritestart callback
+ if (typeof me.onwritestart === "function") {
+ me.onwritestart(new ProgressEvent("writestart", {"target":me}));
+ }
+
+ // Write file
+ exec(
+ // Success callback
+ function(r) {
+ // 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;
+
+ // DONE state
+ me.readyState = FileWriter.DONE;
+
+ // If onwrite callback
+ if (typeof me.onwrite === "function") {
+ me.onwrite(new ProgressEvent("write", {"target":me}));
+ }
+
+ // If onwriteend callback
+ if (typeof me.onwriteend === "function") {
+ me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+ }
+ },
+ // Error callback
+ function(e) {
+ // If DONE (cancelled), then don't do anything
+ if (me.readyState === FileWriter.DONE) {
+ return;
+ }
+
+ // DONE state
+ me.readyState = FileWriter.DONE;
+
+ // Save error
+ me.error = new FileError(e);
+
+ // If onerror callback
+ if (typeof me.onerror === "function") {
+ me.onerror(new ProgressEvent("error", {"target":me}));
+ }
+
+ // If onwriteend callback
+ if (typeof me.onwriteend === "function") {
+ me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+ }
+ }, "File", "write", [this.fileName, text, this.position]);
+};
+
+/**
+ * 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 new FileError(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 new FileError(FileError.INVALID_STATE_ERR);
+ }
+
+ // WRITING state
+ this.readyState = FileWriter.WRITING;
+
+ var me = this;
+
+ // If onwritestart callback
+ if (typeof me.onwritestart === "function") {
+ me.onwritestart(new ProgressEvent("writestart", {"target":this}));
+ }
+
+ // Write file
+ exec(
+ // Success callback
+ function(r) {
+ // If DONE (cancelled), then don't do anything
+ if (me.readyState === FileWriter.DONE) {
+ return;
+ }
+
+ // DONE state
+ me.readyState = FileWriter.DONE;
+
+ // 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(new ProgressEvent("write", {"target":me}));
+ }
+
+ // If onwriteend callback
+ if (typeof me.onwriteend === "function") {
+ me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+ }
+ },
+ // Error callback
+ function(e) {
+ // If DONE (cancelled), then don't do anything
+ if (me.readyState === FileWriter.DONE) {
+ return;
+ }
+
+ // DONE state
+ me.readyState = FileWriter.DONE;
+
+ // Save error
+ me.error = new FileError(e);
+
+ // If onerror callback
+ if (typeof me.onerror === "function") {
+ me.onerror(new ProgressEvent("error", {"target":me}));
+ }
+
+ // If onwriteend callback
+ if (typeof me.onwriteend === "function") {
+ me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+ }
+ }, "File", "truncate", [this.fileName, size]);
+};
+
+module.exports = FileWriter;
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/Flags.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/Flags.js b/lib0/plugin/Flags.js
new file mode 100644
index 0000000..d918c38
--- /dev/null
+++ b/lib0/plugin/Flags.js
@@ -0,0 +1,15 @@
+/**
+ * Supplies arguments to methods that lookup or create files and directories.
+ *
+ * @param create
+ * {boolean} file or directory if it doesn't exist
+ * @param exclusive
+ * {boolean} used with create; if true the command will fail if
+ * target path exists
+ */
+function Flags(create, exclusive) {
+ this.create = create || false;
+ this.exclusive = exclusive || false;
+}
+
+module.exports = Flags;
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/LocalFileSystem.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/LocalFileSystem.js b/lib0/plugin/LocalFileSystem.js
new file mode 100644
index 0000000..f71ae62
--- /dev/null
+++ b/lib0/plugin/LocalFileSystem.js
@@ -0,0 +1,13 @@
+var exec = require('cordova/exec');
+
+/**
+ * Represents a local file system.
+ */
+var LocalFileSystem = function() {
+
+};
+
+LocalFileSystem.TEMPORARY = 0; //temporary, with no guarantee of persistence
+LocalFileSystem.PERSISTENT = 1; //persistent
+
+module.exports = LocalFileSystem;
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/Media.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/Media.js b/lib0/plugin/Media.js
new file mode 100644
index 0000000..8d56da9
--- /dev/null
+++ b/lib0/plugin/Media.js
@@ -0,0 +1,186 @@
+var utils = require('cordova/utils'),
+ exec = require('cordova/exec');
+
+var mediaObjects = {};
+
+/**
+ * This class provides access to the device media, interfaces to both sound and video
+ *
+ * @constructor
+ * @param src The file name or url to play
+ * @param successCallback The callback to be called when the file is done playing or recording.
+ * successCallback()
+ * @param errorCallback The callback to be called if there is an error.
+ * errorCallback(int errorCode) - OPTIONAL
+ * @param statusCallback The callback to be called when media status has changed.
+ * statusCallback(int statusCode) - OPTIONAL
+ */
+var Media = function(src, successCallback, errorCallback, statusCallback) {
+
+ // successCallback optional
+ if (successCallback && (typeof successCallback !== "function")) {
+ console.log("Media Error: successCallback is not a function");
+ return;
+ }
+
+ // errorCallback optional
+ if (errorCallback && (typeof errorCallback !== "function")) {
+ console.log("Media Error: errorCallback is not a function");
+ return;
+ }
+
+ // statusCallback optional
+ if (statusCallback && (typeof statusCallback !== "function")) {
+ console.log("Media Error: statusCallback is not a function");
+ return;
+ }
+
+ this.id = utils.createUUID();
+ mediaObjects[this.id] = this;
+ this.src = src;
+ this.successCallback = successCallback;
+ this.errorCallback = errorCallback;
+ this.statusCallback = statusCallback;
+ this._duration = -1;
+ this._position = -1;
+ exec(null, this.errorCallback, "Media", "create", [this.id, this.src]);
+};
+
+// Media messages
+Media.MEDIA_STATE = 1;
+Media.MEDIA_DURATION = 2;
+Media.MEDIA_POSITION = 3;
+Media.MEDIA_ERROR = 9;
+
+// Media states
+Media.MEDIA_NONE = 0;
+Media.MEDIA_STARTING = 1;
+Media.MEDIA_RUNNING = 2;
+Media.MEDIA_PAUSED = 3;
+Media.MEDIA_STOPPED = 4;
+Media.MEDIA_MSG = ["None", "Starting", "Running", "Paused", "Stopped"];
+
+// "static" function to return existing objs.
+Media.get = function(id) {
+ return mediaObjects[id];
+};
+
+/**
+ * Start or resume playing audio file.
+ */
+Media.prototype.play = function() {
+ exec(this.successCallback, this.errorCallback, "Media", "startPlayingAudio", [this.id, this.src]);
+};
+
+/**
+ * Stop playing audio file.
+ */
+Media.prototype.stop = function() {
+ var me = this;
+ exec(function() {
+ me._position = 0;
+ me.successCallback();
+ }, this.errorCallback, "Media", "stopPlayingAudio", [this.id]);
+};
+
+/**
+ * Seek or jump to a new time in the track..
+ */
+Media.prototype.seekTo = function(milliseconds) {
+ var me = this;
+ exec(function(p) {
+ me._position = p;
+ }, this.errorCallback, "Media", "seekToAudio", [this.id, milliseconds]);
+};
+
+/**
+ * Pause playing audio file.
+ */
+Media.prototype.pause = function() {
+ exec(null, this.errorCallback, "Media", "pausePlayingAudio", [this.id]);
+};
+
+/**
+ * Get duration of an audio file.
+ * The duration is only set for audio that is playing, paused or stopped.
+ *
+ * @return duration or -1 if not known.
+ */
+Media.prototype.getDuration = function() {
+ return this._duration;
+};
+
+/**
+ * Get position of audio.
+ */
+Media.prototype.getCurrentPosition = function(success, fail) {
+ var me = this;
+ exec(function(p) {
+ me._position = p;
+ success(p);
+ }, fail, "Media", "getCurrentPositionAudio", [this.id]);
+};
+
+/**
+ * Start recording audio file.
+ */
+Media.prototype.startRecord = function() {
+ exec(this.successCallback, this.errorCallback, "Media", "startRecordingAudio", [this.id, this.src]);
+};
+
+/**
+ * Stop recording audio file.
+ */
+Media.prototype.stopRecord = function() {
+ exec(this.successCallback, this.errorCallback, "Media", "stopRecordingAudio", [this.id]);
+};
+
+/**
+ * Release the resources.
+ */
+Media.prototype.release = function() {
+ exec(null, this.errorCallback, "Media", "release", [this.id]);
+};
+
+/**
+ * Adjust the volume.
+ */
+Media.prototype.setVolume = function(volume) {
+ exec(null, null, "Media", "setVolume", [this.id, volume]);
+};
+
+/**
+ * Audio has status update.
+ * PRIVATE
+ *
+ * @param id The media object id (string)
+ * @param status The status code (int)
+ * @param msg The status message (string)
+ */
+Media.onStatus = function(id, msg, value) {
+ var media = mediaObjects[id];
+ // If state update
+ if (msg === Media.MEDIA_STATE) {
+ if (value === Media.MEDIA_STOPPED) {
+ if (media.successCallback) {
+ media.successCallback();
+ }
+ }
+ if (media.statusCallback) {
+ media.statusCallback(value);
+ }
+ }
+ else if (msg === Media.MEDIA_DURATION) {
+ media._duration = value;
+ }
+ else if (msg === Media.MEDIA_ERROR) {
+ if (media.errorCallback) {
+ media.errorCallback({"code":value});
+ }
+ }
+ else if (msg === Media.MEDIA_POSITION) {
+ media._position = value;
+ }
+};
+
+module.exports = Media;
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/MediaError.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/MediaError.js b/lib0/plugin/MediaError.js
new file mode 100644
index 0000000..40ce8f1
--- /dev/null
+++ b/lib0/plugin/MediaError.js
@@ -0,0 +1,16 @@
+/**
+ * This class contains information about any Media errors.
+ * @constructor
+ */
+var MediaError = function(code, msg) {
+ this.code = (code !== undefined ? code : null);
+ this.message = msg || "";
+};
+
+MediaError.MEDIA_ERR_NONE_ACTIVE = 0;
+MediaError.MEDIA_ERR_ABORTED = 1;
+MediaError.MEDIA_ERR_NETWORK = 2;
+MediaError.MEDIA_ERR_DECODE = 3;
+MediaError.MEDIA_ERR_NONE_SUPPORTED = 4;
+
+module.exports = MediaError;
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/MediaFile.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/MediaFile.js b/lib0/plugin/MediaFile.js
new file mode 100644
index 0000000..e73716b
--- /dev/null
+++ b/lib0/plugin/MediaFile.js
@@ -0,0 +1,56 @@
+var utils = require('cordova/utils'),
+ exec = require('cordova/exec'),
+ File = require('cordova/plugin/File'),
+ CaptureError = require('cordova/plugin/CaptureError');
+/**
+ * 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){
+ MediaFile.__super__.constructor.apply(this, arguments);
+};
+
+utils.extend(MediaFile, File);
+
+/**
+ * Request capture format data for a specific file and type
+ *
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ */
+MediaFile.prototype.getFormatData = function(successCallback, errorCallback) {
+ if (typeof this.fullPath === "undefined" || this.fullPath === null) {
+ errorCallback(new CaptureError(CaptureError.CAPTURE_INVALID_ARGUMENT));
+ } else {
+ exec(successCallback, errorCallback, "Capture", "getFormatData", [this.fullPath, this.type]);
+ }
+};
+
+/**
+ * Casts a PluginResult message property (array of objects) to an array of MediaFile objects
+ * (used in Objective-C and Android)
+ *
+ * @param {PluginResult} pluginResult
+ */
+MediaFile.cast = 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;
+};
+
+module.exports = MediaFile;
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/MediaFileData.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/MediaFileData.js b/lib0/plugin/MediaFileData.js
new file mode 100644
index 0000000..ea5c2a3
--- /dev/null
+++ b/lib0/plugin/MediaFileData.js
@@ -0,0 +1,18 @@
+/**
+ * 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;
+};
+
+module.exports = MediaFileData;
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/Metadata.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/Metadata.js b/lib0/plugin/Metadata.js
new file mode 100644
index 0000000..b29cc7c
--- /dev/null
+++ b/lib0/plugin/Metadata.js
@@ -0,0 +1,10 @@
+/**
+ * Information about the state of the file or directory
+ *
+ * {Date} modificationTime (readonly)
+ */
+var Metadata = function(time) {
+ this.modificationTime = (typeof time != 'undefined'?new Date(time):null);
+};
+
+module.exports = Metadata;
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/Position.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/Position.js b/lib0/plugin/Position.js
new file mode 100644
index 0000000..25096c4
--- /dev/null
+++ b/lib0/plugin/Position.js
@@ -0,0 +1,8 @@
+var Coordinates = require('cordova/plugin/Coordinates');
+
+var Position = function(coords, timestamp) {
+ this.coords = new Coordinates(coords.latitude, coords.longitude, coords.altitude, coords.accuracy, coords.heading, coords.velocity, coords.altitudeAccuracy);
+ this.timestamp = (timestamp !== undefined) ? timestamp : new Date().getTime();
+};
+
+module.exports = Position;
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/PositionError.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/PositionError.js b/lib0/plugin/PositionError.js
new file mode 100644
index 0000000..07012d6
--- /dev/null
+++ b/lib0/plugin/PositionError.js
@@ -0,0 +1,17 @@
+/**
+ * Position error object
+ *
+ * @constructor
+ * @param code
+ * @param message
+ */
+var PositionError = function(code, message) {
+ this.code = code || null;
+ this.message = message || '';
+};
+
+PositionError.PERMISSION_DENIED = 1;
+PositionError.POSITION_UNAVAILABLE = 2;
+PositionError.TIMEOUT = 3;
+
+module.exports = PositionError;
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/ProgressEvent.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/ProgressEvent.js b/lib0/plugin/ProgressEvent.js
new file mode 100644
index 0000000..d8e41c1
--- /dev/null
+++ b/lib0/plugin/ProgressEvent.js
@@ -0,0 +1,46 @@
+// If ProgressEvent exists in global context, use it already, otherwise use our own polyfill
+// Feature test: See if we can instantiate a native ProgressEvent;
+// if so, use that approach,
+// otherwise fill-in with our own implementation.
+//
+// NOTE: right now we always fill in with our own. Down the road would be nice if we can use whatever is native in the webview.
+var ProgressEvent = (function() {
+ /*
+ var createEvent = function(data) {
+ var event = document.createEvent('Events');
+ event.initEvent('ProgressEvent', false, false);
+ if (data) {
+ for (var i in data) {
+ if (data.hasOwnProperty(i)) {
+ event[i] = data[i];
+ }
+ }
+ if (data.target) {
+ // TODO: cannot call <some_custom_object>.dispatchEvent
+ // need to first figure out how to implement EventTarget
+ }
+ }
+ return event;
+ };
+ try {
+ var ev = createEvent({type:"abort",target:document});
+ return function ProgressEvent(type, data) {
+ data.type = type;
+ return createEvent(data);
+ };
+ } catch(e){
+ */
+ return function ProgressEvent(type, dict) {
+ this.type = type;
+ this.bubbles = false;
+ this.cancelBubble = false;
+ this.cancelable = false;
+ this.lengthComputable = false;
+ this.loaded = dict && dict.loaded ? dict.loaded : 0;
+ this.total = dict && dict.total ? dict.total : 0;
+ this.target = dict && dict.target ? dict.target : null;
+ };
+ //}
+})();
+
+module.exports = ProgressEvent;
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/accelerometer.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/accelerometer.js b/lib0/plugin/accelerometer.js
new file mode 100644
index 0000000..6f01ab8
--- /dev/null
+++ b/lib0/plugin/accelerometer.js
@@ -0,0 +1,95 @@
+/**
+ * This class provides access to device accelerometer data.
+ * @constructor
+ */
+var utils = require("cordova/utils"),
+ exec = require("cordova/exec");
+
+// Local singleton variables.
+var timers = {};
+
+var accelerometer = {
+ /**
+ * 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)
+ */
+ 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;
+ }
+
+ // Get acceleration
+ exec(successCallback, errorCallback, "Accelerometer", "getAcceleration", []);
+ },
+
+ /**
+ * 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.
+ */
+ watchAcceleration: function(successCallback, errorCallback, options) {
+
+ // Default interval (10 sec)
+ var frequency = (options !== undefined && options.frequency !== undefined)? options.frequency : 10000;
+
+ // 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;
+ }
+
+ // Make sure accelerometer timeout > frequency + 10 sec
+ exec(
+ function(timeout) {
+ if (timeout < (frequency + 10000)) {
+ exec(null, null, "Accelerometer", "setTimeout", [frequency + 10000]);
+ }
+ },
+ function(e) { }, "Accelerometer", "getTimeout", []);
+
+ // Start watch timer
+ var id = utils.createUUID();
+ timers[id] = window.setInterval(function() {
+ exec(successCallback, errorCallback, "Accelerometer", "getAcceleration", []);
+ }, (frequency ? frequency : 1));
+
+ return id;
+ },
+
+ /**
+ * Clears the specified accelerometer watch.
+ *
+ * @param {String} id The id of the watch returned from #watchAcceleration.
+ */
+ clearWatch: function(id) {
+
+ // Stop javascript timer & remove from timer list
+ if (id && timers[id] !== undefined) {
+ window.clearInterval(timers[id]);
+ delete timers[id];
+ }
+ }
+};
+
+module.exports = accelerometer;
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/android/app.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/android/app.js b/lib0/plugin/android/app.js
new file mode 100644
index 0000000..f858829
--- /dev/null
+++ b/lib0/plugin/android/app.js
@@ -0,0 +1,71 @@
+var exec = require('cordova/exec');
+
+module.exports = {
+ /**
+ * Clear the resource cache.
+ */
+ clearCache:function() {
+ exec(null, null, "App", "clearCache", []);
+ },
+
+ /**
+ * Load the url into the webview or into new browser instance.
+ *
+ * @param url The URL to load
+ * @param props Properties that can be passed in to the activity:
+ * wait: int => wait msec before loading URL
+ * loadingDialog: "Title,Message" => display a native loading dialog
+ * loadUrlTimeoutValue: int => time in msec to wait before triggering a timeout error
+ * clearHistory: boolean => clear webview history (default=false)
+ * openExternal: boolean => open in a new browser (default=false)
+ *
+ * Example:
+ * navigator.app.loadUrl("http://server/myapp/index.html", {wait:2000, loadingDialog:"Wait,Loading App", loadUrlTimeoutValue: 60000});
+ */
+ loadUrl:function(url, props) {
+ exec(null, null, "App", "loadUrl", [url, props]);
+ },
+
+ /**
+ * Cancel loadUrl that is waiting to be loaded.
+ */
+ cancelLoadUrl:function() {
+ exec(null, null, "App", "cancelLoadUrl", []);
+ },
+
+ /**
+ * Clear web history in this web view.
+ * Instead of BACK button loading the previous web page, it will exit the app.
+ */
+ clearHistory:function() {
+ exec(null, null, "App", "clearHistory", []);
+ },
+
+ /**
+ * Go to previous page displayed.
+ * This is the same as pressing the backbutton on Android device.
+ */
+ backHistory:function() {
+ exec(null, null, "App", "backHistory", []);
+ },
+
+ /**
+ * Override the default behavior of the Android back button.
+ * If overridden, when the back button is pressed, the "backKeyDown" JavaScript event will be fired.
+ *
+ * Note: The user should not have to call this method. Instead, when the user
+ * registers for the "backbutton" event, this is automatically done.
+ *
+ * @param override T=override, F=cancel override
+ */
+ overrideBackbutton:function(override) {
+ exec(null, null, "App", "overrideBackbutton", [override]);
+ },
+
+ /**
+ * Exit and terminate the application.
+ */
+ exitApp:function() {
+ return exec(null, null, "App", "exitApp", []);
+ }
+};
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/android/callback.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/android/callback.js b/lib0/plugin/android/callback.js
new file mode 100644
index 0000000..d5768a7
--- /dev/null
+++ b/lib0/plugin/android/callback.js
@@ -0,0 +1,85 @@
+var port = null,
+ token = null,
+ cordova = require('cordova'),
+ polling = require('cordova/plugin/android/polling'),
+ callback = function() {
+ // Exit if shutting down app
+ if (cordova.shuttingDown) {
+ return;
+ }
+
+ // If polling flag was changed, start using polling from now on
+ if (cordova.UsePolling) {
+ polling();
+ return;
+ }
+
+ var xmlhttp = new XMLHttpRequest();
+
+ // Callback function when XMLHttpRequest is ready
+ xmlhttp.onreadystatechange=function(){
+ if(xmlhttp.readyState === 4){
+
+ // Exit if shutting down app
+ if (cordova.shuttingDown) {
+ return;
+ }
+
+ // If callback has JavaScript statement to execute
+ if (xmlhttp.status === 200) {
+
+ // Need to url decode the response
+ var msg = decodeURIComponent(xmlhttp.responseText);
+ setTimeout(function() {
+ try {
+ var t = eval(msg);
+ }
+ catch (e) {
+ // If we're getting an error here, seeing the message will help in debugging
+ console.log("JSCallback: Message from Server: " + msg);
+ console.log("JSCallback Error: "+e);
+ }
+ }, 1);
+ setTimeout(callback, 1);
+ }
+
+ // If callback ping (used to keep XHR request from timing out)
+ else if (xmlhttp.status === 404) {
+ setTimeout(callback, 10);
+ }
+
+ // If security error
+ else if (xmlhttp.status === 403) {
+ console.log("JSCallback Error: Invalid token. Stopping callbacks.");
+ }
+
+ // If server is stopping
+ else if (xmlhttp.status === 503) {
+ console.log("JSCallback Server Closed: Stopping callbacks.");
+ }
+
+ // If request wasn't GET
+ else if (xmlhttp.status === 400) {
+ console.log("JSCallback Error: Bad request. Stopping callbacks.");
+ }
+
+ // If error, revert to polling
+ else {
+ console.log("JSCallback Error: Request failed.");
+ cordova.UsePolling = true;
+ polling();
+ }
+ }
+ };
+
+ if (port === null) {
+ port = prompt("getPort", "gap_callbackServer:");
+ }
+ if (token === null) {
+ token = prompt("getToken", "gap_callbackServer:");
+ }
+ xmlhttp.open("GET", "http://127.0.0.1:"+port+"/"+token , true);
+ xmlhttp.send();
+};
+
+module.exports = callback;
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/android/device.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/android/device.js b/lib0/plugin/android/device.js
new file mode 100644
index 0000000..1defbbe
--- /dev/null
+++ b/lib0/plugin/android/device.js
@@ -0,0 +1,92 @@
+var channel = require('cordova/channel'),
+ exec = require('cordova/exec');
+
+/**
+ * This represents the mobile device, and provides properties for inspecting the model, version, UUID of the
+ * phone, etc.
+ * @constructor
+ */
+function Device() {
+ this.available = false;
+ this.platform = null;
+ this.version = null;
+ this.name = null;
+ this.uuid = null;
+ this.cordova = null;
+
+ var me = this;
+ this.getInfo(
+ function(info) {
+ me.available = true;
+ me.platform = info.platform;
+ me.version = info.version;
+ me.name = info.name;
+ me.uuid = info.uuid;
+ me.cordova = info.cordova;
+ channel.onCordovaInfoReady.fire();
+ },
+ function(e) {
+ me.available = false;
+ console.log("Error initializing Cordova: " + e);
+ alert("Error initializing Cordova: "+e);
+ });
+}
+
+/**
+ * Get device info
+ *
+ * @param {Function} successCallback The function to call when the heading data is available
+ * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL)
+ */
+Device.prototype.getInfo = function(successCallback, errorCallback) {
+
+ // successCallback required
+ if (typeof successCallback !== "function") {
+ console.log("Device Error: successCallback is not a function");
+ return;
+ }
+
+ // errorCallback optional
+ if (errorCallback && (typeof errorCallback !== "function")) {
+ console.log("Device Error: errorCallback is not a function");
+ return;
+ }
+
+ // Get info
+ exec(successCallback, errorCallback, "Device", "getDeviceInfo", []);
+};
+
+/*
+ * DEPRECATED
+ * This is only for Android.
+ *
+ * You must explicitly override the back button.
+ */
+Device.prototype.overrideBackButton = function() {
+ console.log("Device.overrideBackButton() is deprecated. Use App.overrideBackbutton(true).");
+ navigator.app.overrideBackbutton(true);
+};
+
+/*
+ * DEPRECATED
+ * This is only for Android.
+ *
+ * This resets the back button to the default behaviour
+ */
+Device.prototype.resetBackButton = function() {
+ console.log("Device.resetBackButton() is deprecated. Use App.overrideBackbutton(false).");
+ navigator.app.overrideBackbutton(false);
+};
+
+/*
+ * DEPRECATED
+ * This is only for Android.
+ *
+ * This terminates the activity!
+ */
+Device.prototype.exitApp = function() {
+ console.log("Device.exitApp() is deprecated. Use App.exitApp().");
+ navigator.app.exitApp();
+};
+
+module.exports = new Device();
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/android/polling.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/android/polling.js b/lib0/plugin/android/polling.js
new file mode 100644
index 0000000..36b8e86
--- /dev/null
+++ b/lib0/plugin/android/polling.js
@@ -0,0 +1,33 @@
+var cordova = require('cordova'),
+ period = 50,
+ polling = function() {
+ // Exit if shutting down app
+ if (cordova.shuttingDown) {
+ return;
+ }
+
+ // If polling flag was changed, stop using polling from now on and switch to XHR server / callback
+ if (!cordova.UsePolling) {
+ require('cordova/plugin/android/callback')();
+ return;
+ }
+
+ var msg = prompt("", "gap_poll:");
+ if (msg) {
+ setTimeout(function() {
+ try {
+ var t = eval(""+msg);
+ }
+ catch (e) {
+ console.log("JSCallbackPolling: Message from Server: " + msg);
+ console.log("JSCallbackPolling Error: "+e);
+ }
+ }, 1);
+ setTimeout(polling, 1);
+ }
+ else {
+ setTimeout(polling, period);
+ }
+};
+
+module.exports = polling;
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/android/storage.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/android/storage.js b/lib0/plugin/android/storage.js
new file mode 100644
index 0000000..000612b
--- /dev/null
+++ b/lib0/plugin/android/storage.js
@@ -0,0 +1,377 @@
+var utils = require('cordova/utils'),
+ exec = require('cordova/exec');
+ channel = require('cordova/channel');
+
+var queryQueue = {};
+
+/**
+ * SQL result set object
+ * PRIVATE METHOD
+ * @constructor
+ */
+var DroidDB_Rows = function() {
+ this.resultSet = []; // results array
+ this.length = 0; // number of rows
+};
+
+/**
+ * Get item from SQL result set
+ *
+ * @param row The row number to return
+ * @return The row object
+ */
+DroidDB_Rows.prototype.item = function(row) {
+ return this.resultSet[row];
+};
+
+/**
+ * SQL result set that is returned to user.
+ * PRIVATE METHOD
+ * @constructor
+ */
+var DroidDB_Result = function() {
+ this.rows = new DroidDB_Rows();
+};
+
+/**
+ * Callback from native code when query is complete.
+ * PRIVATE METHOD
+ *
+ * @param id Query id
+ */
+function completeQuery(id, data) {
+ var query = queryQueue[id];
+ if (query) {
+ try {
+ delete queryQueue[id];
+
+ // Get transaction
+ var tx = query.tx;
+
+ // If transaction hasn't failed
+ // Note: We ignore all query results if previous query
+ // in the same transaction failed.
+ if (tx && tx.queryList[id]) {
+
+ // Save query results
+ var r = new DroidDB_Result();
+ r.rows.resultSet = data;
+ r.rows.length = data.length;
+ try {
+ if (typeof query.successCallback === 'function') {
+ query.successCallback(query.tx, r);
+ }
+ } catch (ex) {
+ console.log("executeSql error calling user success callback: "+ex);
+ }
+
+ tx.queryComplete(id);
+ }
+ } catch (e) {
+ console.log("executeSql error: "+e);
+ }
+ }
+}
+
+/**
+ * Callback from native code when query fails
+ * PRIVATE METHOD
+ *
+ * @param reason Error message
+ * @param id Query id
+ */
+function failQuery(reason, id) {
+ var query = queryQueue[id];
+ if (query) {
+ try {
+ delete queryQueue[id];
+
+ // Get transaction
+ var tx = query.tx;
+
+ // If transaction hasn't failed
+ // Note: We ignore all query results if previous query
+ // in the same transaction failed.
+ if (tx && tx.queryList[id]) {
+ tx.queryList = {};
+
+ try {
+ if (typeof query.errorCallback === 'function') {
+ query.errorCallback(query.tx, reason);
+ }
+ } catch (ex) {
+ console.log("executeSql error calling user error callback: "+ex);
+ }
+
+ tx.queryFailed(id, reason);
+ }
+
+ } catch (e) {
+ console.log("executeSql error: "+e);
+ }
+ }
+}
+
+/**
+ * SQL query object
+ * PRIVATE METHOD
+ *
+ * @constructor
+ * @param tx The transaction object that this query belongs to
+ */
+var DroidDB_Query = function(tx) {
+
+ // Set the id of the query
+ this.id = utils.createUUID();
+
+ // Add this query to the queue
+ queryQueue[this.id] = this;
+
+ // Init result
+ this.resultSet = [];
+
+ // Set transaction that this query belongs to
+ this.tx = tx;
+
+ // Add this query to transaction list
+ this.tx.queryList[this.id] = this;
+
+ // Callbacks
+ this.successCallback = null;
+ this.errorCallback = null;
+
+};
+
+/**
+ * Transaction object
+ * PRIVATE METHOD
+ * @constructor
+ */
+var DroidDB_Tx = function() {
+
+ // Set the id of the transaction
+ this.id = utils.createUUID();
+
+ // Callbacks
+ this.successCallback = null;
+ this.errorCallback = null;
+
+ // Query list
+ this.queryList = {};
+};
+
+/**
+ * Mark query in transaction as complete.
+ * If all queries are complete, call the user's transaction success callback.
+ *
+ * @param id Query id
+ */
+DroidDB_Tx.prototype.queryComplete = function(id) {
+ delete this.queryList[id];
+
+ // If no more outstanding queries, then fire transaction success
+ if (this.successCallback) {
+ var count = 0;
+ var i;
+ for (i in this.queryList) {
+ if (this.queryList.hasOwnProperty(i)) {
+ count++;
+ }
+ }
+ if (count === 0) {
+ try {
+ this.successCallback();
+ } catch(e) {
+ console.log("Transaction error calling user success callback: " + e);
+ }
+ }
+ }
+};
+
+/**
+ * Mark query in transaction as failed.
+ *
+ * @param id Query id
+ * @param reason Error message
+ */
+DroidDB_Tx.prototype.queryFailed = function(id, reason) {
+
+ // The sql queries in this transaction have already been run, since
+ // we really don't have a real transaction implemented in native code.
+ // However, the user callbacks for the remaining sql queries in transaction
+ // will not be called.
+ this.queryList = {};
+
+ if (this.errorCallback) {
+ try {
+ this.errorCallback(reason);
+ } catch(e) {
+ console.log("Transaction error calling user error callback: " + e);
+ }
+ }
+};
+
+/**
+ * Execute SQL statement
+ *
+ * @param sql SQL statement to execute
+ * @param params Statement parameters
+ * @param successCallback Success callback
+ * @param errorCallback Error callback
+ */
+DroidDB_Tx.prototype.executeSql = function(sql, params, successCallback, errorCallback) {
+
+ // Init params array
+ if (typeof params === 'undefined') {
+ params = [];
+ }
+
+ // Create query and add to queue
+ var query = new DroidDB_Query(this);
+ queryQueue[query.id] = query;
+
+ // Save callbacks
+ query.successCallback = successCallback;
+ query.errorCallback = errorCallback;
+
+ // Call native code
+ exec(null, null, "Storage", "executeSql", [sql, params, query.id]);
+};
+
+var DatabaseShell = function() {
+};
+
+/**
+ * Start a transaction.
+ * Does not support rollback in event of failure.
+ *
+ * @param process {Function} The transaction function
+ * @param successCallback {Function}
+ * @param errorCallback {Function}
+ */
+DatabaseShell.prototype.transaction = function(process, errorCallback, successCallback) {
+ var tx = new DroidDB_Tx();
+ tx.successCallback = successCallback;
+ tx.errorCallback = errorCallback;
+ try {
+ process(tx);
+ } catch (e) {
+ console.log("Transaction error: "+e);
+ if (tx.errorCallback) {
+ try {
+ tx.errorCallback(e);
+ } catch (ex) {
+ console.log("Transaction error calling user error callback: "+e);
+ }
+ }
+ }
+};
+
+/**
+ * Open database
+ *
+ * @param name Database name
+ * @param version Database version
+ * @param display_name Database display name
+ * @param size Database size in bytes
+ * @return Database object
+ */
+var DroidDB_openDatabase = function(name, version, display_name, size) {
+ exec(null, null, "Storage", "openDatabase", [name, version, display_name, size]);
+ var db = new DatabaseShell();
+ return db;
+};
+
+/**
+ * For browsers with no localStorage we emulate it with SQLite. Follows the w3c api.
+ * TODO: Do similar for sessionStorage.
+ * @constructor
+ */
+var CupcakeLocalStorage = function() {
+ channel.waitForInitialization("cupcakeStorage");
+
+ try {
+
+ this.db = openDatabase('localStorage', '1.0', 'localStorage', 2621440);
+ var storage = {};
+ this.length = 0;
+ function setLength (length) {
+ this.length = length;
+ localStorage.length = length;
+ }
+ this.db.transaction(
+ function (transaction) {
+ var i;
+ transaction.executeSql('CREATE TABLE IF NOT EXISTS storage (id NVARCHAR(40) PRIMARY KEY, body NVARCHAR(255))');
+ transaction.executeSql('SELECT * FROM storage', [], function(tx, result) {
+ for(var i = 0; i < result.rows.length; i++) {
+ storage[result.rows.item(i)['id']] = result.rows.item(i)['body'];
+ }
+ setLength(result.rows.length);
+ channel.initializationComplete("cupcakeStorage");
+ });
+
+ },
+ function (err) {
+ alert(err.message);
+ }
+ );
+ this.setItem = function(key, val) {
+ if (typeof(storage[key])=='undefined') {
+ this.length++;
+ }
+ storage[key] = val;
+ this.db.transaction(
+ function (transaction) {
+ transaction.executeSql('CREATE TABLE IF NOT EXISTS storage (id NVARCHAR(40) PRIMARY KEY, body NVARCHAR(255))');
+ transaction.executeSql('REPLACE INTO storage (id, body) values(?,?)', [key,val]);
+ }
+ );
+ };
+ this.getItem = function(key) {
+ return storage[key];
+ };
+ this.removeItem = function(key) {
+ delete storage[key];
+ this.length--;
+ this.db.transaction(
+ function (transaction) {
+ transaction.executeSql('CREATE TABLE IF NOT EXISTS storage (id NVARCHAR(40) PRIMARY KEY, body NVARCHAR(255))');
+ transaction.executeSql('DELETE FROM storage where id=?', [key]);
+ }
+ );
+ };
+ this.clear = function() {
+ storage = {};
+ this.length = 0;
+ this.db.transaction(
+ function (transaction) {
+ transaction.executeSql('CREATE TABLE IF NOT EXISTS storage (id NVARCHAR(40) PRIMARY KEY, body NVARCHAR(255))');
+ transaction.executeSql('DELETE FROM storage', []);
+ }
+ );
+ };
+ this.key = function(index) {
+ var i = 0;
+ for (var j in storage) {
+ if (i==index) {
+ return j;
+ } else {
+ i++;
+ }
+ }
+ return null;
+ };
+
+ } catch(e) {
+ alert("Database error "+e+".");
+ return;
+ }
+};
+
+module.exports = {
+ openDatabase:DroidDB_openDatabase,
+ CupcakeLocalStorage:CupcakeLocalStorage,
+ failQuery:failQuery,
+ completeQuery:completeQuery
+};
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/battery.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/battery.js b/lib0/plugin/battery.js
new file mode 100644
index 0000000..5649356
--- /dev/null
+++ b/lib0/plugin/battery.js
@@ -0,0 +1,87 @@
+/**
+ * This class contains information about the current battery status.
+ * @constructor
+ */
+var cordova = require('cordova'),
+ exec = require('cordova/exec');
+
+function handlers() {
+ return battery.channels.batterystatus.numHandlers +
+ battery.channels.batterylow.numHandlers +
+ battery.channels.batterycritical.numHandlers;
+}
+
+var Battery = function() {
+ this._level = null;
+ this._isPlugged = null;
+ // Create new event handlers on the window (returns a channel instance)
+ var subscriptionEvents = {
+ onSubscribe:this.onSubscribe,
+ onUnsubscribe:this.onUnsubscribe
+ };
+ this.channels = {
+ batterystatus:cordova.addWindowEventHandler("batterystatus", subscriptionEvents),
+ batterylow:cordova.addWindowEventHandler("batterylow", subscriptionEvents),
+ batterycritical:cordova.addWindowEventHandler("batterycritical", subscriptionEvents)
+ };
+};
+/**
+ * Event handlers for when callbacks get registered for the battery.
+ * Keep track of how many handlers we have so we can start and stop the native battery listener
+ * appropriately (and hopefully save on battery life!).
+ */
+Battery.prototype.onSubscribe = function() {
+ var me = battery;
+ // If we just registered the first handler, make sure native listener is started.
+ if (handlers() === 1) {
+ exec(me._status, me._error, "Battery", "start", []);
+ }
+};
+
+Battery.prototype.onUnsubscribe = function() {
+ var me = battery;
+
+ // If we just unregistered the last handler, make sure native listener is stopped.
+ if (handlers() === 0) {
+ exec(null, null, "Battery", "stop", []);
+ }
+};
+
+/**
+ * Callback for battery status
+ *
+ * @param {Object} info keys: level, isPlugged
+ */
+Battery.prototype._status = function(info) {
+ if (info) {
+ var me = battery;
+ var level = info.level;
+ if (me._level !== level || me._isPlugged !== info.isPlugged) {
+ // Fire batterystatus event
+ cordova.fireWindowEvent("batterystatus", info);
+
+ // Fire low battery event
+ if (level === 20 || level === 5) {
+ if (level === 20) {
+ cordova.fireWindowEvent("batterylow", info);
+ }
+ else {
+ cordova.fireWindowEvent("batterycritical", info);
+ }
+ }
+ }
+ me._level = level;
+ me._isPlugged = info.isPlugged;
+ }
+};
+
+/**
+ * Error callback for battery start
+ */
+Battery.prototype._error = function(e) {
+ console.log("Error initializing Battery: " + e);
+};
+
+var battery = new Battery();
+
+module.exports = battery;
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/blackberry/DirectoryEntry.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/blackberry/DirectoryEntry.js b/lib0/plugin/blackberry/DirectoryEntry.js
new file mode 100644
index 0000000..76acaf7
--- /dev/null
+++ b/lib0/plugin/blackberry/DirectoryEntry.js
@@ -0,0 +1,239 @@
+var DirectoryEntry = require('cordova/plugin/DirectoryEntry'),
+ FileEntry = require('cordova/plugin/FileEntry'),
+ FileError = require('cordova/plugin/FileError'),
+ exec = require('cordova/exec');
+
+module.exports = {
+ /**
+ * Creates or looks up a directory; override for BlackBerry.
+ *
+ * @param path
+ * {DOMString} either a relative or absolute path from this
+ * directory in which to look up or create a directory
+ * @param options
+ * {Flags} options to create or exclusively create the directory
+ * @param successCallback
+ * {Function} called with the new DirectoryEntry
+ * @param errorCallback
+ * {Function} called with a FileError
+ */
+ getDirectory : function(path, options, successCallback, errorCallback) {
+ // create directory if it doesn't exist
+ var create = (options && options.create === true) ? true : false,
+ // if true, causes failure if create is true and path already exists
+ exclusive = (options && options.exclusive === true) ? true : false,
+ // directory exists
+ exists,
+ // create a new DirectoryEntry object and invoke success callback
+ createEntry = function() {
+ var path_parts = path.split('/'),
+ name = path_parts[path_parts.length - 1],
+ dirEntry = new DirectoryEntry(name, path);
+
+ // invoke success callback
+ if (typeof successCallback === 'function') {
+ successCallback(dirEntry);
+ }
+ };
+
+ var fail = function(error) {
+ if (typeof errorCallback === 'function') {
+ errorCallback(new FileError(error));
+ }
+ };
+
+ // determine if path is relative or absolute
+ if (!path) {
+ fail(FileError.ENCODING_ERR);
+ return;
+ } else if (path.indexOf(this.fullPath) !== 0) {
+ // path does not begin with the fullPath of this directory
+ // therefore, it is relative
+ path = this.fullPath + '/' + path;
+ }
+
+ // determine if directory exists
+ try {
+ // will return true if path exists AND is a directory
+ exists = blackberry.io.dir.exists(path);
+ } catch (e) {
+ // invalid path
+ fail(FileError.ENCODING_ERR);
+ return;
+ }
+
+ // path is a directory
+ if (exists) {
+ if (create && exclusive) {
+ // can't guarantee exclusivity
+ fail(FileError.PATH_EXISTS_ERR);
+ } else {
+ // create entry for existing directory
+ createEntry();
+ }
+ }
+ // will return true if path exists AND is a file
+ else if (blackberry.io.file.exists(path)) {
+ // the path is a file
+ fail(FileError.TYPE_MISMATCH_ERR);
+ }
+ // path does not exist, create it
+ else if (create) {
+ try {
+ // directory path must have trailing slash
+ var dirPath = path;
+ if (dirPath.substr(-1) !== '/') {
+ dirPath += '/';
+ }
+ blackberry.io.dir.createNewDir(dirPath);
+ createEntry();
+ } catch (eone) {
+ // unable to create directory
+ fail(FileError.NOT_FOUND_ERR);
+ }
+ }
+ // path does not exist, don't create
+ else {
+ // directory doesn't exist
+ fail(FileError.NOT_FOUND_ERR);
+ }
+ },
+ /**
+ * Create or look up a file.
+ *
+ * @param path {DOMString}
+ * either a relative or absolute path from this directory in
+ * which to look up or create a file
+ * @param options {Flags}
+ * options to create or exclusively create the file
+ * @param successCallback {Function}
+ * called with the new FileEntry object
+ * @param errorCallback {Function}
+ * called with a FileError object if error occurs
+ */
+ getFile:function(path, options, successCallback, errorCallback) {
+ // create file if it doesn't exist
+ var create = (options && options.create === true) ? true : false,
+ // if true, causes failure if create is true and path already exists
+ exclusive = (options && options.exclusive === true) ? true : false,
+ // file exists
+ exists,
+ // create a new FileEntry object and invoke success callback
+ createEntry = function() {
+ var path_parts = path.split('/'),
+ name = path_parts[path_parts.length - 1],
+ fileEntry = new FileEntry(name, path);
+
+ // invoke success callback
+ if (typeof successCallback === 'function') {
+ successCallback(fileEntry);
+ }
+ };
+
+ var fail = function(error) {
+ if (typeof errorCallback === 'function') {
+ errorCallback(new FileError(error));
+ }
+ };
+
+ // determine if path is relative or absolute
+ if (!path) {
+ fail(FileError.ENCODING_ERR);
+ return;
+ }
+ else if (path.indexOf(this.fullPath) !== 0) {
+ // path does not begin with the fullPath of this directory
+ // therefore, it is relative
+ path = this.fullPath + '/' + path;
+ }
+
+ // determine if file exists
+ try {
+ // will return true if path exists AND is a file
+ exists = blackberry.io.file.exists(path);
+ }
+ catch (e) {
+ // invalid path
+ fail(FileError.ENCODING_ERR);
+ return;
+ }
+
+ // path is a file
+ if (exists) {
+ if (create && exclusive) {
+ // can't guarantee exclusivity
+ fail(FileError.PATH_EXISTS_ERR);
+ }
+ else {
+ // create entry for existing file
+ createEntry();
+ }
+ }
+ // will return true if path exists AND is a directory
+ else if (blackberry.io.dir.exists(path)) {
+ // the path is a directory
+ fail(FileError.TYPE_MISMATCH_ERR);
+ }
+ // path does not exist, create it
+ else if (create) {
+ // create empty file
+ exec(
+ function(result) {
+ // file created
+ createEntry();
+ },
+ fail, "File", "write", [ path, "", 0 ]);
+ }
+ // path does not exist, don't create
+ else {
+ // file doesn't exist
+ fail(FileError.NOT_FOUND_ERR);
+ }
+ },
+
+ /**
+ * Delete a directory and all of it's contents.
+ *
+ * @param successCallback {Function} called with no parameters
+ * @param errorCallback {Function} called with a FileError
+ */
+ removeRecursively : function(successCallback, errorCallback) {
+ // we're removing THIS directory
+ var path = this.fullPath;
+
+ var fail = function(error) {
+ if (typeof errorCallback === 'function') {
+ errorCallback(new FileError(error));
+ }
+ };
+
+ // attempt to delete directory
+ if (blackberry.io.dir.exists(path)) {
+ // it is an error to attempt to remove the file system root
+ if (exec(null, null, "File", "isFileSystemRoot", [ path ]) === true) {
+ fail(FileError.NO_MODIFICATION_ALLOWED_ERR);
+ }
+ else {
+ try {
+ // delete the directory, setting recursive flag to true
+ blackberry.io.dir.deleteDirectory(path, true);
+ if (typeof successCallback === "function") {
+ successCallback();
+ }
+ } catch (e) {
+ // permissions don't allow deletion
+ console.log(e);
+ fail(FileError.NO_MODIFICATION_ALLOWED_ERR);
+ }
+ }
+ }
+ // it's a file, not a directory
+ else if (blackberry.io.file.exists(path)) {
+ fail(FileError.TYPE_MISMATCH_ERR);
+ }
+ // not found
+ else {
+ fail(FileError.NOT_FOUND_ERR);
+ }
+ }
+};
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/blackberry/Entry.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/blackberry/Entry.js b/lib0/plugin/blackberry/Entry.js
new file mode 100644
index 0000000..cc9626d
--- /dev/null
+++ b/lib0/plugin/blackberry/Entry.js
@@ -0,0 +1,87 @@
+var FileError = require('cordova/plugin/FileError'),
+ LocalFileSystem = require('cordova/plugin/LocalFileSystem'),
+ resolveLocalFileSystemURI = require('cordova/plugin/resolveLocalFileSystemURI'),
+ exec = require('cordova/exec');
+
+module.exports = {
+ remove : function(successCallback, errorCallback) {
+ var path = this.fullPath,
+ // directory contents
+ contents = [];
+
+ var fail = function(error) {
+ if (typeof errorCallback === 'function') {
+ errorCallback(new FileError(error));
+ }
+ };
+
+ // file
+ if (blackberry.io.file.exists(path)) {
+ try {
+ blackberry.io.file.deleteFile(path);
+ if (typeof successCallback === "function") {
+ successCallback();
+ }
+ } catch (e) {
+ // permissions don't allow
+ fail(FileError.INVALID_MODIFICATION_ERR);
+ }
+ }
+ // directory
+ else if (blackberry.io.dir.exists(path)) {
+ // it is an error to attempt to remove the file system root
+ if (exec(null, null, "File", "isFileSystemRoot", [ path ]) === true) {
+ fail(FileError.NO_MODIFICATION_ALLOWED_ERR);
+ } else {
+ // check to see if directory is empty
+ contents = blackberry.io.dir.listFiles(path);
+ if (contents.length !== 0) {
+ fail(FileError.INVALID_MODIFICATION_ERR);
+ } else {
+ try {
+ // delete
+ blackberry.io.dir.deleteDirectory(path, false);
+ if (typeof successCallback === "function") {
+ successCallback();
+ }
+ } catch (eone) {
+ // permissions don't allow
+ fail(FileError.NO_MODIFICATION_ALLOWED_ERR);
+ }
+ }
+ }
+ }
+ // not found
+ else {
+ fail(FileError.NOT_FOUND_ERR);
+ }
+ },
+ getParent : function(successCallback, errorCallback) {
+ var that = this;
+
+ try {
+ // On BlackBerry, the TEMPORARY file system is actually a temporary
+ // directory that is created on a per-application basis. This is
+ // to help ensure that applications do not share the same temporary
+ // space. So we check to see if this is the TEMPORARY file system
+ // (directory). If it is, we must return this Entry, rather than
+ // the Entry for its parent.
+ requestFileSystem(LocalFileSystem.TEMPORARY, 0,
+ function(fileSystem) {
+ if (fileSystem.root.fullPath === that.fullPath) {
+ if (typeof successCallback === 'function') {
+ successCallback(fileSystem.root);
+ }
+ } else {
+ resolveLocalFileSystemURI(blackberry.io.dir
+ .getParentDirectory(that.fullPath),
+ successCallback, errorCallback);
+ }
+ }, errorCallback);
+ } catch (e) {
+ if (typeof errorCallback === 'function') {
+ errorCallback(new FileError(FileError.NOT_FOUND_ERR));
+ }
+ }
+ }
+};
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/blackberry/app.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/blackberry/app.js b/lib0/plugin/blackberry/app.js
new file mode 100644
index 0000000..6c58e30
--- /dev/null
+++ b/lib0/plugin/blackberry/app.js
@@ -0,0 +1,51 @@
+var exec = require('cordova/exec');
+var manager = require('cordova/plugin/blackberry/manager');
+
+module.exports = {
+ /**
+ * Clear the resource cache.
+ */
+ clearCache:function() {
+ if (typeof blackberry.widgetcache === "undefined"
+ || blackberry.widgetcache === null) {
+ console.log("blackberry.widgetcache permission not found. Cache clear denied.");
+ return;
+ }
+ blackberry.widgetcache.clearAll();
+ },
+
+ /**
+ * Clear web history in this web view.
+ * Instead of BACK button loading the previous web page, it will exit the app.
+ */
+ clearHistory:function() {
+ exec(null, null, "App", "clearHistory", []);
+ },
+
+ /**
+ * Go to previous page displayed.
+ * This is the same as pressing the backbutton on Android device.
+ */
+ backHistory:function() {
+ // window.history.back() behaves oddly on BlackBerry, so use
+ // native implementation.
+ exec(null, null, "App", "backHistory", []);
+ },
+
+ /**
+ * Exit and terminate the application.
+ */
+ exitApp:function() {
+ // Call onunload if it is defined since BlackBerry does not invoke
+ // on application exit.
+ if (typeof window.onunload === "function") {
+ window.onunload();
+ }
+
+ // allow Cordova JavaScript Extension opportunity to cleanup
+ manager.destroy();
+
+ // exit the app
+ blackberry.app.exit();
+ }
+};
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/blackberry/device.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/blackberry/device.js b/lib0/plugin/blackberry/device.js
new file mode 100644
index 0000000..42a0647
--- /dev/null
+++ b/lib0/plugin/blackberry/device.js
@@ -0,0 +1,23 @@
+var me = {},
+ channel = require('cordova/channel'),
+ exec = require('cordova/exec');
+
+exec(
+ function (device) {
+ me.platform = device.platform;
+ me.version = device.version;
+ me.name = device.name;
+ me.uuid = device.uuid;
+ me.cordova = device.cordova;
+
+ channel.onCordovaInfoReady.fire();
+ },
+ function (e) {
+ console.log("error initializing cordova: " + e);
+ },
+ "Device",
+ "getDeviceInfo",
+ []
+);
+
+module.exports = me;
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/blackberry/manager.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/blackberry/manager.js b/lib0/plugin/blackberry/manager.js
new file mode 100644
index 0000000..ef353bb
--- /dev/null
+++ b/lib0/plugin/blackberry/manager.js
@@ -0,0 +1,87 @@
+var webworks = require('cordova/plugin/webworks/manager'),
+ Cordova = require('cordova'),
+ plugins = {};
+
+function _exec(win, fail, clazz, action, args) {
+ var callbackId = clazz + Cordova.callbackId++,
+ origResult,
+ evalResult,
+ execResult;
+
+ try {
+
+ if (win || fail) {
+ Cordova.callbacks[callbackId] = {success: win, fail: fail};
+ }
+
+ // Note: Device returns string, but for some reason emulator returns object - so convert to string.
+ origResult = "" + org.apache.cordova.JavaPluginManager.exec(clazz, action, callbackId, JSON.stringify(args), true);
+
+ // If a result was returned
+ if (origResult.length > 0) {
+ eval("evalResult = " + origResult + ";");
+
+ // If status is OK, then return evalResultalue back to caller
+ if (evalResult.status === Cordova.callbackStatus.OK) {
+
+ // If there is a success callback, then call it now with returned evalResultalue
+ if (win) {
+ // Clear callback if not expecting any more results
+ if (!evalResult.keepCallback) {
+ delete Cordova.callbacks[callbackId];
+ }
+ }
+ } else if (evalResult.status === Cordova.callbackStatus.NO_RESULT) {
+
+ // Clear callback if not expecting any more results
+ if (!evalResult.keepCallback) {
+ delete Cordova.callbacks[callbackId];
+ }
+ } else {
+ // If there is a fail callback, then call it now with returned evalResultalue
+ if (fail) {
+
+ // Clear callback if not expecting any more results
+ if (!evalResult.keepCallback) {
+ delete Cordova.callbacks[callbackId];
+ }
+ }
+ }
+ execResult = evalResult;
+ } else {
+ // Asynchronous calls return an empty string. Return a NO_RESULT
+ // status for those executions.
+ execResult = {"status" : Cordova.callbackStatus.NO_RESULT,
+ "message" : ""};
+ }
+ } catch (e) {
+ console.log("BlackBerryPluginManager Error: " + e);
+ execResult = {"status" : Cordova.callbackStatus.ERROR,
+ "message" : e.message};
+ }
+
+ return execResult;
+}
+
+module.exports = {
+ exec: function (win, fail, clazz, action, args) {
+ var result = webworks.exec(win, fail, clazz, action, args);
+
+ //We got a sync result or a not found from WW that we can pass on to get a native mixin
+ //For async calls there's nothing to do
+ if (result.status === Cordova.callbackStatus.CLASS_NOT_FOUND_EXCEPTION ||
+ result.status === Cordova.callbackStatus.INVALID_ACTION ||
+ result.status === Cordova.callbackStatus.OK) {
+ if (plugins[clazz]) {
+ return plugins[clazz].execute(result.message, action, args, win, fail);
+ } else {
+ result = _exec(win, fail, clazz, action, args);
+ }
+ }
+
+ return result;
+ },
+ resume: org.apache.cordova.JavaPluginManager.resume,
+ pause: org.apache.cordova.JavaPluginManager.pause,
+ destroy: org.apache.cordova.JavaPluginManager.destroy
+};
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/blackberry/notification.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/blackberry/notification.js b/lib0/plugin/blackberry/notification.js
new file mode 100644
index 0000000..83bc77c
--- /dev/null
+++ b/lib0/plugin/blackberry/notification.js
@@ -0,0 +1,53 @@
+var exec = require('cordova/exec');
+
+/**
+ * Provides BlackBerry enhanced notification API.
+ */
+module.exports = {
+ activityStart : function(title, message) {
+ // If title and message not specified then mimic Android behavior of
+ // using default strings.
+ if (typeof title === "undefined" && typeof message == "undefined") {
+ title = "Busy";
+ message = 'Please wait...';
+ }
+
+ exec(null, null, 'Notification', 'activityStart', [ title, message ]);
+ },
+
+ /**
+ * Close an activity dialog
+ */
+ activityStop : function() {
+ exec(null, null, 'Notification', 'activityStop', []);
+ },
+
+ /**
+ * Display a progress dialog with progress bar that goes from 0 to 100.
+ *
+ * @param {String}
+ * title Title of the progress dialog.
+ * @param {String}
+ * message Message to display in the dialog.
+ */
+ progressStart : function(title, message) {
+ exec(null, null, 'Notification', 'progressStart', [ title, message ]);
+ },
+
+ /**
+ * Close the progress dialog.
+ */
+ progressStop : function() {
+ exec(null, null, 'Notification', 'progressStop', []);
+ },
+
+ /**
+ * Set the progress dialog value.
+ *
+ * @param {Number}
+ * value 0-100
+ */
+ progressValue : function(value) {
+ exec(null, null, 'Notification', 'progressValue', [ value ]);
+ },
+};
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/capture.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/capture.js b/lib0/plugin/capture.js
new file mode 100644
index 0000000..e088ba6
--- /dev/null
+++ b/lib0/plugin/capture.js
@@ -0,0 +1,72 @@
+var exec = require('cordova/exec'),
+ MediaFile = require('cordova/plugin/MediaFile');
+
+/**
+ * Launches a capture of different types.
+ *
+ * @param (DOMString} type
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureVideoOptions} options
+ */
+function _capture(type, successCallback, errorCallback, options) {
+ var win = function(pluginResult) {
+ var mediaFiles = [];
+ var i;
+ for (i = 0; i < pluginResult.length; i++) {
+ var mediaFile = new MediaFile();
+ mediaFile.name = pluginResult[i].name;
+ mediaFile.fullPath = pluginResult[i].fullPath;
+ mediaFile.type = pluginResult[i].type;
+ mediaFile.lastModifiedDate = pluginResult[i].lastModifiedDate;
+ mediaFile.size = pluginResult[i].size;
+ mediaFiles.push(mediaFile);
+ }
+ successCallback(mediaFiles);
+ };
+ exec(win, errorCallback, "Capture", type, [options]);
+}
+/**
+ * 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
+ */
+Capture.prototype.captureAudio = function(successCallback, errorCallback, options){
+ _capture("captureAudio", successCallback, errorCallback, options);
+};
+
+/**
+ * Launch camera application for taking image(s).
+ *
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureImageOptions} options
+ */
+Capture.prototype.captureImage = function(successCallback, errorCallback, options){
+ _capture("captureImage", successCallback, errorCallback, 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){
+ _capture("captureVideo", successCallback, errorCallback, options);
+};
+
+
+module.exports = new Capture();
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/compass.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/compass.js b/lib0/plugin/compass.js
new file mode 100644
index 0000000..1685f2d
--- /dev/null
+++ b/lib0/plugin/compass.js
@@ -0,0 +1,90 @@
+var exec = require('cordova/exec'),
+ utils = require('cordova/utils'),
+ CompassHeading = require('cordova/plugin/CompassHeading'),
+ CompassError = require('cordova/plugin/CompassError'),
+ timers = {},
+ compass = {
+ /**
+ * Asynchronously acquires 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.
+ * @param {CompassOptions} options The options for getting the heading data (not used).
+ */
+ getCurrentHeading:function(successCallback, errorCallback) {
+ // 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;
+ }
+
+ var win = function(result) {
+ var ch = new CompassHeading(result.magneticHeading, result.trueHeading, result.headingAccuracy, result.timestamp);
+ successCallback(ch);
+ };
+ var fail = function(code) {
+ var ce = new CompassError(code);
+ errorCallback(ce);
+ }
+
+ // Get heading
+ exec(win, fail, "Compass", "getHeading", []);
+ },
+
+ /**
+ * Asynchronously acquires 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.
+ * @param {HeadingOptions} options The options for getting the heading data
+ * such as timeout and the frequency of the watch.
+ */
+ watchHeading:function(successCallback, errorCallback, options) {
+ // Default interval (100 msec)
+ var frequency = (options !== undefined && options.frequency !== undefined) ? options.frequency : 100;
+
+ // successCallback required
+ if (typeof successCallback !== "function") {
+ console.log("Compass Error: successCallback is not a function");
+ return;
+ }
+
+ // errorCallback optional
+ if (errorCallback && (typeof errorCallback !== "function")) {
+ console.log("Compass Error: errorCallback is not a function");
+ return;
+ }
+
+ // Start watch timer to get headings
+ var id = utils.createUUID();
+
+ timers[id] = window.setInterval(function() {
+ compass.getCurrentHeading(successCallback, errorCallback);
+ }, frequency);
+
+ return id;
+ },
+
+ /**
+ * Clears the specified heading watch.
+ * @param {String} watchId The ID of the watch returned from #watchHeading.
+ */
+ clearWatch:function(id) {
+ // Stop javascript timer & remove from timer list
+ if (id && timers[id]) {
+ clearInterval(timers[id]);
+ delete timers[id];
+ }
+ }
+ // TODO: add the filter-based iOS-only methods
+ };
+
+module.exports = compass;
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/contacts.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/contacts.js b/lib0/plugin/contacts.js
new file mode 100644
index 0000000..7212f7b
--- /dev/null
+++ b/lib0/plugin/contacts.js
@@ -0,0 +1,57 @@
+var exec = require('cordova/exec'),
+ ContactError = require('cordova/plugin/ContactError'),
+ Contact = require('cordova/plugin/Contact');
+
+/**
+* Represents a group of Contacts.
+* @constructor
+*/
+var contacts = {
+ /**
+ * Returns an array of Contacts matching the search criteria.
+ * @param fields that should be searched
+ * @param successCB success callback
+ * @param errorCB error callback
+ * @param {ContactFindOptions} options that can be applied to contact searching
+ * @return array of Contacts matching search criteria
+ */
+ find:function(fields, successCB, errorCB, options) {
+ if (!successCB) {
+ throw new TypeError("You must specify a success callback for the find command.");
+ }
+ if (!fields || (fields instanceof Array && fields.length === 0)) {
+ if (typeof errorCB === "function") {
+ errorCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR));
+ }
+ } else {
+ var win = function(result) {
+ var cs = [];
+ for (var i = 0, l = result.length; i < l; i++) {
+ cs.push(contacts.create(result[i]));
+ }
+ successCB(cs);
+ };
+ exec(win, errorCB, "Contacts", "search", [fields, options]);
+ }
+ },
+
+ /**
+ * This function creates a new contact, but it does not persist the contact
+ * to device storage. To persist the contact to device storage, invoke
+ * contact.save().
+ * @param properties an object who's properties will be examined to create a new Contact
+ * @returns new Contact object
+ */
+ create:function(properties) {
+ var i;
+ var contact = new Contact();
+ for (i in properties) {
+ if (typeof contact[i] !== 'undefined' && properties.hasOwnProperty(i)) {
+ contact[i] = properties[i];
+ }
+ }
+ return contact;
+ }
+};
+
+module.exports = contacts;
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/errgen/device.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/errgen/device.js b/lib0/plugin/errgen/device.js
new file mode 100644
index 0000000..4e05777
--- /dev/null
+++ b/lib0/plugin/errgen/device.js
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * this represents the mobile device, and provides properties for inspecting the model, version, UUID of the
+ * phone, etc.
+ * @constructor
+ */
+
+//------------------------------------------------------------------------------
+function Device() {
+ window.DeviceInfo = {}
+
+ this.platform = "errgen"
+ this.version = "any"
+ this.name = "errgen"
+ this.phonegap = {}
+ this.gap = this.phonegap
+ this.uuid = "1234-5678-9012-3456"
+ this.available = true
+
+ require('cordova/channel').onCordovaInfoReady.fire()
+}
+
+//------------------------------------------------------------------------------
+module.exports = window.DeviceInfo = new Device()
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/geolocation.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/geolocation.js b/lib0/plugin/geolocation.js
new file mode 100644
index 0000000..e1169f6
--- /dev/null
+++ b/lib0/plugin/geolocation.js
@@ -0,0 +1,94 @@
+var utils = require('cordova/utils'),
+ exec = require('cordova/exec'),
+ PositionError = require('cordova/plugin/PositionError'),
+ Position = require('cordova/plugin/Position');
+
+var timers = {}; // list of timers in use
+
+// Returns default params, overrides if provided with values
+function parseParameters(options) {
+ var opt = {
+ maximumAge: 10000,
+ enableHighAccuracy: false,
+ timeout: 10000
+ };
+
+ if (options) {
+ if (options.maximumAge !== undefined) {
+ opt.maximumAge = options.maximumAge;
+ }
+ if (options.enableHighAccuracy !== undefined) {
+ opt.enableHighAccuracy = options.enableHighAccuracy;
+ }
+ if (options.timeout !== undefined) {
+ opt.timeout = options.timeout;
+ }
+ }
+
+ return opt;
+}
+
+var geolocation = {
+ /**
+ * Asynchronously aquires the current position.
+ *
+ * @param {Function} successCallback The function to call when the position data is available
+ * @param {Function} errorCallback The function to call when there is an error getting the heading position. (OPTIONAL)
+ * @param {PositionOptions} options The options for getting the position data. (OPTIONAL)
+ */
+ getCurrentPosition:function(successCallback, errorCallback, options) {
+ options = parseParameters(options);
+
+ var win = function(p) {
+ successCallback(new Position(
+ {
+ latitude:p.latitude,
+ longitude:p.longitude,
+ altitude:p.altitude,
+ accuracy:p.accuracy,
+ heading:p.heading,
+ velocity:p.velocity,
+ altitudeAccuracy:p.altitudeAccuracy
+ },
+ p.timestamp || new Date()
+ ));
+ };
+ var fail = function(e) {
+ errorCallback(new PositionError(e.code, e.message));
+ };
+
+ exec(win, fail, "Geolocation", "getLocation", [options.enableHighAccuracy, options.timeout, options.maximumAge]);
+ },
+ /**
+ * Asynchronously watches the geolocation for changes to geolocation. When a change occurs,
+ * the successCallback is called with the new location.
+ *
+ * @param {Function} successCallback The function to call each time the location data is available
+ * @param {Function} errorCallback The function to call when there is an error getting the location data. (OPTIONAL)
+ * @param {PositionOptions} options The options for getting the location data such as frequency. (OPTIONAL)
+ * @return String The watch id that must be passed to #clearWatch to stop watching.
+ */
+ watchPosition:function(successCallback, errorCallback, options) {
+ options = parseParameters(options);
+
+ var id = utils.createUUID();
+ timers[id] = window.setInterval(function() {
+ geolocation.getCurrentPosition(successCallback, errorCallback, options);
+ }, options.timeout);
+
+ return id;
+ },
+ /**
+ * Clears the specified heading watch.
+ *
+ * @param {String} id The ID of the watch returned from #watchPosition
+ */
+ clearWatch:function(id) {
+ if (id && timers[id] !== undefined) {
+ window.clearInterval(timers[id]);
+ delete timers[id];
+ }
+ }
+};
+
+module.exports = geolocation;
http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/76f64673/lib0/plugin/ios/Entry.js
----------------------------------------------------------------------
diff --git a/lib0/plugin/ios/Entry.js b/lib0/plugin/ios/Entry.js
new file mode 100644
index 0000000..230da8a
--- /dev/null
+++ b/lib0/plugin/ios/Entry.js
@@ -0,0 +1,7 @@
+module.exports = {
+ toURL:function() {
+ // TODO: refactor path in a cross-platform way so we can eliminate
+ // these kinds of platform-specific hacks.
+ return "file://localhost" + this.fullPath;
+ }
+}