mirror of
https://github.com/futurepress/epub.js.git
synced 2025-10-03 14:59:18 +02:00
updated cfi to handle text nodes and character offset
This commit is contained in:
parent
0a0a13f5f5
commit
73ac66ba65
19 changed files with 529 additions and 228 deletions
2
books
2
books
|
@ -1 +1 @@
|
|||
Subproject commit ab9755a74714b647290c861f666515de220935d8
|
||||
Subproject commit 09bd1725f5839996e747cf83500a2526b86ae6af
|
214
build/epub.js
214
build/epub.js
|
@ -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,27 +3070,23 @@ 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);
|
||||
|
@ -3090,6 +3095,13 @@ EPUBJS.EpubCFI.prototype.generateFragment = function(element, chapter) {
|
|||
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,110 +3122,152 @@ 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;
|
||||
|
||||
//-- 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_id = part.match(/\[(.*)\]/);
|
||||
|
||||
|
||||
if(has_id && has_id[1]){
|
||||
id = has_id[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;
|
||||
num, index, part, sections,
|
||||
text, textBegin, textEnd;
|
||||
|
||||
// sections.shift(); //-- html
|
||||
if(typeof cfi === 'string') {
|
||||
cfi = this.parse(cfi);
|
||||
}
|
||||
|
||||
sections = cfi.steps;
|
||||
|
||||
while(sections && sections.length > 0) {
|
||||
|
||||
part = sections.shift();
|
||||
|
||||
if(part.id){
|
||||
|
||||
element = doc.getElementById(part.id);
|
||||
// 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(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];
|
||||
}
|
||||
|
||||
|
||||
|
@ -3224,7 +3278,44 @@ EPUBJS.EpubCFI.prototype.getElement = function(cfi, _doc) {
|
|||
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
6
build/epub.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -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,27 +3069,23 @@ 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);
|
||||
|
@ -3089,6 +3094,13 @@ EPUBJS.EpubCFI.prototype.generateFragment = function(element, chapter) {
|
|||
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,110 +3121,152 @@ 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;
|
||||
|
||||
//-- 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_id = part.match(/\[(.*)\]/);
|
||||
|
||||
|
||||
if(has_id && has_id[1]){
|
||||
id = has_id[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;
|
||||
num, index, part, sections,
|
||||
text, textBegin, textEnd;
|
||||
|
||||
// sections.shift(); //-- html
|
||||
if(typeof cfi === 'string') {
|
||||
cfi = this.parse(cfi);
|
||||
}
|
||||
|
||||
sections = cfi.steps;
|
||||
|
||||
while(sections && sections.length > 0) {
|
||||
|
||||
part = sections.shift();
|
||||
|
||||
if(part.id){
|
||||
|
||||
element = doc.getElementById(part.id);
|
||||
// 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(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];
|
||||
}
|
||||
|
||||
|
||||
|
@ -3223,7 +3277,44 @@ EPUBJS.EpubCFI.prototype.getElement = function(cfi, _doc) {
|
|||
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
|
||||
|
|
|
@ -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";
|
||||
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
2
build/hooks.min.js
vendored
|
@ -1 +1 @@
|
|||
EPUBJS.Hooks.register("beforeChapterDisplay").endnotes=function(a,b){var c=b.contents.querySelectorAll("a[href]"),d=Array.prototype.slice.call(c),e="epub:type",f="noteref",g=EPUBJS.core.folder(location.pathname),h=g+EPUBJS.cssPath||g,i={};EPUBJS.core.addCss(h+"popup.css",!1,b.render.document.head),d.forEach(function(a){function c(){var c,e=b.height,f=b.width,j=225;o||(c=l.cloneNode(!0),o=c.querySelector("p")),i[k]||(i[k]=document.createElement("div"),i[k].setAttribute("class","popup"),pop_content=document.createElement("div"),i[k].appendChild(pop_content),pop_content.appendChild(o),pop_content.setAttribute("class","pop_content"),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
2
build/libs/zip.min.js
vendored
2
build/libs/zip.min.js
vendored
File diff suppressed because one or more lines are too long
6
demo/js/epub.min.js
vendored
6
demo/js/epub.min.js
vendored
File diff suppressed because one or more lines are too long
2
demo/js/hooks.min.js
vendored
2
demo/js/hooks.min.js
vendored
|
@ -1 +1 @@
|
|||
EPUBJS.Hooks.register("beforeChapterDisplay").endnotes=function(a,b){var c=b.contents.querySelectorAll("a[href]"),d=Array.prototype.slice.call(c),e="epub:type",f="noteref",g=EPUBJS.core.folder(location.pathname),h=g+EPUBJS.cssPath||g,i={};EPUBJS.core.addCss(h+"popup.css",!1,b.render.document.head),d.forEach(function(a){function c(){var c,e=b.height,f=b.width,j=225;o||(c=l.cloneNode(!0),o=c.querySelector("p")),i[k]||(i[k]=document.createElement("div"),i[k].setAttribute("class","popup"),pop_content=document.createElement("div"),i[k].appendChild(pop_content),pop_content.appendChild(o),pop_content.setAttribute("class","pop_content"),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()};
|
2
demo/js/libs/inflate.min.js
vendored
2
demo/js/libs/inflate.min.js
vendored
File diff suppressed because one or more lines are too long
2
demo/js/libs/zip.min.js
vendored
2
demo/js/libs/zip.min.js
vendored
File diff suppressed because one or more lines are too long
2
demo/js/reader.min.js
vendored
2
demo/js/reader.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -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";
|
||||
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);
|
||||
|
|
11
src/core.js
11
src/core.js
|
@ -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;
|
||||
};
|
195
src/epubcfi.js
195
src/epubcfi.js
|
@ -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,27 +11,23 @@ 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);
|
||||
|
@ -41,6 +36,13 @@ EPUBJS.EpubCFI.prototype.generateFragment = function(element, chapter) {
|
|||
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,110 +63,152 @@ 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;
|
||||
|
||||
//-- 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_id = part.match(/\[(.*)\]/);
|
||||
|
||||
|
||||
if(has_id && has_id[1]){
|
||||
id = has_id[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;
|
||||
num, index, part, sections,
|
||||
text, textBegin, textEnd;
|
||||
|
||||
// sections.shift(); //-- html
|
||||
if(typeof cfi === 'string') {
|
||||
cfi = this.parse(cfi);
|
||||
}
|
||||
|
||||
sections = cfi.steps;
|
||||
|
||||
while(sections && sections.length > 0) {
|
||||
|
||||
part = sections.shift();
|
||||
|
||||
if(part.id){
|
||||
|
||||
element = doc.getElementById(part.id);
|
||||
// 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(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];
|
||||
}
|
||||
|
||||
|
||||
|
@ -175,4 +219,41 @@ EPUBJS.EpubCFI.prototype.getElement = function(cfi, _doc) {
|
|||
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;
|
||||
};
|
|
@ -0,0 +1,5 @@
|
|||
EPUBJS.Navigation = function() {
|
||||
|
||||
};
|
||||
|
||||
// percentage at cfi, nearest page to Cfi, total pages and goto page.
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue