1
0
Fork 0
mirror of https://github.com/futurepress/epub.js.git synced 2025-10-03 14:59:18 +02:00
epub.js/src/epubcfi.js

172 lines
3 KiB
JavaScript

EPUBJS.EpubCFI = function(cfiStr){
if(cfiStr) return this.parse(cfiStr);
}
EPUBJS.EpubCFI.prototype.generateChapter = function(spineNodeIndex, pos, id) {
var spineNodeIndex = spineNodeIndex + 1,
cfi = '/'+spineNodeIndex+'/';
cfi += (pos + 1) * 2;
if(id) cfi += "[" + id + "]";
cfi += "!";
return cfi;
}
EPUBJS.EpubCFI.prototype.generateFragment = function(element, chapter) {
var path = this.pathTo(element),
parts = [];
if(chapter) parts.push(chapter);
path.forEach(function(part){
parts.push((part.index + 1) * 2);
if(part.id &&
part.id.slice(0, 6) != "EPUBJS") { //-- ignore internal @EPUBJS ids
parts.push("[" + part.id + "]");
}
});
return parts.join('/');
}
EPUBJS.EpubCFI.prototype.pathTo = function(node) {
var stack = [],
children;
while(node && node.parentNode !== null) {
children = node.parentNode.children;
stack.unshift({
'id' : node.id,
// 'classList' : node.classList,
'tagName' : node.tagName,
'index' : children ? Array.prototype.indexOf.call(children, node) : 0
});
node = node.parentNode;
}
return stack;
}
EPUBJS.EpubCFI.prototype.getChapter = function(cfiStr) {
var splitStr = cfiStr.split("!");
return splitStr[0];
}
EPUBJS.EpubCFI.prototype.getFragment = function(cfiStr) {
var splitStr = cfiStr.split("!");
return splitStr[1];
}
EPUBJS.EpubCFI.prototype.getOffset = function(cfiStr) {
var splitStr = cfiStr.split(":");
return [splitStr[0], splitStr[1]];
}
EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
var cfi = {},
chapId,
path,
end,
text;
cfi.chapter = this.getChapter(cfiStr);
cfi.fragment = this.getFragment(cfiStr);
cfi.spinePos = (parseInt(cfi.chapter.split("/")[2]) / 2 - 1 ) || 0;
chapId = cfi.chapter.match(/\[(.*)\]/);
cfi.spineId = 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
}
path.forEach(function(part){
var index, has_id, id;
if(!part) return;
index = parseInt(part) / 2 - 1;
has_id = part.match(/\[(.*)\]/);
if(has_id && has_id[1]){
id = has_id[1];
}
cfi.sections.push({
'index' : index,
'id' : id || false
});
});
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
while(sections.length > 0) {
part = sections.shift();
if(part.id){
element = doc.querySelector("#" + part.id);
}else{
element = children[part.index];
if(!children) console.error("No Kids", element);
}
if(!element) console.error("No Element For", part);
children = Array.prototype.slice.call(element.children);
}
return element;
}
//-- Todo: function to remove IDs to sort