refactor(builder): use shared escaper everywhere, drop 26 local copies
Replace divergent, buggy local esc/escapeHtml helpers across 26 files with imports from src/utils/escape (escapeHtml/escapeAttr). Attribute call sites use escapeAttr, text-content sites use escapeHtml. Several toHtml outputs now correctly escape & where old local escapers omitted it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@ import { useNode, UserComponent } from '@craftjs/core';
|
||||
import { cssPropsToString } from '../../utils/style-helpers';
|
||||
import { usePages } from '../../state/PageContext';
|
||||
import { useSiteDesign } from '../../state/SiteDesignContext';
|
||||
import { escapeHtml, escapeAttr } from '../../utils/escape';
|
||||
|
||||
/* ---------- Types ---------- */
|
||||
|
||||
@@ -70,12 +71,6 @@ async function uploadToWhp(file: File): Promise<string | null> {
|
||||
} catch { return null; }
|
||||
}
|
||||
|
||||
/* ---------- Helper: escape HTML ---------- */
|
||||
function esc(str: any): string {
|
||||
str = String(str ?? "");
|
||||
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
||||
}
|
||||
|
||||
/* ---------- Component ---------- */
|
||||
|
||||
export const Navbar: UserComponent<NavbarProps> = ({
|
||||
@@ -853,7 +848,7 @@ Navbar.craft = {
|
||||
let logoHtml: string;
|
||||
if (props.logoType === 'image' && props.logoImage) {
|
||||
const imgStyle = cssPropsToString({ width: props.logoWidth || '120px', height: 'auto', display: 'block' });
|
||||
logoHtml = `<a href="${esc(logoUrl)}" style="text-decoration:none;display:flex;align-items:center;flex-shrink:0"><img src="${esc(props.logoImage)}" alt="${esc(props.logoText || 'Logo')}"${imgStyle ? ` style="${imgStyle}"` : ''} /></a>`;
|
||||
logoHtml = `<a href="${escapeAttr(logoUrl)}" style="text-decoration:none;display:flex;align-items:center;flex-shrink:0"><img src="${escapeAttr(props.logoImage)}" alt="${escapeAttr(props.logoText || 'Logo')}"${imgStyle ? ` style="${imgStyle}"` : ''} /></a>`;
|
||||
} else {
|
||||
const logoStyle = cssPropsToString({
|
||||
fontWeight: '700',
|
||||
@@ -861,7 +856,7 @@ Navbar.craft = {
|
||||
fontFamily: props.logoFontFamily || 'Inter, sans-serif',
|
||||
color: props.logoColor || textCol,
|
||||
});
|
||||
logoHtml = `<a href="${esc(logoUrl)}" style="text-decoration:none;display:flex;align-items:center;flex-shrink:0"><span${logoStyle ? ` style="${logoStyle}"` : ''}>${esc(props.logoText || 'MySite')}</span></a>`;
|
||||
logoHtml = `<a href="${escapeAttr(logoUrl)}" style="text-decoration:none;display:flex;align-items:center;flex-shrink:0"><span${logoStyle ? ` style="${logoStyle}"` : ''}>${escapeHtml(props.logoText || 'MySite')}</span></a>`;
|
||||
}
|
||||
|
||||
// Links HTML
|
||||
@@ -878,15 +873,15 @@ Navbar.craft = {
|
||||
borderRadius: link.isCta ? '6px' : '0',
|
||||
transition: 'color 0.15s, background-color 0.15s',
|
||||
});
|
||||
return `<a href="${esc(link.href)}"${target}${linkStyle ? ` style="${linkStyle}"` : ''}>${esc(link.text)}</a>`;
|
||||
return `<a href="${escapeAttr(link.href)}"${target}${linkStyle ? ` style="${linkStyle}"` : ''}>${escapeHtml(link.text)}</a>`;
|
||||
}).join('\n ');
|
||||
|
||||
// Hamburger HTML for mobile
|
||||
const hamburgerHtml = mobile
|
||||
? `\n <button class="navbar-hamburger" onclick="this.parentElement.querySelector('.navbar-links').classList.toggle('navbar-open')" style="display:none;background:none;border:none;cursor:pointer;padding:4px;flex-direction:column;gap:4px">
|
||||
<span style="display:block;width:24px;height:2px;background-color:${esc(textCol)}"></span>
|
||||
<span style="display:block;width:24px;height:2px;background-color:${esc(textCol)}"></span>
|
||||
<span style="display:block;width:24px;height:2px;background-color:${esc(textCol)}"></span>
|
||||
<span style="display:block;width:24px;height:2px;background-color:${escapeAttr(textCol)}"></span>
|
||||
<span style="display:block;width:24px;height:2px;background-color:${escapeAttr(textCol)}"></span>
|
||||
<span style="display:block;width:24px;height:2px;background-color:${escapeAttr(textCol)}"></span>
|
||||
</button>`
|
||||
: '';
|
||||
|
||||
@@ -915,7 +910,7 @@ Navbar.craft = {
|
||||
borderRadius: link.isCta ? '6px' : '0',
|
||||
transition: 'color 0.15s, background-color 0.15s',
|
||||
});
|
||||
return `<a href="${esc(link.href)}" class="${cls}"${target}${linkStyle ? ` style="${linkStyle}"` : ''}>${esc(link.text)}</a>`;
|
||||
return `<a href="${escapeAttr(link.href)}" class="${cls}"${target}${linkStyle ? ` style="${linkStyle}"` : ''}>${escapeHtml(link.text)}</a>`;
|
||||
}).join('\n ');
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user