All files / scripts/generate-news-indexes/template/client-script-runtime helpers.ts

100% Statements 1/1
100% Branches 0/0
100% Functions 0/0
100% Lines 1/1

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                        7x                                                                                
/**
 * @module generate-news-indexes/template/client-script-runtime/helpers
 * @description Pure utility helpers (XSS escape, safe href, i18n template
 * interpolation) — emitted as a string fragment into the inline `<script>`
 * body. Keep small: this is a CSP-relevant surface per
 * `Secure_Development_Policy.md`.
 *
 * @author Hack23 AB
 * @license Apache-2.0
 */
 
/** Helper functions (escape / safe href / i18n template). */
export const HELPER_FUNCTIONS = `
    // HTML-escape helper to prevent XSS when interpolating article fields into innerHTML
    function esc(str) {
      return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;');
    }
 
    function safeHref(slug) {
      var s = String(slug);
      // Allow relative HTML paths including subdirectory articles (e.g. "2026-05-04-election-cycle/current-en.html").
      // Block control chars, backslashes, and protocol-relative URLs.
      if (!s || /[\\\\\\x00-\\x1F\\x7F]/.test(s) || s.indexOf('//') === 0) {
        return '#';
      }
      if (!/^[A-Za-z0-9._/-]+\\.html$/.test(s)) {
        return '#';
      }
      return esc(s);
    }
 
    function i18nShowing(shown, total) {
      var template;
      if (i18nShowingConfig && typeof i18nShowingConfig === 'object') {
        if (shown === 1 && Object.prototype.hasOwnProperty.call(i18nShowingConfig, 'one')) {
          template = i18nShowingConfig.one;
        } else if (Object.prototype.hasOwnProperty.call(i18nShowingConfig, 'other')) {
          template = i18nShowingConfig.other;
        } else {
          template = String(i18nShowingConfig);
        }
      } else {
        template = i18nShowingConfig || '';
      }
      if (typeof template !== 'string') {
        template = String(template);
      }
      return template
        .replace('{shown}', String(shown))
        .replace('{total}', String(total));
    }
`;