mirror of
https://github.com/futurepress/epub.js.git
synced 2025-10-03 14:59:18 +02:00
offline storage
This commit is contained in:
parent
8e6f8289ca
commit
0690ad97d0
11 changed files with 926 additions and 342 deletions
BIN
.DS_Store
vendored
BIN
.DS_Store
vendored
Binary file not shown.
|
@ -15,15 +15,16 @@ FP.Book = function(elem, bookUrl){
|
||||||
this.createEvent("book:bookReady");
|
this.createEvent("book:bookReady");
|
||||||
this.createEvent("book:chapterReady");
|
this.createEvent("book:chapterReady");
|
||||||
this.createEvent("book:resized");
|
this.createEvent("book:resized");
|
||||||
|
this.createEvent("book:stored");
|
||||||
|
|
||||||
this.initialize(this.el);
|
this.initialize(this.el);
|
||||||
|
|
||||||
this.online = navigator.onLine;
|
this.online = navigator.onLine;
|
||||||
this.listeners();
|
this.listeners();
|
||||||
|
|
||||||
//-- Determine storage type
|
//-- Determine storage method
|
||||||
// options: none | ram
|
//-- Override options: none | ram | websql | indexedDB | filesystem
|
||||||
FP.storage.storageMethod("indexedDB");
|
this.determineStorageMethod();
|
||||||
|
|
||||||
// BookUrl is optional, but if present start loading process
|
// BookUrl is optional, but if present start loading process
|
||||||
if(bookUrl) {
|
if(bookUrl) {
|
||||||
|
@ -412,20 +413,20 @@ FP.Book.prototype.nextPage = function(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FP.Book.prototype.prevPage = function(){
|
FP.Book.prototype.prevPage = function() {
|
||||||
var prev = this.currentChapter.prevPage();
|
var prev = this.currentChapter.prevPage();
|
||||||
if(!prev){
|
if(!prev){
|
||||||
this.prevChapter();
|
this.prevChapter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FP.Book.prototype.nextChapter = function(){
|
FP.Book.prototype.nextChapter = function() {
|
||||||
this.spinePos++;
|
this.spinePos++;
|
||||||
|
|
||||||
this.displayChapter(this.spinePos);
|
this.displayChapter(this.spinePos);
|
||||||
}
|
}
|
||||||
|
|
||||||
FP.Book.prototype.prevChapter = function(){
|
FP.Book.prototype.prevChapter = function() {
|
||||||
this.spinePos--;
|
this.spinePos--;
|
||||||
|
|
||||||
this.displayChapter(this.spinePos, true);
|
this.displayChapter(this.spinePos, true);
|
||||||
|
@ -433,27 +434,53 @@ FP.Book.prototype.prevChapter = function(){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FP.Book.prototype.getTOC = function(){
|
FP.Book.prototype.getTOC = function() {
|
||||||
return this.toc;
|
return this.toc;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FP.Book.prototype.preloadNextChapter = function(){
|
FP.Book.prototype.preloadNextChapter = function() {
|
||||||
var next = this.spinePos + 1,
|
var next = this.spinePos + 1,
|
||||||
path = this.spine[next].href;
|
path = this.spine[next].href;
|
||||||
|
|
||||||
file = FP.storage.preload(path);
|
file = FP.storage.preload(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
FP.Book.prototype.storeOffline = function(callback){
|
FP.Book.prototype.storeOffline = function(callback) {
|
||||||
var assets = FP.core.toArray(this.assets);
|
var assets = FP.core.toArray(this.assets);
|
||||||
FP.storage.batch(assets, function(){
|
FP.storage.batch(assets, function(){
|
||||||
this.stored = 1;
|
this.stored = 1;
|
||||||
localStorage.setItem("stored", 1);
|
localStorage.setItem("stored", 1);
|
||||||
|
this.tell("book:stored");
|
||||||
if(callback) callback();
|
if(callback) callback();
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
FP.Book.prototype.availableOffline = function(){
|
FP.Book.prototype.availableOffline = function() {
|
||||||
return this.stored > 0 ? true : false;
|
return this.stored > 0 ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FP.Book.prototype.determineStorageMethod = function(override) {
|
||||||
|
var method = 'ram';
|
||||||
|
// options: none | ram | websql | indexedDB | filesystem
|
||||||
|
if(override){
|
||||||
|
method = override;
|
||||||
|
}else{
|
||||||
|
if (Modernizr.websqldatabase) { method = "websql" }
|
||||||
|
if (Modernizr.indexeddb) { method = "indexedDB" }
|
||||||
|
if (Modernizr.filesystem) { method = "filesystem" }
|
||||||
|
}
|
||||||
|
|
||||||
|
FP.storage.storageMethod(method);
|
||||||
|
}
|
||||||
|
|
||||||
|
Modernizr.addTest('filesystem', function(){
|
||||||
|
|
||||||
|
var prefixes = Modernizr._domPrefixes;
|
||||||
|
|
||||||
|
for ( var i = -1, len = prefixes.length; ++i < len; ){
|
||||||
|
if ( window[prefixes[i] + 'RequestFileSystem'] ) return true;
|
||||||
|
}
|
||||||
|
return 'requestFileSystem' in window;
|
||||||
|
|
||||||
|
});
|
|
@ -109,6 +109,15 @@ FP.Chapter.prototype.formatSpread = function(){
|
||||||
|
|
||||||
this.calcPages();
|
this.calcPages();
|
||||||
|
|
||||||
|
if(!this.book.online){
|
||||||
|
//-- Temp place to parse Links
|
||||||
|
this.replaceLinks(function(){
|
||||||
|
this.visible(true);
|
||||||
|
}.bind(this));
|
||||||
|
}else{
|
||||||
|
this.visible(true);
|
||||||
|
}
|
||||||
|
|
||||||
//-- Go to current page after resize
|
//-- Go to current page after resize
|
||||||
if(this.OldcolWidth){
|
if(this.OldcolWidth){
|
||||||
this.leftPos = (this.chapterPos - 1 ) * this.spreadWidth;
|
this.leftPos = (this.chapterPos - 1 ) * this.spreadWidth;
|
||||||
|
@ -120,11 +129,21 @@ FP.Chapter.prototype.goToChapterEnd = function(){
|
||||||
this.chapterEnd();
|
this.chapterEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FP.Chapter.prototype.visible = function(bool){
|
||||||
|
if(bool){
|
||||||
|
this.bodyEl.style.visibility = "visible";
|
||||||
|
}else{
|
||||||
|
this.bodyEl.style.visibility = "hidden";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FP.Chapter.prototype.calcPages = function(){
|
FP.Chapter.prototype.calcPages = function(){
|
||||||
this.totalWidth = this.iframe.contentDocument.documentElement.scrollWidth; //this.bodyEl.scrollWidth;
|
this.totalWidth = this.iframe.contentDocument.documentElement.scrollWidth; //this.bodyEl.scrollWidth;
|
||||||
|
|
||||||
this.displayedPages = Math.ceil(this.totalWidth / this.spreadWidth);
|
this.displayedPages = Math.ceil(this.totalWidth / this.spreadWidth);
|
||||||
this.bodyEl.style.visibility = "visible";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//-- I work for Chrome
|
//-- I work for Chrome
|
||||||
//this.iframe.contentDocument.body.scrollLeft = 200;
|
//this.iframe.contentDocument.body.scrollLeft = 200;
|
||||||
|
@ -178,4 +197,28 @@ FP.Chapter.prototype.setLeft = function(leftPos){
|
||||||
this.bodyEl.style.marginLeft = -leftPos + "px";
|
this.bodyEl.style.marginLeft = -leftPos + "px";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FP.Chapter.prototype.replaceLinks = function(callback){
|
||||||
|
var doc = this.iframe.contentDocument,
|
||||||
|
links = doc.querySelectorAll('[href], [src]'),
|
||||||
|
items = Array.prototype.slice.call(links),
|
||||||
|
count = items.length;
|
||||||
|
|
||||||
|
items.forEach(function(link){
|
||||||
|
var path,
|
||||||
|
href = link.getAttribute("href"),
|
||||||
|
src = link.getAttribute("src"),
|
||||||
|
full = href ? this.book.basePath + href : this.book.basePath + src;
|
||||||
|
|
||||||
|
FP.storage.get(full, function(url){
|
||||||
|
if(href) link.setAttribute("href", url);
|
||||||
|
if(src) link.setAttribute("src", url);
|
||||||
|
count--;
|
||||||
|
if(count <= 0 && callback) callback();
|
||||||
|
});
|
||||||
|
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -137,3 +137,28 @@ FP.core.toArray = function(obj) {
|
||||||
|
|
||||||
return arr;
|
return arr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//-- https://github.com/ebidel/filer.js/blob/master/src/filer.js#L128
|
||||||
|
FP.core.dataURLToBlob = function(dataURL) {
|
||||||
|
var BASE64_MARKER = ';base64,';
|
||||||
|
if (dataURL.indexOf(BASE64_MARKER) == -1) {
|
||||||
|
var parts = dataURL.split(',');
|
||||||
|
var contentType = parts[0].split(':')[1];
|
||||||
|
var raw = parts[1];
|
||||||
|
|
||||||
|
return new Blob([raw], {type: contentType});
|
||||||
|
}
|
||||||
|
|
||||||
|
var parts = dataURL.split(BASE64_MARKER);
|
||||||
|
var contentType = parts[0].split(':')[1];
|
||||||
|
var raw = window.atob(parts[1]);
|
||||||
|
var rawLength = raw.length;
|
||||||
|
|
||||||
|
var uInt8Array = new Uint8Array(rawLength);
|
||||||
|
|
||||||
|
for (var i = 0; i < rawLength; ++i) {
|
||||||
|
uInt8Array[i] = raw.charCodeAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Blob([uInt8Array], {type: contentType});
|
||||||
|
}
|
117
fpjs/render/loader_filesystem.js
Normal file
117
fpjs/render/loader_filesystem.js
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
importScripts('core.js');
|
||||||
|
|
||||||
|
var _requestFileSystem = self.requestFileSystem || self.webkitRequestFileSystem;
|
||||||
|
|
||||||
|
const DBSIZE = 5*1024*1024;
|
||||||
|
const DBTYPE = TEMPORARY;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
self.onmessage = function(event){
|
||||||
|
var path = event.data;
|
||||||
|
|
||||||
|
|
||||||
|
self.request(path, function(file){
|
||||||
|
self.save(path, file, function(){
|
||||||
|
self.postMessage("succeeded");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
self.openFs = function(callback){
|
||||||
|
|
||||||
|
if(self._fs){
|
||||||
|
if(callback) callback(self._fs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_requestFileSystem(DBTYPE, DBSIZE, function(fs){
|
||||||
|
self._fs = fs;
|
||||||
|
if(callback) callback(fs);
|
||||||
|
}, self.failure);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
self.request = function(path, callback) {
|
||||||
|
var xhr = new FP.core.loadFile(path);
|
||||||
|
|
||||||
|
xhr.succeeded = function(file) {
|
||||||
|
if(callback) callback(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.failed = function(err){
|
||||||
|
self.postMessage("failed: " +err.toString());
|
||||||
|
};
|
||||||
|
|
||||||
|
xhr.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
self.save = function(path, file, callback) {
|
||||||
|
self.openFs(function(fs){
|
||||||
|
var base = path.split('/').slice(0,-1);
|
||||||
|
self.createDir(fs.root, base);
|
||||||
|
|
||||||
|
fs.root.getFile(path, {create: true},
|
||||||
|
function(fileEntry) {
|
||||||
|
|
||||||
|
fileEntry.createWriter(function(fileWriter) {
|
||||||
|
|
||||||
|
fileWriter.onwriteend = function(e) {
|
||||||
|
callback(e);
|
||||||
|
};
|
||||||
|
|
||||||
|
fileWriter.onerror = function(e){
|
||||||
|
self.postMessage("write error:" + self.errorHandler(err) + " path="+path);
|
||||||
|
};
|
||||||
|
|
||||||
|
fileWriter.write(file);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}, self.failure );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self.createDir = function(rootDirEntry, folders) {
|
||||||
|
// Throw out './' or '/' and move on to prevent something like '/foo/.//bar'.
|
||||||
|
if (folders[0] == '.' || folders[0] == '') {
|
||||||
|
folders = folders.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
rootDirEntry.getDirectory(folders[0], {create: true}, function(dirEntry) {
|
||||||
|
// Recursively add the new subfolder (if we still have another to create).
|
||||||
|
if (folders.length) {
|
||||||
|
createDir(dirEntry, folders.slice(1));
|
||||||
|
}
|
||||||
|
}, self.failure);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.failure = function(err){
|
||||||
|
self.postMessage("failed: " + self.errorHandler(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.errorHandler = function(e) {
|
||||||
|
switch (e.code) {
|
||||||
|
case FileError.QUOTA_EXCEEDED_ERR:
|
||||||
|
return 'QUOTA_EXCEEDED_ERR';
|
||||||
|
break;
|
||||||
|
case FileError.NOT_FOUND_ERR:
|
||||||
|
return 'NOT_FOUND_ERR';
|
||||||
|
break;
|
||||||
|
case FileError.SECURITY_ERR:
|
||||||
|
return 'SECURITY_ERR';
|
||||||
|
break;
|
||||||
|
case FileError.INVALID_MODIFICATION_ERR:
|
||||||
|
return 'INVALID_MODIFICATION_ERR';
|
||||||
|
break;
|
||||||
|
case FileError.INVALID_STATE_ERR:
|
||||||
|
return 'INVALID_STATE_ERR';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 'Unknown Error';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.openFs();
|
|
@ -31,10 +31,11 @@ FP.storage = function(){
|
||||||
return this._store.batch(group, callback);
|
return this._store.batch(group, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function replace(path, content, callback) {
|
function getURL(path) {
|
||||||
//return this._store.batch(group, callback);
|
return this._store.getURL(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function _error(err){
|
function _error(err){
|
||||||
console.log("error", err);
|
console.log("error", err);
|
||||||
}
|
}
|
||||||
|
@ -43,7 +44,8 @@ FP.storage = function(){
|
||||||
"get" : get,
|
"get" : get,
|
||||||
"preload" : preload,
|
"preload" : preload,
|
||||||
"batch" : batch,
|
"batch" : batch,
|
||||||
"storageMethod": storageMethod
|
"storageMethod": storageMethod,
|
||||||
|
"getURL": getURL
|
||||||
}
|
}
|
||||||
|
|
||||||
}();
|
}();
|
||||||
|
@ -240,327 +242,3 @@ FP.storage.none = function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FP.storage.ram = function() {
|
|
||||||
var _store = {},
|
|
||||||
_blobs = {},
|
|
||||||
_queue = new FP.Queue(loader, 6);
|
|
||||||
//-- max of 6 concurrent requests: http://www.browserscope.org/?category=network
|
|
||||||
|
|
||||||
|
|
||||||
function loader(msg, callback){
|
|
||||||
var e = {"data":null},
|
|
||||||
fromCache = check(msg);
|
|
||||||
|
|
||||||
if(fromCache){
|
|
||||||
e.data = fromCache;
|
|
||||||
callback(e);
|
|
||||||
}else{
|
|
||||||
request(msg, function(file){
|
|
||||||
e.data = file;
|
|
||||||
callback(e);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function preload(path) {
|
|
||||||
var fromCache = check(path);
|
|
||||||
|
|
||||||
if(!fromCache){
|
|
||||||
_queue.add(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function batch(group, callback){
|
|
||||||
_queue.addGroup(group, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-- Fetches url
|
|
||||||
function get(path, callback) {
|
|
||||||
var fromCache = check(path),
|
|
||||||
url;
|
|
||||||
|
|
||||||
if(fromCache){
|
|
||||||
url = getURL(path, fromCache);
|
|
||||||
if(typeof(callback) != "undefined"){
|
|
||||||
callback(url);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
_queue.add(path, function(file){
|
|
||||||
url = getURL(path, file);
|
|
||||||
if(typeof(callback) != "undefined"){
|
|
||||||
callback(url);
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function check(path) {
|
|
||||||
var file = _store[path];
|
|
||||||
|
|
||||||
if(typeof(file) != "undefined"){
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function request(path, callback) {
|
|
||||||
var xhr = new FP.core.loadFile(path);
|
|
||||||
|
|
||||||
xhr.succeeded = function(file) {
|
|
||||||
//console.log("file", file)
|
|
||||||
cache(path, file);
|
|
||||||
if(typeof(callback) != "undefined"){
|
|
||||||
callback(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xhr.failed = _error;
|
|
||||||
|
|
||||||
xhr.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
function cache(path, file) {
|
|
||||||
if(_store[path]) return;
|
|
||||||
|
|
||||||
_store[path] = file;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getURL(path, file){
|
|
||||||
var url;
|
|
||||||
|
|
||||||
if(typeof(_blobs[path]) != "undefined"){
|
|
||||||
return _blobs[path];
|
|
||||||
}
|
|
||||||
|
|
||||||
url = this._URL.createObjectURL(file);
|
|
||||||
|
|
||||||
//-- need to revokeObjectURL previous urls, but only when cleaning cache
|
|
||||||
// this.createdURLs.forEach(function(url){
|
|
||||||
// this._URL.revokeObjectURL(url);
|
|
||||||
// });
|
|
||||||
|
|
||||||
_blobs[path] = url;
|
|
||||||
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this.succeeded = function(){
|
|
||||||
// console.log("loaded");
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// this.failed = function(){
|
|
||||||
// console.log("loaded");
|
|
||||||
// }
|
|
||||||
|
|
||||||
function _error(err){
|
|
||||||
if(typeof(this.failed) == "undefined"){
|
|
||||||
console.log("Error: ", err);
|
|
||||||
}else{
|
|
||||||
this.failed(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
"get" : get,
|
|
||||||
"preload" : preload,
|
|
||||||
"batch" : batch
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FP.storage.indexedDB = function() {
|
|
||||||
var _store = {},
|
|
||||||
_blobs = {},
|
|
||||||
_queue = new FP.Queue(loader, 6),
|
|
||||||
_indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB,
|
|
||||||
_db;
|
|
||||||
|
|
||||||
const DBNAME = "fpjs_db";
|
|
||||||
|
|
||||||
//-- max of 6 concurrent requests: http://www.browserscope.org/?category=network
|
|
||||||
function loader(msg, postMessage){
|
|
||||||
var e = {"data":null},
|
|
||||||
path = msg;
|
|
||||||
|
|
||||||
request(msg, function(file){
|
|
||||||
save(path, file);
|
|
||||||
postMessage(e);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function opendb(callback){
|
|
||||||
var request;
|
|
||||||
|
|
||||||
if(_db){
|
|
||||||
callback(_db);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
request = indexedDB.open(DBNAME);
|
|
||||||
|
|
||||||
|
|
||||||
request.onsuccess = function(event) {
|
|
||||||
_db = request.result;
|
|
||||||
|
|
||||||
_db.onerror = function(event) {
|
|
||||||
console.log("Database error: " + event.target.errorCode);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
if(callback) callback(_db);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
request.onerror = function(event) {
|
|
||||||
// Handle errors.
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
request.onupgradeneeded = function(event) {
|
|
||||||
var db = event.target.result,
|
|
||||||
objectStore = db.createObjectStore("files", { keyPath: "path" }); //keyPath: "id", autoIncrement: true
|
|
||||||
|
|
||||||
//objectStore.createIndex("path", "path", { unique: true });
|
|
||||||
|
|
||||||
//objectStore.createIndex("file", "file", { unique: false });
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function preload(path) {
|
|
||||||
// var fromCache = check(path);
|
|
||||||
//
|
|
||||||
// if(!fromCache){
|
|
||||||
// _queue.add(path);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
function batch(group, callback){
|
|
||||||
_queue.addGroup(group, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-- Fetches url
|
|
||||||
function get(path, callback) {
|
|
||||||
|
|
||||||
check(path, function(fromCache){
|
|
||||||
|
|
||||||
var url;
|
|
||||||
|
|
||||||
if(fromCache){
|
|
||||||
url = getURL(path, fromCache);
|
|
||||||
if(typeof(callback) != "undefined"){
|
|
||||||
callback(url);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
_queue.add(path, function(file){
|
|
||||||
url = getURL(path, file);
|
|
||||||
if(typeof(callback) != "undefined"){
|
|
||||||
callback(url);
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function check(path, callback) {
|
|
||||||
var request,
|
|
||||||
objectStore;
|
|
||||||
|
|
||||||
opendb(function(db){
|
|
||||||
objectStore = db.transaction(["files"]).objectStore("files");
|
|
||||||
request = objectStore.get(path);
|
|
||||||
|
|
||||||
request.onerror = function(event) {
|
|
||||||
callback(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
request.onsuccess = function(event) {
|
|
||||||
callback(request.result.file);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//-- should be in worker
|
|
||||||
|
|
||||||
function request(path, callback) {
|
|
||||||
var xhr = new FP.core.loadFile(path);
|
|
||||||
|
|
||||||
xhr.succeeded = function(file) {
|
|
||||||
if(typeof(callback) != "undefined"){
|
|
||||||
callback(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xhr.failed = _error;
|
|
||||||
|
|
||||||
xhr.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
function save(path, file) {
|
|
||||||
var entry = {"path" : path, "file": file},
|
|
||||||
request;
|
|
||||||
|
|
||||||
var transaction = _db.transaction(["files"], "readwrite");
|
|
||||||
var store = transaction.objectStore("files");
|
|
||||||
request = store.put(entry);
|
|
||||||
|
|
||||||
request.onerror = function(event) {
|
|
||||||
console.log("failed: " + event.target.errorCode);
|
|
||||||
};
|
|
||||||
|
|
||||||
request.onsuccess = function(event) {
|
|
||||||
//-- Do nothing for now
|
|
||||||
console.log("saved", path);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//-- end worker
|
|
||||||
|
|
||||||
function getURL(path, file){
|
|
||||||
var url;
|
|
||||||
|
|
||||||
if(typeof(_blobs[path]) != "undefined"){
|
|
||||||
return _blobs[path];
|
|
||||||
}
|
|
||||||
|
|
||||||
url = this._URL.createObjectURL(file);
|
|
||||||
|
|
||||||
//-- need to revokeObjectURL previous urls, but only when cleaning cache
|
|
||||||
// this.createdURLs.forEach(function(url){
|
|
||||||
// this._URL.revokeObjectURL(url);
|
|
||||||
// });
|
|
||||||
|
|
||||||
_blobs[path] = url;
|
|
||||||
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
function _error(err){
|
|
||||||
if(typeof(this.failed) == "undefined"){
|
|
||||||
console.log("Error: ", err);
|
|
||||||
}else{
|
|
||||||
this.failed(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
|
||||||
"get" : get,
|
|
||||||
"preload" : preload,
|
|
||||||
"batch" : batch
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
151
fpjs/render/storage_filesystem.js
Normal file
151
fpjs/render/storage_filesystem.js
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
FP.storage = FP.storage || {}
|
||||||
|
|
||||||
|
FP.storage.filesystem = function() {
|
||||||
|
var _urls = {},
|
||||||
|
_queue = new FP.Queue("fpjs/render/loader_filesystem.js", 6),
|
||||||
|
_requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem,
|
||||||
|
_fs;
|
||||||
|
|
||||||
|
const DBSIZE = 5*1024*1024;
|
||||||
|
const DBTYPE = TEMPORARY;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function openFs(callback){
|
||||||
|
|
||||||
|
if(_fs){
|
||||||
|
callback(_fs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_requestFileSystem(DBTYPE, DBSIZE, function(fs){
|
||||||
|
_fs = fs;
|
||||||
|
callback(fs);
|
||||||
|
}, _error);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function preload(path) {
|
||||||
|
// var fromCache = check(path);
|
||||||
|
//
|
||||||
|
// if(!fromCache){
|
||||||
|
// _queue.add(path);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
function batch(group, callback){
|
||||||
|
_queue.addGroup(group, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-- Fetches url
|
||||||
|
function get(path, callback) {
|
||||||
|
|
||||||
|
if(typeof(_urls[path]) != "undefined"){
|
||||||
|
return _urls[path];
|
||||||
|
}
|
||||||
|
|
||||||
|
check(path, function(fromCache){
|
||||||
|
|
||||||
|
var url;
|
||||||
|
//-- should only be checking urls? but blank on reload?
|
||||||
|
if(fromCache){
|
||||||
|
url = getURL(path, fromCache);
|
||||||
|
if(typeof(callback) != "undefined"){
|
||||||
|
callback(url);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
_queue.add(path, function(file){
|
||||||
|
url = getURL(path, file);
|
||||||
|
if(typeof(callback) != "undefined"){
|
||||||
|
callback(url);
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function check(path, callback) {
|
||||||
|
var request,
|
||||||
|
objectStore;
|
||||||
|
|
||||||
|
openFs(function(fs){
|
||||||
|
fs.root.getFile(path, {},
|
||||||
|
function(fileEntry) {
|
||||||
|
callback(fileEntry);
|
||||||
|
},
|
||||||
|
function(){
|
||||||
|
callback(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//-- should be in worker
|
||||||
|
|
||||||
|
function request(path, callback) {
|
||||||
|
var xhr = new FP.core.loadFile(path);
|
||||||
|
|
||||||
|
xhr.succeeded = function(file) {
|
||||||
|
if(typeof(callback) != "undefined"){
|
||||||
|
callback(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.failed = _error;
|
||||||
|
|
||||||
|
xhr.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
function save(path, file) {
|
||||||
|
var entry = {"path" : path, "file": file},
|
||||||
|
request;
|
||||||
|
|
||||||
|
var transaction = _db.transaction(["files"], "readwrite");
|
||||||
|
var store = transaction.objectStore("files");
|
||||||
|
request = store.put(entry);
|
||||||
|
|
||||||
|
request.onerror = function(event) {
|
||||||
|
console.log("failed: " + event.target.errorCode);
|
||||||
|
};
|
||||||
|
|
||||||
|
request.onsuccess = function(event) {
|
||||||
|
//-- Do nothing for now
|
||||||
|
console.log("saved", path);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//-- end worker
|
||||||
|
|
||||||
|
function getURL(path, fileEntry){
|
||||||
|
var url;
|
||||||
|
|
||||||
|
if(typeof(_urls[path]) != "undefined"){
|
||||||
|
return _urls[path];
|
||||||
|
}
|
||||||
|
|
||||||
|
url = fileEntry.toURL();
|
||||||
|
|
||||||
|
_urls[path] = url;
|
||||||
|
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _error(err){
|
||||||
|
if(typeof(this.failed) == "undefined"){
|
||||||
|
console.log("Error: ", err);
|
||||||
|
}else{
|
||||||
|
this.failed(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
"get" : get,
|
||||||
|
"preload" : preload,
|
||||||
|
"batch" : batch
|
||||||
|
}
|
||||||
|
}
|
202
fpjs/render/storage_indexeddb.js
Normal file
202
fpjs/render/storage_indexeddb.js
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
FP.storage = FP.storage || {}
|
||||||
|
|
||||||
|
FP.storage.indexedDB = function() {
|
||||||
|
var _store = {},
|
||||||
|
_blobs = {},
|
||||||
|
_queue = new FP.Queue(loader, 6),
|
||||||
|
_indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB,
|
||||||
|
_db;
|
||||||
|
|
||||||
|
const DBNAME = "fpjs_db";
|
||||||
|
|
||||||
|
//-- max of 6 concurrent requests: http://www.browserscope.org/?category=network
|
||||||
|
function loader(msg, postMessage){
|
||||||
|
var e = {"data":null},
|
||||||
|
path = msg;
|
||||||
|
|
||||||
|
request(msg, function(file){
|
||||||
|
save(path, file);
|
||||||
|
postMessage(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function opendb(callback){
|
||||||
|
var request;
|
||||||
|
|
||||||
|
if(_db){
|
||||||
|
callback(_db);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
request = indexedDB.open(DBNAME);
|
||||||
|
|
||||||
|
|
||||||
|
request.onsuccess = function(event) {
|
||||||
|
_db = request.result;
|
||||||
|
|
||||||
|
_db.onerror = function(event) {
|
||||||
|
console.log("Database error: " + event.target.errorCode);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
if(callback) callback(_db);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
request.onerror = function(event) {
|
||||||
|
// Handle errors.
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
request.onupgradeneeded = function(event) {
|
||||||
|
var db = event.target.result,
|
||||||
|
objectStore = db.createObjectStore("files", { keyPath: "path" }); //keyPath: "id", autoIncrement: true
|
||||||
|
|
||||||
|
//objectStore.createIndex("path", "path", { unique: true });
|
||||||
|
|
||||||
|
//objectStore.createIndex("file", "file", { unique: false });
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function preload(path) {
|
||||||
|
// var fromCache = check(path);
|
||||||
|
//
|
||||||
|
// if(!fromCache){
|
||||||
|
// _queue.add(path);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
function batch(group, callback){
|
||||||
|
_queue.addGroup(group, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-- Fetches url
|
||||||
|
function get(path, callback) {
|
||||||
|
|
||||||
|
if(typeof(_blobs[path]) != "undefined"){
|
||||||
|
callback(_blobs[path]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
check(path, function(fromCache){
|
||||||
|
|
||||||
|
var url;
|
||||||
|
|
||||||
|
if(fromCache){
|
||||||
|
url = getURL(path, fromCache);
|
||||||
|
if(typeof(callback) != "undefined"){
|
||||||
|
callback(url);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
_queue.add(path, function(file){
|
||||||
|
url = getURL(path, file);
|
||||||
|
if(typeof(callback) != "undefined"){
|
||||||
|
callback(url);
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function check(path, callback) {
|
||||||
|
var request,
|
||||||
|
objectStore;
|
||||||
|
|
||||||
|
opendb(function(db){
|
||||||
|
objectStore = db.transaction(["files"]).objectStore("files");
|
||||||
|
request = objectStore.get(path);
|
||||||
|
|
||||||
|
request.onerror = function(event) {
|
||||||
|
callback(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
request.onsuccess = function(event) {
|
||||||
|
callback(request.result.file);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//-- should be in worker
|
||||||
|
|
||||||
|
function request(path, callback) {
|
||||||
|
var xhr = new FP.core.loadFile(path);
|
||||||
|
|
||||||
|
xhr.succeeded = function(file) {
|
||||||
|
if(typeof(callback) != "undefined"){
|
||||||
|
callback(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.failed = _error;
|
||||||
|
|
||||||
|
xhr.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
function save(path, file) {
|
||||||
|
var entry = {"path" : path, "file": file},
|
||||||
|
request;
|
||||||
|
|
||||||
|
opendb(function(db){
|
||||||
|
var transaction = db.transaction(["files"], "readwrite");
|
||||||
|
var store = transaction.objectStore("files");
|
||||||
|
request = store.put(entry);
|
||||||
|
|
||||||
|
request.onerror = function(event) {
|
||||||
|
console.log("failed: " + event.target.errorCode);
|
||||||
|
};
|
||||||
|
|
||||||
|
request.onsuccess = function(event) {
|
||||||
|
//-- Do nothing for now
|
||||||
|
console.log("saved", path);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//-- end worker
|
||||||
|
|
||||||
|
function getURL(path, file){
|
||||||
|
var url;
|
||||||
|
|
||||||
|
if(typeof(_blobs[path]) != "undefined"){
|
||||||
|
callback(_blobs[path]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
url = this._URL.createObjectURL(file);
|
||||||
|
|
||||||
|
//-- need to revokeObjectURL previous urls, but only when cleaning cache
|
||||||
|
// this.createdURLs.forEach(function(url){
|
||||||
|
// this._URL.revokeObjectURL(url);
|
||||||
|
// });
|
||||||
|
|
||||||
|
_blobs[path] = url;
|
||||||
|
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _error(err){
|
||||||
|
if(typeof(this.failed) == "undefined"){
|
||||||
|
console.log("Error: ", err);
|
||||||
|
}else{
|
||||||
|
this.failed(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
"get" : get,
|
||||||
|
"preload" : preload,
|
||||||
|
"batch" : batch
|
||||||
|
}
|
||||||
|
}
|
130
fpjs/render/storage_ram.js
Normal file
130
fpjs/render/storage_ram.js
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
FP.storage = FP.storage || {};
|
||||||
|
|
||||||
|
FP.storage.ram = function() {
|
||||||
|
var _store = {},
|
||||||
|
_blobs = {},
|
||||||
|
_queue = new FP.Queue(loader, 6);
|
||||||
|
//-- max of 6 concurrent requests: http://www.browserscope.org/?category=network
|
||||||
|
|
||||||
|
|
||||||
|
function loader(msg, callback){
|
||||||
|
var e = {"data":null},
|
||||||
|
fromCache = check(msg);
|
||||||
|
|
||||||
|
if(fromCache){
|
||||||
|
e.data = fromCache;
|
||||||
|
callback(e);
|
||||||
|
}else{
|
||||||
|
request(msg, function(file){
|
||||||
|
e.data = file;
|
||||||
|
callback(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function preload(path) {
|
||||||
|
var fromCache = check(path);
|
||||||
|
|
||||||
|
if(!fromCache){
|
||||||
|
_queue.add(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function batch(group, callback){
|
||||||
|
_queue.addGroup(group, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-- Fetches url
|
||||||
|
function get(path, callback) {
|
||||||
|
var fromCache = check(path),
|
||||||
|
url;
|
||||||
|
|
||||||
|
if(fromCache){
|
||||||
|
url = getURL(path, fromCache);
|
||||||
|
if(typeof(callback) != "undefined"){
|
||||||
|
callback(url);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
_queue.add(path, function(file){
|
||||||
|
url = getURL(path, file);
|
||||||
|
if(typeof(callback) != "undefined"){
|
||||||
|
callback(url);
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function check(path) {
|
||||||
|
var file = _store[path];
|
||||||
|
|
||||||
|
if(typeof(file) != "undefined"){
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function request(path, callback) {
|
||||||
|
var xhr = new FP.core.loadFile(path);
|
||||||
|
|
||||||
|
xhr.succeeded = function(file) {
|
||||||
|
//console.log("file", file)
|
||||||
|
cache(path, file);
|
||||||
|
if(typeof(callback) != "undefined"){
|
||||||
|
callback(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.failed = _error;
|
||||||
|
|
||||||
|
xhr.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
function cache(path, file) {
|
||||||
|
if(_store[path]) return;
|
||||||
|
|
||||||
|
_store[path] = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getURL(path, file){
|
||||||
|
var url;
|
||||||
|
|
||||||
|
if(typeof(_blobs[path]) != "undefined"){
|
||||||
|
return _blobs[path];
|
||||||
|
}
|
||||||
|
|
||||||
|
url = this._URL.createObjectURL(file);
|
||||||
|
|
||||||
|
//-- need to revokeObjectURL previous urls, but only when cleaning cache
|
||||||
|
// this.createdURLs.forEach(function(url){
|
||||||
|
// this._URL.revokeObjectURL(url);
|
||||||
|
// });
|
||||||
|
|
||||||
|
_blobs[path] = url;
|
||||||
|
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this.succeeded = function(){
|
||||||
|
// console.log("loaded");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// this.failed = function(){
|
||||||
|
// console.log("loaded");
|
||||||
|
// }
|
||||||
|
|
||||||
|
function _error(err){
|
||||||
|
if(typeof(this.failed) == "undefined"){
|
||||||
|
console.log("Error: ", err);
|
||||||
|
}else{
|
||||||
|
this.failed(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"get" : get,
|
||||||
|
"preload" : preload,
|
||||||
|
"batch" : batch
|
||||||
|
}
|
||||||
|
}
|
207
fpjs/render/storage_websql.js
Normal file
207
fpjs/render/storage_websql.js
Normal file
|
@ -0,0 +1,207 @@
|
||||||
|
FP.storage = FP.storage || {}
|
||||||
|
|
||||||
|
FP.storage.websql = function() {
|
||||||
|
var _blobs = {},
|
||||||
|
_queue = new FP.Queue(loader, 6),
|
||||||
|
_db;
|
||||||
|
|
||||||
|
const DBNAME = "fpjs_db";
|
||||||
|
const DBVERSION = "1";
|
||||||
|
const DBDESC = "cache for files";
|
||||||
|
const DBSIZE = 5 * 1024 * 1024;
|
||||||
|
const TABLENAME = "files";
|
||||||
|
|
||||||
|
function loader(msg, postMessage){
|
||||||
|
var e = {"data":null},
|
||||||
|
path = msg;
|
||||||
|
|
||||||
|
request(msg, function(file){
|
||||||
|
save(path, file);
|
||||||
|
postMessage(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function opendb(callback){
|
||||||
|
|
||||||
|
if(_db){
|
||||||
|
callback(_db);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_db = openDatabase(DBNAME, DBVERSION, DBDESC, DBSIZE);
|
||||||
|
|
||||||
|
if(!_db){
|
||||||
|
console.error("Database error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_db.transaction(function (tx) {
|
||||||
|
tx.executeSql('CREATE TABLE IF NOT EXISTS '+ TABLENAME +' (path TEXT PRIMARY KEY ASC UNIQUE, file BLOB, type TEXT)');
|
||||||
|
if(callback) callback(_db);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function preload(path) {
|
||||||
|
// var fromCache = check(path);
|
||||||
|
//
|
||||||
|
// if(!fromCache){
|
||||||
|
// _queue.add(path);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
function batch(group, callback){
|
||||||
|
_queue.addGroup(group, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-- Fetches url
|
||||||
|
function get(path, callback) {
|
||||||
|
|
||||||
|
if(typeof(_blobs[path]) != "undefined"){
|
||||||
|
callback(_blobs[path]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
check(path, function(fromCache){
|
||||||
|
|
||||||
|
var url;
|
||||||
|
|
||||||
|
if(fromCache){
|
||||||
|
url = getURL(path, fromCache);
|
||||||
|
if(typeof(callback) != "undefined"){
|
||||||
|
callback(url);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
_queue.add(path, function(file){
|
||||||
|
url = getURL(path, file);
|
||||||
|
if(typeof(callback) != "undefined"){
|
||||||
|
callback(url);
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function check(path, callback) {
|
||||||
|
var request = {};
|
||||||
|
|
||||||
|
request.onError = function(event, err) {
|
||||||
|
console.log("get Error", err);
|
||||||
|
|
||||||
|
callback(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
request.onSuccess = function(transaction, result) {
|
||||||
|
var row;
|
||||||
|
|
||||||
|
if(result.rows.length){
|
||||||
|
row = result.rows.item(0);
|
||||||
|
callback(row.file);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
opendb(function(db){
|
||||||
|
|
||||||
|
db.transaction(function(tx){
|
||||||
|
tx.executeSql("SELECT * FROM "+TABLENAME+" WHERE path='"+path+"' LIMIT 1",
|
||||||
|
[],
|
||||||
|
request.onSuccess,
|
||||||
|
request.onError);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function request(path, callback) {
|
||||||
|
var xhr = new FP.core.loadFile(path);
|
||||||
|
|
||||||
|
xhr.succeeded = function(file) {
|
||||||
|
if(typeof(callback) != "undefined"){
|
||||||
|
callback(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.failed = _error;
|
||||||
|
|
||||||
|
xhr.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
function save(path, file) {
|
||||||
|
var request = {},
|
||||||
|
reader = new FileReader(),
|
||||||
|
fileString;
|
||||||
|
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
|
||||||
|
reader.onload = function(event){
|
||||||
|
fileString = event.target.result;
|
||||||
|
opendb(function(db){
|
||||||
|
|
||||||
|
db.transaction(function(tx){
|
||||||
|
tx.executeSql("REPLACE INTO "+TABLENAME+" (path, file, type) VALUES (?,?,?)",
|
||||||
|
[path, fileString, file.type],
|
||||||
|
request.onSuccess,
|
||||||
|
request.onError);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
request.onError = function(event, err) {
|
||||||
|
console.log("failed: ", err);
|
||||||
|
};
|
||||||
|
|
||||||
|
request.onSuccess = function(event) {
|
||||||
|
//-- Do nothing for now
|
||||||
|
//console.log("saved", path);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function getURL(path, file){
|
||||||
|
var url, blob;
|
||||||
|
|
||||||
|
if(typeof(_blobs[path]) != "undefined"){
|
||||||
|
callback(_blobs[path]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
blob = FP.core.dataURLToBlob(file); //go from data url to blob
|
||||||
|
url = this._URL.createObjectURL(blob);
|
||||||
|
|
||||||
|
//-- need to revokeObjectURL previous urls, but only when cleaning cache
|
||||||
|
// this.createdURLs.forEach(function(url){
|
||||||
|
// this._URL.revokeObjectURL(url);
|
||||||
|
// });
|
||||||
|
|
||||||
|
_blobs[path] = url;
|
||||||
|
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _error(err){
|
||||||
|
if(typeof(this.failed) == "undefined"){
|
||||||
|
console.log("Error: ", err);
|
||||||
|
}else{
|
||||||
|
this.failed(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
"get" : get,
|
||||||
|
"preload" : preload,
|
||||||
|
"batch" : batch,
|
||||||
|
"getURL" : getURL
|
||||||
|
}
|
||||||
|
}
|
|
@ -39,6 +39,10 @@
|
||||||
<script async src="fpjs/render/core.js"></script>
|
<script async src="fpjs/render/core.js"></script>
|
||||||
<script async src="fpjs/render/queue.js"></script>
|
<script async src="fpjs/render/queue.js"></script>
|
||||||
<script async src="fpjs/render/storage.js"></script>
|
<script async src="fpjs/render/storage.js"></script>
|
||||||
|
<script async src="fpjs/render/storage_ram.js"></script>
|
||||||
|
<script async src="fpjs/render/storage_websql.js"></script>
|
||||||
|
<script async src="fpjs/render/storage_indexeddb.js"></script>
|
||||||
|
<script async src="fpjs/render/storage_filesystem.js"></script>
|
||||||
<script async src="fpjs/render/events.js"></script>
|
<script async src="fpjs/render/events.js"></script>
|
||||||
<script async src="fpjs/render/book.js"></script>
|
<script async src="fpjs/render/book.js"></script>
|
||||||
<script async src="fpjs/render/chapter.js"></script>
|
<script async src="fpjs/render/chapter.js"></script>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue