public insertBefore()

in packages/miniapp-runtime/src/dom/node.ts [148:212]


  public insertBefore<T extends Node>(newChild: T, refChild?: Node | null, isReplace?: boolean): T {
    if (newChild.nodeName === DOCUMENT_FRAGMENT) {
      newChild.childNodes.reduceRight((previousValue, currentValue) => {
        this.insertBefore(currentValue, previousValue);
        return currentValue;
      }, refChild);
      return newChild;
    }

    // Parent release newChild
    //   - cleanRef: false (No need to clean eventSource, because newChild is about to be inserted)
    //   - update: true (Need to update parent.childNodes, because parent.childNodes is reordered)
    newChild.remove({ cleanRef: false });

    // Data structure
    newChild.parentNode = this;
    if (refChild) {
      // insertBefore & replaceChild
      const index = this.findIndex(refChild);
      this.childNodes.splice(index, 0, newChild);
    } else {
      // appendChild
      this.childNodes.push(newChild);
    }

    // Serialization
    if (this._root) {
      if (!refChild) {
        // appendChild
        const isOnlyChild = this.childNodes.length === 1;
        if (isOnlyChild) {
          this.updateChildNodes();
        } else {
          this.enqueueUpdate({
            path: newChild._path,
            value: this.hydrate(newChild),
          });
        }
      } else if (isReplace) {
        // replaceChild
        this.enqueueUpdate({
          path: newChild._path,
          value: this.hydrate(newChild),
        });
      } else {
        // insertBefore
        this.updateChildNodes();
      }
    }

    MutationObserver.record({
      type: MutationRecordType.CHILD_LIST,
      target: this,
      addedNodes: [newChild],
      removedNodes: isReplace
        ? [refChild as Node] /** replaceChild */
        : [],
      nextSibling: isReplace
        ? (refChild as Node).nextSibling /** replaceChild */
        : (refChild || null), /** insertBefore & appendChild */
      previousSibling: newChild.previousSibling,
    });

    return newChild;
  }