UNPKG

@limetech/lime-elements

Version:
51 lines (50 loc) 1.98 kB
/** * Checks whether the given HTML contains any images with a `data-remote-src` * attribute, indicating they reference external (remote) resources. * * @param html - The HTML string to inspect. */ export function containsRemoteImages(html) { const parser = new DOMParser(); const document = parser.parseFromString(html, 'text/html'); return document.querySelector('img[data-remote-src]') !== null; } /** * If `allowRemoteImages` is `true`, replaces the `src` attribute of every * `<img data-remote-src="...">` element with the value of `data-remote-src` * (provided it points to an http(s) URL) and removes the data attribute. * * When `allowRemoteImages` is `false` the HTML is returned unchanged. * * Returns an HTML fragment that is safe to assign to `innerHTML` on a regular * container element (not a full `<html>/<head>/<body>` document string). * * @param html - The HTML string to process. * @param allowRemoteImages - Whether to restore remote image sources. */ export function applyRemoteImagesPolicy(html, allowRemoteImages) { if (!allowRemoteImages) { return html; } const parser = new DOMParser(); const document = parser.parseFromString(html, 'text/html'); const images = document.querySelectorAll('img[data-remote-src]'); for (const image of images) { const remoteSrc = image.dataset.remoteSrc; if (!remoteSrc || !isAllowedRemoteImageUrl(remoteSrc)) { delete image.dataset.remoteSrc; continue; } image.setAttribute('src', remoteSrc); delete image.dataset.remoteSrc; } const headStyles = [...document.head.querySelectorAll('style')] .map((style) => style.outerHTML) .join(''); return `${headStyles}${document.body.innerHTML}`; } function isAllowedRemoteImageUrl(url) { const trimmed = url.trim(); const lower = trimmed.toLowerCase(); return lower.startsWith('https://') || lower.startsWith('http://'); }