1
0
Fork 0
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:
Fred Chasen 2014-03-14 18:50:28 -07:00
parent aba8dc3c6f
commit 6a69eeb2a9
27 changed files with 1241 additions and 171 deletions

View file

@ -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: {

View file

@ -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

File diff suppressed because one or more lines are too long

View file

@ -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

View file

@ -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
View file

@ -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()};

View file

@ -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 &#187;";
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");
}

View file

@ -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;
}

View file

@ -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">

View file

@ -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

File diff suppressed because one or more lines are too long

View file

@ -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
View 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
};
};

File diff suppressed because one or more lines are too long

View file

@ -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 {

View file

@ -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);

View 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 &#187;";
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
};
};

View file

@ -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");
}

View file

@ -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;

View file

@ -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);

View file

@ -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();
}

View file

@ -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;

View file

@ -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);
};

View file

@ -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

View file

@ -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];

View file

@ -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");
})

View file

@ -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");
});