cordova-app-loader
Advanced tools
Comparing version 0.18.0 to 1.0.0
@@ -19,3 +19,3 @@ (function(){ | ||
// cb placeholder to avoid using var, should not be used | ||
xhr.onreadystatechange = xhr.then = function(onSuccess, onError, cb) { | ||
xhr.onreadystatechange = xhr.then = function(onSuccess, onError, cb, result) { | ||
@@ -28,10 +28,18 @@ // Test if onSuccess is a function or a load event | ||
// index will be: | ||
// 0 if status is between 0 and 399 | ||
// 1 if status is over | ||
cb = a[0|xhr.status / 400]; | ||
try { | ||
if(xhr.status === 200 || xhr.status === 0){ | ||
result = JSON.parse(xhr.responseText); | ||
cb = a[0]; | ||
} else { | ||
result = new Error('Status: '+xhr.status); | ||
cb = a[1]; | ||
} | ||
} catch(e) { | ||
result = e; | ||
cb = a[1]; | ||
} | ||
// Safari doesn't support xhr.responseType = 'json' | ||
// so the response is parsed | ||
if (cb) cb(xhr.status === 200 || xhr.status === 0?JSON.parse(xhr.responseText):xhr); | ||
if (cb) cb(result); | ||
} | ||
@@ -81,2 +89,3 @@ }; | ||
el= document.createElement('script'); | ||
el.charset="UTF-8"; | ||
el.type= 'text/javascript'; | ||
@@ -83,0 +92,0 @@ el.src= src + '?' + now; |
@@ -19,3 +19,3 @@ (function(){ | ||
// cb placeholder to avoid using var, should not be used | ||
xhr.onreadystatechange = xhr.then = function(onSuccess, onError, cb) { | ||
xhr.onreadystatechange = xhr.then = function(onSuccess, onError, cb, result) { | ||
@@ -28,10 +28,18 @@ // Test if onSuccess is a function or a load event | ||
// index will be: | ||
// 0 if status is between 0 and 399 | ||
// 1 if status is over | ||
cb = a[0|xhr.status / 400]; | ||
try { | ||
if(xhr.status === 200 || xhr.status === 0){ | ||
result = JSON.parse(xhr.responseText); | ||
cb = a[0]; | ||
} else { | ||
result = new Error('Status: '+xhr.status); | ||
cb = a[1]; | ||
} | ||
} catch(e) { | ||
result = e; | ||
cb = a[1]; | ||
} | ||
// Safari doesn't support xhr.responseType = 'json' | ||
// so the response is parsed | ||
if (cb) cb(xhr.status === 200 || xhr.status === 0?JSON.parse(xhr.responseText):xhr); | ||
if (cb) cb(result); | ||
} | ||
@@ -81,2 +89,3 @@ }; | ||
el= document.createElement('script'); | ||
el.charset="UTF-8"; | ||
el.type= 'text/javascript'; | ||
@@ -83,0 +92,0 @@ el.src= src + '?' + now; |
@@ -1,1 +0,1 @@ | ||
!function(){function t(t,e,o){function n(){r.forEach(function(e){e&&("/"===e[0]&&(e=e.substr(1)),e=t.root+e,".js"===e.substr(-3)?(a=document.createElement("script"),a.type="text/javascript",a.src=e+"?"+i,a.async=!1):(a=document.createElement("link"),a.rel="stylesheet",a.href=e+"?"+i,a.type="text/css"),s.appendChild(a))})}if(e&&setTimeout(function(){window.BOOTSTRAP_OK||(console.warn("BOOTSTRAP_OK !== true; Resetting to original manifest.json..."),localStorage.removeItem("manifest"),location.reload())},o),!t.load)return void console.error("Manifest has nothing to load (manifest.load is empty).",t);var a,s=document.getElementsByTagName("head")[0],r=t.load.concat(),i=Date.now();t.root=t.root||"./",t.root.length>0&&"/"!==t.root[t.root.length-1]&&(t.root+="/"),e||localStorage.setItem("manifest",JSON.stringify(t)),"undefined"!=typeof window.cordova?document.addEventListener("deviceready",n,!1):n(),window.Manifest=t}window.pegasus=function(t,e){return e=new XMLHttpRequest,e.open("GET",t),t=[],e.onreadystatechange=e.then=function(o,n,a){o.call&&(t=[o,n]),4==e.readyState&&(a=t[0|e.status/400],a&&a(200===e.status||0===e.status?JSON.parse(e.responseText):e))},e.send(),e},window.Manifest={};var e=JSON.parse(localStorage.getItem("manifest")),o=document.querySelector("script[manifest]");if(e)t(e,!0,o.getAttribute("timeout")||1e4);else{var n=(o?o.getAttribute("manifest"):null)||"manifest.json";pegasus(n).then(t,function(t){console.error("Could not download "+n+": "+t.status)})}}(); | ||
!function(){function t(t,e,o){function n(){r.forEach(function(e){e&&("/"===e[0]&&(e=e.substr(1)),e=t.root+e,".js"===e.substr(-3)?(a=document.createElement("script"),a.charset="UTF-8",a.type="text/javascript",a.src=e+"?"+i,a.async=!1):(a=document.createElement("link"),a.rel="stylesheet",a.href=e+"?"+i,a.type="text/css"),s.appendChild(a))})}if(e&&setTimeout(function(){window.BOOTSTRAP_OK||(console.warn("BOOTSTRAP_OK !== true; Resetting to original manifest.json..."),localStorage.removeItem("manifest"),location.reload())},o),!t.load)return void console.error("Manifest has nothing to load (manifest.load is empty).",t);var a,s=document.getElementsByTagName("head")[0],r=t.load.concat(),i=Date.now();t.root=t.root||"./",t.root.length>0&&"/"!==t.root[t.root.length-1]&&(t.root+="/"),e||localStorage.setItem("manifest",JSON.stringify(t)),"undefined"!=typeof window.cordova?document.addEventListener("deviceready",n,!1):n(),window.Manifest=t}window.pegasus=function(t,e){return e=new XMLHttpRequest,e.open("GET",t),t=[],e.onreadystatechange=e.then=function(o,n,a,s){if(o.call&&(t=[o,n]),4==e.readyState){try{200===e.status||0===e.status?(s=JSON.parse(e.responseText),a=t[0]):(s=new Error("Status: "+e.status),a=t[1])}catch(e){s=e,a=t[1]}a&&a(s)}},e.send(),e},window.Manifest={};var e=JSON.parse(localStorage.getItem("manifest")),o=document.querySelector("script[manifest]");if(e)t(e,!0,o.getAttribute("timeout")||1e4);else{var n=(o?o.getAttribute("manifest"):null)||"manifest.json";pegasus(n).then(t,function(t){console.error("Could not download "+n+": "+t.status)})}}(); |
@@ -92,2 +92,3 @@ /******/ (function(modules) { // webpackBootstrap | ||
this.bundledManifest = null; | ||
this.preventAutoUpdateLoop = options.preventAutoUpdateLoop === true; | ||
this._lastUpdateFiles = localStorage.getItem('last_update_files'); | ||
@@ -174,3 +175,3 @@ | ||
// Check if the newFiles match the previous files (last_update_files) | ||
if(newFiles === self._lastUpdateFiles) { | ||
if(self.preventAutoUpdateLoop === true && newFiles === self._lastUpdateFiles) { | ||
// YES! So we're doing the same update again! | ||
@@ -193,3 +194,3 @@ | ||
if(!newManifest.files){ | ||
reject('Downloaded Manifest has no "files" attribute.'); | ||
reject(new Error('Downloaded Manifest has no "files" attribute.')); | ||
return; | ||
@@ -209,2 +210,3 @@ } | ||
var isCordova = self.cache._fs.isCordova; | ||
var changes = 0; | ||
Object.keys(newFiles) | ||
@@ -216,3 +218,3 @@ // Find files that have changed version or are missing | ||
// version has changed, or... | ||
oldFiles[file].version !== newFiles[file].version || | ||
oldFiles[file].version !== newFiles[file].version //|| | ||
// not in cache for some reason | ||
@@ -230,2 +232,5 @@ !self.cache.isCached(file); | ||
} | ||
if(!bundledFiles[file] || bundledFiles[file].version !== newFiles[file].version){ | ||
changes++; | ||
} | ||
}); | ||
@@ -248,3 +253,3 @@ | ||
var changes = self._toBeDeleted.length + self._toBeDownloaded.length; | ||
changes += self._toBeDeleted.length; | ||
// Note: if we only need to copy files, we can keep serving from bundle! | ||
@@ -255,3 +260,3 @@ // So no update is needed! | ||
self.newManifest = newManifest; | ||
self.newManifest.root = self.cache.localInternalURL; | ||
self.newManifest.root = self.cache.localUrl; | ||
resolve(true); | ||
@@ -275,3 +280,3 @@ } else { | ||
AppLoader.prototype.download = function(onprogress){ | ||
AppLoader.prototype.download = function(onprogress,includeFileProgressEvents){ | ||
var self = this; | ||
@@ -297,3 +302,3 @@ if(!self.canDownload()) { | ||
self.cache.add(self._toBeDownloaded); | ||
return self.cache.download(onprogress); | ||
return self.cache.download(onprogress,includeFileProgressEvents); | ||
}).then(function(){ | ||
@@ -352,3 +357,3 @@ self._toBeDeleted = []; | ||
this._fs = options.fs; | ||
if(!this._fs) { | ||
if(!this._fs) { | ||
throw new Error('Missing required option "fs". Add an instance of cordova-promise-fs.'); | ||
@@ -453,5 +458,6 @@ } | ||
FileCache.prototype.download = function download(onprogress){ | ||
FileCache.prototype.download = function download(onprogress,includeFileProgressEvents){ | ||
var fs = this._fs; | ||
var self = this; | ||
includeFileProgressEvents = includeFileProgressEvents || false; | ||
self.abort(); | ||
@@ -476,2 +482,3 @@ | ||
var total = self._downloading.length + queue.length; | ||
var percentage = 0; | ||
@@ -490,5 +497,7 @@ // download every file in the queue (which is the diff from _added with _cached) | ||
ev.percentage = done / total; | ||
if(ev.loaded > 0 && ev.total > 0 && index !== total){ | ||
if(ev.loaded > 0 && ev.total > 0 && done !== total){ | ||
ev.percentage += (ev.loaded / ev.total) / total; | ||
} | ||
ev.percentage = Math.max(percentage,ev.percentage); | ||
percentage = ev.percentage; | ||
onprogress(ev); | ||
@@ -501,2 +510,3 @@ }; | ||
done++; | ||
onSingleDownloadProgress(new ProgressEvent()); | ||
@@ -523,3 +533,3 @@ // when we're done | ||
if(self._cacheBuster) downloadUrl += "?"+Date.now(); | ||
var download = fs.download(downloadUrl,path,{retry:self._retry},onSingleDownloadProgress); | ||
var download = fs.download(downloadUrl,path,{retry:self._retry},includeFileProgressEvents? onSingleDownloadProgress: undefined); | ||
download.then(onDone,onDone); | ||
@@ -563,3 +573,3 @@ self._downloading.push(download); | ||
path = this.toPath(url); | ||
if(this._cached[path]) return this._cached[path].toInternalURL; | ||
if(this._cached[path]) return this._cached[path].toURL; | ||
return this.toServerURL(url); | ||
@@ -599,3 +609,7 @@ }; | ||
} else { | ||
return this.localRoot + hash(url) + url.substr(url.lastIndexOf('.')); | ||
var ext = url.substr(url.lastIndexOf('.')); | ||
if ((ext.indexOf("?") > 0) || (ext.indexOf("/") > 0)) { | ||
ext = ".txt"; | ||
} | ||
return this.localRoot + hash(url) + ext; | ||
} | ||
@@ -710,4 +724,27 @@ }; | ||
if(str[0] === '/') str = str.substr(1); | ||
if(!!str && str.indexOf('.') < 0 && str[str.length-1] !== '/') str += '/'; | ||
if(str === './') str = ''; | ||
var tokens = str.split('/'), last = tokens[0]; | ||
// check tokens for instances of .. and . | ||
for(var i=1;i < tokens.length;i++) { | ||
last = tokens[i]; | ||
if (tokens[i] === '..') { | ||
// remove the .. and the previous token | ||
tokens.splice(i-1,2); | ||
// rewind 'cursor' 2 tokens | ||
i = i - 2; | ||
} else if (tokens[i] === '.') { | ||
// remove the .. and the previous token | ||
tokens.splice(i,1); | ||
// rewind 'cursor' 1 token | ||
i--; | ||
} | ||
} | ||
str = tokens.join('/'); | ||
if(str === './') { | ||
str = ''; | ||
} else if(last && last.indexOf('.') < 0 && str[str.length - 1] != '/'){ | ||
str += '/'; | ||
} | ||
return str; | ||
@@ -728,3 +765,3 @@ } | ||
/* default options */ | ||
this.options = options = options || {}; | ||
options = options || {}; | ||
options.persistent = options.persistent !== undefined? options.persistent: true; | ||
@@ -734,2 +771,3 @@ options.storageSize = options.storageSize || 20*1024*1024; | ||
options.retry = options.retry || []; | ||
options.debug = !!options.debug; | ||
@@ -755,3 +793,3 @@ /* Cordova deviceready promise */ | ||
if (xhr.readyState == 4) { | ||
if(xhr.status === 200){ | ||
if(xhr.status === 200 && !this._aborted){ | ||
write(file,xhr.response).then(win,fail); | ||
@@ -766,2 +804,5 @@ } else { | ||
}; | ||
FileTransfer.prototype.abort = function(){ | ||
this._aborted = true; | ||
}; | ||
window.ProgressEvent = function ProgressEvent(){}; | ||
@@ -787,10 +828,5 @@ window.FileEntry = function FileEntry(){}; | ||
var type = options.persistent? 1: 0; | ||
if(typeof options.fileSystem === 'number'){ | ||
if(options.fileSystem && isCordova){ | ||
type = options.fileSystem; | ||
} | ||
// Chrome only supports persistent and temp storage, not the exotic onces from Cordova | ||
if(!isCordova && type > 1) { | ||
console.warn('Chrome does not support fileSystem "'+type+'". Falling back on "0" (temporary).'); | ||
type = 0; | ||
} | ||
// On chrome, request quota to store persistent files | ||
@@ -800,7 +836,15 @@ if (!isCordova && type === 1 && navigator.webkitPersistentStorage) { | ||
window.requestFileSystem(type, grantedBytes, resolve, reject); | ||
}); | ||
}, reject); | ||
} else { | ||
// Exotic Cordova Directories (options.fileSystem = string) | ||
if(isNaN(type)) { | ||
window.resolveLocalFileSystemURL(type,function(directory){ | ||
resolve(directory.filesystem); | ||
},reject); | ||
// Normal browser usage | ||
} else { | ||
window.requestFileSystem(type, options.storageSize, resolve, reject); | ||
} | ||
} | ||
else { | ||
window.requestFileSystem(type, options.storageSize, resolve, reject); | ||
} | ||
setTimeout(function(){ reject(new Error('Could not retrieve FileSystem after 5 seconds.')); },5100); | ||
@@ -812,2 +856,4 @@ },reject); | ||
fs.then(function(fs){ | ||
CDV_INTERNAL_URL_ROOT = fs.root.toInternalURL(); | ||
CDV_URL_ROOT = fs.root.toURL(); | ||
window.__fs = fs; | ||
@@ -950,3 +996,5 @@ },function(err){ | ||
/* convert path to URL to be used in JS/CSS/HTML */ | ||
var toInternalURL,toInternalURLSync; | ||
var toInternalURL,toInternalURLSync,toURLSync; | ||
CDV_INTERNAL_URL_ROOT = 'cdvfile://localhost/'+(options.persistent? 'persistent/':'temporary/'); | ||
CDV_URL_ROOT = ''; | ||
if(isCordova) { | ||
@@ -956,4 +1004,9 @@ /* synchronous helper to get internal URL. */ | ||
path = normalize(path); | ||
return path.indexOf('://') < 0? 'cdvfile://localhost/'+(options.persistent? 'persistent/':'temporary/') + path: path; | ||
return path.indexOf('://') < 0? CDV_INTERNAL_URL_ROOT + path: path; | ||
}; | ||
/* synchronous helper to get native URL. */ | ||
toURLSync = function(path){ | ||
path = normalize(path); | ||
return path.indexOf('://') < 0? CDV_URL_ROOT + path: path; | ||
}; | ||
@@ -977,2 +1030,3 @@ toInternalURL = function(path) { | ||
}; | ||
toURLSync = toInternalURLSync; | ||
} | ||
@@ -1016,5 +1070,5 @@ | ||
if(typeof blob === 'string') { | ||
blob = new Blob([blob],{type: mimeType || 'text/plain'}); | ||
blob = createBlob([blob], mimeType || 'text/plain'); | ||
} else if(blob instanceof Blob !== true){ | ||
blob = new Blob([JSON.stringify(blob,null,4)],{type: mimeType || 'application/json'}); | ||
blob = createBlob([JSON.stringify(blob,null,4)], mimeType || 'application/json'); | ||
} | ||
@@ -1027,2 +1081,22 @@ writer.write(blob); | ||
function createBlob(parts, type) { | ||
var BlobBuilder, | ||
bb; | ||
try { | ||
return new Blob(parts, {type: type}); | ||
} catch(e) { | ||
BlobBuilder = window.BlobBuilder || | ||
window.WebKitBlobBuilder || | ||
window.MozBlobBuilder || | ||
window.MSBlobBuilder; | ||
if(BlobBuilder) { | ||
bb = new BlobBuilder(); | ||
bb.append(parts); | ||
return bb.getBlob(type); | ||
} else { | ||
throw new Error("Unable to create blob"); | ||
} | ||
} | ||
} | ||
/* move a file */ | ||
@@ -1100,10 +1174,10 @@ function move(src,dest) { | ||
var args = transferQueue.pop(); | ||
var ft = args.shift(); | ||
var isDownload = args.shift(); | ||
var serverUrl = args.shift(); | ||
var localPath = args.shift(); | ||
var win = args.shift(); | ||
var fail = args.shift(); | ||
var trustAllHosts = args.shift(); | ||
var transferOptions = args.shift(); | ||
var ft = args.fileTransfer, | ||
isDownload = args.isDownload, | ||
serverUrl = args.serverUrl, | ||
localPath = args.localPath, | ||
trustAllHosts = args.trustAllHosts, | ||
transferOptions = args.transferOptions, | ||
win = args.win, | ||
fail = args.fail; | ||
@@ -1135,3 +1209,3 @@ if(ft._aborted) { | ||
} | ||
if(isCordova && localPath.indexOf('://') < 0) localPath = toInternalURLSync(localPath); | ||
if(isCordova && localPath.indexOf('://') < 0) localPath = toURLSync(localPath); | ||
@@ -1153,5 +1227,17 @@ transferOptions = transferOptions || {}; | ||
if(transferOptions.retry.length === 0) { | ||
if(options.debug) console.log('FileTransfer Error: '+serverUrl,err); | ||
reject(err); | ||
} else { | ||
transferQueue.unshift([ft,isDownload,serverUrl,localPath,resolve,attempt,transferOptions.trustAllHosts || false,transferOptions]); | ||
var transferJob = { | ||
fileTransfer:ft, | ||
isDownload:isDownload, | ||
serverUrl:serverUrl, | ||
localPath:localPath, | ||
trustAllHosts:transferOptions.trustAllHosts || false, | ||
transferOptions:transferOptions, | ||
win:resolve, | ||
fail:attempt | ||
}; | ||
transferQueue.unshift(transferJob); | ||
var timeout = transferOptions.retry.shift(); | ||
@@ -1158,0 +1244,0 @@ if(timeout > 0) { |
@@ -1,1 +0,1 @@ | ||
!function(t){function e(o){if(n[o])return n[o].exports;var r=n[o]={exports:{},id:o,loaded:!1};return t[o].call(r.exports,r,r.exports,e),r.loaded=!0,r.exports}var n={};return e.m=t,e.c=n,e.p="",e(0)}([function(t,e,n){window.CordovaAppLoader=n(1),window.CordovaFileCache=n(2),window.CordovaPromiseFS=n(4),window.Promise=n(5),window.setImmediate=window.setTimeout},function(t,e,n){function o(t){var e=Object.keys(t);e.sort();var n="";return e.forEach(function(e){t[e]&&t[e].version,n+="@"+t[e].version}),i.hash(n)+""}function r(t){if(!t)throw new Error("CordovaAppLoader has no options!");if(!t.fs)throw new Error('CordovaAppLoader has no "fs" option (cordova-promise-fs)');if(!t.serverRoot)throw new Error('CordovaAppLoader has no "serverRoot" option.');if(!window.pegasus||!window.Manifest)throw new Error("CordovaAppLoader bootstrap.js is missing.");this.allowServerRootFromManifest=t.allowServerRootFromManifest===!0,a=t.fs.Promise,this.manifest=window.Manifest,this.newManifest=null,this.bundledManifest=null,this._lastUpdateFiles=localStorage.getItem("last_update_files"),t.serverRoot=t.serverRoot||"",t.serverRoot&&"/"!==t.serverRoot[t.serverRoot.length-1]&&(t.serverRoot+="/"),this.newManifestUrl=t.manifestUrl||t.serverRoot+(t.manifest||"manifest.json"),t.mode&&(t.mode="mirror"),this.cache=new i(t),this.corruptNewManifest=!1,this._toBeCopied=[],this._toBeDeleted=[],this._toBeDownloaded=[],this._updateReady=!1,this._checkTimeout=t.checkTimeout||1e4}var i=n(2),a=(n(4),null),u=location.href.replace(location.hash,"");u=u.substr(0,u.lastIndexOf("/")+1),/ip(hone|ad|od)/i.test(navigator.userAgent)&&(u=location.pathname.substr(location.pathname.indexOf("/www/")),u=u.substr(0,u.lastIndexOf("/")+1),u="cdvfile://localhost/bundle"+u),r.prototype._createFilemap=function(t){var e={},n=this.cache._fs.normalize;return Object.keys(t).forEach(function(o){t[o].filename=n(t[o].filename),e[t[o].filename]=t[o]}),e},r.prototype.copyFromBundle=function(t){var e=u+t;return this.cache._fs.download(e,this.cache.localRoot+t)},r.prototype.getBundledManifest=function(){var t=this,e=document.querySelector("script[manifest]"),n=(e?e.getAttribute("manifest"):null)||"manifest.json";return new a(function(e,o){t.bundledManifest?e(t.bundledManifest):(pegasus(n).then(function(n){t.bundledManifest=n,e(n)},o),setTimeout(function(){o(new Error("bundled manifest timeout"))},t._checkTimeout))})},r.prototype.check=function(t){var e=this,n=this.manifest;"string"==typeof t&&(e.newManifestUrl=t,t=void 0);var r=new a(function(n,o){"object"==typeof t?n(t):(pegasus(e.newManifestUrl).then(n,o),setTimeout(function(){o(new Error("new manifest timeout"))},e._checkTimeout))});return new a(function(t,i){a.all([r,e.getBundledManifest(),e.cache.list()]).then(function(r){var a=r[0],u=r[1],s=o(a.files);if(s===e._lastUpdateFiles){var c=o(Manifest.files);return e._lastUpdateFiles!==c&&(console.warn("New manifest available, but an earlier update attempt failed. Will not download."),e.corruptNewManifest=!0,t(null)),void t(!1)}if(!a.files)return void i('Downloaded Manifest has no "files" attribute.');var f=r[2],l=e._createFilemap(n.files),s=e._createFilemap(a.files),d=e._createFilemap(u.files);e._toBeDownloaded=[],e._toBeCopied=[],e._toBeDeleted=[];var h=e.cache._fs.isCordova;Object.keys(s).filter(function(t){return!l[t]||l[t].version!==s[t].version||!e.cache.isCached(t)}).forEach(function(t){h&&d[t]&&d[t].version===s[t].version?e._toBeCopied.push(t):e._toBeDownloaded.push(t)}),e._toBeDeleted=f.map(function(t){return t.substr(e.cache.localRoot.length)}).filter(function(t){return!s[t]||e._toBeDownloaded.indexOf(t)>=0||e._toBeCopied.indexOf(t)>=0});var p=e._toBeDeleted.length+e._toBeDownloaded.length;p>0?(e.newManifest=a,e.newManifest.root=e.cache.localInternalURL,t(!0)):t(!1)},function(t){i(t)})})},r.prototype.canDownload=function(){return!!this.newManifest&&!this._updateReady},r.prototype.canUpdate=function(){return this._updateReady},r.prototype.download=function(t){var e=this;return e.canDownload()?(localStorage.removeItem("manifest"),localStorage.setItem("last_update_files",o(this.newManifest.files)),this.manifest.files=Manifest.files={},e.cache.remove(e._toBeDeleted,!0).then(function(){return a.all(e._toBeCopied.map(function(t){return e.cache._fs.download(u+t,e.cache.localRoot+t)}))}).then(function(){return e.allowServerRootFromManifest&&e.newManifest.serverRoot&&(e.cache.serverRoot=e.newManifest.serverRoot),e.cache.add(e._toBeDownloaded),e.cache.download(t)}).then(function(){return e._toBeDeleted=[],e._toBeDownloaded=[],e._updateReady=!0,e.newManifest},function(t){return t&&t.length&&e.cache.remove(t),t})):new a(function(t){t(null)})},r.prototype.update=function(t){return this._updateReady?(localStorage.setItem("manifest",JSON.stringify(this.newManifest)),t!==!1&&location.reload(),!0):!1},r.prototype.clear=function(){return localStorage.removeItem("last_update_files"),localStorage.removeItem("manifest"),this.cache.clear()},r.prototype.reset=function(){return this.clear().then(function(){location.reload()},function(){location.reload()})},t.exports=r},function(t,e,n){function o(t){var e=this;if(this._fs=t.fs,!this._fs)throw new Error('Missing required option "fs". Add an instance of cordova-promise-fs.');i=this._fs.Promise,this._mirrorMode="hash"!==t.mode,this._retry=t.retry||[500,1500,8e3],this._cacheBuster=!!t.cacheBuster,this.localRoot=this._fs.normalize(t.localRoot||"data"),this.serverRoot=this._fs.normalize(t.serverRoot||""),this._downloading=[],this._added=[],this._cached={},this.ready=this._fs.ensure(this.localRoot).then(function(t){return e.localInternalURL=a?t.toInternalURL():t.toURL(),e.localUrl=t.toURL(),e.list()})}var r=n(3),i=null,a="undefined"!=typeof cordova;o.hash=r,o.prototype.list=function(){var t=this;return new i(function(e){t._fs.list(t.localRoot,"rfe").then(function(n){t._cached={},n=n.map(function(e){var n=t._fs.normalize(e.fullPath);return t._cached[n]={toInternalURL:a?e.toInternalURL():e.toURL(),toURL:e.toURL()},n}),e(n)},function(){e([])})})},o.prototype.add=function(t){t||(t=[]),"string"==typeof t&&(t=[t]);var e=this;return t.forEach(function(t){t=e.toServerURL(t),-1===e._added.indexOf(t)&&e._added.push(t)}),e.isDirty()},o.prototype.remove=function(t,e){t||(t=[]);var n=[];"string"==typeof t&&(t=[t]);var o=this;return t.forEach(function(t){var e=o._added.indexOf(o.toServerURL(t));e>=0&&o._added.splice(e,1);var r=o.toPath(t);n.push(o._fs.remove(r)),delete o._cached[r]}),e?i.all(n):o.isDirty()},o.prototype.getDownloadQueue=function(){var t=this,e=t._added.filter(function(e){return!t.isCached(e)});return e},o.prototype.getAdded=function(){return this._added},o.prototype.isDirty=function(){return this.getDownloadQueue().length>0},o.prototype.download=function(t){var e=this._fs,n=this;return n.abort(),new i(function(o,r){e.ensure(n.localRoot).then(function(){return n.list()}).then(function(){if(!n.isDirty())return void o(n);var i=n.getDownloadQueue(),a=n._downloading.length,u=n._downloading.length+i.length;i.forEach(function(i){var s,c=n.toPath(i);"function"==typeof t&&(s=function(e){e.queueIndex=a,e.queueSize=u,e.url=i,e.path=c,e.percentage=a/u,e.loaded>0&&e.total>0&&index!==u&&(e.percentage+=e.loaded/e.total/u),t(e)});var f=function(){a++,a===u&&(n._downloading=[],n.list().then(function(){s&&s(new ProgressEvent),n.isDirty()?r(n.getDownloadQueue()):o(n)},r))},l=i;n._cacheBuster&&(l+="?"+Date.now());var d=e.download(l,c,{retry:n._retry},s);d.then(f,f),n._downloading.push(d)})},r)})},o.prototype.abort=function(){this._downloading.forEach(function(t){t.abort()}),this._downloading=[]},o.prototype.isCached=function(t){return t=this.toPath(t),!!this._cached[t]},o.prototype.clear=function(){var t=this;return this._cached={},this._fs.removeDir(this.localRoot).then(function(){return t._fs.ensure(t.localRoot)})},o.prototype.toInternalURL=function(t){return path=this.toPath(t),this._cached[path]?this._cached[path].toInternalURL:t},o.prototype.get=function(t){return path=this.toPath(t),this._cached[path]?this._cached[path].toInternalURL:this.toServerURL(t)},o.prototype.toDataURL=function(t){return this._fs.toDataURL(this.toPath(t))},o.prototype.toURL=function(t){return path=this.toPath(t),this._cached[path]?this._cached[path].toURL:t},o.prototype.toServerURL=function(t){return t=this._fs.normalize(t),t.indexOf("://")<0?this.serverRoot+t:t},o.prototype.toPath=function(t){if(this._mirrorMode){var e=t.indexOf("?");return e>-1&&(t=t.substr(0,e)),t=t=this._fs.normalize(t||""),len=this.serverRoot.length,t.substr(0,len)!==this.serverRoot?this.localRoot+t:this.localRoot+t.substr(len)}return this.localRoot+r(t)+t.substr(t.lastIndexOf("."))},t.exports=o},function(t){function e(t,e){var n,o,r,i,a,u,s,c;for(n=3&t.length,o=t.length-n,r=e,a=3432918353,u=461845907,c=0;o>c;)s=255&t.charCodeAt(c)|(255&t.charCodeAt(++c))<<8|(255&t.charCodeAt(++c))<<16|(255&t.charCodeAt(++c))<<24,++c,s=(65535&s)*a+(((s>>>16)*a&65535)<<16)&4294967295,s=s<<15|s>>>17,s=(65535&s)*u+(((s>>>16)*u&65535)<<16)&4294967295,r^=s,r=r<<13|r>>>19,i=5*(65535&r)+((5*(r>>>16)&65535)<<16)&4294967295,r=(65535&i)+27492+(((i>>>16)+58964&65535)<<16);switch(s=0,n){case 3:s^=(255&t.charCodeAt(c+2))<<16;case 2:s^=(255&t.charCodeAt(c+1))<<8;case 1:s^=255&t.charCodeAt(c),s=(65535&s)*a+(((s>>>16)*a&65535)<<16)&4294967295,s=s<<15|s>>>17,s=(65535&s)*u+(((s>>>16)*u&65535)<<16)&4294967295,r^=s}return r^=t.length,r^=r>>>16,r=2246822507*(65535&r)+((2246822507*(r>>>16)&65535)<<16)&4294967295,r^=r>>>13,r=3266489909*(65535&r)+((3266489909*(r>>>16)&65535)<<16)&4294967295,r^=r>>>16,r>>>0}t.exports=e},function(t){function e(t,n,o,r){t.getDirectory(n[0],{create:!0},function(t){n.length>1?e(t,n.slice(1),o,r):o(t)},r)}function n(t){return t=t.substr(0,t.lastIndexOf("/")+1),"/"===t[0]&&(t=t.substr(1)),t}function o(t){return t.substr(t.lastIndexOf("/")+1)}function r(t){return t=t||"","/"===t[0]&&(t=t.substr(1)),t&&t.indexOf(".")<0&&"/"!==t[t.length-1]&&(t+="/"),"./"===t&&(t=""),t}var i=[],a=0;t.exports=function(t){function u(t){return new F(function(e){return e(t)})}function s(t){return new F(function(n,o){return E.then(function(r){t?(t=t.split("/").filter(function(t){return t&&t.length>0&&"."!==t&&".."!==t}),e(r.root,t,n,o)):n(r.root)},o)})}function c(t,e){return new F(function(n,o){return"object"==typeof t?n(t):(t=r(t),e=e||{},E.then(function(r){r.root.getFile(t,e,n,o)},o))})}function f(t,e){return t=r(t),e=e||{},new F(function(n,o){return E.then(function(r){t&&"/"!==t?r.root.getDirectory(t,e,n,o):n(r.root)},o)})}function l(t,e){e=e||"";var n=e.indexOf("r")>-1,o=e.indexOf("e")>-1,r=e.indexOf("f")>-1,i=e.indexOf("d")>-1;return r&&i&&(r=!1,i=!1),new F(function(e,a){return f(t).then(function(t){var s=t.createReader();s.readEntries(function(t){var s=[u(t)];n&&t.filter(function(t){return t.isDirectory}).forEach(function(t){s.push(l(t.fullPath,"re"))}),F.all(s).then(function(t){var n=[];n=n.concat.apply(n,t),r&&(n=n.filter(function(t){return t.isFile})),i&&(n=n.filter(function(t){return t.isDirectory})),o||(n=n.map(function(t){return t.fullPath})),e(n)},a)},a)},a)})}function d(t){return new F(function(e,n){c(t).then(function(t){e(t)},function(t){1===t.code?e(!1):n(t)})})}function h(t){return new F(function(e,n){f(t).then(function(t){e(t)},function(t){1===t.code?e(!1):n(t)})})}function p(t){return s(n(t)).then(function(){return c(t,{create:!0})})}function w(t){return c(t).then(function(t){return t.toURL()})}function m(t,e){return e=e||"readAsText",c(t).then(function(t){return new F(function(n,o){t.file(function(t){var o=new FileReader;o.onloadend=function(){n(this.result)},o[e](t)},o)})})}function v(t){return m(t,"readAsDataURL")}function y(t){return m(t).then(JSON.parse)}function _(t,e,o){return s(n(t)).then(function(){return c(t,{create:!0})}).then(function(t){return new F(function(n,r){t.createWriter(function(t){t.onwriteend=n,t.onerror=r,"string"==typeof e?e=new Blob([e],{type:o||"text/plain"}):e instanceof Blob!=!0&&(e=new Blob([JSON.stringify(e,null,4)],{type:o||"application/json"})),t.write(e)},r)})})}function g(t,e){return s(n(e)).then(function(n){return c(t).then(function(t){return new F(function(r,i){t.moveTo(n,o(e),r,i)})})})}function R(t,e){return t=t.replace(/\/$/,""),e=e.replace(/\/$/,""),s(n(e)).then(function(n){return f(t).then(function(t){return new F(function(r,i){t.moveTo(n,o(e),r,i)})})})}function b(t,e){return s(n(e)).then(function(n){return c(t).then(function(t){return new F(function(r,i){t.copyTo(n,o(e),r,i)})})})}function T(t,e){var n=e?c:d;return new F(function(e,o){n(t).then(function(t){t!==!1?t.remove(e,o):e(1)},o)}).then(function(t){return 1===t?!1:!0})}function S(t){return f(t).then(function(t){return new F(function(e,n){t.removeRecursively(e,n)})})}function L(){for(;i.length>0&&a<t.concurrency;){a++;var e=i.pop(),n=e.shift(),o=e.shift(),r=e.shift(),u=e.shift(),s=e.shift(),c=e.shift(),f=e.shift(),l=e.shift();n._aborted?a--:o?(n.download.call(n,r,u,s,c,f,l),n.onprogress&&n.onprogress(new ProgressEvent)):n.upload.call(n,u,r,s,c,l,f)}}function x(t){return a--,L(),t}function D(e,n,r,u,s){"function"==typeof u&&(s=u,u={}),C&&r.indexOf("://")<0&&(r=O(r)),u=u||{},u.retry&&u.retry.length||(u.retry=t.retry),u.retry=u.retry.concat(),u.file||e||(u.fileName=o(r));var c=new FileTransfer;s=s||u.onprogress,"function"==typeof s&&(c.onprogress=s);var f=new F(function(t,o){var s=function(a){if(0===u.retry.length)o(a);else{i.unshift([c,e,n,r,t,s,u.trustAllHosts||!1,u]);var f=u.retry.shift();f>0?setTimeout(x,f):x()}};u.retry.unshift(0),a++,s()});return f.then(x,x),f.progress=function(t){return c.onprogress=t,f},f.abort=function(){return c._aborted=!0,c.abort(),f},f}function I(t,e,n,o){return D(!0,t,e,n,o)}function U(t,e,n,o){return D(!1,e,t,n,o)}var F=t.Promise||window.Promise;if(!F)throw new Error("No Promise library given in options.Promise");this.options=t=t||{},t.persistent=void 0!==t.persistent?t.persistent:!0,t.storageSize=t.storageSize||20971520,t.concurrency=t.concurrency||3,t.retry=t.retry||[];var M,C="undefined"!=typeof cordova;C?M=new F(function(t,e){document.addEventListener("deviceready",t,!1),setTimeout(function(){e(new Error("deviceready has not fired after 5 seconds."))},5100)}):(M=u(!0),"undefined"!=typeof webkitRequestFileSystem?(window.requestFileSystem=webkitRequestFileSystem,window.FileTransfer=function(){},FileTransfer.prototype.download=function(t,e,n,o){var r=new XMLHttpRequest;return r.open("GET",t),r.responseType="blob",r.onreadystatechange=function(){4==r.readyState&&(200===r.status?_(e,r.response).then(n,o):o(r.status))},r.send(),r},window.ProgressEvent=function(){},window.FileEntry=function(){}):window.requestFileSystem=function(t,e,n,o){o(new Error("requestFileSystem not supported!"))});var E=new F(function(e,n){M.then(function(){var o=t.persistent?1:0;"number"==typeof t.fileSystem&&(o=t.fileSystem),!C&&o>1&&(console.warn('Chrome does not support fileSystem "'+o+'". Falling back on "0" (temporary).'),o=0),!C&&1===o&&navigator.webkitPersistentStorage?navigator.webkitPersistentStorage.requestQuota(t.storageSize,function(t){window.requestFileSystem(o,t,e,n)}):window.requestFileSystem(o,t.storageSize,e,n),setTimeout(function(){n(new Error("Could not retrieve FileSystem after 5 seconds."))},5100)},n)});E.then(function(t){window.__fs=t},function(t){console.error("Could not get Cordova FileSystem:",t)});var B,O;return C?(O=function(e){return e=r(e),e.indexOf("://")<0?"cdvfile://localhost/"+(t.persistent?"persistent/":"temporary/")+e:e},B=function(t){return c(t).then(function(t){return t.toInternalURL()})}):(O=function(e){return e=r(e),"filesystem:"+location.origin+(t.persistent?"/persistent/":"/temporary/")+e},B=function(t){return c(t).then(function(t){return t.toURL()})}),{fs:E,normalize:r,file:c,filename:o,dir:f,dirname:n,create:p,read:m,readJSON:y,write:_,move:g,moveDir:R,copy:b,remove:T,removeDir:S,list:l,ensure:s,exists:d,existsDir:h,download:I,upload:U,toURL:w,isCordova:C,toInternalURLSync:O,toInternalURL:B,toDataURL:v,deviceready:M,options:t,Promise:F}}},function(t,e,n){(function(e){!function(n,o){function r(t,e){return(typeof e)[0]==t}function i(t,e){return e=function u(s,c,f,l,d,h){function p(t){return function(e){d&&(d=0,u(r,t,e))}}if(l=u.q,s!=r)return i(function(t,e){l.push({p:this,r:t,j:e,1:s,0:c})});if(f&&r(n,f)|r(o,f))try{d=f.then}catch(t){c=0,f=t}if(r(n,d))try{d.call(f,p(1),c=p(0))}catch(t){c(t)}else for(e=function(e,o){return r(n,e=c?e:o)?i(function(t,n){a(this,t,n,f,e)}):t},h=0;h<l.length;)d=l[h++],r(n,s=d[c])?a(d.p,d.r,d.j,f,s):(c?d.r:d.j)(f)},e.q=[],t.call(t={then:function(t,n){return e(t,n)},catch:function(t){return e(0,t)}},function(t){e(r,1,t)},function(t){e(r,0,t)}),t}function a(t,i,a,u,s){e(function(){try{u=s(u),s=u&&r(o,u)|r(n,u)&&u.then,r(n,s)?u==t?a(TypeError()):s.call(u,i,a):i(u)}catch(t){a(t)}})}function u(t){return i(function(e){e(t)})}t.exports=i,i.resolve=u,i.reject=function(t){return i(function(e,n){n(t)})},i.all=function(t){return i(function(e,n,o,r){r=[],o=t.length||e(r),t.map(function(t,i){u(t).then(function(t){r[i]=t,--o||e(r)},n)})})}}("f","o")}).call(e,n(6).setImmediate)},function(t,e,n){(function(t,o){function r(t,e){this._id=t,this._clearFn=e}var i=n(7).nextTick,a=Function.prototype.apply,u=Array.prototype.slice,s={},c=0;e.setTimeout=function(){return new r(a.call(setTimeout,window,arguments),clearTimeout)},e.setInterval=function(){return new r(a.call(setInterval,window,arguments),clearInterval)},e.clearTimeout=e.clearInterval=function(t){t.close()},r.prototype.unref=r.prototype.ref=function(){},r.prototype.close=function(){this._clearFn.call(window,this._id)},e.enroll=function(t,e){clearTimeout(t._idleTimeoutId),t._idleTimeout=e},e.unenroll=function(t){clearTimeout(t._idleTimeoutId),t._idleTimeout=-1},e._unrefActive=e.active=function(t){clearTimeout(t._idleTimeoutId);var e=t._idleTimeout;e>=0&&(t._idleTimeoutId=setTimeout(function(){t._onTimeout&&t._onTimeout()},e))},e.setImmediate="function"==typeof t?t:function(t){var n=c++,o=arguments.length<2?!1:u.call(arguments,1);return s[n]=!0,i(function(){s[n]&&(o?t.apply(null,o):t.call(null),e.clearImmediate(n))}),n},e.clearImmediate="function"==typeof o?o:function(t){delete s[t]}}).call(e,n(6).setImmediate,n(6).clearImmediate)},function(t){function e(){s=!1,i.length?u=i.concat(u):c=-1,u.length&&n()}function n(){if(!s){var t=setTimeout(e);s=!0;for(var n=u.length;n;){for(i=u,u=[];++c<n;)i&&i[c].run();c=-1,n=u.length}i=null,s=!1,clearTimeout(t)}}function o(t,e){this.fun=t,this.array=e}function r(){}var i,a=t.exports={},u=[],s=!1,c=-1;a.nextTick=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var r=1;r<arguments.length;r++)e[r-1]=arguments[r];u.push(new o(t,e)),1!==u.length||s||setTimeout(n,0)},o.prototype.run=function(){this.fun.apply(null,this.array)},a.title="browser",a.browser=!0,a.env={},a.argv=[],a.version="",a.versions={},a.on=r,a.addListener=r,a.once=r,a.off=r,a.removeListener=r,a.removeAllListeners=r,a.emit=r,a.binding=function(){throw new Error("process.binding is not supported")},a.cwd=function(){return"/"},a.chdir=function(){throw new Error("process.chdir is not supported")},a.umask=function(){return 0}}]); | ||
!function(t){function e(o){if(n[o])return n[o].exports;var r=n[o]={exports:{},id:o,loaded:!1};return t[o].call(r.exports,r,r.exports,e),r.loaded=!0,r.exports}var n={};return e.m=t,e.c=n,e.p="",e(0)}([function(t,e,n){window.CordovaAppLoader=n(1),window.CordovaFileCache=n(2),window.CordovaPromiseFS=n(4),window.Promise=n(5),window.setImmediate=window.setTimeout},function(t,e,n){function o(t){var e=Object.keys(t);e.sort();var n="";return e.forEach(function(e){t[e]&&t[e].version,n+="@"+t[e].version}),i.hash(n)+""}function r(t){if(!t)throw new Error("CordovaAppLoader has no options!");if(!t.fs)throw new Error('CordovaAppLoader has no "fs" option (cordova-promise-fs)');if(!t.serverRoot)throw new Error('CordovaAppLoader has no "serverRoot" option.');if(!window.pegasus||!window.Manifest)throw new Error("CordovaAppLoader bootstrap.js is missing.");this.allowServerRootFromManifest=t.allowServerRootFromManifest===!0,a=t.fs.Promise,this.manifest=window.Manifest,this.newManifest=null,this.bundledManifest=null,this.preventAutoUpdateLoop=t.preventAutoUpdateLoop===!0,this._lastUpdateFiles=localStorage.getItem("last_update_files"),t.serverRoot=t.serverRoot||"",t.serverRoot&&"/"!==t.serverRoot[t.serverRoot.length-1]&&(t.serverRoot+="/"),this.newManifestUrl=t.manifestUrl||t.serverRoot+(t.manifest||"manifest.json"),t.mode&&(t.mode="mirror"),this.cache=new i(t),this.corruptNewManifest=!1,this._toBeCopied=[],this._toBeDeleted=[],this._toBeDownloaded=[],this._updateReady=!1,this._checkTimeout=t.checkTimeout||1e4}var i=n(2),a=(n(4),null),u=location.href.replace(location.hash,"");u=u.substr(0,u.lastIndexOf("/")+1),/ip(hone|ad|od)/i.test(navigator.userAgent)&&(u=location.pathname.substr(location.pathname.indexOf("/www/")),u=u.substr(0,u.lastIndexOf("/")+1),u="cdvfile://localhost/bundle"+u),r.prototype._createFilemap=function(t){var e={},n=this.cache._fs.normalize;return Object.keys(t).forEach(function(o){t[o].filename=n(t[o].filename),e[t[o].filename]=t[o]}),e},r.prototype.copyFromBundle=function(t){var e=u+t;return this.cache._fs.download(e,this.cache.localRoot+t)},r.prototype.getBundledManifest=function(){var t=this,e=document.querySelector("script[manifest]"),n=(e?e.getAttribute("manifest"):null)||"manifest.json";return new a(function(e,o){t.bundledManifest?e(t.bundledManifest):(pegasus(n).then(function(n){t.bundledManifest=n,e(n)},o),setTimeout(function(){o(new Error("bundled manifest timeout"))},t._checkTimeout))})},r.prototype.check=function(t){var e=this,n=this.manifest;"string"==typeof t&&(e.newManifestUrl=t,t=void 0);var r=new a(function(n,o){"object"==typeof t?n(t):(pegasus(e.newManifestUrl).then(n,o),setTimeout(function(){o(new Error("new manifest timeout"))},e._checkTimeout))});return new a(function(t,i){a.all([r,e.getBundledManifest(),e.cache.list()]).then(function(r){var a=r[0],u=r[1],s=o(a.files);if(e.preventAutoUpdateLoop===!0&&s===e._lastUpdateFiles){var c=o(Manifest.files);return e._lastUpdateFiles!==c&&(console.warn("New manifest available, but an earlier update attempt failed. Will not download."),e.corruptNewManifest=!0,t(null)),void t(!1)}if(!a.files)return void i(new Error('Downloaded Manifest has no "files" attribute.'));var f=r[2],l=e._createFilemap(n.files),s=e._createFilemap(a.files),d=e._createFilemap(u.files);e._toBeDownloaded=[],e._toBeCopied=[],e._toBeDeleted=[];var h=e.cache._fs.isCordova,p=0;Object.keys(s).filter(function(t){return!l[t]||l[t].version!==s[t].version}).forEach(function(t){h&&d[t]&&d[t].version===s[t].version?e._toBeCopied.push(t):e._toBeDownloaded.push(t),d[t]&&d[t].version===s[t].version||p++}),e._toBeDeleted=f.map(function(t){return t.substr(e.cache.localRoot.length)}).filter(function(t){return!s[t]||e._toBeDownloaded.indexOf(t)>=0||e._toBeCopied.indexOf(t)>=0}),p+=e._toBeDeleted.length,p>0?(e.newManifest=a,e.newManifest.root=e.cache.localUrl,t(!0)):t(!1)},function(t){i(t)})})},r.prototype.canDownload=function(){return!!this.newManifest&&!this._updateReady},r.prototype.canUpdate=function(){return this._updateReady},r.prototype.download=function(t,e){var n=this;return n.canDownload()?(localStorage.removeItem("manifest"),localStorage.setItem("last_update_files",o(this.newManifest.files)),this.manifest.files=Manifest.files={},n.cache.remove(n._toBeDeleted,!0).then(function(){return a.all(n._toBeCopied.map(function(t){return n.cache._fs.download(u+t,n.cache.localRoot+t)}))}).then(function(){return n.allowServerRootFromManifest&&n.newManifest.serverRoot&&(n.cache.serverRoot=n.newManifest.serverRoot),n.cache.add(n._toBeDownloaded),n.cache.download(t,e)}).then(function(){return n._toBeDeleted=[],n._toBeDownloaded=[],n._updateReady=!0,n.newManifest},function(t){return t&&t.length&&n.cache.remove(t),t})):new a(function(t){t(null)})},r.prototype.update=function(t){return this._updateReady?(localStorage.setItem("manifest",JSON.stringify(this.newManifest)),t!==!1&&location.reload(),!0):!1},r.prototype.clear=function(){return localStorage.removeItem("last_update_files"),localStorage.removeItem("manifest"),this.cache.clear()},r.prototype.reset=function(){return this.clear().then(function(){location.reload()},function(){location.reload()})},t.exports=r},function(t,e,n){function o(t){var e=this;if(this._fs=t.fs,!this._fs)throw new Error('Missing required option "fs". Add an instance of cordova-promise-fs.');i=this._fs.Promise,this._mirrorMode="hash"!==t.mode,this._retry=t.retry||[500,1500,8e3],this._cacheBuster=!!t.cacheBuster,this.localRoot=this._fs.normalize(t.localRoot||"data"),this.serverRoot=this._fs.normalize(t.serverRoot||""),this._downloading=[],this._added=[],this._cached={},this.ready=this._fs.ensure(this.localRoot).then(function(t){return e.localInternalURL=a?t.toInternalURL():t.toURL(),e.localUrl=t.toURL(),e.list()})}var r=n(3),i=null,a="undefined"!=typeof cordova;o.hash=r,o.prototype.list=function(){var t=this;return new i(function(e){t._fs.list(t.localRoot,"rfe").then(function(n){t._cached={},n=n.map(function(e){var n=t._fs.normalize(e.fullPath);return t._cached[n]={toInternalURL:a?e.toInternalURL():e.toURL(),toURL:e.toURL()},n}),e(n)},function(){e([])})})},o.prototype.add=function(t){t||(t=[]),"string"==typeof t&&(t=[t]);var e=this;return t.forEach(function(t){t=e.toServerURL(t),-1===e._added.indexOf(t)&&e._added.push(t)}),e.isDirty()},o.prototype.remove=function(t,e){t||(t=[]);var n=[];"string"==typeof t&&(t=[t]);var o=this;return t.forEach(function(t){var e=o._added.indexOf(o.toServerURL(t));e>=0&&o._added.splice(e,1);var r=o.toPath(t);n.push(o._fs.remove(r)),delete o._cached[r]}),e?i.all(n):o.isDirty()},o.prototype.getDownloadQueue=function(){var t=this,e=t._added.filter(function(e){return!t.isCached(e)});return e},o.prototype.getAdded=function(){return this._added},o.prototype.isDirty=function(){return this.getDownloadQueue().length>0},o.prototype.download=function(t,e){var n=this._fs,o=this;return e=e||!1,o.abort(),new i(function(r,i){n.ensure(o.localRoot).then(function(){return o.list()}).then(function(){if(!o.isDirty())return void r(o);var a=o.getDownloadQueue(),u=o._downloading.length,s=o._downloading.length+a.length,c=0;a.forEach(function(a){var f,l=o.toPath(a);"function"==typeof t&&(f=function(e){e.queueIndex=u,e.queueSize=s,e.url=a,e.path=l,e.percentage=u/s,e.loaded>0&&e.total>0&&u!==s&&(e.percentage+=e.loaded/e.total/s),e.percentage=Math.max(c,e.percentage),c=e.percentage,t(e)});var d=function(){u++,f(new ProgressEvent),u===s&&(o._downloading=[],o.list().then(function(){f&&f(new ProgressEvent),o.isDirty()?i(o.getDownloadQueue()):r(o)},i))},h=a;o._cacheBuster&&(h+="?"+Date.now());var p=n.download(h,l,{retry:o._retry},e?f:void 0);p.then(d,d),o._downloading.push(p)})},i)})},o.prototype.abort=function(){this._downloading.forEach(function(t){t.abort()}),this._downloading=[]},o.prototype.isCached=function(t){return t=this.toPath(t),!!this._cached[t]},o.prototype.clear=function(){var t=this;return this._cached={},this._fs.removeDir(this.localRoot).then(function(){return t._fs.ensure(t.localRoot)})},o.prototype.toInternalURL=function(t){return path=this.toPath(t),this._cached[path]?this._cached[path].toInternalURL:t},o.prototype.get=function(t){return path=this.toPath(t),this._cached[path]?this._cached[path].toURL:this.toServerURL(t)},o.prototype.toDataURL=function(t){return this._fs.toDataURL(this.toPath(t))},o.prototype.toURL=function(t){return path=this.toPath(t),this._cached[path]?this._cached[path].toURL:t},o.prototype.toServerURL=function(t){return t=this._fs.normalize(t),t.indexOf("://")<0?this.serverRoot+t:t},o.prototype.toPath=function(t){if(this._mirrorMode){var e=t.indexOf("?");return e>-1&&(t=t.substr(0,e)),t=t=this._fs.normalize(t||""),len=this.serverRoot.length,t.substr(0,len)!==this.serverRoot?this.localRoot+t:this.localRoot+t.substr(len)}var n=t.substr(t.lastIndexOf("."));return(n.indexOf("?")>0||n.indexOf("/")>0)&&(n=".txt"),this.localRoot+r(t)+n},t.exports=o},function(t){function e(t,e){var n,o,r,i,a,u,s,c;for(n=3&t.length,o=t.length-n,r=e,a=3432918353,u=461845907,c=0;o>c;)s=255&t.charCodeAt(c)|(255&t.charCodeAt(++c))<<8|(255&t.charCodeAt(++c))<<16|(255&t.charCodeAt(++c))<<24,++c,s=(65535&s)*a+(((s>>>16)*a&65535)<<16)&4294967295,s=s<<15|s>>>17,s=(65535&s)*u+(((s>>>16)*u&65535)<<16)&4294967295,r^=s,r=r<<13|r>>>19,i=5*(65535&r)+((5*(r>>>16)&65535)<<16)&4294967295,r=(65535&i)+27492+(((i>>>16)+58964&65535)<<16);switch(s=0,n){case 3:s^=(255&t.charCodeAt(c+2))<<16;case 2:s^=(255&t.charCodeAt(c+1))<<8;case 1:s^=255&t.charCodeAt(c),s=(65535&s)*a+(((s>>>16)*a&65535)<<16)&4294967295,s=s<<15|s>>>17,s=(65535&s)*u+(((s>>>16)*u&65535)<<16)&4294967295,r^=s}return r^=t.length,r^=r>>>16,r=2246822507*(65535&r)+((2246822507*(r>>>16)&65535)<<16)&4294967295,r^=r>>>13,r=3266489909*(65535&r)+((3266489909*(r>>>16)&65535)<<16)&4294967295,r^=r>>>16,r>>>0}t.exports=e},function(t){function e(t,n,o,r){t.getDirectory(n[0],{create:!0},function(t){n.length>1?e(t,n.slice(1),o,r):o(t)},r)}function n(t){return t=t.substr(0,t.lastIndexOf("/")+1),"/"===t[0]&&(t=t.substr(1)),t}function o(t){return t.substr(t.lastIndexOf("/")+1)}function r(t){t=t||"","/"===t[0]&&(t=t.substr(1));for(var e=t.split("/"),n=e[0],o=1;o<e.length;o++)n=e[o],".."===e[o]?(e.splice(o-1,2),o-=2):"."===e[o]&&(e.splice(o,1),o--);return t=e.join("/"),"./"===t?t="":n&&n.indexOf(".")<0&&"/"!=t[t.length-1]&&(t+="/"),t}var i=[],a=0;t.exports=function(t){function u(t){return new E(function(e){return e(t)})}function s(t){return new E(function(n,o){return B.then(function(r){t?(t=t.split("/").filter(function(t){return t&&t.length>0&&"."!==t&&".."!==t}),e(r.root,t,n,o)):n(r.root)},o)})}function c(t,e){return new E(function(n,o){return"object"==typeof t?n(t):(t=r(t),e=e||{},B.then(function(r){r.root.getFile(t,e,n,o)},o))})}function f(t,e){return t=r(t),e=e||{},new E(function(n,o){return B.then(function(r){t&&"/"!==t?r.root.getDirectory(t,e,n,o):n(r.root)},o)})}function l(t,e){e=e||"";var n=e.indexOf("r")>-1,o=e.indexOf("e")>-1,r=e.indexOf("f")>-1,i=e.indexOf("d")>-1;return r&&i&&(r=!1,i=!1),new E(function(e,a){return f(t).then(function(t){var s=t.createReader();s.readEntries(function(t){var s=[u(t)];n&&t.filter(function(t){return t.isDirectory}).forEach(function(t){s.push(l(t.fullPath,"re"))}),E.all(s).then(function(t){var n=[];n=n.concat.apply(n,t),r&&(n=n.filter(function(t){return t.isFile})),i&&(n=n.filter(function(t){return t.isDirectory})),o||(n=n.map(function(t){return t.fullPath})),e(n)},a)},a)},a)})}function d(t){return new E(function(e,n){c(t).then(function(t){e(t)},function(t){1===t.code?e(!1):n(t)})})}function h(t){return new E(function(e,n){f(t).then(function(t){e(t)},function(t){1===t.code?e(!1):n(t)})})}function p(t){return s(n(t)).then(function(){return c(t,{create:!0})})}function w(t){return c(t).then(function(t){return t.toURL()})}function v(t,e){return e=e||"readAsText",c(t).then(function(t){return new E(function(n,o){t.file(function(t){var o=new FileReader;o.onloadend=function(){n(this.result)},o[e](t)},o)})})}function m(t){return v(t,"readAsDataURL")}function y(t){return v(t).then(JSON.parse)}function _(t,e,o){return s(n(t)).then(function(){return c(t,{create:!0})}).then(function(t){return new E(function(n,r){t.createWriter(function(t){t.onwriteend=n,t.onerror=r,"string"==typeof e?e=g([e],o||"text/plain"):e instanceof Blob!=!0&&(e=g([JSON.stringify(e,null,4)],o||"application/json")),t.write(e)},r)})})}function g(t,e){var n,o;try{return new Blob(t,{type:e})}catch(r){if(n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder)return o=new n,o.append(t),o.getBlob(e);throw new Error("Unable to create blob")}}function R(t,e){return s(n(e)).then(function(n){return c(t).then(function(t){return new E(function(r,i){t.moveTo(n,o(e),r,i)})})})}function b(t,e){return t=t.replace(/\/$/,""),e=e.replace(/\/$/,""),s(n(e)).then(function(n){return f(t).then(function(t){return new E(function(r,i){t.moveTo(n,o(e),r,i)})})})}function T(t,e){return s(n(e)).then(function(n){return c(t).then(function(t){return new E(function(r,i){t.copyTo(n,o(e),r,i)})})})}function L(t,e){var n=e?c:d;return new E(function(e,o){n(t).then(function(t){t!==!1?t.remove(e,o):e(1)},o)}).then(function(t){return 1===t?!1:!0})}function U(t){return f(t).then(function(t){return new E(function(e,n){t.removeRecursively(e,n)})})}function D(){for(;i.length>0&&a<t.concurrency;){a++;var e=i.pop(),n=e.fileTransfer,o=e.isDownload,r=e.serverUrl,u=e.localPath,s=e.trustAllHosts,c=e.transferOptions,f=e.win,l=e.fail;n._aborted?a--:o?(n.download.call(n,r,u,f,l,s,c),n.onprogress&&n.onprogress(new ProgressEvent)):n.upload.call(n,u,r,f,l,c,s)}}function O(t){return a--,D(),t}function x(e,n,r,u,s){"function"==typeof u&&(s=u,u={}),M&&r.indexOf("://")<0&&(r=P(r)),u=u||{},u.retry&&u.retry.length||(u.retry=t.retry),u.retry=u.retry.concat(),u.file||e||(u.fileName=o(r));var c=new FileTransfer;s=s||u.onprogress,"function"==typeof s&&(c.onprogress=s);var f=new E(function(o,s){var f=function(a){if(0===u.retry.length)t.debug&&console.log("FileTransfer Error: "+n,a),s(a);else{var l={fileTransfer:c,isDownload:e,serverUrl:n,localPath:r,trustAllHosts:u.trustAllHosts||!1,transferOptions:u,win:o,fail:f};i.unshift(l);var d=u.retry.shift();d>0?setTimeout(O,d):O()}};u.retry.unshift(0),a++,f()});return f.then(O,O),f.progress=function(t){return c.onprogress=t,f},f.abort=function(){return c._aborted=!0,c.abort(),f},f}function S(t,e,n,o){return x(!0,t,e,n,o)}function I(t,e,n,o){return x(!1,e,t,n,o)}var E=t.Promise||window.Promise;if(!E)throw new Error("No Promise library given in options.Promise");t=t||{},t.persistent=void 0!==t.persistent?t.persistent:!0,t.storageSize=t.storageSize||20971520,t.concurrency=t.concurrency||3,t.retry=t.retry||[],t.debug=!!t.debug;var F,M="undefined"!=typeof cordova;M?F=new E(function(t,e){document.addEventListener("deviceready",t,!1),setTimeout(function(){e(new Error("deviceready has not fired after 5 seconds."))},5100)}):(F=u(!0),"undefined"!=typeof webkitRequestFileSystem?(window.requestFileSystem=webkitRequestFileSystem,window.FileTransfer=function(){},FileTransfer.prototype.download=function(t,e,n,o){var r=new XMLHttpRequest;return r.open("GET",t),r.responseType="blob",r.onreadystatechange=function(){4==r.readyState&&(200!==r.status||this._aborted?o(r.status):_(e,r.response).then(n,o))},r.send(),r},FileTransfer.prototype.abort=function(){this._aborted=!0},window.ProgressEvent=function(){},window.FileEntry=function(){}):window.requestFileSystem=function(t,e,n,o){o(new Error("requestFileSystem not supported!"))});var B=new E(function(e,n){F.then(function(){var o=t.persistent?1:0;t.fileSystem&&M&&(o=t.fileSystem),!M&&1===o&&navigator.webkitPersistentStorage?navigator.webkitPersistentStorage.requestQuota(t.storageSize,function(t){window.requestFileSystem(o,t,e,n)},n):isNaN(o)?window.resolveLocalFileSystemURL(o,function(t){e(t.filesystem)},n):window.requestFileSystem(o,t.storageSize,e,n),setTimeout(function(){n(new Error("Could not retrieve FileSystem after 5 seconds."))},5100)},n)});B.then(function(t){CDV_INTERNAL_URL_ROOT=t.root.toInternalURL(),CDV_URL_ROOT=t.root.toURL(),window.__fs=t},function(t){console.error("Could not get Cordova FileSystem:",t)});var C,A,P;return CDV_INTERNAL_URL_ROOT="cdvfile://localhost/"+(t.persistent?"persistent/":"temporary/"),CDV_URL_ROOT="",M?(A=function(t){return t=r(t),t.indexOf("://")<0?CDV_INTERNAL_URL_ROOT+t:t},P=function(t){return t=r(t),t.indexOf("://")<0?CDV_URL_ROOT+t:t},C=function(t){return c(t).then(function(t){return t.toInternalURL()})}):(A=function(e){return e=r(e),"filesystem:"+location.origin+(t.persistent?"/persistent/":"/temporary/")+e},C=function(t){return c(t).then(function(t){return t.toURL()})},P=A),{fs:B,normalize:r,file:c,filename:o,dir:f,dirname:n,create:p,read:v,readJSON:y,write:_,move:R,moveDir:b,copy:T,remove:L,removeDir:U,list:l,ensure:s,exists:d,existsDir:h,download:S,upload:I,toURL:w,isCordova:M,toInternalURLSync:A,toInternalURL:C,toDataURL:m,deviceready:F,options:t,Promise:E}}},function(t,e,n){(function(e){!function(n,o){function r(t,e){return(typeof e)[0]==t}function i(t,e){return e=function u(s,c,f,l,d,h){function p(t){return function(e){d&&(d=0,u(r,t,e))}}if(l=u.q,s!=r)return i(function(t,e){l.push({p:this,r:t,j:e,1:s,0:c})});if(f&&r(n,f)|r(o,f))try{d=f.then}catch(t){c=0,f=t}if(r(n,d))try{d.call(f,p(1),c=p(0))}catch(t){c(t)}else for(e=function(e,o){return r(n,e=c?e:o)?i(function(t,n){a(this,t,n,f,e)}):t},h=0;h<l.length;)d=l[h++],r(n,s=d[c])?a(d.p,d.r,d.j,f,s):(c?d.r:d.j)(f)},e.q=[],t.call(t={then:function(t,n){return e(t,n)},catch:function(t){return e(0,t)}},function(t){e(r,1,t)},function(t){e(r,0,t)}),t}function a(t,i,a,u,s){e(function(){try{u=s(u),s=u&&r(o,u)|r(n,u)&&u.then,r(n,s)?u==t?a(TypeError()):s.call(u,i,a):i(u)}catch(t){a(t)}})}function u(t){return i(function(e){e(t)})}t.exports=i,i.resolve=u,i.reject=function(t){return i(function(e,n){n(t)})},i.all=function(t){return i(function(e,n,o,r){r=[],o=t.length||e(r),t.map(function(t,i){u(t).then(function(t){r[i]=t,--o||e(r)},n)})})}}("f","o")}).call(e,n(6).setImmediate)},function(t,e,n){(function(t,o){function r(t,e){this._id=t,this._clearFn=e}var i=n(7).nextTick,a=Function.prototype.apply,u=Array.prototype.slice,s={},c=0;e.setTimeout=function(){return new r(a.call(setTimeout,window,arguments),clearTimeout)},e.setInterval=function(){return new r(a.call(setInterval,window,arguments),clearInterval)},e.clearTimeout=e.clearInterval=function(t){t.close()},r.prototype.unref=r.prototype.ref=function(){},r.prototype.close=function(){this._clearFn.call(window,this._id)},e.enroll=function(t,e){clearTimeout(t._idleTimeoutId),t._idleTimeout=e},e.unenroll=function(t){clearTimeout(t._idleTimeoutId),t._idleTimeout=-1},e._unrefActive=e.active=function(t){clearTimeout(t._idleTimeoutId);var e=t._idleTimeout;e>=0&&(t._idleTimeoutId=setTimeout(function(){t._onTimeout&&t._onTimeout()},e))},e.setImmediate="function"==typeof t?t:function(t){var n=c++,o=arguments.length<2?!1:u.call(arguments,1);return s[n]=!0,i(function(){s[n]&&(o?t.apply(null,o):t.call(null),e.clearImmediate(n))}),n},e.clearImmediate="function"==typeof o?o:function(t){delete s[t]}}).call(e,n(6).setImmediate,n(6).clearImmediate)},function(t){function e(){s=!1,i.length?u=i.concat(u):c=-1,u.length&&n()}function n(){if(!s){var t=setTimeout(e);s=!0;for(var n=u.length;n;){for(i=u,u=[];++c<n;)i&&i[c].run();c=-1,n=u.length}i=null,s=!1,clearTimeout(t)}}function o(t,e){this.fun=t,this.array=e}function r(){}var i,a=t.exports={},u=[],s=!1,c=-1;a.nextTick=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var r=1;r<arguments.length;r++)e[r-1]=arguments[r];u.push(new o(t,e)),1!==u.length||s||setTimeout(n,0)},o.prototype.run=function(){this.fun.apply(null,this.array)},a.title="browser",a.browser=!0,a.env={},a.argv=[],a.version="",a.versions={},a.on=r,a.addListener=r,a.once=r,a.off=r,a.removeListener=r,a.removeAllListeners=r,a.emit=r,a.binding=function(){throw new Error("process.binding is not supported")},a.cwd=function(){return"/"},a.chdir=function(){throw new Error("process.chdir is not supported")},a.umask=function(){return 0}}]); |
@@ -83,2 +83,3 @@ var CordovaAppLoader = | ||
this.bundledManifest = null; | ||
this.preventAutoUpdateLoop = options.preventAutoUpdateLoop === true; | ||
this._lastUpdateFiles = localStorage.getItem('last_update_files'); | ||
@@ -165,3 +166,3 @@ | ||
// Check if the newFiles match the previous files (last_update_files) | ||
if(newFiles === self._lastUpdateFiles) { | ||
if(self.preventAutoUpdateLoop === true && newFiles === self._lastUpdateFiles) { | ||
// YES! So we're doing the same update again! | ||
@@ -184,3 +185,3 @@ | ||
if(!newManifest.files){ | ||
reject('Downloaded Manifest has no "files" attribute.'); | ||
reject(new Error('Downloaded Manifest has no "files" attribute.')); | ||
return; | ||
@@ -200,2 +201,3 @@ } | ||
var isCordova = self.cache._fs.isCordova; | ||
var changes = 0; | ||
Object.keys(newFiles) | ||
@@ -207,3 +209,3 @@ // Find files that have changed version or are missing | ||
// version has changed, or... | ||
oldFiles[file].version !== newFiles[file].version || | ||
oldFiles[file].version !== newFiles[file].version //|| | ||
// not in cache for some reason | ||
@@ -221,2 +223,5 @@ !self.cache.isCached(file); | ||
} | ||
if(!bundledFiles[file] || bundledFiles[file].version !== newFiles[file].version){ | ||
changes++; | ||
} | ||
}); | ||
@@ -239,3 +244,3 @@ | ||
var changes = self._toBeDeleted.length + self._toBeDownloaded.length; | ||
changes += self._toBeDeleted.length; | ||
// Note: if we only need to copy files, we can keep serving from bundle! | ||
@@ -246,3 +251,3 @@ // So no update is needed! | ||
self.newManifest = newManifest; | ||
self.newManifest.root = self.cache.localInternalURL; | ||
self.newManifest.root = self.cache.localUrl; | ||
resolve(true); | ||
@@ -266,3 +271,3 @@ } else { | ||
AppLoader.prototype.download = function(onprogress){ | ||
AppLoader.prototype.download = function(onprogress,includeFileProgressEvents){ | ||
var self = this; | ||
@@ -288,3 +293,3 @@ if(!self.canDownload()) { | ||
self.cache.add(self._toBeDownloaded); | ||
return self.cache.download(onprogress); | ||
return self.cache.download(onprogress,includeFileProgressEvents); | ||
}).then(function(){ | ||
@@ -343,3 +348,3 @@ self._toBeDeleted = []; | ||
this._fs = options.fs; | ||
if(!this._fs) { | ||
if(!this._fs) { | ||
throw new Error('Missing required option "fs". Add an instance of cordova-promise-fs.'); | ||
@@ -444,5 +449,6 @@ } | ||
FileCache.prototype.download = function download(onprogress){ | ||
FileCache.prototype.download = function download(onprogress,includeFileProgressEvents){ | ||
var fs = this._fs; | ||
var self = this; | ||
includeFileProgressEvents = includeFileProgressEvents || false; | ||
self.abort(); | ||
@@ -467,2 +473,3 @@ | ||
var total = self._downloading.length + queue.length; | ||
var percentage = 0; | ||
@@ -481,5 +488,7 @@ // download every file in the queue (which is the diff from _added with _cached) | ||
ev.percentage = done / total; | ||
if(ev.loaded > 0 && ev.total > 0 && index !== total){ | ||
if(ev.loaded > 0 && ev.total > 0 && done !== total){ | ||
ev.percentage += (ev.loaded / ev.total) / total; | ||
} | ||
ev.percentage = Math.max(percentage,ev.percentage); | ||
percentage = ev.percentage; | ||
onprogress(ev); | ||
@@ -492,2 +501,3 @@ }; | ||
done++; | ||
onSingleDownloadProgress(new ProgressEvent()); | ||
@@ -514,3 +524,3 @@ // when we're done | ||
if(self._cacheBuster) downloadUrl += "?"+Date.now(); | ||
var download = fs.download(downloadUrl,path,{retry:self._retry},onSingleDownloadProgress); | ||
var download = fs.download(downloadUrl,path,{retry:self._retry},includeFileProgressEvents? onSingleDownloadProgress: undefined); | ||
download.then(onDone,onDone); | ||
@@ -554,3 +564,3 @@ self._downloading.push(download); | ||
path = this.toPath(url); | ||
if(this._cached[path]) return this._cached[path].toInternalURL; | ||
if(this._cached[path]) return this._cached[path].toURL; | ||
return this.toServerURL(url); | ||
@@ -590,3 +600,7 @@ }; | ||
} else { | ||
return this.localRoot + hash(url) + url.substr(url.lastIndexOf('.')); | ||
var ext = url.substr(url.lastIndexOf('.')); | ||
if ((ext.indexOf("?") > 0) || (ext.indexOf("/") > 0)) { | ||
ext = ".txt"; | ||
} | ||
return this.localRoot + hash(url) + ext; | ||
} | ||
@@ -701,4 +715,27 @@ }; | ||
if(str[0] === '/') str = str.substr(1); | ||
if(!!str && str.indexOf('.') < 0 && str[str.length-1] !== '/') str += '/'; | ||
if(str === './') str = ''; | ||
var tokens = str.split('/'), last = tokens[0]; | ||
// check tokens for instances of .. and . | ||
for(var i=1;i < tokens.length;i++) { | ||
last = tokens[i]; | ||
if (tokens[i] === '..') { | ||
// remove the .. and the previous token | ||
tokens.splice(i-1,2); | ||
// rewind 'cursor' 2 tokens | ||
i = i - 2; | ||
} else if (tokens[i] === '.') { | ||
// remove the .. and the previous token | ||
tokens.splice(i,1); | ||
// rewind 'cursor' 1 token | ||
i--; | ||
} | ||
} | ||
str = tokens.join('/'); | ||
if(str === './') { | ||
str = ''; | ||
} else if(last && last.indexOf('.') < 0 && str[str.length - 1] != '/'){ | ||
str += '/'; | ||
} | ||
return str; | ||
@@ -719,3 +756,3 @@ } | ||
/* default options */ | ||
this.options = options = options || {}; | ||
options = options || {}; | ||
options.persistent = options.persistent !== undefined? options.persistent: true; | ||
@@ -725,2 +762,3 @@ options.storageSize = options.storageSize || 20*1024*1024; | ||
options.retry = options.retry || []; | ||
options.debug = !!options.debug; | ||
@@ -746,3 +784,3 @@ /* Cordova deviceready promise */ | ||
if (xhr.readyState == 4) { | ||
if(xhr.status === 200){ | ||
if(xhr.status === 200 && !this._aborted){ | ||
write(file,xhr.response).then(win,fail); | ||
@@ -757,2 +795,5 @@ } else { | ||
}; | ||
FileTransfer.prototype.abort = function(){ | ||
this._aborted = true; | ||
}; | ||
window.ProgressEvent = function ProgressEvent(){}; | ||
@@ -778,10 +819,5 @@ window.FileEntry = function FileEntry(){}; | ||
var type = options.persistent? 1: 0; | ||
if(typeof options.fileSystem === 'number'){ | ||
if(options.fileSystem && isCordova){ | ||
type = options.fileSystem; | ||
} | ||
// Chrome only supports persistent and temp storage, not the exotic onces from Cordova | ||
if(!isCordova && type > 1) { | ||
console.warn('Chrome does not support fileSystem "'+type+'". Falling back on "0" (temporary).'); | ||
type = 0; | ||
} | ||
// On chrome, request quota to store persistent files | ||
@@ -791,7 +827,15 @@ if (!isCordova && type === 1 && navigator.webkitPersistentStorage) { | ||
window.requestFileSystem(type, grantedBytes, resolve, reject); | ||
}); | ||
}, reject); | ||
} else { | ||
// Exotic Cordova Directories (options.fileSystem = string) | ||
if(isNaN(type)) { | ||
window.resolveLocalFileSystemURL(type,function(directory){ | ||
resolve(directory.filesystem); | ||
},reject); | ||
// Normal browser usage | ||
} else { | ||
window.requestFileSystem(type, options.storageSize, resolve, reject); | ||
} | ||
} | ||
else { | ||
window.requestFileSystem(type, options.storageSize, resolve, reject); | ||
} | ||
setTimeout(function(){ reject(new Error('Could not retrieve FileSystem after 5 seconds.')); },5100); | ||
@@ -803,2 +847,4 @@ },reject); | ||
fs.then(function(fs){ | ||
CDV_INTERNAL_URL_ROOT = fs.root.toInternalURL(); | ||
CDV_URL_ROOT = fs.root.toURL(); | ||
window.__fs = fs; | ||
@@ -941,3 +987,5 @@ },function(err){ | ||
/* convert path to URL to be used in JS/CSS/HTML */ | ||
var toInternalURL,toInternalURLSync; | ||
var toInternalURL,toInternalURLSync,toURLSync; | ||
CDV_INTERNAL_URL_ROOT = 'cdvfile://localhost/'+(options.persistent? 'persistent/':'temporary/'); | ||
CDV_URL_ROOT = ''; | ||
if(isCordova) { | ||
@@ -947,4 +995,9 @@ /* synchronous helper to get internal URL. */ | ||
path = normalize(path); | ||
return path.indexOf('://') < 0? 'cdvfile://localhost/'+(options.persistent? 'persistent/':'temporary/') + path: path; | ||
return path.indexOf('://') < 0? CDV_INTERNAL_URL_ROOT + path: path; | ||
}; | ||
/* synchronous helper to get native URL. */ | ||
toURLSync = function(path){ | ||
path = normalize(path); | ||
return path.indexOf('://') < 0? CDV_URL_ROOT + path: path; | ||
}; | ||
@@ -968,2 +1021,3 @@ toInternalURL = function(path) { | ||
}; | ||
toURLSync = toInternalURLSync; | ||
} | ||
@@ -1007,5 +1061,5 @@ | ||
if(typeof blob === 'string') { | ||
blob = new Blob([blob],{type: mimeType || 'text/plain'}); | ||
blob = createBlob([blob], mimeType || 'text/plain'); | ||
} else if(blob instanceof Blob !== true){ | ||
blob = new Blob([JSON.stringify(blob,null,4)],{type: mimeType || 'application/json'}); | ||
blob = createBlob([JSON.stringify(blob,null,4)], mimeType || 'application/json'); | ||
} | ||
@@ -1018,2 +1072,22 @@ writer.write(blob); | ||
function createBlob(parts, type) { | ||
var BlobBuilder, | ||
bb; | ||
try { | ||
return new Blob(parts, {type: type}); | ||
} catch(e) { | ||
BlobBuilder = window.BlobBuilder || | ||
window.WebKitBlobBuilder || | ||
window.MozBlobBuilder || | ||
window.MSBlobBuilder; | ||
if(BlobBuilder) { | ||
bb = new BlobBuilder(); | ||
bb.append(parts); | ||
return bb.getBlob(type); | ||
} else { | ||
throw new Error("Unable to create blob"); | ||
} | ||
} | ||
} | ||
/* move a file */ | ||
@@ -1091,10 +1165,10 @@ function move(src,dest) { | ||
var args = transferQueue.pop(); | ||
var ft = args.shift(); | ||
var isDownload = args.shift(); | ||
var serverUrl = args.shift(); | ||
var localPath = args.shift(); | ||
var win = args.shift(); | ||
var fail = args.shift(); | ||
var trustAllHosts = args.shift(); | ||
var transferOptions = args.shift(); | ||
var ft = args.fileTransfer, | ||
isDownload = args.isDownload, | ||
serverUrl = args.serverUrl, | ||
localPath = args.localPath, | ||
trustAllHosts = args.trustAllHosts, | ||
transferOptions = args.transferOptions, | ||
win = args.win, | ||
fail = args.fail; | ||
@@ -1126,3 +1200,3 @@ if(ft._aborted) { | ||
} | ||
if(isCordova && localPath.indexOf('://') < 0) localPath = toInternalURLSync(localPath); | ||
if(isCordova && localPath.indexOf('://') < 0) localPath = toURLSync(localPath); | ||
@@ -1144,5 +1218,17 @@ transferOptions = transferOptions || {}; | ||
if(transferOptions.retry.length === 0) { | ||
if(options.debug) console.log('FileTransfer Error: '+serverUrl,err); | ||
reject(err); | ||
} else { | ||
transferQueue.unshift([ft,isDownload,serverUrl,localPath,resolve,attempt,transferOptions.trustAllHosts || false,transferOptions]); | ||
var transferJob = { | ||
fileTransfer:ft, | ||
isDownload:isDownload, | ||
serverUrl:serverUrl, | ||
localPath:localPath, | ||
trustAllHosts:transferOptions.trustAllHosts || false, | ||
transferOptions:transferOptions, | ||
win:resolve, | ||
fail:attempt | ||
}; | ||
transferQueue.unshift(transferJob); | ||
var timeout = transferOptions.retry.shift(); | ||
@@ -1149,0 +1235,0 @@ if(timeout > 0) { |
@@ -1,1 +0,1 @@ | ||
var CordovaAppLoader=function(t){function e(o){if(n[o])return n[o].exports;var r=n[o]={exports:{},id:o,loaded:!1};return t[o].call(r.exports,r,r.exports,e),r.loaded=!0,r.exports}var n={};return e.m=t,e.c=n,e.p="",e(0)}([function(t,e,n){function o(t){var e=Object.keys(t);e.sort();var n="";return e.forEach(function(e){t[e]&&t[e].version,n+="@"+t[e].version}),i.hash(n)+""}function r(t){if(!t)throw new Error("CordovaAppLoader has no options!");if(!t.fs)throw new Error('CordovaAppLoader has no "fs" option (cordova-promise-fs)');if(!t.serverRoot)throw new Error('CordovaAppLoader has no "serverRoot" option.');if(!window.pegasus||!window.Manifest)throw new Error("CordovaAppLoader bootstrap.js is missing.");this.allowServerRootFromManifest=t.allowServerRootFromManifest===!0,a=t.fs.Promise,this.manifest=window.Manifest,this.newManifest=null,this.bundledManifest=null,this._lastUpdateFiles=localStorage.getItem("last_update_files"),t.serverRoot=t.serverRoot||"",t.serverRoot&&"/"!==t.serverRoot[t.serverRoot.length-1]&&(t.serverRoot+="/"),this.newManifestUrl=t.manifestUrl||t.serverRoot+(t.manifest||"manifest.json"),t.mode&&(t.mode="mirror"),this.cache=new i(t),this.corruptNewManifest=!1,this._toBeCopied=[],this._toBeDeleted=[],this._toBeDownloaded=[],this._updateReady=!1,this._checkTimeout=t.checkTimeout||1e4}var i=n(1),a=(n(3),null),s=location.href.replace(location.hash,"");s=s.substr(0,s.lastIndexOf("/")+1),/ip(hone|ad|od)/i.test(navigator.userAgent)&&(s=location.pathname.substr(location.pathname.indexOf("/www/")),s=s.substr(0,s.lastIndexOf("/")+1),s="cdvfile://localhost/bundle"+s),r.prototype._createFilemap=function(t){var e={},n=this.cache._fs.normalize;return Object.keys(t).forEach(function(o){t[o].filename=n(t[o].filename),e[t[o].filename]=t[o]}),e},r.prototype.copyFromBundle=function(t){var e=s+t;return this.cache._fs.download(e,this.cache.localRoot+t)},r.prototype.getBundledManifest=function(){var t=this,e=document.querySelector("script[manifest]"),n=(e?e.getAttribute("manifest"):null)||"manifest.json";return new a(function(e,o){t.bundledManifest?e(t.bundledManifest):(pegasus(n).then(function(n){t.bundledManifest=n,e(n)},o),setTimeout(function(){o(new Error("bundled manifest timeout"))},t._checkTimeout))})},r.prototype.check=function(t){var e=this,n=this.manifest;"string"==typeof t&&(e.newManifestUrl=t,t=void 0);var r=new a(function(n,o){"object"==typeof t?n(t):(pegasus(e.newManifestUrl).then(n,o),setTimeout(function(){o(new Error("new manifest timeout"))},e._checkTimeout))});return new a(function(t,i){a.all([r,e.getBundledManifest(),e.cache.list()]).then(function(r){var a=r[0],s=r[1],u=o(a.files);if(u===e._lastUpdateFiles){var c=o(Manifest.files);return e._lastUpdateFiles!==c&&(console.warn("New manifest available, but an earlier update attempt failed. Will not download."),e.corruptNewManifest=!0,t(null)),void t(!1)}if(!a.files)return void i('Downloaded Manifest has no "files" attribute.');var f=r[2],l=e._createFilemap(n.files),u=e._createFilemap(a.files),d=e._createFilemap(s.files);e._toBeDownloaded=[],e._toBeCopied=[],e._toBeDeleted=[];var h=e.cache._fs.isCordova;Object.keys(u).filter(function(t){return!l[t]||l[t].version!==u[t].version||!e.cache.isCached(t)}).forEach(function(t){h&&d[t]&&d[t].version===u[t].version?e._toBeCopied.push(t):e._toBeDownloaded.push(t)}),e._toBeDeleted=f.map(function(t){return t.substr(e.cache.localRoot.length)}).filter(function(t){return!u[t]||e._toBeDownloaded.indexOf(t)>=0||e._toBeCopied.indexOf(t)>=0});var p=e._toBeDeleted.length+e._toBeDownloaded.length;p>0?(e.newManifest=a,e.newManifest.root=e.cache.localInternalURL,t(!0)):t(!1)},function(t){i(t)})})},r.prototype.canDownload=function(){return!!this.newManifest&&!this._updateReady},r.prototype.canUpdate=function(){return this._updateReady},r.prototype.download=function(t){var e=this;return e.canDownload()?(localStorage.removeItem("manifest"),localStorage.setItem("last_update_files",o(this.newManifest.files)),this.manifest.files=Manifest.files={},e.cache.remove(e._toBeDeleted,!0).then(function(){return a.all(e._toBeCopied.map(function(t){return e.cache._fs.download(s+t,e.cache.localRoot+t)}))}).then(function(){return e.allowServerRootFromManifest&&e.newManifest.serverRoot&&(e.cache.serverRoot=e.newManifest.serverRoot),e.cache.add(e._toBeDownloaded),e.cache.download(t)}).then(function(){return e._toBeDeleted=[],e._toBeDownloaded=[],e._updateReady=!0,e.newManifest},function(t){return t&&t.length&&e.cache.remove(t),t})):new a(function(t){t(null)})},r.prototype.update=function(t){return this._updateReady?(localStorage.setItem("manifest",JSON.stringify(this.newManifest)),t!==!1&&location.reload(),!0):!1},r.prototype.clear=function(){return localStorage.removeItem("last_update_files"),localStorage.removeItem("manifest"),this.cache.clear()},r.prototype.reset=function(){return this.clear().then(function(){location.reload()},function(){location.reload()})},t.exports=r},function(t,e,n){function o(t){var e=this;if(this._fs=t.fs,!this._fs)throw new Error('Missing required option "fs". Add an instance of cordova-promise-fs.');i=this._fs.Promise,this._mirrorMode="hash"!==t.mode,this._retry=t.retry||[500,1500,8e3],this._cacheBuster=!!t.cacheBuster,this.localRoot=this._fs.normalize(t.localRoot||"data"),this.serverRoot=this._fs.normalize(t.serverRoot||""),this._downloading=[],this._added=[],this._cached={},this.ready=this._fs.ensure(this.localRoot).then(function(t){return e.localInternalURL=a?t.toInternalURL():t.toURL(),e.localUrl=t.toURL(),e.list()})}var r=n(2),i=null,a="undefined"!=typeof cordova;o.hash=r,o.prototype.list=function(){var t=this;return new i(function(e){t._fs.list(t.localRoot,"rfe").then(function(n){t._cached={},n=n.map(function(e){var n=t._fs.normalize(e.fullPath);return t._cached[n]={toInternalURL:a?e.toInternalURL():e.toURL(),toURL:e.toURL()},n}),e(n)},function(){e([])})})},o.prototype.add=function(t){t||(t=[]),"string"==typeof t&&(t=[t]);var e=this;return t.forEach(function(t){t=e.toServerURL(t),-1===e._added.indexOf(t)&&e._added.push(t)}),e.isDirty()},o.prototype.remove=function(t,e){t||(t=[]);var n=[];"string"==typeof t&&(t=[t]);var o=this;return t.forEach(function(t){var e=o._added.indexOf(o.toServerURL(t));e>=0&&o._added.splice(e,1);var r=o.toPath(t);n.push(o._fs.remove(r)),delete o._cached[r]}),e?i.all(n):o.isDirty()},o.prototype.getDownloadQueue=function(){var t=this,e=t._added.filter(function(e){return!t.isCached(e)});return e},o.prototype.getAdded=function(){return this._added},o.prototype.isDirty=function(){return this.getDownloadQueue().length>0},o.prototype.download=function(t){var e=this._fs,n=this;return n.abort(),new i(function(o,r){e.ensure(n.localRoot).then(function(){return n.list()}).then(function(){if(!n.isDirty())return void o(n);var i=n.getDownloadQueue(),a=n._downloading.length,s=n._downloading.length+i.length;i.forEach(function(i){var u,c=n.toPath(i);"function"==typeof t&&(u=function(e){e.queueIndex=a,e.queueSize=s,e.url=i,e.path=c,e.percentage=a/s,e.loaded>0&&e.total>0&&index!==s&&(e.percentage+=e.loaded/e.total/s),t(e)});var f=function(){a++,a===s&&(n._downloading=[],n.list().then(function(){u&&u(new ProgressEvent),n.isDirty()?r(n.getDownloadQueue()):o(n)},r))},l=i;n._cacheBuster&&(l+="?"+Date.now());var d=e.download(l,c,{retry:n._retry},u);d.then(f,f),n._downloading.push(d)})},r)})},o.prototype.abort=function(){this._downloading.forEach(function(t){t.abort()}),this._downloading=[]},o.prototype.isCached=function(t){return t=this.toPath(t),!!this._cached[t]},o.prototype.clear=function(){var t=this;return this._cached={},this._fs.removeDir(this.localRoot).then(function(){return t._fs.ensure(t.localRoot)})},o.prototype.toInternalURL=function(t){return path=this.toPath(t),this._cached[path]?this._cached[path].toInternalURL:t},o.prototype.get=function(t){return path=this.toPath(t),this._cached[path]?this._cached[path].toInternalURL:this.toServerURL(t)},o.prototype.toDataURL=function(t){return this._fs.toDataURL(this.toPath(t))},o.prototype.toURL=function(t){return path=this.toPath(t),this._cached[path]?this._cached[path].toURL:t},o.prototype.toServerURL=function(t){return t=this._fs.normalize(t),t.indexOf("://")<0?this.serverRoot+t:t},o.prototype.toPath=function(t){if(this._mirrorMode){var e=t.indexOf("?");return e>-1&&(t=t.substr(0,e)),t=t=this._fs.normalize(t||""),len=this.serverRoot.length,t.substr(0,len)!==this.serverRoot?this.localRoot+t:this.localRoot+t.substr(len)}return this.localRoot+r(t)+t.substr(t.lastIndexOf("."))},t.exports=o},function(t){function e(t,e){var n,o,r,i,a,s,u,c;for(n=3&t.length,o=t.length-n,r=e,a=3432918353,s=461845907,c=0;o>c;)u=255&t.charCodeAt(c)|(255&t.charCodeAt(++c))<<8|(255&t.charCodeAt(++c))<<16|(255&t.charCodeAt(++c))<<24,++c,u=(65535&u)*a+(((u>>>16)*a&65535)<<16)&4294967295,u=u<<15|u>>>17,u=(65535&u)*s+(((u>>>16)*s&65535)<<16)&4294967295,r^=u,r=r<<13|r>>>19,i=5*(65535&r)+((5*(r>>>16)&65535)<<16)&4294967295,r=(65535&i)+27492+(((i>>>16)+58964&65535)<<16);switch(u=0,n){case 3:u^=(255&t.charCodeAt(c+2))<<16;case 2:u^=(255&t.charCodeAt(c+1))<<8;case 1:u^=255&t.charCodeAt(c),u=(65535&u)*a+(((u>>>16)*a&65535)<<16)&4294967295,u=u<<15|u>>>17,u=(65535&u)*s+(((u>>>16)*s&65535)<<16)&4294967295,r^=u}return r^=t.length,r^=r>>>16,r=2246822507*(65535&r)+((2246822507*(r>>>16)&65535)<<16)&4294967295,r^=r>>>13,r=3266489909*(65535&r)+((3266489909*(r>>>16)&65535)<<16)&4294967295,r^=r>>>16,r>>>0}t.exports=e},function(t){function e(t,n,o,r){t.getDirectory(n[0],{create:!0},function(t){n.length>1?e(t,n.slice(1),o,r):o(t)},r)}function n(t){return t=t.substr(0,t.lastIndexOf("/")+1),"/"===t[0]&&(t=t.substr(1)),t}function o(t){return t.substr(t.lastIndexOf("/")+1)}function r(t){return t=t||"","/"===t[0]&&(t=t.substr(1)),t&&t.indexOf(".")<0&&"/"!==t[t.length-1]&&(t+="/"),"./"===t&&(t=""),t}var i=[],a=0;t.exports=function(t){function s(t){return new B(function(e){return e(t)})}function u(t){return new B(function(n,o){return O.then(function(r){t?(t=t.split("/").filter(function(t){return t&&t.length>0&&"."!==t&&".."!==t}),e(r.root,t,n,o)):n(r.root)},o)})}function c(t,e){return new B(function(n,o){return"object"==typeof t?n(t):(t=r(t),e=e||{},O.then(function(r){r.root.getFile(t,e,n,o)},o))})}function f(t,e){return t=r(t),e=e||{},new B(function(n,o){return O.then(function(r){t&&"/"!==t?r.root.getDirectory(t,e,n,o):n(r.root)},o)})}function l(t,e){e=e||"";var n=e.indexOf("r")>-1,o=e.indexOf("e")>-1,r=e.indexOf("f")>-1,i=e.indexOf("d")>-1;return r&&i&&(r=!1,i=!1),new B(function(e,a){return f(t).then(function(t){var u=t.createReader();u.readEntries(function(t){var u=[s(t)];n&&t.filter(function(t){return t.isDirectory}).forEach(function(t){u.push(l(t.fullPath,"re"))}),B.all(u).then(function(t){var n=[];n=n.concat.apply(n,t),r&&(n=n.filter(function(t){return t.isFile})),i&&(n=n.filter(function(t){return t.isDirectory})),o||(n=n.map(function(t){return t.fullPath})),e(n)},a)},a)},a)})}function d(t){return new B(function(e,n){c(t).then(function(t){e(t)},function(t){1===t.code?e(!1):n(t)})})}function h(t){return new B(function(e,n){f(t).then(function(t){e(t)},function(t){1===t.code?e(!1):n(t)})})}function p(t){return u(n(t)).then(function(){return c(t,{create:!0})})}function w(t){return c(t).then(function(t){return t.toURL()})}function v(t,e){return e=e||"readAsText",c(t).then(function(t){return new B(function(n,o){t.file(function(t){var o=new FileReader;o.onloadend=function(){n(this.result)},o[e](t)},o)})})}function m(t){return v(t,"readAsDataURL")}function y(t){return v(t).then(JSON.parse)}function _(t,e,o){return u(n(t)).then(function(){return c(t,{create:!0})}).then(function(t){return new B(function(n,r){t.createWriter(function(t){t.onwriteend=n,t.onerror=r,"string"==typeof e?e=new Blob([e],{type:o||"text/plain"}):e instanceof Blob!=!0&&(e=new Blob([JSON.stringify(e,null,4)],{type:o||"application/json"})),t.write(e)},r)})})}function g(t,e){return u(n(e)).then(function(n){return c(t).then(function(t){return new B(function(r,i){t.moveTo(n,o(e),r,i)})})})}function R(t,e){return t=t.replace(/\/$/,""),e=e.replace(/\/$/,""),u(n(e)).then(function(n){return f(t).then(function(t){return new B(function(r,i){t.moveTo(n,o(e),r,i)})})})}function b(t,e){return u(n(e)).then(function(n){return c(t).then(function(t){return new B(function(r,i){t.copyTo(n,o(e),r,i)})})})}function S(t,e){var n=e?c:d;return new B(function(e,o){n(t).then(function(t){t!==!1?t.remove(e,o):e(1)},o)}).then(function(t){return 1===t?!1:!0})}function D(t){return f(t).then(function(t){return new B(function(e,n){t.removeRecursively(e,n)})})}function U(){for(;i.length>0&&a<t.concurrency;){a++;var e=i.pop(),n=e.shift(),o=e.shift(),r=e.shift(),s=e.shift(),u=e.shift(),c=e.shift(),f=e.shift(),l=e.shift();n._aborted?a--:o?(n.download.call(n,r,s,u,c,f,l),n.onprogress&&n.onprogress(new ProgressEvent)):n.upload.call(n,s,r,u,c,l,f)}}function L(t){return a--,U(),t}function x(e,n,r,s,u){"function"==typeof s&&(u=s,s={}),E&&r.indexOf("://")<0&&(r=P(r)),s=s||{},s.retry&&s.retry.length||(s.retry=t.retry),s.retry=s.retry.concat(),s.file||e||(s.fileName=o(r));var c=new FileTransfer;u=u||s.onprogress,"function"==typeof u&&(c.onprogress=u);var f=new B(function(t,o){var u=function(a){if(0===s.retry.length)o(a);else{i.unshift([c,e,n,r,t,u,s.trustAllHosts||!1,s]);var f=s.retry.shift();f>0?setTimeout(L,f):L()}};s.retry.unshift(0),a++,u()});return f.then(L,L),f.progress=function(t){return c.onprogress=t,f},f.abort=function(){return c._aborted=!0,c.abort(),f},f}function M(t,e,n,o){return x(!0,t,e,n,o)}function F(t,e,n,o){return x(!1,e,t,n,o)}var B=t.Promise||window.Promise;if(!B)throw new Error("No Promise library given in options.Promise");this.options=t=t||{},t.persistent=void 0!==t.persistent?t.persistent:!0,t.storageSize=t.storageSize||20971520,t.concurrency=t.concurrency||3,t.retry=t.retry||[];var C,E="undefined"!=typeof cordova;E?C=new B(function(t,e){document.addEventListener("deviceready",t,!1),setTimeout(function(){e(new Error("deviceready has not fired after 5 seconds."))},5100)}):(C=s(!0),"undefined"!=typeof webkitRequestFileSystem?(window.requestFileSystem=webkitRequestFileSystem,window.FileTransfer=function(){},FileTransfer.prototype.download=function(t,e,n,o){var r=new XMLHttpRequest;return r.open("GET",t),r.responseType="blob",r.onreadystatechange=function(){4==r.readyState&&(200===r.status?_(e,r.response).then(n,o):o(r.status))},r.send(),r},window.ProgressEvent=function(){},window.FileEntry=function(){}):window.requestFileSystem=function(t,e,n,o){o(new Error("requestFileSystem not supported!"))});var O=new B(function(e,n){C.then(function(){var o=t.persistent?1:0;"number"==typeof t.fileSystem&&(o=t.fileSystem),!E&&o>1&&(console.warn('Chrome does not support fileSystem "'+o+'". Falling back on "0" (temporary).'),o=0),!E&&1===o&&navigator.webkitPersistentStorage?navigator.webkitPersistentStorage.requestQuota(t.storageSize,function(t){window.requestFileSystem(o,t,e,n)}):window.requestFileSystem(o,t.storageSize,e,n),setTimeout(function(){n(new Error("Could not retrieve FileSystem after 5 seconds."))},5100)},n)});O.then(function(t){window.__fs=t},function(t){console.error("Could not get Cordova FileSystem:",t)});var I,P;return E?(P=function(e){return e=r(e),e.indexOf("://")<0?"cdvfile://localhost/"+(t.persistent?"persistent/":"temporary/")+e:e},I=function(t){return c(t).then(function(t){return t.toInternalURL()})}):(P=function(e){return e=r(e),"filesystem:"+location.origin+(t.persistent?"/persistent/":"/temporary/")+e},I=function(t){return c(t).then(function(t){return t.toURL()})}),{fs:O,normalize:r,file:c,filename:o,dir:f,dirname:n,create:p,read:v,readJSON:y,write:_,move:g,moveDir:R,copy:b,remove:S,removeDir:D,list:l,ensure:u,exists:d,existsDir:h,download:M,upload:F,toURL:w,isCordova:E,toInternalURLSync:P,toInternalURL:I,toDataURL:m,deviceready:C,options:t,Promise:B}}}]); | ||
var CordovaAppLoader=function(e){function t(o){if(n[o])return n[o].exports;var r=n[o]={exports:{},id:o,loaded:!1};return e[o].call(r.exports,r,r.exports,t),r.loaded=!0,r.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){function o(e){var t=Object.keys(e);t.sort();var n="";return t.forEach(function(t){e[t]&&e[t].version,n+="@"+e[t].version}),i.hash(n)+""}function r(e){if(!e)throw new Error("CordovaAppLoader has no options!");if(!e.fs)throw new Error('CordovaAppLoader has no "fs" option (cordova-promise-fs)');if(!e.serverRoot)throw new Error('CordovaAppLoader has no "serverRoot" option.');if(!window.pegasus||!window.Manifest)throw new Error("CordovaAppLoader bootstrap.js is missing.");this.allowServerRootFromManifest=e.allowServerRootFromManifest===!0,a=e.fs.Promise,this.manifest=window.Manifest,this.newManifest=null,this.bundledManifest=null,this.preventAutoUpdateLoop=e.preventAutoUpdateLoop===!0,this._lastUpdateFiles=localStorage.getItem("last_update_files"),e.serverRoot=e.serverRoot||"",e.serverRoot&&"/"!==e.serverRoot[e.serverRoot.length-1]&&(e.serverRoot+="/"),this.newManifestUrl=e.manifestUrl||e.serverRoot+(e.manifest||"manifest.json"),e.mode&&(e.mode="mirror"),this.cache=new i(e),this.corruptNewManifest=!1,this._toBeCopied=[],this._toBeDeleted=[],this._toBeDownloaded=[],this._updateReady=!1,this._checkTimeout=e.checkTimeout||1e4}var i=n(1),a=(n(3),null),s=location.href.replace(location.hash,"");s=s.substr(0,s.lastIndexOf("/")+1),/ip(hone|ad|od)/i.test(navigator.userAgent)&&(s=location.pathname.substr(location.pathname.indexOf("/www/")),s=s.substr(0,s.lastIndexOf("/")+1),s="cdvfile://localhost/bundle"+s),r.prototype._createFilemap=function(e){var t={},n=this.cache._fs.normalize;return Object.keys(e).forEach(function(o){e[o].filename=n(e[o].filename),t[e[o].filename]=e[o]}),t},r.prototype.copyFromBundle=function(e){var t=s+e;return this.cache._fs.download(t,this.cache.localRoot+e)},r.prototype.getBundledManifest=function(){var e=this,t=document.querySelector("script[manifest]"),n=(t?t.getAttribute("manifest"):null)||"manifest.json";return new a(function(t,o){e.bundledManifest?t(e.bundledManifest):(pegasus(n).then(function(n){e.bundledManifest=n,t(n)},o),setTimeout(function(){o(new Error("bundled manifest timeout"))},e._checkTimeout))})},r.prototype.check=function(e){var t=this,n=this.manifest;"string"==typeof e&&(t.newManifestUrl=e,e=void 0);var r=new a(function(n,o){"object"==typeof e?n(e):(pegasus(t.newManifestUrl).then(n,o),setTimeout(function(){o(new Error("new manifest timeout"))},t._checkTimeout))});return new a(function(e,i){a.all([r,t.getBundledManifest(),t.cache.list()]).then(function(r){var a=r[0],s=r[1],u=o(a.files);if(t.preventAutoUpdateLoop===!0&&u===t._lastUpdateFiles){var c=o(Manifest.files);return t._lastUpdateFiles!==c&&(console.warn("New manifest available, but an earlier update attempt failed. Will not download."),t.corruptNewManifest=!0,e(null)),void e(!1)}if(!a.files)return void i(new Error('Downloaded Manifest has no "files" attribute.'));var f=r[2],l=t._createFilemap(n.files),u=t._createFilemap(a.files),d=t._createFilemap(s.files);t._toBeDownloaded=[],t._toBeCopied=[],t._toBeDeleted=[];var h=t.cache._fs.isCordova,p=0;Object.keys(u).filter(function(e){return!l[e]||l[e].version!==u[e].version}).forEach(function(e){h&&d[e]&&d[e].version===u[e].version?t._toBeCopied.push(e):t._toBeDownloaded.push(e),d[e]&&d[e].version===u[e].version||p++}),t._toBeDeleted=f.map(function(e){return e.substr(t.cache.localRoot.length)}).filter(function(e){return!u[e]||t._toBeDownloaded.indexOf(e)>=0||t._toBeCopied.indexOf(e)>=0}),p+=t._toBeDeleted.length,p>0?(t.newManifest=a,t.newManifest.root=t.cache.localUrl,e(!0)):e(!1)},function(e){i(e)})})},r.prototype.canDownload=function(){return!!this.newManifest&&!this._updateReady},r.prototype.canUpdate=function(){return this._updateReady},r.prototype.download=function(e,t){var n=this;return n.canDownload()?(localStorage.removeItem("manifest"),localStorage.setItem("last_update_files",o(this.newManifest.files)),this.manifest.files=Manifest.files={},n.cache.remove(n._toBeDeleted,!0).then(function(){return a.all(n._toBeCopied.map(function(e){return n.cache._fs.download(s+e,n.cache.localRoot+e)}))}).then(function(){return n.allowServerRootFromManifest&&n.newManifest.serverRoot&&(n.cache.serverRoot=n.newManifest.serverRoot),n.cache.add(n._toBeDownloaded),n.cache.download(e,t)}).then(function(){return n._toBeDeleted=[],n._toBeDownloaded=[],n._updateReady=!0,n.newManifest},function(e){return e&&e.length&&n.cache.remove(e),e})):new a(function(e){e(null)})},r.prototype.update=function(e){return this._updateReady?(localStorage.setItem("manifest",JSON.stringify(this.newManifest)),e!==!1&&location.reload(),!0):!1},r.prototype.clear=function(){return localStorage.removeItem("last_update_files"),localStorage.removeItem("manifest"),this.cache.clear()},r.prototype.reset=function(){return this.clear().then(function(){location.reload()},function(){location.reload()})},e.exports=r},function(e,t,n){function o(e){var t=this;if(this._fs=e.fs,!this._fs)throw new Error('Missing required option "fs". Add an instance of cordova-promise-fs.');i=this._fs.Promise,this._mirrorMode="hash"!==e.mode,this._retry=e.retry||[500,1500,8e3],this._cacheBuster=!!e.cacheBuster,this.localRoot=this._fs.normalize(e.localRoot||"data"),this.serverRoot=this._fs.normalize(e.serverRoot||""),this._downloading=[],this._added=[],this._cached={},this.ready=this._fs.ensure(this.localRoot).then(function(e){return t.localInternalURL=a?e.toInternalURL():e.toURL(),t.localUrl=e.toURL(),t.list()})}var r=n(2),i=null,a="undefined"!=typeof cordova;o.hash=r,o.prototype.list=function(){var e=this;return new i(function(t){e._fs.list(e.localRoot,"rfe").then(function(n){e._cached={},n=n.map(function(t){var n=e._fs.normalize(t.fullPath);return e._cached[n]={toInternalURL:a?t.toInternalURL():t.toURL(),toURL:t.toURL()},n}),t(n)},function(){t([])})})},o.prototype.add=function(e){e||(e=[]),"string"==typeof e&&(e=[e]);var t=this;return e.forEach(function(e){e=t.toServerURL(e),-1===t._added.indexOf(e)&&t._added.push(e)}),t.isDirty()},o.prototype.remove=function(e,t){e||(e=[]);var n=[];"string"==typeof e&&(e=[e]);var o=this;return e.forEach(function(e){var t=o._added.indexOf(o.toServerURL(e));t>=0&&o._added.splice(t,1);var r=o.toPath(e);n.push(o._fs.remove(r)),delete o._cached[r]}),t?i.all(n):o.isDirty()},o.prototype.getDownloadQueue=function(){var e=this,t=e._added.filter(function(t){return!e.isCached(t)});return t},o.prototype.getAdded=function(){return this._added},o.prototype.isDirty=function(){return this.getDownloadQueue().length>0},o.prototype.download=function(e,t){var n=this._fs,o=this;return t=t||!1,o.abort(),new i(function(r,i){n.ensure(o.localRoot).then(function(){return o.list()}).then(function(){if(!o.isDirty())return void r(o);var a=o.getDownloadQueue(),s=o._downloading.length,u=o._downloading.length+a.length,c=0;a.forEach(function(a){var f,l=o.toPath(a);"function"==typeof e&&(f=function(t){t.queueIndex=s,t.queueSize=u,t.url=a,t.path=l,t.percentage=s/u,t.loaded>0&&t.total>0&&s!==u&&(t.percentage+=t.loaded/t.total/u),t.percentage=Math.max(c,t.percentage),c=t.percentage,e(t)});var d=function(){s++,f(new ProgressEvent),s===u&&(o._downloading=[],o.list().then(function(){f&&f(new ProgressEvent),o.isDirty()?i(o.getDownloadQueue()):r(o)},i))},h=a;o._cacheBuster&&(h+="?"+Date.now());var p=n.download(h,l,{retry:o._retry},t?f:void 0);p.then(d,d),o._downloading.push(p)})},i)})},o.prototype.abort=function(){this._downloading.forEach(function(e){e.abort()}),this._downloading=[]},o.prototype.isCached=function(e){return e=this.toPath(e),!!this._cached[e]},o.prototype.clear=function(){var e=this;return this._cached={},this._fs.removeDir(this.localRoot).then(function(){return e._fs.ensure(e.localRoot)})},o.prototype.toInternalURL=function(e){return path=this.toPath(e),this._cached[path]?this._cached[path].toInternalURL:e},o.prototype.get=function(e){return path=this.toPath(e),this._cached[path]?this._cached[path].toURL:this.toServerURL(e)},o.prototype.toDataURL=function(e){return this._fs.toDataURL(this.toPath(e))},o.prototype.toURL=function(e){return path=this.toPath(e),this._cached[path]?this._cached[path].toURL:e},o.prototype.toServerURL=function(e){return e=this._fs.normalize(e),e.indexOf("://")<0?this.serverRoot+e:e},o.prototype.toPath=function(e){if(this._mirrorMode){var t=e.indexOf("?");return t>-1&&(e=e.substr(0,t)),e=e=this._fs.normalize(e||""),len=this.serverRoot.length,e.substr(0,len)!==this.serverRoot?this.localRoot+e:this.localRoot+e.substr(len)}var n=e.substr(e.lastIndexOf("."));return(n.indexOf("?")>0||n.indexOf("/")>0)&&(n=".txt"),this.localRoot+r(e)+n},e.exports=o},function(e){function t(e,t){var n,o,r,i,a,s,u,c;for(n=3&e.length,o=e.length-n,r=t,a=3432918353,s=461845907,c=0;o>c;)u=255&e.charCodeAt(c)|(255&e.charCodeAt(++c))<<8|(255&e.charCodeAt(++c))<<16|(255&e.charCodeAt(++c))<<24,++c,u=(65535&u)*a+(((u>>>16)*a&65535)<<16)&4294967295,u=u<<15|u>>>17,u=(65535&u)*s+(((u>>>16)*s&65535)<<16)&4294967295,r^=u,r=r<<13|r>>>19,i=5*(65535&r)+((5*(r>>>16)&65535)<<16)&4294967295,r=(65535&i)+27492+(((i>>>16)+58964&65535)<<16);switch(u=0,n){case 3:u^=(255&e.charCodeAt(c+2))<<16;case 2:u^=(255&e.charCodeAt(c+1))<<8;case 1:u^=255&e.charCodeAt(c),u=(65535&u)*a+(((u>>>16)*a&65535)<<16)&4294967295,u=u<<15|u>>>17,u=(65535&u)*s+(((u>>>16)*s&65535)<<16)&4294967295,r^=u}return r^=e.length,r^=r>>>16,r=2246822507*(65535&r)+((2246822507*(r>>>16)&65535)<<16)&4294967295,r^=r>>>13,r=3266489909*(65535&r)+((3266489909*(r>>>16)&65535)<<16)&4294967295,r^=r>>>16,r>>>0}e.exports=t},function(e){function t(e,n,o,r){e.getDirectory(n[0],{create:!0},function(e){n.length>1?t(e,n.slice(1),o,r):o(e)},r)}function n(e){return e=e.substr(0,e.lastIndexOf("/")+1),"/"===e[0]&&(e=e.substr(1)),e}function o(e){return e.substr(e.lastIndexOf("/")+1)}function r(e){e=e||"","/"===e[0]&&(e=e.substr(1));for(var t=e.split("/"),n=t[0],o=1;o<t.length;o++)n=t[o],".."===t[o]?(t.splice(o-1,2),o-=2):"."===t[o]&&(t.splice(o,1),o--);return e=t.join("/"),"./"===e?e="":n&&n.indexOf(".")<0&&"/"!=e[e.length-1]&&(e+="/"),e}var i=[],a=0;e.exports=function(e){function s(e){return new E(function(t){return t(e)})}function u(e){return new E(function(n,o){return F.then(function(r){e?(e=e.split("/").filter(function(e){return e&&e.length>0&&"."!==e&&".."!==e}),t(r.root,e,n,o)):n(r.root)},o)})}function c(e,t){return new E(function(n,o){return"object"==typeof e?n(e):(e=r(e),t=t||{},F.then(function(r){r.root.getFile(e,t,n,o)},o))})}function f(e,t){return e=r(e),t=t||{},new E(function(n,o){return F.then(function(r){e&&"/"!==e?r.root.getDirectory(e,t,n,o):n(r.root)},o)})}function l(e,t){t=t||"";var n=t.indexOf("r")>-1,o=t.indexOf("e")>-1,r=t.indexOf("f")>-1,i=t.indexOf("d")>-1;return r&&i&&(r=!1,i=!1),new E(function(t,a){return f(e).then(function(e){var u=e.createReader();u.readEntries(function(e){var u=[s(e)];n&&e.filter(function(e){return e.isDirectory}).forEach(function(e){u.push(l(e.fullPath,"re"))}),E.all(u).then(function(e){var n=[];n=n.concat.apply(n,e),r&&(n=n.filter(function(e){return e.isFile})),i&&(n=n.filter(function(e){return e.isDirectory})),o||(n=n.map(function(e){return e.fullPath})),t(n)},a)},a)},a)})}function d(e){return new E(function(t,n){c(e).then(function(e){t(e)},function(e){1===e.code?t(!1):n(e)})})}function h(e){return new E(function(t,n){f(e).then(function(e){t(e)},function(e){1===e.code?t(!1):n(e)})})}function p(e){return u(n(e)).then(function(){return c(e,{create:!0})})}function w(e){return c(e).then(function(e){return e.toURL()})}function v(e,t){return t=t||"readAsText",c(e).then(function(e){return new E(function(n,o){e.file(function(e){var o=new FileReader;o.onloadend=function(){n(this.result)},o[t](e)},o)})})}function m(e){return v(e,"readAsDataURL")}function y(e){return v(e).then(JSON.parse)}function _(e,t,o){return u(n(e)).then(function(){return c(e,{create:!0})}).then(function(e){return new E(function(n,r){e.createWriter(function(e){e.onwriteend=n,e.onerror=r,"string"==typeof t?t=g([t],o||"text/plain"):t instanceof Blob!=!0&&(t=g([JSON.stringify(t,null,4)],o||"application/json")),e.write(t)},r)})})}function g(e,t){var n,o;try{return new Blob(e,{type:t})}catch(r){if(n=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder)return o=new n,o.append(e),o.getBlob(t);throw new Error("Unable to create blob")}}function R(e,t){return u(n(t)).then(function(n){return c(e).then(function(e){return new E(function(r,i){e.moveTo(n,o(t),r,i)})})})}function b(e,t){return e=e.replace(/\/$/,""),t=t.replace(/\/$/,""),u(n(t)).then(function(n){return f(e).then(function(e){return new E(function(r,i){e.moveTo(n,o(t),r,i)})})})}function U(e,t){return u(n(t)).then(function(n){return c(e).then(function(e){return new E(function(r,i){e.copyTo(n,o(t),r,i)})})})}function L(e,t){var n=t?c:d;return new E(function(t,o){n(e).then(function(e){e!==!1?e.remove(t,o):t(1)},o)}).then(function(e){return 1===e?!1:!0})}function D(e){return f(e).then(function(e){return new E(function(t,n){e.removeRecursively(t,n)})})}function O(){for(;i.length>0&&a<e.concurrency;){a++;var t=i.pop(),n=t.fileTransfer,o=t.isDownload,r=t.serverUrl,s=t.localPath,u=t.trustAllHosts,c=t.transferOptions,f=t.win,l=t.fail;n._aborted?a--:o?(n.download.call(n,r,s,f,l,u,c),n.onprogress&&n.onprogress(new ProgressEvent)):n.upload.call(n,s,r,f,l,c,u)}}function S(e){return a--,O(),e}function x(t,n,r,s,u){"function"==typeof s&&(u=s,s={}),C&&r.indexOf("://")<0&&(r=I(r)),s=s||{},s.retry&&s.retry.length||(s.retry=e.retry),s.retry=s.retry.concat(),s.file||t||(s.fileName=o(r));var c=new FileTransfer;u=u||s.onprogress,"function"==typeof u&&(c.onprogress=u);var f=new E(function(o,u){var f=function(a){if(0===s.retry.length)e.debug&&console.log("FileTransfer Error: "+n,a),u(a);else{var l={fileTransfer:c,isDownload:t,serverUrl:n,localPath:r,trustAllHosts:s.trustAllHosts||!1,transferOptions:s,win:o,fail:f};i.unshift(l);var d=s.retry.shift();d>0?setTimeout(S,d):S()}};s.retry.unshift(0),a++,f()});return f.then(S,S),f.progress=function(e){return c.onprogress=e,f},f.abort=function(){return c._aborted=!0,c.abort(),f},f}function M(e,t,n,o){return x(!0,e,t,n,o)}function B(e,t,n,o){return x(!1,t,e,n,o)}var E=e.Promise||window.Promise;if(!E)throw new Error("No Promise library given in options.Promise");e=e||{},e.persistent=void 0!==e.persistent?e.persistent:!0,e.storageSize=e.storageSize||20971520,e.concurrency=e.concurrency||3,e.retry=e.retry||[],e.debug=!!e.debug;var T,C="undefined"!=typeof cordova;C?T=new E(function(e,t){document.addEventListener("deviceready",e,!1),setTimeout(function(){t(new Error("deviceready has not fired after 5 seconds."))},5100)}):(T=s(!0),"undefined"!=typeof webkitRequestFileSystem?(window.requestFileSystem=webkitRequestFileSystem,window.FileTransfer=function(){},FileTransfer.prototype.download=function(e,t,n,o){var r=new XMLHttpRequest;return r.open("GET",e),r.responseType="blob",r.onreadystatechange=function(){4==r.readyState&&(200!==r.status||this._aborted?o(r.status):_(t,r.response).then(n,o))},r.send(),r},FileTransfer.prototype.abort=function(){this._aborted=!0},window.ProgressEvent=function(){},window.FileEntry=function(){}):window.requestFileSystem=function(e,t,n,o){o(new Error("requestFileSystem not supported!"))});var F=new E(function(t,n){T.then(function(){var o=e.persistent?1:0;e.fileSystem&&C&&(o=e.fileSystem),!C&&1===o&&navigator.webkitPersistentStorage?navigator.webkitPersistentStorage.requestQuota(e.storageSize,function(e){window.requestFileSystem(o,e,t,n)},n):isNaN(o)?window.resolveLocalFileSystemURL(o,function(e){t(e.filesystem)},n):window.requestFileSystem(o,e.storageSize,t,n),setTimeout(function(){n(new Error("Could not retrieve FileSystem after 5 seconds."))},5100)},n)});F.then(function(e){CDV_INTERNAL_URL_ROOT=e.root.toInternalURL(),CDV_URL_ROOT=e.root.toURL(),window.__fs=e},function(e){console.error("Could not get Cordova FileSystem:",e)});var A,P,I;return CDV_INTERNAL_URL_ROOT="cdvfile://localhost/"+(e.persistent?"persistent/":"temporary/"),CDV_URL_ROOT="",C?(P=function(e){return e=r(e),e.indexOf("://")<0?CDV_INTERNAL_URL_ROOT+e:e},I=function(e){return e=r(e),e.indexOf("://")<0?CDV_URL_ROOT+e:e},A=function(e){return c(e).then(function(e){return e.toInternalURL()})}):(P=function(t){return t=r(t),"filesystem:"+location.origin+(e.persistent?"/persistent/":"/temporary/")+t},A=function(e){return c(e).then(function(e){return e.toURL()})},I=P),{fs:F,normalize:r,file:c,filename:o,dir:f,dirname:n,create:p,read:v,readJSON:y,write:_,move:R,moveDir:b,copy:U,remove:L,removeDir:D,list:l,ensure:u,exists:d,existsDir:h,download:M,upload:B,toURL:w,isCordova:C,toInternalURLSync:P,toInternalURL:A,toDataURL:m,deviceready:T,options:e,Promise:E}}}]); |
19
index.js
@@ -36,2 +36,3 @@ var CordovaFileCache = require('cordova-file-cache'); | ||
this.bundledManifest = null; | ||
this.preventAutoUpdateLoop = options.preventAutoUpdateLoop === true; | ||
this._lastUpdateFiles = localStorage.getItem('last_update_files'); | ||
@@ -118,3 +119,3 @@ | ||
// Check if the newFiles match the previous files (last_update_files) | ||
if(newFiles === self._lastUpdateFiles) { | ||
if(self.preventAutoUpdateLoop === true && newFiles === self._lastUpdateFiles) { | ||
// YES! So we're doing the same update again! | ||
@@ -137,3 +138,3 @@ | ||
if(!newManifest.files){ | ||
reject('Downloaded Manifest has no "files" attribute.'); | ||
reject(new Error('Downloaded Manifest has no "files" attribute.')); | ||
return; | ||
@@ -153,2 +154,3 @@ } | ||
var isCordova = self.cache._fs.isCordova; | ||
var changes = 0; | ||
Object.keys(newFiles) | ||
@@ -160,3 +162,3 @@ // Find files that have changed version or are missing | ||
// version has changed, or... | ||
oldFiles[file].version !== newFiles[file].version || | ||
oldFiles[file].version !== newFiles[file].version //|| | ||
// not in cache for some reason | ||
@@ -174,2 +176,5 @@ !self.cache.isCached(file); | ||
} | ||
if(!bundledFiles[file] || bundledFiles[file].version !== newFiles[file].version){ | ||
changes++; | ||
} | ||
}); | ||
@@ -192,3 +197,3 @@ | ||
var changes = self._toBeDeleted.length + self._toBeDownloaded.length; | ||
changes += self._toBeDeleted.length; | ||
// Note: if we only need to copy files, we can keep serving from bundle! | ||
@@ -199,3 +204,3 @@ // So no update is needed! | ||
self.newManifest = newManifest; | ||
self.newManifest.root = self.cache.localInternalURL; | ||
self.newManifest.root = self.cache.localUrl; | ||
resolve(true); | ||
@@ -219,3 +224,3 @@ } else { | ||
AppLoader.prototype.download = function(onprogress){ | ||
AppLoader.prototype.download = function(onprogress,includeFileProgressEvents){ | ||
var self = this; | ||
@@ -241,3 +246,3 @@ if(!self.canDownload()) { | ||
self.cache.add(self._toBeDownloaded); | ||
return self.cache.download(onprogress); | ||
return self.cache.download(onprogress,includeFileProgressEvents); | ||
}).then(function(){ | ||
@@ -244,0 +249,0 @@ self._toBeDeleted = []; |
{ | ||
"name": "cordova-app-loader", | ||
"version": "0.18.0", | ||
"version": "1.0.0", | ||
"description": "Cordova App Loader - remote update your cordova app", | ||
@@ -28,5 +28,5 @@ "main": "index.js", | ||
"dependencies": { | ||
"cordova-file-cache": "^0.13.0", | ||
"cordova-promise-fs": "^0.13.0" | ||
"cordova-file-cache": "^1.1.0", | ||
"cordova-promise-fs": "^1.1.0" | ||
} | ||
} |
@@ -29,4 +29,4 @@ cordova-app-loader | ||
cordova platform add ios@3.7.0 | ||
cordova plugin add org.apache.cordova.file | ||
cordova plugin add org.apache.cordova.file-transfer | ||
cordova plugin add cordova-plugin-file | ||
cordova plugin add cordova-plugin-file-transfer | ||
cordova run ios | ||
@@ -410,2 +410,9 @@ ``` | ||
### 1.0.0 (23/01/2016) | ||
* Version bump for Cordova File Cache + Cordova Promise FS | ||
* Defaults to no progress events for file transfer (performance boost!) | ||
* Fix toInternalURL Sync for different fileSystems. | ||
* Minor bugfixes | ||
### 0.18.0 (23/01/2016) | ||
@@ -412,0 +419,0 @@ |
@@ -19,3 +19,3 @@ (function(){ | ||
// cb placeholder to avoid using var, should not be used | ||
xhr.onreadystatechange = xhr.then = function(onSuccess, onError, cb) { | ||
xhr.onreadystatechange = xhr.then = function(onSuccess, onError, cb, result) { | ||
@@ -28,10 +28,18 @@ // Test if onSuccess is a function or a load event | ||
// index will be: | ||
// 0 if status is between 0 and 399 | ||
// 1 if status is over | ||
cb = a[0|xhr.status / 400]; | ||
try { | ||
if(xhr.status === 200 || xhr.status === 0){ | ||
result = JSON.parse(xhr.responseText); | ||
cb = a[0]; | ||
} else { | ||
result = new Error('Status: '+xhr.status); | ||
cb = a[1]; | ||
} | ||
} catch(e) { | ||
result = e; | ||
cb = a[1]; | ||
} | ||
// Safari doesn't support xhr.responseType = 'json' | ||
// so the response is parsed | ||
if (cb) cb(xhr.status === 200 || xhr.status === 0?JSON.parse(xhr.responseText):xhr); | ||
if (cb) cb(result); | ||
} | ||
@@ -81,2 +89,3 @@ }; | ||
el= document.createElement('script'); | ||
el.charset="UTF-8"; | ||
el.type= 'text/javascript'; | ||
@@ -83,0 +92,0 @@ el.src= src + '?' + now; |
@@ -92,2 +92,3 @@ /******/ (function(modules) { // webpackBootstrap | ||
this.bundledManifest = null; | ||
this.preventAutoUpdateLoop = options.preventAutoUpdateLoop === true; | ||
this._lastUpdateFiles = localStorage.getItem('last_update_files'); | ||
@@ -174,3 +175,3 @@ | ||
// Check if the newFiles match the previous files (last_update_files) | ||
if(newFiles === self._lastUpdateFiles) { | ||
if(self.preventAutoUpdateLoop === true && newFiles === self._lastUpdateFiles) { | ||
// YES! So we're doing the same update again! | ||
@@ -193,3 +194,3 @@ | ||
if(!newManifest.files){ | ||
reject('Downloaded Manifest has no "files" attribute.'); | ||
reject(new Error('Downloaded Manifest has no "files" attribute.')); | ||
return; | ||
@@ -209,2 +210,3 @@ } | ||
var isCordova = self.cache._fs.isCordova; | ||
var changes = 0; | ||
Object.keys(newFiles) | ||
@@ -216,3 +218,3 @@ // Find files that have changed version or are missing | ||
// version has changed, or... | ||
oldFiles[file].version !== newFiles[file].version || | ||
oldFiles[file].version !== newFiles[file].version //|| | ||
// not in cache for some reason | ||
@@ -230,2 +232,5 @@ !self.cache.isCached(file); | ||
} | ||
if(!bundledFiles[file] || bundledFiles[file].version !== newFiles[file].version){ | ||
changes++; | ||
} | ||
}); | ||
@@ -248,3 +253,3 @@ | ||
var changes = self._toBeDeleted.length + self._toBeDownloaded.length; | ||
changes += self._toBeDeleted.length; | ||
// Note: if we only need to copy files, we can keep serving from bundle! | ||
@@ -255,3 +260,3 @@ // So no update is needed! | ||
self.newManifest = newManifest; | ||
self.newManifest.root = self.cache.localInternalURL; | ||
self.newManifest.root = self.cache.localUrl; | ||
resolve(true); | ||
@@ -275,3 +280,3 @@ } else { | ||
AppLoader.prototype.download = function(onprogress){ | ||
AppLoader.prototype.download = function(onprogress,includeFileProgressEvents){ | ||
var self = this; | ||
@@ -297,3 +302,3 @@ if(!self.canDownload()) { | ||
self.cache.add(self._toBeDownloaded); | ||
return self.cache.download(onprogress); | ||
return self.cache.download(onprogress,includeFileProgressEvents); | ||
}).then(function(){ | ||
@@ -352,3 +357,3 @@ self._toBeDeleted = []; | ||
this._fs = options.fs; | ||
if(!this._fs) { | ||
if(!this._fs) { | ||
throw new Error('Missing required option "fs". Add an instance of cordova-promise-fs.'); | ||
@@ -453,5 +458,6 @@ } | ||
FileCache.prototype.download = function download(onprogress){ | ||
FileCache.prototype.download = function download(onprogress,includeFileProgressEvents){ | ||
var fs = this._fs; | ||
var self = this; | ||
includeFileProgressEvents = includeFileProgressEvents || false; | ||
self.abort(); | ||
@@ -476,2 +482,3 @@ | ||
var total = self._downloading.length + queue.length; | ||
var percentage = 0; | ||
@@ -490,5 +497,7 @@ // download every file in the queue (which is the diff from _added with _cached) | ||
ev.percentage = done / total; | ||
if(ev.loaded > 0 && ev.total > 0 && index !== total){ | ||
if(ev.loaded > 0 && ev.total > 0 && done !== total){ | ||
ev.percentage += (ev.loaded / ev.total) / total; | ||
} | ||
ev.percentage = Math.max(percentage,ev.percentage); | ||
percentage = ev.percentage; | ||
onprogress(ev); | ||
@@ -501,2 +510,3 @@ }; | ||
done++; | ||
onSingleDownloadProgress(new ProgressEvent()); | ||
@@ -523,3 +533,3 @@ // when we're done | ||
if(self._cacheBuster) downloadUrl += "?"+Date.now(); | ||
var download = fs.download(downloadUrl,path,{retry:self._retry},onSingleDownloadProgress); | ||
var download = fs.download(downloadUrl,path,{retry:self._retry},includeFileProgressEvents? onSingleDownloadProgress: undefined); | ||
download.then(onDone,onDone); | ||
@@ -563,3 +573,3 @@ self._downloading.push(download); | ||
path = this.toPath(url); | ||
if(this._cached[path]) return this._cached[path].toInternalURL; | ||
if(this._cached[path]) return this._cached[path].toURL; | ||
return this.toServerURL(url); | ||
@@ -599,3 +609,7 @@ }; | ||
} else { | ||
return this.localRoot + hash(url) + url.substr(url.lastIndexOf('.')); | ||
var ext = url.substr(url.lastIndexOf('.')); | ||
if ((ext.indexOf("?") > 0) || (ext.indexOf("/") > 0)) { | ||
ext = ".txt"; | ||
} | ||
return this.localRoot + hash(url) + ext; | ||
} | ||
@@ -710,4 +724,27 @@ }; | ||
if(str[0] === '/') str = str.substr(1); | ||
if(!!str && str.indexOf('.') < 0 && str[str.length-1] !== '/') str += '/'; | ||
if(str === './') str = ''; | ||
var tokens = str.split('/'), last = tokens[0]; | ||
// check tokens for instances of .. and . | ||
for(var i=1;i < tokens.length;i++) { | ||
last = tokens[i]; | ||
if (tokens[i] === '..') { | ||
// remove the .. and the previous token | ||
tokens.splice(i-1,2); | ||
// rewind 'cursor' 2 tokens | ||
i = i - 2; | ||
} else if (tokens[i] === '.') { | ||
// remove the .. and the previous token | ||
tokens.splice(i,1); | ||
// rewind 'cursor' 1 token | ||
i--; | ||
} | ||
} | ||
str = tokens.join('/'); | ||
if(str === './') { | ||
str = ''; | ||
} else if(last && last.indexOf('.') < 0 && str[str.length - 1] != '/'){ | ||
str += '/'; | ||
} | ||
return str; | ||
@@ -728,3 +765,3 @@ } | ||
/* default options */ | ||
this.options = options = options || {}; | ||
options = options || {}; | ||
options.persistent = options.persistent !== undefined? options.persistent: true; | ||
@@ -734,2 +771,3 @@ options.storageSize = options.storageSize || 20*1024*1024; | ||
options.retry = options.retry || []; | ||
options.debug = !!options.debug; | ||
@@ -755,3 +793,3 @@ /* Cordova deviceready promise */ | ||
if (xhr.readyState == 4) { | ||
if(xhr.status === 200){ | ||
if(xhr.status === 200 && !this._aborted){ | ||
write(file,xhr.response).then(win,fail); | ||
@@ -766,2 +804,5 @@ } else { | ||
}; | ||
FileTransfer.prototype.abort = function(){ | ||
this._aborted = true; | ||
}; | ||
window.ProgressEvent = function ProgressEvent(){}; | ||
@@ -787,10 +828,5 @@ window.FileEntry = function FileEntry(){}; | ||
var type = options.persistent? 1: 0; | ||
if(typeof options.fileSystem === 'number'){ | ||
if(options.fileSystem && isCordova){ | ||
type = options.fileSystem; | ||
} | ||
// Chrome only supports persistent and temp storage, not the exotic onces from Cordova | ||
if(!isCordova && type > 1) { | ||
console.warn('Chrome does not support fileSystem "'+type+'". Falling back on "0" (temporary).'); | ||
type = 0; | ||
} | ||
// On chrome, request quota to store persistent files | ||
@@ -800,7 +836,15 @@ if (!isCordova && type === 1 && navigator.webkitPersistentStorage) { | ||
window.requestFileSystem(type, grantedBytes, resolve, reject); | ||
}); | ||
}, reject); | ||
} else { | ||
// Exotic Cordova Directories (options.fileSystem = string) | ||
if(isNaN(type)) { | ||
window.resolveLocalFileSystemURL(type,function(directory){ | ||
resolve(directory.filesystem); | ||
},reject); | ||
// Normal browser usage | ||
} else { | ||
window.requestFileSystem(type, options.storageSize, resolve, reject); | ||
} | ||
} | ||
else { | ||
window.requestFileSystem(type, options.storageSize, resolve, reject); | ||
} | ||
setTimeout(function(){ reject(new Error('Could not retrieve FileSystem after 5 seconds.')); },5100); | ||
@@ -812,2 +856,4 @@ },reject); | ||
fs.then(function(fs){ | ||
CDV_INTERNAL_URL_ROOT = fs.root.toInternalURL(); | ||
CDV_URL_ROOT = fs.root.toURL(); | ||
window.__fs = fs; | ||
@@ -950,3 +996,5 @@ },function(err){ | ||
/* convert path to URL to be used in JS/CSS/HTML */ | ||
var toInternalURL,toInternalURLSync; | ||
var toInternalURL,toInternalURLSync,toURLSync; | ||
CDV_INTERNAL_URL_ROOT = 'cdvfile://localhost/'+(options.persistent? 'persistent/':'temporary/'); | ||
CDV_URL_ROOT = ''; | ||
if(isCordova) { | ||
@@ -956,4 +1004,9 @@ /* synchronous helper to get internal URL. */ | ||
path = normalize(path); | ||
return path.indexOf('://') < 0? 'cdvfile://localhost/'+(options.persistent? 'persistent/':'temporary/') + path: path; | ||
return path.indexOf('://') < 0? CDV_INTERNAL_URL_ROOT + path: path; | ||
}; | ||
/* synchronous helper to get native URL. */ | ||
toURLSync = function(path){ | ||
path = normalize(path); | ||
return path.indexOf('://') < 0? CDV_URL_ROOT + path: path; | ||
}; | ||
@@ -977,2 +1030,3 @@ toInternalURL = function(path) { | ||
}; | ||
toURLSync = toInternalURLSync; | ||
} | ||
@@ -1016,5 +1070,5 @@ | ||
if(typeof blob === 'string') { | ||
blob = new Blob([blob],{type: mimeType || 'text/plain'}); | ||
blob = createBlob([blob], mimeType || 'text/plain'); | ||
} else if(blob instanceof Blob !== true){ | ||
blob = new Blob([JSON.stringify(blob,null,4)],{type: mimeType || 'application/json'}); | ||
blob = createBlob([JSON.stringify(blob,null,4)], mimeType || 'application/json'); | ||
} | ||
@@ -1027,2 +1081,22 @@ writer.write(blob); | ||
function createBlob(parts, type) { | ||
var BlobBuilder, | ||
bb; | ||
try { | ||
return new Blob(parts, {type: type}); | ||
} catch(e) { | ||
BlobBuilder = window.BlobBuilder || | ||
window.WebKitBlobBuilder || | ||
window.MozBlobBuilder || | ||
window.MSBlobBuilder; | ||
if(BlobBuilder) { | ||
bb = new BlobBuilder(); | ||
bb.append(parts); | ||
return bb.getBlob(type); | ||
} else { | ||
throw new Error("Unable to create blob"); | ||
} | ||
} | ||
} | ||
/* move a file */ | ||
@@ -1100,10 +1174,10 @@ function move(src,dest) { | ||
var args = transferQueue.pop(); | ||
var ft = args.shift(); | ||
var isDownload = args.shift(); | ||
var serverUrl = args.shift(); | ||
var localPath = args.shift(); | ||
var win = args.shift(); | ||
var fail = args.shift(); | ||
var trustAllHosts = args.shift(); | ||
var transferOptions = args.shift(); | ||
var ft = args.fileTransfer, | ||
isDownload = args.isDownload, | ||
serverUrl = args.serverUrl, | ||
localPath = args.localPath, | ||
trustAllHosts = args.trustAllHosts, | ||
transferOptions = args.transferOptions, | ||
win = args.win, | ||
fail = args.fail; | ||
@@ -1135,3 +1209,3 @@ if(ft._aborted) { | ||
} | ||
if(isCordova && localPath.indexOf('://') < 0) localPath = toInternalURLSync(localPath); | ||
if(isCordova && localPath.indexOf('://') < 0) localPath = toURLSync(localPath); | ||
@@ -1153,5 +1227,17 @@ transferOptions = transferOptions || {}; | ||
if(transferOptions.retry.length === 0) { | ||
if(options.debug) console.log('FileTransfer Error: '+serverUrl,err); | ||
reject(err); | ||
} else { | ||
transferQueue.unshift([ft,isDownload,serverUrl,localPath,resolve,attempt,transferOptions.trustAllHosts || false,transferOptions]); | ||
var transferJob = { | ||
fileTransfer:ft, | ||
isDownload:isDownload, | ||
serverUrl:serverUrl, | ||
localPath:localPath, | ||
trustAllHosts:transferOptions.trustAllHosts || false, | ||
transferOptions:transferOptions, | ||
win:resolve, | ||
fail:attempt | ||
}; | ||
transferQueue.unshift(transferJob); | ||
var timeout = transferOptions.retry.shift(); | ||
@@ -1158,0 +1244,0 @@ if(timeout > 0) { |
@@ -83,2 +83,3 @@ var CordovaAppLoader = | ||
this.bundledManifest = null; | ||
this.preventAutoUpdateLoop = options.preventAutoUpdateLoop === true; | ||
this._lastUpdateFiles = localStorage.getItem('last_update_files'); | ||
@@ -165,3 +166,3 @@ | ||
// Check if the newFiles match the previous files (last_update_files) | ||
if(newFiles === self._lastUpdateFiles) { | ||
if(self.preventAutoUpdateLoop === true && newFiles === self._lastUpdateFiles) { | ||
// YES! So we're doing the same update again! | ||
@@ -184,3 +185,3 @@ | ||
if(!newManifest.files){ | ||
reject('Downloaded Manifest has no "files" attribute.'); | ||
reject(new Error('Downloaded Manifest has no "files" attribute.')); | ||
return; | ||
@@ -200,2 +201,3 @@ } | ||
var isCordova = self.cache._fs.isCordova; | ||
var changes = 0; | ||
Object.keys(newFiles) | ||
@@ -207,3 +209,3 @@ // Find files that have changed version or are missing | ||
// version has changed, or... | ||
oldFiles[file].version !== newFiles[file].version || | ||
oldFiles[file].version !== newFiles[file].version //|| | ||
// not in cache for some reason | ||
@@ -221,2 +223,5 @@ !self.cache.isCached(file); | ||
} | ||
if(!bundledFiles[file] || bundledFiles[file].version !== newFiles[file].version){ | ||
changes++; | ||
} | ||
}); | ||
@@ -239,3 +244,3 @@ | ||
var changes = self._toBeDeleted.length + self._toBeDownloaded.length; | ||
changes += self._toBeDeleted.length; | ||
// Note: if we only need to copy files, we can keep serving from bundle! | ||
@@ -246,3 +251,3 @@ // So no update is needed! | ||
self.newManifest = newManifest; | ||
self.newManifest.root = self.cache.localInternalURL; | ||
self.newManifest.root = self.cache.localUrl; | ||
resolve(true); | ||
@@ -266,3 +271,3 @@ } else { | ||
AppLoader.prototype.download = function(onprogress){ | ||
AppLoader.prototype.download = function(onprogress,includeFileProgressEvents){ | ||
var self = this; | ||
@@ -288,3 +293,3 @@ if(!self.canDownload()) { | ||
self.cache.add(self._toBeDownloaded); | ||
return self.cache.download(onprogress); | ||
return self.cache.download(onprogress,includeFileProgressEvents); | ||
}).then(function(){ | ||
@@ -343,3 +348,3 @@ self._toBeDeleted = []; | ||
this._fs = options.fs; | ||
if(!this._fs) { | ||
if(!this._fs) { | ||
throw new Error('Missing required option "fs". Add an instance of cordova-promise-fs.'); | ||
@@ -444,5 +449,6 @@ } | ||
FileCache.prototype.download = function download(onprogress){ | ||
FileCache.prototype.download = function download(onprogress,includeFileProgressEvents){ | ||
var fs = this._fs; | ||
var self = this; | ||
includeFileProgressEvents = includeFileProgressEvents || false; | ||
self.abort(); | ||
@@ -467,2 +473,3 @@ | ||
var total = self._downloading.length + queue.length; | ||
var percentage = 0; | ||
@@ -481,5 +488,7 @@ // download every file in the queue (which is the diff from _added with _cached) | ||
ev.percentage = done / total; | ||
if(ev.loaded > 0 && ev.total > 0 && index !== total){ | ||
if(ev.loaded > 0 && ev.total > 0 && done !== total){ | ||
ev.percentage += (ev.loaded / ev.total) / total; | ||
} | ||
ev.percentage = Math.max(percentage,ev.percentage); | ||
percentage = ev.percentage; | ||
onprogress(ev); | ||
@@ -492,2 +501,3 @@ }; | ||
done++; | ||
onSingleDownloadProgress(new ProgressEvent()); | ||
@@ -514,3 +524,3 @@ // when we're done | ||
if(self._cacheBuster) downloadUrl += "?"+Date.now(); | ||
var download = fs.download(downloadUrl,path,{retry:self._retry},onSingleDownloadProgress); | ||
var download = fs.download(downloadUrl,path,{retry:self._retry},includeFileProgressEvents? onSingleDownloadProgress: undefined); | ||
download.then(onDone,onDone); | ||
@@ -554,3 +564,3 @@ self._downloading.push(download); | ||
path = this.toPath(url); | ||
if(this._cached[path]) return this._cached[path].toInternalURL; | ||
if(this._cached[path]) return this._cached[path].toURL; | ||
return this.toServerURL(url); | ||
@@ -590,3 +600,7 @@ }; | ||
} else { | ||
return this.localRoot + hash(url) + url.substr(url.lastIndexOf('.')); | ||
var ext = url.substr(url.lastIndexOf('.')); | ||
if ((ext.indexOf("?") > 0) || (ext.indexOf("/") > 0)) { | ||
ext = ".txt"; | ||
} | ||
return this.localRoot + hash(url) + ext; | ||
} | ||
@@ -701,4 +715,27 @@ }; | ||
if(str[0] === '/') str = str.substr(1); | ||
if(!!str && str.indexOf('.') < 0 && str[str.length-1] !== '/') str += '/'; | ||
if(str === './') str = ''; | ||
var tokens = str.split('/'), last = tokens[0]; | ||
// check tokens for instances of .. and . | ||
for(var i=1;i < tokens.length;i++) { | ||
last = tokens[i]; | ||
if (tokens[i] === '..') { | ||
// remove the .. and the previous token | ||
tokens.splice(i-1,2); | ||
// rewind 'cursor' 2 tokens | ||
i = i - 2; | ||
} else if (tokens[i] === '.') { | ||
// remove the .. and the previous token | ||
tokens.splice(i,1); | ||
// rewind 'cursor' 1 token | ||
i--; | ||
} | ||
} | ||
str = tokens.join('/'); | ||
if(str === './') { | ||
str = ''; | ||
} else if(last && last.indexOf('.') < 0 && str[str.length - 1] != '/'){ | ||
str += '/'; | ||
} | ||
return str; | ||
@@ -719,3 +756,3 @@ } | ||
/* default options */ | ||
this.options = options = options || {}; | ||
options = options || {}; | ||
options.persistent = options.persistent !== undefined? options.persistent: true; | ||
@@ -725,2 +762,3 @@ options.storageSize = options.storageSize || 20*1024*1024; | ||
options.retry = options.retry || []; | ||
options.debug = !!options.debug; | ||
@@ -746,3 +784,3 @@ /* Cordova deviceready promise */ | ||
if (xhr.readyState == 4) { | ||
if(xhr.status === 200){ | ||
if(xhr.status === 200 && !this._aborted){ | ||
write(file,xhr.response).then(win,fail); | ||
@@ -757,2 +795,5 @@ } else { | ||
}; | ||
FileTransfer.prototype.abort = function(){ | ||
this._aborted = true; | ||
}; | ||
window.ProgressEvent = function ProgressEvent(){}; | ||
@@ -778,10 +819,5 @@ window.FileEntry = function FileEntry(){}; | ||
var type = options.persistent? 1: 0; | ||
if(typeof options.fileSystem === 'number'){ | ||
if(options.fileSystem && isCordova){ | ||
type = options.fileSystem; | ||
} | ||
// Chrome only supports persistent and temp storage, not the exotic onces from Cordova | ||
if(!isCordova && type > 1) { | ||
console.warn('Chrome does not support fileSystem "'+type+'". Falling back on "0" (temporary).'); | ||
type = 0; | ||
} | ||
// On chrome, request quota to store persistent files | ||
@@ -791,7 +827,15 @@ if (!isCordova && type === 1 && navigator.webkitPersistentStorage) { | ||
window.requestFileSystem(type, grantedBytes, resolve, reject); | ||
}); | ||
}, reject); | ||
} else { | ||
// Exotic Cordova Directories (options.fileSystem = string) | ||
if(isNaN(type)) { | ||
window.resolveLocalFileSystemURL(type,function(directory){ | ||
resolve(directory.filesystem); | ||
},reject); | ||
// Normal browser usage | ||
} else { | ||
window.requestFileSystem(type, options.storageSize, resolve, reject); | ||
} | ||
} | ||
else { | ||
window.requestFileSystem(type, options.storageSize, resolve, reject); | ||
} | ||
setTimeout(function(){ reject(new Error('Could not retrieve FileSystem after 5 seconds.')); },5100); | ||
@@ -803,2 +847,4 @@ },reject); | ||
fs.then(function(fs){ | ||
CDV_INTERNAL_URL_ROOT = fs.root.toInternalURL(); | ||
CDV_URL_ROOT = fs.root.toURL(); | ||
window.__fs = fs; | ||
@@ -941,3 +987,5 @@ },function(err){ | ||
/* convert path to URL to be used in JS/CSS/HTML */ | ||
var toInternalURL,toInternalURLSync; | ||
var toInternalURL,toInternalURLSync,toURLSync; | ||
CDV_INTERNAL_URL_ROOT = 'cdvfile://localhost/'+(options.persistent? 'persistent/':'temporary/'); | ||
CDV_URL_ROOT = ''; | ||
if(isCordova) { | ||
@@ -947,4 +995,9 @@ /* synchronous helper to get internal URL. */ | ||
path = normalize(path); | ||
return path.indexOf('://') < 0? 'cdvfile://localhost/'+(options.persistent? 'persistent/':'temporary/') + path: path; | ||
return path.indexOf('://') < 0? CDV_INTERNAL_URL_ROOT + path: path; | ||
}; | ||
/* synchronous helper to get native URL. */ | ||
toURLSync = function(path){ | ||
path = normalize(path); | ||
return path.indexOf('://') < 0? CDV_URL_ROOT + path: path; | ||
}; | ||
@@ -968,2 +1021,3 @@ toInternalURL = function(path) { | ||
}; | ||
toURLSync = toInternalURLSync; | ||
} | ||
@@ -1007,5 +1061,5 @@ | ||
if(typeof blob === 'string') { | ||
blob = new Blob([blob],{type: mimeType || 'text/plain'}); | ||
blob = createBlob([blob], mimeType || 'text/plain'); | ||
} else if(blob instanceof Blob !== true){ | ||
blob = new Blob([JSON.stringify(blob,null,4)],{type: mimeType || 'application/json'}); | ||
blob = createBlob([JSON.stringify(blob,null,4)], mimeType || 'application/json'); | ||
} | ||
@@ -1018,2 +1072,22 @@ writer.write(blob); | ||
function createBlob(parts, type) { | ||
var BlobBuilder, | ||
bb; | ||
try { | ||
return new Blob(parts, {type: type}); | ||
} catch(e) { | ||
BlobBuilder = window.BlobBuilder || | ||
window.WebKitBlobBuilder || | ||
window.MozBlobBuilder || | ||
window.MSBlobBuilder; | ||
if(BlobBuilder) { | ||
bb = new BlobBuilder(); | ||
bb.append(parts); | ||
return bb.getBlob(type); | ||
} else { | ||
throw new Error("Unable to create blob"); | ||
} | ||
} | ||
} | ||
/* move a file */ | ||
@@ -1091,10 +1165,10 @@ function move(src,dest) { | ||
var args = transferQueue.pop(); | ||
var ft = args.shift(); | ||
var isDownload = args.shift(); | ||
var serverUrl = args.shift(); | ||
var localPath = args.shift(); | ||
var win = args.shift(); | ||
var fail = args.shift(); | ||
var trustAllHosts = args.shift(); | ||
var transferOptions = args.shift(); | ||
var ft = args.fileTransfer, | ||
isDownload = args.isDownload, | ||
serverUrl = args.serverUrl, | ||
localPath = args.localPath, | ||
trustAllHosts = args.trustAllHosts, | ||
transferOptions = args.transferOptions, | ||
win = args.win, | ||
fail = args.fail; | ||
@@ -1126,3 +1200,3 @@ if(ft._aborted) { | ||
} | ||
if(isCordova && localPath.indexOf('://') < 0) localPath = toInternalURLSync(localPath); | ||
if(isCordova && localPath.indexOf('://') < 0) localPath = toURLSync(localPath); | ||
@@ -1144,5 +1218,17 @@ transferOptions = transferOptions || {}; | ||
if(transferOptions.retry.length === 0) { | ||
if(options.debug) console.log('FileTransfer Error: '+serverUrl,err); | ||
reject(err); | ||
} else { | ||
transferQueue.unshift([ft,isDownload,serverUrl,localPath,resolve,attempt,transferOptions.trustAllHosts || false,transferOptions]); | ||
var transferJob = { | ||
fileTransfer:ft, | ||
isDownload:isDownload, | ||
serverUrl:serverUrl, | ||
localPath:localPath, | ||
trustAllHosts:transferOptions.trustAllHosts || false, | ||
transferOptions:transferOptions, | ||
win:resolve, | ||
fail:attempt | ||
}; | ||
transferQueue.unshift(transferJob); | ||
var timeout = transferOptions.retry.shift(); | ||
@@ -1149,0 +1235,0 @@ if(timeout > 0) { |
@@ -13,3 +13,3 @@ (function(){ | ||
fs = new CordovaPromiseFS({ | ||
persistent: typeof cordova !== 'undefined', | ||
persistent: 0, | ||
Promise:Promise | ||
@@ -16,0 +16,0 @@ }); |
@@ -40,2 +40,4 @@ (function(){ | ||
assert.equal(fs.normalize('/dir/sub/sub/sub'), 'dir/sub/sub/sub/', 'subdirectories'); | ||
assert.equal(fs.normalize('/dir/sub/../sub'), 'dir/sub/', 'normalize ..'); | ||
assert.equal(fs.normalize('/dir/sub/./sub'), 'dir/sub/sub/', 'normalize .'); | ||
}); | ||
@@ -42,0 +44,0 @@ |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
1725142
38684
2
524
+ Addedcordova-file-cache@1.2.2(transitive)
+ Addedcordova-promise-fs@1.2.5(transitive)
- Removedcordova-file-cache@0.13.0(transitive)
- Removedcordova-promise-fs@0.13.0(transitive)
Updatedcordova-file-cache@^1.1.0
Updatedcordova-promise-fs@^1.1.0