From f8e0efad05524467251d2a66829282e5558b46c2 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Tue, 29 Nov 2022 15:40:22 +0800 Subject: [PATCH] fix bug --- .../src/websites/stack-overflow-handler.ts | 92 +++++++++---------- 1 file changed, 44 insertions(+), 48 deletions(-) diff --git a/packages/content-handler/src/websites/stack-overflow-handler.ts b/packages/content-handler/src/websites/stack-overflow-handler.ts index de937dc33..ecfe77029 100644 --- a/packages/content-handler/src/websites/stack-overflow-handler.ts +++ b/packages/content-handler/src/websites/stack-overflow-handler.ts @@ -6,30 +6,29 @@ export class StackOverflowHandler extends ContentHandler { this.name = 'stackoverflow' } - parseVotes(element: Element, dom: Document, title: string) { - const votes = element.querySelector(`div[itemprop='upvoteCount']`) - if (votes) { - const newVotes = dom.createElement('div') - newVotes.innerHTML = `

${title}: ${votes.innerHTML}vote(s)

` - element.prepend(newVotes) + parseText(element: Element, title: string) { + const newText = element.ownerDocument.createElement('div') + const text = element.querySelector(`div[itemprop='text']`) + if (text) { + const votes = element.querySelector(`div[itemprop='upvoteCount']`) + + if (votes) { + newText.innerHTML = `

${title}:${votes.innerHTML}vote(s)

${text.innerHTML}
` + } } + return newText } - parseComments(element: Element, dom: Document) { + parseComments(element: Element) { + const dom = element.ownerDocument + const newComments = dom.createElement('div') + // comments const commentsDiv = element.querySelector(`.comments`) if (commentsDiv) { const comments = commentsDiv.querySelectorAll(`.comment`) if (comments.length > 0) { - // const count = element.querySelector( - // `span[itemprop='commentCount']` - // )?.textContent - - const newComments = dom.createElement('div') - newComments.innerHTML = `

Comments

` - // newComments.innerHTML = `

${ - // count ? count + ' Comments' : 'Comment' - // }

` + newComments.innerHTML = `

Comments

` comments.forEach((comment) => { const author = comment.querySelector(`.comment-user`) @@ -38,36 +37,41 @@ export class StackOverflowHandler extends ContentHandler { const date = comment.querySelector(`.relativetime-clean`)?.textContent if (author && text && authorHref && date) { const newComment = dom.createElement('p') - newComment.innerHTML = `${author.innerHTML}: ${text} - ${date}` + newComment.innerHTML = `${author.innerHTML}: ${text} - ${date}` newComments.appendChild(newComment) } }) - commentsDiv.parentNode?.replaceChild(newComments, commentsDiv) } } - // remove comment count - element.querySelector(`span[itemprop='commentCount']`)?.remove() + return newComments } - parseUser(element: Element, dom: Document) { - const users = element.querySelectorAll(`.post-signature`) - users.forEach((user) => { - const name = user.querySelector(`.user-details a`)?.textContent - const link = user.querySelector(`.user-details a`)?.getAttribute('href') - const reputation = user.querySelector(`.reputation-score`)?.textContent - const badges = Array.from(user.querySelectorAll(`span[title*='badges']`)) + parseAuthors(element: Element) { + const dom = element.ownerDocument + const newAuthors = dom.createElement('div') + + const authors = element.querySelectorAll(`.post-signature`) + authors.forEach((author) => { + const name = author.querySelector(`.user-details a`)?.textContent + const link = author.querySelector(`.user-details a`)?.getAttribute('href') + const reputation = author.querySelector(`.reputation-score`)?.textContent + const badges = Array.from( + author.querySelectorAll(`span[title*='badges']`) + ) .map((badge) => badge.getAttribute('title')) .join(', ') - const date = user.querySelector(`.user-action-time`)?.textContent + const date = author.querySelector(`.user-action-time`)?.textContent if (name && link && reputation && date) { - const newUser = dom.createElement('p') - newUser.innerHTML = `By ${name} - ${reputation} reputation - ${ + const newAuthor = dom.createElement('p') + newAuthor.innerHTML = `${name} - ${reputation} reputation - ${ badges || 'no badge' } - ${date}` - element.replaceChild(newUser, user) + newAuthors.appendChild(newAuthor) } }) + + return newAuthors } shouldPreParse(url: string, dom: Document): boolean { @@ -77,36 +81,28 @@ export class StackOverflowHandler extends ContentHandler { async preParse(url: string, dom: Document): Promise { const mainEntity = dom.querySelector(`div[itemprop='mainEntity']`) if (mainEntity) { + const newMainEntity = dom.createElement('div') const question = mainEntity.querySelector('.question') if (question) { - this.parseVotes(question, dom, 'Question') - this.parseComments(question, dom) - this.parseUser(question, dom) + newMainEntity.appendChild(this.parseText(question, 'Question')) + newMainEntity.appendChild(this.parseAuthors(question)) + newMainEntity.appendChild(this.parseComments(question)) } const answersDiv = mainEntity.querySelector('#answers') if (answersDiv) { - // const count = mainEntity.querySelector( - // `span[itemprop='answerCount']` - // )?.textContent - const newAnswers = dom.createElement('div') - newAnswers.innerHTML = `

Answers

` - // newAnswers.innerHTML = `

${ - // count ? count + ' Answers' : 'Answer' - // }

` - const answers = answersDiv.querySelectorAll(`.answer`) answers.forEach((answer) => { const title = answer.classList.contains('accepted-answer') ? 'Accepted Answer' : 'Answer' - this.parseVotes(answer, dom, title) - this.parseComments(answer, dom) - this.parseUser(answer, dom) - newAnswers.appendChild(answer) + newMainEntity.appendChild(this.parseText(answer, title)) + newMainEntity.appendChild(this.parseAuthors(answer)) + newMainEntity.appendChild(this.parseComments(answer)) }) - answersDiv.replaceChildren(newAnswers) } + + dom.body.replaceChildren(newMainEntity) } return Promise.resolve(dom)