(childNodes: NodeListOf<ChildNode>)
| 33 | }) |
| 34 | } |
| 35 | const createChildren = async (childNodes: NodeListOf<ChildNode>): Promise<E[]> => { |
| 36 | const children: E[] = [] |
| 37 | for (let i = 0; i < childNodes.length; i++) { |
| 38 | const child = childNodes[i] as HTMLElement |
| 39 | if (child.nodeType === 8) { |
| 40 | // skip comments |
| 41 | continue |
| 42 | } else if (child.nodeType === 3) { |
| 43 | // text node — string is a valid child for hono/jsx and React; cast to E |
| 44 | children.push(child.textContent as E) |
| 45 | } else if (child.nodeName === 'TEMPLATE' && child.id.match(/(?:H|E):\d+/)) { |
| 46 | const placeholderElement = document.createElement('hono-placeholder') |
| 47 | placeholderElement.style.display = 'none' |
| 48 | |
| 49 | let resolve: (nodes: E[]) => void |
| 50 | const promise = new Promise<E[]>((r) => (resolve = r)) |
| 51 | |
| 52 | // Suspense: replace content by `replaceWith` when resolved |
| 53 | // ErrorBoundary: replace content by `replaceWith` when error |
| 54 | child.replaceWith = (node: DocumentFragment) => { |
| 55 | createChildren(node.childNodes).then(resolve) |
| 56 | placeholderElement.remove() |
| 57 | } |
| 58 | |
| 59 | // eslint-disable-next-line @typescript-eslint/no-explicit-any |
| 60 | let fallback: any = [] |
| 61 | |
| 62 | // gather fallback content and find placeholder comment |
| 63 | for ( |
| 64 | // equivalent to i++ |
| 65 | placeholderElement.appendChild(child); |
| 66 | i < childNodes.length; |
| 67 | i++ |
| 68 | ) { |
| 69 | const child = childNodes[i] |
| 70 | if (child.nodeType === 8) { |
| 71 | // <!--/$--> or <!--E:1--> |
| 72 | placeholderElement.appendChild(child) |
| 73 | i-- |
| 74 | break |
| 75 | } else if (child.nodeType === 3) { |
| 76 | fallback.push(child.textContent) |
| 77 | } else { |
| 78 | fallback.push(await createElementFromHTMLElement(child as HTMLElement)) |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | // if already resolved or error, get content from added template element |
| 83 | const fallbackTemplates = document.querySelectorAll<HTMLTemplateElement>( |
| 84 | `[data-hono-target="${child.id}"]` |
| 85 | ) |
| 86 | if (fallbackTemplates.length > 0) { |
| 87 | const fallbackTemplate = fallbackTemplates[fallbackTemplates.length - 1] |
| 88 | fallback = await createChildren(fallbackTemplate.content.childNodes) |
| 89 | } |
| 90 | |
| 91 | // if no content available, wait for ErrorBoundary fallback content |
| 92 | if (fallback.length === 0 && child.id.startsWith('E:')) { |
no test coverage detected