44 * import { ngAspnetCoreEngine } from `@ng-universal/ng-aspnetcore-engine`;
55 */
66
7- import { Type , NgModuleRef , ApplicationRef , Provider } from '@angular/core' ;
8- import { platformDynamicServer , PlatformState } from '@angular/platform-server' ;
7+ import { Type , NgModuleFactory , NgModuleRef , ApplicationRef , Provider } from '@angular/core' ;
8+ import { platformServer , platformDynamicServer , PlatformState } from '@angular/platform-server' ;
99
1010export function ngAspnetCoreEngine (
1111 providers : Provider [ ] ,
@@ -109,5 +109,112 @@ export function ngAspnetCoreEngine(
109109 reject ( err ) ;
110110 } ) ;
111111
112+ } ) ;
113+ }
114+
115+ // Temporary - these will be combined in what will be the official npm version in `angular/universal` repo
116+
117+ export function ngAspnetCoreEngineAoT (
118+ providers : Provider [ ] ,
119+ ngModule : NgModuleFactory < { } >
120+ ) : Promise < { html : string , globals : { styles : string , title : string , meta : string , [ key : string ] : any } } > {
121+
122+ return new Promise ( ( resolve , reject ) => {
123+
124+ const platform = platformServer ( providers ) ;
125+
126+ return platform . bootstrapModuleFactory ( ngModule ) . then ( ( moduleRef : NgModuleRef < { } > ) => {
127+
128+ const state : PlatformState = moduleRef . injector . get ( PlatformState ) ;
129+ const appRef : ApplicationRef = moduleRef . injector . get ( ApplicationRef ) ;
130+
131+ appRef . isStable
132+ . filter ( ( isStable : boolean ) => isStable )
133+ . first ( )
134+ . subscribe ( ( stable ) => {
135+
136+ // Fire the TransferCache
137+ const bootstrap = moduleRef . instance [ 'ngOnBootstrap' ] ;
138+ bootstrap && bootstrap ( ) ;
139+
140+ // The parse5 Document itself
141+ const AST_DOCUMENT = state . getDocument ( ) ;
142+
143+ // Strip out the Angular application
144+ const htmlDoc = state . renderToString ( ) ;
145+
146+ const APP_HTML = htmlDoc . substring (
147+ htmlDoc . indexOf ( '<body>' ) + 6 ,
148+ htmlDoc . indexOf ( '</body>' )
149+ ) ;
150+
151+ // Strip out Styles / Meta-tags / Title
152+ const STYLES = [ ] ;
153+ const META = [ ] ;
154+ const LINKS = [ ] ;
155+ let TITLE = '' ;
156+
157+ const STYLES_STRING = htmlDoc . substring (
158+ htmlDoc . indexOf ( '<style ng-transition' ) ,
159+ htmlDoc . lastIndexOf ( '</style>' ) + 8
160+ ) ;
161+
162+ const HEAD = AST_DOCUMENT . head ;
163+
164+ let count = 0 ;
165+
166+ for ( let i = 0 ; i < HEAD . children . length ; i ++ ) {
167+ let element = HEAD . children [ i ] ;
168+
169+ if ( element . name === 'title' ) {
170+ TITLE = element . children [ 0 ] . data ;
171+ }
172+
173+ // Broken after 4.0 (worked in rc)
174+ // if (element.name === 'style') {
175+ // let styleTag = '<style ';
176+ // for (let key in element.attribs) {
177+ // styleTag += `${key}="${element.attribs[key]}">`;
178+ // }
179+
180+ // styleTag += `${element.children[0].data}</style>`;
181+ // STYLES.push(styleTag);
182+ // }
183+
184+ if ( element . name === 'meta' ) {
185+ count = count + 1 ;
186+ let metaString = '<meta' ;
187+ for ( let key in element . attribs ) {
188+ metaString += ` ${ key } ="${ element . attribs [ key ] } "` ;
189+ }
190+ META . push ( `${ metaString } />\n` ) ;
191+ }
192+
193+ if ( element . name === 'link' ) {
194+ let linkString = '<link' ;
195+ for ( let key in element . attribs ) {
196+ linkString += ` ${ key } ="${ element . attribs [ key ] } "` ;
197+ }
198+ LINKS . push ( `${ linkString } />\n` ) ;
199+ }
200+ }
201+
202+ resolve ( {
203+ html : APP_HTML ,
204+ globals : {
205+ styles : STYLES_STRING ,
206+ title : TITLE ,
207+ meta : META . join ( ' ' ) ,
208+ links : LINKS . join ( ' ' )
209+ }
210+ } ) ;
211+
212+ moduleRef . destroy ( ) ;
213+
214+ } ) ;
215+ } ) . catch ( err => {
216+ reject ( err ) ;
217+ } ) ;
218+
112219 } ) ;
113220}
0 commit comments