1
0
Fork 0
mirror of https://github.com/futurepress/epub.js.git synced 2025-10-04 15:09:16 +02:00

updated cfi to handle text nodes and character offset

This commit is contained in:
fchasen 2014-01-29 11:04:48 -08:00
parent 0a0a13f5f5
commit 73ac66ba65
19 changed files with 529 additions and 228 deletions

2
books

@ -1 +1 @@
Subproject commit ab9755a74714b647290c861f666515de220935d8
Subproject commit 09bd1725f5839996e747cf83500a2526b86ae6af

View file

@ -3047,12 +3047,21 @@ EPUBJS.core.resolveUrl = function(base, path) {
return url.join("/");
};
// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
EPUBJS.core.uuid = function() {
var d = new Date().getTime();
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = (d + Math.random()*16)%16 | 0;
d = Math.floor(d/16);
return (c=='x' ? r : (r&0x7|0x8)).toString(16);
});
return uuid;
};
EPUBJS.EpubCFI = function(cfiStr){
if(cfiStr) return this.parse(cfiStr);
};
EPUBJS.EpubCFI.prototype.generateChapter = function(_spineNodeIndex, _pos, id) {
EPUBJS.EpubCFI.prototype.generateChapterComponent = function(_spineNodeIndex, _pos, id) {
var pos = parseInt(_pos),
spineNodeIndex = _spineNodeIndex + 1,
cfi = '/'+spineNodeIndex+'/';
@ -3061,35 +3070,38 @@ EPUBJS.EpubCFI.prototype.generateChapter = function(_spineNodeIndex, _pos, id) {
if(id) cfi += "[" + id + "]";
cfi += "!";
//cfi += "!";
return cfi;
};
EPUBJS.EpubCFI.prototype.generatePathComponent = function(steps) {
var parts = [];
EPUBJS.EpubCFI.prototype.generateFragment = function(element, chapter) {
var path = this.pathTo(element),
parts = [];
if(chapter) parts.push(chapter);
path.forEach(function(part){
steps.forEach(function(part){
var segment = '';
segment += (part.index + 1) * 2;
if(part.id &&
part.id.slice(0, 6) != "EPUBJS") { //-- ignore internal @EPUBJS ids
if(part.id && part.id.slice(0, 6) === "EPUBJS") {
//-- ignore internal @EPUBJS ids for
return;
} else if(part.id) {
segment += "[" + part.id + "]";
}
parts.push(segment);
});
return parts.join('/');
};
EPUBJS.EpubCFI.prototype.generateCfiFromElement = function(element, chapter) {
var steps = this.pathTo(element);
var path = this.generatePathComponent(steps);
return "epubcfi(" + chapter + "!" + path + ")";
};
EPUBJS.EpubCFI.prototype.pathTo = function(node) {
var stack = [],
children;
@ -3110,121 +3122,200 @@ EPUBJS.EpubCFI.prototype.pathTo = function(node) {
return stack;
};
EPUBJS.EpubCFI.prototype.getChapter = function(cfiStr) {
EPUBJS.EpubCFI.prototype.getChapterComponent = function(cfiStr) {
var splitStr = cfiStr.split("!");
return splitStr[0];
};
EPUBJS.EpubCFI.prototype.getFragment = function(cfiStr) {
EPUBJS.EpubCFI.prototype.getPathComponent = function(cfiStr) {
var splitStr = cfiStr.split("!");
var pathComponent = splitStr[1] ? splitStr[1].split(":") : '';
return splitStr[1];
return pathComponent[0];
};
EPUBJS.EpubCFI.prototype.getOffset = function(cfiStr) {
EPUBJS.EpubCFI.prototype.getCharecterOffsetComponent = function(cfiStr) {
var splitStr = cfiStr.split(":");
return [splitStr[0], splitStr[1]];
return splitStr[1] || '';
};
EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
var cfi = {},
chapSegment,
chapterComponent,
pathComponent,
charecterOffsetComponent,
assertion,
chapId,
path,
end,
text;
cfi.chapter = this.getChapter(cfiStr);
if(cfiStr.indexOf("epubcfi(") === 0) {
// Remove intial epubcfi( and ending )
cfiStr = cfiStr.slice(8, cfiStr.length-1);
}
chapSegment = parseInt(cfi.chapter.split("/")[2]) || false;
cfi.fragment = this.getFragment(cfiStr);
if(!chapSegment || !cfi.fragment) return {spinePos: -1};
chapterComponent = this.getChapterComponent(cfiStr);
pathComponent = this.getPathComponent(cfiStr);
charecterOffsetComponent = this.getCharecterOffsetComponent(cfiStr);
// Make sure this is a valid cfi or return
if(!chapterComponent.length || !pathComponent.length) {
return {spinePos: -1};
}
// Chapter segment is always the second one
chapSegment = chapterComponent.split("/")[2] || '';
if(!chapSegment) return {spinePos:-1};
cfi.spinePos = (parseInt(chapSegment) / 2 - 1 ) || 0;
chapId = cfi.chapter.match(/\[(.*)\]/);
chapId = chapSegment.match(/\[(.*)\]/);
cfi.spineId = chapId ? chapId[1] : false;
path = cfi.fragment.split('/');
end = path[path.length-1];
cfi.sections = [];
//-- Check for Character Offset
if(parseInt(end) % 2){
text = this.getOffset();
cfi.text = parseInt(text[0]);
cfi.character = parseInt(text[1]);
path.pop(); //-- remove from path to element
if(pathComponent.indexOf(',') != -1) {
// Handle ranges -- not supported yet
console.warn("CFI Ranges are not supported");
}
path = pathComponent.split('/');
end = path[path.length-1];
cfi.steps = [];
path.forEach(function(part){
var index, has_id, id;
var type, index, has_brackets, id;
if(!part) return;
index = parseInt(part) / 2 - 1;
has_id = part.match(/\[(.*)\]/);
if(has_id && has_id[1]){
id = has_id[1];
//-- 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.sections.push({
cfi.steps.push({
"type" : type,
'index' : index,
'id' : id || false
});
assertion = charecterOffsetComponent.match(/\[(.*)\]/);
if(assertion && assertion[1]){
cfi.characterOffset = parseInt(charecterOffsetComponent.split('[')[0]);
// We arent handling these assertions yet
cfi.textLocationAssertion = assertion[1];
} else {
cfi.characterOffset = parseInt(charecterOffsetComponent);
}
});
return cfi;
};
EPUBJS.EpubCFI.prototype.getElement = function(cfi, _doc) {
var doc = _doc || document,
sections = cfi.sections,
element = doc.getElementsByTagName('html')[0],
children = Array.prototype.slice.call(element.children),
num, index, part,
has_id, id;
// sections.shift(); //-- html
var doc = _doc || document,
element = doc.getElementsByTagName('html')[0],
children = Array.prototype.slice.call(element.children),
num, index, part, sections,
text, textBegin, textEnd;
if(typeof cfi === 'string') {
cfi = this.parse(cfi);
}
sections = cfi.steps;
while(sections && sections.length > 0) {
part = sections.shift();
// Wrap text elements in a span and return that new element
if(part.type === "text") {
text = element.childNodes[part.index];
element = doc.createElement('span');
element.id = "EPUBJS-CFI-MARKER:"+ EPUBJS.core.uuid();
if(part.id){
if(cfi.characterOffset) {
textBegin = doc.createTextNode(text.textContent.slice(0, cfi.characterOffset));
textEnd = doc.createTextNode(text.textContent.slice(cfi.characterOffset));
text.parentNode.insertBefore(textEnd, text);
text.parentNode.insertBefore(element, textEnd);
text.parentNode.insertBefore(textBegin, element);
text.parentNode.removeChild(text);
} else {
text.parentNode.insertBefore(element, text);
}
// sort cut to find element by id
} else if(part.id){
element = doc.getElementById(part.id);
// find element in parent
}else{
element = children[part.index];
if(!children) console.error("No Kids", element);
element = children[part.index];
}
if(!element) console.error("No Element For", part, cfi);
children = Array.prototype.slice.call(element.children);
}
return element;
};
//-- Todo: function to remove IDs to sort
EPUBJS.EpubCFI.prototype.compare = function(cfiOne, cfiTwo) {
if(typeof cfiOne === 'string') {
cfiOne = this.parse(cfiOne);
}
if(typeof cfiTwo === 'string') {
cfiTwo = this.parse(cfiTwo);
}
// Compare Spine Positions
if(cfiOne.spinePos > cfiTwo.spinePos) {
return 1;
}
if(cfiOne.spinePos < cfiTwo.spinePos) {
return -1;
}
// Compare Each Step
for (var i = 0; i < cfiOne.steps.length; i++) {
if(!cfiTwo.steps[i]) {
return 1;
}
if(cfiOne.steps[i].index > cfiTwo.steps[i].index) {
return 1;
}
if(cfiOne.steps[i].index < cfiTwo.steps[i].index) {
return -1;
}
// Otherwise continue checking
}
// Compare the charecter offset of the text node
if(cfiOne.characterOffset > cfiTwo.characterOffset) {
return 1;
}
if(cfiOne.characterOffset < cfiTwo.characterOffset) {
return -1;
}
// CFI's are equal
return 0;
};
EPUBJS.Events = function(obj, el){
this.events = {};
@ -3538,6 +3629,11 @@ EPUBJS.Layout.Fixed.prototype.calculatePages = function(){
pageCount : 1
};
};
EPUBJS.Navigation = function() {
};
// percentage at cfi, nearest page to Cfi, total pages and goto page.
EPUBJS.Parser = function(baseUrl){
this.baseUrl = baseUrl || '';
@ -3759,7 +3855,7 @@ EPUBJS.Parser.prototype.spine = function(spineXml, manifest){
//-- Add to array to mantain ordering and cross reference with manifest
items.forEach(function(item, index){
var Id = item.getAttribute('idref');
var cfiBase = epubcfi.generateChapter(spineNodeIndex, index, Id);
var cfiBase = epubcfi.generateChapterComponent(spineNodeIndex, index, Id);
var props = item.getAttribute('properties') || '';
var propArray = props.length ? props.split(' ') : [];
var manifestProps = manifest[Id].properties;
@ -4528,7 +4624,7 @@ EPUBJS.Renderer.prototype.walk = function(node) {
EPUBJS.Renderer.prototype.getPageCfi = function(prevEl){
this.visibileEl = this.findFirstVisible(prevEl);
return this.epubcfi.generateFragment(this.visibileEl, this.currentChapter.cfiBase);
return this.epubcfi.generateCfiFromElement(this.visibileEl, this.currentChapter.cfiBase);
};
// Goto a cfi position in the current chapter

6
build/epub.min.js vendored

File diff suppressed because one or more lines are too long

View file

@ -3046,12 +3046,21 @@ EPUBJS.core.resolveUrl = function(base, path) {
return url.join("/");
};
// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
EPUBJS.core.uuid = function() {
var d = new Date().getTime();
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = (d + Math.random()*16)%16 | 0;
d = Math.floor(d/16);
return (c=='x' ? r : (r&0x7|0x8)).toString(16);
});
return uuid;
};
EPUBJS.EpubCFI = function(cfiStr){
if(cfiStr) return this.parse(cfiStr);
};
EPUBJS.EpubCFI.prototype.generateChapter = function(_spineNodeIndex, _pos, id) {
EPUBJS.EpubCFI.prototype.generateChapterComponent = function(_spineNodeIndex, _pos, id) {
var pos = parseInt(_pos),
spineNodeIndex = _spineNodeIndex + 1,
cfi = '/'+spineNodeIndex+'/';
@ -3060,35 +3069,38 @@ EPUBJS.EpubCFI.prototype.generateChapter = function(_spineNodeIndex, _pos, id) {
if(id) cfi += "[" + id + "]";
cfi += "!";
//cfi += "!";
return cfi;
};
EPUBJS.EpubCFI.prototype.generatePathComponent = function(steps) {
var parts = [];
EPUBJS.EpubCFI.prototype.generateFragment = function(element, chapter) {
var path = this.pathTo(element),
parts = [];
if(chapter) parts.push(chapter);
path.forEach(function(part){
steps.forEach(function(part){
var segment = '';
segment += (part.index + 1) * 2;
if(part.id &&
part.id.slice(0, 6) != "EPUBJS") { //-- ignore internal @EPUBJS ids
if(part.id && part.id.slice(0, 6) === "EPUBJS") {
//-- ignore internal @EPUBJS ids for
return;
} else if(part.id) {
segment += "[" + part.id + "]";
}
parts.push(segment);
});
return parts.join('/');
};
EPUBJS.EpubCFI.prototype.generateCfiFromElement = function(element, chapter) {
var steps = this.pathTo(element);
var path = this.generatePathComponent(steps);
return "epubcfi(" + chapter + "!" + path + ")";
};
EPUBJS.EpubCFI.prototype.pathTo = function(node) {
var stack = [],
children;
@ -3109,121 +3121,200 @@ EPUBJS.EpubCFI.prototype.pathTo = function(node) {
return stack;
};
EPUBJS.EpubCFI.prototype.getChapter = function(cfiStr) {
EPUBJS.EpubCFI.prototype.getChapterComponent = function(cfiStr) {
var splitStr = cfiStr.split("!");
return splitStr[0];
};
EPUBJS.EpubCFI.prototype.getFragment = function(cfiStr) {
EPUBJS.EpubCFI.prototype.getPathComponent = function(cfiStr) {
var splitStr = cfiStr.split("!");
var pathComponent = splitStr[1] ? splitStr[1].split(":") : '';
return splitStr[1];
return pathComponent[0];
};
EPUBJS.EpubCFI.prototype.getOffset = function(cfiStr) {
EPUBJS.EpubCFI.prototype.getCharecterOffsetComponent = function(cfiStr) {
var splitStr = cfiStr.split(":");
return [splitStr[0], splitStr[1]];
return splitStr[1] || '';
};
EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
var cfi = {},
chapSegment,
chapterComponent,
pathComponent,
charecterOffsetComponent,
assertion,
chapId,
path,
end,
text;
cfi.chapter = this.getChapter(cfiStr);
if(cfiStr.indexOf("epubcfi(") === 0) {
// Remove intial epubcfi( and ending )
cfiStr = cfiStr.slice(8, cfiStr.length-1);
}
chapSegment = parseInt(cfi.chapter.split("/")[2]) || false;
cfi.fragment = this.getFragment(cfiStr);
if(!chapSegment || !cfi.fragment) return {spinePos: -1};
chapterComponent = this.getChapterComponent(cfiStr);
pathComponent = this.getPathComponent(cfiStr);
charecterOffsetComponent = this.getCharecterOffsetComponent(cfiStr);
// Make sure this is a valid cfi or return
if(!chapterComponent.length || !pathComponent.length) {
return {spinePos: -1};
}
// Chapter segment is always the second one
chapSegment = chapterComponent.split("/")[2] || '';
if(!chapSegment) return {spinePos:-1};
cfi.spinePos = (parseInt(chapSegment) / 2 - 1 ) || 0;
chapId = cfi.chapter.match(/\[(.*)\]/);
chapId = chapSegment.match(/\[(.*)\]/);
cfi.spineId = chapId ? chapId[1] : false;
path = cfi.fragment.split('/');
end = path[path.length-1];
cfi.sections = [];
//-- Check for Character Offset
if(parseInt(end) % 2){
text = this.getOffset();
cfi.text = parseInt(text[0]);
cfi.character = parseInt(text[1]);
path.pop(); //-- remove from path to element
if(pathComponent.indexOf(',') != -1) {
// Handle ranges -- not supported yet
console.warn("CFI Ranges are not supported");
}
path = pathComponent.split('/');
end = path[path.length-1];
cfi.steps = [];
path.forEach(function(part){
var index, has_id, id;
var type, index, has_brackets, id;
if(!part) return;
index = parseInt(part) / 2 - 1;
has_id = part.match(/\[(.*)\]/);
if(has_id && has_id[1]){
id = has_id[1];
//-- 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.sections.push({
cfi.steps.push({
"type" : type,
'index' : index,
'id' : id || false
});
assertion = charecterOffsetComponent.match(/\[(.*)\]/);
if(assertion && assertion[1]){
cfi.characterOffset = parseInt(charecterOffsetComponent.split('[')[0]);
// We arent handling these assertions yet
cfi.textLocationAssertion = assertion[1];
} else {
cfi.characterOffset = parseInt(charecterOffsetComponent);
}
});
return cfi;
};
EPUBJS.EpubCFI.prototype.getElement = function(cfi, _doc) {
var doc = _doc || document,
sections = cfi.sections,
element = doc.getElementsByTagName('html')[0],
children = Array.prototype.slice.call(element.children),
num, index, part,
has_id, id;
// sections.shift(); //-- html
var doc = _doc || document,
element = doc.getElementsByTagName('html')[0],
children = Array.prototype.slice.call(element.children),
num, index, part, sections,
text, textBegin, textEnd;
if(typeof cfi === 'string') {
cfi = this.parse(cfi);
}
sections = cfi.steps;
while(sections && sections.length > 0) {
part = sections.shift();
// Wrap text elements in a span and return that new element
if(part.type === "text") {
text = element.childNodes[part.index];
element = doc.createElement('span');
element.id = "EPUBJS-CFI-MARKER:"+ EPUBJS.core.uuid();
if(part.id){
if(cfi.characterOffset) {
textBegin = doc.createTextNode(text.textContent.slice(0, cfi.characterOffset));
textEnd = doc.createTextNode(text.textContent.slice(cfi.characterOffset));
text.parentNode.insertBefore(textEnd, text);
text.parentNode.insertBefore(element, textEnd);
text.parentNode.insertBefore(textBegin, element);
text.parentNode.removeChild(text);
} else {
text.parentNode.insertBefore(element, text);
}
// sort cut to find element by id
} else if(part.id){
element = doc.getElementById(part.id);
// find element in parent
}else{
element = children[part.index];
if(!children) console.error("No Kids", element);
element = children[part.index];
}
if(!element) console.error("No Element For", part, cfi);
children = Array.prototype.slice.call(element.children);
}
return element;
};
//-- Todo: function to remove IDs to sort
EPUBJS.EpubCFI.prototype.compare = function(cfiOne, cfiTwo) {
if(typeof cfiOne === 'string') {
cfiOne = this.parse(cfiOne);
}
if(typeof cfiTwo === 'string') {
cfiTwo = this.parse(cfiTwo);
}
// Compare Spine Positions
if(cfiOne.spinePos > cfiTwo.spinePos) {
return 1;
}
if(cfiOne.spinePos < cfiTwo.spinePos) {
return -1;
}
// Compare Each Step
for (var i = 0; i < cfiOne.steps.length; i++) {
if(!cfiTwo.steps[i]) {
return 1;
}
if(cfiOne.steps[i].index > cfiTwo.steps[i].index) {
return 1;
}
if(cfiOne.steps[i].index < cfiTwo.steps[i].index) {
return -1;
}
// Otherwise continue checking
}
// Compare the charecter offset of the text node
if(cfiOne.characterOffset > cfiTwo.characterOffset) {
return 1;
}
if(cfiOne.characterOffset < cfiTwo.characterOffset) {
return -1;
}
// CFI's are equal
return 0;
};
EPUBJS.Events = function(obj, el){
this.events = {};
@ -3537,6 +3628,11 @@ EPUBJS.Layout.Fixed.prototype.calculatePages = function(){
pageCount : 1
};
};
EPUBJS.Navigation = function() {
};
// percentage at cfi, nearest page to Cfi, total pages and goto page.
EPUBJS.Parser = function(baseUrl){
this.baseUrl = baseUrl || '';
@ -3758,7 +3854,7 @@ EPUBJS.Parser.prototype.spine = function(spineXml, manifest){
//-- Add to array to mantain ordering and cross reference with manifest
items.forEach(function(item, index){
var Id = item.getAttribute('idref');
var cfiBase = epubcfi.generateChapter(spineNodeIndex, index, Id);
var cfiBase = epubcfi.generateChapterComponent(spineNodeIndex, index, Id);
var props = item.getAttribute('properties') || '';
var propArray = props.length ? props.split(' ') : [];
var manifestProps = manifest[Id].properties;
@ -4527,7 +4623,7 @@ EPUBJS.Renderer.prototype.walk = function(node) {
EPUBJS.Renderer.prototype.getPageCfi = function(prevEl){
this.visibileEl = this.findFirstVisible(prevEl);
return this.epubcfi.generateFragment(this.visibileEl, this.currentChapter.cfiBase);
return this.epubcfi.generateCfiFromElement(this.visibileEl, this.currentChapter.cfiBase);
};
// Goto a cfi position in the current chapter

View file

@ -205,7 +205,7 @@ EPUBJS.Hooks.register("beforeChapterDisplay").smartimages = function(callback, r
newHeight,
fontSize = Number(getComputedStyle(item, "").fontSize.match(/(\d*(\.\d*)?)px/)[1]),
fontAdjust = fontSize ? fontSize / 2 : 0;
iheight = renderer.contents.clientHeight;
if(top < 0) top = 0;
@ -217,10 +217,16 @@ EPUBJS.Hooks.register("beforeChapterDisplay").smartimages = function(callback, r
item.style.maxHeight = newHeight + "px";
item.style.width= "auto";
}else{
newHeight = (height < iheight ? height : iheight);
item.style.maxHeight = newHeight + "px";
item.style.marginTop = iheight - top + "px";
item.style.width= "auto";
if(height > iheight) {
item.style.maxHeight = iheight + "px";
item.style.width= "auto";
itemRect = item.getBoundingClientRect();
height = itemRect.height;
}
item.style.display = "block";
item.style["WebkitColumnBreakBefore"] = "always";
item.style["breakBefore"] = "column";
}
item.setAttribute('data-height', newHeight);

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"),chapter.bodyEl.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"):(c=e>i?i:e,a.style.maxHeight=c+"px",a.style.marginTop=e-g+"px",a.style.width="auto"),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=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"),chapter.bodyEl.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()};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

6
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"),chapter.bodyEl.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"):(c=e>i?i:e,a.style.maxHeight=c+"px",a.style.marginTop=e-g+"px",a.style.width="auto"),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=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"),chapter.bodyEl.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()};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -20,7 +20,7 @@ EPUBJS.Hooks.register("beforeChapterDisplay").smartimages = function(callback, r
newHeight,
fontSize = Number(getComputedStyle(item, "").fontSize.match(/(\d*(\.\d*)?)px/)[1]),
fontAdjust = fontSize ? fontSize / 2 : 0;
iheight = renderer.contents.clientHeight;
if(top < 0) top = 0;
@ -32,10 +32,16 @@ EPUBJS.Hooks.register("beforeChapterDisplay").smartimages = function(callback, r
item.style.maxHeight = newHeight + "px";
item.style.width= "auto";
}else{
newHeight = (height < iheight ? height : iheight);
item.style.maxHeight = newHeight + "px";
item.style.marginTop = iheight - top + "px";
item.style.width= "auto";
if(height > iheight) {
item.style.maxHeight = iheight + "px";
item.style.width= "auto";
itemRect = item.getBoundingClientRect();
height = itemRect.height;
}
item.style.display = "block";
item.style["WebkitColumnBreakBefore"] = "always";
item.style["breakBefore"] = "column";
}
item.setAttribute('data-height', newHeight);

View file

@ -303,3 +303,14 @@ EPUBJS.core.resolveUrl = function(base, path) {
return url.join("/");
};
// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
EPUBJS.core.uuid = function() {
var d = new Date().getTime();
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = (d + Math.random()*16)%16 | 0;
d = Math.floor(d/16);
return (c=='x' ? r : (r&0x7|0x8)).toString(16);
});
return uuid;
};

View file

@ -2,8 +2,7 @@ EPUBJS.EpubCFI = function(cfiStr){
if(cfiStr) return this.parse(cfiStr);
};
EPUBJS.EpubCFI.prototype.generateChapter = function(_spineNodeIndex, _pos, id) {
EPUBJS.EpubCFI.prototype.generateChapterComponent = function(_spineNodeIndex, _pos, id) {
var pos = parseInt(_pos),
spineNodeIndex = _spineNodeIndex + 1,
cfi = '/'+spineNodeIndex+'/';
@ -12,35 +11,38 @@ EPUBJS.EpubCFI.prototype.generateChapter = function(_spineNodeIndex, _pos, id) {
if(id) cfi += "[" + id + "]";
cfi += "!";
//cfi += "!";
return cfi;
};
EPUBJS.EpubCFI.prototype.generatePathComponent = function(steps) {
var parts = [];
EPUBJS.EpubCFI.prototype.generateFragment = function(element, chapter) {
var path = this.pathTo(element),
parts = [];
if(chapter) parts.push(chapter);
path.forEach(function(part){
steps.forEach(function(part){
var segment = '';
segment += (part.index + 1) * 2;
if(part.id &&
part.id.slice(0, 6) != "EPUBJS") { //-- ignore internal @EPUBJS ids
if(part.id && part.id.slice(0, 6) === "EPUBJS") {
//-- ignore internal @EPUBJS ids for
return;
} else if(part.id) {
segment += "[" + part.id + "]";
}
parts.push(segment);
});
return parts.join('/');
};
EPUBJS.EpubCFI.prototype.generateCfiFromElement = function(element, chapter) {
var steps = this.pathTo(element);
var path = this.generatePathComponent(steps);
return "epubcfi(" + chapter + "!" + path + ")";
};
EPUBJS.EpubCFI.prototype.pathTo = function(node) {
var stack = [],
children;
@ -61,118 +63,197 @@ EPUBJS.EpubCFI.prototype.pathTo = function(node) {
return stack;
};
EPUBJS.EpubCFI.prototype.getChapter = function(cfiStr) {
EPUBJS.EpubCFI.prototype.getChapterComponent = function(cfiStr) {
var splitStr = cfiStr.split("!");
return splitStr[0];
};
EPUBJS.EpubCFI.prototype.getFragment = function(cfiStr) {
EPUBJS.EpubCFI.prototype.getPathComponent = function(cfiStr) {
var splitStr = cfiStr.split("!");
var pathComponent = splitStr[1] ? splitStr[1].split(":") : '';
return splitStr[1];
return pathComponent[0];
};
EPUBJS.EpubCFI.prototype.getOffset = function(cfiStr) {
EPUBJS.EpubCFI.prototype.getCharecterOffsetComponent = function(cfiStr) {
var splitStr = cfiStr.split(":");
return [splitStr[0], splitStr[1]];
return splitStr[1] || '';
};
EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
var cfi = {},
chapSegment,
chapterComponent,
pathComponent,
charecterOffsetComponent,
assertion,
chapId,
path,
end,
text;
cfi.chapter = this.getChapter(cfiStr);
if(cfiStr.indexOf("epubcfi(") === 0) {
// Remove intial epubcfi( and ending )
cfiStr = cfiStr.slice(8, cfiStr.length-1);
}
chapSegment = parseInt(cfi.chapter.split("/")[2]) || false;
cfi.fragment = this.getFragment(cfiStr);
if(!chapSegment || !cfi.fragment) return {spinePos: -1};
chapterComponent = this.getChapterComponent(cfiStr);
pathComponent = this.getPathComponent(cfiStr);
charecterOffsetComponent = this.getCharecterOffsetComponent(cfiStr);
// Make sure this is a valid cfi or return
if(!chapterComponent.length || !pathComponent.length) {
return {spinePos: -1};
}
// Chapter segment is always the second one
chapSegment = chapterComponent.split("/")[2] || '';
if(!chapSegment) return {spinePos:-1};
cfi.spinePos = (parseInt(chapSegment) / 2 - 1 ) || 0;
chapId = cfi.chapter.match(/\[(.*)\]/);
chapId = chapSegment.match(/\[(.*)\]/);
cfi.spineId = chapId ? chapId[1] : false;
path = cfi.fragment.split('/');
end = path[path.length-1];
cfi.sections = [];
//-- Check for Character Offset
if(parseInt(end) % 2){
text = this.getOffset();
cfi.text = parseInt(text[0]);
cfi.character = parseInt(text[1]);
path.pop(); //-- remove from path to element
if(pathComponent.indexOf(',') != -1) {
// Handle ranges -- not supported yet
console.warn("CFI Ranges are not supported");
}
path = pathComponent.split('/');
end = path[path.length-1];
cfi.steps = [];
path.forEach(function(part){
var index, has_id, id;
var type, index, has_brackets, id;
if(!part) return;
index = parseInt(part) / 2 - 1;
has_id = part.match(/\[(.*)\]/);
if(has_id && has_id[1]){
id = has_id[1];
//-- 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.sections.push({
cfi.steps.push({
"type" : type,
'index' : index,
'id' : id || false
});
assertion = charecterOffsetComponent.match(/\[(.*)\]/);
if(assertion && assertion[1]){
cfi.characterOffset = parseInt(charecterOffsetComponent.split('[')[0]);
// We arent handling these assertions yet
cfi.textLocationAssertion = assertion[1];
} else {
cfi.characterOffset = parseInt(charecterOffsetComponent);
}
});
return cfi;
};
EPUBJS.EpubCFI.prototype.getElement = function(cfi, _doc) {
var doc = _doc || document,
sections = cfi.sections,
element = doc.getElementsByTagName('html')[0],
children = Array.prototype.slice.call(element.children),
num, index, part,
has_id, id;
// sections.shift(); //-- html
var doc = _doc || document,
element = doc.getElementsByTagName('html')[0],
children = Array.prototype.slice.call(element.children),
num, index, part, sections,
text, textBegin, textEnd;
if(typeof cfi === 'string') {
cfi = this.parse(cfi);
}
sections = cfi.steps;
while(sections && sections.length > 0) {
part = sections.shift();
// Wrap text elements in a span and return that new element
if(part.type === "text") {
text = element.childNodes[part.index];
element = doc.createElement('span');
element.id = "EPUBJS-CFI-MARKER:"+ EPUBJS.core.uuid();
if(part.id){
if(cfi.characterOffset) {
textBegin = doc.createTextNode(text.textContent.slice(0, cfi.characterOffset));
textEnd = doc.createTextNode(text.textContent.slice(cfi.characterOffset));
text.parentNode.insertBefore(textEnd, text);
text.parentNode.insertBefore(element, textEnd);
text.parentNode.insertBefore(textBegin, element);
text.parentNode.removeChild(text);
} else {
text.parentNode.insertBefore(element, text);
}
// sort cut to find element by id
} else if(part.id){
element = doc.getElementById(part.id);
// find element in parent
}else{
element = children[part.index];
if(!children) console.error("No Kids", element);
element = children[part.index];
}
if(!element) console.error("No Element For", part, cfi);
children = Array.prototype.slice.call(element.children);
}
return element;
};
//-- Todo: function to remove IDs to sort
EPUBJS.EpubCFI.prototype.compare = function(cfiOne, cfiTwo) {
if(typeof cfiOne === 'string') {
cfiOne = this.parse(cfiOne);
}
if(typeof cfiTwo === 'string') {
cfiTwo = this.parse(cfiTwo);
}
// Compare Spine Positions
if(cfiOne.spinePos > cfiTwo.spinePos) {
return 1;
}
if(cfiOne.spinePos < cfiTwo.spinePos) {
return -1;
}
// Compare Each Step
for (var i = 0; i < cfiOne.steps.length; i++) {
if(!cfiTwo.steps[i]) {
return 1;
}
if(cfiOne.steps[i].index > cfiTwo.steps[i].index) {
return 1;
}
if(cfiOne.steps[i].index < cfiTwo.steps[i].index) {
return -1;
}
// Otherwise continue checking
}
// Compare the charecter offset of the text node
if(cfiOne.characterOffset > cfiTwo.characterOffset) {
return 1;
}
if(cfiOne.characterOffset < cfiTwo.characterOffset) {
return -1;
}
// CFI's are equal
return 0;
};

View file

@ -0,0 +1,5 @@
EPUBJS.Navigation = function() {
};
// percentage at cfi, nearest page to Cfi, total pages and goto page.

View file

@ -218,7 +218,7 @@ EPUBJS.Parser.prototype.spine = function(spineXml, manifest){
//-- Add to array to mantain ordering and cross reference with manifest
items.forEach(function(item, index){
var Id = item.getAttribute('idref');
var cfiBase = epubcfi.generateChapter(spineNodeIndex, index, Id);
var cfiBase = epubcfi.generateChapterComponent(spineNodeIndex, index, Id);
var props = item.getAttribute('properties') || '';
var propArray = props.length ? props.split(' ') : [];
var manifestProps = manifest[Id].properties;

View file

@ -425,7 +425,7 @@ EPUBJS.Renderer.prototype.walk = function(node) {
EPUBJS.Renderer.prototype.getPageCfi = function(prevEl){
this.visibileEl = this.findFirstVisible(prevEl);
return this.epubcfi.generateFragment(this.visibileEl, this.currentChapter.cfiBase);
return this.epubcfi.generateCfiFromElement(this.visibileEl, this.currentChapter.cfiBase);
};
// Goto a cfi position in the current chapter