{"version":3,"sources":["../src/simulator.ts"],"sourcesContent":["/**\n * Simulates the DOM mutations Chrome / Google Translate performs when\n * translating a page, so tests can reproduce the well-known class of React\n * crashes and stale-text bugs without a real browser translation session.\n *\n * Mutation shape, cross-verified from facebook/react#11538 (incl. the verbatim\n * Chromium bug 872770 analysis in comment 59) and\n * https://martijnhols.nl/blog/everything-about-google-translate-crashing-react:\n *\n *  1. Adjacent Text nodes are merged first (`normalize()`), so several\n *     renderer-owned text nodes can collapse into one run.\n *  2. Each run is split into segments (numbers get isolated into their own\n *     segment), and every segment becomes a nested double\n *     `<font style=\"vertical-align: inherit;\">` wrapper around a NEW text\n *     node with the translated content.\n *  3. The wrappers are inserted before the original text node, then the\n *     original is REMOVED — it stays alive in memory (renderers still hold\n *     references) but has parentNode === null.\n *  4. Translation can also delete text nodes outright and move inline\n *     elements to match target-language word order (Chromium bug 872770).\n *  5. Comment nodes are never touched.\n *  6. A MutationObserver keeps watching the page and translates content that\n *     appears or changes later.\n *  7. BEFORE any text is touched, the document is marked: a `translated-ltr`\n *     class and a `lang` flip on <html> (class first, then lang — verified\n *     empirically against real Chrome, where both land ~275-500ms ahead of\n *     the first displacement mutation).\n */\n\nexport function pseudoTranslate(text: string): string {\n  return `[${text}]`;\n}\n\nexport type TranslateFn = (text: string) => string;\n\nexport interface TranslateOptions {\n  /** Text nodes the \"translation\" deletes outright (no replacement). */\n  deleteTextNodes?: Text[];\n  /** Inline elements moved to the end of their parent (word-order change). */\n  moveToParentEnd?: Element[];\n}\n\n/** Inner text nodes created by the simulator (already-translated content). */\nconst simulatorOwnedTextNodes = new WeakSet<Text>();\n\nfunction isText(node: Node): node is Text {\n  return node.nodeType === Node.TEXT_NODE;\n}\n\nfunction hasTranslatableContent(node: Text): boolean {\n  return /\\S/.test(node.nodeValue ?? '');\n}\n\nfunction isInsideFont(node: Node): boolean {\n  let current: Node | null = node.parentNode;\n  while (current) {\n    if (current.nodeName === 'FONT') return true;\n    current = current.parentNode;\n  }\n  return false;\n}\n\nfunction createFontWrapper(translatedText: string): HTMLElement {\n  const outer = document.createElement('font');\n  outer.setAttribute('style', 'vertical-align: inherit;');\n  const inner = document.createElement('font');\n  inner.setAttribute('style', 'vertical-align: inherit;');\n  const translatedNode = document.createTextNode(translatedText);\n  simulatorOwnedTextNodes.add(translatedNode);\n  inner.appendChild(translatedNode);\n  outer.appendChild(inner);\n  return outer;\n}\n\n/** Numbers are isolated into their own segment, like the real translator. */\nfunction splitIntoSegments(text: string): string[] {\n  return text.split(/(\\d+)/).filter((segment) => segment !== '');\n}\n\n/**\n * Replaces a single text node with translated <font> wrappers, exactly the\n * way Google Translate does: insert the wrappers, then detach the original.\n */\nfunction translateTextNode(textNode: Text, translate: TranslateFn): void {\n  const parent = textNode.parentNode;\n  if (!parent) return;\n  for (const segment of splitIntoSegments(textNode.nodeValue ?? '')) {\n    parent.insertBefore(createFontWrapper(translate(segment)), textNode);\n  }\n  parent.removeChild(textNode);\n}\n\nfunction collectTranslatableTextNodes(root: Node): Text[] {\n  const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);\n  const result: Text[] = [];\n  let node = walker.nextNode();\n  while (node) {\n    if (isText(node) && hasTranslatableContent(node) && !isInsideFont(node) && !simulatorOwnedTextNodes.has(node)) {\n      result.push(node);\n    }\n    node = walker.nextNode();\n  }\n  return result;\n}\n\n/**\n * Spec-equivalent Node.normalize(): merge each run of adjacent Text siblings\n * into the first node of the run and remove the rest. Done with explicit DOM\n * operations (rather than calling normalize()) so the MutationRecords emitted\n * are deterministic across DOM implementations.\n */\nfunction mergeAdjacentTextNodes(parent: Node): void {\n  let child = parent.firstChild;\n  while (child) {\n    if (isText(child)) {\n      let next = child.nextSibling;\n      while (next && isText(next)) {\n        const after = next.nextSibling;\n        child.nodeValue = (child.nodeValue ?? '') + (next.nodeValue ?? '');\n        parent.removeChild(next);\n        next = after;\n      }\n    }\n    child = child.nextSibling;\n  }\n}\n\nfunction normalizeSubtree(root: Node): void {\n  const base = isText(root) ? (root.parentNode ?? root) : root;\n  mergeAdjacentTextNodes(base);\n  const walker = document.createTreeWalker(base, NodeFilter.SHOW_ELEMENT);\n  let element = walker.nextNode();\n  while (element) {\n    mergeAdjacentTextNodes(element);\n    element = walker.nextNode();\n  }\n}\n\n/**\n * Marks the document the way Chrome's translator does before touching any\n * text: a `translated-ltr` class and a `lang` flip on <html>. Emitting these\n * first lets lazily-activating consumers (like translation-resilience\n * itself) arm before displacement begins.\n */\nfunction emitTranslationSignals(root: Node): void {\n  const doc = root.ownerDocument ?? (root instanceof Document ? root : document);\n  const html = doc.documentElement;\n  if (!html.classList.contains('translated-ltr')) html.classList.add('translated-ltr');\n  if (html.getAttribute('lang') !== 'x-pseudo') html.setAttribute('lang', 'x-pseudo');\n}\n\n/** One-shot translation pass over a subtree, like the initial page translate. */\nexport function translateSubtree(\n  root: Node,\n  translate: TranslateFn = pseudoTranslate,\n  options: TranslateOptions = {}\n): void {\n  emitTranslationSignals(root);\n  for (const textNode of options.deleteTextNodes ?? []) {\n    textNode.parentNode?.removeChild(textNode);\n  }\n  normalizeSubtree(root);\n  for (const textNode of collectTranslatableTextNodes(root)) {\n    translateTextNode(textNode, translate);\n  }\n  if (isText(root) && hasTranslatableContent(root) && !isInsideFont(root) && !simulatorOwnedTextNodes.has(root)) {\n    translateTextNode(root, translate);\n  }\n  for (const element of options.moveToParentEnd ?? []) {\n    element.parentNode?.appendChild(element);\n  }\n}\n\n/**\n * Models Google Translate's ongoing observation of the page: newly inserted\n * text gets translated (including a fresh normalize pass over its parent,\n * merging adjacent restored text nodes); text that changes inside an existing\n * <font> wrapper is re-translated in place.\n *\n * Returns a stop function.\n */\nexport function startTranslateObserver(root: Node, translate: TranslateFn = pseudoTranslate): () => void {\n  const observer = new MutationObserver((records) => {\n    const parentsToTranslate = new Set<Node>();\n    for (const record of records) {\n      if (record.type === 'childList') {\n        for (const added of record.addedNodes) {\n          if (isText(added) && simulatorOwnedTextNodes.has(added)) continue;\n          if (isInsideFont(added)) {\n            if (isText(added) && hasTranslatableContent(added)) {\n              added.nodeValue = translate(added.nodeValue ?? '');\n              simulatorOwnedTextNodes.add(added);\n            }\n          } else if (isText(added)) {\n            if (hasTranslatableContent(added) && added.parentNode) parentsToTranslate.add(added.parentNode);\n          } else {\n            parentsToTranslate.add(added);\n          }\n        }\n      } else if (record.type === 'characterData') {\n        const target = record.target;\n        if (\n          isText(target) &&\n          !simulatorOwnedTextNodes.has(target) &&\n          isInsideFont(target) &&\n          hasTranslatableContent(target)\n        ) {\n          target.nodeValue = translate(target.nodeValue ?? '');\n          simulatorOwnedTextNodes.add(target);\n        }\n      }\n    }\n    for (const parent of parentsToTranslate) {\n      if (parent.isConnected) translateSubtree(parent, translate);\n    }\n  });\n  observer.observe(root, { childList: true, subtree: true, characterData: true });\n  return () => observer.disconnect();\n}\n\n/**\n * Native DOM entry points, captured when this module is first imported — that\n * is, before `installTranslationResilience` patches `Node.prototype`.\n *\n * A real page translator (Chrome's, Edge's, the Google Translate extension)\n * runs in the browser engine's own *isolated world*: it shares the DOM but\n * holds a separate copy of `Node.prototype`, so none of the shim's patched\n * methods ever observe its mutations. Calling these captured natives\n * reproduces exactly that constraint inside a single realm.\n *\n * This distinction decides whether a test is meaningful. A simulator that\n * displaces text through the live prototype methods arms the shim through a\n * path no real translator can reach, so it passes whether or not the shim\n * would survive a real translation — which is how a whole class of production\n * crash stayed green in CI. Displace through these instead.\n */\nconst nativeDataSetter = Object.getOwnPropertyDescriptor(CharacterData.prototype, 'data')?.set;\n\nconst nativeDom = {\n  insertBefore: Node.prototype.insertBefore,\n  removeChild: Node.prototype.removeChild,\n  appendChild: Node.prototype.appendChild,\n  setAttribute: Element.prototype.setAttribute,\n  removeAttribute: Element.prototype.removeAttribute,\n  setData(node: CharacterData, value: string): void {\n    if (!nativeDataSetter) throw new Error('simulator: CharacterData.prototype.data has no setter');\n    nativeDataSetter.call(node, value);\n  },\n};\n\n/** Which browser's wrapper markup to emit. */\nexport type TranslatorSignature = 'google' | 'edge';\n\n/**\n * Built entirely through the captured natives — including while assembling the\n * wrapper off-document. Using the live `appendChild` here would call the\n * shim's patched method with a signature <font>, arming it through the very\n * path a real translator cannot reach, and the test would pass for the wrong\n * reason.\n */\nfunction createSignatureWrapper(translatedText: string, signature: TranslatorSignature): HTMLElement {\n  const translatedNode = document.createTextNode(translatedText);\n  simulatorOwnedTextNodes.add(translatedNode);\n\n  if (signature === 'google') {\n    // Chrome's translator and its extension: doubly nested\n    // <font style=\"vertical-align: inherit;\">.\n    const outer = document.createElement('font');\n    outer.setAttribute('style', 'vertical-align: inherit;');\n    const inner = document.createElement('font');\n    inner.setAttribute('style', 'vertical-align: inherit;');\n    nativeDom.appendChild.call(inner, translatedNode);\n    nativeDom.appendChild.call(outer, inner);\n    return outer;\n  }\n\n  // Edge's built-in translator: a <font> carrying _msttexthash/_msthash and no\n  // style, and no `translated-*` class or `lang` flip on <html> at all.\n  const font = document.createElement('font');\n  font.setAttribute('_msttexthash', '27820');\n  font.setAttribute('_msthash', '1');\n  nativeDom.appendChild.call(font, translatedNode);\n  return font;\n}\n\n/**\n * Displaces one text node the way a real translator does — wrapper in, original\n * out — using only the captured natives, so the shim's patched methods never\n * see the operation. This is the faithful reproduction of a browser\n * translator; `translateSubtree` is the same mutation shape performed in-realm.\n *\n * Returns the wrapper now standing in for the original.\n */\nexport function displaceFromIsolatedWorld(\n  textNode: Text,\n  translatedText: string = pseudoTranslate(textNode.nodeValue ?? ''),\n  signature: TranslatorSignature = 'google'\n): HTMLElement {\n  const parent = textNode.parentNode;\n  if (!parent) throw new Error('displaceFromIsolatedWorld: text node must be attached');\n  const wrapper = createSignatureWrapper(translatedText, signature);\n  nativeDom.insertBefore.call(parent, wrapper, textNode);\n  nativeDom.removeChild.call(parent, textNode);\n  return wrapper;\n}\n\n/**\n * Firefox's full-page translator (translations-document.sys.mjs) sends an\n * element's content to its engine as one piece — adjacent Text nodes\n * serialise into a single run of text — and applies the result with its\n * `merge()`: every child is detached, first to last; then the translated\n * nodes are appended in order, reusing the element's live Text nodes BY\n * POSITION (their data overwritten) and its live elements by identity, each\n * merged recursively before it is re-appended. A run of several renderer Text\n * nodes comes back as one translated text, so the first node of the run\n * carries the whole translation and the rest are never re-appended: they stay\n * detached while the renderer still holds them.\n *\n * Like the other out-of-world helpers, this uses DOM natives captured at\n * import: Firefox applies translations through Xray wrappers, which never see\n * a page's prototype patches.\n *\n * One deliberate difference in ordering: Firefox overwrites a reused Text\n * node, and merges a child element, while it is detached, and browsers report\n * those mutations to page observers through the DOM's transient registered\n * observers. jsdom does not implement transient observers, so it would never\n * report them. Here each node is overwritten or merged just after it is\n * re-appended instead: every parent's own record sequence and the final DOM\n * are the same, and jsdom sees every mutation a browser would report.\n */\nexport function mergeLikeFirefox(element: Element, translate: TranslateFn = pseudoTranslate): void {\n  mergeChildren(element, translate);\n  for (const tagged of element.querySelectorAll(`[${FIREFOX_ID_ATTRIBUTE}]`)) {\n    nativeDom.removeAttribute.call(tagged, FIREFOX_ID_ATTRIBUTE);\n  }\n}\n\n/**\n * Firefox tags the elements inside a block it sends to its engine, so it can\n * match them up with the translated markup, and removes the tags when it\n * merges. Blocks of plain text carry none.\n */\nconst FIREFOX_ID_ATTRIBUTE = 'data-moz-translations-id';\n\nfunction mergeChildren(element: Element, translate: TranslateFn): void {\n  const children = [...element.childNodes];\n  const translated: Array<string | Element> = [];\n  let run = '';\n  const endRun = (): void => {\n    if (run === '') return;\n    translated.push(/\\S/.test(run) ? translate(run) : run);\n    run = '';\n  };\n  for (const child of children) {\n    if (isText(child)) {\n      run += child.data;\n    } else if (child instanceof Element) {\n      endRun();\n      translated.push(child);\n    }\n  }\n  endRun();\n\n  const liveTextNodes = children.filter(isText);\n  let first = element.firstChild;\n  while (first) {\n    nativeDom.removeChild.call(element, first);\n    first = element.firstChild;\n  }\n  for (const item of translated) {\n    if (typeof item === 'string') {\n      const reused = liveTextNodes.shift();\n      if (reused) {\n        nativeDom.appendChild.call(element, reused);\n        nativeDom.setData(reused, item);\n      } else {\n        const created = document.createTextNode(item);\n        simulatorOwnedTextNodes.add(created);\n        nativeDom.appendChild.call(element, created);\n      }\n    } else {\n      nativeDom.appendChild.call(element, item);\n      if (/\\S/.test(item.textContent ?? '')) mergeChildren(item, translate);\n    }\n  }\n}\n\n/**\n * The whole of a Firefox page translation of `element`, in the order a real\n * one happens: `<html lang>` is set to the target language from outside the\n * page's JavaScript world as translation starts, the elements inside the\n * block are tagged as it is sent to the engine, and the translation arrives\n * later, from the engine running in another process — so the merge happens in\n * a later task.\n */\nexport async function translateLikeFirefox(\n  element: Element,\n  translate: TranslateFn = pseudoTranslate,\n  targetLanguage = 'x-pseudo'\n): Promise<void> {\n  const doc = element.ownerDocument;\n  nativeDom.setAttribute.call(doc.documentElement, 'lang', targetLanguage);\n  element.querySelectorAll('*').forEach((descendant, index) => {\n    nativeDom.setAttribute.call(descendant, FIREFOX_ID_ATTRIBUTE, String(index));\n  });\n  await new Promise((resolve) => setTimeout(resolve, 0));\n  mergeLikeFirefox(element, translate);\n}\n"],"mappings":"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","names":["_a"]}