Home Manual Reference Source Repository

docs/layout/LayoutManipulator.js

import { Type } from '../di';
import { Renderable } from '../dom';
import { RenderableArg } from '../common';
import { Observable, Observer } from '../events';
import { TagUtil } from '../TagUtil';

export enum LayoutInsertPosition {
  FURTHEST,
  CLOSEST
}

export interface LayoutInsertArgs {
  insert: RenderableArg<Renderable>;
  from: Renderable;
  into: Type<Renderable>|Type<Renderable>[];
  position?: LayoutInsertPosition;
  index?: number;
  tag?: string;
}

export class LayoutManipulator {
  insert(args: LayoutInsertArgs): Observable<Renderable> {
    return Observable.create((observer: Observer<Renderable>) => {
      const { from, insert, into, index = -1, position = LayoutInsertPosition.CLOSEST } = args;

      const parents = from.getParents(into);
      const container = position === LayoutInsertPosition.CLOSEST ? parents[0] : parents[parents.length - 1];

      if (container) {
        let child = args.tag ? TagUtil.matches(container.contentItems, [ args.tag ])[0] : null;
        
        if (!child) {
          child = container.createChild(insert);
          
          container.addChild(child, {
            index: index === -1 ? container.contentItems.length : index
          });

          if (args.tag) {
            child.tags.add(args.tag);
          }
        }

        observer.next(child);
      }

      observer.complete();
    });
  }
}