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)