2022-11-18 19:16:40 +00:00
|
|
|
marked.use({
|
|
|
|
extensions: [
|
|
|
|
{
|
|
|
|
name: 'mention',
|
|
|
|
level: 'inline',
|
|
|
|
start: function(src){
|
2023-09-15 01:24:16 +00:00
|
|
|
const match = src.match(/@[\w-]{1,30}/);
|
2022-11-18 19:16:40 +00:00
|
|
|
return match != null ? match.index : -1;
|
|
|
|
},
|
|
|
|
tokenizer: function(src) {
|
2023-09-15 01:24:16 +00:00
|
|
|
const rule = /^@[\w-]{1,30}/;
|
2022-11-18 19:16:40 +00:00
|
|
|
const match = rule.exec(src);
|
2023-08-06 03:33:34 +00:00
|
|
|
if (match){
|
2022-11-18 19:16:40 +00:00
|
|
|
return {
|
|
|
|
type: 'mention',
|
|
|
|
raw: match[0],
|
|
|
|
text: match[0].trim().slice(1),
|
|
|
|
tokens: []
|
|
|
|
};
|
|
|
|
}
|
|
|
|
},
|
|
|
|
renderer(token) {
|
|
|
|
const u = token.raw;
|
2023-07-22 18:48:47 +00:00
|
|
|
return `<a href="/${u}"><img loading="lazy" src="/${u}/pic" class="pp20"> ${u}</a>`;
|
2022-11-18 19:16:40 +00:00
|
|
|
}
|
2023-03-18 07:00:46 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: 'group_mention',
|
|
|
|
level: 'inline',
|
|
|
|
start: function(src){
|
2023-09-15 01:24:16 +00:00
|
|
|
const match = src.match(/![\w-]{3,25}/);
|
2023-03-18 07:00:46 +00:00
|
|
|
return match != null ? match.index : -1;
|
|
|
|
},
|
|
|
|
tokenizer: function(src) {
|
2023-09-15 01:24:16 +00:00
|
|
|
const rule = /^![\w-]{3,25}/;
|
2023-03-18 07:00:46 +00:00
|
|
|
const match = rule.exec(src);
|
2023-08-06 03:33:34 +00:00
|
|
|
if (match){
|
2023-03-18 07:00:46 +00:00
|
|
|
return {
|
|
|
|
type: 'group_mention',
|
|
|
|
raw: match[0],
|
|
|
|
text: match[0].trim().slice(1),
|
|
|
|
tokens: []
|
|
|
|
};
|
|
|
|
}
|
|
|
|
},
|
|
|
|
renderer(token) {
|
|
|
|
const g = token.raw;
|
2023-03-22 16:24:34 +00:00
|
|
|
return `<a href="/${g}">${g}</a>`;
|
2023-03-18 07:00:46 +00:00
|
|
|
}
|
|
|
|
},
|
2022-11-18 19:16:40 +00:00
|
|
|
]
|
|
|
|
});
|
|
|
|
|
|
|
|
const reDisableBeforeUnload = /^\/submit|^\/h\/[a-zA-Z0-9_\-]{3,20}\/submit/;
|
|
|
|
|
2023-03-07 01:52:02 +00:00
|
|
|
const image_regex_extensions = document.getElementById('IMAGE_FORMATS').value.replaceAll(',', '|')
|
2023-10-28 19:45:24 +00:00
|
|
|
const regex_pattern = String.raw`(^|\s)(https:\/\/[\w\-.#&/=\?@%;+,:]{5,250}(\.|\?format=)(` + image_regex_extensions + String.raw`)((\?|&)[\w\-.#&/=\?@%;+,:]*)?)(?=$|\s|<)`
|
2023-03-07 01:52:02 +00:00
|
|
|
const compiled_regex = new RegExp(regex_pattern, "g");
|
|
|
|
|
2023-04-29 20:50:47 +00:00
|
|
|
const approved_embed_hosts = document.getElementById('approved_embed_hosts').value.replace("{'", "").replace("'}", "").split("', '")
|
|
|
|
function replace_image(match, prefix, url) {
|
|
|
|
if (approved_embed_hosts.some(x => url.startsWith(`https://${x}/`)))
|
|
|
|
return `${prefix}![](${url})`
|
|
|
|
|
|
|
|
return match
|
|
|
|
}
|
2023-07-03 00:26:20 +00:00
|
|
|
|
2023-08-04 10:13:36 +00:00
|
|
|
const MODIFIERS = {
|
|
|
|
PAT: 1,
|
2023-09-07 15:26:31 +00:00
|
|
|
TALKING: 2,
|
2023-08-04 10:13:36 +00:00
|
|
|
LARGE: 3,
|
|
|
|
REVERSED: 4,
|
2023-08-05 01:49:51 +00:00
|
|
|
USER: 5,
|
2024-02-23 18:04:25 +00:00
|
|
|
GENOCIDE: 6,
|
|
|
|
LOVE: 7,
|
|
|
|
TYPING: 8,
|
2023-08-04 10:13:36 +00:00
|
|
|
};
|
|
|
|
|
2023-10-06 18:56:56 +00:00
|
|
|
const findAllEmojiEndings = (word) => {
|
2023-08-09 08:33:14 +00:00
|
|
|
let hasReachedNonModifer = false;
|
|
|
|
let currWord = word;
|
|
|
|
const currEndings = [];
|
|
|
|
while(!hasReachedNonModifer) {
|
|
|
|
if(currWord.endsWith('pat')) {
|
|
|
|
if(currEndings.indexOf(MODIFIERS.PAT) !== -1) {
|
|
|
|
hasReachedNonModifer = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
currWord = currWord.slice(0, -3);
|
|
|
|
currEndings.push(MODIFIERS.PAT);
|
|
|
|
continue;
|
|
|
|
}
|
2023-09-07 15:26:31 +00:00
|
|
|
|
2023-08-09 08:33:14 +00:00
|
|
|
if(currWord.endsWith('talking')) {
|
|
|
|
if(currEndings.indexOf(MODIFIERS.TALKING) !== -1) {
|
|
|
|
hasReachedNonModifer = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
currWord = currWord.slice(0, -7);
|
|
|
|
currEndings.push(MODIFIERS.TALKING);
|
|
|
|
continue;
|
|
|
|
}
|
2023-09-07 15:26:31 +00:00
|
|
|
|
2023-08-09 08:33:14 +00:00
|
|
|
if(currWord.endsWith('genocide')) {
|
|
|
|
if(currEndings.indexOf(MODIFIERS.GENOCIDE) !== -1) {
|
|
|
|
hasReachedNonModifer = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
currWord = currWord.slice(0, -8);
|
|
|
|
currEndings.push(MODIFIERS.GENOCIDE);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2023-08-17 15:37:30 +00:00
|
|
|
if(currWord.endsWith('love')) {
|
2023-08-10 12:36:32 +00:00
|
|
|
if(currEndings.indexOf(MODIFIERS.LOVE) !== -1) {
|
|
|
|
hasReachedNonModifer = true;
|
|
|
|
continue;
|
|
|
|
}
|
2023-08-17 18:03:01 +00:00
|
|
|
currWord = currWord.slice(0, -4);
|
2023-08-10 12:36:32 +00:00
|
|
|
currEndings.push(MODIFIERS.LOVE);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2024-01-29 03:51:04 +00:00
|
|
|
if(currWord.endsWith('typing')) {
|
|
|
|
if(currEndings.indexOf(MODIFIERS.TYPING) !== -1) {
|
|
|
|
hasReachedNonModifer = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
currWord = currWord.slice(0, -6);
|
|
|
|
currEndings.push(MODIFIERS.TYPING);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2023-08-09 08:33:14 +00:00
|
|
|
hasReachedNonModifer = true;
|
|
|
|
}
|
2023-09-07 15:26:31 +00:00
|
|
|
|
2023-08-09 08:33:14 +00:00
|
|
|
|
|
|
|
return [currEndings, currWord];
|
|
|
|
}
|
|
|
|
|
2022-11-18 19:16:40 +00:00
|
|
|
function markdown(t) {
|
|
|
|
let input = t.value;
|
|
|
|
|
|
|
|
if (!reDisableBeforeUnload.test(location.pathname))
|
|
|
|
{
|
2023-09-29 01:10:05 +00:00
|
|
|
if (!window.onbeforeunload)
|
2022-11-18 19:16:40 +00:00
|
|
|
{
|
2023-09-29 01:10:05 +00:00
|
|
|
window.onbeforeunload = function (e) {
|
|
|
|
e = e || window.event;
|
2022-11-18 19:16:40 +00:00
|
|
|
if (e) {
|
|
|
|
e.returnValue = 'Any string';
|
|
|
|
}
|
|
|
|
return 'Any string';
|
|
|
|
};
|
|
|
|
}
|
|
|
|
else if (!input) {
|
2023-09-29 01:10:05 +00:00
|
|
|
window.onbeforeunload = null
|
2022-11-18 19:16:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-05 14:21:05 +00:00
|
|
|
if (!input.includes('```') && !input.includes('<pre>'))
|
|
|
|
input = input.replace(/\n/g, '\n\n')
|
2022-11-18 19:16:40 +00:00
|
|
|
input = input.replace(/\|\|(.*?)\|\|/g, '<spoiler>$1</spoiler>')
|
|
|
|
input = input.replace(/(\n|^)>([^ >][^\n]*)/g, '$1<g>\>$2</g>')
|
2023-03-19 13:54:18 +00:00
|
|
|
input = input.replace(/((\s|^)[0-9]+)\. /g, '$1\\. ')
|
2022-11-18 19:16:40 +00:00
|
|
|
|
2023-08-10 12:36:58 +00:00
|
|
|
const emojis = Array.from(input.matchAll(/:([a-z0-9_\-!#@]{1,72}):(?![^`]*`)/gi))
|
2023-08-06 03:33:34 +00:00
|
|
|
if (emojis != null){
|
2022-11-18 19:16:40 +00:00
|
|
|
for(i = 0; i < emojis.length; i++){
|
2022-12-04 15:40:32 +00:00
|
|
|
const old = emojis[i][0];
|
2023-08-04 10:13:36 +00:00
|
|
|
if (old.includes('marseyrandom')) continue;
|
2024-02-23 18:04:25 +00:00
|
|
|
|
2023-08-04 10:13:36 +00:00
|
|
|
let emoji = old.replace(/[:]/g,'').toLowerCase();
|
2023-09-07 15:26:31 +00:00
|
|
|
|
2023-08-04 10:13:36 +00:00
|
|
|
const modifiers = new Set();
|
2023-09-07 15:26:31 +00:00
|
|
|
|
2023-08-09 08:33:14 +00:00
|
|
|
let length = emoji.length;
|
2023-08-05 01:49:51 +00:00
|
|
|
emoji = emoji.replaceAll('!', '');
|
2023-08-06 03:33:34 +00:00
|
|
|
if (length !== emoji.length) {
|
2023-08-05 01:49:51 +00:00
|
|
|
modifiers.add(MODIFIERS.REVERSED);
|
|
|
|
length = emoji.length;
|
|
|
|
}
|
|
|
|
emoji = emoji.replaceAll('#', '');
|
2023-08-06 03:33:34 +00:00
|
|
|
if (length !== emoji.length) {
|
2023-08-05 01:49:51 +00:00
|
|
|
modifiers.add(MODIFIERS.LARGE);
|
|
|
|
}
|
2023-08-09 08:33:14 +00:00
|
|
|
let endingModifiers;
|
2023-10-06 18:56:56 +00:00
|
|
|
[endingModifiers, emoji] = findAllEmojiEndings(emoji);
|
2023-08-09 08:33:14 +00:00
|
|
|
const isTalkingFirst = endingModifiers.indexOf(MODIFIERS.PAT) > endingModifiers.indexOf(MODIFIERS.TALKING);
|
|
|
|
|
|
|
|
endingModifiers.forEach(modifiers.add, modifiers)
|
2023-09-07 15:26:31 +00:00
|
|
|
|
2023-08-06 03:33:34 +00:00
|
|
|
if (emoji.startsWith('@')) {
|
2023-08-05 01:49:51 +00:00
|
|
|
emoji = emoji.slice(1);
|
2023-08-04 10:13:36 +00:00
|
|
|
modifiers.add(MODIFIERS.USER);
|
|
|
|
}
|
2023-09-07 15:26:31 +00:00
|
|
|
|
|
|
|
|
2023-08-06 03:33:34 +00:00
|
|
|
if (emoji === 'marseyunpettable') {
|
2023-08-04 10:13:36 +00:00
|
|
|
modifiers.delete(MODIFIERS.PAT);
|
2023-08-06 03:33:34 +00:00
|
|
|
if (!isTalkingFirst) {
|
2023-08-04 10:13:36 +00:00
|
|
|
modifiers.delete(MODIFIERS.TALKING);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-09 08:33:14 +00:00
|
|
|
const genocideClass = modifiers.has(MODIFIERS.GENOCIDE) ? 'cide' : '';
|
2023-08-04 10:13:36 +00:00
|
|
|
const emojiClass = modifiers.has(MODIFIERS.LARGE) ? 'emoji-lg' : 'emoji';
|
2023-08-10 12:36:32 +00:00
|
|
|
const patClass = modifiers.has(MODIFIERS.PAT) ? 'pat-preview' : '';
|
2023-08-05 01:49:51 +00:00
|
|
|
|
2023-10-06 18:56:56 +00:00
|
|
|
// patted emojis cannot be flipped back easily so they don't support double flipping
|
2023-08-10 12:36:32 +00:00
|
|
|
const lovedClass = modifiers.has(MODIFIERS.LOVE) ? 'love-preview' : '';
|
|
|
|
|
2024-01-29 03:51:04 +00:00
|
|
|
if ([MODIFIERS.TALKING, MODIFIERS.GENOCIDE, MODIFIERS.PAT, MODIFIERS.LOVE, MODIFIERS.TYPING].some((modifer) => modifiers.has(modifer))) {
|
|
|
|
const typingHtml = modifiers.has(MODIFIERS.TYPING) ? `<img loading="lazy" class="typing-hands-preview" src="${SITE_FULL_IMAGES}/i/typing-hands.webp">` : '';
|
2023-08-04 10:13:36 +00:00
|
|
|
const talkingHtml = modifiers.has(MODIFIERS.TALKING) ? `<img loading="lazy" src="${SITE_FULL_IMAGES}/i/talking.webp">` : '';
|
|
|
|
const patHtml = modifiers.has(MODIFIERS.PAT) ? `<img loading="lazy" src="${SITE_FULL_IMAGES}/i/hand.webp">` : '';
|
2023-08-10 12:36:32 +00:00
|
|
|
const loveHtml = modifiers.has(MODIFIERS.LOVE) ? `<img loading="lazy" class="${emojiClass}" src="${SITE_FULL_IMAGES}/i/love-foreground.webp"><img loading="lazy" class="${emojiClass}" src="${SITE_FULL_IMAGES}/i/love-background.webp">` : '';
|
2023-08-04 10:13:36 +00:00
|
|
|
const url = modifiers.has(MODIFIERS.USER) ? `/@${emoji}/pic` : `${SITE_FULL_IMAGES}/e/${emoji}.webp`;
|
2024-01-29 03:51:04 +00:00
|
|
|
const modifierHtml = isTalkingFirst ? `${talkingHtml}${patHtml}${loveHtml}${typingHtml}` : `${patHtml}${talkingHtml}${loveHtml}${typingHtml}`;
|
2024-02-23 18:04:25 +00:00
|
|
|
input = input.replace(old, `<span alt="${old}" class="${patClass} ${genocideClass}" data-bs-toggle="tooltip">${modifierHtml}<img alt="${old}" loading="lazy" class="${emojiClass} ${lovedClass}" src="${url}"></span>`);
|
2022-11-18 19:16:40 +00:00
|
|
|
} else {
|
2024-02-23 18:04:25 +00:00
|
|
|
input = input.replace(old, `<img alt="${old}" loading="lazy" class="${emojiClass}}" src="${SITE_FULL_IMAGES}/e/${emoji}.webp">`);
|
2022-11-18 19:16:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-07 17:12:53 +00:00
|
|
|
let options = Array.from(input.matchAll(/\$\$([^\$\n]+)\$\$(?![^`]*`)/gi))
|
2023-08-06 03:33:34 +00:00
|
|
|
if (options != null){
|
2022-11-18 19:16:40 +00:00
|
|
|
for(i = 0; i < options.length; i++){
|
2022-12-04 15:40:32 +00:00
|
|
|
const option = options[i][0];
|
|
|
|
const option2 = option.replace(/\$\$/g, '').replace(/\n/g, '')
|
2023-03-01 21:02:24 +00:00
|
|
|
input = input.replace(option, `<div class="custom-control mb-3"><input type="checkbox" class="custom-control-input" id="option-${i}"><label class="custom-control-label" for="option-${i}">${option2} - <a>0 votes</a></label></div>`);
|
2022-11-18 19:16:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-07 17:12:53 +00:00
|
|
|
options = Array.from(input.matchAll(/&&([^&\n]+)&&(?![^`]*`)/gi))
|
2023-08-06 03:33:34 +00:00
|
|
|
if (options != null){
|
2022-11-18 19:16:40 +00:00
|
|
|
for(i = 0; i < options.length; i++){
|
2022-12-04 15:40:32 +00:00
|
|
|
const option = options[i][0];
|
|
|
|
const option2 = option.replace(/&&/g, '').replace(/\n/g, '')
|
2023-03-01 21:02:24 +00:00
|
|
|
input = input.replace(option, `<div class="custom-control mb-3"><input type="radio" name="choice" class="custom-control-input" id="option-${i}"><label class="custom-control-label" for="option-${i}">${option2} - <a>0 votes</a></label></div>`);
|
2022-11-18 19:16:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-29 20:50:47 +00:00
|
|
|
input = input.replace(compiled_regex, replace_image)
|
2023-03-07 01:52:02 +00:00
|
|
|
|
2022-11-18 19:16:40 +00:00
|
|
|
input = marked(input)
|
|
|
|
|
2023-02-03 03:15:30 +00:00
|
|
|
const preview = document.getElementById(t.dataset.preview)
|
2023-02-03 03:04:23 +00:00
|
|
|
|
2023-02-03 03:15:30 +00:00
|
|
|
preview.innerHTML = input
|
|
|
|
|
|
|
|
const expandable = preview.querySelectorAll('img[alt]');
|
2023-02-03 03:04:23 +00:00
|
|
|
for (const element of expandable) {
|
|
|
|
element.onclick = () => {expandImage()};
|
|
|
|
}
|
2022-11-18 19:16:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function charLimit(form, text) {
|
|
|
|
|
2022-12-04 15:40:32 +00:00
|
|
|
const input = document.getElementById(form);
|
2022-11-18 19:16:40 +00:00
|
|
|
|
2022-12-04 15:40:32 +00:00
|
|
|
text = document.getElementById(text);
|
2022-11-18 19:16:40 +00:00
|
|
|
|
2022-12-04 15:40:32 +00:00
|
|
|
const length = input.value.length;
|
2022-11-18 19:16:40 +00:00
|
|
|
|
2022-12-04 15:40:32 +00:00
|
|
|
const maxLength = input.getAttribute("maxlength");
|
2022-11-18 19:16:40 +00:00
|
|
|
|
|
|
|
if (length >= maxLength) {
|
|
|
|
text.style.color = "#E53E3E";
|
|
|
|
}
|
|
|
|
else if (length >= maxLength * .72){
|
|
|
|
text.style.color = "#FFC107";
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
text.style.color = "#A0AEC0";
|
|
|
|
}
|
|
|
|
|
2023-08-14 14:29:06 +00:00
|
|
|
text.textContent = length + ' / ' + maxLength;
|
2022-11-18 19:16:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function remove_dialog() {
|
2023-09-29 01:10:05 +00:00
|
|
|
window.onbeforeunload = null;
|
2022-12-04 15:40:32 +00:00
|
|
|
}
|