Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
This commit is contained in:
parent
41c5f94fbf
commit
fa9c418e21
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -10,6 +10,7 @@ dist
|
|||
.netlify/
|
||||
|
||||
public/shiki
|
||||
public/emojis
|
||||
|
||||
*~
|
||||
*swp
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
import type { Emoji } from 'masto'
|
||||
import type { Node } from 'ultrahtml'
|
||||
import { TEXT_NODE, parse, render, walkSync } from 'ultrahtml'
|
||||
import createEmojiRegex from 'emoji-regex'
|
||||
|
||||
export const EMOJI_REGEX = createEmojiRegex()
|
||||
import { findAndReplaceEmojisInText } from '@iconify/utils'
|
||||
import { emojiRegEx, getEmojiAttributes } from '../config/emojis'
|
||||
|
||||
const decoder = process.client ? document.createElement('textarea') : null as any as HTMLTextAreaElement
|
||||
export function decodeHtml(text: string) {
|
||||
|
@ -16,17 +15,17 @@ export function decodeHtml(text: string) {
|
|||
* Parse raw HTML form Mastodon server to AST,
|
||||
* with interop of custom emojis and inline Markdown syntax
|
||||
*/
|
||||
export function parseMastodonHTML(html: string, customEmojis: Record<string, Emoji> = {}, markdown = true) {
|
||||
let processed = html
|
||||
// custom emojis
|
||||
.replace(/:([\w-]+?):/g, (_, name) => {
|
||||
const emoji = customEmojis[name]
|
||||
export function parseMastodonHTML(html: string, customEmojis: Record<string, Emoji> = {}, markdown = true, forTiptap = false) {
|
||||
// unicode emojis to images, but only if not converting HTML for Tiptap
|
||||
let processed = forTiptap ? html : replaceUnicodeEmoji(html)
|
||||
|
||||
return emoji
|
||||
? `<img src="${emoji.url}" alt=":${name}:" class="custom-emoji" data-emoji-id="${name}" />`
|
||||
: `:${name}:`
|
||||
// custom emojis
|
||||
processed = processed.replace(/:([\w-]+?):/g, (_, name) => {
|
||||
const emoji = customEmojis[name]
|
||||
if (emoji)
|
||||
return `<img src="${emoji.url}" alt=":${name}:" class="custom-emoji" data-emoji-id="${name}" />`
|
||||
return `:${name}:`
|
||||
})
|
||||
.replace(EMOJI_REGEX, '<em-emoji native="$&" fallback="$&" />')
|
||||
|
||||
if (markdown) {
|
||||
// handle code blocks
|
||||
|
@ -66,8 +65,11 @@ export function parseMastodonHTML(html: string, customEmojis: Record<string, Emo
|
|||
return parse(processed)
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts raw HTML form Mastodon server to HTML for Tiptap editor
|
||||
*/
|
||||
export function convertMastodonHTML(html: string, customEmojis: Record<string, Emoji> = {}) {
|
||||
const tree = parseMastodonHTML(html, customEmojis)
|
||||
const tree = parseMastodonHTML(html, customEmojis, true, true)
|
||||
return render(tree)
|
||||
}
|
||||
|
||||
|
@ -118,12 +120,22 @@ export function treeToText(input: Node): string {
|
|||
if ('children' in input)
|
||||
body = (input.children as Node[]).map(n => treeToText(n)).join('')
|
||||
|
||||
// add spaces around emoji to prevent parsing errors: 2 or more consecutive emojis will not be parsed
|
||||
if (input.name === 'img' && input.attributes.class?.includes('custom-emoji'))
|
||||
if (input.name === 'img') {
|
||||
if (input.attributes.class?.includes('custom-emoji'))
|
||||
return `:${input.attributes['data-emoji-id']}:`
|
||||
|
||||
if (input.name === 'em-emoji')
|
||||
return `${input.attributes.native}`
|
||||
if (input.attributes.class?.includes('iconify-emoji'))
|
||||
return input.attributes.alt
|
||||
}
|
||||
|
||||
return pre + body + post
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace unicode emojis with locally hosted images
|
||||
*/
|
||||
export function replaceUnicodeEmoji(html: string) {
|
||||
return findAndReplaceEmojisInText(emojiRegEx, html, (match) => {
|
||||
const attrs = getEmojiAttributes(match)
|
||||
return `<img src="${attrs.src}" alt="${attrs.alt}" class="${attrs.class}" />`
|
||||
}) || html
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import {
|
|||
mergeAttributes,
|
||||
nodeInputRule,
|
||||
} from '@tiptap/core'
|
||||
import { emojiRegEx, getEmojiAttributes } from '~/config/emojis'
|
||||
|
||||
export const Emoji = Node.create({
|
||||
name: 'em-emoji',
|
||||
|
@ -14,35 +15,35 @@ export const Emoji = Node.create({
|
|||
parseHTML() {
|
||||
return [
|
||||
{
|
||||
tag: 'em-emoji[native]',
|
||||
tag: 'img.iconify-emoji',
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
addAttributes() {
|
||||
return {
|
||||
native: {
|
||||
alt: {
|
||||
default: null,
|
||||
},
|
||||
fallback: {
|
||||
src: {
|
||||
default: null,
|
||||
},
|
||||
class: {
|
||||
default: null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
renderHTML(args) {
|
||||
return ['em-emoji', mergeAttributes(this.options.HTMLAttributes, args.HTMLAttributes)]
|
||||
return ['img', mergeAttributes(this.options.HTMLAttributes, args.HTMLAttributes)]
|
||||
},
|
||||
|
||||
addCommands() {
|
||||
return {
|
||||
insertEmoji: name => ({ commands }) => {
|
||||
insertEmoji: code => ({ commands }) => {
|
||||
return commands.insertContent({
|
||||
type: this.name,
|
||||
attrs: {
|
||||
native: name,
|
||||
fallback: name,
|
||||
},
|
||||
attrs: getEmojiAttributes(code),
|
||||
})
|
||||
},
|
||||
}
|
||||
|
@ -50,14 +51,11 @@ export const Emoji = Node.create({
|
|||
|
||||
addInputRules() {
|
||||
const inputRule = nodeInputRule({
|
||||
find: EMOJI_REGEX,
|
||||
find: emojiRegEx as RegExp,
|
||||
type: this.type,
|
||||
getAttributes: (match) => {
|
||||
const [native] = match
|
||||
return {
|
||||
native,
|
||||
fallback: native,
|
||||
}
|
||||
return getEmojiAttributes(native)
|
||||
},
|
||||
})
|
||||
// Error catch for unsupported emoji
|
||||
|
|
22
config/emojis.ts
Normal file
22
config/emojis.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
import { emojiFilename, emojiPrefix, emojiRegEx } from '@iconify-emoji/twemoji'
|
||||
import type { EmojiRegexMatch } from '@iconify/utils/lib/emoji/replace/find'
|
||||
import { getEmojiMatchesInText } from '@iconify/utils/lib/emoji/replace/find'
|
||||
|
||||
// Re-export everything from package
|
||||
export * from '@iconify-emoji/twemoji'
|
||||
|
||||
// Package name
|
||||
export const iconifyEmojiPackage = '@iconify-emoji/twemoji'
|
||||
|
||||
export function getEmojiAttributes(input: EmojiRegexMatch | string) {
|
||||
const match = typeof input === 'string'
|
||||
? getEmojiMatchesInText(emojiRegEx, input)?.[0]
|
||||
: input
|
||||
const file = emojiFilename(match)
|
||||
const className = `iconify-emoji iconify-emoji--${emojiPrefix}${file.padding ? ' iconify-emoji-padded' : ''}`
|
||||
return {
|
||||
class: className,
|
||||
src: `/emojis/${emojiPrefix}/${file.filename}`,
|
||||
alt: match.match,
|
||||
}
|
||||
}
|
|
@ -26,6 +26,8 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@fnando/sparkline": "^0.3.10",
|
||||
"@iconify-emoji/twemoji": "^1.0.2",
|
||||
"@iconify/utils": "^2.0.7",
|
||||
"@nuxtjs/color-mode": "^3.2.0",
|
||||
"@tiptap/extension-character-count": "2.0.0-beta.204",
|
||||
"@tiptap/extension-code-block": "2.0.0-beta.204",
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
export default defineNuxtPlugin(() => {
|
||||
if (process.server)
|
||||
return
|
||||
|
||||
const promise = import('@emoji-mart/data').then(r => r.default)
|
||||
import('emoji-mart').then(r => r.init({
|
||||
data: () => promise,
|
||||
}))
|
||||
})
|
|
@ -5,12 +5,14 @@ specifiers:
|
|||
'@antfu/ni': ^0.18.8
|
||||
'@emoji-mart/data': ^1.1.0
|
||||
'@fnando/sparkline': ^0.3.10
|
||||
'@iconify-emoji/twemoji': ^1.0.2
|
||||
'@iconify-json/carbon': ^1.1.11
|
||||
'@iconify-json/logos': ^1.1.19
|
||||
'@iconify-json/material-symbols': ^1.1.26
|
||||
'@iconify-json/ph': ^1.1.3
|
||||
'@iconify-json/ri': ^1.1.4
|
||||
'@iconify-json/twemoji': ^1.1.7
|
||||
'@iconify/utils': ^2.0.7
|
||||
'@nuxtjs/color-mode': ^3.2.0
|
||||
'@nuxtjs/i18n': ^8.0.0-beta.7
|
||||
'@pinia/nuxt': ^0.4.6
|
||||
|
@ -86,6 +88,8 @@ specifiers:
|
|||
|
||||
dependencies:
|
||||
'@fnando/sparkline': 0.3.10
|
||||
'@iconify-emoji/twemoji': 1.0.2
|
||||
'@iconify/utils': 2.0.8
|
||||
'@nuxtjs/color-mode': 3.2.0
|
||||
'@tiptap/extension-character-count': 2.0.0-beta.204
|
||||
'@tiptap/extension-code-block': 2.0.0-beta.204
|
||||
|
@ -273,7 +277,6 @@ packages:
|
|||
dependencies:
|
||||
execa: 5.1.1
|
||||
find-up: 5.0.0
|
||||
dev: true
|
||||
|
||||
/@antfu/ni/0.18.8:
|
||||
resolution: {integrity: sha512-0m++AudwQq+wWAz/Ax7g+sh/wFW51HHQ6BtPLsuTAsFIzWB/bv/0COwZE7BRS+u0nqMb6Ks6nlk6cY1TpPDwHg==}
|
||||
|
@ -286,7 +289,6 @@ packages:
|
|||
|
||||
/@antfu/utils/0.7.2:
|
||||
resolution: {integrity: sha512-vy9fM3pIxZmX07dL+VX1aZe7ynZ+YyB0jY+jE6r3hOK6GNY2t6W8rzpFC4tgpbXUYABkFQwgJq2XYXlxbXAI0g==}
|
||||
dev: true
|
||||
|
||||
/@apideck/better-ajv-errors/0.3.6_ajv@8.11.2:
|
||||
resolution: {integrity: sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==}
|
||||
|
@ -1564,6 +1566,10 @@ packages:
|
|||
resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
|
||||
dev: true
|
||||
|
||||
/@iconify-emoji/twemoji/1.0.2:
|
||||
resolution: {integrity: sha512-C4W6ov4BkDXiVU3GzyqyVo8SBbU21KivXnZERgAnrYZEKjuiI3JwPDnu9oVJPsUkNI/Q4SM8iVnXjGW6kxt9DQ==}
|
||||
dev: false
|
||||
|
||||
/@iconify-json/carbon/1.1.11:
|
||||
resolution: {integrity: sha512-IHkHSNmTM6q6b8DuKSzd+AEMYPZywSxcb+37kZU7ywtcwsGen3aVEvWFykopIWjjwj3xdZ/5UdwJRqhZDQMlNg==}
|
||||
dependencies:
|
||||
|
@ -1602,20 +1608,18 @@ packages:
|
|||
|
||||
/@iconify/types/2.0.0:
|
||||
resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
|
||||
dev: true
|
||||
|
||||
/@iconify/utils/2.0.5:
|
||||
resolution: {integrity: sha512-UMT1WhBkr7oYggc69dFl/1RHE9XDisCrWaKXXQLpIccLCytHWZEX3247b/wR+sexYIKBSWs8YIKmMBe3g4oGCw==}
|
||||
/@iconify/utils/2.0.8:
|
||||
resolution: {integrity: sha512-e/1Rng92uxQTM+481EZaV1t7S03PFKIiWyc7io2/923DRUvOMcB1hwP6a2dvQ1Uf/0ncwXcwD+5bMTOkZlEdYw==}
|
||||
dependencies:
|
||||
'@antfu/install-pkg': 0.1.1
|
||||
'@antfu/utils': 0.5.2
|
||||
'@antfu/utils': 0.7.2
|
||||
'@iconify/types': 2.0.0
|
||||
debug: 4.3.4
|
||||
kolorist: 1.6.0
|
||||
local-pkg: 0.4.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@intlify/bundle-utils/3.4.0_vue-i18n@9.3.0-beta.10:
|
||||
resolution: {integrity: sha512-2UQkqiSAOSPEHMGWlybqWm4G2K0X+FyYho5AwXz6QklSX1EY5EDmOSxZmwscn2qmKBnp6OYsme5kUrnN9xrWzQ==}
|
||||
|
@ -1629,8 +1633,8 @@ packages:
|
|||
vue-i18n:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@intlify/message-compiler': 9.3.0-beta.12
|
||||
'@intlify/shared': 9.3.0-beta.12
|
||||
'@intlify/message-compiler': 9.3.0-beta.11
|
||||
'@intlify/shared': 9.3.0-beta.11
|
||||
jsonc-eslint-parser: 1.4.1
|
||||
source-map: 0.6.1
|
||||
vue-i18n: 9.3.0-beta.10
|
||||
|
@ -1662,8 +1666,8 @@ packages:
|
|||
source-map: 0.6.1
|
||||
dev: true
|
||||
|
||||
/@intlify/message-compiler/9.3.0-beta.12:
|
||||
resolution: {integrity: sha512-A8/s7pb3v8nf6HG77qFPJntxgQKI9GXxGnkn7aO+b03/X/GkF/4WceDSAIk3i+yLeIgszeBn9GZ23tSg4sTEHA==}
|
||||
/@intlify/message-compiler/9.3.0-beta.11:
|
||||
resolution: {integrity: sha512-gGGfBGzM7JBXp1Q9gbDAy5jELz9ho3ILqnpxp2yp64+gkqohrqc2YXIvCdwZoc6AtKIh/Zmv4sWVqxkvMsBWtQ==}
|
||||
engines: {node: '>= 14'}
|
||||
dependencies:
|
||||
'@intlify/shared': 9.3.0-beta.11
|
||||
|
@ -1680,11 +1684,6 @@ packages:
|
|||
engines: {node: '>= 14'}
|
||||
dev: true
|
||||
|
||||
/@intlify/shared/9.3.0-beta.12:
|
||||
resolution: {integrity: sha512-WsmaS54sA8xuwezPKpa/OMoaX1v2VF2fCgAmYS6prDr2ir0CkUFWPm9A8ilmxzv4nkS61/v8+vf4lGGkn5uBdA==}
|
||||
engines: {node: '>= 14'}
|
||||
dev: true
|
||||
|
||||
/@intlify/unplugin-vue-i18n/0.8.0_vue-i18n@9.3.0-beta.10:
|
||||
resolution: {integrity: sha512-bqMDYrbmV0oMLGHTdYMUXfcEsy2rPwQnGrQAg4gvw5FimvJfTQt3RliLVayT5ldOfeT2g0IUc/0t7LPeGrFUag==}
|
||||
engines: {node: '>= 14.16'}
|
||||
|
@ -1701,7 +1700,7 @@ packages:
|
|||
optional: true
|
||||
dependencies:
|
||||
'@intlify/bundle-utils': 3.4.0_vue-i18n@9.3.0-beta.10
|
||||
'@intlify/shared': 9.3.0-beta.12
|
||||
'@intlify/shared': 9.3.0-beta.11
|
||||
'@rollup/pluginutils': 4.2.1
|
||||
'@vue/compiler-sfc': 3.2.45
|
||||
debug: 4.3.4
|
||||
|
@ -2968,7 +2967,7 @@ packages:
|
|||
/@unocss/preset-icons/0.48.0:
|
||||
resolution: {integrity: sha512-3vro36gTkjEic5rO9BcUudby8tQ9ZRCduKZ1+4CKP0hKoB58nDm1QZM+kvWQ8RVN2xoSU9vWkHhx1RLl8miE0g==}
|
||||
dependencies:
|
||||
'@iconify/utils': 2.0.5
|
||||
'@iconify/utils': 2.0.8
|
||||
'@unocss/core': 0.48.0
|
||||
ohmyfetch: 0.4.21
|
||||
transitivePeerDependencies:
|
||||
|
@ -4490,7 +4489,6 @@ packages:
|
|||
path-key: 3.1.1
|
||||
shebang-command: 2.0.0
|
||||
which: 2.0.2
|
||||
dev: true
|
||||
|
||||
/crypto-random-string/2.0.0:
|
||||
resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==}
|
||||
|
@ -5651,7 +5649,6 @@ packages:
|
|||
onetime: 5.1.2
|
||||
signal-exit: 3.0.7
|
||||
strip-final-newline: 2.0.0
|
||||
dev: true
|
||||
|
||||
/execa/6.1.0:
|
||||
resolution: {integrity: sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==}
|
||||
|
@ -5770,7 +5767,6 @@ packages:
|
|||
dependencies:
|
||||
locate-path: 6.0.0
|
||||
path-exists: 4.0.0
|
||||
dev: true
|
||||
|
||||
/flat-cache/3.0.4:
|
||||
resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==}
|
||||
|
@ -5982,7 +5978,6 @@ packages:
|
|||
/get-stream/6.0.1:
|
||||
resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
|
||||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
/get-symbol-description/1.0.0:
|
||||
resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==}
|
||||
|
@ -6260,7 +6255,6 @@ packages:
|
|||
/human-signals/2.1.0:
|
||||
resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
|
||||
engines: {node: '>=10.17.0'}
|
||||
dev: true
|
||||
|
||||
/human-signals/3.0.1:
|
||||
resolution: {integrity: sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==}
|
||||
|
@ -6569,7 +6563,6 @@ packages:
|
|||
/is-stream/2.0.1:
|
||||
resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/is-stream/3.0.0:
|
||||
resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==}
|
||||
|
@ -6613,7 +6606,6 @@ packages:
|
|||
|
||||
/isexe/2.0.0:
|
||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||
dev: true
|
||||
|
||||
/iso-639-1/2.1.15:
|
||||
resolution: {integrity: sha512-7c7mBznZu2ktfvyT582E2msM+Udc1EjOyhVRE/0ZsjD9LBtWSm23h3PtiRh2a35XoUsTQQjJXaJzuLjXsOdFDg==}
|
||||
|
@ -6822,7 +6814,6 @@ packages:
|
|||
|
||||
/kolorist/1.6.0:
|
||||
resolution: {integrity: sha512-dLkz37Ab97HWMx9KTes3Tbi3D1ln9fCAy2zr2YVExJasDRPGRaKcoE4fycWNtnCAJfjFqe0cnY+f8KT2JePEXQ==}
|
||||
dev: true
|
||||
|
||||
/lazystream/1.0.1:
|
||||
resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==}
|
||||
|
@ -6932,7 +6923,6 @@ packages:
|
|||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
p-locate: 5.0.0
|
||||
dev: true
|
||||
|
||||
/lodash._reinterpolate/3.0.0:
|
||||
resolution: {integrity: sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==}
|
||||
|
@ -7115,7 +7105,6 @@ packages:
|
|||
|
||||
/merge-stream/2.0.0:
|
||||
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
|
||||
dev: true
|
||||
|
||||
/merge2/1.4.1:
|
||||
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
|
||||
|
@ -7168,7 +7157,6 @@ packages:
|
|||
/mimic-fn/2.1.0:
|
||||
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/mimic-fn/4.0.0:
|
||||
resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==}
|
||||
|
@ -7467,7 +7455,6 @@ packages:
|
|||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
path-key: 3.1.1
|
||||
dev: true
|
||||
|
||||
/npm-run-path/5.1.0:
|
||||
resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==}
|
||||
|
@ -7643,7 +7630,6 @@ packages:
|
|||
engines: {node: '>=6'}
|
||||
dependencies:
|
||||
mimic-fn: 2.1.0
|
||||
dev: true
|
||||
|
||||
/onetime/6.0.0:
|
||||
resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==}
|
||||
|
@ -7721,7 +7707,6 @@ packages:
|
|||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
yocto-queue: 0.1.0
|
||||
dev: true
|
||||
|
||||
/p-locate/4.1.0:
|
||||
resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
|
||||
|
@ -7735,7 +7720,6 @@ packages:
|
|||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
p-limit: 3.1.0
|
||||
dev: true
|
||||
|
||||
/p-map/4.0.0:
|
||||
resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==}
|
||||
|
@ -7832,7 +7816,6 @@ packages:
|
|||
/path-exists/4.0.0:
|
||||
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/path-is-absolute/1.0.1:
|
||||
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
|
||||
|
@ -7842,7 +7825,6 @@ packages:
|
|||
/path-key/3.1.1:
|
||||
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/path-key/4.0.0:
|
||||
resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==}
|
||||
|
@ -8825,12 +8807,10 @@ packages:
|
|||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
shebang-regex: 3.0.0
|
||||
dev: true
|
||||
|
||||
/shebang-regex/3.0.0:
|
||||
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/shiki-es/0.1.2:
|
||||
resolution: {integrity: sha512-eqtfk8idlYlSLAn0gp0Ly2+FbKc2d78IddigHSS4iHAnpXoY2kdRzyFGZOdi6TvemYMnRhZBi1HsSqZc5eNKqg==}
|
||||
|
@ -8854,7 +8834,6 @@ packages:
|
|||
|
||||
/signal-exit/3.0.7:
|
||||
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
|
||||
dev: true
|
||||
|
||||
/simple-git-hooks/2.8.1:
|
||||
resolution: {integrity: sha512-DYpcVR1AGtSfFUNzlBdHrQGPsOhuuEJ/FkmPOOlFysP60AHd3nsEpkGq/QEOdtUyT1Qhk7w9oLmFoMG+75BDog==}
|
||||
|
@ -9109,7 +9088,6 @@ packages:
|
|||
/strip-final-newline/2.0.0:
|
||||
resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/strip-final-newline/3.0.0:
|
||||
resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==}
|
||||
|
@ -10200,7 +10178,7 @@ packages:
|
|||
vue-router:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@intlify/shared': 9.3.0-beta.12
|
||||
'@intlify/shared': 9.3.0-beta.11
|
||||
'@intlify/vue-i18n-bridge': 0.8.0_vue-i18n@9.3.0-beta.10
|
||||
'@intlify/vue-router-bridge': 0.8.0
|
||||
ufo: 1.0.1
|
||||
|
@ -10376,7 +10354,6 @@ packages:
|
|||
hasBin: true
|
||||
dependencies:
|
||||
isexe: 2.0.0
|
||||
dev: true
|
||||
|
||||
/wide-align/1.1.5:
|
||||
resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==}
|
||||
|
@ -10652,7 +10629,6 @@ packages:
|
|||
/yocto-queue/0.1.0:
|
||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
/zip-stream/4.1.0:
|
||||
resolution: {integrity: sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { copy } from 'fs-extra'
|
||||
import { emojiPrefix, iconifyEmojiPackage } from '../config/emojis'
|
||||
|
||||
const dereference = process.platform === 'win32' ? true : undefined
|
||||
|
||||
|
@ -8,3 +9,4 @@ await copy('node_modules/shiki-es/dist/assets', 'public/shiki/', {
|
|||
})
|
||||
await copy('node_modules/theme-vitesse/themes', 'public/shiki/themes', { dereference })
|
||||
await copy('node_modules/theme-vitesse/themes', 'node_modules/shiki/themes', { overwrite: true, dereference })
|
||||
await copy(`node_modules/${iconifyEmojiPackage}/icons`, `public/emojis/${emojiPrefix}`, { overwrite: true, dereference })
|
||||
|
|
|
@ -30,11 +30,6 @@ html {
|
|||
font-weight: 400;
|
||||
src: url(/fonts/homemade-apple-v18.ttf) format('truetype');
|
||||
}
|
||||
@font-face {
|
||||
font-display: swap;
|
||||
font-family: 'EmojiMart';
|
||||
src: url('/fonts/seguiemj.ttf') format('truetype');
|
||||
}
|
||||
|
||||
* {
|
||||
scrollbar-color: #8885 var(--c-border);
|
||||
|
@ -88,6 +83,19 @@ body {
|
|||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
.iconify-emoji {
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
max-height: 1.2em;
|
||||
max-width: 1.2em;
|
||||
vertical-align: text-bottom;
|
||||
margin: 0 0.1em;
|
||||
}
|
||||
|
||||
.iconify-emoji-padded {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.content-rich {
|
||||
line-height: calc(4 / 3 * 1em);
|
||||
overflow-wrap: break-word;
|
||||
|
@ -195,10 +203,6 @@ html[dir="rtl"] .rtl-flip {
|
|||
em-emoji-picker {
|
||||
--border-radius: 0;
|
||||
}
|
||||
em-emoji {
|
||||
font-size: 1.2em;
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
footer {
|
||||
a {
|
||||
|
|
|
@ -36,7 +36,13 @@ exports[`content-rich > empty 1`] = `""`;
|
|||
|
||||
exports[`content-rich > link + mention 1`] = `
|
||||
"<p>
|
||||
Happy <em-emoji native=\\"🤗\\" fallback=\\"🤗\\"></em-emoji> we’re now using
|
||||
Happy
|
||||
<img
|
||||
src=\\"/emojis/twemoji/1f917.svg\\"
|
||||
alt=\\"🤗\\"
|
||||
class=\\"iconify-emoji iconify-emoji--twemoji\\"
|
||||
/>
|
||||
we’re now using
|
||||
<span class=\\"h-card\\"
|
||||
><a
|
||||
class=\\"u-url mention\\"
|
||||
|
|
|
@ -55,10 +55,25 @@ exports[`html-parse > custom emoji > html 1`] = `
|
|||
exports[`html-parse > custom emoji > text 1`] = `"Daniel Roe :nuxt:"`;
|
||||
|
||||
exports[`html-parse > emojis > html 1`] = `
|
||||
"<em-emoji native=\\"🇫🇷\\" fallback=\\"🇫🇷\\"></em-emoji>
|
||||
<em-emoji native=\\"👨👩👦\\" fallback=\\"👨👩👦\\"></em-emoji>
|
||||
<em-emoji native=\\"👩🚒\\" fallback=\\"👩🚒\\"></em-emoji
|
||||
><em-emoji native=\\"🧑🏽🚀\\" fallback=\\"🧑🏽🚀\\"></em-emoji>
|
||||
"<img
|
||||
src=\\"/emojis/twemoji/1f1eb-1f1f7.svg\\"
|
||||
alt=\\"🇫🇷\\"
|
||||
class=\\"iconify-emoji iconify-emoji--twemoji\\"
|
||||
/>
|
||||
<img
|
||||
src=\\"/emojis/twemoji/1f468-200d-1f469-200d-1f466.svg\\"
|
||||
alt=\\"👨👩👦\\"
|
||||
class=\\"iconify-emoji iconify-emoji--twemoji\\"
|
||||
/>
|
||||
<img
|
||||
src=\\"/emojis/twemoji/1f469-200d-1f692.svg\\"
|
||||
alt=\\"👩🚒\\"
|
||||
class=\\"iconify-emoji iconify-emoji--twemoji\\"
|
||||
/><img
|
||||
src=\\"/emojis/twemoji/1f9d1-1f3fd-200d-1f680.svg\\"
|
||||
alt=\\"🧑🏽🚀\\"
|
||||
class=\\"iconify-emoji iconify-emoji--twemoji\\"
|
||||
/>
|
||||
"
|
||||
`;
|
||||
|
||||
|
@ -87,7 +102,13 @@ code block
|
|||
|
||||
exports[`html-parse > link + mention > html 1`] = `
|
||||
"<p>
|
||||
Happy <em-emoji native=\\"🤗\\" fallback=\\"🤗\\"></em-emoji> we’re now using
|
||||
Happy
|
||||
<img
|
||||
src=\\"/emojis/twemoji/1f917.svg\\"
|
||||
alt=\\"🤗\\"
|
||||
class=\\"iconify-emoji iconify-emoji--twemoji\\"
|
||||
/>
|
||||
we’re now using
|
||||
<span class=\\"h-card\\"
|
||||
><a
|
||||
href=\\"https://mas.to/@vitest\\"
|
||||
|
|
Loading…
Reference in a new issue