You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by sg...@apache.org on 2016/01/26 14:19:28 UTC

[1/2] cordova-plugin-file git commit: CB-10419 cordova-plugin-file 4.0.0 error with browserify workflow

Repository: cordova-plugin-file
Updated Branches:
  refs/heads/master 563dcaf7b -> 79956e4c3


http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/79956e4c/www/browser/Preparing.js
----------------------------------------------------------------------
diff --git a/www/browser/Preparing.js b/www/browser/Preparing.js
index f302ee9..2f94c70 100644
--- a/www/browser/Preparing.js
+++ b/www/browser/Preparing.js
@@ -19,168 +19,170 @@
  *
 */
 
-/*global require*/
-
-//Only Chrome uses this file.
-if (!require('./isChrome')()) {
-    return;
-}
-
-var channel = require('cordova/channel');
-var FileError = require('./FileError');
-var PERSISTENT_FS_QUOTA = 5 * 1024 * 1024;
-var filePluginIsReadyEvent = new Event('filePluginIsReady');
-
-var entryFunctionsCreated = false;
-var quotaWasRequested = false;
-var eventWasThrown = false;
-
-if (!window.requestFileSystem) {
-    window.requestFileSystem = function(type, size, win, fail) {
-        if (fail) {
-            fail("Not supported");
-        }
-    };
-} else {
-    window.requestFileSystem(window.TEMPORARY, 1, createFileEntryFunctions, function() {});
-}
+(function () {
+    /*global require*/
 
-if (!window.resolveLocalFileSystemURL) {
-    window.resolveLocalFileSystemURL = function(url, win, fail) {
-        if(fail) {
-            fail("Not supported");
-        }
-    };
-}
-
-// Resolves a filesystem entry by its path - which is passed either in standard (filesystem:file://) or
-// Cordova-specific (cdvfile://) universal way.
-// Aligns with specification: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#widl-LocalFileSystem-resolveLocalFileSystemURL
-var nativeResolveLocalFileSystemURL = window.resolveLocalFileSystemURL || window.webkitResolveLocalFileSystemURL;
-window.resolveLocalFileSystemURL = function(url, win, fail) {
-    /* If url starts with `cdvfile` then we need convert it to Chrome real url first:
-      cdvfile://localhost/persistent/path/to/file -> filesystem:file://persistent/path/to/file */
-    if (url.trim().substr(0,7) === "cdvfile") {
-        /* Quirk:
-        Plugin supports cdvfile://localhost (local resources) only.
-        I.e. external resources are not supported via cdvfile. */
-        if (url.indexOf("cdvfile://localhost") !== -1) {
-            // Browser supports temporary and persistent only
-            var indexPersistent = url.indexOf('persistent');
-            var indexTemporary = url.indexOf('temporary');
-
-            /* Chrome urls start with 'filesystem:' prefix. See quirk:
-               toURL function in Chrome returns filesystem:-prefixed path depending on application host.
-               For example, filesystem:file:///persistent/somefile.txt,
-               filesystem:http://localhost:8080/persistent/somefile.txt. */
-            var prefix = 'filesystem:file:///';
-            if (location.protocol !== 'file:') {
-                prefix = 'filesystem:' + location.origin + '/';
-            }
+    //Only Chrome uses this file.
+    if (!require('./isChrome')()) {
+        return;
+    }
 
-            var result;
-            if (indexPersistent !== -1) {
-                // cdvfile://localhost/persistent/path/to/file -> filesystem:file://persistent/path/to/file
-                // or filesystem:http://localhost:8080/persistent/path/to/file
-                result =  prefix + 'persistent' + url.substr(indexPersistent + 10);
-                nativeResolveLocalFileSystemURL(result, win, fail);
-                return;
-            }
+    var channel = require('cordova/channel');
+    var FileError = require('./FileError');
+    var PERSISTENT_FS_QUOTA = 5 * 1024 * 1024;
+    var filePluginIsReadyEvent = new Event('filePluginIsReady');
 
-            if (indexTemporary !== -1) {
-                // cdvfile://localhost/temporary/path/to/file -> filesystem:file://temporary/path/to/file
-                // or filesystem:http://localhost:8080/temporary/path/to/file
-                result = prefix + 'temporary' + url.substr(indexTemporary + 9);
-                nativeResolveLocalFileSystemURL(result, win, fail);
-                return;
-            }
-        }
+    var entryFunctionsCreated = false;
+    var quotaWasRequested = false;
+    var eventWasThrown = false;
 
-        // cdvfile other than local file resource is not supported
-        fail && fail(new FileError(FileError.ENCODING_ERR));
-    } else {
-        nativeResolveLocalFileSystemURL(url, win, fail);
-    }
-};
-
-function createFileEntryFunctions(fs) {
-    fs.root.getFile('todelete_658674_833_4_cdv', {create: true}, function(fileEntry) {
-        var fileEntryType = Object.getPrototypeOf(fileEntry);
-        var entryType = Object.getPrototypeOf(fileEntryType);
-
-        // Save the original method
-        var origToURL = entryType.toURL;
-        entryType.toURL = function () {
-            var origURL = origToURL.call(this);
-            if (this.isDirectory && origURL.substr(-1) !== '/') {
-                return origURL + '/';
+    if (!window.requestFileSystem) {
+        window.requestFileSystem = function(type, size, win, fail) {
+            if (fail) {
+                fail("Not supported");
             }
-            return origURL;
         };
+    } else {
+        window.requestFileSystem(window.TEMPORARY, 1, createFileEntryFunctions, function() {});
+    }
 
-        entryType.toNativeURL = function () {
-            console.warn("DEPRECATED: Update your code to use 'toURL'");
-            return this.toURL();
+    if (!window.resolveLocalFileSystemURL) {
+        window.resolveLocalFileSystemURL = function(url, win, fail) {
+            if(fail) {
+                fail("Not supported");
+            }
         };
+    }
 
-        entryType.toInternalURL = function() {
-            if (this.toURL().indexOf("persistent") > -1) {
-                return "cdvfile://localhost/persistent" + this.fullPath;
+    // Resolves a filesystem entry by its path - which is passed either in standard (filesystem:file://) or
+    // Cordova-specific (cdvfile://) universal way.
+    // Aligns with specification: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#widl-LocalFileSystem-resolveLocalFileSystemURL
+    var nativeResolveLocalFileSystemURL = window.resolveLocalFileSystemURL || window.webkitResolveLocalFileSystemURL;
+    window.resolveLocalFileSystemURL = function(url, win, fail) {
+        /* If url starts with `cdvfile` then we need convert it to Chrome real url first:
+          cdvfile://localhost/persistent/path/to/file -> filesystem:file://persistent/path/to/file */
+        if (url.trim().substr(0,7) === "cdvfile") {
+            /* Quirk:
+            Plugin supports cdvfile://localhost (local resources) only.
+            I.e. external resources are not supported via cdvfile. */
+            if (url.indexOf("cdvfile://localhost") !== -1) {
+                // Browser supports temporary and persistent only
+                var indexPersistent = url.indexOf('persistent');
+                var indexTemporary = url.indexOf('temporary');
+
+                /* Chrome urls start with 'filesystem:' prefix. See quirk:
+                   toURL function in Chrome returns filesystem:-prefixed path depending on application host.
+                   For example, filesystem:file:///persistent/somefile.txt,
+                   filesystem:http://localhost:8080/persistent/somefile.txt. */
+                var prefix = 'filesystem:file:///';
+                if (location.protocol !== 'file:') {
+                    prefix = 'filesystem:' + location.origin + '/';
+                }
+
+                var result;
+                if (indexPersistent !== -1) {
+                    // cdvfile://localhost/persistent/path/to/file -> filesystem:file://persistent/path/to/file
+                    // or filesystem:http://localhost:8080/persistent/path/to/file
+                    result =  prefix + 'persistent' + url.substr(indexPersistent + 10);
+                    nativeResolveLocalFileSystemURL(result, win, fail);
+                    return;
+                }
+
+                if (indexTemporary !== -1) {
+                    // cdvfile://localhost/temporary/path/to/file -> filesystem:file://temporary/path/to/file
+                    // or filesystem:http://localhost:8080/temporary/path/to/file
+                    result = prefix + 'temporary' + url.substr(indexTemporary + 9);
+                    nativeResolveLocalFileSystemURL(result, win, fail);
+                    return;
+                }
             }
 
-            if (this.toURL().indexOf("temporary") > -1) {
-                return "cdvfile://localhost/temporary" + this.fullPath;
-            }
-        };
+            // cdvfile other than local file resource is not supported
+            fail && fail(new FileError(FileError.ENCODING_ERR));
+        } else {
+            nativeResolveLocalFileSystemURL(url, win, fail);
+        }
+    };
 
-        entryType.setMetadata = function(win, fail /*, metadata*/) {
-            fail && fail("Not supported");
-        };
+    function createFileEntryFunctions(fs) {
+        fs.root.getFile('todelete_658674_833_4_cdv', {create: true}, function(fileEntry) {
+            var fileEntryType = Object.getPrototypeOf(fileEntry);
+            var entryType = Object.getPrototypeOf(fileEntryType);
+
+            // Save the original method
+            var origToURL = entryType.toURL;
+            entryType.toURL = function () {
+                var origURL = origToURL.call(this);
+                if (this.isDirectory && origURL.substr(-1) !== '/') {
+                    return origURL + '/';
+                }
+                return origURL;
+            };
 
-        fileEntry.createWriter(function(writer) {
-            var originalWrite = writer.write;
-            var writerProto = Object.getPrototypeOf(writer);
-            writerProto.write = function(blob) {
-                if(blob instanceof Blob) {
-                    originalWrite.apply(this, [blob]);
-                } else {
-                    var realBlob = new Blob([blob]);
-                    originalWrite.apply(this, [realBlob]);
-               }
+            entryType.toNativeURL = function () {
+                console.warn("DEPRECATED: Update your code to use 'toURL'");
+                return this.toURL();
             };
 
-            fileEntry.remove(function(){ entryFunctionsCreated = true; }, function(){ /* empty callback */ });
-      });
-    });
-}
+            entryType.toInternalURL = function() {
+                if (this.toURL().indexOf("persistent") > -1) {
+                    return "cdvfile://localhost/persistent" + this.fullPath;
+                }
 
-window.initPersistentFileSystem = function(size, win, fail) {
-    if (navigator.webkitPersistentStorage) {
-        navigator.webkitPersistentStorage.requestQuota(size, win, fail);
-        return;
+                if (this.toURL().indexOf("temporary") > -1) {
+                    return "cdvfile://localhost/temporary" + this.fullPath;
+                }
+            };
+
+            entryType.setMetadata = function(win, fail /*, metadata*/) {
+                fail && fail("Not supported");
+            };
+
+            fileEntry.createWriter(function(writer) {
+                var originalWrite = writer.write;
+                var writerProto = Object.getPrototypeOf(writer);
+                writerProto.write = function(blob) {
+                    if(blob instanceof Blob) {
+                        originalWrite.apply(this, [blob]);
+                    } else {
+                        var realBlob = new Blob([blob]);
+                        originalWrite.apply(this, [realBlob]);
+                   }
+                };
+
+                fileEntry.remove(function(){ entryFunctionsCreated = true; }, function(){ /* empty callback */ });
+          });
+        });
     }
 
-    fail("This browser does not support this function");
-};
+    window.initPersistentFileSystem = function(size, win, fail) {
+        if (navigator.webkitPersistentStorage) {
+            navigator.webkitPersistentStorage.requestQuota(size, win, fail);
+            return;
+        }
 
-window.isFilePluginReadyRaised = function () { return eventWasThrown; };
+        fail("This browser does not support this function");
+    };
 
-window.initPersistentFileSystem(PERSISTENT_FS_QUOTA, function() {
-    console.log('Persistent fs quota granted');
-    quotaWasRequested = true;
-}, function(e){
-    console.log('Error occured while trying to request Persistent fs quota: ' + JSON.stringify(e));
-});
+    window.isFilePluginReadyRaised = function () { return eventWasThrown; };
 
-channel.onCordovaReady.subscribe(function () {
-    function dispatchEventIfReady() {
-        if (entryFunctionsCreated && quotaWasRequested) {
-            window.dispatchEvent(filePluginIsReadyEvent);
-            eventWasThrown = true;
-        } else {
-            setTimeout(dispatchEventIfReady, 100);
+    window.initPersistentFileSystem(PERSISTENT_FS_QUOTA, function() {
+        console.log('Persistent fs quota granted');
+        quotaWasRequested = true;
+    }, function(e){
+        console.log('Error occured while trying to request Persistent fs quota: ' + JSON.stringify(e));
+    });
+
+    channel.onCordovaReady.subscribe(function () {
+        function dispatchEventIfReady() {
+            if (entryFunctionsCreated && quotaWasRequested) {
+                window.dispatchEvent(filePluginIsReadyEvent);
+                eventWasThrown = true;
+            } else {
+                setTimeout(dispatchEventIfReady, 100);
+            }
         }
-    }
 
-    dispatchEventIfReady();
-}, false);
+        dispatchEventIfReady();
+    }, false);
+})();

http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/79956e4c/www/requestFileSystem.js
----------------------------------------------------------------------
diff --git a/www/requestFileSystem.js b/www/requestFileSystem.js
index 098047c..1c6c5f4 100644
--- a/www/requestFileSystem.js
+++ b/www/requestFileSystem.js
@@ -18,61 +18,62 @@
  * under the License.
  *
 */
-
-//For browser platform: not all browsers use this file.
-function checkBrowser() {
-    if (cordova.platformId === "browser" && require('./isChrome')()) {
-        module.exports = window.requestFileSystem || window.webkitRequestFileSystem;
-        return true;
+(function() {
+    //For browser platform: not all browsers use this file.
+    function checkBrowser() {
+        if (cordova.platformId === "browser" && require('./isChrome')()) {
+            module.exports = window.requestFileSystem || window.webkitRequestFileSystem;
+            return true;
+        }
+        return false;
+    }
+    if (checkBrowser()) {
+        return;
     }
-    return false;
-}
-if (checkBrowser()) {
-    return;
-}
 
-var argscheck = require('cordova/argscheck'),
-    FileError = require('./FileError'),
-    FileSystem = require('./FileSystem'),
-    exec = require('cordova/exec');
-var fileSystems = require('./fileSystems');
+    var argscheck = require('cordova/argscheck'),
+        FileError = require('./FileError'),
+        FileSystem = require('./FileSystem'),
+        exec = require('cordova/exec');
+    var fileSystems = require('./fileSystems');
 
-/**
- * Request a file system in which to store application data.
- * @param type  local file system type
- * @param size  indicates how much storage space, in bytes, the application expects to need
- * @param successCallback  invoked with a FileSystem object
- * @param errorCallback  invoked if error occurs retrieving file system
- */
-var requestFileSystem = function(type, size, successCallback, errorCallback) {
-    argscheck.checkArgs('nnFF', 'requestFileSystem', arguments);
-    var fail = function(code) {
-        errorCallback && errorCallback(new FileError(code));
-    };
+    /**
+     * Request a file system in which to store application data.
+     * @param type  local file system type
+     * @param size  indicates how much storage space, in bytes, the application expects to need
+     * @param successCallback  invoked with a FileSystem object
+     * @param errorCallback  invoked if error occurs retrieving file system
+     */
+    var requestFileSystem = function(type, size, successCallback, errorCallback) {
+        argscheck.checkArgs('nnFF', 'requestFileSystem', arguments);
+        var fail = function(code) {
+            errorCallback && errorCallback(new FileError(code));
+        };
 
-    if (type < 0) {
-        fail(FileError.SYNTAX_ERR);
-    } else {
-        // if successful, return a FileSystem object
-        var success = function(file_system) {
-            if (file_system) {
-                if (successCallback) {
-                    fileSystems.getFs(file_system.name, function(fs) {
-                        // This should happen only on platforms that haven't implemented requestAllFileSystems (windows)
-                        if (!fs) {
-                            fs = new FileSystem(file_system.name, file_system.root);
-                        }
-                        successCallback(fs);
-                    });
+        if (type < 0) {
+            fail(FileError.SYNTAX_ERR);
+        } else {
+            // if successful, return a FileSystem object
+            var success = function(file_system) {
+                if (file_system) {
+                    if (successCallback) {
+                        fileSystems.getFs(file_system.name, function(fs) {
+                            // This should happen only on platforms that haven't implemented requestAllFileSystems (windows)
+                            if (!fs) {
+                                fs = new FileSystem(file_system.name, file_system.root);
+                            }
+                            successCallback(fs);
+                        });
+                    }
                 }
-            }
-            else {
-                // no FileSystem object returned
-                fail(FileError.NOT_FOUND_ERR);
-            }
-        };
-        exec(success, fail, "File", "requestFileSystem", [type, size]);
-    }
-};
+                else {
+                    // no FileSystem object returned
+                    fail(FileError.NOT_FOUND_ERR);
+                }
+            };
+            exec(success, fail, "File", "requestFileSystem", [type, size]);
+        }
+    };
 
-module.exports = requestFileSystem;
+    module.exports = requestFileSystem;
+})();

http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/79956e4c/www/resolveLocalFileSystemURI.js
----------------------------------------------------------------------
diff --git a/www/resolveLocalFileSystemURI.js b/www/resolveLocalFileSystemURI.js
index 633c1d2..4761222 100644
--- a/www/resolveLocalFileSystemURI.js
+++ b/www/resolveLocalFileSystemURI.js
@@ -18,72 +18,73 @@
  * under the License.
  *
 */
-
-//For browser platform: not all browsers use overrided `resolveLocalFileSystemURL`.
-function checkBrowser() {
-    if (cordova.platformId === "browser" && require('./isChrome')()) {
-        module.exports.resolveLocalFileSystemURL = window.resolveLocalFileSystemURL || window.webkitResolveLocalFileSystemURL;
-        return true;
+(function() {
+    //For browser platform: not all browsers use overrided `resolveLocalFileSystemURL`.
+    function checkBrowser() {
+        if (cordova.platformId === "browser" && require('./isChrome')()) {
+            module.exports.resolveLocalFileSystemURL = window.resolveLocalFileSystemURL || window.webkitResolveLocalFileSystemURL;
+            return true;
+        }
+        return false;
     }
-    return false;
-}
-if (checkBrowser()) {
-    return;
-}
-
-var argscheck = require('cordova/argscheck'),
-    DirectoryEntry = require('./DirectoryEntry'),
-    FileEntry = require('./FileEntry'),
-    FileError = require('./FileError'),
-    exec = require('cordova/exec');
-var fileSystems = require('./fileSystems');
-
-/**
- * Look up file system Entry referred to by local URI.
- * @param {DOMString} uri  URI referring to a local file or directory
- * @param successCallback  invoked with Entry object corresponding to URI
- * @param errorCallback    invoked if error occurs retrieving file system entry
- */
-module.exports.resolveLocalFileSystemURL = module.exports.resolveLocalFileSystemURL || function(uri, successCallback, errorCallback) {
-    argscheck.checkArgs('sFF', 'resolveLocalFileSystemURI', arguments);
-    // error callback
-    var fail = function(error) {
-        errorCallback && errorCallback(new FileError(error));
-    };
-    // sanity check for 'not:valid:filename' or '/not:valid:filename'
-    // file.spec.12 window.resolveLocalFileSystemURI should error (ENCODING_ERR) when resolving invalid URI with leading /.
-    if(!uri || uri.split(":").length > 2) {
-        setTimeout( function() {
-            fail(FileError.ENCODING_ERR);
-        },0);
+    if (checkBrowser()) {
         return;
     }
-    // if successful, return either a file or directory entry
-    var success = function(entry) {
-        if (entry) {
-            if (successCallback) {
-                // create appropriate Entry object
-                var fsName = entry.filesystemName || (entry.filesystem && entry.filesystem.name) || (entry.filesystem == window.PERSISTENT ? 'persistent' : 'temporary');
-                fileSystems.getFs(fsName, function(fs) {
-                    // This should happen only on platforms that haven't implemented requestAllFileSystems (windows)
-                    if (!fs) {
-                        fs = new FileSystem(fsName, {name:"", fullPath:"/"});
-                    }
-                    var result = (entry.isDirectory) ? new DirectoryEntry(entry.name, entry.fullPath, fs, entry.nativeURL) : new FileEntry(entry.name, entry.fullPath, fs, entry.nativeURL);
-                    successCallback(result);
-                });
-            }
-        }
-        else {
-            // no Entry object returned
-            fail(FileError.NOT_FOUND_ERR);
+
+    var argscheck = require('cordova/argscheck'),
+        DirectoryEntry = require('./DirectoryEntry'),
+        FileEntry = require('./FileEntry'),
+        FileError = require('./FileError'),
+        exec = require('cordova/exec');
+    var fileSystems = require('./fileSystems');
+
+    /**
+     * Look up file system Entry referred to by local URI.
+     * @param {DOMString} uri  URI referring to a local file or directory
+     * @param successCallback  invoked with Entry object corresponding to URI
+     * @param errorCallback    invoked if error occurs retrieving file system entry
+     */
+    module.exports.resolveLocalFileSystemURL = module.exports.resolveLocalFileSystemURL || function(uri, successCallback, errorCallback) {
+        argscheck.checkArgs('sFF', 'resolveLocalFileSystemURI', arguments);
+        // error callback
+        var fail = function(error) {
+            errorCallback && errorCallback(new FileError(error));
+        };
+        // sanity check for 'not:valid:filename' or '/not:valid:filename'
+        // file.spec.12 window.resolveLocalFileSystemURI should error (ENCODING_ERR) when resolving invalid URI with leading /.
+        if(!uri || uri.split(":").length > 2) {
+            setTimeout( function() {
+                fail(FileError.ENCODING_ERR);
+            },0);
+            return;
         }
-    };
+        // if successful, return either a file or directory entry
+        var success = function(entry) {
+            if (entry) {
+                if (successCallback) {
+                    // create appropriate Entry object
+                    var fsName = entry.filesystemName || (entry.filesystem && entry.filesystem.name) || (entry.filesystem == window.PERSISTENT ? 'persistent' : 'temporary');
+                    fileSystems.getFs(fsName, function(fs) {
+                        // This should happen only on platforms that haven't implemented requestAllFileSystems (windows)
+                        if (!fs) {
+                            fs = new FileSystem(fsName, {name:"", fullPath:"/"});
+                        }
+                        var result = (entry.isDirectory) ? new DirectoryEntry(entry.name, entry.fullPath, fs, entry.nativeURL) : new FileEntry(entry.name, entry.fullPath, fs, entry.nativeURL);
+                        successCallback(result);
+                    });
+                }
+            }
+            else {
+                // no Entry object returned
+                fail(FileError.NOT_FOUND_ERR);
+            }
+        };
 
-    exec(success, fail, "File", "resolveLocalFileSystemURI", [uri]);
-};
+        exec(success, fail, "File", "resolveLocalFileSystemURI", [uri]);
+    };
 
-module.exports.resolveLocalFileSystemURI = function() {
-    console.log("resolveLocalFileSystemURI is deprecated. Please call resolveLocalFileSystemURL instead.");
-    module.exports.resolveLocalFileSystemURL.apply(this, arguments);
-};
+    module.exports.resolveLocalFileSystemURI = function() {
+        console.log("resolveLocalFileSystemURI is deprecated. Please call resolveLocalFileSystemURL instead.");
+        module.exports.resolveLocalFileSystemURL.apply(this, arguments);
+    };
+})();


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org


[2/2] cordova-plugin-file git commit: CB-10419 cordova-plugin-file 4.0.0 error with browserify workflow

Posted by sg...@apache.org.
CB-10419 cordova-plugin-file 4.0.0 error with browserify workflow

github close #157


Project: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/commit/79956e4c
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/79956e4c
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/79956e4c

Branch: refs/heads/master
Commit: 79956e4c3c8a90abe3bfa237ce59dd6d1e482311
Parents: 563dcaf
Author: sgrebnov <v-...@microsoft.com>
Authored: Tue Jan 26 13:11:01 2016 +0300
Committer: sgrebnov <v-...@microsoft.com>
Committed: Tue Jan 26 16:19:41 2016 +0300

----------------------------------------------------------------------
 plugin.xml                       |   10 +-
 src/browser/FileProxy.js         | 1533 +++++++++++++++++----------------
 www/browser/Preparing.js         |  286 +++---
 www/requestFileSystem.js         |  105 +--
 www/resolveLocalFileSystemURI.js |  127 +--
 5 files changed, 1034 insertions(+), 1027 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/79956e4c/plugin.xml
----------------------------------------------------------------------
diff --git a/plugin.xml b/plugin.xml
index 6820120..16d8112 100644
--- a/plugin.xml
+++ b/plugin.xml
@@ -102,6 +102,12 @@ xmlns:android="http://schemas.android.com/apk/res/android"
         <merges target="window" />
     </js-module>
 
+    <!-- Required for browserify: we always link module below as there is conditional reference
+    to this module from requestFileSystem and resolveLocalFileSystemURI modules. -->
+    <js-module src="www/browser/isChrome.js" name="isChrome">
+        <runs />
+    </js-module>
+
     <info>
 The Android Persistent storage location now defaults to "Internal". Please check this plugins README to see if you application needs any changes in its config.xml.
 
@@ -396,10 +402,6 @@ to config.xml in order for the application to find previously stored files.
     </platform>
 
     <platform name="browser">
-        <js-module src="www/browser/isChrome.js" name="isChrome">
-            <runs />
-        </js-module>
-
         <!-- File for Chrome -->
         <js-module src="www/browser/Preparing.js" name="Preparing">
             <runs />

http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/79956e4c/src/browser/FileProxy.js
----------------------------------------------------------------------
diff --git a/src/browser/FileProxy.js b/src/browser/FileProxy.js
index 0e0e0de..6d5938d 100644
--- a/src/browser/FileProxy.js
+++ b/src/browser/FileProxy.js
@@ -18,942 +18,943 @@
  * under the License.
  *
  */
+(function() {
+    /*global require, exports, module*/
+    /*global FILESYSTEM_PREFIX*/
+    /*global IDBKeyRange*/
+
+    /* Heavily based on https://github.com/ebidel/idb.filesystem.js */
+
+    // For chrome we don't need to implement proxy methods
+    // All functionality can be accessed natively.
+    if (require('./isChrome')()) {
+        var pathsPrefix = {
+            // Read-only directory where the application is installed.
+            applicationDirectory: location.origin + "/",
+            // Where to put app-specific data files.
+            dataDirectory: 'filesystem:file:///persistent/',
+            // Cached files that should survive app restarts.
+            // Apps should not rely on the OS to delete files in here.
+            cacheDirectory: 'filesystem:file:///temporary/',
+        };
 
-/*global require, exports, module*/
-/*global FILESYSTEM_PREFIX*/
-/*global IDBKeyRange*/
-
-/* Heavily based on https://github.com/ebidel/idb.filesystem.js */
-
-// For chrome we don't need to implement proxy methods
-// All functionality can be accessed natively.
-if (require('./isChrome')()) {
-    var pathsPrefix = {
-        // Read-only directory where the application is installed.
-        applicationDirectory: location.origin + "/",
-        // Where to put app-specific data files.
-        dataDirectory: 'filesystem:file:///persistent/',
-        // Cached files that should survive app restarts.
-        // Apps should not rely on the OS to delete files in here.
-        cacheDirectory: 'filesystem:file:///temporary/',
-    };
-
-    exports.requestAllPaths = function(successCallback) {
-        successCallback(pathsPrefix);
-    };
+        exports.requestAllPaths = function(successCallback) {
+            successCallback(pathsPrefix);
+        };
 
-    require("cordova/exec/proxy").add("File", module.exports);
-    return;
-}
-
-var LocalFileSystem = require('./LocalFileSystem'),
-    FileSystem = require('./FileSystem'),
-    FileEntry = require('./FileEntry'),
-    FileError = require('./FileError'),
-    DirectoryEntry = require('./DirectoryEntry'),
-    File = require('./File');
-
-(function(exports, global) {
-    var indexedDB = global.indexedDB || global.mozIndexedDB;
-    if (!indexedDB) {
-        throw "Firefox OS File plugin: indexedDB not supported";
+        require("cordova/exec/proxy").add("File", module.exports);
+        return;
     }
 
-    var fs_ = null;
-
-    var idb_ = {};
-    idb_.db = null;
-    var FILE_STORE_ = 'entries';
+    var LocalFileSystem = require('./LocalFileSystem'),
+        FileSystem = require('./FileSystem'),
+        FileEntry = require('./FileEntry'),
+        FileError = require('./FileError'),
+        DirectoryEntry = require('./DirectoryEntry'),
+        File = require('./File');
+
+    (function(exports, global) {
+        var indexedDB = global.indexedDB || global.mozIndexedDB;
+        if (!indexedDB) {
+            throw "Firefox OS File plugin: indexedDB not supported";
+        }
 
-    var DIR_SEPARATOR = '/';
+        var fs_ = null;
 
-    var pathsPrefix = {
-        // Read-only directory where the application is installed.
-        applicationDirectory: location.origin + "/",
-        // Where to put app-specific data files.
-        dataDirectory: 'file:///persistent/',
-        // Cached files that should survive app restarts.
-        // Apps should not rely on the OS to delete files in here.
-        cacheDirectory: 'file:///temporary/',
-    };
+        var idb_ = {};
+        idb_.db = null;
+        var FILE_STORE_ = 'entries';
 
-    var unicodeLastChar = 65535;
+        var DIR_SEPARATOR = '/';
 
-/*** Exported functionality ***/
+        var pathsPrefix = {
+            // Read-only directory where the application is installed.
+            applicationDirectory: location.origin + "/",
+            // Where to put app-specific data files.
+            dataDirectory: 'file:///persistent/',
+            // Cached files that should survive app restarts.
+            // Apps should not rely on the OS to delete files in here.
+            cacheDirectory: 'file:///temporary/',
+        };
 
-    exports.requestFileSystem = function(successCallback, errorCallback, args) {
-        var type = args[0];
-        // Size is ignored since IDB filesystem size depends
-        // on browser implementation and can't be set up by user
-        var size = args[1]; // jshint ignore: line
+        var unicodeLastChar = 65535;
 
-        if (type !== LocalFileSystem.TEMPORARY && type !== LocalFileSystem.PERSISTENT) {
-            errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR);
-            return;
-        }
+    /*** Exported functionality ***/
 
-        var name = type === LocalFileSystem.TEMPORARY ? 'temporary' : 'persistent';
-        var storageName = (location.protocol + location.host).replace(/:/g, '_');
+        exports.requestFileSystem = function(successCallback, errorCallback, args) {
+            var type = args[0];
+            // Size is ignored since IDB filesystem size depends
+            // on browser implementation and can't be set up by user
+            var size = args[1]; // jshint ignore: line
 
-        var root = new DirectoryEntry('', DIR_SEPARATOR);
-        fs_ = new FileSystem(name, root);
+            if (type !== LocalFileSystem.TEMPORARY && type !== LocalFileSystem.PERSISTENT) {
+                errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR);
+                return;
+            }
 
-        idb_.open(storageName, function() {
-            successCallback(fs_);
-        }, errorCallback);
-    };
+            var name = type === LocalFileSystem.TEMPORARY ? 'temporary' : 'persistent';
+            var storageName = (location.protocol + location.host).replace(/:/g, '_');
 
-    // Overridden by Android, BlackBerry 10 and iOS to populate fsMap
-    require('./fileSystems').getFs = function(name, callback) {
-        callback(new FileSystem(name, fs_.root));
-    };
+            var root = new DirectoryEntry('', DIR_SEPARATOR);
+            fs_ = new FileSystem(name, root);
 
-    // list a directory's contents (files and folders).
-    exports.readEntries = function(successCallback, errorCallback, args) {
-        var fullPath = args[0];
+            idb_.open(storageName, function() {
+                successCallback(fs_);
+            }, errorCallback);
+        };
 
-        if (typeof successCallback !== 'function') {
-            throw Error('Expected successCallback argument.');
-        }
+        // Overridden by Android, BlackBerry 10 and iOS to populate fsMap
+        require('./fileSystems').getFs = function(name, callback) {
+            callback(new FileSystem(name, fs_.root));
+        };
 
-        var path = resolveToFullPath_(fullPath);
+        // list a directory's contents (files and folders).
+        exports.readEntries = function(successCallback, errorCallback, args) {
+            var fullPath = args[0];
 
-        exports.getDirectory(function() {
-            idb_.getAllEntries(path.fullPath + DIR_SEPARATOR, path.storagePath, function(entries) {
-                successCallback(entries);
-            }, errorCallback);
-        }, function() {
-            if (errorCallback) {
-                errorCallback(FileError.NOT_FOUND_ERR);
+            if (typeof successCallback !== 'function') {
+                throw Error('Expected successCallback argument.');
             }
-        }, [path.storagePath, path.fullPath, {create: false}]);
-    };
-
-    exports.getFile = function(successCallback, errorCallback, args) {
-        var fullPath = args[0];
-        var path = args[1];
-        var options = args[2] || {};
 
-        // Create an absolute path if we were handed a relative one.
-        path = resolveToFullPath_(fullPath, path);
-
-        idb_.get(path.storagePath, function(fileEntry) {
-            if (options.create === true && options.exclusive === true && fileEntry) {
-                // If create and exclusive are both true, and the path already exists,
-                // getFile must fail.
+            var path = resolveToFullPath_(fullPath);
 
+            exports.getDirectory(function() {
+                idb_.getAllEntries(path.fullPath + DIR_SEPARATOR, path.storagePath, function(entries) {
+                    successCallback(entries);
+                }, errorCallback);
+            }, function() {
                 if (errorCallback) {
-                    errorCallback(FileError.PATH_EXISTS_ERR);
+                    errorCallback(FileError.NOT_FOUND_ERR);
                 }
-            } else if (options.create === true && !fileEntry) {
-                // If create is true, the path doesn't exist, and no other error occurs,
-                // getFile must create it as a zero-length file and return a corresponding
-                // FileEntry.
-                var newFileEntry = new FileEntry(path.fileName, path.fullPath, new FileSystem(path.fsName, fs_.root));
-
-                newFileEntry.file_ = new MyFile({
-                    size: 0,
-                    name: newFileEntry.name,
-                    lastModifiedDate: new Date(),
-                    storagePath: path.storagePath
-                });
+            }, [path.storagePath, path.fullPath, {create: false}]);
+        };
+
+        exports.getFile = function(successCallback, errorCallback, args) {
+            var fullPath = args[0];
+            var path = args[1];
+            var options = args[2] || {};
+
+            // Create an absolute path if we were handed a relative one.
+            path = resolveToFullPath_(fullPath, path);
+
+            idb_.get(path.storagePath, function(fileEntry) {
+                if (options.create === true && options.exclusive === true && fileEntry) {
+                    // If create and exclusive are both true, and the path already exists,
+                    // getFile must fail.
 
-                idb_.put(newFileEntry, path.storagePath, successCallback, errorCallback);
-            } else if (options.create === true && fileEntry) {
-                if (fileEntry.isFile) {
-                    // Overwrite file, delete then create new.
-                    idb_['delete'](path.storagePath, function() {
-                        var newFileEntry = new FileEntry(path.fileName, path.fullPath, new FileSystem(path.fsName, fs_.root));
-
-                        newFileEntry.file_ = new MyFile({
-                            size: 0,
-                            name: newFileEntry.name,
-                            lastModifiedDate: new Date(),
-                            storagePath: path.storagePath
-                        });
-
-                        idb_.put(newFileEntry, path.storagePath, successCallback, errorCallback);
-                    }, errorCallback);
-                } else {
                     if (errorCallback) {
-                        errorCallback(FileError.INVALID_MODIFICATION_ERR);
+                        errorCallback(FileError.PATH_EXISTS_ERR);
                     }
+                } else if (options.create === true && !fileEntry) {
+                    // If create is true, the path doesn't exist, and no other error occurs,
+                    // getFile must create it as a zero-length file and return a corresponding
+                    // FileEntry.
+                    var newFileEntry = new FileEntry(path.fileName, path.fullPath, new FileSystem(path.fsName, fs_.root));
+
+                    newFileEntry.file_ = new MyFile({
+                        size: 0,
+                        name: newFileEntry.name,
+                        lastModifiedDate: new Date(),
+                        storagePath: path.storagePath
+                    });
+
+                    idb_.put(newFileEntry, path.storagePath, successCallback, errorCallback);
+                } else if (options.create === true && fileEntry) {
+                    if (fileEntry.isFile) {
+                        // Overwrite file, delete then create new.
+                        idb_['delete'](path.storagePath, function() {
+                            var newFileEntry = new FileEntry(path.fileName, path.fullPath, new FileSystem(path.fsName, fs_.root));
+
+                            newFileEntry.file_ = new MyFile({
+                                size: 0,
+                                name: newFileEntry.name,
+                                lastModifiedDate: new Date(),
+                                storagePath: path.storagePath
+                            });
+
+                            idb_.put(newFileEntry, path.storagePath, successCallback, errorCallback);
+                        }, errorCallback);
+                    } else {
+                        if (errorCallback) {
+                            errorCallback(FileError.INVALID_MODIFICATION_ERR);
+                        }
+                    }
+                } else if ((!options.create || options.create === false) && !fileEntry) {
+                    // If create is not true and the path doesn't exist, getFile must fail.
+                    if (errorCallback) {
+                        errorCallback(FileError.NOT_FOUND_ERR);
+                    }
+                } else if ((!options.create || options.create === false) && fileEntry &&
+                    fileEntry.isDirectory) {
+                    // If create is not true and the path exists, but is a directory, getFile
+                    // must fail.
+                    if (errorCallback) {
+                        errorCallback(FileError.TYPE_MISMATCH_ERR);
+                    }
+                } else {
+                    // Otherwise, if no other error occurs, getFile must return a FileEntry
+                    // corresponding to path.
+
+                    successCallback(fileEntryFromIdbEntry(fileEntry));
                 }
-            } else if ((!options.create || options.create === false) && !fileEntry) {
-                // If create is not true and the path doesn't exist, getFile must fail.
-                if (errorCallback) {
-                    errorCallback(FileError.NOT_FOUND_ERR);
-                }
-            } else if ((!options.create || options.create === false) && fileEntry &&
-                fileEntry.isDirectory) {
-                // If create is not true and the path exists, but is a directory, getFile
-                // must fail.
-                if (errorCallback) {
-                    errorCallback(FileError.TYPE_MISMATCH_ERR);
-                }
-            } else {
-                // Otherwise, if no other error occurs, getFile must return a FileEntry
-                // corresponding to path.
+            }, errorCallback);
+        };
 
-                successCallback(fileEntryFromIdbEntry(fileEntry));
-            }
-        }, errorCallback);
-    };
-
-    exports.getFileMetadata = function(successCallback, errorCallback, args) {
-        var fullPath = args[0];
-
-        exports.getFile(function(fileEntry) {
-            successCallback(new File(fileEntry.file_.name, fileEntry.fullPath, '', fileEntry.file_.lastModifiedDate,
-                fileEntry.file_.size));
-        }, errorCallback, [fullPath, null]);
-    };
-
-    exports.getMetadata = function(successCallback, errorCallback, args) {
-        exports.getFile(function (fileEntry) {
-            successCallback(
-                {
-                    modificationTime: fileEntry.file_.lastModifiedDate,
-                    size: fileEntry.file_.lastModifiedDate
-                });
-        }, errorCallback, args);
-    };
-
-    exports.setMetadata = function(successCallback, errorCallback, args) {
-        var fullPath = args[0];
-        var metadataObject = args[1];
-
-        exports.getFile(function (fileEntry) {
-              fileEntry.file_.lastModifiedDate = metadataObject.modificationTime;
-              idb_.put(fileEntry, fileEntry.file_.storagePath, successCallback, errorCallback);
-        }, errorCallback, [fullPath, null]);
-    };
-
-    exports.write = function(successCallback, errorCallback, args) {
-        var fileName = args[0],
-            data = args[1],
-            position = args[2],
-            isBinary = args[3]; // jshint ignore: line
-
-        if (!data) {
-            errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR);
-            return;
-        }
+        exports.getFileMetadata = function(successCallback, errorCallback, args) {
+            var fullPath = args[0];
 
-        if (typeof data === 'string' || data instanceof String) {
-            data = new Blob([data]);
-        }
+            exports.getFile(function(fileEntry) {
+                successCallback(new File(fileEntry.file_.name, fileEntry.fullPath, '', fileEntry.file_.lastModifiedDate,
+                    fileEntry.file_.size));
+            }, errorCallback, [fullPath, null]);
+        };
 
-        exports.getFile(function(fileEntry) {
-            var blob_ = fileEntry.file_.blob_;
+        exports.getMetadata = function(successCallback, errorCallback, args) {
+            exports.getFile(function (fileEntry) {
+                successCallback(
+                    {
+                        modificationTime: fileEntry.file_.lastModifiedDate,
+                        size: fileEntry.file_.lastModifiedDate
+                    });
+            }, errorCallback, args);
+        };
 
-            if (!blob_) {
-                blob_ = new Blob([data], {type: data.type});
-            } else {
-                // Calc the head and tail fragments
-                var head = blob_.slice(0, position);
-                var tail = blob_.slice(position + (data.size || data.byteLength));
-
-                // Calc the padding
-                var padding = position - head.size;
-                if (padding < 0) {
-                    padding = 0;
-                }
+        exports.setMetadata = function(successCallback, errorCallback, args) {
+            var fullPath = args[0];
+            var metadataObject = args[1];
+
+            exports.getFile(function (fileEntry) {
+                  fileEntry.file_.lastModifiedDate = metadataObject.modificationTime;
+                  idb_.put(fileEntry, fileEntry.file_.storagePath, successCallback, errorCallback);
+            }, errorCallback, [fullPath, null]);
+        };
 
-                // Do the "write". In fact, a full overwrite of the Blob.
-                blob_ = new Blob([head, new Uint8Array(padding), data, tail],
-                    {type: data.type});
+        exports.write = function(successCallback, errorCallback, args) {
+            var fileName = args[0],
+                data = args[1],
+                position = args[2],
+                isBinary = args[3]; // jshint ignore: line
+
+            if (!data) {
+                errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR);
+                return;
             }
 
-            // Set the blob we're writing on this file entry so we can recall it later.
-            fileEntry.file_.blob_ = blob_;
-            fileEntry.file_.lastModifiedDate = new Date() || null;
-            fileEntry.file_.size = blob_.size;
-            fileEntry.file_.name = blob_.name;
-            fileEntry.file_.type = blob_.type;
+            if (typeof data === 'string' || data instanceof String) {
+                data = new Blob([data]);
+            }
 
-            idb_.put(fileEntry, fileEntry.file_.storagePath, function() {
-                successCallback(data.size || data.byteLength);
-            }, errorCallback);
-        }, errorCallback, [fileName, null]);
-    };
+            exports.getFile(function(fileEntry) {
+                var blob_ = fileEntry.file_.blob_;
 
-    exports.readAsText = function(successCallback, errorCallback, args) {
-        var fileName = args[0],
-            enc = args[1],
-            startPos = args[2],
-            endPos = args[3];
+                if (!blob_) {
+                    blob_ = new Blob([data], {type: data.type});
+                } else {
+                    // Calc the head and tail fragments
+                    var head = blob_.slice(0, position);
+                    var tail = blob_.slice(position + (data.size || data.byteLength));
+
+                    // Calc the padding
+                    var padding = position - head.size;
+                    if (padding < 0) {
+                        padding = 0;
+                    }
 
-        readAs('text', fileName, enc, startPos, endPos, successCallback, errorCallback);
-    };
+                    // Do the "write". In fact, a full overwrite of the Blob.
+                    blob_ = new Blob([head, new Uint8Array(padding), data, tail],
+                        {type: data.type});
+                }
 
-    exports.readAsDataURL = function(successCallback, errorCallback, args) {
-        var fileName = args[0],
-            startPos = args[1],
-            endPos = args[2];
+                // Set the blob we're writing on this file entry so we can recall it later.
+                fileEntry.file_.blob_ = blob_;
+                fileEntry.file_.lastModifiedDate = new Date() || null;
+                fileEntry.file_.size = blob_.size;
+                fileEntry.file_.name = blob_.name;
+                fileEntry.file_.type = blob_.type;
+
+                idb_.put(fileEntry, fileEntry.file_.storagePath, function() {
+                    successCallback(data.size || data.byteLength);
+                }, errorCallback);
+            }, errorCallback, [fileName, null]);
+        };
 
-        readAs('dataURL', fileName, null, startPos, endPos, successCallback, errorCallback);
-    };
+        exports.readAsText = function(successCallback, errorCallback, args) {
+            var fileName = args[0],
+                enc = args[1],
+                startPos = args[2],
+                endPos = args[3];
 
-    exports.readAsBinaryString = function(successCallback, errorCallback, args) {
-        var fileName = args[0],
-            startPos = args[1],
-            endPos = args[2];
+            readAs('text', fileName, enc, startPos, endPos, successCallback, errorCallback);
+        };
 
-        readAs('binaryString', fileName, null, startPos, endPos, successCallback, errorCallback);
-    };
+        exports.readAsDataURL = function(successCallback, errorCallback, args) {
+            var fileName = args[0],
+                startPos = args[1],
+                endPos = args[2];
 
-    exports.readAsArrayBuffer = function(successCallback, errorCallback, args) {
-        var fileName = args[0],
-            startPos = args[1],
-            endPos = args[2];
+            readAs('dataURL', fileName, null, startPos, endPos, successCallback, errorCallback);
+        };
 
-        readAs('arrayBuffer', fileName, null, startPos, endPos, successCallback, errorCallback);
-    };
+        exports.readAsBinaryString = function(successCallback, errorCallback, args) {
+            var fileName = args[0],
+                startPos = args[1],
+                endPos = args[2];
 
-    exports.removeRecursively = exports.remove = function(successCallback, errorCallback, args) {
-        if (typeof successCallback !== 'function') {
-            throw Error('Expected successCallback argument.');
-        }
+            readAs('binaryString', fileName, null, startPos, endPos, successCallback, errorCallback);
+        };
 
-        var fullPath = resolveToFullPath_(args[0]).storagePath;
-        if (fullPath === pathsPrefix.cacheDirectory || fullPath === pathsPrefix.dataDirectory) {
-            errorCallback(FileError.NO_MODIFICATION_ALLOWED_ERR);
-            return;
-        }
+        exports.readAsArrayBuffer = function(successCallback, errorCallback, args) {
+            var fileName = args[0],
+                startPos = args[1],
+                endPos = args[2];
 
-        function deleteEntry(isDirectory) {
-            // TODO: This doesn't protect against directories that have content in it.
-            // Should throw an error instead if the dirEntry is not empty.
-            idb_['delete'](fullPath, function() {
-                successCallback();
-            }, function() {
-                    if (errorCallback) { errorCallback(); }
-            }, isDirectory);
-        }
+            readAs('arrayBuffer', fileName, null, startPos, endPos, successCallback, errorCallback);
+        };
 
-        // We need to to understand what we are deleting:
-        exports.getDirectory(function(entry) {
-            deleteEntry(entry.isDirectory);
-        }, function(){
-            //DirectoryEntry was already deleted or entry is FileEntry
-            deleteEntry(false);
-        }, [fullPath, null, {create: false}]);
-    };
-
-    exports.getDirectory = function(successCallback, errorCallback, args) {
-        var fullPath = args[0];
-        var path = args[1];
-        var options = args[2];
-
-        // Create an absolute path if we were handed a relative one.
-        path = resolveToFullPath_(fullPath, path);
-
-        idb_.get(path.storagePath, function(folderEntry) {
-            if (!options) {
-                options = {};
+        exports.removeRecursively = exports.remove = function(successCallback, errorCallback, args) {
+            if (typeof successCallback !== 'function') {
+                throw Error('Expected successCallback argument.');
             }
 
-            if (options.create === true && options.exclusive === true && folderEntry) {
-                // If create and exclusive are both true, and the path already exists,
-                // getDirectory must fail.
-                if (errorCallback) {
-                    errorCallback(FileError.PATH_EXISTS_ERR);
-                }
-                // There is a strange bug in mobilespec + FF, which results in coming to multiple else-if's
-                // so we are shielding from it with returns.
+            var fullPath = resolveToFullPath_(args[0]).storagePath;
+            if (fullPath === pathsPrefix.cacheDirectory || fullPath === pathsPrefix.dataDirectory) {
+                errorCallback(FileError.NO_MODIFICATION_ALLOWED_ERR);
                 return;
             }
 
-            if (options.create === true && !folderEntry) {
-                // If create is true, the path doesn't exist, and no other error occurs,
-                // getDirectory must create it as a zero-length file and return a corresponding
-                // MyDirectoryEntry.
-                var dirEntry = new DirectoryEntry(path.fileName, path.fullPath, new FileSystem(path.fsName, fs_.root));
-
-                idb_.put(dirEntry, path.storagePath, successCallback, errorCallback);
-                return;
+            function deleteEntry(isDirectory) {
+                // TODO: This doesn't protect against directories that have content in it.
+                // Should throw an error instead if the dirEntry is not empty.
+                idb_['delete'](fullPath, function() {
+                    successCallback();
+                }, function() {
+                        if (errorCallback) { errorCallback(); }
+                }, isDirectory);
             }
 
-            if (options.create === true && folderEntry) {
+            // We need to to understand what we are deleting:
+            exports.getDirectory(function(entry) {
+                deleteEntry(entry.isDirectory);
+            }, function(){
+                //DirectoryEntry was already deleted or entry is FileEntry
+                deleteEntry(false);
+            }, [fullPath, null, {create: false}]);
+        };
 
-                if (folderEntry.isDirectory) {
-                    // IDB won't save methods, so we need re-create the MyDirectoryEntry.
-                    successCallback(new DirectoryEntry(folderEntry.name, folderEntry.fullPath, folderEntry.filesystem));
-                } else {
+        exports.getDirectory = function(successCallback, errorCallback, args) {
+            var fullPath = args[0];
+            var path = args[1];
+            var options = args[2];
+
+            // Create an absolute path if we were handed a relative one.
+            path = resolveToFullPath_(fullPath, path);
+
+            idb_.get(path.storagePath, function(folderEntry) {
+                if (!options) {
+                    options = {};
+                }
+
+                if (options.create === true && options.exclusive === true && folderEntry) {
+                    // If create and exclusive are both true, and the path already exists,
+                    // getDirectory must fail.
                     if (errorCallback) {
-                        errorCallback(FileError.INVALID_MODIFICATION_ERR);
+                        errorCallback(FileError.PATH_EXISTS_ERR);
                     }
+                    // There is a strange bug in mobilespec + FF, which results in coming to multiple else-if's
+                    // so we are shielding from it with returns.
+                    return;
                 }
-                return;
-            }
 
-            if ((!options.create || options.create === false) && !folderEntry) {
-                // Handle root special. It should always exist.
-                if (path.fullPath === DIR_SEPARATOR) {
-                    successCallback(fs_.root);
+                if (options.create === true && !folderEntry) {
+                    // If create is true, the path doesn't exist, and no other error occurs,
+                    // getDirectory must create it as a zero-length file and return a corresponding
+                    // MyDirectoryEntry.
+                    var dirEntry = new DirectoryEntry(path.fileName, path.fullPath, new FileSystem(path.fsName, fs_.root));
+
+                    idb_.put(dirEntry, path.storagePath, successCallback, errorCallback);
                     return;
                 }
 
-                // If create is not true and the path doesn't exist, getDirectory must fail.
-                if (errorCallback) {
-                    errorCallback(FileError.NOT_FOUND_ERR);
-                }
+                if (options.create === true && folderEntry) {
 
-                return;
-            }
-            if ((!options.create || options.create === false) && folderEntry && folderEntry.isFile) {
-                // If create is not true and the path exists, but is a file, getDirectory
-                // must fail.
-                if (errorCallback) {
-                    errorCallback(FileError.TYPE_MISMATCH_ERR);
+                    if (folderEntry.isDirectory) {
+                        // IDB won't save methods, so we need re-create the MyDirectoryEntry.
+                        successCallback(new DirectoryEntry(folderEntry.name, folderEntry.fullPath, folderEntry.filesystem));
+                    } else {
+                        if (errorCallback) {
+                            errorCallback(FileError.INVALID_MODIFICATION_ERR);
+                        }
+                    }
+                    return;
                 }
-                return;
-            }
 
-            // Otherwise, if no other error occurs, getDirectory must return a
-            // MyDirectoryEntry corresponding to path.
+                if ((!options.create || options.create === false) && !folderEntry) {
+                    // Handle root special. It should always exist.
+                    if (path.fullPath === DIR_SEPARATOR) {
+                        successCallback(fs_.root);
+                        return;
+                    }
 
-            // IDB won't' save methods, so we need re-create MyDirectoryEntry.
-            successCallback(new DirectoryEntry(folderEntry.name, folderEntry.fullPath, folderEntry.filesystem));
-        }, errorCallback);
-    };
+                    // If create is not true and the path doesn't exist, getDirectory must fail.
+                    if (errorCallback) {
+                        errorCallback(FileError.NOT_FOUND_ERR);
+                    }
 
-    exports.getParent = function(successCallback, errorCallback, args) {
-        if (typeof successCallback !== 'function') {
-            throw Error('Expected successCallback argument.');
-        }
+                    return;
+                }
+                if ((!options.create || options.create === false) && folderEntry && folderEntry.isFile) {
+                    // If create is not true and the path exists, but is a file, getDirectory
+                    // must fail.
+                    if (errorCallback) {
+                        errorCallback(FileError.TYPE_MISMATCH_ERR);
+                    }
+                    return;
+                }
 
-        var fullPath = args[0];
-        //fullPath is like this:
-        //file:///persistent/path/to/file or
-        //file:///persistent/path/to/directory/
+                // Otherwise, if no other error occurs, getDirectory must return a
+                // MyDirectoryEntry corresponding to path.
 
-        if (fullPath === DIR_SEPARATOR || fullPath === pathsPrefix.cacheDirectory ||
-            fullPath === pathsPrefix.dataDirectory) {
-            successCallback(fs_.root);
-            return;
-        }
+                // IDB won't' save methods, so we need re-create MyDirectoryEntry.
+                successCallback(new DirectoryEntry(folderEntry.name, folderEntry.fullPath, folderEntry.filesystem));
+            }, errorCallback);
+        };
 
-        //To delete all slashes at the end
-        while (fullPath[fullPath.length - 1] === '/') {
-            fullPath = fullPath.substr(0, fullPath.length - 1);
-        }
+        exports.getParent = function(successCallback, errorCallback, args) {
+            if (typeof successCallback !== 'function') {
+                throw Error('Expected successCallback argument.');
+            }
 
-        var pathArr = fullPath.split(DIR_SEPARATOR);
-        pathArr.pop();
-        var parentName = pathArr.pop();
-        var path = pathArr.join(DIR_SEPARATOR) + DIR_SEPARATOR;
+            var fullPath = args[0];
+            //fullPath is like this:
+            //file:///persistent/path/to/file or
+            //file:///persistent/path/to/directory/
 
-        //To get parent of root files
-        var joined = path + parentName + DIR_SEPARATOR;//is like this: file:///persistent/
-        if (joined === pathsPrefix.cacheDirectory || joined === pathsPrefix.dataDirectory) {
-            exports.getDirectory(successCallback, errorCallback, [joined, DIR_SEPARATOR, {create: false}]);
-            return;
-        }
+            if (fullPath === DIR_SEPARATOR || fullPath === pathsPrefix.cacheDirectory ||
+                fullPath === pathsPrefix.dataDirectory) {
+                successCallback(fs_.root);
+                return;
+            }
 
-        exports.getDirectory(successCallback, errorCallback, [path, parentName, {create: false}]);
-    };
+            //To delete all slashes at the end
+            while (fullPath[fullPath.length - 1] === '/') {
+                fullPath = fullPath.substr(0, fullPath.length - 1);
+            }
 
-    exports.copyTo = function(successCallback, errorCallback, args) {
-        var srcPath = args[0];
-        var parentFullPath = args[1];
-        var name = args[2];
+            var pathArr = fullPath.split(DIR_SEPARATOR);
+            pathArr.pop();
+            var parentName = pathArr.pop();
+            var path = pathArr.join(DIR_SEPARATOR) + DIR_SEPARATOR;
 
-        if (name.indexOf('/') !== -1 || srcPath === parentFullPath + name) {
-            if (errorCallback) {
-                errorCallback(FileError.INVALID_MODIFICATION_ERR);
+            //To get parent of root files
+            var joined = path + parentName + DIR_SEPARATOR;//is like this: file:///persistent/
+            if (joined === pathsPrefix.cacheDirectory || joined === pathsPrefix.dataDirectory) {
+                exports.getDirectory(successCallback, errorCallback, [joined, DIR_SEPARATOR, {create: false}]);
+                return;
             }
 
-            return;
-        }
+            exports.getDirectory(successCallback, errorCallback, [path, parentName, {create: false}]);
+        };
 
-        // Read src file
-        exports.getFile(function(srcFileEntry) {
+        exports.copyTo = function(successCallback, errorCallback, args) {
+            var srcPath = args[0];
+            var parentFullPath = args[1];
+            var name = args[2];
 
-            var path = resolveToFullPath_(parentFullPath);
-            //Check directory
-            exports.getDirectory(function() {
+            if (name.indexOf('/') !== -1 || srcPath === parentFullPath + name) {
+                if (errorCallback) {
+                    errorCallback(FileError.INVALID_MODIFICATION_ERR);
+                }
 
-                // Create dest file
-                exports.getFile(function(dstFileEntry) {
+                return;
+            }
 
-                    exports.write(function() {
-                        successCallback(dstFileEntry);
-                    }, errorCallback, [dstFileEntry.file_.storagePath, srcFileEntry.file_.blob_, 0]);
+            // Read src file
+            exports.getFile(function(srcFileEntry) {
 
-                }, errorCallback, [parentFullPath, name, {create: true}]);
+                var path = resolveToFullPath_(parentFullPath);
+                //Check directory
+                exports.getDirectory(function() {
 
-            }, function() { if (errorCallback) { errorCallback(FileError.NOT_FOUND_ERR); }},
-            [path.storagePath, null, {create:false}]);
+                    // Create dest file
+                    exports.getFile(function(dstFileEntry) {
 
-        }, errorCallback, [srcPath, null]);
-    };
+                        exports.write(function() {
+                            successCallback(dstFileEntry);
+                        }, errorCallback, [dstFileEntry.file_.storagePath, srcFileEntry.file_.blob_, 0]);
 
-    exports.moveTo = function(successCallback, errorCallback, args) {
-        var srcPath = args[0];
-        // parentFullPath and name parameters is ignored because
-        // args is being passed downstream to exports.copyTo method
-        var parentFullPath = args[1]; // jshint ignore: line
-        var name = args[2]; // jshint ignore: line
+                    }, errorCallback, [parentFullPath, name, {create: true}]);
 
-        exports.copyTo(function (fileEntry) {
+                }, function() { if (errorCallback) { errorCallback(FileError.NOT_FOUND_ERR); }},
+                [path.storagePath, null, {create:false}]);
 
-            exports.remove(function () {
-                successCallback(fileEntry);
-            }, errorCallback, [srcPath]);
+            }, errorCallback, [srcPath, null]);
+        };
 
-        }, errorCallback, args);
-    };
+        exports.moveTo = function(successCallback, errorCallback, args) {
+            var srcPath = args[0];
+            // parentFullPath and name parameters is ignored because
+            // args is being passed downstream to exports.copyTo method
+            var parentFullPath = args[1]; // jshint ignore: line
+            var name = args[2]; // jshint ignore: line
 
-    exports.resolveLocalFileSystemURI = function(successCallback, errorCallback, args) {
-        var path = args[0];
+            exports.copyTo(function (fileEntry) {
 
-        // Ignore parameters
-        if (path.indexOf('?') !== -1) {
-            path = String(path).split("?")[0];
-        }
+                exports.remove(function () {
+                    successCallback(fileEntry);
+                }, errorCallback, [srcPath]);
 
-        // support for encodeURI
-        if (/\%5/g.test(path) || /\%20/g.test(path)) {
-            path = decodeURI(path);
-        }
+            }, errorCallback, args);
+        };
 
-        if (path.trim()[0] === '/') {
-            errorCallback && errorCallback(FileError.ENCODING_ERR);
-            return;
-        }
+        exports.resolveLocalFileSystemURI = function(successCallback, errorCallback, args) {
+            var path = args[0];
 
-        //support for cdvfile
-        if (path.trim().substr(0,7) === "cdvfile") {
-            if (path.indexOf("cdvfile://localhost") === -1) {
-                errorCallback && errorCallback(FileError.ENCODING_ERR);
-                return;
+            // Ignore parameters
+            if (path.indexOf('?') !== -1) {
+                path = String(path).split("?")[0];
             }
 
-            var indexPersistent = path.indexOf("persistent");
-            var indexTemporary = path.indexOf("temporary");
+            // support for encodeURI
+            if (/\%5/g.test(path) || /\%20/g.test(path)) {
+                path = decodeURI(path);
+            }
 
-            //cdvfile://localhost/persistent/path/to/file
-            if (indexPersistent !== -1) {
-                path =  "file:///persistent" + path.substr(indexPersistent + 10);
-            } else if (indexTemporary !== -1) {
-                path = "file:///temporary" + path.substr(indexTemporary + 9);
-            } else {
+            if (path.trim()[0] === '/') {
                 errorCallback && errorCallback(FileError.ENCODING_ERR);
                 return;
             }
-        }
 
-        // to avoid path form of '///path/to/file'
-        function handlePathSlashes(path) {
-            var cutIndex  = 0;
-            for (var i = 0; i < path.length - 1; i++) {
-                if (path[i] === DIR_SEPARATOR && path[i + 1] === DIR_SEPARATOR) {
-                    cutIndex = i + 1;
-                } else break;
-            }
+            //support for cdvfile
+            if (path.trim().substr(0,7) === "cdvfile") {
+                if (path.indexOf("cdvfile://localhost") === -1) {
+                    errorCallback && errorCallback(FileError.ENCODING_ERR);
+                    return;
+                }
 
-            return path.substr(cutIndex);
-        }
+                var indexPersistent = path.indexOf("persistent");
+                var indexTemporary = path.indexOf("temporary");
 
-        // Handle localhost containing paths (see specs )
-        if (path.indexOf('file://localhost/') === 0) {
-            path = path.replace('file://localhost/', 'file:///');
-        }
+                //cdvfile://localhost/persistent/path/to/file
+                if (indexPersistent !== -1) {
+                    path =  "file:///persistent" + path.substr(indexPersistent + 10);
+                } else if (indexTemporary !== -1) {
+                    path = "file:///temporary" + path.substr(indexTemporary + 9);
+                } else {
+                    errorCallback && errorCallback(FileError.ENCODING_ERR);
+                    return;
+                }
+            }
 
-        if (path.indexOf(pathsPrefix.dataDirectory) === 0) {
-            path = path.substring(pathsPrefix.dataDirectory.length - 1);
-            path = handlePathSlashes(path);
-
-            exports.requestFileSystem(function() {
-                exports.getFile(successCallback, function() {
-                    exports.getDirectory(successCallback, errorCallback, [pathsPrefix.dataDirectory, path,
-                    {create: false}]);
-                }, [pathsPrefix.dataDirectory, path, {create: false}]);
-            }, errorCallback, [LocalFileSystem.PERSISTENT]);
-        } else if (path.indexOf(pathsPrefix.cacheDirectory) === 0) {
-            path = path.substring(pathsPrefix.cacheDirectory.length - 1);
-            path = handlePathSlashes(path);
-
-            exports.requestFileSystem(function() {
-                exports.getFile(successCallback, function() {
-                    exports.getDirectory(successCallback, errorCallback, [pathsPrefix.cacheDirectory, path,
-                    {create: false}]);
-                }, [pathsPrefix.cacheDirectory, path, {create: false}]);
-            }, errorCallback, [LocalFileSystem.TEMPORARY]);
-        } else if (path.indexOf(pathsPrefix.applicationDirectory) === 0) {
-            path = path.substring(pathsPrefix.applicationDirectory.length);
-            //TODO: need to cut out redundant slashes?
-
-            var xhr = new XMLHttpRequest();
-            xhr.open("GET", path, true);
-            xhr.onreadystatechange = function () {
-                if (xhr.status === 200 && xhr.readyState === 4) {
-                    exports.requestFileSystem(function(fs) {
-                        fs.name = location.hostname;
-
-                        //TODO: need to call exports.getFile(...) to handle errors correct
-                        fs.root.getFile(path, {create: true}, writeFile, errorCallback);
-                    }, errorCallback, [LocalFileSystem.PERSISTENT]);
+            // to avoid path form of '///path/to/file'
+            function handlePathSlashes(path) {
+                var cutIndex  = 0;
+                for (var i = 0; i < path.length - 1; i++) {
+                    if (path[i] === DIR_SEPARATOR && path[i + 1] === DIR_SEPARATOR) {
+                        cutIndex = i + 1;
+                    } else break;
                 }
-            };
 
-            xhr.onerror = function () {
-                errorCallback && errorCallback(FileError.NOT_READABLE_ERR);
-            };
+                return path.substr(cutIndex);
+            }
 
-            xhr.send();
-        } else {
-            errorCallback && errorCallback(FileError.NOT_FOUND_ERR);
-        }
+            // Handle localhost containing paths (see specs )
+            if (path.indexOf('file://localhost/') === 0) {
+                path = path.replace('file://localhost/', 'file:///');
+            }
 
-        function writeFile(entry) {
-            entry.createWriter(function (fileWriter) {
-                fileWriter.onwriteend = function (evt) {
-                    if (!evt.target.error) {
-                        entry.filesystemName = location.hostname;
-                        successCallback(entry);
+            if (path.indexOf(pathsPrefix.dataDirectory) === 0) {
+                path = path.substring(pathsPrefix.dataDirectory.length - 1);
+                path = handlePathSlashes(path);
+
+                exports.requestFileSystem(function() {
+                    exports.getFile(successCallback, function() {
+                        exports.getDirectory(successCallback, errorCallback, [pathsPrefix.dataDirectory, path,
+                        {create: false}]);
+                    }, [pathsPrefix.dataDirectory, path, {create: false}]);
+                }, errorCallback, [LocalFileSystem.PERSISTENT]);
+            } else if (path.indexOf(pathsPrefix.cacheDirectory) === 0) {
+                path = path.substring(pathsPrefix.cacheDirectory.length - 1);
+                path = handlePathSlashes(path);
+
+                exports.requestFileSystem(function() {
+                    exports.getFile(successCallback, function() {
+                        exports.getDirectory(successCallback, errorCallback, [pathsPrefix.cacheDirectory, path,
+                        {create: false}]);
+                    }, [pathsPrefix.cacheDirectory, path, {create: false}]);
+                }, errorCallback, [LocalFileSystem.TEMPORARY]);
+            } else if (path.indexOf(pathsPrefix.applicationDirectory) === 0) {
+                path = path.substring(pathsPrefix.applicationDirectory.length);
+                //TODO: need to cut out redundant slashes?
+
+                var xhr = new XMLHttpRequest();
+                xhr.open("GET", path, true);
+                xhr.onreadystatechange = function () {
+                    if (xhr.status === 200 && xhr.readyState === 4) {
+                        exports.requestFileSystem(function(fs) {
+                            fs.name = location.hostname;
+
+                            //TODO: need to call exports.getFile(...) to handle errors correct
+                            fs.root.getFile(path, {create: true}, writeFile, errorCallback);
+                        }, errorCallback, [LocalFileSystem.PERSISTENT]);
                     }
                 };
-                fileWriter.onerror = function () {
+
+                xhr.onerror = function () {
                     errorCallback && errorCallback(FileError.NOT_READABLE_ERR);
                 };
-                fileWriter.write(new Blob([xhr.response]));
-            }, errorCallback);
-        }
-    };
-
-    exports.requestAllPaths = function(successCallback) {
-        successCallback(pathsPrefix);
-    };
-
-/*** Helpers ***/
-
-    /**
-     * Interface to wrap the native File interface.
-     *
-     * This interface is necessary for creating zero-length (empty) files,
-     * something the Filesystem API allows you to do. Unfortunately, File's
-     * constructor cannot be called directly, making it impossible to instantiate
-     * an empty File in JS.
-     *
-     * @param {Object} opts Initial values.
-     * @constructor
-     */
-    function MyFile(opts) {
-        var blob_ = new Blob();
-
-        this.size = opts.size || 0;
-        this.name = opts.name || '';
-        this.type = opts.type || '';
-        this.lastModifiedDate = opts.lastModifiedDate || null;
-        this.storagePath = opts.storagePath || '';
-
-        // Need some black magic to correct the object's size/name/type based on the
-        // blob that is saved.
-        Object.defineProperty(this, 'blob_', {
-            enumerable: true,
-            get: function() {
-                return blob_;
-            },
-            set: function(val) {
-                blob_ = val;
-                this.size = blob_.size;
-                this.name = blob_.name;
-                this.type = blob_.type;
-                this.lastModifiedDate = blob_.lastModifiedDate;
-            }.bind(this)
-        });
-    }
 
-    MyFile.prototype.constructor = MyFile;
+                xhr.send();
+            } else {
+                errorCallback && errorCallback(FileError.NOT_FOUND_ERR);
+            }
+
+            function writeFile(entry) {
+                entry.createWriter(function (fileWriter) {
+                    fileWriter.onwriteend = function (evt) {
+                        if (!evt.target.error) {
+                            entry.filesystemName = location.hostname;
+                            successCallback(entry);
+                        }
+                    };
+                    fileWriter.onerror = function () {
+                        errorCallback && errorCallback(FileError.NOT_READABLE_ERR);
+                    };
+                    fileWriter.write(new Blob([xhr.response]));
+                }, errorCallback);
+            }
+        };
 
-    // When saving an entry, the fullPath should always lead with a slash and never
-    // end with one (e.g. a directory). Also, resolve '.' and '..' to an absolute
-    // one. This method ensures path is legit!
-    function resolveToFullPath_(cwdFullPath, path) {
-        path = path || '';
-        var fullPath = path;
-        var prefix = '';
+        exports.requestAllPaths = function(successCallback) {
+            successCallback(pathsPrefix);
+        };
 
-        cwdFullPath = cwdFullPath || DIR_SEPARATOR;
-        if (cwdFullPath.indexOf(FILESYSTEM_PREFIX) === 0) {
-            prefix = cwdFullPath.substring(0, cwdFullPath.indexOf(DIR_SEPARATOR, FILESYSTEM_PREFIX.length));
-            cwdFullPath = cwdFullPath.substring(cwdFullPath.indexOf(DIR_SEPARATOR, FILESYSTEM_PREFIX.length));
+    /*** Helpers ***/
+
+        /**
+         * Interface to wrap the native File interface.
+         *
+         * This interface is necessary for creating zero-length (empty) files,
+         * something the Filesystem API allows you to do. Unfortunately, File's
+         * constructor cannot be called directly, making it impossible to instantiate
+         * an empty File in JS.
+         *
+         * @param {Object} opts Initial values.
+         * @constructor
+         */
+        function MyFile(opts) {
+            var blob_ = new Blob();
+
+            this.size = opts.size || 0;
+            this.name = opts.name || '';
+            this.type = opts.type || '';
+            this.lastModifiedDate = opts.lastModifiedDate || null;
+            this.storagePath = opts.storagePath || '';
+
+            // Need some black magic to correct the object's size/name/type based on the
+            // blob that is saved.
+            Object.defineProperty(this, 'blob_', {
+                enumerable: true,
+                get: function() {
+                    return blob_;
+                },
+                set: function(val) {
+                    blob_ = val;
+                    this.size = blob_.size;
+                    this.name = blob_.name;
+                    this.type = blob_.type;
+                    this.lastModifiedDate = blob_.lastModifiedDate;
+                }.bind(this)
+            });
         }
 
-        var relativePath = path[0] !== DIR_SEPARATOR;
-        if (relativePath) {
-            fullPath = cwdFullPath;
-            if (cwdFullPath !== DIR_SEPARATOR) {
-                fullPath += DIR_SEPARATOR + path;
-            } else {
-                fullPath += path;
+        MyFile.prototype.constructor = MyFile;
+
+        // When saving an entry, the fullPath should always lead with a slash and never
+        // end with one (e.g. a directory). Also, resolve '.' and '..' to an absolute
+        // one. This method ensures path is legit!
+        function resolveToFullPath_(cwdFullPath, path) {
+            path = path || '';
+            var fullPath = path;
+            var prefix = '';
+
+            cwdFullPath = cwdFullPath || DIR_SEPARATOR;
+            if (cwdFullPath.indexOf(FILESYSTEM_PREFIX) === 0) {
+                prefix = cwdFullPath.substring(0, cwdFullPath.indexOf(DIR_SEPARATOR, FILESYSTEM_PREFIX.length));
+                cwdFullPath = cwdFullPath.substring(cwdFullPath.indexOf(DIR_SEPARATOR, FILESYSTEM_PREFIX.length));
+            }
+
+            var relativePath = path[0] !== DIR_SEPARATOR;
+            if (relativePath) {
+                fullPath = cwdFullPath;
+                if (cwdFullPath !== DIR_SEPARATOR) {
+                    fullPath += DIR_SEPARATOR + path;
+                } else {
+                    fullPath += path;
+                }
             }
-        }
 
-        // Remove doubled separator substrings
-        var re = new RegExp(DIR_SEPARATOR + DIR_SEPARATOR, 'g');
-        fullPath = fullPath.replace(re, DIR_SEPARATOR);
-
-        // Adjust '..'s by removing parent directories when '..' flows in path.
-        var parts = fullPath.split(DIR_SEPARATOR);
-        for (var i = 0; i < parts.length; ++i) {
-            var part = parts[i];
-            if (part === '..') {
-                parts[i - 1] = '';
-                parts[i] = '';
+            // Remove doubled separator substrings
+            var re = new RegExp(DIR_SEPARATOR + DIR_SEPARATOR, 'g');
+            fullPath = fullPath.replace(re, DIR_SEPARATOR);
+
+            // Adjust '..'s by removing parent directories when '..' flows in path.
+            var parts = fullPath.split(DIR_SEPARATOR);
+            for (var i = 0; i < parts.length; ++i) {
+                var part = parts[i];
+                if (part === '..') {
+                    parts[i - 1] = '';
+                    parts[i] = '';
+                }
             }
-        }
-        fullPath = parts.filter(function(el) {
-            return el;
-        }).join(DIR_SEPARATOR);
+            fullPath = parts.filter(function(el) {
+                return el;
+            }).join(DIR_SEPARATOR);
 
-        // Add back in leading slash.
-        if (fullPath[0] !== DIR_SEPARATOR) {
-            fullPath = DIR_SEPARATOR + fullPath;
-        }
+            // Add back in leading slash.
+            if (fullPath[0] !== DIR_SEPARATOR) {
+                fullPath = DIR_SEPARATOR + fullPath;
+            }
 
-        // Replace './' by current dir. ('./one/./two' -> one/two)
-        fullPath = fullPath.replace(/\.\//g, DIR_SEPARATOR);
+            // Replace './' by current dir. ('./one/./two' -> one/two)
+            fullPath = fullPath.replace(/\.\//g, DIR_SEPARATOR);
 
-        // Replace '//' with '/'.
-        fullPath = fullPath.replace(/\/\//g, DIR_SEPARATOR);
+            // Replace '//' with '/'.
+            fullPath = fullPath.replace(/\/\//g, DIR_SEPARATOR);
 
-        // Replace '/.' with '/'.
-        fullPath = fullPath.replace(/\/\./g, DIR_SEPARATOR);
+            // Replace '/.' with '/'.
+            fullPath = fullPath.replace(/\/\./g, DIR_SEPARATOR);
 
-        // Remove '/' if it appears on the end.
-        if (fullPath[fullPath.length - 1] === DIR_SEPARATOR &&
-            fullPath !== DIR_SEPARATOR) {
-            fullPath = fullPath.substring(0, fullPath.length - 1);
-        }
+            // Remove '/' if it appears on the end.
+            if (fullPath[fullPath.length - 1] === DIR_SEPARATOR &&
+                fullPath !== DIR_SEPARATOR) {
+                fullPath = fullPath.substring(0, fullPath.length - 1);
+            }
 
-        var storagePath = prefix + fullPath;
-        storagePath = decodeURI(storagePath);
-        fullPath = decodeURI(fullPath);
+            var storagePath = prefix + fullPath;
+            storagePath = decodeURI(storagePath);
+            fullPath = decodeURI(fullPath);
 
-        return {
-            storagePath: storagePath,
-            fullPath: fullPath,
-            fileName: fullPath.split(DIR_SEPARATOR).pop(),
-            fsName: prefix.split(DIR_SEPARATOR).pop()
-        };
-    }
+            return {
+                storagePath: storagePath,
+                fullPath: fullPath,
+                fileName: fullPath.split(DIR_SEPARATOR).pop(),
+                fsName: prefix.split(DIR_SEPARATOR).pop()
+            };
+        }
 
-    function fileEntryFromIdbEntry(fileEntry) {
-        // IDB won't save methods, so we need re-create the FileEntry.
-        var clonedFileEntry = new FileEntry(fileEntry.name, fileEntry.fullPath, fileEntry.filesystem);
-        clonedFileEntry.file_ = fileEntry.file_;
+        function fileEntryFromIdbEntry(fileEntry) {
+            // IDB won't save methods, so we need re-create the FileEntry.
+            var clonedFileEntry = new FileEntry(fileEntry.name, fileEntry.fullPath, fileEntry.filesystem);
+            clonedFileEntry.file_ = fileEntry.file_;
 
-        return clonedFileEntry;
-    }
+            return clonedFileEntry;
+        }
 
-    function readAs(what, fullPath, encoding, startPos, endPos, successCallback, errorCallback) {
-        exports.getFile(function(fileEntry) {
-            var fileReader = new FileReader(),
-                blob = fileEntry.file_.blob_.slice(startPos, endPos);
+        function readAs(what, fullPath, encoding, startPos, endPos, successCallback, errorCallback) {
+            exports.getFile(function(fileEntry) {
+                var fileReader = new FileReader(),
+                    blob = fileEntry.file_.blob_.slice(startPos, endPos);
 
-            fileReader.onload = function(e) {
-                successCallback(e.target.result);
-            };
+                fileReader.onload = function(e) {
+                    successCallback(e.target.result);
+                };
 
-            fileReader.onerror = errorCallback;
+                fileReader.onerror = errorCallback;
+
+                switch (what) {
+                    case 'text':
+                        fileReader.readAsText(blob, encoding);
+                        break;
+                    case 'dataURL':
+                        fileReader.readAsDataURL(blob);
+                        break;
+                    case 'arrayBuffer':
+                        fileReader.readAsArrayBuffer(blob);
+                        break;
+                    case 'binaryString':
+                        fileReader.readAsBinaryString(blob);
+                        break;
+                }
 
-            switch (what) {
-                case 'text':
-                    fileReader.readAsText(blob, encoding);
-                    break;
-                case 'dataURL':
-                    fileReader.readAsDataURL(blob);
-                    break;
-                case 'arrayBuffer':
-                    fileReader.readAsArrayBuffer(blob);
-                    break;
-                case 'binaryString':
-                    fileReader.readAsBinaryString(blob);
-                    break;
-            }
+            }, errorCallback, [fullPath, null]);
+        }
 
-        }, errorCallback, [fullPath, null]);
-    }
+    /*** Core logic to handle IDB operations ***/
 
-/*** Core logic to handle IDB operations ***/
+        idb_.open = function(dbName, successCallback, errorCallback) {
+            var self = this;
 
-    idb_.open = function(dbName, successCallback, errorCallback) {
-        var self = this;
+            // TODO: FF 12.0a1 isn't liking a db name with : in it.
+            var request = indexedDB.open(dbName.replace(':', '_')/*, 1 /*version*/);
 
-        // TODO: FF 12.0a1 isn't liking a db name with : in it.
-        var request = indexedDB.open(dbName.replace(':', '_')/*, 1 /*version*/);
+            request.onerror = errorCallback || onError;
 
-        request.onerror = errorCallback || onError;
+            request.onupgradeneeded = function(e) {
+                // First open was called or higher db version was used.
 
-        request.onupgradeneeded = function(e) {
-            // First open was called or higher db version was used.
+                // console.log('onupgradeneeded: oldVersion:' + e.oldVersion,
+                //           'newVersion:' + e.newVersion);
 
-            // console.log('onupgradeneeded: oldVersion:' + e.oldVersion,
-            //           'newVersion:' + e.newVersion);
+                self.db = e.target.result;
+                self.db.onerror = onError;
 
-            self.db = e.target.result;
-            self.db.onerror = onError;
+                if (!self.db.objectStoreNames.contains(FILE_STORE_)) {
+                    self.db.createObjectStore(FILE_STORE_/*,{keyPath: 'id', autoIncrement: true}*/);
+                }
+            };
 
-            if (!self.db.objectStoreNames.contains(FILE_STORE_)) {
-                self.db.createObjectStore(FILE_STORE_/*,{keyPath: 'id', autoIncrement: true}*/);
-            }
-        };
+            request.onsuccess = function(e) {
+                self.db = e.target.result;
+                self.db.onerror = onError;
+                successCallback(e);
+            };
 
-        request.onsuccess = function(e) {
-            self.db = e.target.result;
-            self.db.onerror = onError;
-            successCallback(e);
+            request.onblocked = errorCallback || onError;
         };
 
-        request.onblocked = errorCallback || onError;
-    };
-
-    idb_.close = function() {
-        this.db.close();
-        this.db = null;
-    };
+        idb_.close = function() {
+            this.db.close();
+            this.db = null;
+        };
 
-    idb_.get = function(fullPath, successCallback, errorCallback) {
-        if (!this.db) {
-            errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR);
-            return;
-        }
+        idb_.get = function(fullPath, successCallback, errorCallback) {
+            if (!this.db) {
+                errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR);
+                return;
+            }
 
-        var tx = this.db.transaction([FILE_STORE_], 'readonly');
+            var tx = this.db.transaction([FILE_STORE_], 'readonly');
 
-        var request = tx.objectStore(FILE_STORE_).get(fullPath);
+            var request = tx.objectStore(FILE_STORE_).get(fullPath);
 
-        tx.onabort = errorCallback || onError;
-        tx.oncomplete = function() {
-            successCallback(request.result);
+            tx.onabort = errorCallback || onError;
+            tx.oncomplete = function() {
+                successCallback(request.result);
+            };
         };
-    };
 
-    idb_.getAllEntries = function(fullPath, storagePath, successCallback, errorCallback) {
-        if (!this.db) {
-            errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR);
-            return;
-        }
+        idb_.getAllEntries = function(fullPath, storagePath, successCallback, errorCallback) {
+            if (!this.db) {
+                errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR);
+                return;
+            }
 
-        var results = [];
+            var results = [];
 
-        if (storagePath[storagePath.length - 1] === DIR_SEPARATOR) {
-            storagePath = storagePath.substring(0, storagePath.length - 1);
-        }
+            if (storagePath[storagePath.length - 1] === DIR_SEPARATOR) {
+                storagePath = storagePath.substring(0, storagePath.length - 1);
+            }
 
-        var range = IDBKeyRange.bound(storagePath + DIR_SEPARATOR + ' ',
-            storagePath + DIR_SEPARATOR + String.fromCharCode(unicodeLastChar));
+            var range = IDBKeyRange.bound(storagePath + DIR_SEPARATOR + ' ',
+                storagePath + DIR_SEPARATOR + String.fromCharCode(unicodeLastChar));
 
-        var tx = this.db.transaction([FILE_STORE_], 'readonly');
-        tx.onabort = errorCallback || onError;
-        tx.oncomplete = function() {
-            results = results.filter(function(val) {
-                var pathWithoutSlash = val.fullPath;
+            var tx = this.db.transaction([FILE_STORE_], 'readonly');
+            tx.onabort = errorCallback || onError;
+            tx.oncomplete = function() {
+                results = results.filter(function(val) {
+                    var pathWithoutSlash = val.fullPath;
 
-                if (val.fullPath[val.fullPath.length - 1] === DIR_SEPARATOR) {
-                    pathWithoutSlash = pathWithoutSlash.substr(0, pathWithoutSlash.length - 1);
-                }
+                    if (val.fullPath[val.fullPath.length - 1] === DIR_SEPARATOR) {
+                        pathWithoutSlash = pathWithoutSlash.substr(0, pathWithoutSlash.length - 1);
+                    }
 
-                var valPartsLen = pathWithoutSlash.split(DIR_SEPARATOR).length;
-                var fullPathPartsLen = fullPath.split(DIR_SEPARATOR).length;
+                    var valPartsLen = pathWithoutSlash.split(DIR_SEPARATOR).length;
+                    var fullPathPartsLen = fullPath.split(DIR_SEPARATOR).length;
+
+                    /* Input fullPath parameter  equals '//' for root folder */
+                    /* Entries in root folder has valPartsLen equals 2 (see below) */
+                    if (fullPath[fullPath.length -1] === DIR_SEPARATOR && fullPath.trim().length === 2) {
+                        fullPathPartsLen = 1;
+                    } else if (fullPath[fullPath.length -1] === DIR_SEPARATOR) {
+                        fullPathPartsLen = fullPath.substr(0, fullPath.length - 1).split(DIR_SEPARATOR).length;
+                    } else {
+                        fullPathPartsLen = fullPath.split(DIR_SEPARATOR).length;
+                    }
 
-                /* Input fullPath parameter  equals '//' for root folder */
-                /* Entries in root folder has valPartsLen equals 2 (see below) */
-                if (fullPath[fullPath.length -1] === DIR_SEPARATOR && fullPath.trim().length === 2) {
-                    fullPathPartsLen = 1;
-                } else if (fullPath[fullPath.length -1] === DIR_SEPARATOR) {
-                    fullPathPartsLen = fullPath.substr(0, fullPath.length - 1).split(DIR_SEPARATOR).length;
-                } else {
-                    fullPathPartsLen = fullPath.split(DIR_SEPARATOR).length;
-                }
+                    if (valPartsLen === fullPathPartsLen + 1) {
+                        // If this a subfolder and entry is a direct child, include it in
+                        // the results. Otherwise, it's not an entry of this folder.
+                        return val;
+                    } else return false;
+                });
 
-                if (valPartsLen === fullPathPartsLen + 1) {
-                    // If this a subfolder and entry is a direct child, include it in
-                    // the results. Otherwise, it's not an entry of this folder.
-                    return val;
-                } else return false;
-            });
+                successCallback(results);
+            };
 
-            successCallback(results);
-        };
+            var request = tx.objectStore(FILE_STORE_).openCursor(range);
 
-        var request = tx.objectStore(FILE_STORE_).openCursor(range);
+            request.onsuccess = function(e) {
+                var cursor = e.target.result;
+                if (cursor) {
+                    var val = cursor.value;
 
-        request.onsuccess = function(e) {
-            var cursor = e.target.result;
-            if (cursor) {
-                var val = cursor.value;
+                    results.push(val.isFile ? fileEntryFromIdbEntry(val) : new DirectoryEntry(val.name, val.fullPath, val.filesystem));
+                    cursor['continue']();
+                }
+            };
+        };
 
-                results.push(val.isFile ? fileEntryFromIdbEntry(val) : new DirectoryEntry(val.name, val.fullPath, val.filesystem));
-                cursor['continue']();
+        idb_['delete'] = function(fullPath, successCallback, errorCallback, isDirectory) {
+            if (!idb_.db) {
+                errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR);
+                return;
             }
-        };
-    };
 
-    idb_['delete'] = function(fullPath, successCallback, errorCallback, isDirectory) {
-        if (!idb_.db) {
-            errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR);
-            return;
-        }
+            var tx = this.db.transaction([FILE_STORE_], 'readwrite');
+            tx.oncomplete = successCallback;
+            tx.onabort = errorCallback || onError;
+            tx.oncomplete = function() {
+                if (isDirectory) {
+                    //We delete nested files and folders after deleting parent folder
+                    //We use ranges: https://developer.mozilla.org/en-US/docs/Web/API/IDBKeyRange
+                    fullPath = fullPath + DIR_SEPARATOR;
+
+                    //Range contains all entries in the form fullPath<symbol> where
+                    //symbol in the range from ' ' to symbol which has code `unicodeLastChar`
+                    var range = IDBKeyRange.bound(fullPath + ' ', fullPath + String.fromCharCode(unicodeLastChar));
+
+                    var newTx = this.db.transaction([FILE_STORE_], 'readwrite');
+                    newTx.oncomplete = successCallback;
+                    newTx.onabort = errorCallback || onError;
+                    newTx.objectStore(FILE_STORE_)['delete'](range);
+                } else {
+                    successCallback();
+                }
+            };
+            tx.objectStore(FILE_STORE_)['delete'](fullPath);
+        };
 
-        var tx = this.db.transaction([FILE_STORE_], 'readwrite');
-        tx.oncomplete = successCallback;
-        tx.onabort = errorCallback || onError;
-        tx.oncomplete = function() {
-            if (isDirectory) {
-                //We delete nested files and folders after deleting parent folder
-                //We use ranges: https://developer.mozilla.org/en-US/docs/Web/API/IDBKeyRange
-                fullPath = fullPath + DIR_SEPARATOR;
-
-                //Range contains all entries in the form fullPath<symbol> where
-                //symbol in the range from ' ' to symbol which has code `unicodeLastChar`
-                var range = IDBKeyRange.bound(fullPath + ' ', fullPath + String.fromCharCode(unicodeLastChar));
-
-                var newTx = this.db.transaction([FILE_STORE_], 'readwrite');
-                newTx.oncomplete = successCallback;
-                newTx.onabort = errorCallback || onError;
-                newTx.objectStore(FILE_STORE_)['delete'](range);
-            } else {
-                successCallback();
+        idb_.put = function(entry, storagePath, successCallback, errorCallback) {
+            if (!this.db) {
+                errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR);
+                return;
             }
-        };
-        tx.objectStore(FILE_STORE_)['delete'](fullPath);
-    };
 
-    idb_.put = function(entry, storagePath, successCallback, errorCallback) {
-        if (!this.db) {
-            errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR);
-            return;
-        }
+            var tx = this.db.transaction([FILE_STORE_], 'readwrite');
+            tx.onabort = errorCallback || onError;
+            tx.oncomplete = function() {
+                // TODO: Error is thrown if we pass the request event back instead.
+                successCallback(entry);
+            };
 
-        var tx = this.db.transaction([FILE_STORE_], 'readwrite');
-        tx.onabort = errorCallback || onError;
-        tx.oncomplete = function() {
-            // TODO: Error is thrown if we pass the request event back instead.
-            successCallback(entry);
+            tx.objectStore(FILE_STORE_).put(entry, storagePath);
         };
 
-        tx.objectStore(FILE_STORE_).put(entry, storagePath);
-    };
-
-    // Global error handler. Errors bubble from request, to transaction, to db.
-    function onError(e) {
-        switch (e.target.errorCode) {
-            case 12:
-                console.log('Error - Attempt to open db with a lower version than the ' +
-                    'current one.');
-                break;
-            default:
-                console.log('errorCode: ' + e.target.errorCode);
-        }
+        // Global error handler. Errors bubble from request, to transaction, to db.
+        function onError(e) {
+            switch (e.target.errorCode) {
+                case 12:
+                    console.log('Error - Attempt to open db with a lower version than the ' +
+                        'current one.');
+                    break;
+                default:
+                    console.log('errorCode: ' + e.target.errorCode);
+            }
 
-        console.log(e, e.code, e.message);
-    }
+            console.log(e, e.code, e.message);
+        }
 
-})(module.exports, window);
+    })(module.exports, window);
 
-require("cordova/exec/proxy").add("File", module.exports);
+    require("cordova/exec/proxy").add("File", module.exports);
+})();


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org