UNPKG

angular2

Version:

Angular 2 - a web framework for modern web apps

344 lines (343 loc) 15.1 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; 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); } }; import { resolveForwardRef } from 'angular2/src/core/di'; import { Type, isBlank, isPresent, isArray, stringify, isString } from 'angular2/src/facade/lang'; import { StringMapWrapper } from 'angular2/src/facade/collection'; import { BaseException } from 'angular2/src/facade/exceptions'; import { NoAnnotationError } from 'angular2/src/core/di/reflective_exceptions'; import * as cpl from './compile_metadata'; import * as md from 'angular2/src/core/metadata/directives'; import * as dimd from 'angular2/src/core/metadata/di'; import { DirectiveResolver } from './directive_resolver'; import { PipeResolver } from './pipe_resolver'; import { ViewResolver } from './view_resolver'; import { hasLifecycleHook } from './directive_lifecycle_reflector'; import { LIFECYCLE_HOOKS_VALUES } from 'angular2/src/core/metadata/lifecycle_hooks'; import { reflector } from 'angular2/src/core/reflection/reflection'; import { Injectable, Inject, Optional } from 'angular2/src/core/di'; import { PLATFORM_DIRECTIVES, PLATFORM_PIPES } from 'angular2/src/core/platform_directives_and_pipes'; import { MODULE_SUFFIX, sanitizeIdentifier } from './util'; import { assertArrayOfStrings } from './assertions'; import { getUrlScheme } from 'angular2/src/compiler/url_resolver'; import { Provider } from 'angular2/src/core/di/provider'; import { constructDependencies } from 'angular2/src/core/di/reflective_provider'; import { SelfMetadata, HostMetadata, SkipSelfMetadata } from 'angular2/src/core/di/metadata'; import { ReflectorReader } from 'angular2/src/core/reflection/reflector_reader'; export let RuntimeMetadataResolver = class RuntimeMetadataResolver { constructor(_directiveResolver, _pipeResolver, _viewResolver, _platformDirectives, _platformPipes, _reflector) { this._directiveResolver = _directiveResolver; this._pipeResolver = _pipeResolver; this._viewResolver = _viewResolver; this._platformDirectives = _platformDirectives; this._platformPipes = _platformPipes; this._directiveCache = new Map(); this._pipeCache = new Map(); this._anonymousTypes = new Map(); this._anonymousTypeIndex = 0; if (isPresent(_reflector)) { this._reflector = _reflector; } else { this._reflector = reflector; } } sanitizeTokenName(token) { let identifier = stringify(token); if (identifier.indexOf('(') >= 0) { // case: anonymous functions! let found = this._anonymousTypes.get(token); if (isBlank(found)) { this._anonymousTypes.set(token, this._anonymousTypeIndex++); found = this._anonymousTypes.get(token); } identifier = `anonymous_token_${found}_`; } return sanitizeIdentifier(identifier); } getDirectiveMetadata(directiveType) { var meta = this._directiveCache.get(directiveType); if (isBlank(meta)) { var dirMeta = this._directiveResolver.resolve(directiveType); var moduleUrl = null; var templateMeta = null; var changeDetectionStrategy = null; var viewProviders = []; if (dirMeta instanceof md.ComponentMetadata) { assertArrayOfStrings('styles', dirMeta.styles); var cmpMeta = dirMeta; moduleUrl = calcModuleUrl(this._reflector, directiveType, cmpMeta); var viewMeta = this._viewResolver.resolve(directiveType); assertArrayOfStrings('styles', viewMeta.styles); templateMeta = new cpl.CompileTemplateMetadata({ encapsulation: viewMeta.encapsulation, template: viewMeta.template, templateUrl: viewMeta.templateUrl, styles: viewMeta.styles, styleUrls: viewMeta.styleUrls }); changeDetectionStrategy = cmpMeta.changeDetection; if (isPresent(dirMeta.viewProviders)) { viewProviders = this.getProvidersMetadata(dirMeta.viewProviders); } } var providers = []; if (isPresent(dirMeta.providers)) { providers = this.getProvidersMetadata(dirMeta.providers); } var queries = []; var viewQueries = []; if (isPresent(dirMeta.queries)) { queries = this.getQueriesMetadata(dirMeta.queries, false); viewQueries = this.getQueriesMetadata(dirMeta.queries, true); } meta = cpl.CompileDirectiveMetadata.create({ selector: dirMeta.selector, exportAs: dirMeta.exportAs, isComponent: isPresent(templateMeta), type: this.getTypeMetadata(directiveType, moduleUrl), template: templateMeta, changeDetection: changeDetectionStrategy, inputs: dirMeta.inputs, outputs: dirMeta.outputs, host: dirMeta.host, lifecycleHooks: LIFECYCLE_HOOKS_VALUES.filter(hook => hasLifecycleHook(hook, directiveType)), providers: providers, viewProviders: viewProviders, queries: queries, viewQueries: viewQueries }); this._directiveCache.set(directiveType, meta); } return meta; } getTypeMetadata(type, moduleUrl) { return new cpl.CompileTypeMetadata({ name: this.sanitizeTokenName(type), moduleUrl: moduleUrl, runtime: type, diDeps: this.getDependenciesMetadata(type, null) }); } getFactoryMetadata(factory, moduleUrl) { return new cpl.CompileFactoryMetadata({ name: this.sanitizeTokenName(factory), moduleUrl: moduleUrl, runtime: factory, diDeps: this.getDependenciesMetadata(factory, null) }); } getPipeMetadata(pipeType) { var meta = this._pipeCache.get(pipeType); if (isBlank(meta)) { var pipeMeta = this._pipeResolver.resolve(pipeType); var moduleUrl = this._reflector.importUri(pipeType); meta = new cpl.CompilePipeMetadata({ type: this.getTypeMetadata(pipeType, moduleUrl), name: pipeMeta.name, pure: pipeMeta.pure, lifecycleHooks: LIFECYCLE_HOOKS_VALUES.filter(hook => hasLifecycleHook(hook, pipeType)), }); this._pipeCache.set(pipeType, meta); } return meta; } getViewDirectivesMetadata(component) { var view = this._viewResolver.resolve(component); var directives = flattenDirectives(view, this._platformDirectives); for (var i = 0; i < directives.length; i++) { if (!isValidType(directives[i])) { throw new BaseException(`Unexpected directive value '${stringify(directives[i])}' on the View of component '${stringify(component)}'`); } } return directives.map(type => this.getDirectiveMetadata(type)); } getViewPipesMetadata(component) { var view = this._viewResolver.resolve(component); var pipes = flattenPipes(view, this._platformPipes); for (var i = 0; i < pipes.length; i++) { if (!isValidType(pipes[i])) { throw new BaseException(`Unexpected piped value '${stringify(pipes[i])}' on the View of component '${stringify(component)}'`); } } return pipes.map(type => this.getPipeMetadata(type)); } getDependenciesMetadata(typeOrFunc, dependencies) { var deps; try { deps = constructDependencies(typeOrFunc, dependencies); } catch (e) { if (e instanceof NoAnnotationError) { deps = []; } else { throw e; } } return deps.map((dep) => { var compileToken; var p = dep.properties.find(p => p instanceof dimd.AttributeMetadata); var isAttribute = false; if (isPresent(p)) { compileToken = this.getTokenMetadata(p.attributeName); isAttribute = true; } else { compileToken = this.getTokenMetadata(dep.key.token); } var compileQuery = null; var q = dep.properties.find(p => p instanceof dimd.QueryMetadata); if (isPresent(q)) { compileQuery = this.getQueryMetadata(q, null); } return new cpl.CompileDiDependencyMetadata({ isAttribute: isAttribute, isHost: dep.upperBoundVisibility instanceof HostMetadata, isSelf: dep.upperBoundVisibility instanceof SelfMetadata, isSkipSelf: dep.lowerBoundVisibility instanceof SkipSelfMetadata, isOptional: dep.optional, query: isPresent(q) && !q.isViewQuery ? compileQuery : null, viewQuery: isPresent(q) && q.isViewQuery ? compileQuery : null, token: compileToken }); }); } getTokenMetadata(token) { token = resolveForwardRef(token); var compileToken; if (isString(token)) { compileToken = new cpl.CompileTokenMetadata({ value: token }); } else { compileToken = new cpl.CompileTokenMetadata({ identifier: new cpl.CompileIdentifierMetadata({ runtime: token, name: this.sanitizeTokenName(token) }) }); } return compileToken; } getProvidersMetadata(providers) { return providers.map((provider) => { provider = resolveForwardRef(provider); if (isArray(provider)) { return this.getProvidersMetadata(provider); } else if (provider instanceof Provider) { return this.getProviderMetadata(provider); } else { return this.getTypeMetadata(provider, null); } }); } getProviderMetadata(provider) { var compileDeps; if (isPresent(provider.useClass)) { compileDeps = this.getDependenciesMetadata(provider.useClass, provider.dependencies); } else if (isPresent(provider.useFactory)) { compileDeps = this.getDependenciesMetadata(provider.useFactory, provider.dependencies); } return new cpl.CompileProviderMetadata({ token: this.getTokenMetadata(provider.token), useClass: isPresent(provider.useClass) ? this.getTypeMetadata(provider.useClass, null) : null, useValue: isPresent(provider.useValue) ? new cpl.CompileIdentifierMetadata({ runtime: provider.useValue }) : null, useFactory: isPresent(provider.useFactory) ? this.getFactoryMetadata(provider.useFactory, null) : null, useExisting: isPresent(provider.useExisting) ? this.getTokenMetadata(provider.useExisting) : null, deps: compileDeps, multi: provider.multi }); } getQueriesMetadata(queries, isViewQuery) { var compileQueries = []; StringMapWrapper.forEach(queries, (query, propertyName) => { if (query.isViewQuery === isViewQuery) { compileQueries.push(this.getQueryMetadata(query, propertyName)); } }); return compileQueries; } getQueryMetadata(q, propertyName) { var selectors; if (q.isVarBindingQuery) { selectors = q.varBindings.map(varName => this.getTokenMetadata(varName)); } else { selectors = [this.getTokenMetadata(q.selector)]; } return new cpl.CompileQueryMetadata({ selectors: selectors, first: q.first, descendants: q.descendants, propertyName: propertyName, read: isPresent(q.read) ? this.getTokenMetadata(q.read) : null }); } }; RuntimeMetadataResolver = __decorate([ Injectable(), __param(3, Optional()), __param(3, Inject(PLATFORM_DIRECTIVES)), __param(4, Optional()), __param(4, Inject(PLATFORM_PIPES)), __metadata('design:paramtypes', [DirectiveResolver, PipeResolver, ViewResolver, Array, Array, ReflectorReader]) ], RuntimeMetadataResolver); function flattenDirectives(view, platformDirectives) { let directives = []; if (isPresent(platformDirectives)) { flattenArray(platformDirectives, directives); } if (isPresent(view.directives)) { flattenArray(view.directives, directives); } return directives; } function flattenPipes(view, platformPipes) { let pipes = []; if (isPresent(platformPipes)) { flattenArray(platformPipes, pipes); } if (isPresent(view.pipes)) { flattenArray(view.pipes, pipes); } return pipes; } function flattenArray(tree, out) { for (var i = 0; i < tree.length; i++) { var item = resolveForwardRef(tree[i]); if (isArray(item)) { flattenArray(item, out); } else { out.push(item); } } } function isValidType(value) { return isPresent(value) && (value instanceof Type); } function calcModuleUrl(reflector, type, cmpMetadata) { var moduleId = cmpMetadata.moduleId; if (isPresent(moduleId)) { var scheme = getUrlScheme(moduleId); return isPresent(scheme) && scheme.length > 0 ? moduleId : `package:${moduleId}${MODULE_SUFFIX}`; } else { return reflector.importUri(type); } }