You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ti...@apache.org on 2012/08/25 01:13:45 UTC

webworks commit: 2.1.0rc1

Updated Branches:
  refs/heads/master 724ee4d74 -> ad39f54d4


2.1.0rc1


Project: http://git-wip-us.apache.org/repos/asf/incubator-cordova-blackberry-webworks/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cordova-blackberry-webworks/commit/ad39f54d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-blackberry-webworks/tree/ad39f54d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-blackberry-webworks/diff/ad39f54d

Branch: refs/heads/master
Commit: ad39f54d4bafce60dc3117f91462f79334b95cc9
Parents: 724ee4d
Author: Tim Kim <ti...@nitobi.com>
Authored: Fri Aug 24 16:13:34 2012 -0700
Committer: Tim Kim <ti...@nitobi.com>
Committed: Fri Aug 24 16:13:34 2012 -0700

----------------------------------------------------------------------
 VERSION                                            |    2 +-
 bin/templates/project/www/index.html               |    2 +-
 .../ext/src/org/apache/cordova/device/Device.java  |    2 +-
 javascript/cordova.blackberry.js                   |   77 +++++++-------
 javascript/cordova.playbook.js                     |   83 ++++++++-------
 javascript/cordova.qnx.js                          |   71 ++++++------
 6 files changed, 120 insertions(+), 117 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cordova-blackberry-webworks/blob/ad39f54d/VERSION
----------------------------------------------------------------------
diff --git a/VERSION b/VERSION
index 227cea2..0c271bc 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.0.0
+2.1.0rc1

http://git-wip-us.apache.org/repos/asf/incubator-cordova-blackberry-webworks/blob/ad39f54d/bin/templates/project/www/index.html
----------------------------------------------------------------------
diff --git a/bin/templates/project/www/index.html b/bin/templates/project/www/index.html
index d538be6..a9648b9 100644
--- a/bin/templates/project/www/index.html
+++ b/bin/templates/project/www/index.html
@@ -34,7 +34,7 @@
             </div>
         </div>
         <script type="text/javascript" src="js/webworks-1.0.1.8.js"></script>
-        <script type="text/javascript" src="cordova-2.0.0.js"></script>
+        <script type="text/javascript" src="cordova-2.1.0rc1.js"></script>
         <script type="text/javascript" src="js/index.js"></script>
         <script type="text/javascript">
             app.initialize();

http://git-wip-us.apache.org/repos/asf/incubator-cordova-blackberry-webworks/blob/ad39f54d/framework/ext/src/org/apache/cordova/device/Device.java
----------------------------------------------------------------------
diff --git a/framework/ext/src/org/apache/cordova/device/Device.java b/framework/ext/src/org/apache/cordova/device/Device.java
index c84acbb..cef7011 100644
--- a/framework/ext/src/org/apache/cordova/device/Device.java
+++ b/framework/ext/src/org/apache/cordova/device/Device.java
@@ -53,7 +53,7 @@ public final class Device extends Plugin {
 				JSONObject device = new JSONObject();
 				device.put( FIELD_PLATFORM, new String(DeviceInfo.getPlatformVersion() ) );
 				device.put( FIELD_UUID, new Integer( DeviceInfo.getDeviceId()) );
-				device.put( FIELD_CORDOVA, "2.0.0" );
+				device.put( FIELD_CORDOVA, "2.1.0rc1" );
 				device.put( FIELD_NAME, new String(DeviceInfo.getDeviceName()) );
 				device.put( FIELD_VERSION, new String(DeviceInfo.getSoftwareVersion()) );
 				result = new PluginResult(PluginResult.Status.OK, device);

http://git-wip-us.apache.org/repos/asf/incubator-cordova-blackberry-webworks/blob/ad39f54d/javascript/cordova.blackberry.js
----------------------------------------------------------------------
diff --git a/javascript/cordova.blackberry.js b/javascript/cordova.blackberry.js
index 7f4579f..291fcf8 100644
--- a/javascript/cordova.blackberry.js
+++ b/javascript/cordova.blackberry.js
@@ -1,6 +1,6 @@
-// commit b58d6387cacaae999dc83778f794cf5900ae8dfe
+// commit 69d652e9dcaaaf4bdaa55ec37329636dd5b20fbe
 
-// File generated at :: Thu Aug 23 2012 17:49:07 GMT-0700 (PDT)
+// File generated at :: Fri Aug 24 2012 16:02:13 GMT-0700 (PDT)
 
 /*
  Licensed to the Apache Software Foundation (ASF) under one
@@ -418,7 +418,8 @@ module.exports = {
 
 // file: lib/common/channel.js
 define("cordova/channel", function(require, exports, module) {
-var utils = require('cordova/utils');
+var utils = require('cordova/utils'),
+    nextGuid = 1;
 
 /**
  * Custom pub-sub "channel" that can have functions subscribed to it
@@ -470,7 +471,6 @@ var Channel = function(type, opts) {
     this.type = type;
     this.handlers = {};
     this.numHandlers = 0;
-    this.guid = 1;
     this.fired = false;
     this.enabled = true;
     this.events = {
@@ -563,19 +563,19 @@ Channel.prototype.subscribe = function(f, c, g) {
 
     g = g || func.observer_guid || f.observer_guid;
     if (!g) {
-        // first time we've seen this subscriber
-        g = this.guid++;
-    }
-    else {
-        // subscriber already handled; dont set it twice
-        return g;
+        // first time any channel has seen this subscriber
+        g = nextGuid++;
     }
     func.observer_guid = g;
     f.observer_guid = g;
-    this.handlers[g] = func;
-    this.numHandlers++;
-    if (this.events.onSubscribe) this.events.onSubscribe.call(this);
-    if (this.fired) func.call(this);
+
+    // Don't add the same handler more than once.
+    if (!this.handlers[g]) {
+        this.handlers[g] = func;
+        this.numHandlers++;
+        if (this.events.onSubscribe) this.events.onSubscribe.call(this);
+        if (this.fired) func.apply(this, this.fireArgs);
+    }
     return g;
 };
 
@@ -589,15 +589,14 @@ Channel.prototype.subscribeOnce = function(f, c) {
 
     var g = null;
     var _this = this;
-    var m = function() {
-        f.apply(c || null, arguments);
-        _this.unsubscribe(g);
-    };
     if (this.fired) {
-        if (typeof c == "object") { f = utils.close(c, f); }
-        f.apply(this, this.fireArgs);
+        f.apply(c || null, this.fireArgs);
     } else {
-        g = this.subscribe(m);
+        g = this.subscribe(function() {
+            _this.unsubscribe(g);
+            f.apply(c || null, arguments);
+        });
+        f.observer_guid = g;
     }
     return g;
 };
@@ -613,7 +612,6 @@ Channel.prototype.unsubscribe = function(g) {
     var handler = this.handlers[g];
     if (handler) {
         if (handler.observer_guid) handler.observer_guid=null;
-        this.handlers[g] = null;
         delete this.handlers[g];
         this.numHandlers--;
         if (this.events.onUnsubscribe) this.events.onUnsubscribe.call(this);
@@ -627,14 +625,17 @@ Channel.prototype.fire = function(e) {
     if (this.enabled) {
         var fail = false;
         this.fired = true;
+        this.fireArgs = arguments;
+        // Copy the values first so that it is safe to modify it from within
+        // callbacks.
+        var toCall = [];
         for (var item in this.handlers) {
-            var handler = this.handlers[item];
-            if (typeof handler == 'function') {
-                var rv = (handler.apply(this, arguments)===false);
-                fail = fail || rv;
-            }
+            toCall.push(this.handlers[item]);
+        }
+        for (var i = 0; i < toCall.length; ++i) {
+            var rv = (toCall[i].apply(this, arguments)===false);
+            fail = fail || rv;
         }
-        this.fireArgs = arguments;
         return !fail;
     }
     return true;
@@ -898,7 +899,7 @@ var manager = require('cordova/plugin/manager'),
  * Execute a cordova command.  It is up to the native side whether this action
  * is synchronous or asynchronous.  The native side can return:
  *      Synchronous: PluginResult object as a JSON string
- *      Asynchrounous: Empty string ""
+ *      Asynchronous: Empty string ""
  * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
  * depending upon the result of the action.
  *
@@ -1001,7 +1002,7 @@ module.exports = {
         var eventHandler = function(event) {
             return { onSubscribe : function() {
                 // If we just attached the first handler, let native know we
-                // need to override the back button.
+                // need to override the hardware button.
                 if (this.numHandlers === 1) {
                     blackberry.system.event.onHardwareKey(
                             buttonMapping[event], fireEvent(event));
@@ -1009,7 +1010,7 @@ module.exports = {
             },
             onUnsubscribe : function() {
                 // If we just detached the last handler, let native know we
-                // no longer override the back button.
+                // no longer override the hardware button.
                 if (this.numHandlers === 0) {
                     blackberry.system.event.onHardwareKey(
                             buttonMapping[event], null);
@@ -2899,7 +2900,7 @@ FileWriter.prototype.seek = function(offset) {
     if (offset < 0) {
         this.position = Math.max(offset + this.length, 0);
     }
-    // Offset is bigger then file size so set position
+    // Offset is bigger than file size so set position
     // to the end of the file.
     else if (offset > this.length) {
         this.position = this.length;
@@ -3526,7 +3527,7 @@ var accelerometer = {
 
         if (running) {
             // If we're already running then immediately invoke the success callback
-            // but only if we have retreived a value, sample code does not check for null ...
+            // but only if we have retrieved a value, sample code does not check for null ...
             if(accel) {
                 successCallback(accel);
             }
@@ -4044,7 +4045,7 @@ var contacts = {
      * 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
+     * @param properties an object whose properties will be examined to create a new Contact
      * @returns new Contact object
      */
     create:function(properties) {
@@ -4258,7 +4259,7 @@ var geolocation = {
         } else if (options.timeout === 0) {
             fail({
                 code:PositionError.TIMEOUT,
-                message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceed's provided PositionOptions' maximumAge parameter."
+                message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceeds provided PositionOptions' maximumAge parameter."
             });
         // Otherwise we have to call into native to retrieve a position.
         } else {
@@ -5444,7 +5445,7 @@ module.exports = {
 define("cordova/plugin/java/MediaError", function(require, exports, module) {
 
 // The MediaError object exists on BB OS 6+ which prevents the Cordova version
-// being defined. This object is used to merge in differences between the BB
+// from being defined. This object is used to merge in differences between the BB
 // MediaError object and the Cordova version.
 module.exports = {
         MEDIA_ERR_NONE_ACTIVE : 0,
@@ -5463,7 +5464,7 @@ module.exports = {
    */
   clearCache:function() {
       if (typeof blackberry.widgetcache === "undefined" || blackberry.widgetcache === null) {
-          console.log("blackberry.widgetcache permission not found. Cache clear denied.");
+          console.log("blackberry.widgetcache permission not found. Cache clear request denied.");
           return;
       }
       blackberry.widgetcache.clearAll();
@@ -5706,7 +5707,7 @@ CurrentLevel = LevelsMap.WARN;
  *
  * The value used determines which messages get printed.  The logging
  * values above are in order, and only messages logged at the logging
- * level or above will actually be displayed to the user.  Eg, the
+ * level or above will actually be displayed to the user.  E.g., the
  * default level is WARN, so only messages logged with LOG, ERROR, or
  * WARN will be displayed; INFO and DEBUG messages will be ignored.
  */

http://git-wip-us.apache.org/repos/asf/incubator-cordova-blackberry-webworks/blob/ad39f54d/javascript/cordova.playbook.js
----------------------------------------------------------------------
diff --git a/javascript/cordova.playbook.js b/javascript/cordova.playbook.js
index f9455dc..a76010a 100644
--- a/javascript/cordova.playbook.js
+++ b/javascript/cordova.playbook.js
@@ -1,6 +1,6 @@
-// commit b58d6387cacaae999dc83778f794cf5900ae8dfe
+// commit 69d652e9dcaaaf4bdaa55ec37329636dd5b20fbe
 
-// File generated at :: Thu Aug 23 2012 17:49:07 GMT-0700 (PDT)
+// File generated at :: Fri Aug 24 2012 16:02:13 GMT-0700 (PDT)
 
 /*
  Licensed to the Apache Software Foundation (ASF) under one
@@ -418,7 +418,8 @@ module.exports = {
 
 // file: lib/common/channel.js
 define("cordova/channel", function(require, exports, module) {
-var utils = require('cordova/utils');
+var utils = require('cordova/utils'),
+    nextGuid = 1;
 
 /**
  * Custom pub-sub "channel" that can have functions subscribed to it
@@ -470,7 +471,6 @@ var Channel = function(type, opts) {
     this.type = type;
     this.handlers = {};
     this.numHandlers = 0;
-    this.guid = 1;
     this.fired = false;
     this.enabled = true;
     this.events = {
@@ -563,19 +563,19 @@ Channel.prototype.subscribe = function(f, c, g) {
 
     g = g || func.observer_guid || f.observer_guid;
     if (!g) {
-        // first time we've seen this subscriber
-        g = this.guid++;
-    }
-    else {
-        // subscriber already handled; dont set it twice
-        return g;
+        // first time any channel has seen this subscriber
+        g = nextGuid++;
     }
     func.observer_guid = g;
     f.observer_guid = g;
-    this.handlers[g] = func;
-    this.numHandlers++;
-    if (this.events.onSubscribe) this.events.onSubscribe.call(this);
-    if (this.fired) func.call(this);
+
+    // Don't add the same handler more than once.
+    if (!this.handlers[g]) {
+        this.handlers[g] = func;
+        this.numHandlers++;
+        if (this.events.onSubscribe) this.events.onSubscribe.call(this);
+        if (this.fired) func.apply(this, this.fireArgs);
+    }
     return g;
 };
 
@@ -589,15 +589,14 @@ Channel.prototype.subscribeOnce = function(f, c) {
 
     var g = null;
     var _this = this;
-    var m = function() {
-        f.apply(c || null, arguments);
-        _this.unsubscribe(g);
-    };
     if (this.fired) {
-        if (typeof c == "object") { f = utils.close(c, f); }
-        f.apply(this, this.fireArgs);
+        f.apply(c || null, this.fireArgs);
     } else {
-        g = this.subscribe(m);
+        g = this.subscribe(function() {
+            _this.unsubscribe(g);
+            f.apply(c || null, arguments);
+        });
+        f.observer_guid = g;
     }
     return g;
 };
@@ -613,7 +612,6 @@ Channel.prototype.unsubscribe = function(g) {
     var handler = this.handlers[g];
     if (handler) {
         if (handler.observer_guid) handler.observer_guid=null;
-        this.handlers[g] = null;
         delete this.handlers[g];
         this.numHandlers--;
         if (this.events.onUnsubscribe) this.events.onUnsubscribe.call(this);
@@ -627,14 +625,17 @@ Channel.prototype.fire = function(e) {
     if (this.enabled) {
         var fail = false;
         this.fired = true;
+        this.fireArgs = arguments;
+        // Copy the values first so that it is safe to modify it from within
+        // callbacks.
+        var toCall = [];
         for (var item in this.handlers) {
-            var handler = this.handlers[item];
-            if (typeof handler == 'function') {
-                var rv = (handler.apply(this, arguments)===false);
-                fail = fail || rv;
-            }
+            toCall.push(this.handlers[item]);
+        }
+        for (var i = 0; i < toCall.length; ++i) {
+            var rv = (toCall[i].apply(this, arguments)===false);
+            fail = fail || rv;
         }
-        this.fireArgs = arguments;
         return !fail;
     }
     return true;
@@ -898,7 +899,7 @@ var manager = require('cordova/plugin/manager'),
  * Execute a cordova command.  It is up to the native side whether this action
  * is synchronous or asynchronous.  The native side can return:
  *      Synchronous: PluginResult object as a JSON string
- *      Asynchrounous: Empty string ""
+ *      Asynchronous: Empty string ""
  * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
  * depending upon the result of the action.
  *
@@ -2758,7 +2759,7 @@ FileWriter.prototype.seek = function(offset) {
     if (offset < 0) {
         this.position = Math.max(offset + this.length, 0);
     }
-    // Offset is bigger then file size so set position
+    // Offset is bigger than file size so set position
     // to the end of the file.
     else if (offset > this.length) {
         this.position = this.length;
@@ -3385,7 +3386,7 @@ var accelerometer = {
 
         if (running) {
             // If we're already running then immediately invoke the success callback
-            // but only if we have retreived a value, sample code does not check for null ...
+            // but only if we have retrieved a value, sample code does not check for null ...
             if(accel) {
                 successCallback(accel);
             }
@@ -3802,7 +3803,7 @@ module.exports = {
     },
 
     setMetadata : function(successCallback, errorCallback , metadataObject){
-        console.log('setMetadata is unsupported for playbook');
+        console.log('setMetadata is unsupported for PlayBook');
     },
 
     moveTo : function(parent, newName, successCallback, errorCallback){
@@ -4445,7 +4446,7 @@ module.exports = FileReader;
 // file: lib/webworks/air/plugin/air/FileTransfer.js
 define("cordova/plugin/air/FileTransfer", function(require, exports, module) {
 var cordova = require('cordova'),
-resolveLocalFileSystemURI = require('cordova/plugin/playbook/resolveLocalFileSystemURI'),
+resolveLocalFileSystemURI = require('cordova/plugin/air/resolveLocalFileSystemURI'),
 FileTransferError = require('cordova/plugin/FileTransferError'),
 FileUploadResult = require('cordova/plugin/FileUploadResult'),
 FileEntry = require('cordova/plugin/FileEntry');
@@ -4751,7 +4752,7 @@ FileWriter.prototype.seek = function(offset) {
     if (offset < 0) {
         this.position = Math.max(offset + this.length, 0);
     }
-    // Offset is bigger then file size so set position
+    // Offset is bigger than file size so set position
     // to the end of the file.
     else if (offset > this.length) {
         this.position = this.length;
@@ -4846,7 +4847,7 @@ var cordova = require('cordova');
 
 module.exports = {
     start: function (args, win, fail) {
-        // Register one listener to each of level and state change
+        // Register one listener to each of the level and state change
         // events using WebWorks API.
         blackberry.system.event.deviceBatteryStateChange(function(state) {
             var me = navigator.battery;
@@ -5018,13 +5019,14 @@ module.exports = {
             version: blackberry.system.softwareVersion,
             name: blackberry.system.model,
             uuid: blackberry.identity.PIN,
-            cordova: "2.0.0"
+            cordova: "2.1.0rc1"
         });
 
         return { "status" : cordova.callbackStatus.NO_RESULT, "message" : "Device info returned" };
     }
 
 };
+
 });
 
 // file: lib/webworks/air/plugin/air/network.js
@@ -5703,7 +5705,7 @@ var contacts = {
      * 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
+     * @param properties an object whose properties will be examined to create a new Contact
      * @returns new Contact object
      */
     create:function(properties) {
@@ -5917,7 +5919,7 @@ var geolocation = {
         } else if (options.timeout === 0) {
             fail({
                 code:PositionError.TIMEOUT,
-                message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceed's provided PositionOptions' maximumAge parameter."
+                message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceeds provided PositionOptions' maximumAge parameter."
             });
         // Otherwise we have to call into native to retrieve a position.
         } else {
@@ -6081,7 +6083,7 @@ CurrentLevel = LevelsMap.WARN;
  *
  * The value used determines which messages get printed.  The logging
  * values above are in order, and only messages logged at the logging
- * level or above will actually be displayed to the user.  Eg, the
+ * level or above will actually be displayed to the user.  E.g., the
  * default level is WARN, so only messages logged with LOG, ERROR, or
  * WARN will be displayed; INFO and DEBUG messages will be ignored.
  */
@@ -6246,8 +6248,7 @@ var cordova = require('cordova'),
         'Capture' : require('cordova/plugin/air/capture'),
         'Accelerometer' : require('cordova/plugin/webworks/accelerometer'),
         'NetworkStatus' : require('cordova/plugin/air/network'),
-        'Notification' : require('cordova/plugin/webworks/notification'),
-        'FileTransfer' : require('cordova/plugin/air/FileTransfer')
+        'Notification' : require('cordova/plugin/webworks/notification')
     };
 
 module.exports = {

http://git-wip-us.apache.org/repos/asf/incubator-cordova-blackberry-webworks/blob/ad39f54d/javascript/cordova.qnx.js
----------------------------------------------------------------------
diff --git a/javascript/cordova.qnx.js b/javascript/cordova.qnx.js
index cf96df5..46f7f33 100644
--- a/javascript/cordova.qnx.js
+++ b/javascript/cordova.qnx.js
@@ -1,6 +1,6 @@
-// commit b58d6387cacaae999dc83778f794cf5900ae8dfe
+// commit 69d652e9dcaaaf4bdaa55ec37329636dd5b20fbe
 
-// File generated at :: Thu Aug 23 2012 17:49:07 GMT-0700 (PDT)
+// File generated at :: Fri Aug 24 2012 16:02:13 GMT-0700 (PDT)
 
 /*
  Licensed to the Apache Software Foundation (ASF) under one
@@ -418,7 +418,8 @@ module.exports = {
 
 // file: lib/common/channel.js
 define("cordova/channel", function(require, exports, module) {
-var utils = require('cordova/utils');
+var utils = require('cordova/utils'),
+    nextGuid = 1;
 
 /**
  * Custom pub-sub "channel" that can have functions subscribed to it
@@ -470,7 +471,6 @@ var Channel = function(type, opts) {
     this.type = type;
     this.handlers = {};
     this.numHandlers = 0;
-    this.guid = 1;
     this.fired = false;
     this.enabled = true;
     this.events = {
@@ -563,19 +563,19 @@ Channel.prototype.subscribe = function(f, c, g) {
 
     g = g || func.observer_guid || f.observer_guid;
     if (!g) {
-        // first time we've seen this subscriber
-        g = this.guid++;
-    }
-    else {
-        // subscriber already handled; dont set it twice
-        return g;
+        // first time any channel has seen this subscriber
+        g = nextGuid++;
     }
     func.observer_guid = g;
     f.observer_guid = g;
-    this.handlers[g] = func;
-    this.numHandlers++;
-    if (this.events.onSubscribe) this.events.onSubscribe.call(this);
-    if (this.fired) func.call(this);
+
+    // Don't add the same handler more than once.
+    if (!this.handlers[g]) {
+        this.handlers[g] = func;
+        this.numHandlers++;
+        if (this.events.onSubscribe) this.events.onSubscribe.call(this);
+        if (this.fired) func.apply(this, this.fireArgs);
+    }
     return g;
 };
 
@@ -589,15 +589,14 @@ Channel.prototype.subscribeOnce = function(f, c) {
 
     var g = null;
     var _this = this;
-    var m = function() {
-        f.apply(c || null, arguments);
-        _this.unsubscribe(g);
-    };
     if (this.fired) {
-        if (typeof c == "object") { f = utils.close(c, f); }
-        f.apply(this, this.fireArgs);
+        f.apply(c || null, this.fireArgs);
     } else {
-        g = this.subscribe(m);
+        g = this.subscribe(function() {
+            _this.unsubscribe(g);
+            f.apply(c || null, arguments);
+        });
+        f.observer_guid = g;
     }
     return g;
 };
@@ -613,7 +612,6 @@ Channel.prototype.unsubscribe = function(g) {
     var handler = this.handlers[g];
     if (handler) {
         if (handler.observer_guid) handler.observer_guid=null;
-        this.handlers[g] = null;
         delete this.handlers[g];
         this.numHandlers--;
         if (this.events.onUnsubscribe) this.events.onUnsubscribe.call(this);
@@ -627,14 +625,17 @@ Channel.prototype.fire = function(e) {
     if (this.enabled) {
         var fail = false;
         this.fired = true;
+        this.fireArgs = arguments;
+        // Copy the values first so that it is safe to modify it from within
+        // callbacks.
+        var toCall = [];
         for (var item in this.handlers) {
-            var handler = this.handlers[item];
-            if (typeof handler == 'function') {
-                var rv = (handler.apply(this, arguments)===false);
-                fail = fail || rv;
-            }
+            toCall.push(this.handlers[item]);
+        }
+        for (var i = 0; i < toCall.length; ++i) {
+            var rv = (toCall[i].apply(this, arguments)===false);
+            fail = fail || rv;
         }
-        this.fireArgs = arguments;
         return !fail;
     }
     return true;
@@ -898,7 +899,7 @@ var manager = require('cordova/plugin/manager'),
  * Execute a cordova command.  It is up to the native side whether this action
  * is synchronous or asynchronous.  The native side can return:
  *      Synchronous: PluginResult object as a JSON string
- *      Asynchrounous: Empty string ""
+ *      Asynchronous: Empty string ""
  * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
  * depending upon the result of the action.
  *
@@ -2735,7 +2736,7 @@ FileWriter.prototype.seek = function(offset) {
     if (offset < 0) {
         this.position = Math.max(offset + this.length, 0);
     }
-    // Offset is bigger then file size so set position
+    // Offset is bigger than file size so set position
     // to the end of the file.
     else if (offset > this.length) {
         this.position = this.length;
@@ -3362,7 +3363,7 @@ var accelerometer = {
 
         if (running) {
             // If we're already running then immediately invoke the success callback
-            // but only if we have retreived a value, sample code does not check for null ...
+            // but only if we have retrieved a value, sample code does not check for null ...
             if(accel) {
                 successCallback(accel);
             }
@@ -3880,7 +3881,7 @@ var contacts = {
      * 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
+     * @param properties an object whose properties will be examined to create a new Contact
      * @returns new Contact object
      */
     create:function(properties) {
@@ -4094,7 +4095,7 @@ var geolocation = {
         } else if (options.timeout === 0) {
             fail({
                 code:PositionError.TIMEOUT,
-                message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceed's provided PositionOptions' maximumAge parameter."
+                message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceeds provided PositionOptions' maximumAge parameter."
             });
         // Otherwise we have to call into native to retrieve a position.
         } else {
@@ -4258,7 +4259,7 @@ CurrentLevel = LevelsMap.WARN;
  *
  * The value used determines which messages get printed.  The logging
  * values above are in order, and only messages logged at the logging
- * level or above will actually be displayed to the user.  Eg, the
+ * level or above will actually be displayed to the user.  E.g., the
  * default level is WARN, so only messages logged with LOG, ERROR, or
  * WARN will be displayed; INFO and DEBUG messages will be ignored.
  */
@@ -4584,7 +4585,7 @@ module.exports = {
             version: blackberry.system.softwareVersion,
             name: "Dev Alpha",
             uuid: blackberry.identity.uuid,
-            cordova: "2.0.0"
+            cordova: "2.1.0rc1"
         });
 
         return { "status" : cordova.callbackStatus.NO_RESULT, "message" : "Device info returned" };