Stored pages (generated at editor-save time) from before release 2026.11.5 carry FeaturesGrid / Testimonials / NumberCounter grids without data-wsb-grid, so a republish kept repeat(N,1fr) on phones (OLS home: body 594px wide at 360). The <=767px block now matches the exact inline styles those emitters stored (whole-attribute signatures; no spaces, as in git history and every stored OLS/TTM page). Gallery shares the prefix with a free gap and keeps its columns: the two colliding signatures carry :not(:has(> * > Gallery thumbnail)) in their own rule (a browser without :has drops only that rule). Customer grids never match. Mirrored byte-for-byte by WHP generateCompiledHTML (fix/legacy-grid-backend). Tests: vitest selector contract (legacy shapes match, == current emitters minus the hook, Gallery and customer grids never match, pretty == minified); head parity pins updated; new real-browser suite test:browser:legacy-grid (Chromium + Firefox, 360/390/768/1280) on the stored OLS home page + synthetic legacy grids; colors suite folds the new rules back like the mobile-guard ones. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
52 lines
3.5 KiB
TypeScript
52 lines
3.5 KiB
TypeScript
// Bundled (browser IIFE) by scripts/e2e-legacy-grid.mjs. Builds published documents from LEGACY stored HTML
|
|
// (pages saved before the data-wsb-grid hook existed) wrapped in the REAL Preview/publish head
|
|
// (exportComposedPreviewHtml: header + page + footer, as WHP handlePublish composes them; the head is byte-identical
|
|
// to WHP generateCompiledHTML, pinned on both sides by the head-parity tests).
|
|
import { exportBodyHtml, exportComposedPreviewHtml, RESPONSIVE_CSS_MINIFIED } from '../src/utils/html-export';
|
|
import { componentResolver } from '../src/components/resolver';
|
|
import olsHeader from '../tests/fixtures/legacy-grid/ols.header.html';
|
|
import olsIndex from '../tests/fixtures/legacy-grid/ols.index.html';
|
|
import olsFooter from '../tests/fixtures/legacy-grid/ols.footer.html';
|
|
import olsDesign from '../tests/fixtures/legacy-grid/ols.design.json';
|
|
|
|
type N = Record<string, any>;
|
|
const EMPTY = JSON.stringify({ ROOT: { type: { resolvedName: 'Container' }, isCanvas: true, props: { tag: 'div', style: {} }, displayName: 'Container', custom: {}, hidden: false, nodes: [], linkedNodes: {} } });
|
|
const defaults = (type: string): Record<string, unknown> => {
|
|
const c = (componentResolver as any)[type];
|
|
return c?.craft?.props ? JSON.parse(JSON.stringify(c.craft.props)) : {};
|
|
};
|
|
const node = (type: string, props: Record<string, unknown>, extra: N = {}) => ({
|
|
type: { resolvedName: type }, isCanvas: type === 'Container', props: { ...defaults(type), ...props }, displayName: type,
|
|
custom: {}, hidden: false, nodes: [], linkedNodes: {}, ...extra,
|
|
});
|
|
const stripHook = (html: string) => html.replace(/ data-wsb-grid(="")?/g, '');
|
|
const doc = (body: string, title: string) => exportComposedPreviewHtml(EMPTY, body, { title, design: olsDesign as any });
|
|
|
|
/** Every card-grid emitter in its stored (pre-hook) form, Galleries whose gap collides with a card-grid
|
|
* signature, and an unwrapped customer grid (legacy HtmlBlock content has no data-wsb-html wrapper). */
|
|
function synthetic(): string {
|
|
const nodes: N = {};
|
|
const kids: string[] = [];
|
|
const add = (id: string, type: string, props: Record<string, unknown> = {}) => { nodes[id] = node(type, props, { parent: 'ROOT' }); kids.push(id); };
|
|
add('features', 'FeaturesGrid');
|
|
add('t2', 'Testimonials', { columns: 2 });
|
|
add('t3', 'Testimonials');
|
|
add('t4', 'Testimonials', { columns: 4 });
|
|
add('counter', 'NumberCounter', { columns: 4 });
|
|
add('gal', 'Gallery');
|
|
add('gal32', 'Gallery', { columns: 3, gap: '32px', lightbox: true });
|
|
add('gal24', 'Gallery', { columns: 4, gap: '24px' });
|
|
nodes.ROOT = node('Container', { tag: 'div', style: {} }, { nodes: kids });
|
|
const body = stripHook(exportBodyHtml(JSON.stringify(nodes)).html);
|
|
const customer = '<div id="customer" style="padding:16px"><div style="display:grid;grid-template-columns:repeat(3,1fr);gap:32px"><div>One</div><div>Two</div><div>Three</div></div></div>';
|
|
return olsHeader + '\n' + body + customer + '\n' + olsFooter;
|
|
}
|
|
|
|
(window as any).wsbLegacyGridDocs = (): Record<string, string> => ({
|
|
ols: doc(olsHeader + '\n' + olsIndex + '\n' + olsFooter, 'Home'),
|
|
// The same page as a re-save in 2026.11.5 would store it (hook added): phones must look identical.
|
|
olsResaved: doc(olsHeader + '\n' + olsIndex.replace('<div style="max-width:1100px;margin:0 auto;display:grid;', '<div data-wsb-grid style="max-width:1100px;margin:0 auto;display:grid;') + '\n' + olsFooter, 'Home'),
|
|
synthetic: doc(synthetic(), 'Legacy grids'),
|
|
});
|
|
(window as any).wsbResponsiveCss = RESPONSIVE_CSS_MINIFIED;
|