mirror of
https://github.com/futurepress/epub.js.git
synced 2025-10-03 14:59:18 +02:00
172 lines
3 KiB
JavaScript
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
|