bugfix: rendering player with twemojis in eventsdisplay

This commit is contained in:
Evan
2024-11-09 12:02:55 -08:00
parent 5c5423ef31
commit 3de73e665b
2 changed files with 38 additions and 12 deletions
+5 -2
View File
@@ -16,6 +16,7 @@ import {
import { ClientID } from "../../../core/Schemas";
import { Layer } from "./Layer";
import { SendAllianceReplyIntentEvent } from "../../Transport";
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
export enum MessageType {
SUCCESS,
@@ -34,6 +35,7 @@ export class DisplayMessageEvent implements GameEvent {
interface Event {
description: string;
unsafeDescription?: boolean
buttons?: {
text: string;
className: string;
@@ -313,7 +315,8 @@ export class EventsDisplay extends LitElement implements Layer {
});
} else if (event.message.sender === myPlayer && event.message.recipient !== AllPlayers) {
this.addEvent({
description: `Sent ${event.message.recipient.displayName()} ${event.message.emoji}`,
description: `Sent ${event.message.recipient.displayName()}: ${event.message.emoji}`,
unsafeDescription: true,
type: MessageType.INFO,
highlight: true,
createdAt: this.game.ticks(),
@@ -332,7 +335,7 @@ export class EventsDisplay extends LitElement implements Layer {
${this.events.map((event, index) => html`
<tr class="${event.highlight ? 'highlight' : ''} ${MessageType[event.type].toLowerCase()}">
<td>
${event.description}
${event.unsafeDescription ? unsafeHTML(event.description) : event.description}
${event.buttons ? html`
<div class="button-container">
${event.buttons.map(btn => html`
+33 -10
View File
@@ -149,16 +149,39 @@ export function sanitize(name: string): string {
export function processName(name: string): string {
// First sanitize the raw input - strip everything except text and emojis
const withEmojis = twemoji.parse(sanitize(name), {
base: 'https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/', // Use jsDelivr CDN
folder: 'svg', // or 'png' if you prefer
ext: '.svg' // or '.png' if you prefer
});
return DOMPurify.sanitize(withEmojis, {
ALLOWED_TAGS: ['img'],
ALLOWED_ATTR: ['src', 'alt', 'class'],
// Only allow twemoji CDN URLs
ALLOWED_URI_REGEXP: /^https:\/\/cdn\.jsdelivr\.net\/gh\/twitter\/twemoji/
const sanitizedName = sanitize(name);
// Process emojis with twemoji
const withEmojis = twemoji.parse(sanitizedName, {
base: 'https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/',
folder: 'svg',
ext: '.svg'
});
// Add CSS styles inline to the wrapper span
const styledHTML = `
<span class="player-name" style="
display: inline-flex;
align-items: center;
gap: 0.25rem;
font-weight: 500;
vertical-align: middle;
">
${withEmojis}
</span>
`;
// Add CSS for the emoji images
const withEmojiStyles = styledHTML.replace(
/<img/g,
'<img style="height: 1.2em; width: 1.2em; vertical-align: -0.2em; margin: 0 0.05em 0 0.1em;"'
);
// Sanitize the final HTML, allowing styles and specific attributes
return DOMPurify.sanitize(withEmojiStyles, {
ALLOWED_TAGS: ['span', 'img'],
ALLOWED_ATTR: ['src', 'alt', 'class', 'style'],
ALLOWED_URI_REGEXP: /^https:\/\/cdn\.jsdelivr\.net\/gh\/twitter\/twemoji/,
ADD_ATTR: ['style']
});
}