UNPKG

@portabletext/to-html

Version:
49 lines (40 loc) 1.22 kB
const allowedProtocols = ['http', 'https', 'mailto', 'tel'] const charMap: Record<string, string> = { '&': 'amp', '<': 'lt', '>': 'gt', '"': 'quot', "'": '#x27', } export function escapeHTML(str: string): string { return str.replace(/[&<>"']/g, (s) => `&${charMap[s]};`) } export function uriLooksSafe(uri: string): boolean { const url = (uri || '').trim() const first = url.charAt(0) // Allow hash-links, absolute paths and "same-protocol" (//foo.bar) URLs if (first === '#' || first === '/') { return true } // If the URL does not contain a `:`, allow it const colonIndex = url.indexOf(':') if (colonIndex === -1) { return true } // If the protocol is in the allowed list, treat it as OK const proto = url.slice(0, colonIndex).toLowerCase() if (allowedProtocols.indexOf(proto) !== -1) { return true } // If the URL is `site/search?query=author:espen`, allow it const queryIndex = url.indexOf('?') if (queryIndex !== -1 && colonIndex > queryIndex) { return true } // If the URL is `site/search#my:encoded:data`, allow it const hashIndex = url.indexOf('#') if (hashIndex !== -1 && colonIndex > hashIndex) { return true } return false }