mirror of
https://github.com/futurepress/epub.js.git
synced 2025-10-03 14:59:18 +02:00
Update toc nav subitem parsing
This commit is contained in:
parent
4bbec4501d
commit
5f53b7223c
3 changed files with 110 additions and 56 deletions
|
@ -102,14 +102,22 @@
|
|||
var $nav = document.getElementById("toc"),
|
||||
docfrag = document.createDocumentFragment();
|
||||
|
||||
toc.forEach(function(chapter, index) {
|
||||
var processTocItem = function(chapter, parent) {
|
||||
var item = document.createElement("li");
|
||||
var link = document.createElement("a");
|
||||
link.id = "chap-" + chapter.id;
|
||||
link.textContent = chapter.label;
|
||||
link.href = chapter.href;
|
||||
item.appendChild(link);
|
||||
docfrag.appendChild(item);
|
||||
parent.appendChild(item);
|
||||
|
||||
if (chapter.subitems.length) {
|
||||
var ul = document.createElement("ul");
|
||||
item.appendChild(ul);
|
||||
chapter.subitems.forEach(function(subchapter) {
|
||||
processTocItem(subchapter, ul);
|
||||
});
|
||||
}
|
||||
|
||||
link.onclick = function(){
|
||||
var url = link.getAttribute("href");
|
||||
|
@ -118,6 +126,10 @@
|
|||
return false;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
toc.forEach(function(chapter) {
|
||||
processTocItem(chapter, docfrag);
|
||||
});
|
||||
|
||||
$nav.appendChild(docfrag);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {qs, qsa, querySelectorByType} from "./utils/core";
|
||||
import {qs, qsa, querySelectorByType, filterChildren, getParentByTagName} from "./utils/core";
|
||||
|
||||
/**
|
||||
* Navigation Parser
|
||||
|
@ -37,6 +37,8 @@ class Navigation {
|
|||
this.toc = this.parseNcx(xml);
|
||||
}
|
||||
|
||||
this.length = 0;
|
||||
|
||||
this.unpack(this.toc);
|
||||
}
|
||||
|
||||
|
@ -50,11 +52,22 @@ class Navigation {
|
|||
|
||||
for (var i = 0; i < toc.length; i++) {
|
||||
item = toc[i];
|
||||
|
||||
if (item.href) {
|
||||
this.tocByHref[item.href] = i;
|
||||
}
|
||||
|
||||
if (item.id) {
|
||||
this.tocById[item.id] = i;
|
||||
}
|
||||
|
||||
this.length = toc.length;
|
||||
this.length++;
|
||||
|
||||
if (item.subitems.length) {
|
||||
this.unpack(item.subitems);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -78,40 +91,6 @@ class Navigation {
|
|||
return this.toc[index];
|
||||
}
|
||||
|
||||
createTocItem(linkElement, id) {
|
||||
var list = [],
|
||||
tocLinkElms = linkElement.childNodes,
|
||||
tocLinkArray = Array.prototype.slice.call(tocLinkElms);
|
||||
|
||||
var index = id ? id : 0;
|
||||
tocLinkArray.forEach((linkElm) => {
|
||||
if (linkElm.nodeName.toLowerCase() === 'li') {
|
||||
var tocLink = qs(linkElm, 'a'),
|
||||
tocLinkData = {
|
||||
id: -1,
|
||||
href: tocLink.getAttribute('href'),
|
||||
label: tocLink.textContent,
|
||||
parent: null
|
||||
},
|
||||
subItemElm = qs(linkElm, 'ol');
|
||||
index++;
|
||||
tocLinkData.id = index;
|
||||
if (id) {
|
||||
tocLinkData.parent = id;
|
||||
}
|
||||
list.push(tocLinkData);
|
||||
if (subItemElm) {
|
||||
var subitems = this.createTocItem(subItemElm, index);
|
||||
if (subitems && subitems.length > 0) {
|
||||
index = index + subitems.length;
|
||||
list = list.concat(subitems);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse from a Epub > 3.0 Nav
|
||||
* @private
|
||||
|
@ -120,8 +99,29 @@ class Navigation {
|
|||
*/
|
||||
parseNav(navHtml){
|
||||
var navElement = querySelectorByType(navHtml, "nav", "toc");
|
||||
var tocItems = qs(navElement, "ol");
|
||||
return this.createTocItem(tocItems);
|
||||
var navItems = navElement ? qsa(navElement, "li") : [];
|
||||
var length = navItems.length;
|
||||
var i;
|
||||
var toc = {};
|
||||
var list = [];
|
||||
var item, parent;
|
||||
|
||||
if(!navItems || length === 0) return list;
|
||||
|
||||
for (i = 0; i < length; ++i) {
|
||||
item = this.navItem(navItems[i]);
|
||||
if (item) {
|
||||
toc[item.id] = item;
|
||||
if(!item.parent) {
|
||||
list.push(item);
|
||||
} else {
|
||||
parent = toc[item.parent];
|
||||
parent.subitems.push(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -131,16 +131,28 @@ class Navigation {
|
|||
* @return {object} navItem
|
||||
*/
|
||||
navItem(item){
|
||||
var id = item.getAttribute("id") || false,
|
||||
content = qs(item, "a"),
|
||||
src = content.getAttribute("href") || "",
|
||||
text = content.textContent || "",
|
||||
subitems = [],
|
||||
parentNode = item.parentNode,
|
||||
parent;
|
||||
let id = item.getAttribute("id") || undefined;
|
||||
let content = filterChildren(item, "a", true);
|
||||
|
||||
if(parentNode && parentNode.nodeName === "navPoint") {
|
||||
parent = parentNode.getAttribute("id");
|
||||
if (!content) {
|
||||
return;
|
||||
}
|
||||
|
||||
let src = content.getAttribute("href") || "";
|
||||
let text = content.textContent || "";
|
||||
let subitems = [];
|
||||
let parentItem = getParentByTagName(item, "li");
|
||||
let parent;
|
||||
|
||||
if (parentItem) {
|
||||
parent = parentItem.getAttribute("id");
|
||||
}
|
||||
|
||||
while (!parent && parentItem) {
|
||||
parentItem = getParentByTagName(parentItem, "li");
|
||||
if (parentItem) {
|
||||
parent = parentItem.getAttribute("id");
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -510,6 +510,36 @@ export function parents(node) {
|
|||
return nodes
|
||||
}
|
||||
|
||||
export function filterChildren(el, nodeName, single) {
|
||||
var result = [];
|
||||
var childNodes = el.childNodes;
|
||||
for (var i = 0; i < childNodes.length; i++) {
|
||||
let node = childNodes[i];
|
||||
if (node.nodeType === 1 && node.nodeName.toLowerCase() === nodeName) {
|
||||
if (single) {
|
||||
return node;
|
||||
} else {
|
||||
result.push(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!single) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
export function getParentByTagName(node, tagname) {
|
||||
let parent;
|
||||
if (node === null || tagname === '') return;
|
||||
parent = node.parentNode;
|
||||
while (parent.nodeType === 1) {
|
||||
if (parent.tagName.toLowerCase() === tagname) {
|
||||
return parent;
|
||||
}
|
||||
parent = parent.parentNode;
|
||||
}
|
||||
}
|
||||
|
||||
export class RangeObject {
|
||||
constructor() {
|
||||
this.collapsed = false;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue