renderNode now passes the Craft node id as toHtml's 3rd argument
(props, childrenHtml, nodeId). Backward compatible: the resolver map is
untyped (any), so existing 2-arg toHtml implementations/tests are
unaffected. Adds scopeId()/stableHash() helpers in utils/escape.ts:
scopeId derives a scope string from the node id (deterministic AND
unique, since Craft node ids are unique per node and stable across
repeated exports of the same page) with a stableHash(seed) fallback for
legacy call sites without a node id.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds craft/src/utils/escape.ts as the single exported escaping/URL-safety
util (escapeHtml, escapeAttr, safeUrl) for later hardening tasks to
consolidate the 27 divergent local copies into. html-export.ts now
imports escapeHtml from it instead of keeping a private copy.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>