diff --git a/packages/multiple-select-vanilla/src/MultipleSelectInstance.ts b/packages/multiple-select-vanilla/src/MultipleSelectInstance.ts index 194160f2..43006d53 100644 --- a/packages/multiple-select-vanilla/src/MultipleSelectInstance.ts +++ b/packages/multiple-select-vanilla/src/MultipleSelectInstance.ts @@ -18,6 +18,7 @@ import { getComputedSize, getOffset, getSize, + htmlDecode, insertAfter, toggleElement, } from './utils/domUtils.js'; @@ -1487,7 +1488,7 @@ export class MultipleSelectInstance { if (this.isRenderAsHtml) { elmOrProp.innerHTML = (typeof this.options.sanitizer === 'function' ? this.options.sanitizer(value) : value) as unknown as string; } else { - elmOrProp.textContent = value; + elmOrProp.textContent = htmlDecode(value); } } diff --git a/packages/multiple-select-vanilla/src/utils/domUtils.ts b/packages/multiple-select-vanilla/src/utils/domUtils.ts index 41e5d8ad..7a0e6eb3 100644 --- a/packages/multiple-select-vanilla/src/utils/domUtils.ts +++ b/packages/multiple-select-vanilla/src/utils/domUtils.ts @@ -1,5 +1,5 @@ import type { HtmlStruct, InferDOMType } from '../models/interfaces.js'; -import { objectRemoveEmptyProps } from './utils.js'; +import { isDefined, objectRemoveEmptyProps } from './utils.js'; export interface HtmlElementPosition { top: number; @@ -228,6 +228,23 @@ export function findParent(elm: HTMLElement, selector: string) { return targetElm; } +/** + * Simple function to decode the most common HTML entities. + * For example: "<div>Hablar español? ��</div>" => "
Hablar español? 🦄
" + * @param {String} inputValue - input value to be decoded + * @return {String} + */ +export function htmlDecode(input?: string | boolean | number): string { + if (isDefined(input)) { + // 1. decode html entities (e.g. `'` => single quote) + // 2. use textarea to decode the rest (e.g. html tags and symbols, `<div>` => `
`) + const txt = document.createElement('textarea'); + txt.innerHTML = input.toString().replace(/&#(\d+);/g, (_, dec) => String.fromCharCode(dec)); + return txt.value; + } + return ''; +} + export function insertAfter(referenceNode: HTMLElement, newNode: HTMLElement) { referenceNode.parentNode?.insertBefore(newNode, referenceNode.nextSibling); } diff --git a/packages/multiple-select-vanilla/src/utils/utils.ts b/packages/multiple-select-vanilla/src/utils/utils.ts index 0922a855..f3a08c08 100644 --- a/packages/multiple-select-vanilla/src/utils/utils.ts +++ b/packages/multiple-select-vanilla/src/utils/utils.ts @@ -33,8 +33,8 @@ export function deepCopy(obj: T): T { return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, deepCopy(value)])) as T; } -export function isDefined(val: any) { - return val !== undefined && val !== null && val !== ''; +export function isDefined(value: T | undefined | null): value is T { + return value !== undefined && value !== null && value !== ''; } /**