UNPKG

angular2

Version:

Angular 2 - a web framework for modern web apps

306 lines 16.2 kB
'use strict';var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { if (typeof Reflect === "object" && typeof Reflect.decorate === "function") return Reflect.decorate(decorators, target, key, desc); switch (arguments.length) { case 2: return decorators.reduceRight(function(o, d) { return (d && d(o)) || o; }, target); case 3: return decorators.reduceRight(function(o, d) { return (d && d(target, key)), void 0; }, void 0); case 4: return decorators.reduceRight(function(o, d) { return (d && d(target, key, o)) || o; }, desc); } }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; var lang_1 = require('angular2/src/facade/lang'); var api_1 = require('angular2/src/core/render/api'); var di_1 = require('angular2/src/core/di'); var pipe_provider_1 = require('../pipes/pipe_provider'); var pipes_1 = require('../pipes/pipes'); var view_1 = require('./view'); var element_binder_1 = require('./element_binder'); var element_injector_1 = require('./element_injector'); var directive_resolver_1 = require('./directive_resolver'); var view_resolver_1 = require('./view_resolver'); var pipe_resolver_1 = require('./pipe_resolver'); var view_2 = require('../metadata/view'); var platform_directives_and_pipes_1 = require('angular2/src/core/platform_directives_and_pipes'); var template_commands_1 = require('./template_commands'); var render_1 = require('angular2/render'); var application_tokens_1 = require('angular2/src/core/application_tokens'); var ProtoViewFactory = (function () { function ProtoViewFactory(_renderer, _platformPipes, _directiveResolver, _viewResolver, _pipeResolver, _appId) { this._renderer = _renderer; this._platformPipes = _platformPipes; this._directiveResolver = _directiveResolver; this._viewResolver = _viewResolver; this._pipeResolver = _pipeResolver; this._appId = _appId; this._cache = new Map(); this._nextTemplateId = 0; } ProtoViewFactory.prototype.clearCache = function () { this._cache.clear(); }; ProtoViewFactory.prototype.createHost = function (compiledHostTemplate) { var compiledTemplate = compiledHostTemplate.template; var result = this._cache.get(compiledTemplate.id); if (lang_1.isBlank(result)) { var emptyMap = {}; var shortId = this._appId + "-" + this._nextTemplateId++; this._renderer.registerComponentTemplate(new api_1.RenderComponentTemplate(compiledTemplate.id, shortId, view_2.ViewEncapsulation.None, compiledTemplate.commands, [])); result = new view_1.AppProtoView(compiledTemplate.id, compiledTemplate.commands, view_1.ViewType.HOST, true, compiledTemplate.changeDetectorFactory, null, new pipes_1.ProtoPipes(emptyMap)); this._cache.set(compiledTemplate.id, result); } return result; }; ProtoViewFactory.prototype._createComponent = function (cmd) { var _this = this; var nestedProtoView = this._cache.get(cmd.templateId); if (lang_1.isBlank(nestedProtoView)) { var component = cmd.directives[0]; var view = this._viewResolver.resolve(component); var compiledTemplate = cmd.templateGetter(); var styles = _flattenStyleArr(compiledTemplate.styles, []); var shortId = this._appId + "-" + this._nextTemplateId++; this._renderer.registerComponentTemplate(new api_1.RenderComponentTemplate(compiledTemplate.id, shortId, cmd.encapsulation, compiledTemplate.commands, styles)); var boundPipes = this._flattenPipes(view).map(function (pipe) { return _this._bindPipe(pipe); }); nestedProtoView = new view_1.AppProtoView(compiledTemplate.id, compiledTemplate.commands, view_1.ViewType.COMPONENT, true, compiledTemplate.changeDetectorFactory, null, pipes_1.ProtoPipes.fromProviders(boundPipes)); // Note: The cache is updated before recursing // to be able to resolve cycles this._cache.set(compiledTemplate.id, nestedProtoView); this._initializeProtoView(nestedProtoView, null); } return nestedProtoView; }; ProtoViewFactory.prototype._createEmbeddedTemplate = function (cmd, parent) { var nestedProtoView = new view_1.AppProtoView(parent.templateId, cmd.children, view_1.ViewType.EMBEDDED, cmd.isMerged, cmd.changeDetectorFactory, arrayToMap(cmd.variableNameAndValues, true), new pipes_1.ProtoPipes(parent.pipes.config)); if (cmd.isMerged) { this.initializeProtoViewIfNeeded(nestedProtoView); } return nestedProtoView; }; ProtoViewFactory.prototype.initializeProtoViewIfNeeded = function (protoView) { if (!protoView.isInitialized()) { var render = this._renderer.createProtoView(protoView.templateId, protoView.templateCmds); this._initializeProtoView(protoView, render); } }; ProtoViewFactory.prototype._initializeProtoView = function (protoView, render) { var initializer = new _ProtoViewInitializer(protoView, this._directiveResolver, this); template_commands_1.visitAllCommands(initializer, protoView.templateCmds); var mergeInfo = new view_1.AppProtoViewMergeInfo(initializer.mergeEmbeddedViewCount, initializer.mergeElementCount, initializer.mergeViewCount); protoView.init(render, initializer.elementBinders, initializer.boundTextCount, mergeInfo, initializer.variableLocations); }; ProtoViewFactory.prototype._bindPipe = function (typeOrProvider) { var meta = this._pipeResolver.resolve(typeOrProvider); return pipe_provider_1.PipeProvider.createFromType(typeOrProvider, meta); }; ProtoViewFactory.prototype._flattenPipes = function (view) { var pipes = []; if (lang_1.isPresent(this._platformPipes)) { _flattenArray(this._platformPipes, pipes); } if (lang_1.isPresent(view.pipes)) { _flattenArray(view.pipes, pipes); } return pipes; }; ProtoViewFactory = __decorate([ di_1.Injectable(), __param(1, di_1.Optional()), __param(1, di_1.Inject(platform_directives_and_pipes_1.PLATFORM_PIPES)), __param(5, di_1.Inject(application_tokens_1.APP_ID)), __metadata('design:paramtypes', [render_1.Renderer, Array, directive_resolver_1.DirectiveResolver, view_resolver_1.ViewResolver, pipe_resolver_1.PipeResolver, String]) ], ProtoViewFactory); return ProtoViewFactory; })(); exports.ProtoViewFactory = ProtoViewFactory; function createComponent(protoViewFactory, cmd) { return protoViewFactory._createComponent(cmd); } function createEmbeddedTemplate(protoViewFactory, cmd, parent) { return protoViewFactory._createEmbeddedTemplate(cmd, parent); } var _ProtoViewInitializer = (function () { function _ProtoViewInitializer(_protoView, _directiveResolver, _protoViewFactory) { this._protoView = _protoView; this._directiveResolver = _directiveResolver; this._protoViewFactory = _protoViewFactory; this.variableLocations = new Map(); this.boundTextCount = 0; this.boundElementIndex = 0; this.elementBinderStack = []; this.distanceToParentElementBinder = 0; this.distanceToParentProtoElementInjector = 0; this.elementBinders = []; this.mergeEmbeddedViewCount = 0; this.mergeElementCount = 0; this.mergeViewCount = 1; } _ProtoViewInitializer.prototype.visitText = function (cmd, context) { if (cmd.isBound) { this.boundTextCount++; } return null; }; _ProtoViewInitializer.prototype.visitNgContent = function (cmd, context) { return null; }; _ProtoViewInitializer.prototype.visitBeginElement = function (cmd, context) { if (cmd.isBound) { this._visitBeginBoundElement(cmd, null); } else { this._visitBeginElement(cmd, null, null); } return null; }; _ProtoViewInitializer.prototype.visitEndElement = function (context) { return this._visitEndElement(); }; _ProtoViewInitializer.prototype.visitBeginComponent = function (cmd, context) { var nestedProtoView = createComponent(this._protoViewFactory, cmd); return this._visitBeginBoundElement(cmd, nestedProtoView); }; _ProtoViewInitializer.prototype.visitEndComponent = function (context) { return this._visitEndElement(); }; _ProtoViewInitializer.prototype.visitEmbeddedTemplate = function (cmd, context) { var nestedProtoView = createEmbeddedTemplate(this._protoViewFactory, cmd, this._protoView); if (cmd.isMerged) { this.mergeEmbeddedViewCount++; } this._visitBeginBoundElement(cmd, nestedProtoView); return this._visitEndElement(); }; _ProtoViewInitializer.prototype._visitBeginBoundElement = function (cmd, nestedProtoView) { if (lang_1.isPresent(nestedProtoView) && nestedProtoView.isMergable) { this.mergeElementCount += nestedProtoView.mergeInfo.elementCount; this.mergeViewCount += nestedProtoView.mergeInfo.viewCount; this.mergeEmbeddedViewCount += nestedProtoView.mergeInfo.embeddedViewCount; } var elementBinder = _createElementBinder(this._directiveResolver, nestedProtoView, this.elementBinderStack, this.boundElementIndex, this.distanceToParentElementBinder, this.distanceToParentProtoElementInjector, cmd); this.elementBinders.push(elementBinder); var protoElementInjector = elementBinder.protoElementInjector; for (var i = 0; i < cmd.variableNameAndValues.length; i += 2) { this.variableLocations.set(cmd.variableNameAndValues[i], this.boundElementIndex); } this.boundElementIndex++; this.mergeElementCount++; return this._visitBeginElement(cmd, elementBinder, protoElementInjector); }; _ProtoViewInitializer.prototype._visitBeginElement = function (cmd, elementBinder, protoElementInjector) { this.distanceToParentElementBinder = lang_1.isPresent(elementBinder) ? 1 : this.distanceToParentElementBinder + 1; this.distanceToParentProtoElementInjector = lang_1.isPresent(protoElementInjector) ? 1 : this.distanceToParentProtoElementInjector + 1; this.elementBinderStack.push(elementBinder); return null; }; _ProtoViewInitializer.prototype._visitEndElement = function () { var parentElementBinder = this.elementBinderStack.pop(); var parentProtoElementInjector = lang_1.isPresent(parentElementBinder) ? parentElementBinder.protoElementInjector : null; this.distanceToParentElementBinder = lang_1.isPresent(parentElementBinder) ? parentElementBinder.distanceToParent : this.distanceToParentElementBinder - 1; this.distanceToParentProtoElementInjector = lang_1.isPresent(parentProtoElementInjector) ? parentProtoElementInjector.distanceToParent : this.distanceToParentProtoElementInjector - 1; return null; }; return _ProtoViewInitializer; })(); function _createElementBinder(directiveResolver, nestedProtoView, elementBinderStack, boundElementIndex, distanceToParentBinder, distanceToParentPei, beginElementCmd) { var parentElementBinder = null; var parentProtoElementInjector = null; if (distanceToParentBinder > 0) { parentElementBinder = elementBinderStack[elementBinderStack.length - distanceToParentBinder]; } if (lang_1.isBlank(parentElementBinder)) { distanceToParentBinder = -1; } if (distanceToParentPei > 0) { var peiBinder = elementBinderStack[elementBinderStack.length - distanceToParentPei]; if (lang_1.isPresent(peiBinder)) { parentProtoElementInjector = peiBinder.protoElementInjector; } } if (lang_1.isBlank(parentProtoElementInjector)) { distanceToParentPei = -1; } var componentDirectiveProvider = null; var isEmbeddedTemplate = false; var directiveProviders = beginElementCmd.directives.map(function (type) { return provideDirective(directiveResolver, type); }); if (beginElementCmd instanceof template_commands_1.BeginComponentCmd) { componentDirectiveProvider = directiveProviders[0]; } else if (beginElementCmd instanceof template_commands_1.EmbeddedTemplateCmd) { isEmbeddedTemplate = true; } var protoElementInjector = null; // Create a protoElementInjector for any element that either has bindings *or* has one // or more var- defined *or* for <template> elements: // - Elements with a var- defined need a their own element injector // so that, when hydrating, $implicit can be set to the element. // - <template> elements need their own ElementInjector so that we can query their TemplateRef var hasVariables = beginElementCmd.variableNameAndValues.length > 0; if (directiveProviders.length > 0 || hasVariables || isEmbeddedTemplate) { var directiveVariableBindings = new Map(); if (!isEmbeddedTemplate) { directiveVariableBindings = createDirectiveVariableBindings(beginElementCmd.variableNameAndValues, directiveProviders); } protoElementInjector = element_injector_1.ProtoElementInjector.create(parentProtoElementInjector, boundElementIndex, directiveProviders, lang_1.isPresent(componentDirectiveProvider), distanceToParentPei, directiveVariableBindings); protoElementInjector.attributes = arrayToMap(beginElementCmd.attrNameAndValues, false); } return new element_binder_1.ElementBinder(boundElementIndex, parentElementBinder, distanceToParentBinder, protoElementInjector, componentDirectiveProvider, nestedProtoView); } function provideDirective(directiveResolver, type) { var annotation = directiveResolver.resolve(type); return element_injector_1.DirectiveProvider.createFromType(type, annotation); } function createDirectiveVariableBindings(variableNameAndValues, directiveProviders) { var directiveVariableBindings = new Map(); for (var i = 0; i < variableNameAndValues.length; i += 2) { var templateName = variableNameAndValues[i]; var dirIndex = variableNameAndValues[i + 1]; if (lang_1.isNumber(dirIndex)) { directiveVariableBindings.set(templateName, dirIndex); } else { // a variable without a directive index -> reference the element directiveVariableBindings.set(templateName, null); } } return directiveVariableBindings; } exports.createDirectiveVariableBindings = createDirectiveVariableBindings; function arrayToMap(arr, inverse) { var result = new Map(); for (var i = 0; i < arr.length; i += 2) { if (inverse) { result.set(arr[i + 1], arr[i]); } else { result.set(arr[i], arr[i + 1]); } } return result; } function _flattenArray(tree, out) { for (var i = 0; i < tree.length; i++) { var item = di_1.resolveForwardRef(tree[i]); if (lang_1.isArray(item)) { _flattenArray(item, out); } else { out.push(item); } } } function _flattenStyleArr(arr, out) { for (var i = 0; i < arr.length; i++) { var entry = arr[i]; if (lang_1.isArray(entry)) { _flattenStyleArr(entry, out); } else { out.push(entry); } } return out; } //# sourceMappingURL=proto_view_factory.js.map