From 6f7bdf274fae3c74d2859c68296bd1294067313e Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Mon, 9 Jan 2023 22:08:42 +0000 Subject: [PATCH] refactor: use `tiny-decode` for parsing html entities (#922) --- composables/content-parse.ts | 12 ++---------- composables/content-render.ts | 5 +++-- package.json | 1 + pnpm-lock.yaml | 14 ++++++++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/composables/content-parse.ts b/composables/content-parse.ts index 0692adfc..6b00f3db 100644 --- a/composables/content-parse.ts +++ b/composables/content-parse.ts @@ -3,6 +3,7 @@ import type { mastodon } from 'masto' import type { Node } from 'ultrahtml' import { DOCUMENT_NODE, ELEMENT_NODE, TEXT_NODE, h, parse, render } from 'ultrahtml' import { findAndReplaceEmojisInText } from '@iconify/utils' +import { decode } from 'tiny-decode' import { emojiRegEx, getEmojiAttributes } from '../config/emojis' export interface ContentParseOptions { @@ -34,15 +35,6 @@ const sanitizer = sanitize({ }, }) -const decoder = process.client ? document.createElement('textarea') : null -export function decodeHtml(text: string) { - if (!decoder) - // not available when SSR - return text - decoder.innerHTML = text - return decoder.value -} - /** * Parse raw HTML form Mastodon server to AST, * with interop of custom emojis and inline Markdown syntax @@ -113,7 +105,7 @@ export function treeToText(input: Node): string { let post = '' if (input.type === TEXT_NODE) - return decodeHtml(input.value) + return decode(input.value) if (input.name === 'br') return '\n' diff --git a/composables/content-render.ts b/composables/content-render.ts index 31cd980a..e082cacd 100644 --- a/composables/content-render.ts +++ b/composables/content-render.ts @@ -3,8 +3,9 @@ import type { Node } from 'ultrahtml' import { Fragment, h, isVNode } from 'vue' import type { VNode } from 'vue' import { RouterLink } from 'vue-router' +import { decode } from 'tiny-decode' import type { ContentParseOptions } from './content-parse' -import { decodeHtml, parseMastodonHTML } from './content-parse' +import { parseMastodonHTML } from './content-parse' import ContentCode from '~/components/content/ContentCode.vue' import AccountHoverWrapper from '~/components/account/AccountHoverWrapper.vue' @@ -47,7 +48,7 @@ function treeToVNode( input: Node, ): VNode | string | null { if (input.type === TEXT_NODE) - return decodeHtml(input.value) + return decode(input.value) if ('children' in input) { const node = handleNode(input) diff --git a/package.json b/package.json index 7e29146e..60db2eb2 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "slimeform": "^0.8.0", "tauri-plugin-log-api": "github:tauri-apps/tauri-plugin-log", "tauri-plugin-store-api": "github:tauri-apps/tauri-plugin-store", + "tiny-decode": "^0.1.3", "tippy.js": "^6.3.7", "ufo": "^1.0.1", "ultrahtml": "^1.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0703c811..273c23fc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -84,6 +84,7 @@ importers: tauri-plugin-log-api: github:tauri-apps/tauri-plugin-log tauri-plugin-store-api: github:tauri-apps/tauri-plugin-store theme-vitesse: ^0.6.0 + tiny-decode: ^0.1.3 tippy.js: ^6.3.7 typescript: ^4.9.4 ufo: ^1.0.1 @@ -130,6 +131,7 @@ importers: slimeform: 0.8.0 tauri-plugin-log-api: github.com/tauri-apps/tauri-plugin-log/954a857daa45598ffc5e8637fccdba300f9ef757 tauri-plugin-store-api: github.com/tauri-apps/tauri-plugin-store/89100ece4ebe010091e90d1873eaeafbbf5eb60a + tiny-decode: 0.1.3 tippy.js: 6.3.7 ufo: 1.0.1 ultrahtml: 1.2.0 @@ -178,7 +180,7 @@ importers: typescript: 4.9.4 unplugin-auto-import: 0.12.1_@vueuse+core@9.10.0 vite-plugin-inspect: 0.7.11 - vite-plugin-pwa: 0.14.1_workbox-window@6.5.4 + vite-plugin-pwa: 0.14.1 vitest: 0.26.2_jsdom@20.0.3 vue-tsc: 1.0.24_typescript@4.9.4 workbox-window: 6.5.4 @@ -5482,7 +5484,6 @@ packages: /entities/4.4.0: resolution: {integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==} engines: {node: '>=0.12'} - dev: true /errno/0.1.8: resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} @@ -10982,6 +10983,12 @@ packages: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} dev: true + /tiny-decode/0.1.3: + resolution: {integrity: sha512-1z+tXaZpPUyREOfjKDQj5lR6HfD6Pa4NF7pb/9ep7sP4+X5WF76bGdJktWCY1Rm+aMR46vJ75VAL/oAptpD1AA==} + dependencies: + entities: 4.4.0 + dev: false + /tiny-invariant/1.3.1: resolution: {integrity: sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==} dev: true @@ -11815,11 +11822,10 @@ packages: - supports-color dev: true - /vite-plugin-pwa/0.14.1_workbox-window@6.5.4: + /vite-plugin-pwa/0.14.1: resolution: {integrity: sha512-5zx7yhQ8RTLwV71+GA9YsQQ63ALKG8XXIMqRJDdZkR8ZYftFcRgnzM7wOWmQZ/DATspyhPih5wCdcZnAIsM+mA==} peerDependencies: vite: ^3.1.0 || ^4.0.0 - workbox-window: ^6.5.4 dependencies: '@rollup/plugin-replace': 5.0.1_rollup@3.9.1 debug: 4.3.4