mirror of
https://github.com/futurepress/epub.js.git
synced 2025-10-03 14:59:18 +02:00
new namespaces, strict mode, toc updated, jump to links
This commit is contained in:
parent
78e1c05ab0
commit
ce18f4ff15
13 changed files with 439 additions and 155 deletions
BIN
.DS_Store
vendored
BIN
.DS_Store
vendored
Binary file not shown.
77
css/main.css
77
css/main.css
|
@ -4,7 +4,7 @@ body {
|
|||
|
||||
#main {
|
||||
/* height: 500px; */
|
||||
position: fixed;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
/* left: 40px; */
|
||||
|
@ -23,10 +23,11 @@ body {
|
|||
}
|
||||
|
||||
#titlebar {
|
||||
width: 100%;
|
||||
|
||||
height: 8%;
|
||||
min-height: 20px;
|
||||
padding: 10px;
|
||||
padding: 10px 0 10px 0;
|
||||
margin: 0 50px 0 50px;
|
||||
text-align: center;
|
||||
color: #4f4f4f;
|
||||
font-weight: 100;
|
||||
|
@ -84,7 +85,7 @@ body {
|
|||
|
||||
#sidebar {
|
||||
background: #6b6b6b;
|
||||
position: fixed;
|
||||
position: absolute;
|
||||
/* left: -260px; */
|
||||
/* -webkit-transform: translate(-260px, 0);
|
||||
-moz-transform: translate(-260px, 0); */
|
||||
|
@ -92,15 +93,15 @@ body {
|
|||
width: 300px;
|
||||
height: 100%;
|
||||
-webkit-transition: -webkit-transform .5s;
|
||||
-moz-transition: transform .5s;
|
||||
-moz-transition: -moz-transform .5s;
|
||||
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#sidebar.open {
|
||||
/* left: 0; */
|
||||
-webkit-transform: translate(0, 0);
|
||||
-moz-transform: translate(0, 0);
|
||||
/* -webkit-transform: translate(0, 0);
|
||||
-moz-transform: translate(0, 0); */
|
||||
}
|
||||
|
||||
#main.closed {
|
||||
|
@ -169,23 +170,28 @@ input:-moz-placeholder {
|
|||
box-shadow: -2px 0 15px rgba(0, 0, 0, 1);
|
||||
}
|
||||
|
||||
#toc-scroll {
|
||||
overflow-y: auto;
|
||||
#toc {
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: none;
|
||||
visibility: hidden;
|
||||
-webkit-transition: visibility 0 ease .5s;
|
||||
-moz-transition: visibility 0 ease .5s;
|
||||
}
|
||||
|
||||
#sidebar.open #toc-scroll {
|
||||
display: block;
|
||||
#sidebar.open #toc {
|
||||
overflow-y: auto;
|
||||
visibility: visible;
|
||||
-webkit-transition: visibility 0 ease 0;
|
||||
-moz-transition: visibility 0 ease 0;
|
||||
}
|
||||
|
||||
#toc {
|
||||
#toc > ul{
|
||||
margin-top: 50px;
|
||||
margin-bottom: 50px;
|
||||
padding-left: 40px;
|
||||
display: block;
|
||||
|
||||
}
|
||||
|
||||
#toc li {
|
||||
|
@ -197,7 +203,7 @@ input:-moz-placeholder {
|
|||
}
|
||||
|
||||
#toc li:active,
|
||||
#toc li.current
|
||||
#toc li.currentChapter
|
||||
{
|
||||
list-style: square;
|
||||
}
|
||||
|
@ -207,8 +213,19 @@ input:-moz-placeholder {
|
|||
text-decoration: none;
|
||||
}
|
||||
|
||||
#toc a:hover {
|
||||
text-decoration: underline;
|
||||
#toc li.currentChapter > a,
|
||||
#toc li a:hover {
|
||||
color: #f1f1f1
|
||||
}
|
||||
|
||||
#toc li ul {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#toc li.currentChapter > ul,
|
||||
#toc li.openChapter > ul
|
||||
{
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1040px) {
|
||||
|
@ -243,5 +260,31 @@ input:-moz-placeholder {
|
|||
display: none;
|
||||
}
|
||||
|
||||
#main {
|
||||
-webkit-transform: translate(0, 0);
|
||||
-moz-transform: translate(0, 0);
|
||||
}
|
||||
|
||||
#titlebar {
|
||||
font-size: 10px;
|
||||
margin: 0 50px 0 50px;
|
||||
}
|
||||
|
||||
#open {
|
||||
position: fixed;
|
||||
top: 10px;
|
||||
left: 0;
|
||||
z-index: 110;
|
||||
display: block;
|
||||
|
||||
-webkit-transition: -webkit-transform .5s;
|
||||
-moz-transition: -moz-transform .5s;
|
||||
}
|
||||
|
||||
#sidebar.open #open {
|
||||
-webkit-transform: translate(300px, 0);
|
||||
-moz-transform: translate(300px, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
FP.app = {};
|
||||
var FPR = FPR || {};
|
||||
|
||||
FP.app.init = (function($){
|
||||
FPR.app = {};
|
||||
|
||||
FPR.app.init = (function($){
|
||||
"use strict";
|
||||
var Book,
|
||||
offline = false;
|
||||
offline = false,
|
||||
sidebarWidth = 40,
|
||||
windowWidth;
|
||||
|
||||
function init(bookURL){
|
||||
var search = window.location.search.match(/book=(.*)/),
|
||||
|
@ -13,16 +17,24 @@ FP.app.init = (function($){
|
|||
FP.core.crossBrowserColumnCss();
|
||||
|
||||
//-- Set up our sidebar
|
||||
$("#main").width($(window).width()-40);
|
||||
windowWidth = $(window).width();
|
||||
if(windowWidth > 550){
|
||||
$("#main").width(windowWidth-sidebarWidth);
|
||||
}else{
|
||||
$("#main").width(windowWidth);
|
||||
}
|
||||
|
||||
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.listen("book:chapterReady", chapterChange);
|
||||
Book.listen("book:online", goOnline);
|
||||
Book.listen("book:offline", goOffline);
|
||||
|
||||
//Book.setFootnotes(["glossterm", "footnote"]);//["glossterm", "footnote"]);
|
||||
|
||||
Book.start(bookURL + "/");
|
||||
|
||||
//-- Wait for Dom ready to handle jquery
|
||||
|
@ -34,7 +46,7 @@ FP.app.init = (function($){
|
|||
}
|
||||
|
||||
function meta(){
|
||||
var title = Book.getTitle();
|
||||
var title = Book.getTitle(),
|
||||
author = Book.getCreator(),
|
||||
$title = $("#book-title"),
|
||||
$author = $("#chapter-title");
|
||||
|
@ -46,39 +58,84 @@ FP.app.init = (function($){
|
|||
}
|
||||
|
||||
function toc(){
|
||||
var contents = Book.getTOC();
|
||||
$toc = $("#toc");
|
||||
var contents = Book.getTOC(),
|
||||
$toc = $("#toc"),
|
||||
$items;
|
||||
|
||||
$toc.empty();
|
||||
$items = generateTocItems(contents);
|
||||
|
||||
$toc.append($items);
|
||||
|
||||
// contents.forEach(function(item){
|
||||
// $wrapper = $("<li id='toc-"+item.id+"'>");
|
||||
//
|
||||
// $item = $("<a href='#"+item.href+"' data-spinepos='"+item.spinePos+"'>"+item.label+"</a>");
|
||||
//
|
||||
//
|
||||
// $item.on("click", function(e){
|
||||
// $this = $(this);
|
||||
// Book.displayChapter($this.data("spinepos"));
|
||||
// e.preventDefault();
|
||||
// });
|
||||
//
|
||||
// $wrapper.append($item);
|
||||
//
|
||||
// if(item.subitems && item.subitems.length){
|
||||
// $subitems = $("<ul>");
|
||||
// item.subitems.forEach(function(subitem){
|
||||
// //console.log("subitem", subitem)
|
||||
// $subitem = $("<li id='toc-"+subitem.id+"'><a href='#"+subitem.href+"' data-spinepos='"+subitem.spinePos+"'>"+subitem.label+"</a></li>");
|
||||
// $subitems.append($subitem);
|
||||
// });
|
||||
// $wrapper.append($subitems);
|
||||
// }
|
||||
//
|
||||
// $toc.append($wrapper);
|
||||
// });
|
||||
|
||||
|
||||
}
|
||||
|
||||
function generateTocItems(contents){
|
||||
var $container = $("<ul>");
|
||||
|
||||
|
||||
contents.forEach(function(item){
|
||||
$wrapper = $("<li>");
|
||||
var $subitems,
|
||||
$wrapper = $("<li id='toc-"+item.id+"'>"),
|
||||
$item = $("<a href='"+item.href+"'>"+item.label+"</a>");
|
||||
|
||||
$item = $("<a href='#"+item.href+"' data-spinepos='"+item.spinePos+"'>"+item.label+"</a>");
|
||||
$item.data("spinepos", item.spinePos);
|
||||
|
||||
//-- Handle sub items later
|
||||
/*
|
||||
if(item.subitems.length){
|
||||
$subitems = $("<ul>");
|
||||
item.subitems.forEach(function(subitem){
|
||||
$subitem = $("<li><a href='#"+subitem.href+"' data-spinepos='"+subitem.spinePos+"'>"+subitem.label+"</a></li>");
|
||||
$subitems.append($subitem);
|
||||
});
|
||||
$item.append($subitems);
|
||||
if(item.section) {
|
||||
$item.data("section", item.section);
|
||||
}
|
||||
*/
|
||||
|
||||
$item.on("click", function(e){
|
||||
$this = $(this);
|
||||
Book.displayChapter($this.data("spinepos"));
|
||||
var $this = $(this),
|
||||
url = $this.attr("href");
|
||||
//spinepos = $this.data("spinepos"),
|
||||
//section = $this.data("section") || false;
|
||||
|
||||
$(".openChapter").removeClass("openChapter");
|
||||
$this.parent().addClass("openChapter");
|
||||
|
||||
Book.show(url);
|
||||
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
$wrapper.append($item);
|
||||
$toc.append($wrapper);
|
||||
|
||||
if(item.subitems && item.subitems.length){
|
||||
$subitems = generateTocItems(item.subitems);
|
||||
$wrapper.append($subitems);
|
||||
}
|
||||
|
||||
$container.append($wrapper);
|
||||
});
|
||||
|
||||
|
||||
return $container;
|
||||
}
|
||||
|
||||
function goOnline(){
|
||||
|
@ -95,21 +152,37 @@ FP.app.init = (function($){
|
|||
|
||||
}
|
||||
|
||||
function chapterChange(e) {
|
||||
var id = e.msg,
|
||||
$item = $("#toc-"+id),
|
||||
$current = $(".currentChapter");
|
||||
|
||||
if($item.length){
|
||||
$current.removeClass("currentChapter");
|
||||
$item.addClass("currentChapter");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function controls(){
|
||||
var $next = $("#next"),
|
||||
$prev = $("#prev"),
|
||||
$main = $("#main"),
|
||||
$book = $("#area"),
|
||||
$sidebar = $("#sidebar"),
|
||||
$open = $("#open"),
|
||||
$icon = $open.find("img"),
|
||||
$network = $("#network"),
|
||||
$window = $(window),
|
||||
sidebarWidth = 40;
|
||||
$window = $(window);
|
||||
|
||||
|
||||
$window.on("resize", function(){
|
||||
$main.width($window.width()-sidebarWidth);
|
||||
windowWidth = $(window).width();
|
||||
if(windowWidth > 550){
|
||||
$main.width(windowWidth-sidebarWidth);
|
||||
}else{
|
||||
$main.width(windowWidth);
|
||||
}
|
||||
});
|
||||
|
||||
$next.on("click", function(){
|
||||
|
@ -144,19 +217,33 @@ FP.app.init = (function($){
|
|||
}
|
||||
});
|
||||
|
||||
$open.on("click", function(){
|
||||
if($sidebar.hasClass("open")){
|
||||
setTimeout(function(){
|
||||
$sidebar.removeClass("open");
|
||||
}, 500);
|
||||
$main.removeClass("closed");
|
||||
$icon.attr("src", "img/menu-icon.png");
|
||||
}else{
|
||||
function showSidebar(){
|
||||
$book.css("pointer-events", "none"); //-- Avoid capture by ifrmae
|
||||
$sidebar.addClass("open");
|
||||
$main.addClass("closed");
|
||||
$icon.attr("src", "img/close.png");
|
||||
}
|
||||
|
||||
function hideSidebar(){
|
||||
$book.css("pointer-events", "visible");
|
||||
$sidebar.removeClass("open");
|
||||
$main.removeClass("closed");
|
||||
$icon.attr("src", "img/menu-icon.png");
|
||||
}
|
||||
|
||||
$open.on("click", function(){
|
||||
if($sidebar.hasClass("open")){
|
||||
hideSidebar();
|
||||
}else{
|
||||
showSidebar();
|
||||
|
||||
$open.clickOutside(function(){
|
||||
hideSidebar();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
$network.on("click", function(){
|
||||
offline = !offline;
|
||||
|
|
33
fpjs/reader/utils.js
Normal file
33
fpjs/reader/utils.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
//-- http://stackoverflow.com/questions/2124684/jquery-how-click-anywhere-outside-of-the-div-the-div-fades-out
|
||||
|
||||
jQuery.fn.extend({
|
||||
// Calls the handler function if the user has clicked outside the object (and not on any of the exceptions)
|
||||
clickOutside: function(handler, exceptions) {
|
||||
var $this = this;
|
||||
|
||||
jQuery(document).on("click.offer", function(event) {
|
||||
if (exceptions && jQuery.inArray(event.target, exceptions) > -1) {
|
||||
return;
|
||||
} else if (jQuery.contains($this[0], event.target)) {
|
||||
return;
|
||||
} else {
|
||||
jQuery(document).off("click.offer");
|
||||
handler(event, $this);
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
Modernizr.addTest('filesystem', function(){
|
||||
|
||||
var prefixes = Modernizr._domPrefixes;
|
||||
|
||||
for ( var i = -1, len = prefixes.length; ++i < len; ){
|
||||
if ( window[prefixes[i] + 'RequestFileSystem'] ) return true;
|
||||
}
|
||||
return 'requestFileSystem' in window;
|
||||
|
||||
});
|
||||
|
|
@ -14,11 +14,16 @@ FP.Book = function(elem, bookUrl){
|
|||
this.createEvent("book:spineReady");
|
||||
this.createEvent("book:bookReady");
|
||||
this.createEvent("book:chapterReady");
|
||||
this.createEvent("book:chapterDisplayed");
|
||||
this.createEvent("book:resized");
|
||||
this.createEvent("book:stored");
|
||||
this.createEvent("book:online");
|
||||
this.createEvent("book:offline");
|
||||
|
||||
this.hooks = {
|
||||
"beforeChapterDisplay" : []
|
||||
};
|
||||
|
||||
this.initialize(this.el);
|
||||
|
||||
this.online = navigator.onLine;
|
||||
|
@ -30,7 +35,7 @@ FP.Book = function(elem, bookUrl){
|
|||
|
||||
// BookUrl is optional, but if present start loading process
|
||||
if(bookUrl) {
|
||||
this.start(bookUrl);
|
||||
this.display(bookUrl);
|
||||
}
|
||||
|
||||
|
||||
|
@ -128,6 +133,11 @@ FP.Book.prototype.isSaved = function(force) {
|
|||
this.spine = JSON.parse(localStorage.getItem("spine"));
|
||||
this.toc = JSON.parse(localStorage.getItem("toc"));
|
||||
|
||||
if(!this.assets.length || !this.spine.length){
|
||||
this.stored = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -181,10 +191,10 @@ FP.Book.prototype.parseContainer = function(callback){
|
|||
var fullpath;
|
||||
|
||||
//-- <rootfile full-path="OPS/package.opf" media-type="application/oebps-package+xml"/>
|
||||
rootfiles = container.getElementsByTagName("rootfile");
|
||||
rootfile = container.querySelector("rootfile");
|
||||
|
||||
//-- Should only be one
|
||||
rootfile = rootfiles[0];
|
||||
//rootfile = rootfiles[0];
|
||||
|
||||
fullpath = rootfile.getAttribute('full-path').split("/");
|
||||
|
||||
|
@ -206,9 +216,9 @@ FP.Book.prototype.parseContents = function(){
|
|||
url = this.basePath + this.contentsPath;
|
||||
|
||||
FP.core.loadXML(url, function(contents){
|
||||
var metadata = contents.getElementsByTagName("metadata")[0],
|
||||
manifest = contents.getElementsByTagName("manifest")[0],
|
||||
spine = contents.getElementsByTagName("spine")[0];
|
||||
var metadata = contents.querySelector("metadata"),
|
||||
manifest = contents.querySelector("manifest"),
|
||||
spine = contents.querySelector("spine");
|
||||
|
||||
that.parseMetadata(metadata);
|
||||
that.parseManifest(manifest);
|
||||
|
@ -259,7 +269,8 @@ FP.Book.prototype.parseSpine = function(spine){
|
|||
|
||||
this.spine = [];
|
||||
|
||||
this.spineIndex = {}; //-- For quick reference by id, might be a better way
|
||||
this.spineIndexByID = {}; //-- For quick reference by id and url, might be a better way
|
||||
this.spineIndexByURL = {};
|
||||
|
||||
//-- Turn items into an array
|
||||
items = Array.prototype.slice.call(spine.getElementsByTagName("itemref"));
|
||||
|
@ -270,7 +281,8 @@ FP.Book.prototype.parseSpine = function(spine){
|
|||
href = that.assets[id];
|
||||
|
||||
that.spine.push({"id": id, "href": href});
|
||||
that.spineIndex[id] = index;
|
||||
that.spineIndexByID[id] = index;
|
||||
that.spineIndexByURL[href] = index;
|
||||
});
|
||||
|
||||
localStorage.setItem("spine", JSON.stringify(this.spine));
|
||||
|
@ -296,7 +308,7 @@ FP.Book.prototype.parseTOC = function(path){
|
|||
"id": coverID,
|
||||
"href": that.assets[coverID],
|
||||
"label": coverID,
|
||||
"spinePos": parseInt(that.spineIndex[coverID])
|
||||
"spinePos": parseInt(that.spineIndexByID[coverID])
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -308,14 +320,18 @@ FP.Book.prototype.parseTOC = function(path){
|
|||
|
||||
items.forEach(function(item){
|
||||
var id = item.getAttribute('id'),
|
||||
href = that.assets[id],
|
||||
content = item.querySelector("content"),
|
||||
src = content.getAttribute('src'), //that.assets[id],
|
||||
split = src.split("#"),
|
||||
href = that.basePath + split[0],
|
||||
hash = split[1] || false,
|
||||
spinePos = parseInt(that.spineIndexByID[id] || that.spineIndexByURL[href]),
|
||||
navLabel = item.querySelector("navLabel"),
|
||||
text = navLabel.textContent ? navLabel.textContent : "",
|
||||
subitems = item.querySelectorAll("navPoint") || false,
|
||||
subs = false,
|
||||
childof = (item.parentNode == parent);
|
||||
|
||||
|
||||
if(!childof) return; //-- Only get direct children, should xpath for this eventually?
|
||||
|
||||
if(subitems){
|
||||
|
@ -324,10 +340,11 @@ FP.Book.prototype.parseTOC = function(path){
|
|||
|
||||
list.push({
|
||||
"id": id,
|
||||
"href": href,
|
||||
"href": src,
|
||||
"label": text,
|
||||
"spinePos": parseInt(that.spineIndex[id]),
|
||||
"subitems" : subs
|
||||
"spinePos": spinePos,
|
||||
"section" : hash || false,
|
||||
"subitems" : subs || false
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -373,7 +390,7 @@ FP.Book.prototype.startDisplay = function(){
|
|||
|
||||
|
||||
this.tell("book:bookReady");
|
||||
this.displayChapter(this.spinePos, false, function(){
|
||||
this.displayChapter(this.spinePos, function(chapter){
|
||||
|
||||
if(this.online){
|
||||
this.storeOffline();
|
||||
|
@ -384,7 +401,29 @@ FP.Book.prototype.startDisplay = function(){
|
|||
|
||||
}
|
||||
|
||||
FP.Book.prototype.displayChapter = function(pos, end, callback){
|
||||
FP.Book.prototype.show = function(url){
|
||||
var split = url.split("#"),
|
||||
chapter = split[0],
|
||||
section = split[1] || false,
|
||||
absoluteURL = this.basePath + chapter,
|
||||
spinePos = this.spineIndexByURL[absoluteURL];
|
||||
|
||||
if(!chapter){
|
||||
spinePos = this.spinePos;
|
||||
}
|
||||
|
||||
if(!spinePos) return false;
|
||||
|
||||
if(spinePos != this.spinePos){
|
||||
this.displayChapter(spinePos, function(chap){
|
||||
if(section) chap.section(section);
|
||||
});
|
||||
}else{
|
||||
if(section) this.currentChapter.section(section);
|
||||
}
|
||||
}
|
||||
|
||||
FP.Book.prototype.displayChapter = function(pos, callback){
|
||||
var that = this;
|
||||
|
||||
if(pos >= this.spine.length){
|
||||
|
@ -409,12 +448,10 @@ FP.Book.prototype.displayChapter = function(pos, end, callback){
|
|||
//-- TODO: Choose between single and spread
|
||||
//that.formatSpread();
|
||||
|
||||
if(end) chapter.goToChapterEnd();
|
||||
|
||||
that.tell("book:chapterReady");
|
||||
that.tell("book:chapterReady", chapter.getID());
|
||||
|
||||
if(callback){
|
||||
callback();
|
||||
callback(chapter);
|
||||
}
|
||||
//that.preloadNextChapter();
|
||||
|
||||
|
@ -445,7 +482,9 @@ FP.Book.prototype.nextChapter = function() {
|
|||
FP.Book.prototype.prevChapter = function() {
|
||||
this.spinePos--;
|
||||
|
||||
this.displayChapter(this.spinePos, true);
|
||||
this.displayChapter(this.spinePos, function(chapter){
|
||||
chapter.goToChapterEnd();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -464,6 +503,7 @@ FP.Book.prototype.preloadNextChapter = function() {
|
|||
|
||||
FP.Book.prototype.storeOffline = function(callback) {
|
||||
var assets = FP.core.toArray(this.assets);
|
||||
|
||||
FP.storage.batch(assets, function(){
|
||||
this.stored = 1;
|
||||
localStorage.setItem("stored", 1);
|
||||
|
@ -510,13 +550,39 @@ FP.Book.prototype.determineStorageMethod = function(override) {
|
|||
FP.storage.storageMethod(method);
|
||||
}
|
||||
|
||||
Modernizr.addTest('filesystem', function(){
|
||||
FP.Book.prototype.triggerHooks = function(type, callback){
|
||||
var hooks, count;
|
||||
|
||||
var prefixes = Modernizr._domPrefixes;
|
||||
if(typeof(this.hooks[type]) == "undefined") return false;
|
||||
|
||||
for ( var i = -1, len = prefixes.length; ++i < len; ){
|
||||
if ( window[prefixes[i] + 'RequestFileSystem'] ) return true;
|
||||
}
|
||||
return 'requestFileSystem' in window;
|
||||
hooks = this.hooks[type];
|
||||
count = hooks.length;
|
||||
|
||||
function countdown(){
|
||||
count--;
|
||||
if(count <= 0 && callback) callback();
|
||||
};
|
||||
|
||||
hooks.forEach(function(hook){
|
||||
hook(countdown);
|
||||
});
|
||||
}
|
||||
|
||||
FP.Book.prototype.registerHook = function(type, toAdd){
|
||||
var that = this;
|
||||
|
||||
if(typeof(this.hooks[type]) != "undefined"){
|
||||
|
||||
if(typeof(toAdd) === "function"){
|
||||
this.hooks[type].push(toAdd);
|
||||
}else if(Array.isArray(toAdd)){
|
||||
toAdd.forEach(function(hook){
|
||||
that.hooks[type].push(hook);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}else{
|
||||
this.hooks[type] = [func]; //or maybe this should error?
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,20 @@
|
|||
FP.Chapter = function(book){
|
||||
FP.Chapter = function(book, pos){
|
||||
|
||||
this.book = book;
|
||||
this.iframe = this.book.iframe;
|
||||
|
||||
this.chapInfo = this.book.spine[pos || this.book.spinePos];
|
||||
//-- Get the url to the book from the spine
|
||||
this.path = this.book.spine[this.book.spinePos].href;
|
||||
this.path = this.chapInfo.href;
|
||||
this.ID = this.chapInfo.id;
|
||||
|
||||
this.chapterPos = 1;
|
||||
this.leftPos = 0;
|
||||
|
||||
this.book.registerHook("beforeChapterDisplay",
|
||||
[this.replaceLinks.bind(this), this.replaceResources.bind(this)]);
|
||||
|
||||
|
||||
this.load();
|
||||
|
||||
return this;
|
||||
|
@ -34,14 +40,16 @@ FP.Chapter.prototype.setIframeSrc = function(url){
|
|||
var that = this;
|
||||
|
||||
//-- Not sure if this is the best time to do this, but hide current text
|
||||
if(this.bodyEl) this.bodyEl.style.visibility = "hidden";
|
||||
//if(this.bodyEl) this.bodyEl.style.visibility = "hidden";
|
||||
this.visible(false);
|
||||
|
||||
this.iframe.src = url;
|
||||
|
||||
this.iframe.onload = function() {
|
||||
//that.bodyEl = that.iframe.contentDocument.documentElement.getElementsByTagName('body')[0];
|
||||
//that.bodyEl = that.iframe.contentDocument.querySelector('body, html');
|
||||
that.bodyEl = that.book.bodyEl = that.iframe.contentDocument.body;
|
||||
that.doc = that.iframe.contentDocument;
|
||||
that.bodyEl = that.doc.body;
|
||||
|
||||
//-- TODO: Choose between single and spread
|
||||
that.formatSpread();
|
||||
|
@ -109,14 +117,21 @@ FP.Chapter.prototype.formatSpread = function(){
|
|||
|
||||
this.calcPages();
|
||||
|
||||
if(!this.book.online){
|
||||
//-- Temp place to parse Links
|
||||
this.replaceLinks(function(){
|
||||
|
||||
|
||||
// if(!this.book.online){
|
||||
// //-- Temp place to parse Links
|
||||
// this.replaceLinks(function(){
|
||||
// this.visible(true);
|
||||
// }.bind(this));
|
||||
// }else{
|
||||
// this.visible(true);
|
||||
// }
|
||||
|
||||
this.beforeDisplay(function(){
|
||||
this.book.tell("book:chapterDisplayed");
|
||||
this.visible(true);
|
||||
}.bind(this));
|
||||
}else{
|
||||
this.visible(true);
|
||||
}
|
||||
});
|
||||
|
||||
//-- Go to current page after resize
|
||||
if(this.OldcolWidth){
|
||||
|
@ -130,6 +145,8 @@ FP.Chapter.prototype.goToChapterEnd = function(){
|
|||
}
|
||||
|
||||
FP.Chapter.prototype.visible = function(bool){
|
||||
if(!this.bodyEl) return false;
|
||||
|
||||
if(bool){
|
||||
this.bodyEl.style.visibility = "visible";
|
||||
}else{
|
||||
|
@ -142,7 +159,7 @@ FP.Chapter.prototype.calcPages = function(){
|
|||
|
||||
this.displayedPages = Math.ceil(this.totalWidth / this.spreadWidth);
|
||||
|
||||
|
||||
//console.log("Pages:", this.displayedPages)
|
||||
//-- I work for Chrome
|
||||
//this.iframe.contentDocument.body.scrollLeft = 200;
|
||||
|
||||
|
@ -185,9 +202,9 @@ FP.Chapter.prototype.prevPage = function(){
|
|||
}
|
||||
|
||||
FP.Chapter.prototype.chapterEnd = function(){
|
||||
this.chapterPos = this.displayedPages;
|
||||
this.leftPos = this.spreadWidth * (this.displayedPages - 1);//this.totalWidth - this.colWidth;
|
||||
this.setLeft(this.leftPos);
|
||||
this.page(this.displayedPages);
|
||||
//this.leftPos = this.spreadWidth * (this.displayedPages - 1);//this.totalWidth - this.colWidth;
|
||||
//this.setLeft(this.leftPos);
|
||||
}
|
||||
|
||||
FP.Chapter.prototype.setLeft = function(leftPos){
|
||||
|
@ -195,26 +212,42 @@ FP.Chapter.prototype.setLeft = function(leftPos){
|
|||
}
|
||||
|
||||
FP.Chapter.prototype.replaceLinks = function(callback){
|
||||
var doc = this.iframe.contentDocument,
|
||||
links = doc.querySelectorAll('[href], [src]'),
|
||||
items = Array.prototype.slice.call(links),
|
||||
count = items.length;
|
||||
var hrefs = this.doc.querySelectorAll('[href]'),
|
||||
links = Array.prototype.slice.call(hrefs),
|
||||
that = this;
|
||||
|
||||
if(FP.storage.getStorageType() == "filesystem") {
|
||||
links.forEach(function(link){
|
||||
var path,
|
||||
href = link.getAttribute("href");
|
||||
|
||||
link.onclick = function(){
|
||||
that.book.show(href);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if(callback) callback();
|
||||
}
|
||||
|
||||
FP.Chapter.prototype.replaceResources = function(callback){
|
||||
var srcs, resources, count;
|
||||
|
||||
if(this.book.online || FP.storage.getStorageType() == "filesystem") {
|
||||
//-- filesystem api links are relative, so no need to fix
|
||||
if(callback) callback();
|
||||
return false;
|
||||
}
|
||||
|
||||
items.forEach(function(link){
|
||||
var path,
|
||||
href = link.getAttribute("href"),
|
||||
src = link.getAttribute("src"),
|
||||
full = href ? this.book.basePath + href : this.book.basePath + src;
|
||||
srcs = this.doc.querySelectorAll('[src]');
|
||||
resources = Array.prototype.slice.call(srcs);
|
||||
count = resources.length;
|
||||
|
||||
resources.forEach(function(link){
|
||||
var src = link.getAttribute("src"),
|
||||
full = this.book.basePath + src;
|
||||
|
||||
FP.storage.get(full, function(url){
|
||||
if(href) link.setAttribute("href", url);
|
||||
if(src) link.setAttribute("src", url);
|
||||
link.setAttribute("src", url);
|
||||
count--;
|
||||
if(count <= 0 && callback) callback();
|
||||
});
|
||||
|
@ -223,4 +256,31 @@ FP.Chapter.prototype.replaceLinks = function(callback){
|
|||
|
||||
}
|
||||
|
||||
FP.Chapter.prototype.getID = function(){
|
||||
return this.ID;
|
||||
}
|
||||
|
||||
FP.Chapter.prototype.page = function(pg){
|
||||
if(pg >= 1 && pg <= this.displayedPages){
|
||||
this.chapterPos = pg;
|
||||
this.leftPos = this.spreadWidth * (pg-1);
|
||||
this.setLeft(this.leftPos);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
FP.Chapter.prototype.section = function(fragment){
|
||||
var el = this.doc.getElementById(fragment),
|
||||
left = this.leftPos + el.offsetLeft,
|
||||
pg = Math.floor(left / this.spreadWidth) + 1;
|
||||
|
||||
this.page(pg);
|
||||
}
|
||||
|
||||
FP.Chapter.prototype.beforeDisplay = function(callback){
|
||||
this.book.triggerHooks("beforeChapterDisplay", callback.bind(this));
|
||||
}
|
||||
|
||||
|
|
|
@ -162,3 +162,4 @@ FP.core.dataURLToBlob = function(dataURL) {
|
|||
|
||||
return new Blob([uInt8Array], {type: contentType});
|
||||
}
|
||||
|
||||
|
|
|
@ -5,14 +5,14 @@ FP.storage = function(){
|
|||
function storageMethod(storageType){
|
||||
console.log("storageMethod", storageType)
|
||||
//-- Pick store type
|
||||
if(!storageType || typeof(FP.storage[storageType]) == "undefined"){
|
||||
if(!storageType || typeof(FP.store[storageType]) == "undefined"){
|
||||
this.storageType = "none";
|
||||
}else{
|
||||
this.storageType = storageType;
|
||||
}
|
||||
|
||||
//-- Create a new store of that type
|
||||
this._store = new FP.storage[this.storageType];
|
||||
this._store = new FP.store[this.storageType];
|
||||
|
||||
//-- Handle load errors
|
||||
this._store.failed = _error;
|
||||
|
@ -173,7 +173,9 @@ FP.storage.ram = function() {
|
|||
}
|
||||
*/
|
||||
|
||||
FP.storage.none = function() {
|
||||
FP.store = FP.store || {};
|
||||
|
||||
FP.store.none = function() {
|
||||
var _store = {};
|
||||
|
||||
//-- Used for preloading
|
||||
|
@ -185,6 +187,8 @@ FP.storage.none = function() {
|
|||
}
|
||||
}
|
||||
|
||||
//-- need to add batch!
|
||||
|
||||
//-- Fetches url
|
||||
function get(path, callback) {
|
||||
var fromCache = check(path),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
FP.storage = FP.storage || {}
|
||||
FP.store = FP.store || {};
|
||||
|
||||
FP.storage.filesystem = function() {
|
||||
FP.store.filesystem = function() {
|
||||
var _urls = {},
|
||||
_queue = new FP.Queue("fpjs/render/loader_filesystem.js", 6),
|
||||
_requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
FP.storage = FP.storage || {}
|
||||
FP.store = FP.store || {};
|
||||
|
||||
FP.storage.indexedDB = function() {
|
||||
FP.store.indexedDB = function() {
|
||||
var _store = {},
|
||||
_blobs = {},
|
||||
_queue = new FP.Queue(loader, 6),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
FP.storage = FP.storage || {};
|
||||
FP.store = FP.store || {};
|
||||
|
||||
FP.storage.ram = function() {
|
||||
FP.store.ram = function() {
|
||||
var _store = {},
|
||||
_blobs = {},
|
||||
_queue = new FP.Queue(loader, 6);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
FP.storage = FP.storage || {}
|
||||
FP.store = FP.store || {};
|
||||
|
||||
FP.storage.websql = function() {
|
||||
FP.store.websql = function() {
|
||||
var _blobs = {},
|
||||
_queue = new FP.Queue(loader, 6),
|
||||
_db;
|
||||
|
|
22
index.html
22
index.html
|
@ -15,27 +15,18 @@
|
|||
<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>
|
||||
//-- Define Global
|
||||
// var FP = (function(){
|
||||
// "use strict";
|
||||
// return {
|
||||
// namespace: function(name) {
|
||||
// if(this[name] === undefined) { this[name] = {}; }
|
||||
// if(typeof this[name] !== 'object') { throw "Namespace Error: "+name; }
|
||||
// return this[name];
|
||||
// }
|
||||
// };
|
||||
// })();
|
||||
var FP = {};
|
||||
"use strict";
|
||||
|
||||
var FP = FP || {};
|
||||
document.onreadystatechange = function () {
|
||||
if (document.readyState == "complete") {
|
||||
FP.app.init();
|
||||
FPR.app.init();
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<script async src="fpjs/reader/utils.js"></script>
|
||||
<script async src="fpjs/render/core.js"></script>
|
||||
<script async src="fpjs/render/queue.js"></script>
|
||||
<script async src="fpjs/render/storage.js"></script>
|
||||
|
@ -58,8 +49,7 @@
|
|||
<a id="setting"><img id="settings" src="img/settings.png"></a>
|
||||
|
||||
</div>
|
||||
<div id="toc-scroll">
|
||||
<ul id="toc"></ul>
|
||||
<div id="toc">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue