mirror of
https://github.com/futurepress/epub.js.git
synced 2025-10-03 14:59:18 +02:00
Added notes, fixes to cfi sorting, pagination
This commit is contained in:
parent
aba8dc3c6f
commit
6a69eeb2a9
27 changed files with 1241 additions and 171 deletions
|
@ -16,7 +16,8 @@ module.exports = function(grunt) {
|
|||
'demo/js/libs/loader_filesystem.min.js': 'libs/fileStorage/workers/loader_filesystem.min.js',
|
||||
'demo/js/libs/jquery-2.0.3.min.js': 'libs/jquery/jquery-2.0.3.min.js',
|
||||
'demo/js/libs/inflate.js': 'libs/zip/inflate.js',
|
||||
'demo/js/libs/screenfull.min.js': 'libs/screenfull.min.js'
|
||||
'demo/js/libs/screenfull.min.js': 'libs/screenfull.min.js',
|
||||
'demo/js/plugins/search.js': 'reader/plugins/search.js'
|
||||
},
|
||||
uglify: {
|
||||
options: {
|
||||
|
|
|
@ -3408,7 +3408,7 @@ EPUBJS.EpubCFI.prototype.generateCfiFromElement = function(element, chapter) {
|
|||
var path = this.generatePathComponent(steps);
|
||||
if(!path.length) {
|
||||
// Start of Chapter
|
||||
return "epubcfi(" + chapter + ")";
|
||||
return "epubcfi(" + chapter + "!/4/)";
|
||||
} else {
|
||||
// First Text Node
|
||||
return "epubcfi(" + chapter + "!" + path + "/1:0)";
|
||||
|
@ -3503,7 +3503,7 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
|
|||
}
|
||||
|
||||
path = pathComponent.split('/');
|
||||
end = path[path.length-1];
|
||||
end = path.pop();
|
||||
|
||||
cfi.steps = [];
|
||||
|
||||
|
@ -3511,18 +3511,13 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
|
|||
var type, index, has_brackets, id;
|
||||
|
||||
if(!part) return;
|
||||
//-- Check if this is a text node or element
|
||||
if(parseInt(part) % 2){
|
||||
type = "text";
|
||||
index = parseInt(part) - 1;
|
||||
} else {
|
||||
|
||||
type = "element";
|
||||
index = parseInt(part) / 2 - 1;
|
||||
has_brackets = part.match(/\[(.*)\]/);
|
||||
if(has_brackets && has_brackets[1]){
|
||||
id = has_brackets[1];
|
||||
}
|
||||
}
|
||||
|
||||
cfi.steps.push({
|
||||
"type" : type,
|
||||
|
@ -3530,6 +3525,16 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
|
|||
'id' : id || false
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
//-- Check if END is a text node or element
|
||||
if(!isNaN(parseInt(end))) {
|
||||
cfi.steps.push({
|
||||
"type" : "text",
|
||||
'index' : parseInt(end) - 1,
|
||||
});
|
||||
}
|
||||
|
||||
assertion = charecterOffsetComponent.match(/\[(.*)\]/);
|
||||
if(assertion && assertion[1]){
|
||||
cfi.characterOffset = parseInt(charecterOffsetComponent.split('[')[0]);
|
||||
|
@ -3539,9 +3544,6 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
|
|||
cfi.characterOffset = parseInt(charecterOffsetComponent);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
return cfi;
|
||||
};
|
||||
|
||||
|
@ -3726,6 +3728,22 @@ EPUBJS.EpubCFI.prototype.generateCfiFromHref = function(href, book) {
|
|||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
EPUBJS.EpubCFI.prototype.generateCfiFromTextNode = function(anchor, offset, base) {
|
||||
var parent = anchor.parentElement;
|
||||
var steps = this.pathTo(parent);
|
||||
var path = this.generatePathComponent(steps);
|
||||
var index = [].slice.apply(parent.childNodes).indexOf(anchor) + 1;
|
||||
return "epubcfi(" + base + "!" + path + "/"+index+":"+(offset || 0)+")";
|
||||
};
|
||||
|
||||
EPUBJS.EpubCFI.prototype.generateCfiFromRangeAnchor = function(range, base) {
|
||||
var anchor = range.anchorNode;
|
||||
var offset = range.anchorOffset;
|
||||
return this.generateCfiFromTextNode(anchor, offset, base);
|
||||
};
|
||||
|
||||
|
||||
EPUBJS.Events = function(obj, el){
|
||||
|
||||
this.events = {};
|
||||
|
@ -3894,19 +3912,22 @@ EPUBJS.Layout.Reflowable.prototype.format = function(documentElement, _width, _h
|
|||
var columnGap = EPUBJS.core.prefixed('columnGap');
|
||||
var columnWidth = EPUBJS.core.prefixed('columnWidth');
|
||||
|
||||
//-- Check the width and decied on columns
|
||||
var width = (_width % 2 === 0) ? _width : Math.floor(_width) - 1;
|
||||
var section = Math.ceil(width / 8);
|
||||
//-- Check the width and create even width columns
|
||||
var fullWidth = Math.floor(_width);
|
||||
var width = (fullWidth % 2 === 0) ? fullWidth : fullWidth - 1;
|
||||
var section = Math.floor(width / 8);
|
||||
var gap = (section % 2 === 0) ? section : section - 1;
|
||||
|
||||
this.documentElement = documentElement;
|
||||
//-- Single Page
|
||||
this.spreadWidth = (width + gap);
|
||||
|
||||
documentElement.style.width = "auto"; //-- reset width for calculations
|
||||
|
||||
documentElement.style.overflow = "hidden";
|
||||
|
||||
// Must be set to the new calculated width or the columns will be off
|
||||
documentElement.style.width = width + "px";
|
||||
|
||||
//-- Adjust height
|
||||
documentElement.style.height = _height + "px";
|
||||
|
||||
|
@ -3915,7 +3936,6 @@ EPUBJS.Layout.Reflowable.prototype.format = function(documentElement, _width, _h
|
|||
documentElement.style[columnGap] = gap+"px";
|
||||
documentElement.style[columnWidth] = width+"px";
|
||||
|
||||
documentElement.style.width = width + "px";
|
||||
return {
|
||||
pageWidth : this.spreadWidth,
|
||||
pageHeight : _height
|
||||
|
|
4
build/epub.min.js
vendored
4
build/epub.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -3407,7 +3407,7 @@ EPUBJS.EpubCFI.prototype.generateCfiFromElement = function(element, chapter) {
|
|||
var path = this.generatePathComponent(steps);
|
||||
if(!path.length) {
|
||||
// Start of Chapter
|
||||
return "epubcfi(" + chapter + ")";
|
||||
return "epubcfi(" + chapter + "!/4/)";
|
||||
} else {
|
||||
// First Text Node
|
||||
return "epubcfi(" + chapter + "!" + path + "/1:0)";
|
||||
|
@ -3502,7 +3502,7 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
|
|||
}
|
||||
|
||||
path = pathComponent.split('/');
|
||||
end = path[path.length-1];
|
||||
end = path.pop();
|
||||
|
||||
cfi.steps = [];
|
||||
|
||||
|
@ -3510,18 +3510,13 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
|
|||
var type, index, has_brackets, id;
|
||||
|
||||
if(!part) return;
|
||||
//-- Check if this is a text node or element
|
||||
if(parseInt(part) % 2){
|
||||
type = "text";
|
||||
index = parseInt(part) - 1;
|
||||
} else {
|
||||
|
||||
type = "element";
|
||||
index = parseInt(part) / 2 - 1;
|
||||
has_brackets = part.match(/\[(.*)\]/);
|
||||
if(has_brackets && has_brackets[1]){
|
||||
id = has_brackets[1];
|
||||
}
|
||||
}
|
||||
|
||||
cfi.steps.push({
|
||||
"type" : type,
|
||||
|
@ -3529,6 +3524,16 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
|
|||
'id' : id || false
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
//-- Check if END is a text node or element
|
||||
if(!isNaN(parseInt(end))) {
|
||||
cfi.steps.push({
|
||||
"type" : "text",
|
||||
'index' : parseInt(end) - 1,
|
||||
});
|
||||
}
|
||||
|
||||
assertion = charecterOffsetComponent.match(/\[(.*)\]/);
|
||||
if(assertion && assertion[1]){
|
||||
cfi.characterOffset = parseInt(charecterOffsetComponent.split('[')[0]);
|
||||
|
@ -3538,9 +3543,6 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
|
|||
cfi.characterOffset = parseInt(charecterOffsetComponent);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
return cfi;
|
||||
};
|
||||
|
||||
|
@ -3725,6 +3727,22 @@ EPUBJS.EpubCFI.prototype.generateCfiFromHref = function(href, book) {
|
|||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
EPUBJS.EpubCFI.prototype.generateCfiFromTextNode = function(anchor, offset, base) {
|
||||
var parent = anchor.parentElement;
|
||||
var steps = this.pathTo(parent);
|
||||
var path = this.generatePathComponent(steps);
|
||||
var index = [].slice.apply(parent.childNodes).indexOf(anchor) + 1;
|
||||
return "epubcfi(" + base + "!" + path + "/"+index+":"+(offset || 0)+")";
|
||||
};
|
||||
|
||||
EPUBJS.EpubCFI.prototype.generateCfiFromRangeAnchor = function(range, base) {
|
||||
var anchor = range.anchorNode;
|
||||
var offset = range.anchorOffset;
|
||||
return this.generateCfiFromTextNode(anchor, offset, base);
|
||||
};
|
||||
|
||||
|
||||
EPUBJS.Events = function(obj, el){
|
||||
|
||||
this.events = {};
|
||||
|
@ -3893,19 +3911,22 @@ EPUBJS.Layout.Reflowable.prototype.format = function(documentElement, _width, _h
|
|||
var columnGap = EPUBJS.core.prefixed('columnGap');
|
||||
var columnWidth = EPUBJS.core.prefixed('columnWidth');
|
||||
|
||||
//-- Check the width and decied on columns
|
||||
var width = (_width % 2 === 0) ? _width : Math.floor(_width) - 1;
|
||||
var section = Math.ceil(width / 8);
|
||||
//-- Check the width and create even width columns
|
||||
var fullWidth = Math.floor(_width);
|
||||
var width = (fullWidth % 2 === 0) ? fullWidth : fullWidth - 1;
|
||||
var section = Math.floor(width / 8);
|
||||
var gap = (section % 2 === 0) ? section : section - 1;
|
||||
|
||||
this.documentElement = documentElement;
|
||||
//-- Single Page
|
||||
this.spreadWidth = (width + gap);
|
||||
|
||||
documentElement.style.width = "auto"; //-- reset width for calculations
|
||||
|
||||
documentElement.style.overflow = "hidden";
|
||||
|
||||
// Must be set to the new calculated width or the columns will be off
|
||||
documentElement.style.width = width + "px";
|
||||
|
||||
//-- Adjust height
|
||||
documentElement.style.height = _height + "px";
|
||||
|
||||
|
@ -3914,7 +3935,6 @@ EPUBJS.Layout.Reflowable.prototype.format = function(documentElement, _width, _h
|
|||
documentElement.style[columnGap] = gap+"px";
|
||||
documentElement.style[columnWidth] = width+"px";
|
||||
|
||||
documentElement.style.width = width + "px";
|
||||
return {
|
||||
pageWidth : this.spreadWidth,
|
||||
pageHeight : _height
|
||||
|
|
|
@ -38,7 +38,8 @@ EPUBJS.Hooks.register("beforeChapterDisplay").endnotes = function(callback, rend
|
|||
iwidth = renderer.width,
|
||||
tip,
|
||||
pop,
|
||||
maxHeight = 225;
|
||||
maxHeight = 225,
|
||||
itemRect;
|
||||
|
||||
if(!txt) {
|
||||
pop = el.cloneNode(true);
|
||||
|
|
2
build/hooks.min.js
vendored
2
build/hooks.min.js
vendored
|
@ -1 +1 @@
|
|||
EPUBJS.Hooks.register("beforeChapterDisplay").endnotes=function(a,b){var c=b.contents.querySelectorAll("a[href]"),d=Array.prototype.slice.call(c),e="epub:type",f="noteref",g=EPUBJS.core.folder(location.pathname),h=g+EPUBJS.cssPath||g,i={};EPUBJS.core.addCss(h+"popup.css",!1,b.render.document.head),d.forEach(function(a){function c(){var c,e=b.height,f=b.width,j=225;o||(c=l.cloneNode(!0),o=c.querySelector("p")),i[k]||(i[k]=document.createElement("div"),i[k].setAttribute("class","popup"),pop_content=document.createElement("div"),i[k].appendChild(pop_content),pop_content.appendChild(o),pop_content.setAttribute("class","pop_content"),b.render.document.body.appendChild(i[k]),i[k].addEventListener("mouseover",d,!1),i[k].addEventListener("mouseout",g,!1),b.on("renderer:pageChanged",h,this),b.on("renderer:pageChanged",g,this)),c=i[k],itemRect=a.getBoundingClientRect(),m=itemRect.left,n=itemRect.top,c.classList.add("show"),popRect=c.getBoundingClientRect(),c.style.left=m-popRect.width/2+"px",c.style.top=n+"px",j>e/2.5&&(j=e/2.5,pop_content.style.maxHeight=j+"px"),popRect.height+n>=e-25?(c.style.top=n-popRect.height+"px",c.classList.add("above")):c.classList.remove("above"),m-popRect.width<=0?(c.style.left=m+"px",c.classList.add("left")):c.classList.remove("left"),m+popRect.width/2>=f?(c.style.left=m-300+"px",popRect=c.getBoundingClientRect(),c.style.left=m-popRect.width+"px",popRect.height+n>=e-25?(c.style.top=n-popRect.height+"px",c.classList.add("above")):c.classList.remove("above"),c.classList.add("right")):c.classList.remove("right")}function d(){i[k].classList.add("on")}function g(){i[k].classList.remove("on")}function h(){setTimeout(function(){i[k].classList.remove("show")},100)}var j,k,l,m,n,o,p=a.getAttribute(e);p==f&&(j=a.getAttribute("href"),k=j.replace("#",""),l=b.render.document.getElementById(k),a.addEventListener("mouseover",c,!1),a.addEventListener("mouseout",h,!1))}),a&&a()},EPUBJS.Hooks.register("beforeChapterDisplay").mathml=function(a,b){if(-1!==b.currentChapter.manifestProperties.indexOf("mathml")){b.iframe.contentWindow.mathmlCallback=a;var c=document.createElement("script");c.type="text/x-mathjax-config",c.innerHTML=' MathJax.Hub.Register.StartupHook("End",function () { window.mathmlCallback(); }); MathJax.Hub.Config({jax: ["input/TeX","input/MathML","output/SVG"],extensions: ["tex2jax.js","mml2jax.js","MathEvents.js"],TeX: {extensions: ["noErrors.js","noUndefined.js","autoload-all.js"]},MathMenu: {showRenderer: false},menuSettings: {zoom: "Click"},messageStyle: "none"}); ',b.doc.body.appendChild(c),EPUBJS.core.addScript("http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML",null,b.doc.head)}else a&&a()},EPUBJS.Hooks.register("beforeChapterDisplay").smartimages=function(a,b){var c=b.contents.querySelectorAll("img"),d=Array.prototype.slice.call(c),e=b.height;return"reflowable"!=b.layoutSettings.layout?(a(),void 0):(d.forEach(function(a){function c(){var c,d=a.getBoundingClientRect(),f=d.height,g=d.top,h=a.getAttribute("data-height"),i=h||f,j=Number(getComputedStyle(a,"").fontSize.match(/(\d*(\.\d*)?)px/)[1]),k=j?j/2:0;e=b.contents.clientHeight,0>g&&(g=0),i+g>=e?(e/2>g?(c=e-g-k,a.style.maxHeight=c+"px",a.style.width="auto"):(i>e&&(a.style.maxHeight=e+"px",a.style.width="auto",d=a.getBoundingClientRect(),i=d.height),a.style.display="block",a.style.WebkitColumnBreakBefore="always",a.style.breakBefore="column"),a.setAttribute("data-height",c)):(a.style.removeProperty("max-height"),a.style.removeProperty("margin-top"))}a.addEventListener("load",c,!1),b.on("renderer:resized",c),b.on("renderer:chapterUnloaded",function(){a.removeEventListener("load",c),b.off("renderer:resized",c)}),c()}),a&&a(),void 0)},EPUBJS.Hooks.register("beforeChapterDisplay").transculsions=function(a,b){var c=b.contents.querySelectorAll("[transclusion]"),d=Array.prototype.slice.call(c);d.forEach(function(a){function c(){j=g,k=h,j>chapter.colWidth&&(d=chapter.colWidth/j,j=chapter.colWidth,k*=d),f.width=j,f.height=k}var d,e=a.getAttribute("ref"),f=document.createElement("iframe"),g=a.getAttribute("width"),h=a.getAttribute("height"),i=a.parentNode,j=g,k=h;c(),b.listenUntil("renderer:resized","renderer:chapterUnloaded",c),f.src=e,i.replaceChild(f,a)}),a&&a()};
|
||||
EPUBJS.Hooks.register("beforeChapterDisplay").endnotes=function(a,b){var c=b.contents.querySelectorAll("a[href]"),d=Array.prototype.slice.call(c),e="epub:type",f="noteref",g=EPUBJS.core.folder(location.pathname),h=g+EPUBJS.cssPath||g,i={};EPUBJS.core.addCss(h+"popup.css",!1,b.render.document.head),d.forEach(function(a){function c(){var c,e,f=b.height,j=b.width,p=225;o||(c=l.cloneNode(!0),o=c.querySelector("p")),i[k]||(i[k]=document.createElement("div"),i[k].setAttribute("class","popup"),pop_content=document.createElement("div"),i[k].appendChild(pop_content),pop_content.appendChild(o),pop_content.setAttribute("class","pop_content"),b.render.document.body.appendChild(i[k]),i[k].addEventListener("mouseover",d,!1),i[k].addEventListener("mouseout",g,!1),b.on("renderer:pageChanged",h,this),b.on("renderer:pageChanged",g,this)),c=i[k],e=a.getBoundingClientRect(),m=e.left,n=e.top,c.classList.add("show"),popRect=c.getBoundingClientRect(),c.style.left=m-popRect.width/2+"px",c.style.top=n+"px",p>f/2.5&&(p=f/2.5,pop_content.style.maxHeight=p+"px"),popRect.height+n>=f-25?(c.style.top=n-popRect.height+"px",c.classList.add("above")):c.classList.remove("above"),m-popRect.width<=0?(c.style.left=m+"px",c.classList.add("left")):c.classList.remove("left"),m+popRect.width/2>=j?(c.style.left=m-300+"px",popRect=c.getBoundingClientRect(),c.style.left=m-popRect.width+"px",popRect.height+n>=f-25?(c.style.top=n-popRect.height+"px",c.classList.add("above")):c.classList.remove("above"),c.classList.add("right")):c.classList.remove("right")}function d(){i[k].classList.add("on")}function g(){i[k].classList.remove("on")}function h(){setTimeout(function(){i[k].classList.remove("show")},100)}var j,k,l,m,n,o,p=a.getAttribute(e);p==f&&(j=a.getAttribute("href"),k=j.replace("#",""),l=b.render.document.getElementById(k),a.addEventListener("mouseover",c,!1),a.addEventListener("mouseout",h,!1))}),a&&a()},EPUBJS.Hooks.register("beforeChapterDisplay").mathml=function(a,b){if(-1!==b.currentChapter.manifestProperties.indexOf("mathml")){b.iframe.contentWindow.mathmlCallback=a;var c=document.createElement("script");c.type="text/x-mathjax-config",c.innerHTML=' MathJax.Hub.Register.StartupHook("End",function () { window.mathmlCallback(); }); MathJax.Hub.Config({jax: ["input/TeX","input/MathML","output/SVG"],extensions: ["tex2jax.js","mml2jax.js","MathEvents.js"],TeX: {extensions: ["noErrors.js","noUndefined.js","autoload-all.js"]},MathMenu: {showRenderer: false},menuSettings: {zoom: "Click"},messageStyle: "none"}); ',b.doc.body.appendChild(c),EPUBJS.core.addScript("http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML",null,b.doc.head)}else a&&a()},EPUBJS.Hooks.register("beforeChapterDisplay").smartimages=function(a,b){var c=b.contents.querySelectorAll("img"),d=Array.prototype.slice.call(c),e=b.height;return"reflowable"!=b.layoutSettings.layout?(a(),void 0):(d.forEach(function(a){function c(){var c,d=a.getBoundingClientRect(),f=d.height,g=d.top,h=a.getAttribute("data-height"),i=h||f,j=Number(getComputedStyle(a,"").fontSize.match(/(\d*(\.\d*)?)px/)[1]),k=j?j/2:0;e=b.contents.clientHeight,0>g&&(g=0),i+g>=e?(e/2>g?(c=e-g-k,a.style.maxHeight=c+"px",a.style.width="auto"):(i>e&&(a.style.maxHeight=e+"px",a.style.width="auto",d=a.getBoundingClientRect(),i=d.height),a.style.display="block",a.style.WebkitColumnBreakBefore="always",a.style.breakBefore="column"),a.setAttribute("data-height",c)):(a.style.removeProperty("max-height"),a.style.removeProperty("margin-top"))}a.addEventListener("load",c,!1),b.on("renderer:resized",c),b.on("renderer:chapterUnloaded",function(){a.removeEventListener("load",c),b.off("renderer:resized",c)}),c()}),a&&a(),void 0)},EPUBJS.Hooks.register("beforeChapterDisplay").transculsions=function(a,b){var c=b.contents.querySelectorAll("[transclusion]"),d=Array.prototype.slice.call(c);d.forEach(function(a){function c(){j=g,k=h,j>chapter.colWidth&&(d=chapter.colWidth/j,j=chapter.colWidth,k*=d),f.width=j,f.height=k}var d,e=a.getAttribute("ref"),f=document.createElement("iframe"),g=a.getAttribute("width"),h=a.getAttribute("height"),i=a.parentNode,j=g,k=h;c(),b.listenUntil("renderer:resized","renderer:chapterUnloaded",c),f.src=e,i.replaceChild(f,a)}),a&&a()};
|
330
build/reader.js
330
build/reader.js
|
@ -36,10 +36,11 @@ EPUBJS.Reader = function(path, _options) {
|
|||
restore : true,
|
||||
reload : false,
|
||||
bookmarks : null,
|
||||
annotations : null,
|
||||
contained : null,
|
||||
bookKey : null,
|
||||
styles : null,
|
||||
sidebarReflow: false,
|
||||
sidebarReflow: true,
|
||||
generatePagination: false,
|
||||
history: true
|
||||
});
|
||||
|
@ -73,6 +74,10 @@ EPUBJS.Reader = function(path, _options) {
|
|||
this.settings.bookmarks = [];
|
||||
}
|
||||
|
||||
if(!this.settings.annotations) {
|
||||
this.settings.annotations = [];
|
||||
}
|
||||
|
||||
if(this.settings.generatePagination) {
|
||||
book.generatePagination($viewer.width(), $viewer.height());
|
||||
}
|
||||
|
@ -84,6 +89,7 @@ EPUBJS.Reader = function(path, _options) {
|
|||
reader.ControlsController = EPUBJS.reader.ControlsController.call(reader, book);
|
||||
reader.SidebarController = EPUBJS.reader.SidebarController.call(reader, book);
|
||||
reader.BookmarksController = EPUBJS.reader.BookmarksController.call(reader, book);
|
||||
reader.NotesController = EPUBJS.reader.NotesController.call(reader, book);
|
||||
|
||||
// Call Plugins
|
||||
for(plugin in EPUBJS.reader.plugins) {
|
||||
|
@ -193,6 +199,23 @@ EPUBJS.Reader.prototype.clearBookmarks = function() {
|
|||
this.settings.bookmarks = [];
|
||||
};
|
||||
|
||||
//-- Notes
|
||||
EPUBJS.Reader.prototype.addNote = function(note) {
|
||||
this.settings.annotations.push(note);
|
||||
};
|
||||
|
||||
EPUBJS.Reader.prototype.removeNote = function(note) {
|
||||
var index = this.settings.annotations.indexOf(note);
|
||||
if( index === -1 ) return;
|
||||
|
||||
delete this.settings.annotations[index];
|
||||
|
||||
};
|
||||
|
||||
EPUBJS.Reader.prototype.clearNotes = function() {
|
||||
this.settings.annotations = [];
|
||||
};
|
||||
|
||||
//-- Settings
|
||||
EPUBJS.Reader.prototype.setBookKey = function(identifier){
|
||||
if(!this.settings.bookKey) {
|
||||
|
@ -250,16 +273,16 @@ EPUBJS.Reader.prototype.hashChanged = function(){
|
|||
|
||||
EPUBJS.Reader.prototype.selectedRange = function(range){
|
||||
var epubcfi = new EPUBJS.EpubCFI();
|
||||
var cfi = epubcfi.generateCfiFromElement(range.anchorNode.parentElement, this.book.renderer.currentChapter.cfiBase);
|
||||
var cfi = epubcfi.generateCfiFromRangeAnchor(range, this.book.renderer.currentChapter.cfiBase);
|
||||
var cfiFragment = "#"+cfi;
|
||||
console.log("range", range)
|
||||
console.log("anchor", cfi)
|
||||
|
||||
// Update the History Location
|
||||
if(this.settings.history &&
|
||||
window.location.hash != cfiFragment) {
|
||||
// Add CFI fragment to the history
|
||||
history.pushState({}, '', cfiFragment);
|
||||
}};
|
||||
}
|
||||
};
|
||||
|
||||
//-- Enable binding events to reader
|
||||
RSVP.EventTarget.mixin(EPUBJS.Reader.prototype);
|
||||
|
@ -455,6 +478,293 @@ EPUBJS.reader.MetaController = function(meta) {
|
|||
$author.html(author);
|
||||
$dash.show();
|
||||
};
|
||||
EPUBJS.reader.NotesController = function() {
|
||||
var book = this.book;
|
||||
var reader = this;
|
||||
var $notesView = $("#notesView");
|
||||
var $notes = $("#notes");
|
||||
var $text = $("#note-text");
|
||||
var $anchor = $("#note-anchor");
|
||||
var annotations = reader.settings.annotations;
|
||||
var renderer = book.renderer;
|
||||
var popups = [];
|
||||
var epubcfi = new EPUBJS.EpubCFI();
|
||||
|
||||
var show = function() {
|
||||
$notesView.show();
|
||||
};
|
||||
|
||||
var hide = function() {
|
||||
$notesView.hide();
|
||||
}
|
||||
|
||||
var insertAtPoint = function(e) {
|
||||
var range;
|
||||
var textNode;
|
||||
var offset;
|
||||
var doc = book.renderer.doc;
|
||||
var cfi;
|
||||
var annotation;
|
||||
|
||||
// standard
|
||||
if (doc.caretPositionFromPoint) {
|
||||
range = doc.caretPositionFromPoint(e.clientX, e.clientY);
|
||||
textNode = range.offsetNode;
|
||||
offset = range.offset;
|
||||
// WebKit
|
||||
} else if (doc.caretRangeFromPoint) {
|
||||
range = doc.caretRangeFromPoint(e.clientX, e.clientY);
|
||||
textNode = range.startContainer;
|
||||
offset = range.startOffset;
|
||||
}
|
||||
|
||||
if (textNode.nodeType !== 3) {
|
||||
for (var i=0; i < textNode.childNodes.length; i++) {
|
||||
if (textNode.childNodes[i].nodeType == 3) {
|
||||
textNode = textNode.childNodes[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find the end of the sentance
|
||||
offset = textNode.textContent.indexOf(".", offset);
|
||||
if(offset === -1){
|
||||
offset = textNode.length; // Last item
|
||||
} else {
|
||||
offset += 1; // After the period
|
||||
}
|
||||
|
||||
cfi = epubcfi.generateCfiFromTextNode(textNode, offset, book.renderer.currentChapter.cfiBase);
|
||||
|
||||
annotation = {
|
||||
annotatedAt: new Date(),
|
||||
anchor: cfi,
|
||||
body: $text.val()
|
||||
}
|
||||
|
||||
// add to list
|
||||
reader.addNote(annotation);
|
||||
|
||||
// attach
|
||||
addAnnotation(annotation);
|
||||
placeMarker(annotation);
|
||||
|
||||
// clear
|
||||
$text.val('');
|
||||
$anchor.text("Attach");
|
||||
$text.prop("disabled", false);
|
||||
|
||||
book.off("renderer:click", insertAtPoint);
|
||||
|
||||
};
|
||||
|
||||
var addAnnotation = function(annotation){
|
||||
var note = document.createElement("li");
|
||||
var link = document.createElement("a");
|
||||
|
||||
note.innerHTML = annotation.body;
|
||||
// note.setAttribute("ref", annotation.anchor);
|
||||
link.innerHTML = " context »";
|
||||
link.href = "#"+annotation.anchor;
|
||||
link.onclick = function(){
|
||||
book.gotoCfi(annotation.anchor);
|
||||
return false;
|
||||
};
|
||||
|
||||
note.appendChild(link);
|
||||
$notes.append(note);
|
||||
|
||||
};
|
||||
|
||||
var placeMarker = function(annotation){
|
||||
var doc = book.renderer.doc;
|
||||
var marker = document.createElement("span");
|
||||
var mark = document.createElement("a");
|
||||
marker.classList.add("footnotesuperscript", "reader_generated");
|
||||
|
||||
marker.style.verticalAlign = "super";
|
||||
marker.style.fontSize = ".75em";
|
||||
marker.style.position = "relative";
|
||||
marker.style.lineHeight = "1em";
|
||||
|
||||
mark.style.display = "inline-block";
|
||||
mark.style.padding = "2px";
|
||||
mark.style.backgroundColor = "#fffa96";
|
||||
mark.style.borderRadius = "5px";
|
||||
mark.style.cursor = "pointer";
|
||||
|
||||
marker.id = annotation.anchor;
|
||||
mark.innerHTML = annotations.indexOf(annotation) + 1 + "[Reader]";
|
||||
|
||||
marker.appendChild(mark);
|
||||
epubcfi.addMarker(annotation.anchor, doc, marker);
|
||||
|
||||
markerEvents(marker, annotation.body);
|
||||
}
|
||||
|
||||
var markerEvents = function(item, txt){
|
||||
var id = item.id;
|
||||
|
||||
var showPop = function(){
|
||||
var poppos,
|
||||
iheight = renderer.height,
|
||||
iwidth = renderer.width,
|
||||
tip,
|
||||
pop,
|
||||
maxHeight = 225,
|
||||
itemRect,
|
||||
left,
|
||||
top,
|
||||
pos;
|
||||
|
||||
|
||||
//-- create a popup with endnote inside of it
|
||||
if(!popups[id]) {
|
||||
popups[id] = document.createElement("div");
|
||||
popups[id].setAttribute("class", "popup");
|
||||
|
||||
pop_content = document.createElement("div");
|
||||
|
||||
popups[id].appendChild(pop_content);
|
||||
|
||||
pop_content.innerHTML = txt;
|
||||
pop_content.setAttribute("class", "pop_content");
|
||||
|
||||
renderer.render.document.body.appendChild(popups[id]);
|
||||
|
||||
//-- TODO: will these leak memory? - Fred
|
||||
popups[id].addEventListener("mouseover", onPop, false);
|
||||
popups[id].addEventListener("mouseout", offPop, false);
|
||||
|
||||
//-- Add hide on page change
|
||||
renderer.on("renderer:locationChanged", hidePop, this);
|
||||
renderer.on("renderer:locationChanged", offPop, this);
|
||||
// chapter.book.on("renderer:chapterDestroy", hidePop, this);
|
||||
}
|
||||
|
||||
pop = popups[id];
|
||||
|
||||
|
||||
//-- get location of item
|
||||
itemRect = item.getBoundingClientRect();
|
||||
left = itemRect.left;
|
||||
top = itemRect.top;
|
||||
|
||||
//-- show the popup
|
||||
pop.classList.add("show");
|
||||
|
||||
//-- locations of popup
|
||||
popRect = pop.getBoundingClientRect();
|
||||
|
||||
//-- position the popup
|
||||
pop.style.left = left - popRect.width / 2 + "px";
|
||||
pop.style.top = top + "px";
|
||||
|
||||
|
||||
//-- Adjust max height
|
||||
if(maxHeight > iheight / 2.5) {
|
||||
maxHeight = iheight / 2.5;
|
||||
pop_content.style.maxHeight = maxHeight + "px";
|
||||
}
|
||||
|
||||
//-- switch above / below
|
||||
if(popRect.height + top >= iheight - 25) {
|
||||
pop.style.top = top - popRect.height + "px";
|
||||
pop.classList.add("above");
|
||||
}else{
|
||||
pop.classList.remove("above");
|
||||
}
|
||||
|
||||
//-- switch left
|
||||
if(left - popRect.width <= 0) {
|
||||
pop.style.left = left + "px";
|
||||
pop.classList.add("left");
|
||||
}else{
|
||||
pop.classList.remove("left");
|
||||
}
|
||||
|
||||
//-- switch right
|
||||
if(left + popRect.width / 2 >= iwidth) {
|
||||
//-- TEMP MOVE: 300
|
||||
pop.style.left = left - 300 + "px";
|
||||
|
||||
popRect = pop.getBoundingClientRect();
|
||||
pop.style.left = left - popRect.width + "px";
|
||||
//-- switch above / below again
|
||||
if(popRect.height + top >= iheight - 25) {
|
||||
pop.style.top = top - popRect.height + "px";
|
||||
pop.classList.add("above");
|
||||
}else{
|
||||
pop.classList.remove("above");
|
||||
}
|
||||
|
||||
pop.classList.add("right");
|
||||
}else{
|
||||
pop.classList.remove("right");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var onPop = function(){
|
||||
popups[id].classList.add("on");
|
||||
}
|
||||
|
||||
var offPop = function(){
|
||||
popups[id].classList.remove("on");
|
||||
}
|
||||
|
||||
var hidePop = function(){
|
||||
setTimeout(function(){
|
||||
popups[id].classList.remove("show");
|
||||
}, 100);
|
||||
}
|
||||
|
||||
var openSidebar = function(){
|
||||
reader.ReaderController.slideOut();
|
||||
show();
|
||||
};
|
||||
|
||||
item.addEventListener("mouseover", showPop, false);
|
||||
item.addEventListener("mouseout", hidePop, false);
|
||||
item.addEventListener("click", openSidebar, false);
|
||||
|
||||
}
|
||||
$anchor.on("click", function(e){
|
||||
|
||||
$anchor.text("Cancel");
|
||||
$text.prop("disabled", "true");
|
||||
// listen for selection
|
||||
book.on("renderer:click", insertAtPoint);
|
||||
|
||||
});
|
||||
|
||||
annotations.forEach(function(note) {
|
||||
addAnnotation(note);
|
||||
});
|
||||
|
||||
|
||||
renderer.registerHook("beforeChapterDisplay", function(callback, renderer){
|
||||
var chapter = renderer.currentChapter;
|
||||
annotations.forEach(function(note) {
|
||||
var cfi = epubcfi.parse(note.anchor);
|
||||
if(cfi.spinePos === chapter.spinePos) {
|
||||
try {
|
||||
placeMarker(note);
|
||||
} catch(e) {
|
||||
console.log("anchoring failed", note.anchor);
|
||||
}
|
||||
}
|
||||
});
|
||||
callback();
|
||||
}, true);
|
||||
|
||||
|
||||
return {
|
||||
"show" : show,
|
||||
"hide" : hide
|
||||
};
|
||||
};
|
||||
EPUBJS.reader.ReaderController = function(book) {
|
||||
var $main = $("#main"),
|
||||
$divider = $("#divider"),
|
||||
|
@ -462,18 +772,26 @@ EPUBJS.reader.ReaderController = function(book) {
|
|||
$next = $("#next"),
|
||||
$prev = $("#prev");
|
||||
var reader = this;
|
||||
|
||||
var book = this.book;
|
||||
var slideIn = function() {
|
||||
var currentPosition = book.getCurrentLocationCfi();
|
||||
if (reader.settings.sidebarReflow){
|
||||
$main.removeClass('single');
|
||||
$main.one("transitionend", function(){
|
||||
book.gotoCfi(currentPosition);
|
||||
});
|
||||
} else {
|
||||
$main.removeClass("closed");
|
||||
}
|
||||
};
|
||||
|
||||
var slideOut = function() {
|
||||
var currentPosition = book.getCurrentLocationCfi();
|
||||
if (reader.settings.sidebarReflow){
|
||||
$main.addClass('single');
|
||||
$main.one("transitionend", function(){
|
||||
book.gotoCfi(currentPosition);
|
||||
});
|
||||
} else {
|
||||
$main.addClass("closed");
|
||||
}
|
||||
|
|
|
@ -28,8 +28,8 @@ body {
|
|||
border-radius: 5px;
|
||||
background: #fff;
|
||||
overflow: hidden;
|
||||
-webkit-transition: -webkit-transform .5s, width .5s;
|
||||
-moz-transition: -webkit-transform .5s, width .5s;
|
||||
-webkit-transition: -webkit-transform .4s, width .2s;
|
||||
-moz-transition: -webkit-transform .4s, width .2s;
|
||||
|
||||
-moz-box-shadow: inset 0 0 50px rgba(0,0,0,.1);
|
||||
-webkit-box-shadow: inset 0 0 50px rgba(0,0,0,.1);
|
||||
|
@ -170,6 +170,11 @@ body {
|
|||
width: 75%;
|
||||
}
|
||||
|
||||
#main.single #viewer {
|
||||
/* width: 60%;
|
||||
margin-left: 20%; */
|
||||
}
|
||||
|
||||
#panels {
|
||||
background: #4e4e4e;
|
||||
position: absolute;
|
||||
|
@ -288,7 +293,6 @@ input:-moz-placeholder {
|
|||
min-width: 300px;
|
||||
width: 25%;
|
||||
height: 100%;
|
||||
padding-top: 40px;
|
||||
visibility: hidden;
|
||||
-webkit-transition: visibility 0 ease .5s;
|
||||
-moz-transition: visibility 0 ease .5s;
|
||||
|
@ -304,6 +308,10 @@ input:-moz-placeholder {
|
|||
-moz-transition: visibility 0 ease 0;
|
||||
}
|
||||
|
||||
#sidebar.open #tocView {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#tocView > ul,
|
||||
#bookmarksView > ul {
|
||||
margin-top: 15px;
|
||||
|
@ -385,14 +393,15 @@ input:-moz-placeholder {
|
|||
content: '▾';
|
||||
}
|
||||
|
||||
#searchView {
|
||||
.view {
|
||||
width: 300px;
|
||||
height: 100%;
|
||||
display: none;
|
||||
padding-top: 50px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#searchResults {
|
||||
margin-top: 50px;
|
||||
margin-bottom: 50px;
|
||||
padding-left: 20px;
|
||||
display: block;
|
||||
|
@ -434,6 +443,51 @@ input:-moz-placeholder {
|
|||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
#notes {
|
||||
padding: 0 0 0 34px;
|
||||
}
|
||||
|
||||
#notes li {
|
||||
color: #eee;
|
||||
font-size: 12px;
|
||||
width: 240px;
|
||||
border-top: 1px #fff solid;
|
||||
padding-top: 6px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
#notes li a {
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
#notes li a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#notes li img {
|
||||
max-width: 240px;
|
||||
}
|
||||
|
||||
#note-text {
|
||||
display: block;
|
||||
width: 260px;
|
||||
height: 80px;
|
||||
margin: 0 auto;
|
||||
padding: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#note-text[disabled], #note-text[disabled="disabled"]{
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
#note-anchor {
|
||||
margin-left: 218px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#settingsPanel {
|
||||
display:none;
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@
|
|||
<script src="../reader/controllers/settings_controller.js"></script>
|
||||
<script src="../reader/controllers/sidebar_controller.js"></script>
|
||||
<script src="../reader/controllers/toc_controller.js"></script>
|
||||
<script src="../reader/controllers/notes_controller.js"></script>
|
||||
|
||||
<!-- Full Screen -->
|
||||
<script src="js/libs/screenfull.min.js"></script>
|
||||
|
@ -83,6 +84,9 @@
|
|||
<script src="js/libs/jquery.highlight.js"></script>
|
||||
<script async src="../hooks/extensions/highlight.js"></script>
|
||||
|
||||
<!-- Plugins -->
|
||||
<script src="../reader/plugins/search.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="sidebar">
|
||||
|
@ -95,14 +99,21 @@
|
|||
<a id="show-Notes" class="show_view icon-edit" data-view="Notes">Notes</a>
|
||||
|
||||
</div>
|
||||
<div id="tocView">
|
||||
<div id="tocView" class="view">
|
||||
</div>
|
||||
<div id="searchView">
|
||||
<div id="searchView" class="view">
|
||||
<ul id="searchResults"></ul>
|
||||
</div>
|
||||
<div id="bookmarksView">
|
||||
<div id="bookmarksView" class="view">
|
||||
<ul id="bookmarks"></ul>
|
||||
</div>
|
||||
<div id="notesView" class="view">
|
||||
<div id="new-note">
|
||||
<textarea id="note-text"></textarea>
|
||||
<button id="note-anchor">Anchor</button>
|
||||
</div>
|
||||
<ol id="notes"></ol>
|
||||
</div>
|
||||
</div>
|
||||
<div id="main">
|
||||
|
||||
|
|
|
@ -40,6 +40,13 @@
|
|||
<!-- Reader -->
|
||||
<script src="js/reader.min.js"></script>
|
||||
|
||||
<!-- Plugins -->
|
||||
<script src="js/plugins/search.js"></script>
|
||||
|
||||
<!-- Highlights -->
|
||||
<script src="js/libs/jquery.highlight.js"></script>
|
||||
<script src="js/hooks/extensions/highlight.js"></script>
|
||||
|
||||
<!-- File Storage -->
|
||||
<!-- <script src="js/libs/fileStorage.min.js"></script> -->
|
||||
|
||||
|
@ -58,14 +65,21 @@
|
|||
<a id="show-Notes" class="show_view icon-edit" data-view="Notes">Notes</a>
|
||||
|
||||
</div>
|
||||
<div id="tocView">
|
||||
<div id="tocView" class="view">
|
||||
</div>
|
||||
<div id="searchView">
|
||||
<div id="searchView" class="view">
|
||||
<ul id="searchResults"></ul>
|
||||
</div>
|
||||
<div id="bookmarksView">
|
||||
<div id="bookmarksView" class="view">
|
||||
<ul id="bookmarks"></ul>
|
||||
</div>
|
||||
<div id="notesView" class="view">
|
||||
<div id="new-note">
|
||||
<textarea id="note-text"></textarea>
|
||||
<button id="note-anchor">Anchor</button>
|
||||
</div>
|
||||
<ol id="notes"></ol>
|
||||
</div>
|
||||
</div>
|
||||
<div id="main">
|
||||
|
||||
|
|
4
demo/js/epub.min.js
vendored
4
demo/js/epub.min.js
vendored
File diff suppressed because one or more lines are too long
2
demo/js/hooks.min.js
vendored
2
demo/js/hooks.min.js
vendored
|
@ -1 +1 @@
|
|||
EPUBJS.Hooks.register("beforeChapterDisplay").endnotes=function(a,b){var c=b.contents.querySelectorAll("a[href]"),d=Array.prototype.slice.call(c),e="epub:type",f="noteref",g=EPUBJS.core.folder(location.pathname),h=g+EPUBJS.cssPath||g,i={};EPUBJS.core.addCss(h+"popup.css",!1,b.render.document.head),d.forEach(function(a){function c(){var c,e=b.height,f=b.width,j=225;o||(c=l.cloneNode(!0),o=c.querySelector("p")),i[k]||(i[k]=document.createElement("div"),i[k].setAttribute("class","popup"),pop_content=document.createElement("div"),i[k].appendChild(pop_content),pop_content.appendChild(o),pop_content.setAttribute("class","pop_content"),b.render.document.body.appendChild(i[k]),i[k].addEventListener("mouseover",d,!1),i[k].addEventListener("mouseout",g,!1),b.on("renderer:pageChanged",h,this),b.on("renderer:pageChanged",g,this)),c=i[k],itemRect=a.getBoundingClientRect(),m=itemRect.left,n=itemRect.top,c.classList.add("show"),popRect=c.getBoundingClientRect(),c.style.left=m-popRect.width/2+"px",c.style.top=n+"px",j>e/2.5&&(j=e/2.5,pop_content.style.maxHeight=j+"px"),popRect.height+n>=e-25?(c.style.top=n-popRect.height+"px",c.classList.add("above")):c.classList.remove("above"),m-popRect.width<=0?(c.style.left=m+"px",c.classList.add("left")):c.classList.remove("left"),m+popRect.width/2>=f?(c.style.left=m-300+"px",popRect=c.getBoundingClientRect(),c.style.left=m-popRect.width+"px",popRect.height+n>=e-25?(c.style.top=n-popRect.height+"px",c.classList.add("above")):c.classList.remove("above"),c.classList.add("right")):c.classList.remove("right")}function d(){i[k].classList.add("on")}function g(){i[k].classList.remove("on")}function h(){setTimeout(function(){i[k].classList.remove("show")},100)}var j,k,l,m,n,o,p=a.getAttribute(e);p==f&&(j=a.getAttribute("href"),k=j.replace("#",""),l=b.render.document.getElementById(k),a.addEventListener("mouseover",c,!1),a.addEventListener("mouseout",h,!1))}),a&&a()},EPUBJS.Hooks.register("beforeChapterDisplay").mathml=function(a,b){if(-1!==b.currentChapter.manifestProperties.indexOf("mathml")){b.iframe.contentWindow.mathmlCallback=a;var c=document.createElement("script");c.type="text/x-mathjax-config",c.innerHTML=' MathJax.Hub.Register.StartupHook("End",function () { window.mathmlCallback(); }); MathJax.Hub.Config({jax: ["input/TeX","input/MathML","output/SVG"],extensions: ["tex2jax.js","mml2jax.js","MathEvents.js"],TeX: {extensions: ["noErrors.js","noUndefined.js","autoload-all.js"]},MathMenu: {showRenderer: false},menuSettings: {zoom: "Click"},messageStyle: "none"}); ',b.doc.body.appendChild(c),EPUBJS.core.addScript("http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML",null,b.doc.head)}else a&&a()},EPUBJS.Hooks.register("beforeChapterDisplay").smartimages=function(a,b){var c=b.contents.querySelectorAll("img"),d=Array.prototype.slice.call(c),e=b.height;return"reflowable"!=b.layoutSettings.layout?(a(),void 0):(d.forEach(function(a){function c(){var c,d=a.getBoundingClientRect(),f=d.height,g=d.top,h=a.getAttribute("data-height"),i=h||f,j=Number(getComputedStyle(a,"").fontSize.match(/(\d*(\.\d*)?)px/)[1]),k=j?j/2:0;e=b.contents.clientHeight,0>g&&(g=0),i+g>=e?(e/2>g?(c=e-g-k,a.style.maxHeight=c+"px",a.style.width="auto"):(i>e&&(a.style.maxHeight=e+"px",a.style.width="auto",d=a.getBoundingClientRect(),i=d.height),a.style.display="block",a.style.WebkitColumnBreakBefore="always",a.style.breakBefore="column"),a.setAttribute("data-height",c)):(a.style.removeProperty("max-height"),a.style.removeProperty("margin-top"))}a.addEventListener("load",c,!1),b.on("renderer:resized",c),b.on("renderer:chapterUnloaded",function(){a.removeEventListener("load",c),b.off("renderer:resized",c)}),c()}),a&&a(),void 0)},EPUBJS.Hooks.register("beforeChapterDisplay").transculsions=function(a,b){var c=b.contents.querySelectorAll("[transclusion]"),d=Array.prototype.slice.call(c);d.forEach(function(a){function c(){j=g,k=h,j>chapter.colWidth&&(d=chapter.colWidth/j,j=chapter.colWidth,k*=d),f.width=j,f.height=k}var d,e=a.getAttribute("ref"),f=document.createElement("iframe"),g=a.getAttribute("width"),h=a.getAttribute("height"),i=a.parentNode,j=g,k=h;c(),b.listenUntil("renderer:resized","renderer:chapterUnloaded",c),f.src=e,i.replaceChild(f,a)}),a&&a()};
|
||||
EPUBJS.Hooks.register("beforeChapterDisplay").endnotes=function(a,b){var c=b.contents.querySelectorAll("a[href]"),d=Array.prototype.slice.call(c),e="epub:type",f="noteref",g=EPUBJS.core.folder(location.pathname),h=g+EPUBJS.cssPath||g,i={};EPUBJS.core.addCss(h+"popup.css",!1,b.render.document.head),d.forEach(function(a){function c(){var c,e,f=b.height,j=b.width,p=225;o||(c=l.cloneNode(!0),o=c.querySelector("p")),i[k]||(i[k]=document.createElement("div"),i[k].setAttribute("class","popup"),pop_content=document.createElement("div"),i[k].appendChild(pop_content),pop_content.appendChild(o),pop_content.setAttribute("class","pop_content"),b.render.document.body.appendChild(i[k]),i[k].addEventListener("mouseover",d,!1),i[k].addEventListener("mouseout",g,!1),b.on("renderer:pageChanged",h,this),b.on("renderer:pageChanged",g,this)),c=i[k],e=a.getBoundingClientRect(),m=e.left,n=e.top,c.classList.add("show"),popRect=c.getBoundingClientRect(),c.style.left=m-popRect.width/2+"px",c.style.top=n+"px",p>f/2.5&&(p=f/2.5,pop_content.style.maxHeight=p+"px"),popRect.height+n>=f-25?(c.style.top=n-popRect.height+"px",c.classList.add("above")):c.classList.remove("above"),m-popRect.width<=0?(c.style.left=m+"px",c.classList.add("left")):c.classList.remove("left"),m+popRect.width/2>=j?(c.style.left=m-300+"px",popRect=c.getBoundingClientRect(),c.style.left=m-popRect.width+"px",popRect.height+n>=f-25?(c.style.top=n-popRect.height+"px",c.classList.add("above")):c.classList.remove("above"),c.classList.add("right")):c.classList.remove("right")}function d(){i[k].classList.add("on")}function g(){i[k].classList.remove("on")}function h(){setTimeout(function(){i[k].classList.remove("show")},100)}var j,k,l,m,n,o,p=a.getAttribute(e);p==f&&(j=a.getAttribute("href"),k=j.replace("#",""),l=b.render.document.getElementById(k),a.addEventListener("mouseover",c,!1),a.addEventListener("mouseout",h,!1))}),a&&a()},EPUBJS.Hooks.register("beforeChapterDisplay").mathml=function(a,b){if(-1!==b.currentChapter.manifestProperties.indexOf("mathml")){b.iframe.contentWindow.mathmlCallback=a;var c=document.createElement("script");c.type="text/x-mathjax-config",c.innerHTML=' MathJax.Hub.Register.StartupHook("End",function () { window.mathmlCallback(); }); MathJax.Hub.Config({jax: ["input/TeX","input/MathML","output/SVG"],extensions: ["tex2jax.js","mml2jax.js","MathEvents.js"],TeX: {extensions: ["noErrors.js","noUndefined.js","autoload-all.js"]},MathMenu: {showRenderer: false},menuSettings: {zoom: "Click"},messageStyle: "none"}); ',b.doc.body.appendChild(c),EPUBJS.core.addScript("http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML",null,b.doc.head)}else a&&a()},EPUBJS.Hooks.register("beforeChapterDisplay").smartimages=function(a,b){var c=b.contents.querySelectorAll("img"),d=Array.prototype.slice.call(c),e=b.height;return"reflowable"!=b.layoutSettings.layout?(a(),void 0):(d.forEach(function(a){function c(){var c,d=a.getBoundingClientRect(),f=d.height,g=d.top,h=a.getAttribute("data-height"),i=h||f,j=Number(getComputedStyle(a,"").fontSize.match(/(\d*(\.\d*)?)px/)[1]),k=j?j/2:0;e=b.contents.clientHeight,0>g&&(g=0),i+g>=e?(e/2>g?(c=e-g-k,a.style.maxHeight=c+"px",a.style.width="auto"):(i>e&&(a.style.maxHeight=e+"px",a.style.width="auto",d=a.getBoundingClientRect(),i=d.height),a.style.display="block",a.style.WebkitColumnBreakBefore="always",a.style.breakBefore="column"),a.setAttribute("data-height",c)):(a.style.removeProperty("max-height"),a.style.removeProperty("margin-top"))}a.addEventListener("load",c,!1),b.on("renderer:resized",c),b.on("renderer:chapterUnloaded",function(){a.removeEventListener("load",c),b.off("renderer:resized",c)}),c()}),a&&a(),void 0)},EPUBJS.Hooks.register("beforeChapterDisplay").transculsions=function(a,b){var c=b.contents.querySelectorAll("[transclusion]"),d=Array.prototype.slice.call(c);d.forEach(function(a){function c(){j=g,k=h,j>chapter.colWidth&&(d=chapter.colWidth/j,j=chapter.colWidth,k*=d),f.width=j,f.height=k}var d,e=a.getAttribute("ref"),f=document.createElement("iframe"),g=a.getAttribute("width"),h=a.getAttribute("height"),i=a.parentNode,j=g,k=h;c(),b.listenUntil("renderer:resized","renderer:chapterUnloaded",c),f.src=e,i.replaceChild(f,a)}),a&&a()};
|
125
demo/js/plugins/search.js
Normal file
125
demo/js/plugins/search.js
Normal file
|
@ -0,0 +1,125 @@
|
|||
EPUBJS.reader.search = {};
|
||||
|
||||
// Search Server -- https://github.com/futurepress/epubjs-search
|
||||
EPUBJS.reader.search.SERVER = "https://pacific-cliffs-3579.herokuapp.com";
|
||||
|
||||
EPUBJS.reader.search.request = function(q, callback) {
|
||||
var fetch = $.ajax({
|
||||
dataType: "json",
|
||||
url: EPUBJS.reader.search.SERVER + "/search?q=" + encodeURIComponent(q)
|
||||
});
|
||||
|
||||
fetch.fail(function(err) {
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
fetch.done(function(results) {
|
||||
callback(results);
|
||||
});
|
||||
};
|
||||
|
||||
EPUBJS.reader.plugins.SearchController = function(Book) {
|
||||
var reader = this;
|
||||
|
||||
var $searchBox = $("#searchBox"),
|
||||
$searchResults = $("#searchResults"),
|
||||
$searchView = $("#searchView"),
|
||||
iframeDoc;
|
||||
|
||||
var searchShown = false;
|
||||
|
||||
var onShow = function() {
|
||||
query();
|
||||
searchShown = true;
|
||||
$searchView.addClass("shown");
|
||||
};
|
||||
|
||||
var onHide = function() {
|
||||
searchShown = false;
|
||||
$searchView.removeClass("shown");
|
||||
};
|
||||
|
||||
var query = function() {
|
||||
var q = $searchBox.val();
|
||||
|
||||
if(q == '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$searchResults.empty();
|
||||
$searchResults.append("<li><p>Searching...</p></li>");
|
||||
|
||||
|
||||
|
||||
EPUBJS.reader.search.request(q, function(data) {
|
||||
var results = data.results;
|
||||
|
||||
$searchResults.empty();
|
||||
|
||||
if(iframeDoc) {
|
||||
$(iframeDoc).find('body').unhighlight();
|
||||
}
|
||||
|
||||
if(results.length == 0) {
|
||||
$searchResults.append("<li><p>No Results Found</p></li>");
|
||||
return;
|
||||
}
|
||||
|
||||
iframeDoc = $("#viewer iframe")[0].contentDocument;
|
||||
$(iframeDoc).find('body').highlight(q, { element: 'span' });
|
||||
|
||||
results.forEach(function(result) {
|
||||
var $li = $("<li></li>");
|
||||
var $item = $("<a href='"+result.href+"' data-cfi='"+result.cfi+"'><span>"+result.title+"</span><p>"+result.highlight+"</p></a>");
|
||||
|
||||
$item.on("click", function(e) {
|
||||
var $this = $(this),
|
||||
cfi = $this.data("cfi");
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
Book.gotoCfi(cfi+"/1:0");
|
||||
|
||||
Book.on("renderer:chapterDisplayed", function() {
|
||||
iframeDoc = $("#viewer iframe")[0].contentDocument;
|
||||
$(iframeDoc).find('body').highlight(q, { element: 'span' });
|
||||
})
|
||||
|
||||
|
||||
|
||||
});
|
||||
$li.append($item);
|
||||
$searchResults.append($li);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
$searchBox.on("search", function(e) {
|
||||
var q = $searchBox.val();
|
||||
|
||||
//-- SearchBox is empty or cleared
|
||||
if(q == '') {
|
||||
$searchResults.empty();
|
||||
if(reader.SidebarController.getActivePanel() == "Search") {
|
||||
reader.SidebarController.changePanelTo("Toc");
|
||||
}
|
||||
|
||||
$(iframeDoc).find('body').unhighlight();
|
||||
iframeDoc = false;
|
||||
return;
|
||||
}
|
||||
|
||||
reader.SidebarController.changePanelTo("Search");
|
||||
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
|
||||
|
||||
return {
|
||||
"show" : onShow,
|
||||
"hide" : onHide
|
||||
};
|
||||
};
|
2
demo/js/reader.min.js
vendored
2
demo/js/reader.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -30,8 +30,11 @@
|
|||
<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="../src/replace.js"></script>
|
||||
<script src="../src/epubcfi.js"></script>
|
||||
<script src="../src/render_iframe.js"></script>
|
||||
<script src="../src/layout.js"></script>
|
||||
<script src="../src/pagination.js"></script>
|
||||
|
||||
<!-- Hooks -->
|
||||
<!-- <script src="../hooks/default/transculsions.js"></script> -->
|
||||
|
@ -63,6 +66,7 @@
|
|||
height: 80%;
|
||||
margin: 5% auto;
|
||||
max-width: 1250px;
|
||||
|
||||
}
|
||||
|
||||
#area iframe {
|
||||
|
|
|
@ -38,7 +38,8 @@ EPUBJS.Hooks.register("beforeChapterDisplay").endnotes = function(callback, rend
|
|||
iwidth = renderer.width,
|
||||
tip,
|
||||
pop,
|
||||
maxHeight = 225;
|
||||
maxHeight = 225,
|
||||
itemRect;
|
||||
|
||||
if(!txt) {
|
||||
pop = el.cloneNode(true);
|
||||
|
|
287
reader/controllers/notes_controller.js
Normal file
287
reader/controllers/notes_controller.js
Normal file
|
@ -0,0 +1,287 @@
|
|||
EPUBJS.reader.NotesController = function() {
|
||||
var book = this.book;
|
||||
var reader = this;
|
||||
var $notesView = $("#notesView");
|
||||
var $notes = $("#notes");
|
||||
var $text = $("#note-text");
|
||||
var $anchor = $("#note-anchor");
|
||||
var annotations = reader.settings.annotations;
|
||||
var renderer = book.renderer;
|
||||
var popups = [];
|
||||
var epubcfi = new EPUBJS.EpubCFI();
|
||||
|
||||
var show = function() {
|
||||
$notesView.show();
|
||||
};
|
||||
|
||||
var hide = function() {
|
||||
$notesView.hide();
|
||||
}
|
||||
|
||||
var insertAtPoint = function(e) {
|
||||
var range;
|
||||
var textNode;
|
||||
var offset;
|
||||
var doc = book.renderer.doc;
|
||||
var cfi;
|
||||
var annotation;
|
||||
|
||||
// standard
|
||||
if (doc.caretPositionFromPoint) {
|
||||
range = doc.caretPositionFromPoint(e.clientX, e.clientY);
|
||||
textNode = range.offsetNode;
|
||||
offset = range.offset;
|
||||
// WebKit
|
||||
} else if (doc.caretRangeFromPoint) {
|
||||
range = doc.caretRangeFromPoint(e.clientX, e.clientY);
|
||||
textNode = range.startContainer;
|
||||
offset = range.startOffset;
|
||||
}
|
||||
|
||||
if (textNode.nodeType !== 3) {
|
||||
for (var i=0; i < textNode.childNodes.length; i++) {
|
||||
if (textNode.childNodes[i].nodeType == 3) {
|
||||
textNode = textNode.childNodes[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find the end of the sentance
|
||||
offset = textNode.textContent.indexOf(".", offset);
|
||||
if(offset === -1){
|
||||
offset = textNode.length; // Last item
|
||||
} else {
|
||||
offset += 1; // After the period
|
||||
}
|
||||
|
||||
cfi = epubcfi.generateCfiFromTextNode(textNode, offset, book.renderer.currentChapter.cfiBase);
|
||||
|
||||
annotation = {
|
||||
annotatedAt: new Date(),
|
||||
anchor: cfi,
|
||||
body: $text.val()
|
||||
}
|
||||
|
||||
// add to list
|
||||
reader.addNote(annotation);
|
||||
|
||||
// attach
|
||||
addAnnotation(annotation);
|
||||
placeMarker(annotation);
|
||||
|
||||
// clear
|
||||
$text.val('');
|
||||
$anchor.text("Attach");
|
||||
$text.prop("disabled", false);
|
||||
|
||||
book.off("renderer:click", insertAtPoint);
|
||||
|
||||
};
|
||||
|
||||
var addAnnotation = function(annotation){
|
||||
var note = document.createElement("li");
|
||||
var link = document.createElement("a");
|
||||
|
||||
note.innerHTML = annotation.body;
|
||||
// note.setAttribute("ref", annotation.anchor);
|
||||
link.innerHTML = " context »";
|
||||
link.href = "#"+annotation.anchor;
|
||||
link.onclick = function(){
|
||||
book.gotoCfi(annotation.anchor);
|
||||
return false;
|
||||
};
|
||||
|
||||
note.appendChild(link);
|
||||
$notes.append(note);
|
||||
|
||||
};
|
||||
|
||||
var placeMarker = function(annotation){
|
||||
var doc = book.renderer.doc;
|
||||
var marker = document.createElement("span");
|
||||
var mark = document.createElement("a");
|
||||
marker.classList.add("footnotesuperscript", "reader_generated");
|
||||
|
||||
marker.style.verticalAlign = "super";
|
||||
marker.style.fontSize = ".75em";
|
||||
marker.style.position = "relative";
|
||||
marker.style.lineHeight = "1em";
|
||||
|
||||
mark.style.display = "inline-block";
|
||||
mark.style.padding = "2px";
|
||||
mark.style.backgroundColor = "#fffa96";
|
||||
mark.style.borderRadius = "5px";
|
||||
mark.style.cursor = "pointer";
|
||||
|
||||
marker.id = annotation.anchor;
|
||||
mark.innerHTML = annotations.indexOf(annotation) + 1 + "[Reader]";
|
||||
|
||||
marker.appendChild(mark);
|
||||
epubcfi.addMarker(annotation.anchor, doc, marker);
|
||||
|
||||
markerEvents(marker, annotation.body);
|
||||
}
|
||||
|
||||
var markerEvents = function(item, txt){
|
||||
var id = item.id;
|
||||
|
||||
var showPop = function(){
|
||||
var poppos,
|
||||
iheight = renderer.height,
|
||||
iwidth = renderer.width,
|
||||
tip,
|
||||
pop,
|
||||
maxHeight = 225,
|
||||
itemRect,
|
||||
left,
|
||||
top,
|
||||
pos;
|
||||
|
||||
|
||||
//-- create a popup with endnote inside of it
|
||||
if(!popups[id]) {
|
||||
popups[id] = document.createElement("div");
|
||||
popups[id].setAttribute("class", "popup");
|
||||
|
||||
pop_content = document.createElement("div");
|
||||
|
||||
popups[id].appendChild(pop_content);
|
||||
|
||||
pop_content.innerHTML = txt;
|
||||
pop_content.setAttribute("class", "pop_content");
|
||||
|
||||
renderer.render.document.body.appendChild(popups[id]);
|
||||
|
||||
//-- TODO: will these leak memory? - Fred
|
||||
popups[id].addEventListener("mouseover", onPop, false);
|
||||
popups[id].addEventListener("mouseout", offPop, false);
|
||||
|
||||
//-- Add hide on page change
|
||||
renderer.on("renderer:locationChanged", hidePop, this);
|
||||
renderer.on("renderer:locationChanged", offPop, this);
|
||||
// chapter.book.on("renderer:chapterDestroy", hidePop, this);
|
||||
}
|
||||
|
||||
pop = popups[id];
|
||||
|
||||
|
||||
//-- get location of item
|
||||
itemRect = item.getBoundingClientRect();
|
||||
left = itemRect.left;
|
||||
top = itemRect.top;
|
||||
|
||||
//-- show the popup
|
||||
pop.classList.add("show");
|
||||
|
||||
//-- locations of popup
|
||||
popRect = pop.getBoundingClientRect();
|
||||
|
||||
//-- position the popup
|
||||
pop.style.left = left - popRect.width / 2 + "px";
|
||||
pop.style.top = top + "px";
|
||||
|
||||
|
||||
//-- Adjust max height
|
||||
if(maxHeight > iheight / 2.5) {
|
||||
maxHeight = iheight / 2.5;
|
||||
pop_content.style.maxHeight = maxHeight + "px";
|
||||
}
|
||||
|
||||
//-- switch above / below
|
||||
if(popRect.height + top >= iheight - 25) {
|
||||
pop.style.top = top - popRect.height + "px";
|
||||
pop.classList.add("above");
|
||||
}else{
|
||||
pop.classList.remove("above");
|
||||
}
|
||||
|
||||
//-- switch left
|
||||
if(left - popRect.width <= 0) {
|
||||
pop.style.left = left + "px";
|
||||
pop.classList.add("left");
|
||||
}else{
|
||||
pop.classList.remove("left");
|
||||
}
|
||||
|
||||
//-- switch right
|
||||
if(left + popRect.width / 2 >= iwidth) {
|
||||
//-- TEMP MOVE: 300
|
||||
pop.style.left = left - 300 + "px";
|
||||
|
||||
popRect = pop.getBoundingClientRect();
|
||||
pop.style.left = left - popRect.width + "px";
|
||||
//-- switch above / below again
|
||||
if(popRect.height + top >= iheight - 25) {
|
||||
pop.style.top = top - popRect.height + "px";
|
||||
pop.classList.add("above");
|
||||
}else{
|
||||
pop.classList.remove("above");
|
||||
}
|
||||
|
||||
pop.classList.add("right");
|
||||
}else{
|
||||
pop.classList.remove("right");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var onPop = function(){
|
||||
popups[id].classList.add("on");
|
||||
}
|
||||
|
||||
var offPop = function(){
|
||||
popups[id].classList.remove("on");
|
||||
}
|
||||
|
||||
var hidePop = function(){
|
||||
setTimeout(function(){
|
||||
popups[id].classList.remove("show");
|
||||
}, 100);
|
||||
}
|
||||
|
||||
var openSidebar = function(){
|
||||
reader.ReaderController.slideOut();
|
||||
show();
|
||||
};
|
||||
|
||||
item.addEventListener("mouseover", showPop, false);
|
||||
item.addEventListener("mouseout", hidePop, false);
|
||||
item.addEventListener("click", openSidebar, false);
|
||||
|
||||
}
|
||||
$anchor.on("click", function(e){
|
||||
|
||||
$anchor.text("Cancel");
|
||||
$text.prop("disabled", "true");
|
||||
// listen for selection
|
||||
book.on("renderer:click", insertAtPoint);
|
||||
|
||||
});
|
||||
|
||||
annotations.forEach(function(note) {
|
||||
addAnnotation(note);
|
||||
});
|
||||
|
||||
|
||||
renderer.registerHook("beforeChapterDisplay", function(callback, renderer){
|
||||
var chapter = renderer.currentChapter;
|
||||
annotations.forEach(function(note) {
|
||||
var cfi = epubcfi.parse(note.anchor);
|
||||
if(cfi.spinePos === chapter.spinePos) {
|
||||
try {
|
||||
placeMarker(note);
|
||||
} catch(e) {
|
||||
console.log("anchoring failed", note.anchor);
|
||||
}
|
||||
}
|
||||
});
|
||||
callback();
|
||||
}, true);
|
||||
|
||||
|
||||
return {
|
||||
"show" : show,
|
||||
"hide" : hide
|
||||
};
|
||||
};
|
|
@ -5,18 +5,26 @@ EPUBJS.reader.ReaderController = function(book) {
|
|||
$next = $("#next"),
|
||||
$prev = $("#prev");
|
||||
var reader = this;
|
||||
|
||||
var book = this.book;
|
||||
var slideIn = function() {
|
||||
var currentPosition = book.getCurrentLocationCfi();
|
||||
if (reader.settings.sidebarReflow){
|
||||
$main.removeClass('single');
|
||||
$main.one("transitionend", function(){
|
||||
book.gotoCfi(currentPosition);
|
||||
});
|
||||
} else {
|
||||
$main.removeClass("closed");
|
||||
}
|
||||
};
|
||||
|
||||
var slideOut = function() {
|
||||
var currentPosition = book.getCurrentLocationCfi();
|
||||
if (reader.settings.sidebarReflow){
|
||||
$main.addClass('single');
|
||||
$main.one("transitionend", function(){
|
||||
book.gotoCfi(currentPosition);
|
||||
});
|
||||
} else {
|
||||
$main.addClass("closed");
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
EPUBJS.reader.search = {};
|
||||
|
||||
// Search Server -- https://github.com/futurepress/epubjs-search
|
||||
EPUBJS.reader.search.SERVER = "http://localhost:5000";
|
||||
EPUBJS.reader.search.SERVER = "https://pacific-cliffs-3579.herokuapp.com";
|
||||
|
||||
EPUBJS.reader.search.request = function(q, callback) {
|
||||
var fetch = $.ajax({
|
||||
|
@ -78,7 +78,7 @@ EPUBJS.reader.plugins.SearchController = function(Book) {
|
|||
|
||||
e.preventDefault();
|
||||
|
||||
Book.gotoCfi(cfi);
|
||||
Book.gotoCfi(cfi+"/1:0");
|
||||
|
||||
Book.on("renderer:chapterDisplayed", function() {
|
||||
iframeDoc = $("#viewer iframe")[0].contentDocument;
|
||||
|
|
|
@ -36,6 +36,7 @@ EPUBJS.Reader = function(path, _options) {
|
|||
restore : true,
|
||||
reload : false,
|
||||
bookmarks : null,
|
||||
annotations : null,
|
||||
contained : null,
|
||||
bookKey : null,
|
||||
styles : null,
|
||||
|
@ -73,6 +74,10 @@ EPUBJS.Reader = function(path, _options) {
|
|||
this.settings.bookmarks = [];
|
||||
}
|
||||
|
||||
if(!this.settings.annotations) {
|
||||
this.settings.annotations = [];
|
||||
}
|
||||
|
||||
if(this.settings.generatePagination) {
|
||||
book.generatePagination($viewer.width(), $viewer.height());
|
||||
}
|
||||
|
@ -84,6 +89,7 @@ EPUBJS.Reader = function(path, _options) {
|
|||
reader.ControlsController = EPUBJS.reader.ControlsController.call(reader, book);
|
||||
reader.SidebarController = EPUBJS.reader.SidebarController.call(reader, book);
|
||||
reader.BookmarksController = EPUBJS.reader.BookmarksController.call(reader, book);
|
||||
reader.NotesController = EPUBJS.reader.NotesController.call(reader, book);
|
||||
|
||||
// Call Plugins
|
||||
for(plugin in EPUBJS.reader.plugins) {
|
||||
|
@ -193,6 +199,23 @@ EPUBJS.Reader.prototype.clearBookmarks = function() {
|
|||
this.settings.bookmarks = [];
|
||||
};
|
||||
|
||||
//-- Notes
|
||||
EPUBJS.Reader.prototype.addNote = function(note) {
|
||||
this.settings.annotations.push(note);
|
||||
};
|
||||
|
||||
EPUBJS.Reader.prototype.removeNote = function(note) {
|
||||
var index = this.settings.annotations.indexOf(note);
|
||||
if( index === -1 ) return;
|
||||
|
||||
delete this.settings.annotations[index];
|
||||
|
||||
};
|
||||
|
||||
EPUBJS.Reader.prototype.clearNotes = function() {
|
||||
this.settings.annotations = [];
|
||||
};
|
||||
|
||||
//-- Settings
|
||||
EPUBJS.Reader.prototype.setBookKey = function(identifier){
|
||||
if(!this.settings.bookKey) {
|
||||
|
@ -203,10 +226,15 @@ EPUBJS.Reader.prototype.setBookKey = function(identifier){
|
|||
|
||||
//-- Checks if the book setting can be retrieved from localStorage
|
||||
EPUBJS.Reader.prototype.isSaved = function(bookPath) {
|
||||
var storedSettings = localStorage.getItem(this.settings.bookKey);
|
||||
var storedSettings;
|
||||
|
||||
if( !localStorage ||
|
||||
storedSettings === null) {
|
||||
if(!localStorage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
storedSettings = localStorage.getItem(this.settings.bookKey);
|
||||
|
||||
if(storedSettings === null) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
|
@ -214,11 +242,21 @@ EPUBJS.Reader.prototype.isSaved = function(bookPath) {
|
|||
};
|
||||
|
||||
EPUBJS.Reader.prototype.removeSavedSettings = function() {
|
||||
if(!localStorage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
localStorage.removeItem(this.settings.bookKey);
|
||||
};
|
||||
|
||||
EPUBJS.Reader.prototype.applySavedSettings = function() {
|
||||
var stored = JSON.parse(localStorage.getItem(this.settings.bookKey));
|
||||
var stored;
|
||||
|
||||
if(!localStorage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
stored = JSON.parse(localStorage.getItem(this.settings.bookKey));
|
||||
|
||||
if(stored) {
|
||||
this.settings = _.defaults(this.settings, stored);
|
||||
|
@ -233,11 +271,15 @@ EPUBJS.Reader.prototype.saveSettings = function(){
|
|||
this.settings.previousLocationCfi = this.book.getCurrentLocationCfi();
|
||||
}
|
||||
|
||||
if(!localStorage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
localStorage.setItem(this.settings.bookKey, JSON.stringify(this.settings));
|
||||
};
|
||||
|
||||
EPUBJS.Reader.prototype.unload = function(){
|
||||
if(this.settings.restore) {
|
||||
if(this.settings.restore && localStorage) {
|
||||
this.saveSettings();
|
||||
}
|
||||
};
|
||||
|
@ -250,16 +292,16 @@ EPUBJS.Reader.prototype.hashChanged = function(){
|
|||
|
||||
EPUBJS.Reader.prototype.selectedRange = function(range){
|
||||
var epubcfi = new EPUBJS.EpubCFI();
|
||||
var cfi = epubcfi.generateCfiFromElement(range.anchorNode.parentElement, this.book.renderer.currentChapter.cfiBase);
|
||||
var cfi = epubcfi.generateCfiFromRangeAnchor(range, this.book.renderer.currentChapter.cfiBase);
|
||||
var cfiFragment = "#"+cfi;
|
||||
console.log("range", range)
|
||||
console.log("anchor", cfi)
|
||||
|
||||
// Update the History Location
|
||||
if(this.settings.history &&
|
||||
window.location.hash != cfiFragment) {
|
||||
// Add CFI fragment to the history
|
||||
history.pushState({}, '', cfiFragment);
|
||||
}};
|
||||
}
|
||||
};
|
||||
|
||||
//-- Enable binding events to reader
|
||||
RSVP.EventTarget.mixin(EPUBJS.Reader.prototype);
|
18
src/book.js
18
src/book.js
|
@ -143,7 +143,7 @@ EPUBJS.Book.prototype.open = function(bookPath, forceReload){
|
|||
epubpackage = this.loadPackage();
|
||||
}
|
||||
|
||||
if(this.settings.restore && !forceReload){
|
||||
if(this.settings.restore && !forceReload && localStorage){
|
||||
//-- Will load previous package json, or re-unpack if error
|
||||
epubpackage.then(function(packageXml) {
|
||||
var identifier = book.packageIdentifier(packageXml);
|
||||
|
@ -559,7 +559,13 @@ EPUBJS.Book.prototype.isContained = function(bookUrl){
|
|||
|
||||
//-- Checks if the book can be retrieved from localStorage
|
||||
EPUBJS.Book.prototype.isSaved = function(bookKey) {
|
||||
var storedSettings = localStorage.getItem(bookKey);
|
||||
var storedSettings;
|
||||
|
||||
if(!localStorage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
storedSettings = localStorage.getItem(bookKey);
|
||||
|
||||
if( !localStorage ||
|
||||
storedSettings === null) {
|
||||
|
@ -575,10 +581,16 @@ EPUBJS.Book.prototype.generateBookKey = function(identifier){
|
|||
};
|
||||
|
||||
EPUBJS.Book.prototype.saveContents = function(){
|
||||
if(!localStorage) {
|
||||
return false;
|
||||
}
|
||||
localStorage.setItem(this.settings.bookKey, JSON.stringify(this.contents));
|
||||
};
|
||||
|
||||
EPUBJS.Book.prototype.removeSavedContents = function() {
|
||||
if(!localStorage) {
|
||||
return false;
|
||||
}
|
||||
localStorage.removeItem(this.settings.bookKey);
|
||||
};
|
||||
|
||||
|
@ -1028,7 +1040,7 @@ EPUBJS.Book.prototype.forceSingle = function(use) {
|
|||
|
||||
EPUBJS.Book.prototype.unload = function(){
|
||||
|
||||
if(this.settings.restore) {
|
||||
if(this.settings.restore && localStorage) {
|
||||
this.saveContents();
|
||||
}
|
||||
|
||||
|
|
49
src/core.js
49
src/core.js
|
@ -319,15 +319,16 @@ EPUBJS.core.uuid = function() {
|
|||
// http://stackoverflow.com/questions/1344500/efficient-way-to-insert-a-number-into-a-sorted-array-of-numbers
|
||||
EPUBJS.core.insert = function(item, array, compareFunction) {
|
||||
var location = EPUBJS.core.locationOf(item, array, compareFunction);
|
||||
array.splice(location+1, 0, item);
|
||||
array.splice(location, 0, item);
|
||||
|
||||
return location+1;
|
||||
return location;
|
||||
};
|
||||
|
||||
EPUBJS.core.locationOf = function(item, array, compareFunction, _start, _end) {
|
||||
var start = _start || 0;
|
||||
var end = _end || array.length;
|
||||
var pivot = parseInt(start + (end - start) / 2);
|
||||
var compared;
|
||||
if(!compareFunction){
|
||||
compareFunction = function(a, b) {
|
||||
if(a > b) return 1;
|
||||
|
@ -335,16 +336,56 @@ EPUBJS.core.locationOf = function(item, array, compareFunction, _start, _end) {
|
|||
if(a = b) return 0;
|
||||
};
|
||||
}
|
||||
if(end-start <= 1 || compareFunction(array[pivot], item) === 0) {
|
||||
if(end-start <= 0) {
|
||||
return pivot;
|
||||
}
|
||||
if(compareFunction(array[pivot], item) === -1) {
|
||||
|
||||
compared = compareFunction(array[pivot], item);
|
||||
if(end-start === 1) {
|
||||
return compared > 0 ? pivot : pivot + 1;
|
||||
}
|
||||
|
||||
if(compared === 0) {
|
||||
return pivot;
|
||||
}
|
||||
if(compared === -1) {
|
||||
return EPUBJS.core.locationOf(item, array, compareFunction, pivot, end);
|
||||
} else{
|
||||
return EPUBJS.core.locationOf(item, array, compareFunction, start, pivot);
|
||||
}
|
||||
};
|
||||
|
||||
EPUBJS.core.indexOfSorted = function(item, array, compareFunction, _start, _end) {
|
||||
var start = _start || 0;
|
||||
var end = _end || array.length;
|
||||
var pivot = parseInt(start + (end - start) / 2);
|
||||
var compared;
|
||||
if(!compareFunction){
|
||||
compareFunction = function(a, b) {
|
||||
if(a > b) return 1;
|
||||
if(a < b) return -1;
|
||||
if(a = b) return 0;
|
||||
};
|
||||
}
|
||||
if(end-start <= 0) {
|
||||
return -1; // Not found
|
||||
}
|
||||
|
||||
compared = compareFunction(array[pivot], item);
|
||||
if(end-start === 1) {
|
||||
return compared === 0 ? pivot : -1;
|
||||
}
|
||||
if(compared === 0) {
|
||||
return pivot; // Found
|
||||
}
|
||||
if(compared === -1) {
|
||||
return EPUBJS.core.indexOfSorted(item, array, compareFunction, pivot, end);
|
||||
} else{
|
||||
return EPUBJS.core.indexOfSorted(item, array, compareFunction, start, pivot);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
EPUBJS.core.queue = function(_scope){
|
||||
var _q = [];
|
||||
var scope = _scope;
|
||||
|
|
|
@ -38,7 +38,7 @@ EPUBJS.EpubCFI.prototype.generateCfiFromElement = function(element, chapter) {
|
|||
var path = this.generatePathComponent(steps);
|
||||
if(!path.length) {
|
||||
// Start of Chapter
|
||||
return "epubcfi(" + chapter + ")";
|
||||
return "epubcfi(" + chapter + "!/4/)";
|
||||
} else {
|
||||
// First Text Node
|
||||
return "epubcfi(" + chapter + "!" + path + "/1:0)";
|
||||
|
@ -96,7 +96,24 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
|
|||
chapId,
|
||||
path,
|
||||
end,
|
||||
text;
|
||||
endInt,
|
||||
text,
|
||||
parseStep = function(part){
|
||||
var type, index, has_brackets, id;
|
||||
|
||||
type = "element";
|
||||
index = parseInt(part) / 2 - 1;
|
||||
has_brackets = part.match(/\[(.*)\]/);
|
||||
if(has_brackets && has_brackets[1]){
|
||||
id = has_brackets[1];
|
||||
}
|
||||
|
||||
return {
|
||||
"type" : type,
|
||||
'index' : index,
|
||||
'id' : id || false
|
||||
};
|
||||
};
|
||||
|
||||
if(typeof cfiStr !== "string") {
|
||||
return {spinePos: -1};
|
||||
|
@ -133,33 +150,34 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
|
|||
}
|
||||
|
||||
path = pathComponent.split('/');
|
||||
end = path[path.length-1];
|
||||
end = path.pop();
|
||||
|
||||
cfi.steps = [];
|
||||
|
||||
path.forEach(function(part){
|
||||
var type, index, has_brackets, id;
|
||||
var step;
|
||||
|
||||
if(!part) return;
|
||||
//-- Check if this is a text node or element
|
||||
if(parseInt(part) % 2){
|
||||
type = "text";
|
||||
index = parseInt(part) - 1;
|
||||
} else {
|
||||
type = "element";
|
||||
index = parseInt(part) / 2 - 1;
|
||||
has_brackets = part.match(/\[(.*)\]/);
|
||||
if(has_brackets && has_brackets[1]){
|
||||
id = has_brackets[1];
|
||||
if(part) {
|
||||
step = parseStep(part);
|
||||
cfi.steps.push(step);
|
||||
}
|
||||
}
|
||||
|
||||
cfi.steps.push({
|
||||
"type" : type,
|
||||
'index' : index,
|
||||
'id' : id || false
|
||||
});
|
||||
|
||||
//-- Check if END is a text node or element
|
||||
endInt = parseInt(end);
|
||||
if(!isNaN(endInt)) {
|
||||
|
||||
if(endInt % 2 === 0) { // Even = is an element
|
||||
cfi.steps.push(parseStep(end));
|
||||
} else {
|
||||
cfi.steps.push({
|
||||
"type" : "text",
|
||||
'index' : parseInt(end) - 1,
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
assertion = charecterOffsetComponent.match(/\[(.*)\]/);
|
||||
if(assertion && assertion[1]){
|
||||
cfi.characterOffset = parseInt(charecterOffsetComponent.split('[')[0]);
|
||||
|
@ -169,9 +187,6 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
|
|||
cfi.characterOffset = parseInt(charecterOffsetComponent);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
return cfi;
|
||||
};
|
||||
|
||||
|
@ -308,7 +323,9 @@ EPUBJS.EpubCFI.prototype.compare = function(cfiOne, cfiTwo) {
|
|||
if(cfiOne.spinePos < cfiTwo.spinePos) {
|
||||
return -1;
|
||||
}
|
||||
// Compare Each Step
|
||||
|
||||
|
||||
// Compare Each Step in the First item
|
||||
for (var i = 0; i < cfiOne.steps.length; i++) {
|
||||
if(!cfiTwo.steps[i]) {
|
||||
return 1;
|
||||
|
@ -321,6 +338,12 @@ EPUBJS.EpubCFI.prototype.compare = function(cfiOne, cfiTwo) {
|
|||
}
|
||||
// Otherwise continue checking
|
||||
}
|
||||
|
||||
// All steps in First present in Second
|
||||
if(cfiOne.steps.length < cfiTwo.steps.length) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Compare the charecter offset of the text node
|
||||
if(cfiOne.characterOffset > cfiTwo.characterOffset) {
|
||||
return 1;
|
||||
|
@ -356,3 +379,18 @@ EPUBJS.EpubCFI.prototype.generateCfiFromHref = function(href, book) {
|
|||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
EPUBJS.EpubCFI.prototype.generateCfiFromTextNode = function(anchor, offset, base) {
|
||||
var parent = anchor.parentElement;
|
||||
var steps = this.pathTo(parent);
|
||||
var path = this.generatePathComponent(steps);
|
||||
var index = [].slice.apply(parent.childNodes).indexOf(anchor) + 1;
|
||||
return "epubcfi(" + base + "!" + path + "/"+index+":"+(offset || 0)+")";
|
||||
};
|
||||
|
||||
EPUBJS.EpubCFI.prototype.generateCfiFromRangeAnchor = function(range, base) {
|
||||
var anchor = range.anchorNode;
|
||||
var offset = range.anchorOffset;
|
||||
return this.generateCfiFromTextNode(anchor, offset, base);
|
||||
};
|
||||
|
||||
|
|
|
@ -11,19 +11,22 @@ EPUBJS.Layout.Reflowable.prototype.format = function(documentElement, _width, _h
|
|||
var columnGap = EPUBJS.core.prefixed('columnGap');
|
||||
var columnWidth = EPUBJS.core.prefixed('columnWidth');
|
||||
|
||||
//-- Check the width and decied on columns
|
||||
var width = (_width % 2 === 0) ? _width : Math.floor(_width) - 1;
|
||||
var section = Math.ceil(width / 8);
|
||||
//-- Check the width and create even width columns
|
||||
var fullWidth = Math.floor(_width);
|
||||
var width = (fullWidth % 2 === 0) ? fullWidth : fullWidth - 1;
|
||||
var section = Math.floor(width / 8);
|
||||
var gap = (section % 2 === 0) ? section : section - 1;
|
||||
|
||||
this.documentElement = documentElement;
|
||||
//-- Single Page
|
||||
this.spreadWidth = (width + gap);
|
||||
|
||||
documentElement.style.width = "auto"; //-- reset width for calculations
|
||||
|
||||
documentElement.style.overflow = "hidden";
|
||||
|
||||
// Must be set to the new calculated width or the columns will be off
|
||||
documentElement.style.width = width + "px";
|
||||
|
||||
//-- Adjust height
|
||||
documentElement.style.height = _height + "px";
|
||||
|
||||
|
@ -32,7 +35,6 @@ EPUBJS.Layout.Reflowable.prototype.format = function(documentElement, _width, _h
|
|||
documentElement.style[columnGap] = gap+"px";
|
||||
documentElement.style[columnWidth] = width+"px";
|
||||
|
||||
documentElement.style.width = width + "px";
|
||||
return {
|
||||
pageWidth : this.spreadWidth,
|
||||
pageHeight : _height
|
||||
|
|
|
@ -21,18 +21,32 @@ EPUBJS.Pagination.prototype.process = function(pageList){
|
|||
|
||||
EPUBJS.Pagination.prototype.pageFromCfi = function(cfi){
|
||||
var pg = -1;
|
||||
|
||||
// Check if the pageList has not been set yet
|
||||
if(this.locations.length === 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// TODO: check if CFI is valid?
|
||||
|
||||
// check if the cfi is in the location list
|
||||
var index = this.locations.indexOf(cfi);
|
||||
// var index = this.locations.indexOf(cfi);
|
||||
var index = EPUBJS.core.indexOfSorted(cfi, this.locations, this.epubcfi.compare);
|
||||
if(index != -1 && index < (this.pages.length-1) ) {
|
||||
pg = this.pages[index];
|
||||
} else {
|
||||
// Otherwise add it to the list of locations
|
||||
// Insert it in the correct position in the locations page
|
||||
index = EPUBJS.core.insert(cfi, this.locations, this.epubcfi.compare);
|
||||
// Get the page at the location just before the new one
|
||||
pg = this.pages[index-1];
|
||||
// Get the page at the location just before the new one, or return the first
|
||||
pg = index-1 >= 0 ? this.pages[index-1] : this.pages[0];
|
||||
if(pg != undefined) {
|
||||
// Add the new page in so that the locations and page array match up
|
||||
this.pages.splice(index, 0, pg);
|
||||
} else {
|
||||
pg = -1;
|
||||
}
|
||||
|
||||
}
|
||||
return pg;
|
||||
};
|
||||
|
@ -45,6 +59,7 @@ EPUBJS.Pagination.prototype.cfiFromPage = function(pg){
|
|||
}
|
||||
|
||||
// check if the cfi is in the page list
|
||||
// Pages could be unsorted.
|
||||
var index = this.pages.indexOf(pg);
|
||||
if(index != -1) {
|
||||
cfi = this.locations[index];
|
||||
|
|
|
@ -35,3 +35,47 @@ asyncTest("Find CFI from href", 1, function() {
|
|||
|
||||
render.then(result);
|
||||
});
|
||||
|
||||
test("Parse CFIs", null, function() {
|
||||
var epubcfi = new EPUBJS.EpubCFI();
|
||||
var cfiOne = epubcfi.parse("epubcfi(/6/2[cover]!/6)");
|
||||
|
||||
equal(cfiOne.steps.length, 1, "One step");
|
||||
equal(cfiOne.steps[0].type, "element", "Step type is element");
|
||||
equal(cfiOne.steps[0].index, 2, "Step index is two");
|
||||
});
|
||||
|
||||
test("Compare CFI's", null, function() {
|
||||
var epubcfi = new EPUBJS.EpubCFI();
|
||||
// equal(epubcfi.compare("epubcfi(/6/2[cover]!/4)", "epubcfi(/6/2[cover]!/4)"), 0, "equal");
|
||||
|
||||
// Spines
|
||||
equal(epubcfi.compare("epubcfi(/6/4[cover]!/4)", "epubcfi(/6/2[cover]!/4)"), 1, "First spine is greater");
|
||||
equal(epubcfi.compare("epubcfi(/6/4[cover]!/4)", "epubcfi(/6/6[cover]!/4)"), -1, "Second spine is greater");
|
||||
|
||||
// First is deeper
|
||||
equal(epubcfi.compare("epubcfi(/6/2[cover]!/8/2)", "epubcfi(/6/2[cover]!/6)"), 1, "First Element is greater");
|
||||
equal(epubcfi.compare("epubcfi(/6/2[cover]!/4/2)", "epubcfi(/6/2[cover]!/6)"), -1, "Second Element is greater");
|
||||
|
||||
// Second is deeper
|
||||
equal(epubcfi.compare("epubcfi(/6/2[cover]!/8/2)", "epubcfi(/6/2[cover]!/6/4/2/2)"), 1, "First Element is greater");
|
||||
equal(epubcfi.compare("epubcfi(/6/2[cover]!/4/4)", "epubcfi(/6/2[cover]!/6/4/2/2)"), -1, "Second Element is greater");
|
||||
equal(epubcfi.compare("epubcfi(/6/2[cover]!/4/6)", "epubcfi(/6/2[cover]!/4/6/8/1:0)"), -1, "Second");
|
||||
|
||||
// Same Depth
|
||||
equal(epubcfi.compare("epubcfi(/6/2[cover]!/6/8)", "epubcfi(/6/2[cover]!/6/2)"), 1, "First Element is greater");
|
||||
equal(epubcfi.compare("epubcfi(/6/2[cover]!/4/20)", "epubcfi(/6/2[cover]!/6/10)"), -1, "Second Element is greater");
|
||||
|
||||
// Text nodes
|
||||
equal(epubcfi.compare("epubcfi(/6/2[cover]!/4/5)", "epubcfi(/6/2[cover]!/4/3)"), 1, "First TextNode is greater");
|
||||
equal(epubcfi.compare("epubcfi(/6/2[cover]!/4/7)", "epubcfi(/6/2[cover]!/4/13)"), -1, "Second TextNode is greater");
|
||||
|
||||
// Char offset
|
||||
equal(epubcfi.compare("epubcfi(/6/2[cover]!/4/5:1)", "epubcfi(/6/2[cover]!/4/5:0)"), 1, "First Char Offset is greater");
|
||||
equal(epubcfi.compare("epubcfi(/6/2[cover]!/4/5:2)", "epubcfi(/6/2[cover]!/4/5:30)"), -1, "Second Char Offset is greater");
|
||||
|
||||
// Normal example
|
||||
equal(epubcfi.compare("epubcfi(/6/2[cover]!/4/8/5:1)", "epubcfi(/6/2[cover]!/4/6/15:2)"), 1, "First Element is greater");
|
||||
equal(epubcfi.compare("epubcfi(/6/2[cover]!/4/8/1:0)", "epubcfi(/6/2[cover]!/4/8/1:0)"), 0, "All Equal");
|
||||
|
||||
})
|
|
@ -75,7 +75,7 @@ test("Get Page number from a cfi NOT present in the pageList, returning the FIRS
|
|||
var pg = pagination.pageFromCfi("epubcfi(/6/4[ct]!/4/2[d10e42]/4/8/7:0)");
|
||||
var prevIndex = pagination.pages.indexOf("752");
|
||||
equal( pg, "752", "Closest Page is found" );
|
||||
equal( pagination.locations.indexOf("epubcfi(/6/4[ct]!/4/2[d10e42]/4/8/7:0)"), 1, "Pagination.locations is updated" );
|
||||
equal( pagination.locations.indexOf("epubcfi(/6/4[ct]!/4/2[d10e42]/4/8/7:0)"), 0, "Pagination.locations is updated" );
|
||||
equal( pagination.pages[prevIndex+1], "752", "Pagination.pages is updated" );
|
||||
});
|
||||
|
||||
|
@ -159,3 +159,15 @@ asyncTest("gotoPage after generating page list", 2, function() {
|
|||
stop();
|
||||
});
|
||||
});
|
||||
|
||||
test("insert items into page list", null, function() {
|
||||
var pg = new EPUBJS.Pagination();
|
||||
equal(pg.locations.length, 0, "No locations");
|
||||
equal(EPUBJS.core.insert("epubcfi(/6/2[cover]!/4/6)", pg.locations, pg.epubcfi.compare), 0, "inserted first");
|
||||
equal(EPUBJS.core.insert("epubcfi(/6/2[cover]!/4/4/8/1:0)", pg.locations, pg.epubcfi.compare), 0, "inserted before first");
|
||||
equal(EPUBJS.core.insert("epubcfi(/6/2[cover]!/4/4/12/1:0)", pg.locations, pg.epubcfi.compare), 1, "inserted inbetween");
|
||||
equal(EPUBJS.core.insert("epubcfi(/6/2[cover]!/4/6/8/1:0)", pg.locations, pg.epubcfi.compare), 3, "inserted last");
|
||||
equal(EPUBJS.core.indexOfSorted("epubcfi(/6/2[cover]!/4/6)", pg.locations, pg.epubcfi.compare), 2, "already in list");
|
||||
equal(EPUBJS.core.indexOfSorted("epubcfi(/6/2[cover]!/4/60)", pg.locations, pg.epubcfi.compare), -1, "not in list");
|
||||
// equal(pg.locations.length, 2, "New locations");
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue