BREAKING CHANGES: - `ShadowDomStrategy` was removed. To specify the encapsulation of a component use `@View(encapsulation: ViewEncapsulation.NONE | ViewEncapsulation.EMULATED | ViewEncapsulation.NATIVE)` - The default encapsulation strategy is now `ViewEncapsulation.EMULATED` if a component contains styles and `ViewEncapsulation.NONE` if it does not. Before this was always `NONE`. - `ViewLoader` now returns the template as a string and the styles as a separate array
		
			
				
	
	
		
			138 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import {Inject, Injectable} from 'angular2/di';
 | 
						|
import {isPresent} from 'angular2/src/facade/lang';
 | 
						|
import {MapWrapper, ListWrapper, List, Map} from 'angular2/src/facade/collection';
 | 
						|
import {PromiseWrapper, Promise} from 'angular2/src/facade/async';
 | 
						|
import {DOM} from 'angular2/src/dom/dom_adapter';
 | 
						|
 | 
						|
import {DomRenderer} from 'angular2/src/render/dom/dom_renderer';
 | 
						|
import {DOCUMENT_TOKEN} from 'angular2/src/render/dom/dom_tokens';
 | 
						|
import {DefaultDomCompiler} from 'angular2/src/render/dom/compiler/compiler';
 | 
						|
import {
 | 
						|
  RenderViewWithFragments,
 | 
						|
  RenderFragmentRef,
 | 
						|
  RenderViewRef,
 | 
						|
  ProtoViewDto,
 | 
						|
  ViewDefinition,
 | 
						|
  RenderEventDispatcher,
 | 
						|
  DirectiveMetadata,
 | 
						|
  RenderElementRef,
 | 
						|
  RenderProtoViewMergeMapping,
 | 
						|
  RenderProtoViewRef
 | 
						|
} from 'angular2/src/render/api';
 | 
						|
import {resolveInternalDomView} from 'angular2/src/render/dom/view/view';
 | 
						|
import {resolveInternalDomFragment} from 'angular2/src/render/dom/view/fragment';
 | 
						|
import {el, dispatchEvent} from 'angular2/test_lib';
 | 
						|
 | 
						|
export class TestRootView {
 | 
						|
  viewRef: RenderViewRef;
 | 
						|
  fragments: RenderFragmentRef[];
 | 
						|
  hostElement: Element;
 | 
						|
  events: List<List<any>>;
 | 
						|
 | 
						|
  constructor(viewWithFragments: RenderViewWithFragments) {
 | 
						|
    this.viewRef = viewWithFragments.viewRef;
 | 
						|
    this.fragments = viewWithFragments.fragmentRefs;
 | 
						|
    this.hostElement = <Element>resolveInternalDomFragment(this.fragments[0])[0];
 | 
						|
    this.events = [];
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
export class TestRenderElementRef implements RenderElementRef {
 | 
						|
  constructor(public renderView: RenderViewRef, public renderBoundElementIndex: number) {}
 | 
						|
}
 | 
						|
 | 
						|
export function elRef(renderView: RenderViewRef, boundElementIndex: number) {
 | 
						|
  return new TestRenderElementRef(renderView, boundElementIndex);
 | 
						|
}
 | 
						|
 | 
						|
export function rootNodes(view: RenderViewRef) {}
 | 
						|
 | 
						|
class LoggingEventDispatcher implements RenderEventDispatcher {
 | 
						|
  log: List<List<any>>;
 | 
						|
 | 
						|
  constructor(log: List<List<any>>) { this.log = log; }
 | 
						|
 | 
						|
  dispatchRenderEvent(elementIndex: number, eventName: string, locals: Map<string, any>) {
 | 
						|
    this.log.push([elementIndex, eventName, locals]);
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
@Injectable()
 | 
						|
export class DomTestbed {
 | 
						|
  renderer: DomRenderer;
 | 
						|
  compiler: DefaultDomCompiler;
 | 
						|
  rootEl;
 | 
						|
 | 
						|
  constructor(renderer: DomRenderer, compiler: DefaultDomCompiler,
 | 
						|
              @Inject(DOCUMENT_TOKEN) document) {
 | 
						|
    this.renderer = renderer;
 | 
						|
    this.compiler = compiler;
 | 
						|
    this.rootEl = el('<div id="root" class="rootElem"></div>');
 | 
						|
    var oldRoots = DOM.querySelectorAll(document, '#root');
 | 
						|
    for (var i = 0; i < oldRoots.length; i++) {
 | 
						|
      DOM.remove(oldRoots[i]);
 | 
						|
    }
 | 
						|
    DOM.appendChild(DOM.querySelector(document, 'body'), this.rootEl);
 | 
						|
  }
 | 
						|
 | 
						|
  compile(host: DirectiveMetadata, componentViews: ViewDefinition[]): Promise<ProtoViewDto[]> {
 | 
						|
    var promises = [this.compiler.compileHost(host)];
 | 
						|
    componentViews.forEach(view => promises.push(this.compiler.compile(view)));
 | 
						|
    return PromiseWrapper.all(promises);
 | 
						|
  }
 | 
						|
 | 
						|
  merge(protoViews: List<ProtoViewDto | RenderProtoViewRef>): Promise<RenderProtoViewMergeMapping> {
 | 
						|
    return this.compiler.mergeProtoViewsRecursively(collectMergeRenderProtoViewsRecurse(
 | 
						|
        <ProtoViewDto>protoViews[0], ListWrapper.slice(protoViews, 1)));
 | 
						|
  }
 | 
						|
 | 
						|
  compileAndMerge(host: DirectiveMetadata,
 | 
						|
                  componentViews: ViewDefinition[]): Promise<RenderProtoViewMergeMapping> {
 | 
						|
    return this.compile(host, componentViews).then(protoViewDtos => this.merge(protoViewDtos));
 | 
						|
  }
 | 
						|
 | 
						|
  _createTestView(viewWithFragments: RenderViewWithFragments) {
 | 
						|
    var testView = new TestRootView(viewWithFragments);
 | 
						|
    this.renderer.setEventDispatcher(viewWithFragments.viewRef,
 | 
						|
                                     new LoggingEventDispatcher(testView.events));
 | 
						|
    return testView;
 | 
						|
  }
 | 
						|
 | 
						|
  createView(protoView: RenderProtoViewMergeMapping): TestRootView {
 | 
						|
    var viewWithFragments = this.renderer.createView(protoView.mergedProtoViewRef, 0);
 | 
						|
    this.renderer.hydrateView(viewWithFragments.viewRef);
 | 
						|
    return this._createTestView(viewWithFragments);
 | 
						|
  }
 | 
						|
 | 
						|
  triggerEvent(elementRef: RenderElementRef, eventName: string) {
 | 
						|
    var element = resolveInternalDomView(elementRef.renderView)
 | 
						|
                      .boundElements[elementRef.renderBoundElementIndex];
 | 
						|
    dispatchEvent(element, eventName);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function collectMergeRenderProtoViewsRecurse(current: ProtoViewDto,
 | 
						|
                                             components: List<ProtoViewDto | RenderProtoViewRef>):
 | 
						|
    List<RenderProtoViewRef | List<any>> {
 | 
						|
  var result = [current.render];
 | 
						|
  current.elementBinders.forEach((elementBinder) => {
 | 
						|
    if (isPresent(elementBinder.nestedProtoView)) {
 | 
						|
      result.push(collectMergeRenderProtoViewsRecurse(elementBinder.nestedProtoView, components));
 | 
						|
    } else if (elementBinder.directives.length > 0) {
 | 
						|
      if (components.length > 0) {
 | 
						|
        var comp = components.shift();
 | 
						|
        if (comp instanceof ProtoViewDto) {
 | 
						|
          result.push(collectMergeRenderProtoViewsRecurse(comp, components));
 | 
						|
        } else {
 | 
						|
          result.push(comp);
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        result.push(null);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  });
 | 
						|
  return result;
 | 
						|
}
 |