1
0
Fork 0
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:
Fred Chasen 2017-10-31 18:27:26 -07:00
parent 4bbec4501d
commit 5f53b7223c
3 changed files with 110 additions and 56 deletions

View file

@ -102,14 +102,22 @@
var $nav = document.getElementById("toc"), var $nav = document.getElementById("toc"),
docfrag = document.createDocumentFragment(); docfrag = document.createDocumentFragment();
toc.forEach(function(chapter, index) { var processTocItem = function(chapter, parent) {
var item = document.createElement("li"); var item = document.createElement("li");
var link = document.createElement("a"); var link = document.createElement("a");
link.id = "chap-" + chapter.id; link.id = "chap-" + chapter.id;
link.textContent = chapter.label; link.textContent = chapter.label;
link.href = chapter.href; link.href = chapter.href;
item.appendChild(link); 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(){ link.onclick = function(){
var url = link.getAttribute("href"); var url = link.getAttribute("href");
@ -118,6 +126,10 @@
return false; return false;
}; };
}
toc.forEach(function(chapter) {
processTocItem(chapter, docfrag);
}); });
$nav.appendChild(docfrag); $nav.appendChild(docfrag);

View file

@ -1,4 +1,4 @@
import {qs, qsa, querySelectorByType} from "./utils/core"; import {qs, qsa, querySelectorByType, filterChildren, getParentByTagName} from "./utils/core";
/** /**
* Navigation Parser * Navigation Parser
@ -37,6 +37,8 @@ class Navigation {
this.toc = this.parseNcx(xml); this.toc = this.parseNcx(xml);
} }
this.length = 0;
this.unpack(this.toc); this.unpack(this.toc);
} }
@ -50,11 +52,22 @@ class Navigation {
for (var i = 0; i < toc.length; i++) { for (var i = 0; i < toc.length; i++) {
item = toc[i]; item = toc[i];
if (item.href) {
this.tocByHref[item.href] = i; this.tocByHref[item.href] = i;
}
if (item.id) {
this.tocById[item.id] = i; 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]; 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 * Parse from a Epub > 3.0 Nav
* @private * @private
@ -120,8 +99,29 @@ class Navigation {
*/ */
parseNav(navHtml){ parseNav(navHtml){
var navElement = querySelectorByType(navHtml, "nav", "toc"); var navElement = querySelectorByType(navHtml, "nav", "toc");
var tocItems = qs(navElement, "ol"); var navItems = navElement ? qsa(navElement, "li") : [];
return this.createTocItem(tocItems); 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 * @return {object} navItem
*/ */
navItem(item){ navItem(item){
var id = item.getAttribute("id") || false, let id = item.getAttribute("id") || undefined;
content = qs(item, "a"), let content = filterChildren(item, "a", true);
src = content.getAttribute("href") || "",
text = content.textContent || "",
subitems = [],
parentNode = item.parentNode,
parent;
if(parentNode && parentNode.nodeName === "navPoint") { if (!content) {
parent = parentNode.getAttribute("id"); 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 { return {

View file

@ -510,6 +510,36 @@ export function parents(node) {
return nodes 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 { export class RangeObject {
constructor() { constructor() {
this.collapsed = false; this.collapsed = false;