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:
@@ -2,6 +2,7 @@ import React, { CSSProperties } from 'react';
|
||||
import { useNode, UserComponent } from '@craftjs/core';
|
||||
import { cssPropsToString } from '../../utils/style-helpers';
|
||||
import { AnchorIdField } from '../../ui/AnchorIdField';
|
||||
import { escapeHtml, escapeAttr } from '../../utils/escape';
|
||||
|
||||
interface PricingPlan {
|
||||
name: string;
|
||||
@@ -404,13 +405,12 @@ PricingTable.craft = {
|
||||
/* ---------- HTML export ---------- */
|
||||
|
||||
(PricingTable as any).toHtml = (props: PricingTableProps, _childrenHtml: string) => {
|
||||
const esc = (s: any) => String(s ?? "").replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
||||
const bulletType = props.bulletType || 'check';
|
||||
const sectionStyle = cssPropsToString({
|
||||
padding: '80px 20px',
|
||||
...props.style,
|
||||
});
|
||||
const idAttr = props.anchorId ? ` id="${esc(props.anchorId)}"` : '';
|
||||
const idAttr = props.anchorId ? ` id="${escapeAttr(props.anchorId)}"` : '';
|
||||
const plans = props.plans || defaultPlans;
|
||||
const featuredBg = props.featuredBg || '#3b82f6';
|
||||
|
||||
@@ -427,7 +427,7 @@ PricingTable.craft = {
|
||||
const shadow = plan.isFeatured ? 'box-shadow:0 20px 60px rgba(59,130,246,0.3);' : 'box-shadow:0 1px 3px rgba(0,0,0,0.06);';
|
||||
|
||||
const featuresHtml = (Array.isArray(plan.features) ? plan.features : []).map((f) =>
|
||||
`<li style="font-size:14px;color:${featColor};display:flex;align-items:center;gap:8px"><span style="color:${checkColor};font-weight:700">${bulletChars[bulletType] || '✓'}</span>${esc(f)}</li>`
|
||||
`<li style="font-size:14px;color:${featColor};display:flex;align-items:center;gap:8px"><span style="color:${checkColor};font-weight:700">${bulletChars[bulletType] || '✓'}</span>${escapeHtml(f)}</li>`
|
||||
).join('\n ');
|
||||
|
||||
const badge = plan.isFeatured
|
||||
@@ -436,15 +436,15 @@ PricingTable.craft = {
|
||||
|
||||
return `<div style="flex:1 1 280px;max-width:360px;background-color:${cardBg};${cardBorder}border-radius:16px;padding:40px 32px;display:flex;flex-direction:column;align-items:center;text-align:center;position:relative;${scale}${shadow}">
|
||||
${badge}
|
||||
<h3 style="font-size:20px;font-weight:600;color:${textColor};margin-bottom:8px;${plan.isFeatured ? 'margin-top:8px;' : ''}">${esc(plan.name)}</h3>
|
||||
<h3 style="font-size:20px;font-weight:600;color:${textColor};margin-bottom:8px;${plan.isFeatured ? 'margin-top:8px;' : ''}">${escapeHtml(plan.name)}</h3>
|
||||
<div style="margin-bottom:24px">
|
||||
<span style="font-size:48px;font-weight:700;color:${textColor};line-height:1">${esc(plan.price)}</span>
|
||||
<span style="font-size:16px;color:${subColor}">${esc(plan.period)}</span>
|
||||
<span style="font-size:48px;font-weight:700;color:${textColor};line-height:1">${escapeHtml(plan.price)}</span>
|
||||
<span style="font-size:16px;color:${subColor}">${escapeHtml(plan.period)}</span>
|
||||
</div>
|
||||
<ul style="list-style:none;padding:0;margin:0 0 32px 0;width:100%;display:flex;flex-direction:column;gap:12px">
|
||||
${featuresHtml}
|
||||
</ul>
|
||||
<a href="${plan.buttonHref || '#'}" style="margin-top:auto;display:inline-block;padding:14px 32px;background-color:${btnBg};color:${btnColor};text-decoration:none;border-radius:8px;font-weight:600;font-size:14px;width:100%;text-align:center">${esc(plan.buttonText)}</a>
|
||||
<a href="${plan.buttonHref || '#'}" style="margin-top:auto;display:inline-block;padding:14px 32px;background-color:${btnBg};color:${btnColor};text-decoration:none;border-radius:8px;font-weight:600;font-size:14px;width:100%;text-align:center">${escapeHtml(plan.buttonText)}</a>
|
||||
</div>`;
|
||||
}).join('\n ');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user