santitize, popup class

This commit is contained in:
_Bastler 2021-10-28 19:15:02 +02:00
parent 24ac439fa1
commit 7fb13cf54b
7 changed files with 43 additions and 19 deletions

View File

@ -13,6 +13,7 @@ export const isOpenPopupEvent = new tg.IsInterface()
targetObject: tg.isString, targetObject: tg.isString,
message: tg.isString, message: tg.isString,
buttons: tg.isArray(isButtonDescriptor), buttons: tg.isArray(isButtonDescriptor),
popupClass : tg.isString,
input: tg.isBoolean input: tg.isBoolean
}).get(); }).get();

View File

@ -85,7 +85,7 @@ export class WorkAdventureUiCommands extends IframeApiContribution<WorkAdventure
}), }),
]; ];
openPopup(targetObject: string, message: string, buttons: ButtonDescriptor[], input: boolean = false): Popup { openPopup(targetObject: string, message: string, buttons: ButtonDescriptor[], popupClass : string = "", input: boolean = false): Popup {
popupId++; popupId++;
const popup = new Popup(popupId); const popup = new Popup(popupId);
const btnMap = new Map<number, () => void>(); const btnMap = new Map<number, () => void>();
@ -113,6 +113,7 @@ export class WorkAdventureUiCommands extends IframeApiContribution<WorkAdventure
className: button.className, className: button.className,
}; };
}), }),
popupClass,
input input
}, },
}); });

View File

@ -1,24 +1,13 @@
<script lang="ts"> <script lang="ts">
import { layoutManagerActionStore } from "../../Stores/LayoutManagerStore"; import { layoutManagerActionStore } from "../../Stores/LayoutManagerStore";
const sanitizeHtml = require('sanitize-html'); import { HtmlUtils } from "../../WebRtc/HtmlUtils";
function onClick(callback: () => void) { function onClick(callback: () => void) {
callback(); callback();
} }
function sanitize(html : string | number | boolean | undefined) { function sanitize(html : string) {
return sanitizeHtml(html, { return HtmlUtils.sanitize(html);
allowedAttributes: {
'span': ['style'],
},
allowedStyles: {
'span': {
'color': [/^#(0x)?[0-9a-f]+$/i, /^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/],
'font-size': [/^\d+(?:px|em|%)$/]
}
}
});
} }
</script> </script>

View File

@ -97,6 +97,8 @@ import { analyticsClient } from "../../Administration/AnalyticsClient";
import { get } from "svelte/store"; import { get } from "svelte/store";
import { contactPageStore } from "../../Stores/MenuStore"; import { contactPageStore } from "../../Stores/MenuStore";
export interface GameSceneInitInterface { export interface GameSceneInitInterface {
initPosition: PointInterface | null; initPosition: PointInterface | null;
reconnecting: boolean; reconnecting: boolean;
@ -921,7 +923,7 @@ export class GameScene extends DirtyScene {
); );
return; return;
} }
const escapedMessage = HtmlUtils.escapeHtml(openPopupEvent.message); const escapedMessage = HtmlUtils.sanitize(openPopupEvent.message);
let html = `<div id="container" hidden><div class="nes-container with-title is-centered">`; let html = `<div id="container" hidden><div class="nes-container with-title is-centered">`;
html += escapedMessage; html += escapedMessage;
if (openPopupEvent.input) { if (openPopupEvent.input) {
@ -943,7 +945,7 @@ export class GameScene extends DirtyScene {
const container: HTMLDivElement = domElement.getChildByID("container") as HTMLDivElement; const container: HTMLDivElement = domElement.getChildByID("container") as HTMLDivElement;
container.style.width = objectLayerSquare.width + "px"; container.style.width = objectLayerSquare.width + "px";
domElement.scale = 0; domElement.scale = 0;
domElement.setClassName("popUpElement"); domElement.setClassName("popUpElement " + openPopupEvent.popupClass ?? "");
setTimeout(() => { setTimeout(() => {
container.hidden = false; container.hidden = false;

View File

@ -1,3 +1,5 @@
const sanitizeHtml = require('sanitize-html');
export class HtmlUtils { export class HtmlUtils {
public static getElementByIdOrFail<T extends HTMLElement>(id: string): T { public static getElementByIdOrFail<T extends HTMLElement>(id: string): T {
const elem = document.getElementById(id); const elem = document.getElementById(id);
@ -31,6 +33,20 @@ export class HtmlUtils {
return p.innerHTML; return p.innerHTML;
} }
public static sanitize(html : string) {
return sanitizeHtml(html, {
allowedAttributes: {
'span': ['style'],
},
allowedStyles: {
'span': {
'color': [/^#(0x)?[0-9a-f]+$/i, /^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/],
'font-size': [/^\d+(?:px|em|%)$/]
}
}
});
}
public static urlify(text: string, style: string = ""): string { public static urlify(text: string, style: string = ""): string {
const urlRegex = /(https?:\/\/[^\s]+)/g; const urlRegex = /(https?:\/\/[^\s]+)/g;
text = HtmlUtils.escapeHtml(text); text = HtmlUtils.escapeHtml(text);

View File

@ -146,9 +146,9 @@ const wa = {
/** /**
* @deprecated Use WA.ui.openPopup instead * @deprecated Use WA.ui.openPopup instead
*/ */
openPopup(targetObject: string, message: string, buttons: ButtonDescriptor[], input : boolean): Popup { openPopup(targetObject: string, message: string, buttons: ButtonDescriptor[], popupClass : string, input : boolean): Popup {
console.warn('Method WA.openPopup is deprecated. Please use WA.ui.openPopup instead'); console.warn('Method WA.openPopup is deprecated. Please use WA.ui.openPopup instead');
return ui.openPopup(targetObject, message, buttons, input); return ui.openPopup(targetObject, message, buttons, popupClass, input);
}, },
/** /**
* @deprecated Use WA.chat.onChatMessage instead * @deprecated Use WA.chat.onChatMessage instead

View File

@ -1117,3 +1117,18 @@ div.is-silent.hide {
.emote-menu .emoji-picker .emoji-picker__emoji { .emote-menu .emoji-picker .emoji-picker__emoji {
font-family: "Twemoji Mozilla" !important; font-family: "Twemoji Mozilla" !important;
} }
.popUpElement.overlay-text {
div {
background: none;
.nes-container {
font-size: 10px;
color: #000;
background: none;
border: none;
}
}
}