diff --git a/package.json b/package.json index 9b1a6b64be..4890098567 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ } }, "dependencies": { - "@aeharding/remark-lemmy-spoiler": "^1.0.1", + "@aeharding/remark-lemmy-spoiler": "^2.0.0", "@capacitor-community/app-icon": "^5.0.0", "@capacitor/android": "^6.1.0", "@capacitor/app": "^6.0.0", @@ -73,7 +73,6 @@ "mdast-util-gfm-autolink-literal-lemmy": "^3.0.0", "mdast-util-gfm-strikethrough": "^2.0.0", "mdast-util-gfm-table": "^2.0.0", - "mdast-util-lemmy-spoiler": "^1.0.0", "micromark": "^4.0.0", "micromark-extension-gfm-strikethrough": "^2.1.0", "micromark-extension-gfm-table": "^2.1.0", @@ -146,6 +145,7 @@ "eslint-plugin-react-hooks": "^4.6.2", "globals": "^15.8.0", "jsdom": "^24.1.0", + "mdast-util-lemmy-spoiler": "^2.0.0", "prettier": "^3.3.2", "pwa-asset-generator": "^6.3.1", "release-it": "^17.4.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c803e01c33..4032a4f783 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,8 +20,8 @@ importers: .: dependencies: '@aeharding/remark-lemmy-spoiler': - specifier: ^1.0.1 - version: 1.0.1 + specifier: ^2.0.0 + version: 2.0.0 '@capacitor-community/app-icon': specifier: ^5.0.0 version: 5.0.0(@capacitor/core@6.1.0) @@ -145,9 +145,6 @@ importers: mdast-util-gfm-table: specifier: ^2.0.0 version: 2.0.0 - mdast-util-lemmy-spoiler: - specifier: ^1.0.0 - version: 1.0.0 micromark: specifier: ^4.0.0 version: 4.0.0 @@ -359,6 +356,9 @@ importers: jsdom: specifier: ^24.1.0 version: 24.1.0 + mdast-util-lemmy-spoiler: + specifier: ^2.0.0 + version: 2.0.0 prettier: specifier: ^3.3.2 version: 3.3.2 @@ -392,8 +392,8 @@ packages: '@adobe/css-tools@4.4.0': resolution: {integrity: sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==} - '@aeharding/remark-lemmy-spoiler@1.0.1': - resolution: {integrity: sha512-NAykFv7DQYRh7J9xE/fyYSuTaTP5armX3Mla7vfIL+2QMU0DtRaiXpz9pybZxkjeweeB22fss87/NSOqTmB8Aw==} + '@aeharding/remark-lemmy-spoiler@2.0.0': + resolution: {integrity: sha512-Kw2LDXIeNyV2Ks1QXKYISEdwn4ufPev5gb4RzoSNSEUb1iL6aQmOUQvcuA7ePzXChNe6bmerkvJ2KKYXYaLYlQ==} '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} @@ -4571,6 +4571,9 @@ packages: marky@1.2.5: resolution: {integrity: sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==} + mdast-squeeze-paragraphs@6.0.0: + resolution: {integrity: sha512-6NDbJPTg0M0Ye+TlYwX1KJ1LFbp515P2immRJyJQhc9Na9cetHzSoHNYIQcXpANEAP1sm9yd/CTZU2uHqR5A+w==} + mdast-util-find-and-replace@3.0.1: resolution: {integrity: sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==} @@ -4598,8 +4601,8 @@ packages: mdast-util-gfm@3.0.0: resolution: {integrity: sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==} - mdast-util-lemmy-spoiler@1.0.0: - resolution: {integrity: sha512-M6WuaisvDWNkQVfD9LkIpCPDaDKgK6WF/jtalFTZzTQ49cZDq74EniY8RyNUHj9SsIw4kPLTpV2e5e788GId0w==} + mdast-util-lemmy-spoiler@2.0.0: + resolution: {integrity: sha512-5A0fDymXzJ0IbNDOK7+ZcjDX+nVGwpr+ginRcXduGe4CiZ7yw8WJQQhDPlUCSBScSF0Abr90hEKjhnSdOHVP+A==} mdast-util-mdx-expression@2.0.0: resolution: {integrity: sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==} @@ -4672,8 +4675,8 @@ packages: micromark-extension-gfm@3.0.0: resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} - micromark-extension-lemmy-spoiler@1.0.0: - resolution: {integrity: sha512-yVEkqRAK3HAOOzU8Bud0M897Uims5AhA8VuCnCWMKWkdo9NAddrc1txzaciyYSikNg16xDO9x20+7IlLV7Vkgg==} + micromark-extension-lemmy-spoiler@2.0.0: + resolution: {integrity: sha512-EmIUtnlX9Q8EeMWCu0JYujCDDg/7GxgEc/OeJjD6bytSdu5zuonb1PunINgObzJYSrybzAe82hmZugeAdG2Tmw==} micromark-factory-destination@2.0.0: resolution: {integrity: sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==} @@ -5597,6 +5600,9 @@ packages: remark-supersub-lemmy@1.0.0: resolution: {integrity: sha512-8w3yuFfxtI55YnnZIPcrY/QrgCDSWrgY5vxX1XL3lPEwGxNE5DvtTXXgzuino6qTaClnj0PvYSz0bHa+2/D/Xw==} + remark-unlink@5.0.0: + resolution: {integrity: sha512-8NFrI3SecxhOLb734tKaxcU//lNDABabz1I26MGjdlpkUg1I+Fr7lyqL9ckxaCB4kErXD10mScPD7yhCXX4Pfw==} + replace@1.2.2: resolution: {integrity: sha512-C4EDifm22XZM2b2JOYe6Mhn+lBsLBAvLbK8drfUQLTfD1KYl/n3VaW/CDju0Ny4w3xTtegBpg8YNSpFJPUDSjA==} engines: {node: '>= 6'} @@ -6893,11 +6899,12 @@ snapshots: '@adobe/css-tools@4.4.0': {} - '@aeharding/remark-lemmy-spoiler@1.0.1': + '@aeharding/remark-lemmy-spoiler@2.0.0': dependencies: '@types/mdast': 4.0.4 - mdast-util-lemmy-spoiler: 1.0.0 - micromark-extension-lemmy-spoiler: 1.0.0 + mdast-util-lemmy-spoiler: 2.0.0 + micromark-extension-lemmy-spoiler: 2.0.0 + remark-unlink: 5.0.0 unified: 11.0.5 transitivePeerDependencies: - supports-color @@ -12020,6 +12027,11 @@ snapshots: marky@1.2.5: {} + mdast-squeeze-paragraphs@6.0.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-visit: 5.0.0 + mdast-util-find-and-replace@3.0.1: dependencies: '@types/mdast': 4.0.4 @@ -12109,7 +12121,7 @@ snapshots: transitivePeerDependencies: - supports-color - mdast-util-lemmy-spoiler@1.0.0: + mdast-util-lemmy-spoiler@2.0.0: dependencies: '@types/mdast': 4.0.4 '@types/unist': 3.0.2 @@ -12313,7 +12325,7 @@ snapshots: micromark-util-combine-extensions: 2.0.0 micromark-util-types: 2.0.0 - micromark-extension-lemmy-spoiler@1.0.0: + micromark-extension-lemmy-spoiler@2.0.0: dependencies: devlop: 1.1.0 micromark-factory-space: 2.0.0 @@ -13453,6 +13465,12 @@ snapshots: dependencies: unist-util-visit: 5.0.0 + remark-unlink@5.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-squeeze-paragraphs: 6.0.0 + unist-util-visit: 5.0.0 + replace@1.2.2: dependencies: chalk: 2.4.2 diff --git a/src/features/comment/CommentLinks.tsx b/src/features/comment/CommentLinks.tsx index 34b44fde27..c914e101da 100644 --- a/src/features/comment/CommentLinks.tsx +++ b/src/features/comment/CommentLinks.tsx @@ -48,9 +48,9 @@ export default function CommentLinks({ markdown }: CommentLinksProps) { let links: LinkData[] = []; - visit(mdastTree, ["spoiler", "link", "image"], (node) => { + visit(mdastTree, ["details", "link", "image"], (node) => { // don't show links within spoilers - if (node.type === "spoiler") return SKIP; + if (node.type === "details") return SKIP; if (node.type === "link" || (!showCommentImages && node.type === "image")) links.push({ diff --git a/src/features/shared/markdown/InlineMarkdown.tsx b/src/features/shared/markdown/InlineMarkdown.tsx index eed9601300..0d1ca7596d 100644 --- a/src/features/shared/markdown/InlineMarkdown.tsx +++ b/src/features/shared/markdown/InlineMarkdown.tsx @@ -2,7 +2,7 @@ import { useMemo } from "react"; import ReactMarkdown from "react-markdown"; import spoiler from "@aeharding/remark-lemmy-spoiler"; import superSub from "remark-supersub-lemmy"; -import { spoilerSummaryOnlyRehype } from "./spoilerRehype"; +import inlinifySpoiler from "./components/spoiler/inlinifySpoiler"; interface InlineMarkdownProps { children: string; @@ -49,7 +49,7 @@ export default function InlineMarkdown({ children }: InlineMarkdownProps) { sub: "sub", sup: "sup", }} - remarkPlugins={[superSub, spoiler, spoilerSummaryOnlyRehype]} + remarkPlugins={[superSub, spoiler, inlinifySpoiler]} > {children} diff --git a/src/features/shared/markdown/Markdown.tsx b/src/features/shared/markdown/Markdown.tsx index c3f0a94961..9e86c9edbf 100644 --- a/src/features/shared/markdown/Markdown.tsx +++ b/src/features/shared/markdown/Markdown.tsx @@ -10,7 +10,6 @@ import Table from "./components/Table"; import spoiler from "@aeharding/remark-lemmy-spoiler"; import Summary from "./components/spoiler/Summary"; import Details from "./components/spoiler/Details"; -import spoilerRehype from "./spoilerRehype"; import { useMemo } from "react"; import rehypeHighlight from "rehype-highlight"; @@ -128,12 +127,7 @@ export default function Markdown({ [disableInternalLinkRouting, id, props.components], )} remarkPlugins={useMemo( - () => [ - [customRemarkGfm, { connectedInstance }], - superSub, - spoiler, - spoilerRehype, - ], + () => [[customRemarkGfm, { connectedInstance }], superSub, spoiler], [connectedInstance], )} rehypePlugins={rehypePlugins} diff --git a/src/features/shared/markdown/components/spoiler/Details.tsx b/src/features/shared/markdown/components/spoiler/Details.tsx index d7a7d6bbee..abef9b95c0 100644 --- a/src/features/shared/markdown/components/spoiler/Details.tsx +++ b/src/features/shared/markdown/components/spoiler/Details.tsx @@ -28,6 +28,11 @@ const HeaderItem = styled(IonItem)` --background: none; --background-hover: none; + + strong { + // Differentiate from already bold title in header + font-weight: 900; + } `; const StyledIonAccordion = styled(IonAccordion)` @@ -91,7 +96,7 @@ export default function Details({ children, node, id }: DetailsProps) { e.stopPropagation()}> - {label} +
{label}
{children} diff --git a/src/features/shared/markdown/components/spoiler/inlinifySpoiler.ts b/src/features/shared/markdown/components/spoiler/inlinifySpoiler.ts new file mode 100644 index 0000000000..e79df424b1 --- /dev/null +++ b/src/features/shared/markdown/components/spoiler/inlinifySpoiler.ts @@ -0,0 +1,19 @@ +/// + +import { visit } from "unist-util-visit"; +import { Root } from "mdast"; + +/** + * Transform spoiler tree node to details/summary rehype html nodes + */ +export default function inlinifySpoiler() { + return function (tree: Root) { + visit(tree, "summary", function (node, _, parent) { + if (!parent) return; + if (parent.type !== "details") return; + + parent.data = { hName: "p" }; + parent.children = node.children; + }); + }; +} diff --git a/src/features/shared/markdown/spoilerRehype.ts b/src/features/shared/markdown/spoilerRehype.ts deleted file mode 100644 index da4b57949e..0000000000 --- a/src/features/shared/markdown/spoilerRehype.ts +++ /dev/null @@ -1,62 +0,0 @@ -/// - -import { visit } from "unist-util-visit"; -import { Parent, Root } from "mdast"; - -/** - * Transform spoiler tree node to details/summary rehype html nodes - * - * TODO this may not be necessary if the logic can be moved to mdast-util-lemmy-spoiler - * https://github.com/orgs/micromark/discussions/163 - */ -export default function spoilerRehype() { - return function (tree: Root) { - visit(tree, function (node) { - if (node.type === "spoiler") { - const data = node.data || (node.data = {}); - data.hName = "details"; - - node.children = [ - { - type: "paragraph", - data: { - hName: "summary", - }, - children: [ - { - type: "text", - value: node.name, - }, - ], - }, - ...node.children, - ]; - } - }); - }; -} - -/** - * Transform spoiler tree node to details/summary rehype html nodes (SUMMARY ONLY) - * - * TODO this may not be necessary if the logic can be moved to mdast-util-lemmy-spoiler - * https://github.com/orgs/micromark/discussions/163 - */ -export function spoilerSummaryOnlyRehype() { - return function (tree: Root) { - visit(tree, function (node) { - if (node.type === "spoiler") { - // Transform the spoiler summary text to a paragraph node (for inline markdown component) - const nodeAsParagraph = node as Parent; - nodeAsParagraph.type = "paragraph"; - - nodeAsParagraph.children = [ - { - type: "text", - value: node.name, - }, - ]; - } - }); - }; -} diff --git a/vite.config.ts b/vite.config.ts index 5cc9375f58..55f9ab02d3 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -77,6 +77,6 @@ export default defineConfig({ setupFiles: "./src/setupTests.ts", }, optimizeDeps: { - exclude: ["mdast-util-gfm-autolink-literal-lemmy"], + exclude: ["mdast-util-gfm-autolink-literal-lemmy", "remark-lemmy-spoiler"], }, });