{"version":3,"file":"text-content.mjs","sources":["../../../../src/text-content/text-content.ts","../../../../src/text-content/glossary-field-separator.ts"],"sourcesContent":["import { LitElement } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport type { Listener } from '@vanguard/placeholders';\nimport { placeholders } from '@vanguard/placeholders';\nimport { registerAllLoadersWeb } from '@vanguard/placeholders-loaders-common';\nimport {\n  findParentOrganism,\n  setOrganismError,\n  clearOrganismError,\n  setOrganismLoading,\n  clearOrganismLoading,\n} from '../core/organism';\nimport { isSafeRefPath } from '../core/utils';\nimport { GLOSSARY_FIELD_SEPARATOR } from './glossary-field-separator';\nimport { wrapAnchorAsLinkCta, type LinkCtaAttributes } from '../call-to-action/v2/link-cta';\nimport '../footnote-marker';\nimport Env from '@/env';\n\nregisterAllLoadersWeb(Env.ENV === 'prod');\n\n// The only element tags allowed inside rich-mode content.\nconst RICH_ALLOWED_TAGS = new Set([\n  'p', 'b', 'i', 'em', 'strong', 'ul', 'ol', 'li', 'a', 'span', 'br', 'sup'\n]);\n\n// Allowed attributes per tag. '*' applies to all tags.\nconst RICH_ALLOWED_ATTRIBUTES: Record<string, (attr: string) => boolean> = {\n  '*': (attr) => attr === 'class' || attr === 'id' || attr.startsWith('data-'),\n  'a': (attr) => attr === 'href' || attr === 'target' || attr === 'rel' || attr === 'dialog' || attr === 'term' || attr === 'definition',\n};\n\nexport type TextContentFormat = 'none' | 'plain' | 'rich';\n\nexport class TextContentError extends Error {\n  constructor(message: string) {\n    super(message);\n    this.name = 'TextContentError';\n  }\n}\n\n/**\n * Recursively validates that only RICH_ALLOWED_TAGS are present.\n * Returns false if any disallowed tag is found.\n * THIS IS NOT A SECURITY FEATURE - ONLY ENSURES CORRECT TEXT FORMAT\n */\nfunction sanitizeRichText(node: Node): boolean {\n  for (const child of Array.from(node.childNodes)) {\n    if (child.nodeType !== Node.ELEMENT_NODE) continue;\n    const el = child as Element;\n    const tag = el.tagName.toLowerCase();\n    if (!RICH_ALLOWED_TAGS.has(tag)) return false;\n    for (const attr of Array.from(el.attributes)) {\n      if (!RICH_ALLOWED_ATTRIBUTES['*']?.(attr.name) && !RICH_ALLOWED_ATTRIBUTES[tag]?.(attr.name)) {\n        el.removeAttribute(attr.name);\n      }\n    }\n    if (!sanitizeRichText(el)) return false;\n  }\n  return true;\n}\n\nfunction replaceAnchorsWithCta(root: Element): void {\n  for (const anchor of Array.from(root.querySelectorAll('a'))) {\n    if (anchor.closest('span[data-type]')) continue;\n    const attributes: LinkCtaAttributes = {};\n    for (const name of ['dialog', 'term', 'definition'] as const) {\n      const value = anchor.getAttribute(name);\n      if (value !== null) attributes[name] = value;\n      anchor.removeAttribute(name);\n    }\n    wrapAnchorAsLinkCta(anchor, attributes);\n  }\n}\n\nfunction replaceFootnoteSpansWithMarkers(root: Element): void {\n  for (const span of Array.from(root.querySelectorAll('span[data-type=\"footnote\"]'))) {\n    const marker = span.ownerDocument.createElement('pips-v1-footnote-marker');\n    if (span.getAttribute('data-proximity') === 'true') {\n      marker.setAttribute('proximity', '');\n    }\n    const ref = span.getAttribute('data-refs');\n    if (ref) marker.setAttribute('data-refs', ref);\n    span.replaceWith(marker);\n  }\n}\n\n// The ref is stashed on an attribute (not validated here) since this runs on a detached\n// document; the element itself won't survive serialization back into innerHTML.\nfunction replaceGlossarySpansWithCta(root: Element): void {\n  for (const span of Array.from(root.querySelectorAll('span[data-type=\"glossary\"]'))) {\n    // This cta always renders as <a role=\"button\">, so nesting it with any other interactive\n    // element produces invalid nested-interactive HTML.\n    if (\n      span.querySelector('a, span[data-type=\"glossary\"], pips-v1-footnote-marker') ||\n      span.closest('a, pips-v2-call-to-action, pips-v1-footnote-marker')\n    ) {\n      throw new TextContentError(\n        `[pips-v1-text-content] rich mode: a glossary term cannot be nested with another interactive element.`\n      );\n    }\n    const anchor = span.ownerDocument.createElement('a');\n    anchor.append(...Array.from(span.childNodes));\n    const cta = wrapAnchorAsLinkCta(anchor, { dialog: '' }, span);\n    // Always set, even to '', so resolveGlossaryReferences errors on an absent ref rather than skipping it.\n    cta.setAttribute('data-glossary-ref', span.getAttribute('data-refs') ?? '');\n  }\n}\n\n@customElement('pips-v1-text-content')\nexport class TextContent extends LitElement {\n  @property({ type: String, reflect: true })\n  format: TextContentFormat = 'none';\n\n  private rawInput = '';\n  private placeholdersListener: Listener<string> | null = null;\n  private organism: Element | null = null;\n  // Tracks each glossary cta's listener so disconnect/re-resolution can stop it and clear its\n  // organism loading/error state - otherwise a discarded cta lingers in the organism forever.\n  private glossaryResolutions: { source: Element; listener: Listener<string> | null }[] = [];\n\n  override createRenderRoot() {\n    return this;\n  }\n\n  override connectedCallback(): void {\n    super.connectedCallback();\n    this.organism = findParentOrganism(this);\n    if (!this.rawInput) {\n      // Plain mode assigns the captured string straight to textContent, so capture text:\n      // innerHTML re-escapes &, <, > and U+00A0, which would then render as entity text.\n      this.rawInput =\n        this.format === 'plain' ? (this.textContent ?? '') : this.innerHTML;\n    }\n    this.innerHTML = '';\n\n    // Pending until the listener first resolves or errors; the organism times out a\n    // permanently-stuck load. Set before creating the listener since it may fire\n    // synchronously during registration.\n    setOrganismLoading(this.organism, this);\n    this.placeholdersListener = placeholders\n      .template(this.rawInput)\n      .onError((err) => this.handleError(err))\n      .onChange((resolved) => {\n        try {\n          this.applyContent(resolved);\n        } catch (err) {\n          this.handleError(err instanceof Error ? err : new Error(String(err)));\n        }\n      });\n  }\n\n  override disconnectedCallback(): void {\n    super.disconnectedCallback();\n    this.placeholdersListener?.stop();\n    this.placeholdersListener = null;\n    this.clearGlossaryResolutions();\n    clearOrganismError(this.organism, this);\n    clearOrganismLoading(this.organism, this);\n    this.organism = null;\n  }\n\n  private handleError(_err: Error): void {\n    // Also covers a synchronous throw reaching here uncaught, so eagerly-registered CTAs get cleared.\n    this.clearGlossaryResolutions();\n    clearOrganismLoading(this.organism, this);\n    setOrganismError(this.organism, this);\n  }\n\n  private applyContent(html: string): void {\n    // Stop any listeners from a previous run before this one creates its own.\n    this.clearGlossaryResolutions();\n\n    if (this.format === 'none') {\n      clearOrganismLoading(this.organism, this);\n      clearOrganismError(this.organism, this);\n      this.innerHTML = html;\n      return;\n    }\n\n    if (this.format === 'plain') {\n      clearOrganismLoading(this.organism, this);\n      clearOrganismError(this.organism, this);\n      this.textContent = html;\n      return;\n    }\n\n    if (this.format === 'rich') {\n      const parser = new DOMParser();\n      const doc = parser.parseFromString(html, 'text/html');\n      const body = doc.body;\n      // May throw (disallowed tag/nested link) - caught by the onChange wrapper above, via handleError().\n      this.innerHTML = this.processRichText(body);\n      // Must register glossary loading before clearing this component's own loading source, or\n      // the organism could settle before the glossary CTAs are registered.\n      this.resolveGlossaryReferences();\n      return;\n    }\n\n    // Unrecognized format (no runtime validation against the TextContentFormat union) -\n    // clear rather than leave this component's loading source registered indefinitely.\n    clearOrganismLoading(this.organism, this);\n    clearOrganismError(this.organism, this);\n  }\n\n  private processRichText(body: HTMLElement): string {\n    if (!sanitizeRichText(body)) {\n      throw new TextContentError(\n        `[pips-v1-text-content] rich mode: content contains an element not allowed in rich text.`\n      );\n    }\n    // Sanitization and validation runs first to decouple durable rich text format from add-on web UI feature implementation specifics.\n    replaceAnchorsWithCta(body);\n    replaceFootnoteSpansWithMarkers(body);\n    replaceGlossarySpansWithCta(body);\n    return body.innerHTML;\n  }\n\n  // Finds the glossary CTA shells replaceGlossarySpansWithCta left in the live DOM (after\n  // innerHTML assignment - element references from the detached parse don't survive that\n  // serialization) and resolves each one's term/definition from its content fragment.\n  private resolveGlossaryReferences(): void {\n    const entries = Array.from(\n      this.querySelectorAll('pips-v2-call-to-action[data-glossary-ref]')\n    ).map((cta) => {\n      const ref = cta.getAttribute('data-glossary-ref');\n      cta.removeAttribute('data-glossary-ref');\n      return { cta, ref };\n    });\n\n    // Registered up front, before the sequential chain below reaches each entry, so an\n    // interruption mid-chain still leaves every entry clearable.\n    for (const { cta } of entries) {\n      setOrganismLoading(this.organism, cta);\n      this.glossaryResolutions.push({ source: cta, listener: null });\n    }\n    clearOrganismLoading(this.organism, this);\n    clearOrganismError(this.organism, this);\n\n    // Resolved one ref at a time - the CF loader locks its whole `cf` namespace per fetch, so\n    // concurrent calls for different refs would silently drop. Cached by ref (null = errored)\n    // so a repeated ref reuses the result instead of re-fetching.\n    const resolvedByRef = new Map<string, { term: string; definition: string } | null>();\n    let index = 0;\n    const resolveNext = (): void => {\n      if (index >= entries.length) {\n        return;\n      }\n      const { cta, ref } = entries[index];\n      const resolutionEntry = this.glossaryResolutions[index];\n      index++;\n\n      if (!ref || !isSafeRefPath(ref)) {\n        // Mirrors resolveRef: an unsafe/malformed ref errors immediately, no fetch attempted.\n        clearOrganismLoading(this.organism, cta);\n        setOrganismError(this.organism, cta);\n        resolveNext();\n        return;\n      }\n\n      if (resolvedByRef.has(ref)) {\n        const cached = resolvedByRef.get(ref);\n        clearOrganismLoading(this.organism, cta);\n        if (cached) {\n          clearOrganismError(this.organism, cta);\n          cta.setAttribute('term', cached.term);\n          cta.setAttribute('definition', cached.definition);\n        } else {\n          setOrganismError(this.organism, cta);\n        }\n        resolveNext();\n        return;\n      }\n\n      // `${cf.<ref>.ref}` seed expressions resolve recursively, so this wrapping works whether\n      // `ref` is a bare path or already a `${cf.<path>.ref}` expression - same as resolveRef.\n      const template =\n        `\\${cf.${ref}.term}${GLOSSARY_FIELD_SEPARATOR}\\${cf.${ref}.dictionaryDefinition}`;\n      // onChange can fire more than once (e.g. revalidation) - only the first firing advances.\n      let advanced = false;\n      const advanceOnce = (): void => {\n        if (advanced) {\n          return;\n        }\n        advanced = true;\n        resolveNext();\n      };\n      const listener = placeholders\n        .template(template)\n        .onError(() => {\n          clearOrganismLoading(this.organism, cta);\n          setOrganismError(this.organism, cta);\n          resolvedByRef.set(ref, null);\n          advanceOnce();\n        })\n        .onChange((resolved) => {\n          clearOrganismLoading(this.organism, cta);\n          // Exactly one separator expected - any other count is ambiguous (a stray U+001F in\n          // term/definition would produce 2+), so this errors rather than guessing the split.\n          const parts = resolved.split(GLOSSARY_FIELD_SEPARATOR);\n          if (parts.length !== 2) {\n            setOrganismError(this.organism, cta);\n            resolvedByRef.set(ref, null);\n          } else {\n            clearOrganismError(this.organism, cta);\n            cta.setAttribute('term', parts[0]);\n            cta.setAttribute('definition', parts[1]);\n            resolvedByRef.set(ref, { term: parts[0], definition: parts[1] });\n          }\n          advanceOnce();\n        });\n      resolutionEntry.listener = listener;\n    };\n    resolveNext();\n  }\n\n  private clearGlossaryResolutions(): void {\n    for (const { source, listener } of this.glossaryResolutions) {\n      listener?.stop();\n      clearOrganismLoading(this.organism, source);\n      clearOrganismError(this.organism, source);\n    }\n    this.glossaryResolutions = [];\n  }\n}\n","// Split out so text-content.ts's export surface (re-exported wholesale by index.ts) doesn't\n// leak this implementation-detail sentinel into the package's public API.\nexport const GLOSSARY_FIELD_SEPARATOR = '\\u001F';\n"],"names":["registerAllLoadersWeb","Env","ENV","RICH_ALLOWED_TAGS","Set","RICH_ALLOWED_ATTRIBUTES","attr","startsWith","a","TextContentError","Error","message","super","this","name","sanitizeRichText","node","child","Array","from","childNodes","nodeType","Node","ELEMENT_NODE","el","tag","tagName","toLowerCase","has","attributes","removeAttribute","TextContent","LitElement","arguments","format","rawInput","placeholdersListener","organism","glossaryResolutions","createRenderRoot","connectedCallback","findParentOrganism","textContent","innerHTML","setOrganismLoading","placeholders","template","onError","err","handleError","onChange","resolved","applyContent","String","disconnectedCallback","stop","clearGlossaryResolutions","clearOrganismError","clearOrganismLoading","_err","setOrganismError","html","body","DOMParser","parseFromString","processRichText","resolveGlossaryReferences","root","anchor","querySelectorAll","closest","value","getAttribute","wrapAnchorAsLinkCta","span","marker","ownerDocument","createElement","setAttribute","ref","replaceWith","querySelector","append","dialog","entries","map","cta","push","source","listener","resolvedByRef","Map","index","resolveNext","length","resolutionEntry","isSafeRefPath","cached","get","term","definition","advanced","advanceOnce","set","parts","split","__decorateClass","property","type","reflect","prototype","customElement"],"mappings":"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"}