|
import style from "./style.module.scss"; |
|
import {useMemo} from "preact/hooks"; |
|
import {smileysMap} from "@/utils/smileys"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function Preview(props: { |
|
raw: string, |
|
}) { |
|
const html = useMemo(() => { |
|
const escaped = escapeHtml(props.raw); |
|
return injectHTML(escaped); |
|
}, [props.raw]); |
|
|
|
return ( |
|
<div className={style.wrapper} dangerouslySetInnerHTML={{__html: html}}/> |
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
function quoteReplacer(reg: RegExp, raw: string): string { |
|
|
|
const match = reg.exec(raw); |
|
reg.lastIndex = 0; |
|
if (!match) return raw; |
|
|
|
const index = match.index; |
|
const length = match[0].length; |
|
|
|
return quoteReplacer( |
|
reg, |
|
raw.substring(0, index) + `<blockquote>${quoteReplacer(reg, match[0].replace(/^> ?/gm, ""))}</blockquote>` + raw.substring(index + length) |
|
); |
|
} |
|
|
|
|
|
const jvcodeMap: [RegExp, string | ((reg: RegExp, raw: string) => string)][] = [ |
|
[ |
|
/^>.*(?:\n>.*)*/m, |
|
quoteReplacer |
|
], |
|
|
|
[ |
|
/(^|>)([^<]+)($|<)/g, |
|
"$1<p>$2</p>$3" |
|
], |
|
[ |
|
/<p>\s*([\s\S]*?)\s*<\/p>/g, |
|
(reg, raw) => { |
|
|
|
return raw.replace(reg, (_, matched) => { |
|
|
|
console.log(matched) |
|
return `<p>${matched.replace(/\n/g, "<br/>")}</p>`; |
|
}); |
|
} |
|
], |
|
[ |
|
/<spoil>(.*?)<\/spoil>/gm, |
|
(reg, raw) => { |
|
return raw.replace(reg, (_, matched) => { |
|
const randomId = (Math.random() + 1).toString(36).substring(2); |
|
return `<span class="bloc-spoil-jv"><input type="checkbox" id="${randomId}" class="open-spoil"><label class="barre-head" for="${randomId}"><span class="txt-spoil">Spoil</span></label><span class="contenu-spoil">${matched}</span></span>`; |
|
}); |
|
} |
|
], |
|
[ |
|
|
|
/(^|<[a-z]+\/?>| )https?:\/\/image\.noelshack\.com\/(?:fichiers|minis)([A-z0-9/\-_.]+)/gm, |
|
"$1<img class=\"sticker\" width=\"68\" height=\"51\" alt=\"sticker\" src=\"https://image.noelshack.com/minis/$2\"/>" |
|
], |
|
[ |
|
/(^|<[a-z]+\/?>| )https:\/\/vocaroo.com\/(.+)/gm, |
|
"$1<div><iframe width=\"300\" height=\"60\" src=\"https://vocaroo.com/embed/$2?autoplay=0\" frameborder=\"0\" allow=\"autoplay\"></iframe></div>" |
|
], |
|
[ |
|
/(^|<[a-z]+\/?>| )(https?:\/\/[-a-zA-Z0-9@:%._/+~#=?&;]+)/gm, |
|
"$1<a href=\"$2\" target=\"_blank\">$2</a>" |
|
], |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
...[...smileysMap].sort((a, b) => b[0].length - a[0].length).map(mapping => { |
|
return [ |
|
new RegExp("(<p>| )" + mapping[0].replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), "gm"), |
|
`$1<img src="https://image.jeuxvideo.com/smileys_img/${mapping[1]}.gif" alt="${mapping[0]}"/>` |
|
]; |
|
}) |
|
]; |
|
|
|
function injectHTML(input: string): string { |
|
|
|
let text = input.slice() |
|
for (const [regex, htmlOrFunc] of jvcodeMap) { |
|
|
|
regex.lastIndex = 0; |
|
|
|
|
|
|
|
if (htmlOrFunc instanceof Function) { |
|
text = htmlOrFunc(regex, text); |
|
} else { |
|
|
|
|
|
text = text.replace(regex, htmlOrFunc as string); |
|
} |
|
} |
|
|
|
|
|
return text; |
|
} |
|
|
|
function escapeHtml(unsafe: string): string { |
|
|
|
return unsafe |
|
.replace(/&/g, "&") |
|
.replace(/</g, "<") |
|
.replace(/>/g, ">") |
|
.replace(/"/g, """) |
|
.replace(/'/g, "'"); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|