1
0
Fork 0
mirror of https://github.com/futurepress/epub.js.git synced 2025-10-03 14:59:18 +02:00

Views -> Controllers, Moved previousLocationCfi logic to Reader, Bookmarks in Reader

This commit is contained in:
Fred Chasen 2014-01-02 20:32:51 -08:00
parent 3bfadb2abc
commit e4be17a428
24 changed files with 1363 additions and 1003 deletions

View file

@ -9,7 +9,7 @@ module.exports = function(grunt) {
},
concat : {
'build/epub.js': ['<banner>', 'libs/rsvp/rsvp.js', 'src/*.js'],
'build/reader.js': ['<banner>', 'reader/reader.js'],
'build/reader.js': ['<banner>', 'reader/reader.js', 'reader/controllers/*.js'],
'build/hooks.js': ['<banner>', 'hooks/default/*.js'],
'demo/js/libs/fileStorage.min.js': 'libs/fileStorage/fileStorage.min.js',
'demo/js/libs/loader_filesystem.min.js': 'libs/fileStorage/workers/loader_filesystem.min.js',

View file

@ -1777,6 +1777,8 @@ EPUBJS.Book = function(options){
this.settings = _.defaults(options || {}, {
bookPath : null,
bookKey : null,
packageUrl : null,
storage: false, //-- true (auto) or false (none) | override: 'ram', 'websqldatabase', 'indexeddb', 'filesystem'
fromStorage : false,
saved : false,
@ -1871,52 +1873,51 @@ EPUBJS.Book = function(options){
//-- Check bookUrl and start parsing book Assets or load them from storage
EPUBJS.Book.prototype.open = function(bookPath, forceReload){
var book = this,
saved = this.isSaved(bookPath),
opened;
epubpackage,
opened = new RSVP.defer();
this.settings.bookPath = bookPath;
//-- Get a absolute URL from the book path
this.bookUrl = this.urlFrom(bookPath);
// console.log("saved", saved, !forceReload)
//-- Remove the previous settings and reload
if(saved){
//-- Apply settings, keeping newer ones
this.applySavedSettings();
}
if(this.settings.contained || this.isContained(bookPath)){
this.settings.contained = this.contained = true;
this.bookUrl = '';
// return; //-- TODO: this need to be fixed and tested before enabling
opened = this.unarchive(bookPath).then(function(){
if(saved && book.settings.restore && !forceReload){
return book.restore();
}else{
return book.unpack();
}
});
epubpackage = this.unarchive(bookPath).
then(function(){
return this.loadPackage();
});
} else {
epubpackage = this.loadPackage();
}
if(saved && this.settings.restore && !forceReload){
//-- Will load previous package json, or re-unpack if error
opened = this.restore();
if(this.settings.restore && !forceReload){
//-- Will load previous package json, or re-unpack if error
epubpackage.then(function(packageXml) {
var identifier = book.packageIdentifier(packageXml);
var restored = book.restore(identifier);
}else{
if(!restored) {
book.unpack(packageXml);
}
opened.resolve();
book.defer_opened.resolve();
});
//-- Get package information from epub opf
opened = this.unpack();
}
}else{
//-- Get package information from epub opf
epubpackage.then(function(packageXml) {
book.unpack(packageXml);
opened.resolve();
book.defer_opened.resolve();
});
}
//-- If there is network connection, store the books contents
@ -1924,21 +1925,19 @@ EPUBJS.Book.prototype.open = function(bookPath, forceReload){
if(!this.settings.stored) opened.then(book.storeOffline());
}
opened.then(function(){
book.defer_opened.resolve();
});
return opened;
return opened.promise;
};
EPUBJS.Book.prototype.unpack = function(_containerPath){
EPUBJS.Book.prototype.loadPackage = function(_containerPath){
var book = this,
parse = new EPUBJS.Parser(),
containerPath = _containerPath || "META-INF/container.xml";
parse = new EPUBJS.Parser(),
containerPath = _containerPath || "META-INF/container.xml",
containerXml,
packageXml;
//-- Return chain of promises
return book.loadXml(book.bookUrl + containerPath).
if(!this.settings.packageUrl) { //-- provide the packageUrl to skip this step
packageXml = book.loadXml(book.bookUrl + containerPath).
then(function(containerXml){
return parse.container(containerXml); // Container has path to content
}).
@ -1946,58 +1945,74 @@ EPUBJS.Book.prototype.unpack = function(_containerPath){
book.settings.contentsPath = book.bookUrl + paths.basePath;
book.settings.packageUrl = book.bookUrl + paths.packagePath;
return book.loadXml(book.settings.packageUrl); // Containes manifest, spine and metadata
}).
then(function(packageXml){
return parse.package(packageXml, book.settings.contentsPath); // Extract info from contents
}).
then(function(contents){
book.contents = contents;
book.manifest = book.contents.manifest;
book.spine = book.contents.spine;
book.spineIndexByURL = book.contents.spineIndexByURL;
book.metadata = book.contents.metadata;
book.cover = book.contents.cover = book.settings.contentsPath + contents.coverPath;
book.spineNodeIndex = book.contents.spineNodeIndex = contents.spineNodeIndex;
book.ready.manifest.resolve(book.contents.manifest);
book.ready.spine.resolve(book.contents.spine);
book.ready.metadata.resolve(book.contents.metadata);
book.ready.cover.resolve(book.contents.cover);
//-- Adjust setting based on metadata
//-- Load the TOC, optional; either the EPUB3 XHTML Navigation file or the EPUB2 NCX file
if(contents.navPath) {
book.settings.navUrl = book.settings.contentsPath + contents.navPath;
book.loadXml(book.settings.navUrl).
then(function(navHtml){
return parse.nav(navHtml, book.spineIndexByURL, book.spine); // Grab Table of Contents
}).then(function(toc){
book.toc = book.contents.toc = toc;
book.ready.toc.resolve(book.contents.toc);
}, function(error) {
book.ready.toc.resolve(false);
});
} else if(contents.tocPath) {
book.settings.tocUrl = book.settings.contentsPath + contents.tocPath;
book.loadXml(book.settings.tocUrl).
then(function(tocXml){
return parse.toc(tocXml, book.spineIndexByURL, book.spine); // Grab Table of Contents
}).then(function(toc){
book.toc = book.contents.toc = toc;
book.ready.toc.resolve(book.contents.toc);
}, function(error) {
book.ready.toc.resolve(false);
});
} else {
book.ready.toc.resolve(false);
}
});
} else {
packageXml = book.loadXml(book.settings.packageUrl);
}
return packageXml;
};
EPUBJS.Book.prototype.packageIdentifier = function(packageXml){
var book = this,
parse = new EPUBJS.Parser();
return parse.identifier(packageXml);
};
EPUBJS.Book.prototype.unpack = function(packageXml){
var book = this,
parse = new EPUBJS.Parser();
book.contents = parse.packageContents(packageXml, book.settings.contentsPath); // Extract info from contents
book.manifest = book.contents.manifest;
book.spine = book.contents.spine;
book.spineIndexByURL = book.contents.spineIndexByURL;
book.metadata = book.contents.metadata;
book.setBookKey(book.metadata.identifier);
book.cover = book.contents.cover = book.settings.contentsPath + book.contents.coverPath;
book.spineNodeIndex = book.contents.spineNodeIndex;
book.ready.manifest.resolve(book.contents.manifest);
book.ready.spine.resolve(book.contents.spine);
book.ready.metadata.resolve(book.contents.metadata);
book.ready.cover.resolve(book.contents.cover);
//-- TODO: Adjust setting based on metadata
//-- Load the TOC, optional; either the EPUB3 XHTML Navigation file or the EPUB2 NCX file
if(book.contents.navPath) {
book.settings.navUrl = book.settings.contentsPath + book.contents.navPath;
book.loadXml(book.settings.navUrl).
then(function(navHtml){
return parse.nav(navHtml, book.spineIndexByURL, book.spine); // Grab Table of Contents
}).then(function(toc){
book.toc = book.contents.toc = toc;
book.ready.toc.resolve(book.contents.toc);
}, function(error) {
book.ready.toc.resolve(false);
});
} else if(book.contents.tocPath) {
book.settings.tocUrl = book.settings.contentsPath + book.contents.tocPath;
book.loadXml(book.settings.tocUrl).
then(function(tocXml){
return parse.toc(tocXml, book.spineIndexByURL, book.spine); // Grab Table of Contents
}).then(function(toc){
book.toc = book.contents.toc = toc;
book.ready.toc.resolve(book.contents.toc);
}, function(error) {
book.ready.toc.resolve(false);
});
} else {
book.ready.toc.resolve(false);
}
};
EPUBJS.Book.prototype.getMetadata = function() {
@ -2106,7 +2121,7 @@ EPUBJS.Book.prototype.unarchive = function(bookPath){
//-- Checks if url has a .epub or .zip extension
EPUBJS.Book.prototype.isContained = function(bookUrl){
var dot = bookUrl.lastIndexOf('.'),
ext = bookUrl.slice(dot+1);
ext = bookUrl.slice(dot+1);
if(ext && (ext == "epub" || ext == "zip")){
return true;
@ -2115,10 +2130,9 @@ EPUBJS.Book.prototype.isContained = function(bookUrl){
return false;
};
//-- Checks if the book setting can be retrieved from localStorage
EPUBJS.Book.prototype.isSaved = function(bookPath) {
var bookKey = bookPath + ":" + this.settings.version,
storedSettings = localStorage.getItem(bookKey);
//-- Checks if the book can be retrieved from localStorage
EPUBJS.Book.prototype.isSaved = function(bookKey) {
var storedSettings = localStorage.getItem(bookKey);
if( !localStorage ||
storedSettings === null) {
@ -2128,48 +2142,27 @@ EPUBJS.Book.prototype.isSaved = function(bookPath) {
}
};
//-- Remove save book settings
EPUBJS.Book.prototype.removeSavedSettings = function() {
var bookKey = this.settings.bookPath + ":" + this.settings.version;
localStorage.removeItem(bookKey);
this.settings.stored = false; //TODO: is this needed?
};
EPUBJS.Book.prototype.applySavedSettings = function() {
var bookKey = this.settings.bookPath + ":" + this.settings.version,
stored = JSON.parse(localStorage.getItem(bookKey));
if(EPUBJS.VERSION != stored.EPUBJSVERSION) return false;
this.settings = _.defaults(this.settings, stored);
};
EPUBJS.Book.prototype.saveSettings = function(){
var bookKey = this.settings.bookPath + ":" + this.settings.version;
if(this.render) {
this.settings.previousLocationCfi = this.render.currentLocationCfi;
EPUBJS.Book.prototype.setBookKey = function(identifier){
if(!this.settings.bookKey) {
this.settings.bookKey = this.generateBookKey(identifier);
}
return this.settings.bookKey;
};
localStorage.setItem(bookKey, JSON.stringify(this.settings));
EPUBJS.Book.prototype.generateBookKey = function(identifier){
return "epubjs:" + EPUBJS.VERSION + ":" + window.location.host + ":" + identifier;
};
EPUBJS.Book.prototype.saveContents = function(){
var contentsKey = this.settings.bookPath + ":contents:" + this.settings.version;
localStorage.setItem(contentsKey, JSON.stringify(this.contents));
localStorage.setItem(this.settings.bookKey, JSON.stringify(this.contents));
};
EPUBJS.Book.prototype.removeSavedContents = function() {
var bookKey = this.settings.bookPath + ":contents:" + this.settings.version;
localStorage.removeItem(bookKey);
localStorage.removeItem(this.settings.bookKey);
};
// EPUBJS.Book.prototype.chapterTitle = function(){
// return this.spine[this.spinePos].id; //-- TODO: clarify that this is returning title
// }
@ -2220,14 +2213,13 @@ EPUBJS.Book.prototype.startDisplay = function(){
return display;
};
EPUBJS.Book.prototype.restore = function(_reject){
EPUBJS.Book.prototype.restore = function(identifier){
var book = this,
contentsKey = this.settings.bookPath + ":contents:" + this.settings.version,
deferred = new RSVP.defer(),
fetch = ['manifest', 'spine', 'metadata', 'cover', 'toc', 'spineNodeIndex', 'spineIndexByURL'],
reject = _reject || false,
fromStore = localStorage.getItem(contentsKey);
fetch = ['manifest', 'spine', 'metadata', 'cover', 'toc', 'spineNodeIndex', 'spineIndexByURL'],
reject = false,
bookKey = this.setBookKey(identifier),
fromStore = localStorage.getItem(bookKey);
if(this.settings.clearSaved) reject = true;
@ -2242,17 +2234,14 @@ EPUBJS.Book.prototype.restore = function(_reject){
}
if(reject || !fromStore || !this.contents || !this.settings.contentsPath){
// this.removeSavedSettings();
return this.open(this.settings.bookPath, true);
return false;
}else{
this.ready.manifest.resolve(this.manifest);
this.ready.spine.resolve(this.spine);
this.ready.metadata.resolve(this.metadata);
this.ready.cover.resolve(this.cover);
this.ready.toc.resolve(this.toc);
deferred.resolve();
return deferred.promise;
return true;
}
};
@ -2280,15 +2269,15 @@ EPUBJS.Book.prototype.displayChapter = function(chap, end){
}
if(pos < 0 || pos >= this.spine.length){
console.error("Not A Valid Chapter");
return false;
console.warn("Not A Valid Location");
pos = 0;
end = false;
cfi = false;
}
//-- Set the book's spine position
this.spinePos = pos;
//-- Create a new chapter
this.chapter = new EPUBJS.Chapter(this.spine[pos]);
@ -2477,7 +2466,6 @@ EPUBJS.Book.prototype.removeStyle = function(style) {
EPUBJS.Book.prototype.unload = function(){
if(this.settings.restore) {
this.saveSettings();
this.saveContents();
}
@ -2598,7 +2586,7 @@ RSVP.configure('instrument', true); //-- true | will logging out all RSVP reject
// RSVP.on('chained', listener);
// RSVP.on('fulfilled', listener);
RSVP.on('rejected', function(event){
console.error(event.detail, event.detail.message);
console.error(event.detail.message, event.detail.stack);
});
EPUBJS.Chapter = function(spineObject){
@ -2971,6 +2959,7 @@ EPUBJS.EpubCFI.prototype.getOffset = function(cfiStr) {
EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
var cfi = {},
chapSegment,
chapId,
path,
end,
@ -2978,8 +2967,13 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
cfi.chapter = this.getChapter(cfiStr);
chapSegment = parseInt(cfi.chapter.split("/")[2]) || false;
cfi.fragment = this.getFragment(cfiStr);
cfi.spinePos = (parseInt(cfi.chapter.split("/")[2]) / 2 - 1 ) || 0;
if(!chapSegment || !cfi.fragment) return {spinePos: -1};
cfi.spinePos = (parseInt(chapSegment) / 2 - 1 ) || 0;
chapId = cfi.chapter.match(/\[(.*)\]/);
@ -3154,19 +3148,24 @@ EPUBJS.Parser.prototype.container = function(containerXml){
};
};
EPUBJS.Parser.prototype.package = function(packageXml, baseUrl){
EPUBJS.Parser.prototype.identifier = function(packageXml){
var metadataNode = packageXml.querySelector("metadata");
return this.getElementText(metadataNode, "identifier");
};
EPUBJS.Parser.prototype.packageContents = function(packageXml, baseUrl){
var parse = this;
if(baseUrl) this.baseUrl = baseUrl;
var metadataNode = packageXml.querySelector("metadata"),
manifestNode = packageXml.querySelector("manifest"),
spineNode = packageXml.querySelector("spine");
manifestNode = packageXml.querySelector("manifest"),
spineNode = packageXml.querySelector("spine");
var manifest = parse.manifest(manifestNode),
navPath = parse.findNavPath(manifestNode),
tocPath = parse.findTocPath(manifestNode),
coverPath = parse.findCoverPath(manifestNode);
navPath = parse.findNavPath(manifestNode),
tocPath = parse.findTocPath(manifestNode),
coverPath = parse.findCoverPath(manifestNode);
var spineNodeIndex = Array.prototype.indexOf.call(spineNode.parentNode.childNodes, spineNode);
@ -3210,7 +3209,7 @@ EPUBJS.Parser.prototype.findCoverPath = function(manifestNode){
//-- Expanded to match Readium web components
EPUBJS.Parser.prototype.metadata = function(xml){
var metadata = {},
p = this;
p = this;
metadata.bookTitle = p.getElementText(xml, 'title');
metadata.creator = p.getElementText(xml, 'creator');
@ -3261,7 +3260,7 @@ EPUBJS.Parser.prototype.querySelectorText = function(xml, q){
EPUBJS.Parser.prototype.manifest = function(manifestXml){
var baseUrl = this.baseUrl,
manifest = {};
manifest = {};
//-- Turn items into an array
var selected = manifestXml.querySelectorAll("item"),
@ -3270,9 +3269,9 @@ EPUBJS.Parser.prototype.manifest = function(manifestXml){
//-- Create an object with the id as key
items.forEach(function(item){
var id = item.getAttribute('id'),
href = item.getAttribute('href') || '',
type = item.getAttribute('media-type') || '',
properties = item.getAttribute('properties') || '';
href = item.getAttribute('href') || '',
type = item.getAttribute('media-type') || '',
properties = item.getAttribute('properties') || '';
manifest[id] = {
'href' : href,
@ -3291,7 +3290,7 @@ EPUBJS.Parser.prototype.spine = function(spineXml, manifest){
var spine = [];
var selected = spineXml.getElementsByTagName("itemref"),
items = Array.prototype.slice.call(selected);
items = Array.prototype.slice.call(selected);
//-- Add to array to mantain ordering and cross reference with manifest
items.forEach(function(item, index){
@ -3313,7 +3312,7 @@ EPUBJS.Parser.prototype.spine = function(spineXml, manifest){
EPUBJS.Parser.prototype.nav = function(navHtml, spineIndexByURL, bookSpine){
var navEl = navHtml.querySelector('nav'), //-- [*|type="toc"] * Doesn't seem to work
idCounter = 0;
idCounter = 0;
if(!navEl) return [];
@ -3350,10 +3349,10 @@ EPUBJS.Parser.prototype.nav = function(navHtml, spineIndexByURL, bookSpine){
function getTOC(parent){
var list = [],
nodes = findListItems(parent),
items = Array.prototype.slice.call(nodes),
length = items.length,
node;
nodes = findListItems(parent),
items = Array.prototype.slice.call(nodes),
length = items.length,
node;
if(length === 0) return false;
@ -3400,12 +3399,12 @@ EPUBJS.Parser.prototype.toc = function(tocXml, spineIndexByURL, bookSpine){
function getTOC(parent){
var list = [],
items = [],
nodes = parent.childNodes,
nodesArray = Array.prototype.slice.call(nodes),
length = nodesArray.length,
iter = length,
node;
items = [],
nodes = parent.childNodes,
nodesArray = Array.prototype.slice.call(nodes),
length = nodesArray.length,
iter = length,
node;
if(length === 0) return false;
@ -3419,15 +3418,15 @@ EPUBJS.Parser.prototype.toc = function(tocXml, spineIndexByURL, bookSpine){
items.forEach(function(item){
var id = item.getAttribute('id') || false,
content = item.querySelector("content"),
src = content.getAttribute('src'),
navLabel = item.querySelector("navLabel"),
text = navLabel.textContent ? navLabel.textContent : "",
split = src.split("#"),
baseUrl = split[0],
spinePos = spineIndexByURL[baseUrl],
spineItem,
subitems = getTOC(item);
content = item.querySelector("content"),
src = content.getAttribute('src'),
navLabel = item.querySelector("navLabel"),
text = navLabel.textContent ? navLabel.textContent : "",
split = src.split("#"),
baseUrl = split[0],
spinePos = spineIndexByURL[baseUrl],
spineItem,
subitems = getTOC(item);
if(!id) {
if(spinePos) {

4
build/epub.min.js vendored

File diff suppressed because one or more lines are too long

View file

@ -1,5 +1,5 @@
EPUBJS.reader = {};
EPUBJS.reader.plugins = {}; //-- Attach extra view as plugins (like search?)
EPUBJS.reader.plugins = {}; //-- Attach extra Controllers as plugins (like search?)
(function(root) {
@ -26,47 +26,286 @@ EPUBJS.reader.plugins = {}; //-- Attach extra view as plugins (like search?)
})(window);
EPUBJS.Reader = function(path, options) {
EPUBJS.Reader = function(path, _options) {
var reader = this;
var settings = _.defaults(options || {}, {
restore: true
});
var book = this.book = ePub(path, settings);
var book;
this.settings = _.defaults(_options || {}, {
restore: true,
bookmarks: null
});
this.setBookKey(path); //-- This could be username + path or any unique string
if(this.settings.restore && this.isSaved()) {
this.applySavedSettings();
}
this.book = book = new EPUBJS.Book({
bookPath: path,
restore: this.settings.restore,
previousLocationCfi: this.settings.previousLocationCfi
});
this.settings = settings;
this.offline = false;
this.sidebarOpen = false;
if(!this.settings.bookmarks) {
this.settings.bookmarks = [];
}
book.renderTo("viewer");
reader.SettingsView = EPUBJS.reader.SettingsView.call(reader, book);
reader.ControlsView = EPUBJS.reader.ControlsView.call(reader, book);
reader.SidebarView = EPUBJS.reader.SidebarView.call(reader, book);
reader.ReaderController = EPUBJS.reader.ReaderController.call(reader, book);
reader.SettingsController = EPUBJS.reader.SettingsController.call(reader, book);
reader.ControlsController = EPUBJS.reader.ControlsController.call(reader, book);
reader.SidebarController = EPUBJS.reader.SidebarController.call(reader, book);
reader.BookmarksController = EPUBJS.reader.BookmarksController.call(reader, book);
// Call Plugins
for(var plugin in EPUBJS.reader.plugins) {
if(EPUBJS.reader.plugins.hasOwnProperty(plugin)) {
reader[plugin] = EPUBJS.reader.plugins[plugin].call(reader, book);
}
}
book.ready.all.then(function() {
reader.ReaderView = EPUBJS.reader.ReaderView.call(reader, book);
// Call Plugins
for(var plugin in EPUBJS.reader.plugins) {
if(EPUBJS.reader.plugins.hasOwnProperty(plugin)) {
reader[plugin] = EPUBJS.reader.plugins[plugin].call(reader, book);
}
}
reader.ReaderController.hideLoader();
});
book.getMetadata().then(function(meta) {
reader.MetaView = EPUBJS.reader.MetaView.call(reader, meta);
reader.MetaController = EPUBJS.reader.MetaController.call(reader, meta);
});
book.getToc().then(function(toc) {
reader.TocView = EPUBJS.reader.TocView.call(reader, toc);
reader.TocController = EPUBJS.reader.TocController.call(reader, toc);
});
window.addEventListener("beforeunload", this.unload.bind(this), false);
return this;
};
EPUBJS.reader.MetaView = function(meta) {
EPUBJS.Reader.prototype.addBookmark = function(cfi) {
var present = this.isBookmarked(cfi);
if(present > -1 ) return;
this.settings.bookmarks.push(cfi);
this.trigger("reader:bookmarked", cfi);
};
EPUBJS.Reader.prototype.removeBookmark = function(cfi) {
var bookmark = this.isBookmarked(cfi);
if(!bookmark === -1 ) return;
delete this.settings.bookmarks[bookmark];
};
EPUBJS.Reader.prototype.isBookmarked = function(cfi) {
var bookmarks = this.settings.bookmarks;
return bookmarks.indexOf(cfi);
};
/*
EPUBJS.Reader.prototype.searchBookmarked = function(cfi) {
var bookmarks = this.settings.bookmarks,
len = bookmarks.length;
for(var i = 0; i < len; i++) {
if (bookmarks[i]['cfi'] === cfi) return i;
}
return -1;
};
*/
EPUBJS.Reader.prototype.clearBookmarks = function() {
this.settings.bookmarks = [];
};
//-- Settings
EPUBJS.Reader.prototype.setBookKey = function(identifier){
if(!this.settings.bookKey) {
this.settings.bookKey = "epubjsreader:" + EPUBJS.VERSION + ":" + window.location.host + ":" + identifier;
}
return this.settings.bookKey;
};
//-- Checks if the book setting can be retrieved from localStorage
EPUBJS.Reader.prototype.isSaved = function(bookPath) {
var storedSettings = localStorage.getItem(this.settings.bookKey);
if( !localStorage ||
storedSettings === null) {
return false;
} else {
return true;
}
};
EPUBJS.Reader.prototype.removeSavedSettings = function() {
localStorage.removeItem(this.settings.bookKey);
};
EPUBJS.Reader.prototype.applySavedSettings = function() {
var stored = JSON.parse(localStorage.getItem(this.settings.bookKey));
if(stored) {
this.settings = _.defaults(this.settings, stored);
return true;
} else {
return false;
}
};
EPUBJS.Reader.prototype.saveSettings = function(){
if(this.book) {
this.settings.previousLocationCfi = this.book.getCurrentLocationCfi();
}
localStorage.setItem(this.settings.bookKey, JSON.stringify(this.settings));
};
EPUBJS.Reader.prototype.unload = function(){
if(this.settings.restore) {
this.saveSettings();
}
};
//-- Enable binding events to reader
RSVP.EventTarget.mixin(EPUBJS.Reader.prototype);
EPUBJS.reader.BookmarksController = function() {
var book = this.book;
var $bookmarks = $("#bookmarksView"),
$list = $bookmarks.find("#bookmarks");
var docfrag = document.createDocumentFragment();
var show = function() {
$bookmarks.show();
};
var hide = function() {
$bookmarks.hide();
};
var createBookmarkItem = function(cfi) {
var listitem = document.createElement("li"),
link = document.createElement("a");
listitem.classList.add('list_item');
//-- TODO: Parse Cfi
link.textContent = cfi;
link.href = cfi;
link.classList.add('bookmark_link');
link.addEventListener("click", function(event){
var cfi = this.getAttribute('href');
book.gotoCfi(cfi);
event.preventDefault();
}, false);
listitem.appendChild(link);
return listitem;
};
this.settings.bookmarks.forEach(function(cfi) {
var bookmark = createBookmarkItem(cfi);
docfrag.appendChild(bookmark);
});
$list.append(docfrag);
this.on("reader:bookmarked", function(cfi) {
var item = createBookmarkItem(cfi);
$list.append(item);
});
return {
"show" : show,
"hide" : hide
};
};
EPUBJS.reader.ControlsController = function(book) {
var reader = this;
var $store = $("#store"),
$fullscreen = $("#fullscreen"),
$fullscreenicon = $("#fullscreenicon"),
$cancelfullscreenicon = $("#cancelfullscreenicon"),
$slider = $("#slider"),
$main = $("#main"),
$sidebar = $("#sidebar"),
$settings = $("#setting"),
$bookmark = $("#bookmark");
var goOnline = function() {
reader.offline = false;
// $store.attr("src", $icon.data("save"));
};
var goOffline = function() {
reader.offline = true;
// $store.attr("src", $icon.data("saved"));
};
book.on("book:online", goOnline);
book.on("book:offline", goOffline);
$slider.on("click", function () {
if(reader.sidebarOpen) {
reader.SidebarController.hide();
$slider.addClass("icon-menu");
$slider.removeClass("icon-right");
} else {
reader.SidebarController.show();
$slider.addClass("icon-right");
$slider.removeClass("icon-menu");
}
});
$fullscreen.on("click", function() {
screenfull.toggle($('#container')[0]);
$fullscreenicon.toggle();
$cancelfullscreenicon.toggle();
});
$settings.on("click", function() {
reader.SettingsController.show();
});
$bookmark.on("click", function() {
$bookmark.addClass("icon-bookmark");
$bookmark.removeClass("icon-bookmark-empty");
reader.addBookmark(reader.book.getCurrentLocationCfi());
});
book.on('renderer:pageChanged', function(cfi){
//-- Check if bookmarked
var bookmarked = reader.isBookmarked(cfi);
if(bookmarked === -1) { //-- Not bookmarked
$bookmark
.removeClass("icon-bookmark")
.addClass("icon-bookmark-empty");
} else { //-- Bookmarked
$bookmark
.addClass("icon-bookmark")
.removeClass("icon-bookmark-empty");
}
});
return {
};
};
EPUBJS.reader.MetaController = function(meta) {
var title = meta.bookTitle,
author = meta.creator;
@ -80,8 +319,7 @@ EPUBJS.reader.MetaView = function(meta) {
$author.html(author);
$dash.show();
};
EPUBJS.reader.ReaderView = function(book) {
EPUBJS.reader.ReaderController = function(book) {
var $main = $("#main"),
$divider = $("#divider"),
$loader = $("#loader"),
@ -98,10 +336,16 @@ EPUBJS.reader.ReaderView = function(book) {
var showLoader = function() {
$loader.show();
hideDivider();
};
var hideLoader = function() {
$loader.hide();
//-- If the book is using spreads, show the divider
if(!book.single) {
showDivider();
}
};
var showDivider = function() {
@ -153,14 +397,6 @@ EPUBJS.reader.ReaderView = function(book) {
e.preventDefault();
});
//-- Hide the spinning loader
hideLoader();
//-- If the book is using spreads, show the divider
if(!book.single) {
showDivider();
}
return {
"slideOut" : slideOut,
"slideIn" : slideIn,
@ -170,34 +406,66 @@ EPUBJS.reader.ReaderView = function(book) {
"hideDivider" : hideDivider
};
};
EPUBJS.reader.SettingsController = function() {
var book = this.book;
EPUBJS.reader.SidebarView = function(book) {
var $settings = $("#settings-modal"),
$overlay = $(".overlay");
var show = function() {
$settings.addClass("md-show");
};
var hide = function() {
$settings.removeClass("md-show");
};
$settings.find(".closer").on("click", function() {
hide();
});
$overlay.on("click", function() {
hide();
});
return {
"show" : show,
"hide" : hide
};
};
EPUBJS.reader.SidebarController = function(book) {
var reader = this;
var $sidebar = $("#sidebar"),
$panels = $("#panels");
var activePanel = "TocView";
var activePanel = "Toc";
var changePanelTo = function(viewName) {
if(activePanel == viewName || typeof reader[viewName] === 'undefined' ) return;
reader[activePanel].hide();
reader[viewName].show();
var controllerName = viewName + "Controller";
if(activePanel == viewName || typeof reader[controllerName] === 'undefined' ) return;
reader[activePanel+ "Controller"].hide();
reader[controllerName].show();
activePanel = viewName;
$panels.find('.active').removeClass("active");
$panels.find("#show-" + viewName ).addClass("active");
};
var getActivePanel = function() {
return activePanel;
};
var show = function() {
reader.sidebarOpen = true;
reader.ReaderView.slideOut();
reader.ReaderController.slideOut();
$sidebar.addClass("open");
}
var hide = function() {
reader.sidebarOpen = false;
reader.ReaderView.slideIn();
reader.ReaderController.slideIn();
$sidebar.removeClass("open");
}
@ -211,78 +479,11 @@ EPUBJS.reader.SidebarView = function(book) {
return {
'show' : show,
'hide' : hide,
'activePanel' : activePanel,
'getActivePanel' : getActivePanel,
'changePanelTo' : changePanelTo
};
};
EPUBJS.reader.ControlsView = function(book) {
var reader = this;
var $store = $("#store"),
$fullscreen = $("#fullscreen"),
$fullscreenicon = $("#fullscreenicon"),
$cancelfullscreenicon = $("#cancelfullscreenicon"),
$slider = $("#slider"),
$main = $("#main"),
$sidebar = $("#sidebar"),
$settings = $("#settings"),
$bookmark = $("#bookmark");
var goOnline = function() {
reader.offline = false;
// $store.attr("src", $icon.data("save"));
};
var goOffline = function() {
reader.offline = true;
// $store.attr("src", $icon.data("saved"));
};
book.on("book:online", goOnline);
book.on("book:offline", goOffline);
$slider.on("click", function () {
if(reader.sidebarOpen) {
reader.SidebarView.hide();
$slider.addClass("icon-menu");
$slider.removeClass("icon-right");
} else {
reader.SidebarView.show();
$slider.addClass("icon-right");
$slider.removeClass("icon-menu");
}
});
$fullscreen.on("click", function() {
screenfull.toggle($('#container')[0]);
$fullscreenicon.toggle();
$cancelfullscreenicon.toggle();
});
$settings.on("click", function() {
reader.SettingsView.show();
});
$bookmark.on("click", function() {
$bookmark.addClass("icon-bookmark");
$bookmark.removeClass("icon-bookmark-empty");
console.log(reader.book.getCurrentLocationCfi());
});
book.on('renderer:pageChanged', function(cfi){
//-- TODO: Check if bookmarked
$bookmark
.removeClass("icon-bookmark")
.addClass("icon-bookmark-empty");
});
return {
};
};
EPUBJS.reader.TocView = function(toc) {
EPUBJS.reader.TocController = function(toc) {
var book = this.book;
var $list = $("#tocView"),
@ -299,12 +500,15 @@ EPUBJS.reader.TocView = function(toc) {
var listitem = document.createElement("li"),
link = document.createElement("a");
toggle = document.createElement("a");
var subitems;
listitem.id = "toc-"+chapter.id;
listitem.classList.add('list_item');
link.textContent = chapter.label;
link.href = chapter.href;
link.classList.add('toc_link');
listitem.appendChild(link);
@ -393,22 +597,3 @@ EPUBJS.reader.TocView = function(toc) {
"hide" : onHide
};
};
EPUBJS.reader.SettingsView = function() {
var book = this.book;
var $settings = $("#settingsPanel");
var onShow = function() {
$settings.show();
};
var onHide = function() {
$settings.hide();
};
return {
"show" : onShow,
"hide" : onHide
};
};

View file

@ -260,7 +260,8 @@ input:-moz-placeholder {
margin: -33px 0 0 -33px;
}
#tocView {
#tocView,
#bookmarksView {
overflow-x: hidden;
overflow-y: hidden;
width: 300px;
@ -273,21 +274,24 @@ input:-moz-placeholder {
#sidebar.open #tocView {
#sidebar.open #tocView,
#sidebar.open #bookmarksView {
overflow-y: auto;
visibility: visible;
-webkit-transition: visibility 0 ease 0;
-moz-transition: visibility 0 ease 0;
}
#tocView > ul{
#tocView > ul,
#bookmarksView > ul {
margin-top: 15px;
margin-bottom: 50px;
padding-left: 20px;
display: block;
}
#tocView li {
#tocView li,
#bookmarksView li {
margin-bottom:10px;
width: 225px;
font-family: Georgia, "Times New Roman", Times, serif;
@ -301,37 +305,37 @@ input:-moz-placeholder {
list-style: none;
}
#tocView a {
.list_item a {
color: #AAA;
text-decoration: none;
}
#tocView a.chapter {
.list_item a.chapter {
font-size: 1em;
}
#tocView a.section {
.list_item a.section {
font-size: .8em;
}
#tocView li.currentChapter > a,
#tocView li a:hover {
.list_item.currentChapter > a,
.list_item a:hover {
color: #f1f1f1
}
/* #tocView li.openChapter > a, */
#tocView li a:hover {
.list_item a:hover {
color: #E2E2E2;
}
#tocView li ul {
.list_item ul {
padding-left:10px;
margin-top: 8px;
display: none;
}
#tocView li.currentChapter > ul,
#tocView li.openChapter > ul {
.list_item.currentChapter > ul,
.list_item.openChapter > ul {
display: block;
}

View file

@ -66,6 +66,13 @@
<!-- Reader -->
<script src="../reader/reader.js"></script>
<script src="../reader/controllers/bookmarks_controller.js"></script>
<script src="../reader/controllers/controls_controller.js"></script>
<script src="../reader/controllers/meta_controller.js"></script>
<script src="../reader/controllers/reader_controller.js"></script>
<script src="../reader/controllers/settings_controller.js"></script>
<script src="../reader/controllers/sidebar_controller.js"></script>
<script src="../reader/controllers/toc_controller.js"></script>
<!-- Full Screen -->
<script src="js/libs/screenfull.min.js"></script>
@ -80,10 +87,10 @@
<div id="panels">
<input id="searchBox" placeholder="search" type="search">
<a id="show-SearchView" class="show_view icon-search" data-view="SearchView">Search</a>
<a id="show-TocView" class="show_view icon-list-1 active" data-view="TocView">TOC</a>
<a id="show-BookmarksView" class="show_view icon-bookmark" data-view="BookmarksView">Bookmarks</a>
<a id="show-NotesView" class="show_view icon-edit" data-view="NotesView">Notes</a>
<a id="show-Search" class="show_view icon-search" data-view="Search">Search</a>
<a id="show-Toc" class="show_view icon-list-1 active" data-view="Toc">TOC</a>
<a id="show-Bookmarks" class="show_view icon-bookmark" data-view="Bookmarks">Bookmarks</a>
<a id="show-Notes" class="show_view icon-edit" data-view="Notes">Notes</a>
</div>
<div id="tocView">
@ -91,9 +98,9 @@
<div id="searchView">
<ul id="searchResults"></ul>
</div>
<div id="settingsPanel">
<div id="bookmarksView">
<ul id="bookmarks"></ul>
</div>
</div>
<div id="main">

View file

@ -54,10 +54,10 @@
<div id="panels">
<input id="searchBox" placeholder="search" type="search">
<a id="show-SearchView" class="show_view icon-search" data-view="SearchView">Search</a>
<a id="show-TocView" class="show_view icon-list-1 active" data-view="TocView">TOC</a>
<a id="show-BookmarksView" class="show_view icon-bookmark" data-view="BookmarksView">Bookmarks</a>
<a id="show-NotesView" class="show_view icon-edit" data-view="NotesView">Notes</a>
<a id="show-Search" class="show_view icon-search" data-view="Search">Search</a>
<a id="show-Toc" class="show_view icon-list-1 active" data-view="Toc">TOC</a>
<a id="show-Bookmarks" class="show_view icon-bookmark" data-view="Bookmarks">Bookmarks</a>
<a id="show-Notes" class="show_view icon-edit" data-view="Notes">Notes</a>
</div>
<div id="tocView">
@ -65,9 +65,9 @@
<div id="searchView">
<ul id="searchResults"></ul>
</div>
<div id="settingsPanel">
<div id="bookmarksView">
<ul id="bookmarks"></ul>
</div>
</div>
<div id="main">
@ -94,5 +94,15 @@
<div id="loader"><img src="../demo/img/loader.gif"></div>
</div>
<div class="modal md-effect-1" id="settings-modal">
<div class="md-content">
<h3>Settings</h3>
<div>
<p></p>
</div>
<div class="closer icon-cancel-circled"></div>
</div>
</div>
<div class="overlay"></div>
</body>
</html>

4
demo/js/epub.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -31,51 +31,26 @@
}
};
</script>
<!--<script async src="epubjs/libs/jquery.touchy.min.js"></script>-->
<!-- zip -->
<script src="../libs/zip/zip.js"></script>
<script src="../libs/zip/zip-fs.js"></script>
<script src="../libs/zip/zip-ext.js"></script>
<script src="../libs/zip/inflate.js"></script>
<script src="../libs/zip/mime-types.js"></script>
</script>
<!-- Render -->
<script src="../libs/underscore/underscore.js"></script>
<script src="../libs/rsvp/rsvp.js"></script>
<script src="../libs/fileStorage/fileStorage.min.js"></script>
<script src="../src/base.js"></script>
<script src="../src/core.js"></script>
<script src="../src/unarchiver.js"></script>
<script src="../src/parser.js"></script>
<script src="../src/hooks.js"></script>
<script src="../src/book.js"></script>
<script src="../src/chapter.js"></script>
<script src="../src/renderer.js"></script>
<script src="../src/epubcfi.js"></script>
<script src="../demo/js/epub.min.js"></script>
<!-- Hooks -->
<script async src="../hooks/default/transculsions.js"></script>
<script async src="../hooks/default/endnotes.js"></script>
<script async src="../hooks/default/smartimages.js"></script>
<script async src="../hooks/default/pageturns.js"></script>
<script src="../demo/js/hooks.min.js"></script>
<!-- Reader -->
<script src="../reader/reader.js"></script>
<script src="../demo/js/reader.min.js"></script>
<!-- Plugins -->
<script src="../reader/search.js"></script>
<script src="../reader/plugins/search.js"></script>
<!-- Full Screen -->
<script src="../demo/js/libs/screenfull.min.js"></script>
<!-- Highlights -->
<script src="../demo/js/libs/jquery.highlight.js"></script>
<script async src="../hooks/extensions/highlight.js"></script>
<script src="../hooks/extensions/highlight.js"></script>
</head>
<body>
@ -83,10 +58,10 @@
<div id="panels">
<input id="searchBox" placeholder="search" type="search">
<a id="show-SearchView" class="show_view icon-search" data-view="SearchView">Search</a>
<a id="show-TocView" class="show_view icon-list-1 active" data-view="TocView">TOC</a>
<a id="show-BookmarksView" class="show_view icon-bookmark" data-view="BookmarksView">Bookmarks</a>
<a id="show-NotesView" class="show_view icon-edit" data-view="NotesView">Notes</a>
<a id="show-Search" class="show_view icon-search" data-view="Search">Search</a>
<a id="show-Toc" class="show_view icon-list-1 active" data-view="Toc">TOC</a>
<a id="show-Bookmarks" class="show_view icon-bookmark" data-view="Bookmarks">Bookmarks</a>
<a id="show-Notes" class="show_view icon-edit" data-view="Notes">Notes</a>
</div>
<div id="tocView">
@ -94,9 +69,9 @@
<div id="searchView">
<ul id="searchResults"></ul>
</div>
<div id="settingsPanel">
<div id="bookmarksView">
<ul id="bookmarks"></ul>
</div>
</div>
<div id="main">
@ -123,5 +98,14 @@
<div id="loader"><img src="../demo/img/loader.gif"></div>
</div>
<div class="modal md-effect-1" id="settings-modal">
<div class="md-content">
<h3>Settings</h3>
<div>
</div>
<div class="closer icon-cancel-circled"></div>
</div>
</div>
<div class="overlay"></div>
</body>
</html>

View file

@ -0,0 +1,57 @@
EPUBJS.reader.BookmarksController = function() {
var book = this.book;
var $bookmarks = $("#bookmarksView"),
$list = $bookmarks.find("#bookmarks");
var docfrag = document.createDocumentFragment();
var show = function() {
$bookmarks.show();
};
var hide = function() {
$bookmarks.hide();
};
var createBookmarkItem = function(cfi) {
var listitem = document.createElement("li"),
link = document.createElement("a");
listitem.classList.add('list_item');
//-- TODO: Parse Cfi
link.textContent = cfi;
link.href = cfi;
link.classList.add('bookmark_link');
link.addEventListener("click", function(event){
var cfi = this.getAttribute('href');
book.gotoCfi(cfi);
event.preventDefault();
}, false);
listitem.appendChild(link);
return listitem;
};
this.settings.bookmarks.forEach(function(cfi) {
var bookmark = createBookmarkItem(cfi);
docfrag.appendChild(bookmark);
});
$list.append(docfrag);
this.on("reader:bookmarked", function(cfi) {
var item = createBookmarkItem(cfi);
$list.append(item);
});
return {
"show" : show,
"hide" : hide
};
};

View file

@ -0,0 +1,74 @@
EPUBJS.reader.ControlsController = function(book) {
var reader = this;
var $store = $("#store"),
$fullscreen = $("#fullscreen"),
$fullscreenicon = $("#fullscreenicon"),
$cancelfullscreenicon = $("#cancelfullscreenicon"),
$slider = $("#slider"),
$main = $("#main"),
$sidebar = $("#sidebar"),
$settings = $("#setting"),
$bookmark = $("#bookmark");
var goOnline = function() {
reader.offline = false;
// $store.attr("src", $icon.data("save"));
};
var goOffline = function() {
reader.offline = true;
// $store.attr("src", $icon.data("saved"));
};
book.on("book:online", goOnline);
book.on("book:offline", goOffline);
$slider.on("click", function () {
if(reader.sidebarOpen) {
reader.SidebarController.hide();
$slider.addClass("icon-menu");
$slider.removeClass("icon-right");
} else {
reader.SidebarController.show();
$slider.addClass("icon-right");
$slider.removeClass("icon-menu");
}
});
$fullscreen.on("click", function() {
screenfull.toggle($('#container')[0]);
$fullscreenicon.toggle();
$cancelfullscreenicon.toggle();
});
$settings.on("click", function() {
reader.SettingsController.show();
});
$bookmark.on("click", function() {
$bookmark.addClass("icon-bookmark");
$bookmark.removeClass("icon-bookmark-empty");
reader.addBookmark(reader.book.getCurrentLocationCfi());
});
book.on('renderer:pageChanged', function(cfi){
//-- Check if bookmarked
var bookmarked = reader.isBookmarked(cfi);
if(bookmarked === -1) { //-- Not bookmarked
$bookmark
.removeClass("icon-bookmark")
.addClass("icon-bookmark-empty");
} else { //-- Bookmarked
$bookmark
.addClass("icon-bookmark")
.removeClass("icon-bookmark-empty");
}
});
return {
};
};

View file

@ -0,0 +1,14 @@
EPUBJS.reader.MetaController = function(meta) {
var title = meta.bookTitle,
author = meta.creator;
var $title = $("#book-title"),
$author = $("#chapter-title"),
$dash = $("#title-seperator");
document.title = title+" "+author;
$title.html(title);
$author.html(author);
$dash.show();
};

View file

@ -0,0 +1,87 @@
EPUBJS.reader.ReaderController = function(book) {
var $main = $("#main"),
$divider = $("#divider"),
$loader = $("#loader"),
$next = $("#next"),
$prev = $("#prev");
var slideIn = function() {
$main.removeClass("closed");
};
var slideOut = function() {
$main.addClass("closed");
};
var showLoader = function() {
$loader.show();
hideDivider();
};
var hideLoader = function() {
$loader.hide();
//-- If the book is using spreads, show the divider
if(!book.single) {
showDivider();
}
};
var showDivider = function() {
$divider.addClass("show");
};
var hideDivider = function() {
$divider.removeClass("show");
};
var keylock = false;
var arrowKeys = function(e) {
if(e.keyCode == 37) {
book.prevPage();
$prev.addClass("active");
keylock = true;
setTimeout(function(){
keylock = false;
$prev.removeClass("active");
}, 100);
e.preventDefault();
}
if(e.keyCode == 39) {
book.nextPage();
$next.addClass("active");
keylock = true;
setTimeout(function(){
keylock = false;
$next.removeClass("active");
}, 100);
e.preventDefault();
}
}
document.addEventListener('keydown', arrowKeys, false);
$next.on("click", function(e){
book.nextPage();
e.preventDefault();
});
$prev.on("click", function(e){
book.prevPage();
e.preventDefault();
});
return {
"slideOut" : slideOut,
"slideIn" : slideIn,
"showLoader" : showLoader,
"hideLoader" : hideLoader,
"showDivider" : showDivider,
"hideDivider" : hideDivider
};
};

View file

@ -0,0 +1,27 @@
EPUBJS.reader.SettingsController = function() {
var book = this.book;
var $settings = $("#settings-modal"),
$overlay = $(".overlay");
var show = function() {
$settings.addClass("md-show");
};
var hide = function() {
$settings.removeClass("md-show");
};
$settings.find(".closer").on("click", function() {
hide();
});
$overlay.on("click", function() {
hide();
});
return {
"show" : show,
"hide" : hide
};
};

View file

@ -0,0 +1,50 @@
EPUBJS.reader.SidebarController = function(book) {
var reader = this;
var $sidebar = $("#sidebar"),
$panels = $("#panels");
var activePanel = "Toc";
var changePanelTo = function(viewName) {
var controllerName = viewName + "Controller";
if(activePanel == viewName || typeof reader[controllerName] === 'undefined' ) return;
reader[activePanel+ "Controller"].hide();
reader[controllerName].show();
activePanel = viewName;
$panels.find('.active').removeClass("active");
$panels.find("#show-" + viewName ).addClass("active");
};
var getActivePanel = function() {
return activePanel;
};
var show = function() {
reader.sidebarOpen = true;
reader.ReaderController.slideOut();
$sidebar.addClass("open");
}
var hide = function() {
reader.sidebarOpen = false;
reader.ReaderController.slideIn();
$sidebar.removeClass("open");
}
$panels.find(".show_view").on("click", function(event) {
var view = $(this).data("view");
changePanelTo(view);
event.preventDefault();
});
return {
'show' : show,
'hide' : hide,
'getActivePanel' : getActivePanel,
'changePanelTo' : changePanelTo
};
};

View file

@ -0,0 +1,114 @@
EPUBJS.reader.TocController = function(toc) {
var book = this.book;
var $list = $("#tocView"),
docfrag = document.createDocumentFragment();
var currentChapter = false;
var generateTocItems = function(toc, level) {
var container = document.createElement("ul");
if(!level) level = 1;
toc.forEach(function(chapter) {
var listitem = document.createElement("li"),
link = document.createElement("a");
toggle = document.createElement("a");
var subitems;
listitem.id = "toc-"+chapter.id;
listitem.classList.add('list_item');
link.textContent = chapter.label;
link.href = chapter.href;
link.classList.add('toc_link');
listitem.appendChild(link);
if(chapter.subitems) {
level++;
subitems = generateTocItems(chapter.subitems, level);
toggle.classList.add('toc_toggle');
listitem.insertBefore(toggle, link);
listitem.appendChild(subitems);
}
container.appendChild(listitem);
});
return container;
};
var onShow = function() {
$list.show();
};
var onHide = function() {
$list.hide();
};
var chapterChange = function(e) {
var id = e.id,
$item = $list.find("#toc-"+id),
$current = $list.find(".currentChapter"),
$open = $list.find('.openChapter');
if($item.length){
if($item != $current && $item.has(currentChapter).length > 0) {
$current.removeClass("currentChapter");
}
$item.addClass("currentChapter");
// $open.removeClass("openChapter");
$item.parents('li').addClass("openChapter");
}
};
book.on('renderer:chapterDisplayed', chapterChange);
var tocitems = generateTocItems(toc);
docfrag.appendChild(tocitems);
$list.append(docfrag);
$list.find(".toc_link").on("click", function(event){
var url = this.getAttribute('href');
//-- Provide the Book with the url to show
// The Url must be found in the books manifest
book.goto(url);
$list.find(".currentChapter")
.addClass("openChapter")
.removeClass("currentChapter");
$(this).parent('li').addClass("currentChapter");
event.preventDefault();
});
$list.find(".toc_toggle").on("click", function(event){
var $el = $(this).parent('li'),
open = $el.hasClass("openChapter");
if(open){
$el.removeClass("openChapter");
} else {
$el.addClass("openChapter");
}
event.preventDefault();
});
return {
"show" : onShow,
"hide" : onHide
};
};

View file

@ -18,12 +18,11 @@ EPUBJS.reader.search.request = function(q, callback) {
});
};
EPUBJS.reader.plugins.SearchView = function(Book) {
EPUBJS.reader.plugins.SearchController = function(Book) {
var reader = this;
var $searchBox = $("#searchBox"),
$searchResults = $("#searchResults"),
$tocView = $("#tocView"),
$searchView = $("#searchView"),
iframeDoc;
@ -103,9 +102,8 @@ EPUBJS.reader.plugins.SearchView = function(Book) {
//-- SearchBox is empty or cleared
if(q == '') {
$searchResults.empty();
if(reader.SidebarView.activePanel != "SearchView") {
reader.SidebarView.changePanelTo("TocView");
if(reader.SidebarController.getActivePanel() == "Search") {
reader.SidebarController.changePanelTo("Toc");
}
$(iframeDoc).find('body').unhighlight();
@ -113,9 +111,7 @@ EPUBJS.reader.plugins.SearchView = function(Book) {
return;
}
if(reader.SidebarView.activePanel != "SearchView") {
reader.SidebarView.changePanelTo("SearchView");
}
reader.SidebarController.changePanelTo("Search");
e.preventDefault();
});

View file

@ -1,5 +1,5 @@
EPUBJS.reader = {};
EPUBJS.reader.plugins = {}; //-- Attach extra view as plugins (like search?)
EPUBJS.reader.plugins = {}; //-- Attach extra Controllers as plugins (like search?)
(function(root) {
@ -26,398 +26,151 @@ EPUBJS.reader.plugins = {}; //-- Attach extra view as plugins (like search?)
})(window);
EPUBJS.Reader = function(path, options) {
EPUBJS.Reader = function(path, _options) {
var reader = this;
var settings = _.defaults(options || {}, {
restore: true
});
var book = this.book = ePub(path, settings);
var book;
this.settings = _.defaults(_options || {}, {
restore: true,
bookmarks: null
});
this.setBookKey(path); //-- This could be username + path or any unique string
if(this.settings.restore && this.isSaved()) {
this.applySavedSettings();
}
this.book = book = new EPUBJS.Book({
bookPath: path,
restore: this.settings.restore,
previousLocationCfi: this.settings.previousLocationCfi
});
this.settings = settings;
this.offline = false;
this.sidebarOpen = false;
if(!this.settings.bookmarks) {
this.settings.bookmarks = [];
}
book.renderTo("viewer");
reader.SettingsView = EPUBJS.reader.SettingsView.call(reader, book);
reader.ControlsView = EPUBJS.reader.ControlsView.call(reader, book);
reader.SidebarView = EPUBJS.reader.SidebarView.call(reader, book);
reader.ReaderController = EPUBJS.reader.ReaderController.call(reader, book);
reader.SettingsController = EPUBJS.reader.SettingsController.call(reader, book);
reader.ControlsController = EPUBJS.reader.ControlsController.call(reader, book);
reader.SidebarController = EPUBJS.reader.SidebarController.call(reader, book);
reader.BookmarksController = EPUBJS.reader.BookmarksController.call(reader, book);
// Call Plugins
for(var plugin in EPUBJS.reader.plugins) {
if(EPUBJS.reader.plugins.hasOwnProperty(plugin)) {
reader[plugin] = EPUBJS.reader.plugins[plugin].call(reader, book);
}
}
book.ready.all.then(function() {
reader.ReaderView = EPUBJS.reader.ReaderView.call(reader, book);
// Call Plugins
for(var plugin in EPUBJS.reader.plugins) {
if(EPUBJS.reader.plugins.hasOwnProperty(plugin)) {
reader[plugin] = EPUBJS.reader.plugins[plugin].call(reader, book);
}
}
reader.ReaderController.hideLoader();
});
book.getMetadata().then(function(meta) {
reader.MetaView = EPUBJS.reader.MetaView.call(reader, meta);
reader.MetaController = EPUBJS.reader.MetaController.call(reader, meta);
});
book.getToc().then(function(toc) {
reader.TocView = EPUBJS.reader.TocView.call(reader, toc);
reader.TocController = EPUBJS.reader.TocController.call(reader, toc);
});
window.addEventListener("beforeunload", this.unload.bind(this), false);
return this;
};
EPUBJS.reader.MetaView = function(meta) {
var title = meta.bookTitle,
author = meta.creator;
EPUBJS.Reader.prototype.addBookmark = function(cfi) {
var present = this.isBookmarked(cfi);
if(present > -1 ) return;
var $title = $("#book-title"),
$author = $("#chapter-title"),
$dash = $("#title-seperator");
this.settings.bookmarks.push(cfi);
document.title = title+" "+author;
$title.html(title);
$author.html(author);
$dash.show();
this.trigger("reader:bookmarked", cfi);
};
EPUBJS.reader.ReaderView = function(book) {
var $main = $("#main"),
$divider = $("#divider"),
$loader = $("#loader"),
$next = $("#next"),
$prev = $("#prev");
EPUBJS.Reader.prototype.removeBookmark = function(cfi) {
var bookmark = this.isBookmarked(cfi);
if(!bookmark === -1 ) return;
var slideIn = function() {
$main.removeClass("closed");
};
var slideOut = function() {
$main.addClass("closed");
};
var showLoader = function() {
$loader.show();
};
var hideLoader = function() {
$loader.hide();
};
var showDivider = function() {
$divider.addClass("show");
};
var hideDivider = function() {
$divider.removeClass("show");
};
var keylock = false;
var arrowKeys = function(e) {
if(e.keyCode == 37) {
book.prevPage();
$prev.addClass("active");
keylock = true;
setTimeout(function(){
keylock = false;
$prev.removeClass("active");
}, 100);
e.preventDefault();
}
if(e.keyCode == 39) {
book.nextPage();
$next.addClass("active");
keylock = true;
setTimeout(function(){
keylock = false;
$next.removeClass("active");
}, 100);
e.preventDefault();
}
}
document.addEventListener('keydown', arrowKeys, false);
$next.on("click", function(e){
book.nextPage();
e.preventDefault();
});
$prev.on("click", function(e){
book.prevPage();
e.preventDefault();
});
//-- Hide the spinning loader
hideLoader();
//-- If the book is using spreads, show the divider
if(!book.single) {
showDivider();
}
return {
"slideOut" : slideOut,
"slideIn" : slideIn,
"showLoader" : showLoader,
"hideLoader" : hideLoader,
"showDivider" : showDivider,
"hideDivider" : hideDivider
};
delete this.settings.bookmarks[bookmark];
};
EPUBJS.reader.SidebarView = function(book) {
var reader = this;
EPUBJS.Reader.prototype.isBookmarked = function(cfi) {
var bookmarks = this.settings.bookmarks;
var $sidebar = $("#sidebar"),
$panels = $("#panels");
var activePanel = "TocView";
var changePanelTo = function(viewName) {
if(activePanel == viewName || typeof reader[viewName] === 'undefined' ) return;
reader[activePanel].hide();
reader[viewName].show();
activePanel = viewName;
$panels.find('.active').removeClass("active");
$panels.find("#show-" + viewName ).addClass("active");
};
var show = function() {
reader.sidebarOpen = true;
reader.ReaderView.slideOut();
$sidebar.addClass("open");
}
var hide = function() {
reader.sidebarOpen = false;
reader.ReaderView.slideIn();
$sidebar.removeClass("open");
}
$panels.find(".show_view").on("click", function(event) {
var view = $(this).data("view");
changePanelTo(view);
event.preventDefault();
});
return {
'show' : show,
'hide' : hide,
'activePanel' : activePanel,
'changePanelTo' : changePanelTo
};
return bookmarks.indexOf(cfi);
};
EPUBJS.reader.ControlsView = function(book) {
var reader = this;
/*
EPUBJS.Reader.prototype.searchBookmarked = function(cfi) {
var bookmarks = this.settings.bookmarks,
len = bookmarks.length;
var $store = $("#store"),
$fullscreen = $("#fullscreen"),
$fullscreenicon = $("#fullscreenicon"),
$cancelfullscreenicon = $("#cancelfullscreenicon"),
$slider = $("#slider"),
$main = $("#main"),
$sidebar = $("#sidebar"),
$settings = $("#setting"),
$bookmark = $("#bookmark");
for(var i = 0; i < len; i++) {
if (bookmarks[i]['cfi'] === cfi) return i;
}
return -1;
};
*/
var goOnline = function() {
reader.offline = false;
// $store.attr("src", $icon.data("save"));
};
EPUBJS.Reader.prototype.clearBookmarks = function() {
this.settings.bookmarks = [];
};
var goOffline = function() {
reader.offline = true;
// $store.attr("src", $icon.data("saved"));
};
//-- Settings
EPUBJS.Reader.prototype.setBookKey = function(identifier){
if(!this.settings.bookKey) {
this.settings.bookKey = "epubjsreader:" + EPUBJS.VERSION + ":" + window.location.host + ":" + identifier;
}
return this.settings.bookKey;
};
book.on("book:online", goOnline);
book.on("book:offline", goOffline);
//-- Checks if the book setting can be retrieved from localStorage
EPUBJS.Reader.prototype.isSaved = function(bookPath) {
var storedSettings = localStorage.getItem(this.settings.bookKey);
$slider.on("click", function () {
if(reader.sidebarOpen) {
reader.SidebarView.hide();
$slider.addClass("icon-menu");
$slider.removeClass("icon-right");
if( !localStorage ||
storedSettings === null) {
return false;
} else {
return true;
}
};
EPUBJS.Reader.prototype.removeSavedSettings = function() {
localStorage.removeItem(this.settings.bookKey);
};
EPUBJS.Reader.prototype.applySavedSettings = function() {
var stored = JSON.parse(localStorage.getItem(this.settings.bookKey));
if(stored) {
this.settings = _.defaults(this.settings, stored);
return true;
} else {
reader.SidebarView.show();
$slider.addClass("icon-right");
$slider.removeClass("icon-menu");
return false;
}
});
$fullscreen.on("click", function() {
screenfull.toggle($('#container')[0]);
$fullscreenicon.toggle();
$cancelfullscreenicon.toggle();
});
$settings.on("click", function() {
reader.SettingsView.show();
});
$bookmark.on("click", function() {
$bookmark.addClass("icon-bookmark");
$bookmark.removeClass("icon-bookmark-empty");
console.log(reader.book.getCurrentLocationCfi());
});
book.on('renderer:pageChanged', function(cfi){
//-- TODO: Check if bookmarked
$bookmark
.removeClass("icon-bookmark")
.addClass("icon-bookmark-empty");
});
return {
};
};
EPUBJS.reader.TocView = function(toc) {
var book = this.book;
EPUBJS.Reader.prototype.saveSettings = function(){
if(this.book) {
this.settings.previousLocationCfi = this.book.getCurrentLocationCfi();
}
var $list = $("#tocView"),
docfrag = document.createDocumentFragment();
var currentChapter = false;
var generateTocItems = function(toc, level) {
var container = document.createElement("ul");
if(!level) level = 1;
toc.forEach(function(chapter) {
var listitem = document.createElement("li"),
link = document.createElement("a");
toggle = document.createElement("a");
var subitems;
listitem.id = "toc-"+chapter.id;
link.textContent = chapter.label;
link.href = chapter.href;
link.classList.add('toc_link');
listitem.appendChild(link);
if(chapter.subitems) {
level++;
subitems = generateTocItems(chapter.subitems, level);
toggle.classList.add('toc_toggle');
listitem.insertBefore(toggle, link);
listitem.appendChild(subitems);
}
container.appendChild(listitem);
});
return container;
};
var onShow = function() {
$list.show();
};
var onHide = function() {
$list.hide();
};
var chapterChange = function(e) {
var id = e.id,
$item = $list.find("#toc-"+id),
$current = $list.find(".currentChapter"),
$open = $list.find('.openChapter');
if($item.length){
if($item != $current && $item.has(currentChapter).length > 0) {
$current.removeClass("currentChapter");
}
$item.addClass("currentChapter");
// $open.removeClass("openChapter");
$item.parents('li').addClass("openChapter");
}
};
book.on('renderer:chapterDisplayed', chapterChange);
var tocitems = generateTocItems(toc);
docfrag.appendChild(tocitems);
$list.append(docfrag);
$list.find(".toc_link").on("click", function(event){
var url = this.getAttribute('href');
//-- Provide the Book with the url to show
// The Url must be found in the books manifest
book.goto(url);
$list.find(".currentChapter")
.addClass("openChapter")
.removeClass("currentChapter");
$(this).parent('li').addClass("currentChapter");
event.preventDefault();
});
$list.find(".toc_toggle").on("click", function(event){
var $el = $(this).parent('li'),
open = $el.hasClass("openChapter");
if(open){
$el.removeClass("openChapter");
} else {
$el.addClass("openChapter");
}
event.preventDefault();
});
return {
"show" : onShow,
"hide" : onHide
};
localStorage.setItem(this.settings.bookKey, JSON.stringify(this.settings));
};
EPUBJS.reader.SettingsView = function() {
var book = this.book;
var $settings = $("#settings-modal"),
$overlay = $(".overlay");
var show = function() {
$settings.addClass("md-show");
};
var hide = function() {
$settings.removeClass("md-show");
};
$settings.find(".closer").on("click", function() {
hide();
});
$overlay.on("click", function() {
hide();
});
return {
"show" : show,
"hide" : hide
};
EPUBJS.Reader.prototype.unload = function(){
if(this.settings.restore) {
this.saveSettings();
}
};
//-- Enable binding events to reader
RSVP.EventTarget.mixin(EPUBJS.Reader.prototype);

View file

@ -4,6 +4,8 @@ EPUBJS.Book = function(options){
this.settings = _.defaults(options || {}, {
bookPath : null,
bookKey : null,
packageUrl : null,
storage: false, //-- true (auto) or false (none) | override: 'ram', 'websqldatabase', 'indexeddb', 'filesystem'
fromStorage : false,
saved : false,
@ -98,52 +100,51 @@ EPUBJS.Book = function(options){
//-- Check bookUrl and start parsing book Assets or load them from storage
EPUBJS.Book.prototype.open = function(bookPath, forceReload){
var book = this,
saved = this.isSaved(bookPath),
opened;
epubpackage,
opened = new RSVP.defer();
this.settings.bookPath = bookPath;
//-- Get a absolute URL from the book path
this.bookUrl = this.urlFrom(bookPath);
// console.log("saved", saved, !forceReload)
//-- Remove the previous settings and reload
if(saved){
//-- Apply settings, keeping newer ones
this.applySavedSettings();
}
if(this.settings.contained || this.isContained(bookPath)){
this.settings.contained = this.contained = true;
this.bookUrl = '';
// return; //-- TODO: this need to be fixed and tested before enabling
opened = this.unarchive(bookPath).then(function(){
if(saved && book.settings.restore && !forceReload){
return book.restore();
}else{
return book.unpack();
}
});
epubpackage = this.unarchive(bookPath).
then(function(){
return this.loadPackage();
});
} else {
epubpackage = this.loadPackage();
}
if(saved && this.settings.restore && !forceReload){
//-- Will load previous package json, or re-unpack if error
opened = this.restore();
if(this.settings.restore && !forceReload){
//-- Will load previous package json, or re-unpack if error
epubpackage.then(function(packageXml) {
var identifier = book.packageIdentifier(packageXml);
var restored = book.restore(identifier);
}else{
if(!restored) {
book.unpack(packageXml);
}
opened.resolve();
book.defer_opened.resolve();
});
//-- Get package information from epub opf
opened = this.unpack();
}
}else{
//-- Get package information from epub opf
epubpackage.then(function(packageXml) {
book.unpack(packageXml);
opened.resolve();
book.defer_opened.resolve();
});
}
//-- If there is network connection, store the books contents
@ -151,21 +152,19 @@ EPUBJS.Book.prototype.open = function(bookPath, forceReload){
if(!this.settings.stored) opened.then(book.storeOffline());
}
opened.then(function(){
book.defer_opened.resolve();
});
return opened;
return opened.promise;
};
EPUBJS.Book.prototype.unpack = function(_containerPath){
EPUBJS.Book.prototype.loadPackage = function(_containerPath){
var book = this,
parse = new EPUBJS.Parser(),
containerPath = _containerPath || "META-INF/container.xml";
parse = new EPUBJS.Parser(),
containerPath = _containerPath || "META-INF/container.xml",
containerXml,
packageXml;
//-- Return chain of promises
return book.loadXml(book.bookUrl + containerPath).
if(!this.settings.packageUrl) { //-- provide the packageUrl to skip this step
packageXml = book.loadXml(book.bookUrl + containerPath).
then(function(containerXml){
return parse.container(containerXml); // Container has path to content
}).
@ -173,58 +172,74 @@ EPUBJS.Book.prototype.unpack = function(_containerPath){
book.settings.contentsPath = book.bookUrl + paths.basePath;
book.settings.packageUrl = book.bookUrl + paths.packagePath;
return book.loadXml(book.settings.packageUrl); // Containes manifest, spine and metadata
}).
then(function(packageXml){
return parse.package(packageXml, book.settings.contentsPath); // Extract info from contents
}).
then(function(contents){
book.contents = contents;
book.manifest = book.contents.manifest;
book.spine = book.contents.spine;
book.spineIndexByURL = book.contents.spineIndexByURL;
book.metadata = book.contents.metadata;
book.cover = book.contents.cover = book.settings.contentsPath + contents.coverPath;
book.spineNodeIndex = book.contents.spineNodeIndex = contents.spineNodeIndex;
book.ready.manifest.resolve(book.contents.manifest);
book.ready.spine.resolve(book.contents.spine);
book.ready.metadata.resolve(book.contents.metadata);
book.ready.cover.resolve(book.contents.cover);
//-- Adjust setting based on metadata
//-- Load the TOC, optional; either the EPUB3 XHTML Navigation file or the EPUB2 NCX file
if(contents.navPath) {
book.settings.navUrl = book.settings.contentsPath + contents.navPath;
book.loadXml(book.settings.navUrl).
then(function(navHtml){
return parse.nav(navHtml, book.spineIndexByURL, book.spine); // Grab Table of Contents
}).then(function(toc){
book.toc = book.contents.toc = toc;
book.ready.toc.resolve(book.contents.toc);
}, function(error) {
book.ready.toc.resolve(false);
});
} else if(contents.tocPath) {
book.settings.tocUrl = book.settings.contentsPath + contents.tocPath;
book.loadXml(book.settings.tocUrl).
then(function(tocXml){
return parse.toc(tocXml, book.spineIndexByURL, book.spine); // Grab Table of Contents
}).then(function(toc){
book.toc = book.contents.toc = toc;
book.ready.toc.resolve(book.contents.toc);
}, function(error) {
book.ready.toc.resolve(false);
});
} else {
book.ready.toc.resolve(false);
}
});
} else {
packageXml = book.loadXml(book.settings.packageUrl);
}
return packageXml;
};
EPUBJS.Book.prototype.packageIdentifier = function(packageXml){
var book = this,
parse = new EPUBJS.Parser();
return parse.identifier(packageXml);
};
EPUBJS.Book.prototype.unpack = function(packageXml){
var book = this,
parse = new EPUBJS.Parser();
book.contents = parse.packageContents(packageXml, book.settings.contentsPath); // Extract info from contents
book.manifest = book.contents.manifest;
book.spine = book.contents.spine;
book.spineIndexByURL = book.contents.spineIndexByURL;
book.metadata = book.contents.metadata;
book.setBookKey(book.metadata.identifier);
book.cover = book.contents.cover = book.settings.contentsPath + book.contents.coverPath;
book.spineNodeIndex = book.contents.spineNodeIndex;
book.ready.manifest.resolve(book.contents.manifest);
book.ready.spine.resolve(book.contents.spine);
book.ready.metadata.resolve(book.contents.metadata);
book.ready.cover.resolve(book.contents.cover);
//-- TODO: Adjust setting based on metadata
//-- Load the TOC, optional; either the EPUB3 XHTML Navigation file or the EPUB2 NCX file
if(book.contents.navPath) {
book.settings.navUrl = book.settings.contentsPath + book.contents.navPath;
book.loadXml(book.settings.navUrl).
then(function(navHtml){
return parse.nav(navHtml, book.spineIndexByURL, book.spine); // Grab Table of Contents
}).then(function(toc){
book.toc = book.contents.toc = toc;
book.ready.toc.resolve(book.contents.toc);
}, function(error) {
book.ready.toc.resolve(false);
});
} else if(book.contents.tocPath) {
book.settings.tocUrl = book.settings.contentsPath + book.contents.tocPath;
book.loadXml(book.settings.tocUrl).
then(function(tocXml){
return parse.toc(tocXml, book.spineIndexByURL, book.spine); // Grab Table of Contents
}).then(function(toc){
book.toc = book.contents.toc = toc;
book.ready.toc.resolve(book.contents.toc);
}, function(error) {
book.ready.toc.resolve(false);
});
} else {
book.ready.toc.resolve(false);
}
};
EPUBJS.Book.prototype.getMetadata = function() {
@ -333,7 +348,7 @@ EPUBJS.Book.prototype.unarchive = function(bookPath){
//-- Checks if url has a .epub or .zip extension
EPUBJS.Book.prototype.isContained = function(bookUrl){
var dot = bookUrl.lastIndexOf('.'),
ext = bookUrl.slice(dot+1);
ext = bookUrl.slice(dot+1);
if(ext && (ext == "epub" || ext == "zip")){
return true;
@ -342,10 +357,9 @@ EPUBJS.Book.prototype.isContained = function(bookUrl){
return false;
};
//-- Checks if the book setting can be retrieved from localStorage
EPUBJS.Book.prototype.isSaved = function(bookPath) {
var bookKey = bookPath + ":" + this.settings.version,
storedSettings = localStorage.getItem(bookKey);
//-- Checks if the book can be retrieved from localStorage
EPUBJS.Book.prototype.isSaved = function(bookKey) {
var storedSettings = localStorage.getItem(bookKey);
if( !localStorage ||
storedSettings === null) {
@ -355,48 +369,27 @@ EPUBJS.Book.prototype.isSaved = function(bookPath) {
}
};
//-- Remove save book settings
EPUBJS.Book.prototype.removeSavedSettings = function() {
var bookKey = this.settings.bookPath + ":" + this.settings.version;
localStorage.removeItem(bookKey);
this.settings.stored = false; //TODO: is this needed?
};
EPUBJS.Book.prototype.applySavedSettings = function() {
var bookKey = this.settings.bookPath + ":" + this.settings.version,
stored = JSON.parse(localStorage.getItem(bookKey));
if(EPUBJS.VERSION != stored.EPUBJSVERSION) return false;
this.settings = _.defaults(this.settings, stored);
};
EPUBJS.Book.prototype.saveSettings = function(){
var bookKey = this.settings.bookPath + ":" + this.settings.version;
if(this.render) {
this.settings.previousLocationCfi = this.render.currentLocationCfi;
EPUBJS.Book.prototype.setBookKey = function(identifier){
if(!this.settings.bookKey) {
this.settings.bookKey = this.generateBookKey(identifier);
}
return this.settings.bookKey;
};
localStorage.setItem(bookKey, JSON.stringify(this.settings));
EPUBJS.Book.prototype.generateBookKey = function(identifier){
return "epubjs:" + EPUBJS.VERSION + ":" + window.location.host + ":" + identifier;
};
EPUBJS.Book.prototype.saveContents = function(){
var contentsKey = this.settings.bookPath + ":contents:" + this.settings.version;
localStorage.setItem(contentsKey, JSON.stringify(this.contents));
localStorage.setItem(this.settings.bookKey, JSON.stringify(this.contents));
};
EPUBJS.Book.prototype.removeSavedContents = function() {
var bookKey = this.settings.bookPath + ":contents:" + this.settings.version;
localStorage.removeItem(bookKey);
localStorage.removeItem(this.settings.bookKey);
};
// EPUBJS.Book.prototype.chapterTitle = function(){
// return this.spine[this.spinePos].id; //-- TODO: clarify that this is returning title
// }
@ -447,14 +440,13 @@ EPUBJS.Book.prototype.startDisplay = function(){
return display;
};
EPUBJS.Book.prototype.restore = function(_reject){
EPUBJS.Book.prototype.restore = function(identifier){
var book = this,
contentsKey = this.settings.bookPath + ":contents:" + this.settings.version,
deferred = new RSVP.defer(),
fetch = ['manifest', 'spine', 'metadata', 'cover', 'toc', 'spineNodeIndex', 'spineIndexByURL'],
reject = _reject || false,
fromStore = localStorage.getItem(contentsKey);
fetch = ['manifest', 'spine', 'metadata', 'cover', 'toc', 'spineNodeIndex', 'spineIndexByURL'],
reject = false,
bookKey = this.setBookKey(identifier),
fromStore = localStorage.getItem(bookKey);
if(this.settings.clearSaved) reject = true;
@ -469,17 +461,14 @@ EPUBJS.Book.prototype.restore = function(_reject){
}
if(reject || !fromStore || !this.contents || !this.settings.contentsPath){
// this.removeSavedSettings();
return this.open(this.settings.bookPath, true);
return false;
}else{
this.ready.manifest.resolve(this.manifest);
this.ready.spine.resolve(this.spine);
this.ready.metadata.resolve(this.metadata);
this.ready.cover.resolve(this.cover);
this.ready.toc.resolve(this.toc);
deferred.resolve();
return deferred.promise;
return true;
}
};
@ -507,15 +496,15 @@ EPUBJS.Book.prototype.displayChapter = function(chap, end){
}
if(pos < 0 || pos >= this.spine.length){
console.error("Not A Valid Chapter");
return false;
console.warn("Not A Valid Location");
pos = 0;
end = false;
cfi = false;
}
//-- Set the book's spine position
this.spinePos = pos;
//-- Create a new chapter
this.chapter = new EPUBJS.Chapter(this.spine[pos]);
@ -704,7 +693,6 @@ EPUBJS.Book.prototype.removeStyle = function(style) {
EPUBJS.Book.prototype.unload = function(){
if(this.settings.restore) {
this.saveSettings();
this.saveContents();
}
@ -825,5 +813,5 @@ RSVP.configure('instrument', true); //-- true | will logging out all RSVP reject
// RSVP.on('chained', listener);
// RSVP.on('fulfilled', listener);
RSVP.on('rejected', function(event){
console.error(event.detail, event.detail.message);
console.error(event.detail.message, event.detail.stack);
});

View file

@ -85,6 +85,7 @@ EPUBJS.EpubCFI.prototype.getOffset = function(cfiStr) {
EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
var cfi = {},
chapSegment,
chapId,
path,
end,
@ -92,8 +93,13 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
cfi.chapter = this.getChapter(cfiStr);
chapSegment = parseInt(cfi.chapter.split("/")[2]) || false;
cfi.fragment = this.getFragment(cfiStr);
cfi.spinePos = (parseInt(cfi.chapter.split("/")[2]) / 2 - 1 ) || 0;
if(!chapSegment || !cfi.fragment) return {spinePos: -1};
cfi.spinePos = (parseInt(chapSegment) / 2 - 1 ) || 0;
chapId = cfi.chapter.match(/\[(.*)\]/);

View file

@ -16,19 +16,24 @@ EPUBJS.Parser.prototype.container = function(containerXml){
};
};
EPUBJS.Parser.prototype.package = function(packageXml, baseUrl){
EPUBJS.Parser.prototype.identifier = function(packageXml){
var metadataNode = packageXml.querySelector("metadata");
return this.getElementText(metadataNode, "identifier");
};
EPUBJS.Parser.prototype.packageContents = function(packageXml, baseUrl){
var parse = this;
if(baseUrl) this.baseUrl = baseUrl;
var metadataNode = packageXml.querySelector("metadata"),
manifestNode = packageXml.querySelector("manifest"),
spineNode = packageXml.querySelector("spine");
manifestNode = packageXml.querySelector("manifest"),
spineNode = packageXml.querySelector("spine");
var manifest = parse.manifest(manifestNode),
navPath = parse.findNavPath(manifestNode),
tocPath = parse.findTocPath(manifestNode),
coverPath = parse.findCoverPath(manifestNode);
navPath = parse.findNavPath(manifestNode),
tocPath = parse.findTocPath(manifestNode),
coverPath = parse.findCoverPath(manifestNode);
var spineNodeIndex = Array.prototype.indexOf.call(spineNode.parentNode.childNodes, spineNode);
@ -72,7 +77,7 @@ EPUBJS.Parser.prototype.findCoverPath = function(manifestNode){
//-- Expanded to match Readium web components
EPUBJS.Parser.prototype.metadata = function(xml){
var metadata = {},
p = this;
p = this;
metadata.bookTitle = p.getElementText(xml, 'title');
metadata.creator = p.getElementText(xml, 'creator');
@ -123,7 +128,7 @@ EPUBJS.Parser.prototype.querySelectorText = function(xml, q){
EPUBJS.Parser.prototype.manifest = function(manifestXml){
var baseUrl = this.baseUrl,
manifest = {};
manifest = {};
//-- Turn items into an array
var selected = manifestXml.querySelectorAll("item"),
@ -132,9 +137,9 @@ EPUBJS.Parser.prototype.manifest = function(manifestXml){
//-- Create an object with the id as key
items.forEach(function(item){
var id = item.getAttribute('id'),
href = item.getAttribute('href') || '',
type = item.getAttribute('media-type') || '',
properties = item.getAttribute('properties') || '';
href = item.getAttribute('href') || '',
type = item.getAttribute('media-type') || '',
properties = item.getAttribute('properties') || '';
manifest[id] = {
'href' : href,
@ -153,7 +158,7 @@ EPUBJS.Parser.prototype.spine = function(spineXml, manifest){
var spine = [];
var selected = spineXml.getElementsByTagName("itemref"),
items = Array.prototype.slice.call(selected);
items = Array.prototype.slice.call(selected);
//-- Add to array to mantain ordering and cross reference with manifest
items.forEach(function(item, index){
@ -175,7 +180,7 @@ EPUBJS.Parser.prototype.spine = function(spineXml, manifest){
EPUBJS.Parser.prototype.nav = function(navHtml, spineIndexByURL, bookSpine){
var navEl = navHtml.querySelector('nav'), //-- [*|type="toc"] * Doesn't seem to work
idCounter = 0;
idCounter = 0;
if(!navEl) return [];
@ -212,10 +217,10 @@ EPUBJS.Parser.prototype.nav = function(navHtml, spineIndexByURL, bookSpine){
function getTOC(parent){
var list = [],
nodes = findListItems(parent),
items = Array.prototype.slice.call(nodes),
length = items.length,
node;
nodes = findListItems(parent),
items = Array.prototype.slice.call(nodes),
length = items.length,
node;
if(length === 0) return false;
@ -262,12 +267,12 @@ EPUBJS.Parser.prototype.toc = function(tocXml, spineIndexByURL, bookSpine){
function getTOC(parent){
var list = [],
items = [],
nodes = parent.childNodes,
nodesArray = Array.prototype.slice.call(nodes),
length = nodesArray.length,
iter = length,
node;
items = [],
nodes = parent.childNodes,
nodesArray = Array.prototype.slice.call(nodes),
length = nodesArray.length,
iter = length,
node;
if(length === 0) return false;
@ -281,15 +286,15 @@ EPUBJS.Parser.prototype.toc = function(tocXml, spineIndexByURL, bookSpine){
items.forEach(function(item){
var id = item.getAttribute('id') || false,
content = item.querySelector("content"),
src = content.getAttribute('src'),
navLabel = item.querySelector("navLabel"),
text = navLabel.textContent ? navLabel.textContent : "",
split = src.split("#"),
baseUrl = split[0],
spinePos = spineIndexByURL[baseUrl],
spineItem,
subitems = getTOC(item);
content = item.querySelector("content"),
src = content.getAttribute('src'),
navLabel = item.querySelector("navLabel"),
text = navLabel.textContent ? navLabel.textContent : "",
split = src.split("#"),
baseUrl = split[0],
spinePos = spineIndexByURL[baseUrl],
spineItem,
subitems = getTOC(item);
if(!id) {
if(spinePos) {