diff --git a/plugin/js/parsers/KakuyomuParser.js b/plugin/js/parsers/KakuyomuParser.js index 1b6c2dd7..87d2c44c 100644 --- a/plugin/js/parsers/KakuyomuParser.js +++ b/plugin/js/parsers/KakuyomuParser.js @@ -7,13 +7,45 @@ class KakuyomuParser extends Parser{ super(); } - getChapterUrls(dom) { - let chapters = [...dom.querySelectorAll("a.widget-toc-episode-episodeTitle")] - .map(link => ({ - sourceUrl: link.href, - title: link.querySelector(".widget-toc-episode-titleLabel").textContent.trim() - })); - return Promise.resolve(chapters); + async getChapterUrls(dom) { + return this.buildToc(dom); + } + + buildToc(dom) { + let script = dom.querySelector("script#__NEXT_DATA__").innerHTML; + let json = JSON.parse(script).props.pageProps.__APOLLO_STATE__; + let work = json["Work:" + this.extractWorkId(dom)]; + let chapters = [] + for(let tocc of work.tableOfContents) { + this.buildSubToc(chapters, json[tocc.__ref], json, dom.baseURI); + } + return chapters; + } + + extractWorkId(dom) { + let url = dom.baseURI; + let index = url.lastIndexOf("/"); + return url.substring(index + 1); + } + + buildSubToc(chapters, tocc, json, baseURI) { + let chapter = json[tocc.chapter.__ref]; + let arcStart = true; + for(let episoderef of tocc.episodes) { + let episode = this.buildEpisode(json[episoderef.__ref], baseURI); + if (arcStart) { + episode.newArc = chapter.title; + arcStart = false; + } + chapters.push(episode); + } + } + + buildEpisode(episode, baseURI) { + return ({ + sourceUrl: baseURI + "/episodes/" + episode.id, + title: episode.title, + }); } findContent(dom) { @@ -21,12 +53,7 @@ class KakuyomuParser extends Parser{ } extractTitleImpl(dom) { - return dom.querySelector("#workTitle"); - } - - extractAuthor(dom) { - let authorLabel = dom.querySelector("#workAuthor-activityName"); - return (authorLabel === null) ? super.extractAuthor(dom) : authorLabel.textContent; + return dom.querySelector("a[title]"); } findChapterTitle(dom) { @@ -43,6 +70,8 @@ class KakuyomuParser extends Parser{ } getInformationEpubItemChildNodes(dom) { - return [...dom.querySelectorAll("p#introduction")]; + let info = [...dom.querySelectorAll("div")] + .filter(i => i.className.startsWith("CollapseTextWith")); + return (0 < info.length) ? [info[0]] : []; } }