Fix #5514: switch from readability to defuddle

This commit is contained in:
Oliver Blanthorn 2026-08-30 19:21:23 +02:00
parent e7caf837ae
commit 1898d4738e
No known key found for this signature in database
GPG key ID: 2BB8C36BB504BFF3
5 changed files with 185 additions and 13 deletions

View file

@ -1,6 +1,6 @@
{
"firefox": {
"minimumVersion": "94.0",
"minimumVersion": "121.0",
"manifestVersionPath": [
"applications",
"gecko",

View file

@ -12,11 +12,11 @@
"stream": "stream-browserify"
},
"dependencies": {
"@mozilla/readability": "^0.5.0",
"cleanslate": "git+https://github.com/tridactyl/cleanslate.git#master",
"compute-scroll-into-view": "^3.0.0",
"csp-serdes": "github:cmcaine/csp-serdes",
"css": "^3.0.0",
"defuddle": "^0.19.3",
"editor-adapter": "git+https://github.com/tridactyl/editor-adapter.git#master",
"esbuild": "^0.20.2",
"fuse.js": "^7.0.0",

View file

@ -6627,7 +6627,7 @@ export async function extoptions(...optionNameArgs: string[]) {
}
//#content_helper
import { Readability } from "@mozilla/readability"
import Defuddle from "defuddle"
/**
* @hidden
@ -6636,7 +6636,11 @@ import { Readability } from "@mozilla/readability"
export async function readerurl(article: any = undefined) {
if (!article) {
document.querySelectorAll(".TridactylStatusIndicator").forEach(ind => ind.parentNode.removeChild(ind))
article = new Readability(document.cloneNode(true) as any as Document).parse()
const { content, title, site, author, image } = new Defuddle(
document.cloneNode(true) as Document,
{ url: window.location.href },
).parse()
article = { content, title, site, author, image }
article["link"] = window.location.href
article["favicon"] = (await ownTab()).favIconUrl
}

View file

@ -44,6 +44,25 @@ async function updatePage() {
else if (link.target.toLowerCase() === "_blank") link.relList.add("noopener")
else link.target = "_top"
})
if (article.image) {
let coverUrl: URL | undefined
try {
coverUrl = new URL(article.image, article.link ?? document.baseURI)
} catch {
coverUrl = undefined
}
const cover = document.createElement("img")
if (
coverUrl !== undefined &&
["http:", "https:", "data:"].includes(coverUrl.protocol) &&
!Array.from(content.content.querySelectorAll("img")).some(
image => image.src === coverUrl.href,
)
) {
cover.src = coverUrl.href
content.content.prepend(cover)
}
}
article.content = content.innerHTML
let headerHtml = ""
if (article.title !== undefined) {
@ -55,22 +74,22 @@ async function updatePage() {
!(article.title ?? "").includes(article.link)
) {
document.title =
[article.siteName, article.title].filter(Boolean).join(": ") +
[article.site, article.title].filter(Boolean).join(": ") +
" :: " +
article.link
} else {
document.title = [article.siteName, article.title]
document.title = [article.site, article.title]
.filter(Boolean)
.join(": ")
}
title.textContent = article.title
header.appendChild(title)
if (article.byline !== undefined) {
if (article.author !== undefined) {
const author = document.createElement("p")
author.textContent = article.byline
author.textContent = article.author
header.appendChild(author)
}
const {text, words} = readingTime(article.textContent ?? "")
const { text, words } = readingTime(content.content.textContent ?? "")
const readingtime = document.createElement("p")
readingtime.textContent = `${words} words, ${text}`
header.appendChild(readingtime)

157
yarn.lock
View file

@ -889,10 +889,10 @@
resolved "https://registry.yarnpkg.com/@mdn/browser-compat-data/-/browser-compat-data-5.5.7.tgz#984652af52cbe7c111c376d519b5ce765d444003"
integrity sha512-DoHTZ/TjtNfUu9eiqJd+x3IcCQrhS+yOYU436TKUnlE36jZwNbK535D1CmTsSYdi/UcdCWNm5KRQZ9g1tlZCPw==
"@mozilla/readability@^0.5.0":
version "0.5.0"
resolved "https://registry.yarnpkg.com/@mozilla/readability/-/readability-0.5.0.tgz#a6d5055bbadd0f329cc3e72089d4f176ed96c1d5"
integrity sha512-Z+CZ3QaosfFaTqvhQsIktyGrjFjSC0Fa4EMph4mqKnWhmyoGICsV/8QK+8HpXut6zV7zwfWwqDmEjtk1Qf6EgQ==
"@mixmark-io/domino@^2.2.0":
version "2.2.0"
resolved "https://registry.yarnpkg.com/@mixmark-io/domino/-/domino-2.2.0.tgz#4e8ec69bf1afeb7a14f0628b7e2c0f35bdb336c3"
integrity sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==
"@nodelib/fs.scandir@2.1.3":
version "2.1.3"
@ -1338,6 +1338,11 @@
loglevel-plugin-prefix "^0.8.4"
strip-ansi "^7.1.0"
"@xmldom/xmldom@^0.9.10":
version "0.9.12"
resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.9.12.tgz#1f84c07cb95ccf28202299f77b5fd7fc257151e8"
integrity sha512-5AXjrcMClTryPe9LgZrygpB1lj7s0S9E0+W+AHaVKAVyHanafK86iPSvG5xHVSp/jC+VH1UXu0TAEmY279xH7A==
"@zip.js/zip.js@^2.7.53":
version "2.7.54"
resolved "https://registry.yarnpkg.com/@zip.js/zip.js/-/zip.js-2.7.54.tgz#ef0f46644b1a084155473b0d7710c80a892c2687"
@ -1835,6 +1840,11 @@ boolbase@^1.0.0:
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
boolbase@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-2.0.0.tgz#832968d211d5c008d833b86e049bb3943036e5b1"
integrity sha512-DkVaaQHymRhpYEYo9x1oo7Q7B0Y6KJUsjm3c9eTyFDby4MHLBTwZ6ZDWBel5zrYxj1WsZgC5oLpiz+93MluXeA==
boxen@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/boxen/-/boxen-7.0.0.tgz#9e5f8c26e716793fc96edcf7cf754cdf5e3fbf32"
@ -2198,6 +2208,11 @@ commander@2.9.0:
dependencies:
graceful-readlink ">= 1.0.0"
commander@^12.1.0:
version "12.1.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-12.1.0.tgz#01423b36f501259fdaac4d0e4d60c96c991585d3"
integrity sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==
commander@^2.19.0, commander@^2.20.3, commander@^2.6.0:
version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
@ -2330,11 +2345,27 @@ css-select@^5.1.0:
domutils "^3.0.1"
nth-check "^2.0.1"
css-select@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/css-select/-/css-select-7.0.0.tgz#7532bab5977b1f0e83bc16036661dbe0968b4dec"
integrity sha512-snmjEVXy+1LnwXdxhYvTMj1d9tOh4HxkA1YmoayVBeeyR2C14Pum7fcxJIm4SswYspVy866eYNwlH6xC3/VH5g==
dependencies:
boolbase "^2.0.0"
css-what "^8.0.0"
domhandler "^6.0.1"
domutils "^4.0.2"
nth-check "^3.0.1"
css-what@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
css-what@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/css-what/-/css-what-8.0.0.tgz#237889d60c4afef4736892f39e133ab4c8c21f0c"
integrity sha512-DH0Bqq3DNp5tdOReuNyAA+Ev4Y2GS5FMbZpeTLP6C4CDi0h5nL0BmUPChXw3o/qbHLDWHl49sbNqQVY7bMSDdw==
css@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/css/-/css-3.0.0.tgz#4447a4d58fdd03367c516ca9f64ae365cee4aa5d"
@ -2531,6 +2562,18 @@ define-properties@^1.2.0:
has-property-descriptors "^1.0.0"
object-keys "^1.1.1"
defuddle@^0.19.3:
version "0.19.3"
resolved "https://registry.yarnpkg.com/defuddle/-/defuddle-0.19.3.tgz#ca7c71b1eaeab8a47ff702bb6ed18b19a3fdd05b"
integrity sha512-5ZbOQ/B+iiRRqSQWwmCx/zEuqZOA/5q7gxyE2/4O2Bxq7nUC0PgKw9EdyxqWbFF1nrrrYemSeR25jg4TmA2fsA==
dependencies:
commander "^12.1.0"
optionalDependencies:
linkedom "^0.18.12"
mathml-to-latex "^1.8.0"
temml "^0.13.3"
turndown "^7.2.0"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
@ -2581,11 +2624,25 @@ dom-serializer@^2.0.0:
domhandler "^5.0.2"
entities "^4.2.0"
dom-serializer@^3.0.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-3.1.1.tgz#54be70ee4fcc2da010f488165e62294798dc57d3"
integrity sha512-4MEa38/QexBob6gFNwu+EGdWvhJ1OKuNwdYY3Y3NyeWDQfnGeDYQUDfIRzWu5B5gsv03so2Uxd28YC6zrsx3Lw==
dependencies:
domelementtype "^3.0.0"
domhandler "^6.0.0"
entities "^8.0.0"
domelementtype@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
domelementtype@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-3.0.0.tgz#e6c0a24bd39ca5eb7ea67a98d2f699497d7bcc55"
integrity sha512-umCQid3jKbDmVjx8jGaW7uUykm4DEUeyV21hPxNMo2nV955DhUThwqyOIDtreepP31hl84X7G5U9ZfsWvIB3Pg==
domexception@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/domexception/-/domexception-4.0.0.tgz#4ad1be56ccadc86fc76d033353999a8037d03673"
@ -2600,6 +2657,13 @@ domhandler@^5.0.1, domhandler@^5.0.2, domhandler@^5.0.3:
dependencies:
domelementtype "^2.3.0"
domhandler@^6.0.0, domhandler@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-6.0.1.tgz#75f351a03a6e10c35e08418f9cf0d287e00797cf"
integrity sha512-gYzvtM72ZtxQO0T048kd6HWSbbGCNOUwcnfQ01cqIJ4X2IYKFFHZ5mKvrQETcFXxsRObZulDaKmy//R7TPtsBg==
dependencies:
domelementtype "^3.0.0"
domutils@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.0.1.tgz#696b3875238338cb186b6c0612bd4901c89a4f1c"
@ -2609,6 +2673,24 @@ domutils@^3.0.1:
domelementtype "^2.3.0"
domhandler "^5.0.1"
domutils@^3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.2.2.tgz#edbfe2b668b0c1d97c24baf0f1062b132221bc78"
integrity sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==
dependencies:
dom-serializer "^2.0.0"
domelementtype "^2.3.0"
domhandler "^5.0.3"
domutils@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-4.0.2.tgz#0c1ac1fdbe8f554a60a6f5eb143ee85630327c94"
integrity sha512-qI4JLRKnSzqFqr7hAlS5xQDusBCjKSEG4t4+7aNrIQMHBcsC2TGEhuyABJdYkgSewL57PNLYEiibY2iPKhKpaA==
dependencies:
dom-serializer "^3.0.0"
domelementtype "^3.0.0"
domhandler "^6.0.0"
dot-prop@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-6.0.1.tgz#fc26b3cf142b9e59b74dbd39ed66ce620c681083"
@ -2707,6 +2789,16 @@ entities@^6.0.0:
resolved "https://registry.yarnpkg.com/entities/-/entities-6.0.1.tgz#c28c34a43379ca7f61d074130b2f5f7020a30694"
integrity sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==
entities@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/entities/-/entities-7.0.1.tgz#26e8a88889db63417dcb9a1e79a3f1bc92b5976b"
integrity sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==
entities@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-8.0.0.tgz#c1df5fe3602429747fa233d0dd26f142f0ce4743"
integrity sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==
error-ex@^1.3.1, error-ex@^1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
@ -3847,6 +3939,21 @@ html-escaper@^2.0.0:
resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.0.tgz#71e87f931de3fe09e56661ab9a29aadec707b491"
integrity sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig==
html-escaper@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-3.0.3.tgz#4d336674652beb1dcbc29ef6b6ba7f6be6fdfed6"
integrity sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==
htmlparser2@^10.1.0:
version "10.1.0"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-10.1.0.tgz#fe3f2e12c73b6e462d4e10395db9c1119e4d6ae4"
integrity sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==
dependencies:
domelementtype "^2.3.0"
domhandler "^5.0.3"
domutils "^3.2.2"
entities "^7.0.1"
htmlparser2@^8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.1.tgz#abaa985474fcefe269bc761a779b544d7196d010"
@ -5030,6 +5137,17 @@ lines-and-columns@^2.0.2:
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.3.tgz#b2f0badedb556b747020ab8ea7f0373e22efac1b"
integrity sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==
linkedom@^0.18.12:
version "0.18.13"
resolved "https://registry.yarnpkg.com/linkedom/-/linkedom-0.18.13.tgz#db4582d42d5606961dd8e596fc273bd8c06f50df"
integrity sha512-ES/o9qotMpzpN2MHs+Iq/JcVoOj8Fa5wiQYrTdFpvAnwXL0g66XHHUc9WUMk6nAlBtGsFQ24ne+SYnvnaQ2FSw==
dependencies:
css-select "^7.0.0"
cssom "^0.5.0"
html-escaper "^3.0.3"
htmlparser2 "^10.1.0"
uhyphen "^0.2.0"
linkify-it@^5.0.2:
version "5.0.2"
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-5.0.2.tgz#d3be0a693af3da9df3883f1e346a0e97461a8c19"
@ -5168,6 +5286,13 @@ math-intrinsics@^1.1.0:
resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9"
integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==
mathml-to-latex@^1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/mathml-to-latex/-/mathml-to-latex-1.8.0.tgz#1007f1cb3f6c47453d5c52dbbcb90a823380c6be"
integrity sha512-gQ0uK3zqB8HwlfaXJkEL5rgaZNbKUiBMmBP/B/W+b+t6KcseLSuYb1b0BjLgS9ZiQa24ePkqTX8/6FaQuDL7wQ==
dependencies:
"@xmldom/xmldom" "^0.9.10"
mdurl@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-2.0.0.tgz#80676ec0433025dd3e17ee983d0fe8de5a2237e0"
@ -5464,6 +5589,13 @@ nth-check@^2.0.1:
dependencies:
boolbase "^1.0.0"
nth-check@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-3.0.1.tgz#a5ede96060f7f0b74d7d3d8425f2a8f0610c5776"
integrity sha512-GX0gsdbGVCgnRgbeGaubfjpBXyYRWOOCVeYh08bSQvDZqxz5ndXs1OTfAt/h36G1xvI94YIspsI0sVFqAV9+RQ==
dependencies:
boolbase "^2.0.0"
nwsapi@^2.2.2:
version "2.2.24"
resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.24.tgz#f8927043d4c9b516abdebe804a32c8d1f9484d1f"
@ -6786,6 +6918,11 @@ tar-stream@^3.1.5:
fast-fifo "^1.2.0"
streamx "^2.15.0"
temml@^0.13.3:
version "0.13.5"
resolved "https://registry.yarnpkg.com/temml/-/temml-0.13.5.tgz#96c53c4ece59ae719859e2a5074b6d4251cee423"
integrity sha512-aPkDDgunanpLNL0ql32HbolqLep+w8DRcVXRql7rWrMt/PhczdLgL4UBYYVU3BYjCNjkGq4EqwIicu/zWr1iOg==
test-exclude@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e"
@ -6939,6 +7076,13 @@ tunnel-agent@^0.6.0:
dependencies:
safe-buffer "^5.0.1"
turndown@^7.2.0:
version "7.2.4"
resolved "https://registry.yarnpkg.com/turndown/-/turndown-7.2.4.tgz#42d98202aefa8c188c997b586bc6da78bdf27ea2"
integrity sha512-I8yFsfRzmzK0WV1pNNOA4A7y4RDfFxPRxb3t+e3ui14qSGOxGtiSP6GjeX+Y6CHb7HYaFj7ECUD7VE5kQMZWGQ==
dependencies:
"@mixmark-io/domino" "^2.2.0"
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
@ -7063,6 +7207,11 @@ uglify-js@^3.1.4:
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.19.3.tgz#82315e9bbc6f2b25888858acd1fff8441035b77f"
integrity sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==
uhyphen@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/uhyphen/-/uhyphen-0.2.0.tgz#8fdf0623314486e020a3c00ee5cc7a12fe722b81"
integrity sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==
unbox-primitive@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"