···66- Make sure you leave things in a good state. No diagnostics warnings. No type errors.
77- We use tabs for indentation and spaces for alignment
88- Never say “you’re absolutely right”
99+- When writing new tests, put them under `test/new` and use `test` instead of `it`. Try to keep all the setup in the test itself. If you need to share setup between multiple steps, make a function that each test calls.
+49-8
src/morphlex.ts
···11-const SupportsMoveBefore = "moveBefore" in Element.prototype
22-const ParentNodeTypes = new Set([1, 9, 11])
11+const PARENT_NODE_TYPES = new Set([1, 9, 11])
22+const SUPPORTS_MOVE_BEFORE = "moveBefore" in Element.prototype
3344type IdSet = Set<string>
55type IdMap = WeakMap<Node, IdSet>
···1010type PairOfNodes<N extends Node> = [N, N]
1111type PairOfMatchingElements<E extends Element> = Branded<PairOfNodes<E>, "MatchingElementPair">
12121313-interface Options {
1313+export interface Options {
1414 preserveModified?: boolean
1515 beforeNodeVisited?: (fromNode: Node, toNode: Node) => boolean
1616 afterNodeVisited?: (fromNode: Node, toNode: Node) => void
···2828 moveBefore: (node: ChildNode, before: ChildNode | null) => void
2929}
30303131+/**
3232+ * Morph one document to another. If the `to` document is a string, it will be parsed with a DOMParser.
3333+ *
3434+ * @param from The source document to morph from.
3535+ * @param to The target document or string to morph to.
3636+ * @example
3737+ * ```ts
3838+ * morphDocument(document, newDocument)
3939+ * ```
4040+ */
4141+export function morphDocument(from: Document, to: Document | string): void {
4242+ if (typeof to === "string") to = parseDocument(to)
4343+ morph(from.documentElement, to.documentElement)
4444+}
4545+4646+/**
4747+ * Morph one `ChildNode` to another. If the `to` node is a string, it will be parsed with a `<template>` element.
4848+ *
4949+ * @param from The source node to morph from.
5050+ * @param to The target node, node list or string to morph to.
5151+ * @example
5252+ * ```ts
5353+ * morph(originalDom, newDom)
5454+ * ```
5555+ */
3156export function morph(from: ChildNode, to: ChildNode | NodeListOf<ChildNode> | string, options: Options = {}): void {
3232- if (typeof to === "string") to = parseString(to).childNodes
5757+ if (typeof to === "string") to = parseFragment(to).childNodes
33583459 if (isParentNode(from)) flagDirtyInputs(from)
35603661 new Morph(options).morph(from, to)
3762}
38636464+/**
6565+ * Morph the inner content of one ChildNode to the inner content of another.
6666+ * If the `to` node is a string, it will be parsed with a `<template>` element.
6767+ *
6868+ * @param from The source node to morph from.
6969+ * @param to The target node, node list or string to morph to.
7070+ * @example
7171+ * ```ts
7272+ * morphInner(originalDom, newDom)
7373+ * ```
7474+ */
3975export function morphInner(from: ChildNode, to: ChildNode | string, options: Options = {}): void {
4076 if (typeof to === "string") {
4141- const fragment = parseString(to)
7777+ const fragment = parseFragment(to)
42784379 if (fragment.firstChild && fragment.childNodes.length === 1 && isElement(fragment.firstChild)) {
4480 to = fragment.firstChild
···80116 }
81117}
821188383-function parseString(string: string): DocumentFragment {
119119+function parseFragment(string: string): DocumentFragment {
84120 const template = document.createElement("template")
85121 template.innerHTML = string.trim()
8612287123 return template.content
124124+}
125125+126126+function parseDocument(string: string): Document {
127127+ const parser = new DOMParser()
128128+ return parser.parseFromString(string.trim(), "text/html")
88129}
8913090131function moveBefore(parent: ParentNode, node: ChildNode, insertionPoint: ChildNode | null): void {
···598639}
599640600641function supportsMoveBefore(_node: ParentNode): _node is NodeWithMoveBefore {
601601- return SupportsMoveBefore
642642+ return SUPPORTS_MOVE_BEFORE
602643}
603644604645function isMatchingElementPair(pair: PairOfNodes<Element>): pair is PairOfMatchingElements<Element> {
···632673}
633674634675function isParentNode(node: Node): node is ParentNode {
635635- return ParentNodeTypes.has(node.nodeType)
676676+ return PARENT_NODE_TYPES.has(node.nodeType)
636677}