import {Inject, Injectable, OpaqueToken} from 'angular2/src/core/di'; import {AnimationBuilder} from 'angular2/src/animate/animation_builder'; import { isPresent, isBlank, Json, RegExpWrapper, CONST_EXPR, stringify, StringWrapper } from 'angular2/src/facade/lang'; import {BaseException, WrappedException} from 'angular2/src/facade/exceptions'; import {DomSharedStylesHost} from './shared_styles_host'; import {WtfScopeFn, wtfLeave, wtfCreateScope} from 'angular2/src/core/profile/profile'; import { Renderer, RenderProtoViewRef, RenderViewRef, RenderElementRef, RenderFragmentRef, RenderViewWithFragments, RenderTemplateCmd, RenderEventDispatcher, RenderComponentTemplate } from 'angular2/core'; import {EventManager} from './events/event_manager'; import {DOCUMENT} from './dom_tokens'; import { createRenderView, NodeFactory, encapsulateStyles } from 'angular2/src/core/render/view_factory'; import { DefaultRenderView, DefaultRenderFragmentRef, DefaultProtoViewRef } from 'angular2/src/core/render/view'; import {ViewEncapsulation} from 'angular2/src/core/metadata'; import {DOM} from 'angular2/src/platform/dom/dom_adapter'; import {camelCaseToDashCase} from './util'; const NAMESPACE_URIS = CONST_EXPR({'xlink': 'http://www.w3.org/1999/xlink', 'svg': 'http://www.w3.org/2000/svg'}); const TEMPLATE_COMMENT_TEXT = 'template bindings={}'; var TEMPLATE_BINDINGS_EXP = /^template bindings=(.*)$/g; export abstract class DomRenderer extends Renderer implements NodeFactory { abstract registerComponentTemplate(template: RenderComponentTemplate); abstract resolveComponentTemplate(templateId: string): RenderComponentTemplate; abstract createProtoView(componentTemplateId: string, cmds: RenderTemplateCmd[]): RenderProtoViewRef; abstract createRootHostView(hostProtoViewRef: RenderProtoViewRef, fragmentCount: number, hostElementSelector: string): RenderViewWithFragments; abstract createView(protoViewRef: RenderProtoViewRef, fragmentCount: number): RenderViewWithFragments; abstract destroyView(viewRef: RenderViewRef); abstract createRootContentInsertionPoint(); getNativeElementSync(location: RenderElementRef): any { return resolveInternalDomView(location.renderView).boundElements[location.boundElementIndex]; } getRootNodes(fragment: RenderFragmentRef): Node[] { return resolveInternalDomFragment(fragment); } attachFragmentAfterFragment(previousFragmentRef: RenderFragmentRef, fragmentRef: RenderFragmentRef) { var previousFragmentNodes = resolveInternalDomFragment(previousFragmentRef); if (previousFragmentNodes.length > 0) { var sibling = previousFragmentNodes[previousFragmentNodes.length - 1]; let nodes = resolveInternalDomFragment(fragmentRef); moveNodesAfterSibling(sibling, nodes); this.animateNodesEnter(nodes); } } /** * Iterates through all nodes being added to the DOM and animates them if necessary * @param nodes */ animateNodesEnter(nodes: Node[]) { for (let i = 0; i < nodes.length; i++) this.animateNodeEnter(nodes[i]); } /** * Performs animations if necessary * @param node */ abstract animateNodeEnter(node: Node); /** * If animations are necessary, performs animations then removes the element; otherwise, it just * removes the element. * @param node */ abstract animateNodeLeave(node: Node); attachFragmentAfterElement(elementRef: RenderElementRef, fragmentRef: RenderFragmentRef) { var parentView = resolveInternalDomView(elementRef.renderView); var element = parentView.boundElements[elementRef.boundElementIndex]; var nodes = resolveInternalDomFragment(fragmentRef); moveNodesAfterSibling(element, nodes); this.animateNodesEnter(nodes); } abstract detachFragment(fragmentRef: RenderFragmentRef); hydrateView(viewRef: RenderViewRef) { resolveInternalDomView(viewRef).hydrate(); } dehydrateView(viewRef: RenderViewRef) { resolveInternalDomView(viewRef).dehydrate(); } createTemplateAnchor(attrNameAndValues: string[]): Node { return DOM.createComment(TEMPLATE_COMMENT_TEXT); } abstract createElement(name: string, attrNameAndValues: string[]): Node; abstract mergeElement(existing: Node, attrNameAndValues: string[]); abstract createShadowRoot(host: Node, templateId: string): Node; createText(value: string): Node { return DOM.createTextNode(isPresent(value) ? value : ''); } appendChild(parent: Node, child: Node) { DOM.appendChild(parent, child); } abstract on(element: Node, eventName: string, callback: Function); abstract globalOn(target: string, eventName: string, callback: Function): Function; setElementProperty(location: RenderElementRef, propertyName: string, propertyValue: any): void { var view = resolveInternalDomView(location.renderView); DOM.setProperty(view.boundElements[location.boundElementIndex], propertyName, propertyValue); } setElementAttribute(location: RenderElementRef, attributeName: string, attributeValue: string): void { var view = resolveInternalDomView(location.renderView); var element = view.boundElements[location.boundElementIndex]; if (isPresent(attributeValue)) { DOM.setAttribute(element, attributeName, stringify(attributeValue)); } else { DOM.removeAttribute(element, attributeName); } } /** * Used only in debug mode to serialize property changes to comment nodes, * such as