mirror of
https://github.com/danbulant/Nertivia-Client
synced 2026-06-13 19:42:01 +00:00
increase emoji-parsing performance
This commit is contained in:
parent
5db33c4e7c
commit
4393095af4
1 changed files with 41 additions and 21 deletions
|
|
@ -3,39 +3,52 @@ import config from "@/config.js";
|
|||
/* 58: ':' */
|
||||
/* 60: '<' */
|
||||
/* 62: '>' */
|
||||
/* example: '<:cat_1:1hvDmIdozFp2vTTkEIsO-wBHPaYRkGmlP>' */
|
||||
|
||||
function render_custom_emoji(tokens, idx) {
|
||||
return ':3'
|
||||
function skipUntil(state, pos, code) {
|
||||
for (let max = state.src.length; pos < max; pos++) {
|
||||
if (state.src.charCodeAt(pos) === code) { break; }
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
function parseUntil(state, fromPos, until) {
|
||||
// old
|
||||
function parseUntil(state, fromPos, until, maxLength = 16) {
|
||||
let max = state.posMax
|
||||
let found = false
|
||||
|
||||
let pos = state.pos + fromPos
|
||||
let oldPos = state.pos
|
||||
// let start = nameStart + 1
|
||||
state.pos = fromPos
|
||||
let end = -1
|
||||
|
||||
while(state.pos++ < max) {
|
||||
let marker = state.src.charCodeAt(state.pos)
|
||||
|
||||
while(pos < max && pos - oldPos < maxLength) {
|
||||
let marker = state.src.charCodeAt(pos)
|
||||
if(marker === until) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// state.md.inline.skipToken(state);
|
||||
|
||||
pos += 1
|
||||
}
|
||||
|
||||
if(found) {
|
||||
end = state.pos
|
||||
end = pos
|
||||
}
|
||||
|
||||
state.pos = oldPos
|
||||
|
||||
return end
|
||||
}
|
||||
|
||||
function render_custom_emoji(tokens, idx) {
|
||||
return ''
|
||||
}
|
||||
|
||||
|
||||
function parseEmojiName(state, nameStart) {
|
||||
return parseUntil(state, nameStart, 58)
|
||||
// return parseUntil(state, nameStart, 58)
|
||||
|
||||
return skipUntil(state, nameStart, 58)
|
||||
}
|
||||
|
||||
function replace_custom_emoji(state, silent) {
|
||||
|
|
@ -53,8 +66,10 @@ function replace_custom_emoji(state, silent) {
|
|||
let nameStart = pos + 1
|
||||
let nameEnd = parseEmojiName(state, nameStart)
|
||||
|
||||
// console.log(nameEnd, parseUntil(state,nameStart,58))
|
||||
|
||||
// parser failed to find another ':', so it's not a valid emoji
|
||||
if(nameEnd < 0 || nameEnd - nameStart <= 1) { return false; }
|
||||
if(nameEnd > max || nameEnd < 0 || nameEnd - nameStart <= 1) { return false; }
|
||||
|
||||
let emojiName = state.src.slice(nameStart, nameEnd)
|
||||
|
||||
|
|
@ -62,9 +77,9 @@ function replace_custom_emoji(state, silent) {
|
|||
|
||||
// parse until '>'
|
||||
let idStart = pos
|
||||
let idEnd = parseUntil(state, idStart, 62)
|
||||
let idEnd = skipUntil(state, pos, 62);
|
||||
|
||||
if(idEnd < 0 || idEnd - idStart <= 1) { return false; }
|
||||
if(idEnd > max || idEnd < 0 || idEnd - idStart <= 1) { return false; }
|
||||
|
||||
let emojiID = state.src.slice(idStart, idEnd)
|
||||
|
||||
|
|
@ -72,20 +87,25 @@ function replace_custom_emoji(state, silent) {
|
|||
state.pos = idStart
|
||||
state.posMax = idEnd
|
||||
|
||||
let token = state.push('custom_emoji_open', 'img', 1);
|
||||
token.attrs = [[ 'src', `${config.domain}/files/${emojiID}` ]]
|
||||
|
||||
// state.md.inline.tokenize(state)
|
||||
let token = state.push('custom_emoji', 'img', 0);
|
||||
token.attrs = [[ 'src', `${config.domain}/files/${emojiID}` ], [ 'alt', emojiName ]]
|
||||
}
|
||||
|
||||
state.pos = idEnd + 1
|
||||
state.posMax = max
|
||||
return true
|
||||
}
|
||||
|
||||
export default function custom_emoji_plugin(md, opts) {
|
||||
md.renderer.rules.custom_emoji_open = (tokens, idx) => {
|
||||
md.renderer.rules.custom_emoji = (tokens, idx) => {
|
||||
let token = tokens[idx]
|
||||
return `<${md.utils.escapeHtml(token.tag)} class="emoji" src=${md.utils.escapeHtml(token.attrs.find(([name]) => name === 'src')[1])} />`
|
||||
|
||||
// todo: better escaping method,
|
||||
// even if this is good and covers most cases, there may be edge cases where DOMPurify may be better
|
||||
let src = md.utils.escapeHtml(token.attrs.find(([name]) => name === 'src')[1])
|
||||
let alt = md.utils.escapeHtml(token.attrs.find(([name]) => name === 'alt')[1])
|
||||
|
||||
return `<${md.utils.escapeHtml(token.tag)} class="emoji" title=${alt} alt=${alt} src=${src} />`
|
||||
}
|
||||
|
||||
md.inline.ruler.push('custom_emoji', replace_custom_emoji)
|
||||
|
|
|
|||
Loading…
Reference in a new issue