Adds marseycide! #182
|
@ -5594,6 +5594,17 @@ img[src$="/i/hand.webp"]+img[src^="/pp/"], img[src$="/i/hand.webp"]+img[src$="/p
|
||||||
100% { transform: scale(1, 0.8) }
|
100% { transform: scale(1, 0.8) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes cide-anim {
|
||||||
|
0% { transform: scale(1,1) rotate(0deg) }
|
||||||
|
100% { transform: scale(0, 0) rotate(360deg) }
|
||||||
|
}
|
||||||
|
|
||||||
|
.cide, span[cide] {
|
||||||
|
display: inline-block;
|
||||||
|
animation: cide-anim 2s infinite;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
}
|
||||||
|
|
||||||
/* Fix for <ol> being populated with <li><p></p></li> in many contexts. */
|
/* Fix for <ol> being populated with <li><p></p></li> in many contexts. */
|
||||||
.post-body li > p:first-child,
|
.post-body li > p:first-child,
|
||||||
.comment-text li > p:first-child,
|
.comment-text li > p:first-child,
|
||||||
|
|
|
@ -72,8 +72,51 @@ const MODIFIERS = {
|
||||||
REVERSED: 4,
|
REVERSED: 4,
|
||||||
USER: 5,
|
USER: 5,
|
||||||
REVERSED_MODIFIER: 6,
|
REVERSED_MODIFIER: 6,
|
||||||
|
GENOCIDE: 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const findAllEmoteEndings = (word) => {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(currWord.endsWith('talking')) {
|
||||||
|
if(currEndings.indexOf(MODIFIERS.TALKING) !== -1) {
|
||||||
|
hasReachedNonModifer = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
currWord = currWord.slice(0, -7);
|
||||||
|
currEndings.push(MODIFIERS.TALKING);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(currWord.endsWith('genocide')) {
|
||||||
|
if(currEndings.indexOf(MODIFIERS.GENOCIDE) !== -1) {
|
||||||
|
hasReachedNonModifer = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
currWord = currWord.slice(0, -8);
|
||||||
|
currEndings.push(MODIFIERS.GENOCIDE);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
hasReachedNonModifer = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return [currEndings, currWord];
|
||||||
|
}
|
||||||
|
|
||||||
function markdown(t) {
|
function markdown(t) {
|
||||||
let input = t.value;
|
let input = t.value;
|
||||||
|
|
||||||
|
@ -110,7 +153,7 @@ function markdown(t) {
|
||||||
|
|
||||||
const modifiers = new Set();
|
const modifiers = new Set();
|
||||||
|
|
||||||
let length = emoji.length
|
let length = emoji.length;
|
||||||
if(emoji.includes('!!')) modifiers.add(MODIFIERS.REVERSED_MODIFIER);
|
if(emoji.includes('!!')) modifiers.add(MODIFIERS.REVERSED_MODIFIER);
|
||||||
emoji = emoji.replaceAll('!', '');
|
emoji = emoji.replaceAll('!', '');
|
||||||
if (length !== emoji.length) {
|
if (length !== emoji.length) {
|
||||||
|
@ -121,15 +164,11 @@ function markdown(t) {
|
||||||
if (length !== emoji.length) {
|
if (length !== emoji.length) {
|
||||||
modifiers.add(MODIFIERS.LARGE);
|
modifiers.add(MODIFIERS.LARGE);
|
||||||
}
|
}
|
||||||
const isTalkingFirst = !(emoji.endsWith('pat') && emoji.slice(0, -3).endsWith('talking'));
|
let endingModifiers;
|
||||||
if (emoji.endsWith('talking') || (emoji.endsWith('pat') && emoji.slice(0, -3).endsWith('talking'))) {
|
[endingModifiers, emoji] = findAllEmoteEndings(emoji);
|
||||||
modifiers.add(MODIFIERS.TALKING);
|
const isTalkingFirst = endingModifiers.indexOf(MODIFIERS.PAT) > endingModifiers.indexOf(MODIFIERS.TALKING);
|
||||||
emoji = emoji.endsWith('pat') ? [emoji.slice(0, -10), emoji.slice(-3)].join('') : emoji.slice(0, -7);
|
|
||||||
}
|
endingModifiers.forEach(modifiers.add, modifiers)
|
||||||
if (emoji.endsWith('pat')) {
|
|
||||||
modifiers.add(MODIFIERS.PAT);
|
|
||||||
emoji = emoji.slice(0, -3);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (emoji.startsWith('@')) {
|
if (emoji.startsWith('@')) {
|
||||||
emoji = emoji.slice(1);
|
emoji = emoji.slice(1);
|
||||||
|
@ -145,18 +184,19 @@ function markdown(t) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const mirroredClass = 'mirrored';
|
const mirroredClass = 'mirrored';
|
||||||
|
const genocideClass = modifiers.has(MODIFIERS.GENOCIDE) ? 'cide' : '';
|
||||||
const emojiClass = modifiers.has(MODIFIERS.LARGE) ? 'emoji-lg' : 'emoji';
|
const emojiClass = modifiers.has(MODIFIERS.LARGE) ? 'emoji-lg' : 'emoji';
|
||||||
|
|
||||||
// patted emotes cannot be flipped back easily so they don't support double flipping
|
// patted emotes cannot be flipped back easily so they don't support double flipping
|
||||||
const spanClass = modifiers.has(MODIFIERS.REVERSED) && (modifiers.has(MODIFIERS.PAT) || !modifiers.has(MODIFIERS.REVERSED_MODIFIER)) ? mirroredClass : '';
|
const spanClass = modifiers.has(MODIFIERS.REVERSED) && (modifiers.has(MODIFIERS.PAT) || !modifiers.has(MODIFIERS.REVERSED_MODIFIER)) ? mirroredClass : '';
|
||||||
const imgClass = modifiers.has(MODIFIERS.REVERSED) && modifiers.has(MODIFIERS.REVERSED_MODIFIER) ? mirroredClass : ''
|
const imgClass = modifiers.has(MODIFIERS.REVERSED) && modifiers.has(MODIFIERS.REVERSED_MODIFIER) ? mirroredClass : ''
|
||||||
|
|
||||||
if (modifiers.has(MODIFIERS.PAT) || modifiers.has(MODIFIERS.TALKING)) {
|
if (modifiers.has(MODIFIERS.PAT) || modifiers.has(MODIFIERS.TALKING) || modifiers.has(MODIFIERS.GENOCIDE)) {
|
||||||
const talkingHtml = modifiers.has(MODIFIERS.TALKING) ? `<img loading="lazy" src="${SITE_FULL_IMAGES}/i/talking.webp">` : '';
|
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">` : '';
|
const patHtml = modifiers.has(MODIFIERS.PAT) ? `<img loading="lazy" src="${SITE_FULL_IMAGES}/i/hand.webp">` : '';
|
||||||
const url = modifiers.has(MODIFIERS.USER) ? `/@${emoji}/pic` : `${SITE_FULL_IMAGES}/e/${emoji}.webp`;
|
const url = modifiers.has(MODIFIERS.USER) ? `/@${emoji}/pic` : `${SITE_FULL_IMAGES}/e/${emoji}.webp`;
|
||||||
const modifierHtml = isTalkingFirst ? `${talkingHtml}${patHtml}` : `${patHtml}${talkingHtml}`;
|
const modifierHtml = isTalkingFirst ? `${talkingHtml}${patHtml}` : `${patHtml}${talkingHtml}`;
|
||||||
input = input.replace(old, `<span class="pat-preview ${spanClass}" data-bs-toggle="tooltip">${modifierHtml}<img loading="lazy" class="${emojiClass} ${imgClass}" src="${url}"></span>`);
|
input = input.replace(old, `<span class="pat-preview ${spanClass} ${genocideClass}" data-bs-toggle="tooltip">${modifierHtml}<img loading="lazy" class="${emojiClass} ${imgClass} " src="${url}"></span>`);
|
||||||
} else {
|
} else {
|
||||||
input = input.replace(old, `<img loading="lazy" class="${emojiClass} ${modifiers.has(MODIFIERS.REVERSED) ? mirroredClass : ''}" src="${SITE_FULL_IMAGES}/e/${emoji}.webp">`);
|
input = input.replace(old, `<img loading="lazy" class="${emojiClass} ${modifiers.has(MODIFIERS.REVERSED) ? mirroredClass : ''}" src="${SITE_FULL_IMAGES}/e/${emoji}.webp">`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,6 +99,7 @@ def allowed_attributes(tag, name, value):
|
||||||
if name == 'data-bs-toggle' and value == 'tooltip': return True
|
if name == 'data-bs-toggle' and value == 'tooltip': return True
|
||||||
if name == 'title': return True
|
if name == 'title': return True
|
||||||
if name == 'alt': return True
|
if name == 'alt': return True
|
||||||
|
if name == 'cide' and not value: return True
|
||||||
|
|
||||||
if tag == 'table':
|
if tag == 'table':
|
||||||
if name == 'class' and value == 'table': return True
|
if name == 'class' and value == 'table': return True
|
||||||
|
@ -212,6 +213,42 @@ def execute_blackjack(v, target, body, kind):
|
||||||
send_repeatable_notification_duplicated(id, f"Blackjack by @{v.username}: {extra_info}")
|
send_repeatable_notification_duplicated(id, f"Blackjack by @{v.username}: {extra_info}")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def find_all_emote_endings(word):
|
||||||
|
endings = list()
|
||||||
|
curr_word = word
|
||||||
|
|
||||||
|
is_non_ending_found = False
|
||||||
|
while not is_non_ending_found:
|
||||||
|
print(curr_word)
|
||||||
|
if curr_word.endswith('pat'):
|
||||||
|
if 'pat' in endings:
|
||||||
|
is_non_ending_found = True
|
||||||
|
continue
|
||||||
|
endings.append('pat')
|
||||||
|
curr_word = curr_word[:-3]
|
||||||
|
continue
|
||||||
|
|
||||||
|
if curr_word.endswith('talking'):
|
||||||
|
if 'talking' in endings:
|
||||||
|
is_non_ending_found = True
|
||||||
|
continue
|
||||||
|
endings.append('talking')
|
||||||
|
curr_word = curr_word[:-7]
|
||||||
|
continue
|
||||||
|
|
||||||
|
if curr_word.endswith('genocide'):
|
||||||
|
if 'genocide' in endings:
|
||||||
|
is_non_ending_found = True
|
||||||
|
continue
|
||||||
|
endings.append('genocide')
|
||||||
|
curr_word = curr_word[:-8]
|
||||||
|
continue
|
||||||
|
|
||||||
|
is_non_ending_found = True
|
||||||
|
|
||||||
|
return endings, curr_word
|
||||||
|
|
||||||
|
|
||||||
def render_emoji(html, regexp, golden, emojis_used, b=False, is_title=False):
|
def render_emoji(html, regexp, golden, emojis_used, b=False, is_title=False):
|
||||||
emojis = list(regexp.finditer(html))
|
emojis = list(regexp.finditer(html))
|
||||||
captured = set()
|
captured = set()
|
||||||
|
@ -245,12 +282,13 @@ def render_emoji(html, regexp, golden, emojis_used, b=False, is_title=False):
|
||||||
emoji_partial = '<img alt=":{0}:" data-bs-toggle="tooltip" loading="lazy" src="{1}" title=":{0}:"{2}>'
|
emoji_partial = '<img alt=":{0}:" data-bs-toggle="tooltip" loading="lazy" src="{1}" title=":{0}:"{2}>'
|
||||||
emoji_html = None
|
emoji_html = None
|
||||||
|
|
||||||
is_talking = emoji.endswith('talking') or (emoji[:-3].endswith('talking') and emoji.endswith('pat'))
|
ending_modifiers, emoji = find_all_emote_endings(emoji)
|
||||||
is_talking_first = emoji.endswith('talking')
|
|
||||||
emoji = emoji[:-7] if emoji.endswith('talking') else emoji
|
is_talking = 'talking' in ending_modifiers
|
||||||
emoji = f'{emoji[:-10]}pat' if emoji[:-3].endswith('talking') and emoji.endswith('pat') else emoji
|
is_patted = 'pat' in ending_modifiers
|
||||||
is_patted = emoji.endswith('pat')
|
is_talking_first = ending_modifiers.index('pat') > ending_modifiers.index('talking') if is_talking and is_patted else False
|
||||||
emoji = emoji[:-3] if is_patted else emoji
|
|
||||||
|
is_genocided = 'genocide' in ending_modifiers
|
||||||
is_user = emoji.startswith('@')
|
is_user = emoji.startswith('@')
|
||||||
|
|
||||||
end_modifier_length = 3 if is_patted else 0
|
end_modifier_length = 3 if is_patted else 0
|
||||||
|
@ -258,8 +296,9 @@ def render_emoji(html, regexp, golden, emojis_used, b=False, is_title=False):
|
||||||
|
|
||||||
hand_html = f'<img loading="lazy" src="{SITE_FULL_IMAGES}/i/hand.webp">' if is_patted and emoji != 'marseyunpettable' else ''
|
hand_html = f'<img loading="lazy" src="{SITE_FULL_IMAGES}/i/hand.webp">' if is_patted and emoji != 'marseyunpettable' else ''
|
||||||
talking_html = f'<img loading="lazy" src="{SITE_FULL_IMAGES}/i/talking.webp">' if is_talking else ''
|
talking_html = f'<img loading="lazy" src="{SITE_FULL_IMAGES}/i/talking.webp">' if is_talking else ''
|
||||||
|
genocide_attr = ' cide' if is_genocided else ''
|
||||||
|
|
||||||
modifier_html = None
|
modifier_html = ''
|
||||||
if (is_talking and is_patted):
|
if (is_talking and is_patted):
|
||||||
modifier_html = f'{talking_html}{hand_html}' if is_talking_first else f'{hand_html}{talking_html}'
|
modifier_html = f'{talking_html}{hand_html}' if is_talking_first else f'{hand_html}{talking_html}'
|
||||||
elif (is_patted):
|
elif (is_patted):
|
||||||
|
@ -267,12 +306,12 @@ def render_emoji(html, regexp, golden, emojis_used, b=False, is_title=False):
|
||||||
elif (is_talking):
|
elif (is_talking):
|
||||||
modifier_html = talking_html
|
modifier_html = talking_html
|
||||||
|
|
||||||
if (is_patted and emoji != 'marseyunpettable') or is_talking:
|
if (is_patted and emoji != 'marseyunpettable') or is_talking or is_genocided:
|
||||||
if path.isfile(f"files/assets/images/emojis/{emoji}.webp"):
|
if path.isfile(f"files/assets/images/emojis/{emoji}.webp"):
|
||||||
emoji_html = f'<span alt=":{old}:" data-bs-toggle="tooltip" title=":{old}:">{modifier_html}{emoji_partial_pat.format(old, f"{SITE_FULL_IMAGES}/e/{emoji}.webp", attrs)}</span>'
|
emoji_html = f'<span alt=":{old}:" data-bs-toggle="tooltip" title=":{old}:"{genocide_attr}>{modifier_html}{emoji_partial_pat.format(old, f"{SITE_FULL_IMAGES}/e/{emoji}.webp", attrs)}</span>'
|
||||||
elif is_user:
|
elif is_user:
|
||||||
if u := get_user(emoji[1:], graceful=True):
|
if u := get_user(emoji[1:], graceful=True):
|
||||||
emoji_html = f'<span alt=":{old}:" data-bs-toggle="tooltip" title=":{old}:">{modifier_html}{emoji_partial_pat.format(old, f"/pp/{u.id}", attrs)}</span>'
|
emoji_html = f'<span alt=":{old}:" data-bs-toggle="tooltip" title=":{old}:"{genocide_attr}>{modifier_html}{emoji_partial_pat.format(old, f"/pp/{u.id}", attrs)}</span>'
|
||||||
elif path.isfile(f'files/assets/images/emojis/{emoji}.webp'):
|
elif path.isfile(f'files/assets/images/emojis/{emoji}.webp'):
|
||||||
emoji_html = emoji_partial.format(old, f'{SITE_FULL_IMAGES}/e/{emoji}.webp', attrs)
|
emoji_html = emoji_partial.format(old, f'{SITE_FULL_IMAGES}/e/{emoji}.webp', attrs)
|
||||||
|
|
||||||
|
@ -634,6 +673,7 @@ def allowed_attributes_emojis(tag, name, value):
|
||||||
if name == 'data-bs-toggle' and value == 'tooltip': return True
|
if name == 'data-bs-toggle' and value == 'tooltip': return True
|
||||||
if name == 'title': return True
|
if name == 'title': return True
|
||||||
if name == 'alt': return True
|
if name == 'alt': return True
|
||||||
|
if name == 'cide' and not value: return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,10 @@
|
||||||
<input type="checkbox" id="emoji-sel-3" value="talking" class="emoji-postfix">
|
<input type="checkbox" id="emoji-sel-3" value="talking" class="emoji-postfix">
|
||||||
<label class="emoji-option" for="emoji-sel-3">Talking</label>
|
<label class="emoji-option" for="emoji-sel-3">Talking</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div style="display: inline" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Sends the emoji away">
|
||||||
|
<input type="checkbox" id="emoji-sel-4" value="genocide" class="emoji-postfix">
|
||||||
|
<label class="emoji-option" for="emoji-sel-4">Genocide</label>
|
||||||
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue