Skip to content

Commit

Permalink
fix: don't decode HTML entities (&foo;) until rendering (#465)
Browse files Browse the repository at this point in the history
  • Loading branch information
robertvanhoesel authored Dec 20, 2022
1 parent 9a7c37d commit f8ebc0e
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 5 deletions.
5 changes: 2 additions & 3 deletions composables/content-parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { Node } from 'ultrahtml'
import { TEXT_NODE, parse, render, walkSync } from 'ultrahtml'

const decoder = process.client ? document.createElement('textarea') : null as any as HTMLTextAreaElement
function decode(text: string) {
export function decodeHtml(text: string) {
decoder.innerHTML = text
return decoder.value
}
Expand Down Expand Up @@ -40,7 +40,6 @@ export function parseMastodonHTML(html: string, customEmojis: Record<string, Emo
[/\*(.*?)\*/g, '<em>$1</em>'],
[/~~(.*?)~~/g, '<del>$1</del>'],
[/`([^`]+?)`/g, '<code>$1</code>'],
[/&[^;]+;/g, (val: string) => decode(val)],
] as any

for (const [re, replacement] of replacements) {
Expand Down Expand Up @@ -77,7 +76,7 @@ export function treeToText(input: Node): string {
let post = ''

if (input.type === TEXT_NODE)
return input.value
return decodeHtml(input.value)

if (input.name === 'br')
return '\n'
Expand Down
5 changes: 3 additions & 2 deletions composables/content-render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { Node } from 'ultrahtml'
import { Fragment, h, isVNode } from 'vue'
import type { VNode } from 'vue'
import { RouterLink } from 'vue-router'
import { parseMastodonHTML } from './content-parse'
import { decodeHtml, parseMastodonHTML } from './content-parse'
import ContentCode from '~/components/content/ContentCode.vue'
import AccountHoverWrapper from '~/components/account/AccountHoverWrapper.vue'

Expand Down Expand Up @@ -45,11 +45,12 @@ export function nodeToVNode(node: Node): VNode | string | null {
}
return null
}

function treeToVNode(
input: Node,
): VNode | string | null {
if (input.type === TEXT_NODE)
return input.value as string
return decodeHtml(input.value)

if ('children' in input) {
const node = handleNode(input)
Expand Down
7 changes: 7 additions & 0 deletions tests/__snapshots__/html-parse.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ exports[`html-parse > empty > html 1`] = `""`;
exports[`html-parse > empty > text 1`] = `""`;
exports[`html-parse > html entities > html 1`] = `
"<p>Hello &lt;World /&gt;.</p>
"
`;
exports[`html-parse > html entities > text 1`] = `"Hello <World />."`;
exports[`html-parse > inline markdown > html 1`] = `"<p>text <code>code</code> <b>bold</b> <em>italic</em> <del>del</del></p><p><pre><code class=\\"language-js\\">code block</code></pre></p>"`;
exports[`html-parse > inline markdown > text 1`] = `
Expand Down
6 changes: 6 additions & 0 deletions tests/html-parse.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ describe('html-parse', () => {
expect(formatted).toMatchSnapshot('html')
expect(serializedText).toMatchSnapshot('text')
})

it('html entities', async () => {
const { formatted, serializedText } = await render('<p>Hello &lt;World /&gt;.</p>')
expect(formatted).toMatchSnapshot('html')
expect(serializedText).toMatchSnapshot('text')
})
})

async function render(input: string, emojis?: Record<string, Emoji>) {
Expand Down

0 comments on commit f8ebc0e

Please sign in to comment.