diff --git a/fpjs/reader/app.js b/fpjs/reader/app.js index 850adb8..5c1ff9c 100644 --- a/fpjs/reader/app.js +++ b/fpjs/reader/app.js @@ -14,12 +14,14 @@ FP.app.init = (function($){ //-- Set up our sidebar $("#main").width($(window).width()-40); - Book = new FP.Book("area", bookURL + "/"); + Book = new FP.Book("area"); //Book = new FP.Book("area", "/the-hound-of-the-baskervilles/"); Book.listen("book:metadataReady", meta); Book.listen("book:tocReady", toc); - + + Book.start(bookURL + "/"); + //-- Wait for Dom ready to handle jquery $(function() { controls(); diff --git a/fpjs/render/book.js b/fpjs/render/book.js index 89bd8a7..bab270c 100644 --- a/fpjs/render/book.js +++ b/fpjs/render/book.js @@ -23,11 +23,11 @@ FP.Book = function(elem, bookUrl){ //-- Determine storage type // options: none | ram - FP.storage.storageMethod("ram"); + FP.storage.storageMethod("indexedDB"); // BookUrl is optional, but if present start loading process if(bookUrl) { - this.loadEpub(bookUrl); + this.start(bookUrl); } @@ -61,9 +61,14 @@ FP.Book.prototype.listeners = function(){ } -FP.Book.prototype.loadEpub = function(bookUrl){ +FP.Book.prototype.start = function(bookUrl){ this.bookUrl = bookUrl; - + + if(this.bookUrl.search(window.location.origin) == -1){ + //-- get full path + this.bookUrl = window.location.origin + "/" + this.bookUrl; + } + //-- TODO: Check what storage types are available //-- TODO: Checks if the url is a zip file and unpack if(this.isContained(bookUrl)){ @@ -82,7 +87,7 @@ FP.Book.prototype.loadEpub = function(bookUrl){ this.tell("book:tocReady"); this.tell("book:metadataReady"); this.tell("book:spineReady"); - console.log(this.metadata) + //-- Info is saved, start display this.startDisplay(); } @@ -353,10 +358,9 @@ FP.Book.prototype.startDisplay = function(){ this.tell("book:bookReady"); this.displayChapter(this.spinePos, false, function(){ - //-- What happens if the cache expires / is cleared / changed? - //if(!this.stored){ + if(this.online){ this.storeOffline(); - //} + } }.bind(this)); diff --git a/fpjs/render/core.js b/fpjs/render/core.js index 22ac64b..581144d 100644 --- a/fpjs/render/core.js +++ b/fpjs/render/core.js @@ -1,3 +1,4 @@ +var FP = FP || {}; FP.core = {} //-- Get a element for an id diff --git a/fpjs/render/loader_indexeddb.js b/fpjs/render/loader_indexeddb.js index e69de29..aa975b3 100644 --- a/fpjs/render/loader_indexeddb.js +++ b/fpjs/render/loader_indexeddb.js @@ -0,0 +1,94 @@ +importScripts('core.js'); + +const DBNAME = "fpjs_db"; +var indexedDB = self.indexedDB || self.mozIndexedDB || self.webkitIndexedDB || self.msIndexedDB; + +var _q = []; + +self.onmessage = function(event){ + var path = event.data; + + if(self._objectStore){ + self.request(path, function(file){ + self.save(path, file); + self.postMessage("succeeded"); + }); + } + + +}; + +self.opendb = function(callback){ + + var request = indexedDB.open(DBNAME); + + request.onsuccess = function(event) { + self._db = request.result; + + _db.onerror = function(event) { + self.postMessage("failed: " + event.target.errorCode); + }; + + self._transaction = _db.transaction(["files"], "readwrite");//.objectStore("files"); + + self._objectStore = self._transaction.objectStore("files"); + + if(callback) callback(_db); + + }; + + + request.onerror = function(event) { + self.postMessage("failed: " + event.target.errorCode); + }; + + +} + +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); + }; + + xhr.start(); +} + +self.save = function(path, file) { + var entry = {"path" : path, "file": file}, + request; + self.postMessage("failed: before"); + var transaction = _db.transaction(["files"], "readwrite"); + var store = transaction.objectStore("files"); + request = store.put(entry); + self.postMessage("failed: after"); + request.onerror = function(event) { + self.postMessage("failed: " + event.target.errorCode); + }; + + request.onsuccess = function(event) { + //-- Do nothing for now + }; +} + +self.opendb(); +/* +self.opendb(function(db){ + var transaction = db.transaction(["files"], "readwrite")//.objectStore("files"); + + transaction.oncomplete = function(event) { + self.postMessage("All done!"); + }; + + transaction.onerror = function(event) { + self.postMessage("Error in Transaction") + }; + + _objectStore = transaction.objectStore("files"); +}); +*/ diff --git a/fpjs/render/queue.js b/fpjs/render/queue.js index ba43a9c..0d7a473 100644 --- a/fpjs/render/queue.js +++ b/fpjs/render/queue.js @@ -129,7 +129,7 @@ FP.Queue.prototype.next = function(){ //-- listen for worker response worker.onmessage = function(e){ var data = e.data; - + //console.log("data", data) task.callback(data); delete that._tasks[curr]; //-- Remove task @@ -164,4 +164,4 @@ FP.FakeWorker.prototype.onmessage = function(e){ FP.FakeWorker.prototype.close = function(e){ -} \ No newline at end of file +} diff --git a/fpjs/render/storage.js b/fpjs/render/storage.js index 7aab1da..bc0b23a 100644 --- a/fpjs/render/storage.js +++ b/fpjs/render/storage.js @@ -367,4 +367,200 @@ FP.storage.ram = function() { "preload" : preload, "batch" : batch } -} \ No newline at end of file +} + +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 + } +} + + + diff --git a/index.html b/index.html index bf179fe..f6f00f0 100755 --- a/index.html +++ b/index.html @@ -10,7 +10,8 @@ - + +