All files / packages/design-system-2-site/src/lib markdown-legacy.ts

95.45% Statements 21/22
78.94% Branches 15/19
100% Functions 4/4
100% Lines 18/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62                    15x       8x     10x 10x             10x 10x     1x           74x 10x 10x   4x 3x       4x 4x 4x 1x 4x                 1x        
/**
 * Content formats carried over from the Zeroheight / CMS export that aren't
 * remark directives, so they're handled as a string pass after the unified
 * pipeline:
 *
 *   <div data-directive-type="hero-banner|video-embed"   expanded into the
 *        data-directive-attrs="{json}" ...></div>        class-based markup the CSS expects
 */
 
function escapeHtml(s: string): string {
  return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
}
 
const DATA_DIRECTIVE_RE =
  /<div\s+data-directive-type="([^"]+)"\s+data-directive-attrs="([^"]*)"\s+data-directive-children="([^"]*)"[^>]*>\s*<\/div>/g;
 
function parseJsonAttr(type: string, encoded: string): Record<string, string> {
  Iif (!encoded) return {};
  const decoded = encoded
    .replace(/&quot;/g, '"')
    .replace(/&amp;/g, '&')
    .replace(/&lt;/g, '<')
    .replace(/&gt;/g, '>')
    .replace(/&#39;/g, "'")
    .replace(/&#x27;/g, "'");
  try {
    return JSON.parse(decoded);
  } catch (error) {
    // Fail the build: an empty fallback would drop the embed or blank the banner.
    throw new Error(`Invalid data-directive-attrs on a "${type}" directive: ${decoded}`, { cause: error });
  }
}
 
/** Expand `data-directive-type` divs in rendered HTML. Unknown types pass through. */
export function renderDataDirectives(html: string): string {
  return html.replace(DATA_DIRECTIVE_RE, (match, type: string, attrsEncoded: string) => {
    const attrs = parseJsonAttr(type, attrsEncoded);
    switch (type) {
      case 'video-embed': {
        if (!attrs.src) return '';
        return `<div class="video-embed"><div class="video-embed__wrapper"><video controls preload="metadata"><source src="${escapeHtml(attrs.src)}" type="video/mp4"></video></div></div>`;
      }
      case 'hero-banner': {
        // Children are only <h1> / <p> (no nested <div>): `extractLeadingHero` relies on it.
        const { title, image, gradient, version, updated, tagline } = attrs;
        let style = '';
        if (image) style = ` style="background-image:url(${escapeHtml(image)})"`;
        else Eif (gradient) style = ` style="background-image:${escapeHtml(gradient)}"`;
        return (
          `<div class="hero-banner"${style}><h1>${escapeHtml(title || '')}</h1>` +
          (version ? `<p class="hero-banner__version">${escapeHtml(version)}</p>` : '') +
          (updated ? `<p class="hero-banner__updated">${escapeHtml(updated)}</p>` : '') +
          (tagline ? `<p class="hero-banner__tagline">${escapeHtml(tagline)}</p>` : '') +
          '</div>'
        );
      }
      default:
        return match;
    }
  });
}