mirror of
https://github.com/futurepress/epub.js.git
synced 2025-10-03 14:59:18 +02:00
indexeddb storage
This commit is contained in:
parent
d90fd14ad2
commit
8e6f8289ca
7 changed files with 312 additions and 14 deletions
|
@ -14,12 +14,14 @@ FP.app.init = (function($){
|
||||||
//-- Set up our sidebar
|
//-- Set up our sidebar
|
||||||
$("#main").width($(window).width()-40);
|
$("#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 = new FP.Book("area", "/the-hound-of-the-baskervilles/");
|
||||||
|
|
||||||
Book.listen("book:metadataReady", meta);
|
Book.listen("book:metadataReady", meta);
|
||||||
Book.listen("book:tocReady", toc);
|
Book.listen("book:tocReady", toc);
|
||||||
|
|
||||||
|
Book.start(bookURL + "/");
|
||||||
|
|
||||||
//-- Wait for Dom ready to handle jquery
|
//-- Wait for Dom ready to handle jquery
|
||||||
$(function() {
|
$(function() {
|
||||||
controls();
|
controls();
|
||||||
|
|
|
@ -23,11 +23,11 @@ FP.Book = function(elem, bookUrl){
|
||||||
|
|
||||||
//-- Determine storage type
|
//-- Determine storage type
|
||||||
// options: none | ram
|
// options: none | ram
|
||||||
FP.storage.storageMethod("ram");
|
FP.storage.storageMethod("indexedDB");
|
||||||
|
|
||||||
// BookUrl is optional, but if present start loading process
|
// BookUrl is optional, but if present start loading process
|
||||||
if(bookUrl) {
|
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;
|
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: Check what storage types are available
|
||||||
//-- TODO: Checks if the url is a zip file and unpack
|
//-- TODO: Checks if the url is a zip file and unpack
|
||||||
if(this.isContained(bookUrl)){
|
if(this.isContained(bookUrl)){
|
||||||
|
@ -82,7 +87,7 @@ FP.Book.prototype.loadEpub = function(bookUrl){
|
||||||
this.tell("book:tocReady");
|
this.tell("book:tocReady");
|
||||||
this.tell("book:metadataReady");
|
this.tell("book:metadataReady");
|
||||||
this.tell("book:spineReady");
|
this.tell("book:spineReady");
|
||||||
console.log(this.metadata)
|
|
||||||
//-- Info is saved, start display
|
//-- Info is saved, start display
|
||||||
this.startDisplay();
|
this.startDisplay();
|
||||||
}
|
}
|
||||||
|
@ -353,10 +358,9 @@ FP.Book.prototype.startDisplay = function(){
|
||||||
this.tell("book:bookReady");
|
this.tell("book:bookReady");
|
||||||
this.displayChapter(this.spinePos, false, function(){
|
this.displayChapter(this.spinePos, false, function(){
|
||||||
|
|
||||||
//-- What happens if the cache expires / is cleared / changed?
|
if(this.online){
|
||||||
//if(!this.stored){
|
|
||||||
this.storeOffline();
|
this.storeOffline();
|
||||||
//}
|
}
|
||||||
|
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
var FP = FP || {};
|
||||||
FP.core = {}
|
FP.core = {}
|
||||||
|
|
||||||
//-- Get a element for an id
|
//-- Get a element for an id
|
||||||
|
|
|
@ -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");
|
||||||
|
});
|
||||||
|
*/
|
|
@ -129,7 +129,7 @@ FP.Queue.prototype.next = function(){
|
||||||
//-- listen for worker response
|
//-- listen for worker response
|
||||||
worker.onmessage = function(e){
|
worker.onmessage = function(e){
|
||||||
var data = e.data;
|
var data = e.data;
|
||||||
|
//console.log("data", data)
|
||||||
task.callback(data);
|
task.callback(data);
|
||||||
delete that._tasks[curr]; //-- Remove task
|
delete that._tasks[curr]; //-- Remove task
|
||||||
|
|
||||||
|
|
|
@ -368,3 +368,199 @@ FP.storage.ram = function() {
|
||||||
"batch" : batch
|
"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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
|
|
||||||
<link rel="stylesheet" href="css/normalize.css">
|
<link rel="stylesheet" href="css/normalize.css">
|
||||||
<link rel="stylesheet" href="css/main.css">
|
<link rel="stylesheet" href="css/main.css">
|
||||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
|
<!-- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> -->
|
||||||
|
<script src="fpjs/libs/jquery-1.9.0.js"></script>
|
||||||
<script>window.jQuery || document.write('<script src="fpjs/libs/jquery-1.9.0.min.js"><\/script>')</script>
|
<script>window.jQuery || document.write('<script src="fpjs/libs/jquery-1.9.0.min.js"><\/script>')</script>
|
||||||
<script src="fpjs/libs/modernizr-2.6.2.min.js"></script>
|
<script src="fpjs/libs/modernizr-2.6.2.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue