(doc, resolve = (f) => f)
| 347 | }; |
| 348 | |
| 349 | const parseNav = (doc, resolve = (f) => f) => { |
| 350 | const { $, $$, $$$ } = childGetter(doc, NS.XHTML); |
| 351 | const resolveHref = (href) => (href ? decodeURI(resolve(href)) : null); |
| 352 | const parseLI = (getType) => ($li) => { |
| 353 | const $a = $($li, "a") ?? $($li, "span"); |
| 354 | const $ol = $($li, "ol"); |
| 355 | const href = resolveHref($a?.getAttribute("href")); |
| 356 | const label = getElementText($a) || $a?.getAttribute("title"); |
| 357 | // TODO: get and concat alt/title texts in content |
| 358 | const result = { label, href, subitems: parseOL($ol) }; |
| 359 | if (getType) result.type = $a?.getAttributeNS(NS.EPUB, "type")?.split(/\s/); |
| 360 | return result; |
| 361 | }; |
| 362 | const parseOL = ($ol, getType) => ($ol ? $$($ol, "li").map(parseLI(getType)) : null); |
| 363 | const parseNav = ($nav, getType) => parseOL($($nav, "ol"), getType); |
| 364 | |
| 365 | const $$nav = $$$(doc, "nav"); |
| 366 | let toc = null, |
| 367 | pageList = null, |
| 368 | landmarks = null, |
| 369 | others = []; |
| 370 | for (const $nav of $$nav) { |
| 371 | const type = $nav.getAttributeNS(NS.EPUB, "type")?.split(/\s/) ?? []; |
| 372 | if (type.includes("toc")) toc ??= parseNav($nav); |
| 373 | else if (type.includes("page-list")) pageList ??= parseNav($nav); |
| 374 | else if (type.includes("landmarks")) landmarks ??= parseNav($nav, true); |
| 375 | else |
| 376 | others.push({ |
| 377 | label: getElementText($nav.firstElementChild), |
| 378 | type, |
| 379 | list: parseNav($nav), |
| 380 | }); |
| 381 | } |
| 382 | return { toc, pageList, landmarks, others }; |
| 383 | }; |
| 384 | |
| 385 | const parseNCX = (doc, resolve = (f) => f) => { |
| 386 | const { $, $$ } = childGetter(doc, NS.NCX); |
no test coverage detected