insertBefore method

  1. @override
  2. @mustCallSuper
Node insertBefore(
  1. Node child,
  2. Node referenceNode
)
override

Implementation

@override
@mustCallSuper
Node insertBefore(Node child, Node referenceNode) {
  // Node.insertBefore will change element tree structure,
  // so get the referenceIndex before calling it.
  int referenceIndex = childNodes.indexOf(referenceNode);
  Node node = super.insertBefore(child, referenceNode);
  // Update renderStyle tree.
  if (child is Element) {
    child.renderStyle.parent = renderStyle;
  }

  if (isRendererAttached) {
    // If afterRenderObject is null, which means insert child at the head of parent.
    RenderBox? afterRenderObject;

    // Only append child renderer when which is not attached.
    if (!child.isRendererAttached) {
      if (referenceIndex < childNodes.length) {
        while (referenceIndex >= 0) {
          Node reference = childNodes[referenceIndex];
          if (reference.isRendererAttached) {
            afterRenderObject = reference.renderer;
            break;
          } else {
            referenceIndex--;
          }
        }
      }

      // Renderer of referenceNode may not moved to a difference place compared to its original place
      // in the dom tree due to position absolute/fixed.
      // Use the renderPositionPlaceholder to get the same place as dom tree in this case.
      if (afterRenderObject is RenderBoxModel) {
        RenderBox? renderPositionPlaceholder = afterRenderObject.renderPositionPlaceholder;
        if (renderPositionPlaceholder != null) {
          afterRenderObject = renderPositionPlaceholder;
        }
      }

      child.attachTo(this, after: afterRenderObject);
    }
  }

  return node;
}