Return-Path: X-Original-To: apmail-cordova-commits-archive@www.apache.org Delivered-To: apmail-cordova-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id D2605FF0C for ; Mon, 22 Apr 2013 20:14:43 +0000 (UTC) Received: (qmail 66132 invoked by uid 500); 22 Apr 2013 20:14:43 -0000 Delivered-To: apmail-cordova-commits-archive@cordova.apache.org Received: (qmail 66050 invoked by uid 500); 22 Apr 2013 20:14:43 -0000 Mailing-List: contact commits-help@cordova.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: callback-dev@cordova.apache.org Delivered-To: mailing list commits@cordova.apache.org Received: (qmail 65369 invoked by uid 99); 22 Apr 2013 20:14:42 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 22 Apr 2013 20:14:42 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 0E53E81DCBD; Mon, 22 Apr 2013 20:14:42 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: agrieve@apache.org To: commits@cordova.apache.org Date: Mon, 22 Apr 2013 20:15:01 -0000 Message-Id: <5860a8cb38d94c36a69412281246a744@git.apache.org> In-Reply-To: <94212dd6fb394ad984a13a85afe4a6ed@git.apache.org> References: <94212dd6fb394ad984a13a85afe4a6ed@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [21/22] git commit: iOS support for launching an app and returning to menu + misc fixes. - CordovaAppHarnessRedirect plugin for iOS - Fixes to ensure errors don't break promise chain iOS support for launching an app and returning to menu + misc fixes. - CordovaAppHarnessRedirect plugin for iOS - Fixes to ensure errors don't break promise chain Project: http://git-wip-us.apache.org/repos/asf/cordova-app-harness/repo Commit: http://git-wip-us.apache.org/repos/asf/cordova-app-harness/commit/a4c6c39c Tree: http://git-wip-us.apache.org/repos/asf/cordova-app-harness/tree/a4c6c39c Diff: http://git-wip-us.apache.org/repos/asf/cordova-app-harness/diff/a4c6c39c Branch: refs/heads/master Commit: a4c6c39c88d065e78cae4090e7dfd2fe455a09ee Parents: 46b624d Author: Shravan Narayan Authored: Fri Apr 19 22:08:41 2013 -0400 Committer: Shravan Narayan Committed: Mon Apr 22 13:12:18 2013 -0400 ---------------------------------------------------------------------- .jshintignore | 2 +- .jshintrc | 2 +- README.md | 4 +- hooks/after_prepare/cordovajsmenu.js | 4 +- plugins/CordovaAppHarnessRedirect/plugin.xml | 11 +- .../src/android/CordovaAppHarnessRedirect.java | 24 ++- .../src/ios/CordovaAppHarnessRedirect.h | 26 ++ .../src/ios/CordovaAppHarnessRedirect.m | 135 ++++++++++ www/contextMenu.html | 2 +- www/js/AppsService.js | 35 ++-- www/js/ContextMenu.js | 2 +- www/js/ListCtrl.js | 4 +- www/js/ResourcesLoader.js | 205 +++++++++------ 13 files changed, 337 insertions(+), 119 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cordova-app-harness/blob/a4c6c39c/.jshintignore ---------------------------------------------------------------------- diff --git a/.jshintignore b/.jshintignore index 48a8631..e491595 100644 --- a/.jshintignore +++ b/.jshintignore @@ -1 +1 @@ -js/libs/* \ No newline at end of file +www/js/libs/* \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cordova-app-harness/blob/a4c6c39c/.jshintrc ---------------------------------------------------------------------- diff --git a/.jshintrc b/.jshintrc index f1bc9d0..0fef34f 100644 --- a/.jshintrc +++ b/.jshintrc @@ -23,7 +23,7 @@ "eqnull":true, //environment - "browser": false, + "browser": true, "devel":true, //other http://git-wip-us.apache.org/repos/asf/cordova-app-harness/blob/a4c6c39c/README.md ---------------------------------------------------------------------- diff --git a/README.md b/README.md index 1b9f8a1..0bed757 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,6 @@ An App harness for Cordova that can download and run Cordova apps as well as Chr ##Setting up environment -**Very important**: At this time, only the android section is implemented and tested - * Clone the the cordova-app-harness, cordova-android, cordova-ios, cordova-js, plugman, cordova-cli, zip(https://github.com/MobileChromeApps/zip) and chrome-cordova repos into folders of the same name in a common directory - eg 'Repo'. (Note the chrome-cordova repo is required only if you intend to run chrome apps in the harness as well) * Use the future branch of plugman and cordova-cli * Link these plugman and cordova-cli of this branch as the globally symlinked plugman and cordova-cli commands. (You may want to see 'npm link') @@ -36,7 +34,7 @@ An App harness for Cordova that can download and run Cordova apps as well as Chr ##Using the app -* Run the app harness (works in android only currently) +* Run the app harness * Click add new app * Give a name and a url to a zip. The zip should contain a www directory with a index.html file as the start page * Go back to the main screen after you see the prompt "successfully installed" http://git-wip-us.apache.org/repos/asf/cordova-app-harness/blob/a4c6c39c/hooks/after_prepare/cordovajsmenu.js ---------------------------------------------------------------------- diff --git a/hooks/after_prepare/cordovajsmenu.js b/hooks/after_prepare/cordovajsmenu.js index 8a10623..fee47fb 100755 --- a/hooks/after_prepare/cordovajsmenu.js +++ b/hooks/after_prepare/cordovajsmenu.js @@ -11,7 +11,7 @@ var androidAppend = function() { console.log("Injecting menu script"); var contextScript = document.createElement('script'); contextScript.setAttribute("type","text/javascript"); - contextScript.setAttribute("src", "file://__cordovaappharness_contextMenu_script.js"); + contextScript.setAttribute("src", "file:///__cordovaappharness_contextMenu_script.js"); document.getElementsByTagName("head")[0].appendChild(contextScript); } }; @@ -26,7 +26,7 @@ var iosAppend = function() { console.log("Injecting menu script"); var contextScript = document.createElement('script'); contextScript.setAttribute("type","text/javascript"); - contextScript.setAttribute("src", "file://__cordovaappharness_contextMenu_script.js"); + contextScript.setAttribute("src", "file:///__cordovaappharness_contextMenu_script.js"); document.getElementsByTagName("head")[0].appendChild(contextScript); } }; http://git-wip-us.apache.org/repos/asf/cordova-app-harness/blob/a4c6c39c/plugins/CordovaAppHarnessRedirect/plugin.xml ---------------------------------------------------------------------- diff --git a/plugins/CordovaAppHarnessRedirect/plugin.xml b/plugins/CordovaAppHarnessRedirect/plugin.xml index 97d0c59..7740573 100644 --- a/plugins/CordovaAppHarnessRedirect/plugin.xml +++ b/plugins/CordovaAppHarnessRedirect/plugin.xml @@ -13,13 +13,18 @@ - - - + + + + + + + + http://git-wip-us.apache.org/repos/asf/cordova-app-harness/blob/a4c6c39c/plugins/CordovaAppHarnessRedirect/src/android/CordovaAppHarnessRedirect.java ---------------------------------------------------------------------- diff --git a/plugins/CordovaAppHarnessRedirect/src/android/CordovaAppHarnessRedirect.java b/plugins/CordovaAppHarnessRedirect/src/android/CordovaAppHarnessRedirect.java index 0372ed1..93f2fd1 100644 --- a/plugins/CordovaAppHarnessRedirect/src/android/CordovaAppHarnessRedirect.java +++ b/plugins/CordovaAppHarnessRedirect/src/android/CordovaAppHarnessRedirect.java @@ -1,3 +1,21 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ package org.apache.cordova.cordovaappharness; import java.io.IOException; @@ -5,16 +23,18 @@ import java.io.InputStream; import org.apache.cordova.api.CordovaPlugin; import org.apache.cordova.FileHelper; + +import android.net.Uri; import android.webkit.WebResourceResponse; public class CordovaAppHarnessRedirect extends CordovaPlugin { - // Ensure we we redirect any file:///*/cordova.js uri's to the the cordova.js located in the assets + // Ensure we we redirect any file:///*/corodva.js uri's to the the cordova.js located in the assets // Ensure we redirect any file:///*/__cordovaappharness_contextMenu_{menu_choice} uri's to the correct locations @Override public WebResourceResponse shouldInterceptRequest(String url) { - String cleanUrl = url.split("\\?")[0].split("#")[0]; + String cleanUrl = Uri.parse(url).getPath(); String[] urlParts = cleanUrl.split("/"); String fileName = urlParts[urlParts.length - 1]; http://git-wip-us.apache.org/repos/asf/cordova-app-harness/blob/a4c6c39c/plugins/CordovaAppHarnessRedirect/src/ios/CordovaAppHarnessRedirect.h ---------------------------------------------------------------------- diff --git a/plugins/CordovaAppHarnessRedirect/src/ios/CordovaAppHarnessRedirect.h b/plugins/CordovaAppHarnessRedirect/src/ios/CordovaAppHarnessRedirect.h new file mode 100644 index 0000000..af1e85a --- /dev/null +++ b/plugins/CordovaAppHarnessRedirect/src/ios/CordovaAppHarnessRedirect.h @@ -0,0 +1,26 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ +#import +#import + +NSString* const fileURLScheme = @"file"; + +@interface CordovaAppHarnessRedirect : CDVPlugin {} + +@end http://git-wip-us.apache.org/repos/asf/cordova-app-harness/blob/a4c6c39c/plugins/CordovaAppHarnessRedirect/src/ios/CordovaAppHarnessRedirect.m ---------------------------------------------------------------------- diff --git a/plugins/CordovaAppHarnessRedirect/src/ios/CordovaAppHarnessRedirect.m b/plugins/CordovaAppHarnessRedirect/src/ios/CordovaAppHarnessRedirect.m new file mode 100644 index 0000000..0034eff --- /dev/null +++ b/plugins/CordovaAppHarnessRedirect/src/ios/CordovaAppHarnessRedirect.m @@ -0,0 +1,135 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ +#import "CordovaAppHarnessRedirect.h" + +#pragma mark declare + +@interface AppHarnessURLProtocol : NSURLProtocol +@end + +static NSString* pathPrefix; +static UIWebView* uiwebview; + +#pragma mark CordovaAppHarnessRedirect + +@implementation CordovaAppHarnessRedirect + +- (CDVPlugin*)initWithWebView:(UIWebView*)theWebView +{ + self = [super initWithWebView:theWebView]; + uiwebview = theWebView; + if (self) { + [NSURLProtocol registerClass:[AppHarnessURLProtocol class]]; + pathPrefix = [[NSBundle mainBundle] pathForResource:@"chromeapp.html" ofType:@"" inDirectory:@"www"]; + NSRange range = [pathPrefix rangeOfString:@"/www/"]; + pathPrefix = [[pathPrefix substringToIndex:NSMaxRange(range)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; + } + return self; +} + +@end + +#pragma mark AppHarnessURLProtocol + +@implementation AppHarnessURLProtocol + + ++ (BOOL)canInitWithRequest:(NSURLRequest*)request +{ + NSURL* url = [request URL]; + + if(![[url scheme] isEqualToString:fileURLScheme]) { + return NO; + } + + NSString* fileName = [url lastPathComponent]; + + if([fileName isEqualToString:@"cordova.js"] + || [fileName isEqualToString:@"__cordovaappharness_contextMenu_page.html"] + || [fileName isEqualToString:@"__cordovaappharness_contextMenu_script.js"] + || [fileName isEqualToString:@"__cordovaappharness_contextMenu_mainmenu"] + ) { + return YES; + } + return NO; +} + ++ (NSURLRequest*)canonicalRequestForRequest:(NSURLRequest*)request +{ + return request; +} + +- (void)startLoading +{ + NSURL *url = [[self request] URL]; + NSString *fileName = [url lastPathComponent]; + NSString *pathString = @""; + BOOL redirect = NO; + + if ([fileName isEqualToString:@"cordova.js"]) { + pathString = @"cordova.js"; + } else if ([fileName isEqualToString:@"__cordovaappharness_contextMenu_page.html"]) { + pathString = @"contextMenu.html"; + } else if ([fileName isEqualToString:@"__cordovaappharness_contextMenu_script.js"]) { + pathString = @"js/ContextMenu.js"; + } else if ([fileName isEqualToString:@"__cordovaappharness_contextMenu_mainmenu"]) { + pathString = @"index.html"; + redirect = YES; + } else { + NSString* description = [NSString stringWithFormat:@"url %@ cannot be handled",[url absoluteString]]; + NSAssert(FALSE, description); + } + + if(redirect) { + [uiwebview stopLoading]; + NSString *newUrlString = [NSString stringWithFormat:@"file://%@%@", pathPrefix, [pathString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; + NSURL *newUrl = [NSURL URLWithString:newUrlString]; + NSURLRequest *request = [NSURLRequest requestWithURL:newUrl]; + [uiwebview loadRequest:request]; + } else { + NSString *path = [NSString stringWithFormat:@"%@%@", pathPrefix, pathString]; + FILE *fp = fopen([path UTF8String], "r"); + if (fp) { + NSURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:url statusCode:200 HTTPVersion:@"HTTP/1.1" headerFields:@{}]; + [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; + + char buf[32768]; + size_t len; + while ((len = fread(buf,1,sizeof(buf),fp))) { + [[self client] URLProtocol:self didLoadData:[NSData dataWithBytes:buf length:len]]; + } + fclose(fp); + + [[self client] URLProtocolDidFinishLoading:self]; + + } else { + NSURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:url statusCode:404 HTTPVersion:@"HTTP/1.1" headerFields:@{}]; + [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; + [[self client] URLProtocolDidFinishLoading:self]; + } + } + +} + +- (void)stopLoading +{ + // do any cleanup here +} + +@end http://git-wip-us.apache.org/repos/asf/cordova-app-harness/blob/a4c6c39c/www/contextMenu.html ---------------------------------------------------------------------- diff --git a/www/contextMenu.html b/www/contextMenu.html index 27ddd0d..8993ea8 100644 --- a/www/contextMenu.html +++ b/www/contextMenu.html @@ -41,7 +41,7 @@
  • - +
  • \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cordova-app-harness/blob/a4c6c39c/www/js/AppsService.js ---------------------------------------------------------------------- diff --git a/www/js/AppsService.js b/www/js/AppsService.js index ba012a9..f6dadd6 100644 --- a/www/js/AppsService.js +++ b/www/js/AppsService.js @@ -1,7 +1,7 @@ (function() { "use strict"; /* global myApp */ - myApp.factory("AppsService", [ "ResourcesLoader", "INSTALL_DIRECTORY", "TEMP_DIRECTORY", "APPS_JSON", "$window", function(ResourcesLoader, INSTALL_DIRECTORY, TEMP_DIRECTORY, APPS_JSON, $window) { + myApp.factory("AppsService", [ "ResourcesLoader", "INSTALL_DIRECTORY", "TEMP_DIRECTORY", "APPS_JSON", function(ResourcesLoader, INSTALL_DIRECTORY, TEMP_DIRECTORY, APPS_JSON) { function addNewAppFromUrl(appName, appUrl) { var fileName = TEMP_DIRECTORY + appName + ".zip"; @@ -23,17 +23,22 @@ function extractZipToDirectory(fileName, outputDirectory){ var deferred = Q.defer(); - var onZipDone = function(returnCode) { - if(returnCode !== 0) { - deferred.reject(new Error("Something went wrong during the unzipping of: " + fileName)); - } else { - deferred.resolve(); - } - }; + try { + var onZipDone = function(returnCode) { + if(returnCode !== 0) { + deferred.reject(new Error("Something went wrong during the unzipping of: " + fileName)); + } else { + deferred.resolve(); + } + }; - /* global zip */ - zip.unzip(fileName, outputDirectory, onZipDone); - return deferred.promise; + /* global zip */ + zip.unzip(fileName, outputDirectory, onZipDone); + } catch(e) { + deferred.reject(e); + } finally { + return deferred.promise; + } } function registerApp(appName, appSource, appUrl) { @@ -49,14 +54,6 @@ }); } - function getAbsoluteUrl(relativeUrl) { - // Can't use $document from angularJS as it does not provie the create constructor - /* global document */ - var a = document.createElement("a"); - a.href = relativeUrl; - return a.href; - } - function getAppStartPageFromAppLocation(appLocation) { appLocation += (appLocation.substring(appLocation.length - 1) === "/") ? "" : "/"; var startLocation = appLocation + "www/index.html"; http://git-wip-us.apache.org/repos/asf/cordova-app-harness/blob/a4c6c39c/www/js/ContextMenu.js ---------------------------------------------------------------------- diff --git a/www/js/ContextMenu.js b/www/js/ContextMenu.js index 1e3a760..d7cc86a 100644 --- a/www/js/ContextMenu.js +++ b/www/js/ContextMenu.js @@ -1,7 +1,7 @@ (function () { function initialise() { - var contextHTMLUrl = "file://__cordovaappharness_contextMenu_page.html"; + var contextHTMLUrl = "file:///__cordovaappharness_contextMenu_page.html"; var xhr = new window.XMLHttpRequest(); xhr.onreadystatechange=function() { http://git-wip-us.apache.org/repos/asf/cordova-app-harness/blob/a4c6c39c/www/js/ListCtrl.js ---------------------------------------------------------------------- diff --git a/www/js/ListCtrl.js b/www/js/ListCtrl.js index 233c0dc..14c1ab4 100644 --- a/www/js/ListCtrl.js +++ b/www/js/ListCtrl.js @@ -1,7 +1,7 @@ (function(){ "use strict"; /* global myApp */ - myApp.controller("ListCtrl", [ "$scope", "$document", "AppsService", function ($scope, $document, AppsService) { + myApp.controller("ListCtrl", [ "$scope", "AppsService", function ($scope, AppsService) { $scope.appsList = []; @@ -37,6 +37,6 @@ alert("removeApp called: " + app); }; - $document.bind("deviceready", function() { $scope.loadAppsList("deviceready"); }); + document.addEventListener("deviceready", function() { $scope.loadAppsList("deviceready"); }, false); }]); })(); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cordova-app-harness/blob/a4c6c39c/www/js/ResourcesLoader.js ---------------------------------------------------------------------- diff --git a/www/js/ResourcesLoader.js b/www/js/ResourcesLoader.js index 2b4f768..0bd244c 100644 --- a/www/js/ResourcesLoader.js +++ b/www/js/ResourcesLoader.js @@ -2,51 +2,63 @@ "use strict"; /* global myApp */ - myApp.factory("ResourcesLoader", [ "$window", "$document", function ($window, $document) { + myApp.factory("ResourcesLoader", [ "$window", function ($window) { var fs; var initialised = false; - function initialise() { - initialised = true; + function initialiseFileSystem() { + var deferred = Q.defer(); - var failedFileSystemLookUp = function (error) { - var errorString = "An error occurred while reading the file system."; - if(error) { - errorString += " " + JSON.stringify(error); - } - console.error(errorString); - }; + if(!initialised) { + initialised = true; + + var failedFileSystemLookUp = function (error) { + var errorString = "An error occurred while reading the file system."; + if(error) { + errorString += " " + JSON.stringify(error); + } + deferred.reject(new Error(errorString)); + }; - var success = function(_fs) { - fs = _fs; - }; + var success = function(_fs) { + fs = _fs; + deferred.resolve(fs); + }; - try { - $window.requestFileSystem($window.LocalFileSystem.PERSISTENT, 0, success, failedFileSystemLookUp); - } catch (e) { - failedFileSystemLookUp(e); + try { + $window.requestFileSystem($window.LocalFileSystem.PERSISTENT, 0, success, failedFileSystemLookUp); + } catch (e) { + failedFileSystemLookUp(e); + } + } else { + deferred.resolve(fs); } - } - $document.bind("deviceready", function() { initialise(); }); + return deferred.promise; + } //promise returns full path to downloaded file function downloadFromUrl(url, fullFilePath) { var deferred = Q.defer(); - var downloadFail = function(error) { - var str = "There was an error while downloading the file " + JSON.stringify(error); - deferred.reject(new Error(str)); - }; + try { + var downloadFail = function(error) { + var str = "There was an error while downloading the file " + JSON.stringify(error); + deferred.reject(new Error(str)); + }; - var downloadSuccess = function(fileEntry) { - deferred.resolve(fileEntry.fullPath); - }; + var downloadSuccess = function(fileEntry) { + deferred.resolve(fileEntry.fullPath); + }; - var fileTransfer = new $window.FileTransfer(); - var uri = encodeURI(url); - fileTransfer.download(uri, fullFilePath, downloadSuccess, downloadFail); - return deferred.promise; + var fileTransfer = new $window.FileTransfer(); + var uri = encodeURI(url); + fileTransfer.download(uri, fullFilePath, downloadSuccess, downloadFail); + } catch(e) { + deferred.reject(new Error(e)); + } finally { + return deferred.promise; + } } function trim(str) { @@ -66,15 +78,20 @@ function getFileEntry(fileName) { var deferred = Q.defer(); - var errorWhileGettingFileEntry = function(error) { - var str = "There was an error while getting the file entry for file " + fileName + " " + JSON.stringify(error); - deferred.reject(new Error(str)); - }; - var success = function(fileEntry) { - deferred.resolve(fileEntry); - }; - fs.root.getFile(fileName, {create: true, exclusive: false}, success, errorWhileGettingFileEntry); - return deferred.promise; + try { + var errorWhileGettingFileEntry = function(error) { + var str = "There was an error while getting the file entry for file " + fileName + " " + JSON.stringify(error); + deferred.reject(new Error(str)); + }; + var success = function(fileEntry) { + deferred.resolve(fileEntry); + }; + fs.root.getFile(fileName, {create: true, exclusive: false}, success, errorWhileGettingFileEntry); + } catch(e) { + deferred.reject(new Error(e)); + } finally { + return deferred.promise; + } } //promise returns the file @@ -83,13 +100,18 @@ then(function(fileEntry){ var deferred = Q.defer(); - var errorWhileGettingFile = function(error) { - var str = "There was an error while getting the file for file " + fileName + " " + JSON.stringify(error); - deferred.reject(new Error(str)); - }; + try { + var errorWhileGettingFile = function(error) { + var str = "There was an error while getting the file for file " + fileName + " " + JSON.stringify(error); + deferred.reject(new Error(str)); + }; - fileEntry.file(deferred.resolve, errorWhileGettingFile); - return deferred.promise; + fileEntry.file(deferred.resolve, errorWhileGettingFile); + } catch(e) { + deferred.reject(new Error(e)); + } finally { + return deferred.promise; + } }); } @@ -105,62 +127,71 @@ return { // returns a promise with a full path to the dir ensureDirectoryExists : function(directory) { - var deferred = Q.defer(); + return initialiseFileSystem(). + then(function(){ + var deferred = Q.defer(); - directory = truncateToDirectoryPath(directory); - directory = makeRelativeToRoot(directory); + directory = truncateToDirectoryPath(directory); + directory = makeRelativeToRoot(directory); - var gotDirEntry = function(dirEntry) { - deferred.resolve(dirEntry.fullPath); - }; + var gotDirEntry = function(dirEntry) { + deferred.resolve(dirEntry.fullPath); + }; - var failedToGetDirEntry = function(error) { - var str = "There was an error checking the directory: " + directory + " " + JSON.stringify(error); - deferred.reject(new Error(str)); - }; + var failedToGetDirEntry = function(error) { + var str = "There was an error checking the directory: " + directory + " " + JSON.stringify(error); + deferred.reject(new Error(str)); + }; - fs.root.getDirectory(directory, {create: true, exclusive: false}, gotDirEntry, failedToGetDirEntry); - return deferred.promise; + fs.root.getDirectory(directory, {create: true, exclusive: false}, gotDirEntry, failedToGetDirEntry); + return deferred.promise; + }); }, // promise returns full path to file getFullFilePath : function(filePath) { - var deferred = Q.defer(); + return initialiseFileSystem(). + then(function(){ + var deferred = Q.defer(); - // Use the file's parent folder to get the full path - var directory = filePath; - var fileName = ""; + // Use the file's parent folder to get the full path + var directory = filePath; + var fileName = ""; - //remove the filename if it exists - var lastLevelIndex = directory.search(/\/[\w ]+\.[\w ]+$/g); - if(lastLevelIndex !== -1) { - directory = filePath.substring(0, lastLevelIndex); - fileName = filePath.substring(lastLevelIndex + 1); - } + //remove the filename if it exists + var lastLevelIndex = directory.search(/\/[\w ]+\.[\w ]+$/g); + if(lastLevelIndex !== -1) { + directory = filePath.substring(0, lastLevelIndex); + fileName = filePath.substring(lastLevelIndex + 1); + } - //we need the directory name w.r.t the root, so remove any slashes in the beginning - if(directory.indexOf("/") === 0) { - directory = directory.substring(1); - } + //we need the directory name w.r.t the root, so remove any slashes in the beginning + if(directory.charAt(0) === "/") { + directory = directory.substring(1); + } - var gotFullPath = function(dirEntry) { - var fullFilePath = dirEntry.fullPath + "/" + fileName; - deferred.resolve(fullFilePath); - }; + var gotFullPath = function(dirEntry) { + var fullFilePath = dirEntry.fullPath + "/" + fileName; + deferred.resolve(fullFilePath); + }; - var failedToGetFullPath = function(error) { - var str = "There was an error getting the full path of file: " + filePath + " " + JSON.stringify(error); - deferred.reject(new Error(str)); - }; + var failedToGetFullPath = function(error) { + var str = "There was an error getting the full path of file: " + filePath + " " + JSON.stringify(error); + deferred.reject(new Error(str)); + }; - fs.root.getDirectory(directory, {create: true, exclusive: false}, gotFullPath, failedToGetFullPath); - return deferred.promise; + fs.root.getDirectory(directory, {create: true, exclusive: false}, gotFullPath, failedToGetFullPath); + return deferred.promise; + }); }, // returns a promise with a full path to the downloaded file downloadFromUrl : function(url, filePath) { var self = this; - return this.ensureDirectoryExists(filePath) + return initialiseFileSystem(). + then(function(){ + return self.ensureDirectoryExists(filePath); + }) .then(function(){ return self.getFullFilePath(filePath); }) @@ -171,7 +202,10 @@ //returns a promise with the contents of the file readFileContents : function(fileName) { - return getFile(fileName) + return initialiseFileSystem(). + then(function(){ + return getFile(fileName); + }) .then(function(file){ var deferred = Q.defer(); @@ -204,7 +238,10 @@ //returns a promise when file is written writeFileContents : function(fileName, contents) { - return getFileEntry(fileName) + return initialiseFileSystem(). + then(function(){ + return getFileEntry(fileName); + }) .then(function(fileEntry){ var deferred = Q.defer();