-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(core/util/bundler): clean code and support nested arrays resolution
- export bundler function as Public API
- Loading branch information
Showing
3 changed files
with
130 additions
and
140 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
export * from './src/core/di'; | ||
export { bundle } from './src/core/util' | ||
export { | ||
Directive, | ||
Component, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,158 +1,44 @@ | ||
import { global, isArray, isString, isType } from '../../facade/lang'; | ||
import { global } from '../../facade/lang'; | ||
import { reflector } from '../reflection/reflection'; | ||
import { ComponentMetadata } from '../directives/metadata_directives'; | ||
import { getInjectableName, provide } from '../di/provider'; | ||
import { isProviderLiteral, createProvider, ProviderLiteral } from '../di/provider_util'; | ||
import { resolveReflectiveProvider } from '../di/reflective_provider'; | ||
import { getNgModuleMethodByType } from '../di/provider'; | ||
import { _isTypeRegistered, _normalizeProviders, _getNgModuleMetadataByType } from '../di/reflective_provider'; | ||
import { ListWrapper } from '../../facade/collections'; | ||
|
||
export function bundle( ComponentClass: Type, otherProviders: any[] = [], Module?: ng.IModule ): ng.IModule { | ||
export function bundle( ComponentClass: Type, otherProviders: any[] = [], NgModule?: ng.IModule ): ng.IModule { | ||
|
||
const ngModuleName = getInjectableName( ComponentClass ); | ||
const ngModule = Module || global.angular.module( ngModuleName, [] ); | ||
const ngModule = NgModule || global.angular.module( ngModuleName, [] ); | ||
const annotations = reflector.annotations( ComponentClass ); | ||
const cmpAnnotation: ComponentMetadata = annotations[ 0 ]; | ||
const { directives = [], pipes = [], providers = [], viewProviders = [] }={} = cmpAnnotation; | ||
|
||
// console.log( 'directives:', directives ); | ||
// console.log( 'pipes:', pipes ); | ||
// console.log( 'providers:', providers ); | ||
// console.log( 'viewProviders:', viewProviders ); | ||
|
||
|
||
// process component | ||
const cmpProvider = provide( ComponentClass ); | ||
const [cmpName,cmpFactoryFn] = provide( ComponentClass ); | ||
const { providerName, providerMethod, moduleMethod } = _getNgModuleMetadataByType( ComponentClass ); | ||
|
||
if ( isTypeRegistered( cmpProvider[ 0 ], ngModule, '$compileProvider', 'directive' ) ) { | ||
if ( _isTypeRegistered( cmpName, ngModule, providerName, providerMethod ) ) { | ||
return ngModule; | ||
} | ||
|
||
ngModule.directive( cmpProvider[ 0 ], cmpProvider[ 1 ] ); | ||
|
||
|
||
// 1. process component tree | ||
|
||
// step through all providers | ||
providers.forEach( ( ProviderType ) => { | ||
|
||
// @TODO | ||
// recursive | ||
if ( isArray( ProviderType ) ) { | ||
return; | ||
} | ||
|
||
if ( isString( ProviderType ) ) { | ||
ngModule.requires.push( ProviderType ); | ||
return; | ||
} | ||
|
||
if ( isProviderLiteral( ProviderType ) ) { | ||
const provider = createProvider( ProviderType ); | ||
const { method, name, value } = resolveReflectiveProvider( provider ); | ||
if ( !isTypeRegistered( name, ngModule, '$provide', method ) ) { | ||
ngModule[ method ]( name, value ); | ||
} | ||
return; | ||
} | ||
|
||
const serviceProvider = provide( ProviderType ); | ||
if ( !isTypeRegistered( serviceProvider[ 0 ], ngModule, '$provide', 'service' ) ) { | ||
ngModule.service( ...provide( ProviderType ) ); | ||
} | ||
|
||
} ); | ||
// step through all viewProviders | ||
viewProviders.forEach( ( ViewProviderType ) => { | ||
|
||
// @TODO | ||
// recursive | ||
if ( isArray( ViewProviderType ) ) { | ||
return; | ||
} | ||
|
||
if ( isString( ViewProviderType ) ) { | ||
ngModule.requires.push( ViewProviderType ); | ||
return; | ||
} | ||
ngModule[moduleMethod]( cmpName, cmpFactoryFn ); | ||
|
||
if ( isProviderLiteral( ViewProviderType ) ) { | ||
const provider = createProvider( ViewProviderType ); | ||
const { method, name, value } = resolveReflectiveProvider( provider ); | ||
if ( !isTypeRegistered( name, ngModule, '$provide', method ) ) { | ||
ngModule[ method ]( name, value ); | ||
} | ||
return; | ||
} | ||
// 1. process component/directive decorator providers/viewProviders/pipes | ||
_normalizeProviders( ngModule, providers ); | ||
_normalizeProviders( ngModule, viewProviders ); | ||
_normalizeProviders( ngModule, pipes ); | ||
|
||
const serviceProvider = provide( ViewProviderType ); | ||
if ( !isTypeRegistered( serviceProvider[ 0 ], ngModule, '$provide', 'service' ) ) { | ||
ngModule.service( ...provide( ViewProviderType ) ); | ||
} | ||
|
||
} ); | ||
// step through all pipes | ||
pipes.forEach( ( PipeType: Type ) => { | ||
// @TODO | ||
// recursive | ||
if ( isArray( PipeType ) ) { | ||
return; | ||
} | ||
|
||
const pipeProvider = provide( PipeType ); | ||
if ( !isTypeRegistered( pipeProvider[ 0 ], ngModule, '$filterProvider', 'register' ) ) { | ||
ngModule.filter( ...provide( PipeType ) ); | ||
} | ||
} ); | ||
// step through all directives | ||
directives.forEach( ( directiveType: Type ) => { | ||
return bundle( directiveType, [], ngModule ); | ||
ListWrapper.flattenDeep(directives).forEach( ( directiveType: Type ) => { | ||
bundle( directiveType, [], ngModule ); | ||
} ); | ||
|
||
// 2. process otherProviders argument | ||
// - providers can be string(ngModule reference), Type, StringMap(providerLiteral) | ||
otherProviders.forEach( ( providerType: string|Type|ProviderLiteral|any[] ) => { | ||
if ( isString( providerType ) ) { | ||
ngModule.requires.push( providerType ); | ||
} | ||
if ( isType( providerType ) ) { | ||
ngModule[ getNgModuleMethodByType(providerType) ]( ...provide(providerType) ); | ||
} | ||
if ( isProviderLiteral( providerType ) ) { | ||
const provider = createProvider( providerType ); | ||
const { method, name, value } = resolveReflectiveProvider( provider ); | ||
ngModule[ method ]( name, value ); | ||
} | ||
// @TODO | ||
// recursive | ||
if ( isArray( providerType ) ) { | ||
|
||
} | ||
} ); | ||
// - directives can't be registered as via global providers only @Injectable,@Pipe,{provide:any,use*:any} | ||
// registerProviders(ngModule, otherProviders); | ||
_normalizeProviders( ngModule, otherProviders ); | ||
|
||
return ngModule; | ||
|
||
} | ||
|
||
function isTypeRegistered( | ||
findRegisteredType: string, | ||
ngModule: ng.IModule, | ||
instanceType: string, | ||
methodName: string | ||
): boolean { | ||
const invokeQueue: any[] = (ngModule as any)._invokeQueue; | ||
const types = invokeQueue | ||
.filter( ( [type,fnName]:[string,string] ) => { | ||
return type === instanceType && fnName === methodName; | ||
} ) | ||
.map( ( [type,fnName, registeredProvider]:[string,string,[string,any]] ) => { | ||
return registeredProvider | ||
} ); | ||
|
||
return types.some( ( [typeName,typeFn] )=> { | ||
return findRegisteredType === typeName; | ||
} ) | ||
} | ||
|
||
function registerProvider( ngModule: ng.IModule, provider: any ): void { | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters