diff --git a/.pnp.cjs b/.pnp.cjs index a5fedd5a1..367e7018d 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -7241,6 +7241,7 @@ const RAW_RUNTIME_STATE = ["fluent-ffmpeg", "npm:2.1.2"],\ ["got", "npm:12.5.3"],\ ["gunzip-maybe", "npm:1.4.2"],\ + ["happy-dom", "npm:12.10.3"],\ ["hpagent", "npm:0.1.2"],\ ["iceshrimp-js", "workspace:packages/iceshrimp-js"],\ ["ioredis", "npm:5.3.2"],\ @@ -9594,6 +9595,15 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["css.escape", [\ + ["npm:1.5.1", {\ + "packageLocation": "./.yarn/cache/css.escape-npm-1.5.1-b24d2ba77a-f6d38088d8.zip/node_modules/css.escape/",\ + "packageDependencies": [\ + ["css.escape", "npm:1.5.1"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["cssesc", [\ ["npm:3.0.0", {\ "packageLocation": "./.yarn/cache/cssesc-npm-3.0.0-15ec56f86f-0e161912c1.zip/node_modules/cssesc/",\ @@ -13665,6 +13675,21 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["happy-dom", [\ + ["npm:12.10.3", {\ + "packageLocation": "./.yarn/cache/happy-dom-npm-12.10.3-5cca1a5e23-de82ddd1c9.zip/node_modules/happy-dom/",\ + "packageDependencies": [\ + ["happy-dom", "npm:12.10.3"],\ + ["css.escape", "npm:1.5.1"],\ + ["entities", "npm:4.5.0"],\ + ["iconv-lite", "npm:0.6.3"],\ + ["webidl-conversions", "npm:7.0.0"],\ + ["whatwg-encoding", "npm:2.0.0"],\ + ["whatwg-mimetype", "npm:3.0.0"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["hard-rejection", [\ ["npm:2.1.0", {\ "packageLocation": "./.yarn/cache/hard-rejection-npm-2.1.0-a80f2a977d-7baaf80a0c.zip/node_modules/hard-rejection/",\ diff --git a/.yarn/cache/css.escape-npm-1.5.1-b24d2ba77a-f6d38088d8.zip b/.yarn/cache/css.escape-npm-1.5.1-b24d2ba77a-f6d38088d8.zip new file mode 100644 index 000000000..88d9cf7f4 --- /dev/null +++ b/.yarn/cache/css.escape-npm-1.5.1-b24d2ba77a-f6d38088d8.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:160c2a70b6e934480625dd02e85e70feefcb8c21f14708bc8c5c623ad55f1d78 +size 3793 diff --git a/.yarn/cache/happy-dom-npm-12.10.3-5cca1a5e23-de82ddd1c9.zip b/.yarn/cache/happy-dom-npm-12.10.3-5cca1a5e23-de82ddd1c9.zip new file mode 100644 index 000000000..128e27f59 --- /dev/null +++ b/.yarn/cache/happy-dom-npm-12.10.3-5cca1a5e23-de82ddd1c9.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f49c990d09a342bb9602b1c7b5908367bc92dbd4c94e1b82a6e4d12436572079 +size 2333184 diff --git a/packages/backend/package.json b/packages/backend/package.json index 4e7b7fecf..193b72b3a 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -66,6 +66,7 @@ "fluent-ffmpeg": "2.1.2", "got": "12.5.3", "gunzip-maybe": "^1.4.2", + "happy-dom": "^12.10.3", "hpagent": "0.1.2", "iceshrimp-js": "workspace:*", "ioredis": "5.3.2", diff --git a/packages/backend/src/server/api/mastodon/helpers/mfm.ts b/packages/backend/src/server/api/mastodon/helpers/mfm.ts index c1f69e3af..910ff5fe0 100644 --- a/packages/backend/src/server/api/mastodon/helpers/mfm.ts +++ b/packages/backend/src/server/api/mastodon/helpers/mfm.ts @@ -1,5 +1,5 @@ import { IMentionedRemoteUsers } from "@/models/entities/note.js"; -import { JSDOM } from "jsdom"; +import { Window as HappyDom } from "happy-dom"; import config from "@/config/index.js"; import { intersperse } from "@/prelude/array.js"; import mfm from "mfm-js"; @@ -17,7 +17,7 @@ export class MfmHelpers { return null; } - const { window } = new JSDOM(""); + const { window } = new HappyDom(); const doc = window.document; @@ -101,7 +101,7 @@ export class MfmHelpers { hashtag(node) { const a = doc.createElement("a"); - a.href = `${config.url}/tags/${node.props.hashtag}`; + a.setAttribute('href', `${config.url}/tags/${node.props.hashtag}`); a.textContent = `#${node.props.hashtag}`; a.setAttribute("rel", "tag"); a.setAttribute("class", "hashtag"); @@ -130,7 +130,7 @@ export class MfmHelpers { const a = doc.createElement("a"); a.setAttribute("rel", "nofollow noopener noreferrer"); a.setAttribute("target", "_blank"); - a.href = node.props.url; + a.setAttribute('href',node.props.url); await appendChildren(node.children, a); return a; }, @@ -146,7 +146,7 @@ export class MfmHelpers { el.setAttribute("class", "h-card"); el.setAttribute("translate", "no"); const a = doc.createElement("a"); - a.href = resolved.href; + a.setAttribute('href',resolved.href); a.className = "u-url mention"; const span = doc.createElement("span"); span.textContent = resolved.username; @@ -181,14 +181,14 @@ export class MfmHelpers { const a = doc.createElement("a"); a.setAttribute("rel", "nofollow noopener noreferrer"); a.setAttribute("target", "_blank"); - a.href = node.props.url; + a.setAttribute('href', node.props.url); a.textContent = node.props.url.replace(/^https?:\/\//, ''); return a; }, search(node) { const a = doc.createElement("a"); - a.href = `${config.searchEngine}${node.props.query}`; + a.setAttribute('href', `${config.searchEngine}${node.props.query}`); a.textContent = node.props.content; return a; }, @@ -204,7 +204,7 @@ export class MfmHelpers { if (quoteUri !== null) { const a = doc.createElement("a"); - a.href = quoteUri; + a.setAttribute('href', quoteUri); a.textContent = quoteUri.replace(/^https?:\/\//, ''); const quote = doc.createElement("span"); diff --git a/yarn.lock b/yarn.lock index 0afc21a77..ce9df6b49 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5541,6 +5541,7 @@ __metadata: fluent-ffmpeg: "npm:2.1.2" got: "npm:12.5.3" gunzip-maybe: "npm:^1.4.2" + happy-dom: "npm:^12.10.3" hpagent: "npm:0.1.2" iceshrimp-js: "workspace:*" ioredis: "npm:5.3.2" @@ -7430,6 +7431,13 @@ __metadata: languageName: node linkType: hard +"css.escape@npm:^1.5.1": + version: 1.5.1 + resolution: "css.escape@npm:1.5.1" + checksum: f6d38088d870a961794a2580b2b2af1027731bb43261cfdce14f19238a88664b351cc8978abc20f06cc6bbde725699dec8deb6fe9816b139fc3f2af28719e774 + languageName: node + linkType: hard + "css@npm:^3.0.0": version: 3.0.0 resolution: "css@npm:3.0.0" @@ -8451,7 +8459,7 @@ __metadata: languageName: node linkType: hard -"entities@npm:^4.2.0, entities@npm:^4.4.0": +"entities@npm:^4.2.0, entities@npm:^4.4.0, entities@npm:^4.5.0": version: 4.5.0 resolution: "entities@npm:4.5.0" checksum: ede2a35c9bce1aeccd055a1b445d41c75a14a2bb1cd22e242f20cf04d236cdcd7f9c859eb83f76885327bfae0c25bf03303665ee1ce3d47c5927b98b0e3e3d48 @@ -10968,6 +10976,20 @@ __metadata: languageName: node linkType: hard +"happy-dom@npm:^12.10.3": + version: 12.10.3 + resolution: "happy-dom@npm:12.10.3" + dependencies: + css.escape: "npm:^1.5.1" + entities: "npm:^4.5.0" + iconv-lite: "npm:^0.6.3" + webidl-conversions: "npm:^7.0.0" + whatwg-encoding: "npm:^2.0.0" + whatwg-mimetype: "npm:^3.0.0" + checksum: de82ddd1c981f24a95011c62c2d03e12c4c48f86c0234fa7a1a309d8fa1481885956c783fb3cc56371fa49193d2323822a583196156b10db179e7ac754ef7864 + languageName: node + linkType: hard + "hard-rejection@npm:^2.1.0": version: 2.1.0 resolution: "hard-rejection@npm:2.1.0" @@ -11490,7 +11512,7 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2": +"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": version: 0.6.3 resolution: "iconv-lite@npm:0.6.3" dependencies: