resolveNode function

Morphic resolveNode(
  1. dynamic node, {
  2. Component? owner,
})

Resolves a Morphic tree, expanding any Component instances found.

The optional owner parameter identifies which Component is responsible for the top-level node being resolved. It is only meaningful at the call site in ComponentRuntime.mount and requestUpdateFor — it should NOT be forwarded when recursing into children, because each child Component will register itself independently when the recursion reaches it.

Implementation

Morphic resolveNode(dynamic node, {Component? owner}) {
  // ── Component ────────────────────────────────────────────────────────────
  if (node is Component) {
    node.attach(RenderContext.runtime);

    final rendered = RenderContext.runWithComponent(node, () {
      return node.render();
    });

    // Resolve the component's own subtree. The component is the owner of
    // its render output — not whatever called resolveNode on it.
    final resolved = resolveNode(rendered, owner: node);

    // Register the tree. The matching DOM node will arrive via createDom.
    RenderContext.runtime.registerComponentTree(node, resolved);

    // Create and register the DOM node immediately, while we still know
    // which component this subtree belongs to.
    final dom = createDom(resolved, componentOwner: node);
    RenderContext.runtime.registerComponentDomNode(node, dom);

    return resolved;
  }

  // ── ElementMorphic ───────────────────────────────────────────────────────
  if (node is ElementMorphic) {
    final resolvedChildren = <Morphic>[];

    for (final child in node.children) {
      try {
        // Do not forward owner — children register themselves.
        final resolved = resolveNode(child);
        resolvedChildren.add(resolved);
      } catch (e) {
        continue;
      }
    }

    return ElementMorphic(
      tag: node.tag,
      attributes: node.attributes,
      children: resolvedChildren,
      key: node.key,
    );
  }

  // ── TextMorphic ──────────────────────────────────────────────────────────
  if (node is TextMorphic) {
    return node;
  }

  // ── String ───────────────────────────────────────────────────────────────
  if (node is String) {
    return TextMorphic(node);
  }

  throw UnsupportedError('Unknown node type: ${node.runtimeType}');
}