/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {AnimationBuilder, animate, state, style, transition, trigger} from '@angular/animations';
import {PlatformLocation, isPlatformServer} from '@angular/common';
import {HTTP_INTERCEPTORS, HttpClient, HttpClientModule, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing';
import {ApplicationRef, CompilerFactory, Component, HostListener, Inject, Injectable, Input, NgModule, NgModuleRef, NgZone, PLATFORM_ID, PlatformRef, ViewEncapsulation, destroyPlatform, getPlatform} from '@angular/core';
import {async, inject} from '@angular/core/testing';
import {Http, HttpModule, Response, ResponseOptions, XHRBackend} from '@angular/http';
import {MockBackend, MockConnection} from '@angular/http/testing';
import {BrowserModule, DOCUMENT, Title, TransferState, makeStateKey} from '@angular/platform-browser';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
import {BEFORE_APP_SERIALIZED, INITIAL_CONFIG, PlatformState, ServerModule, ServerTransferStateModule, platformDynamicServer, renderModule, renderModuleFactory} from '@angular/platform-server';
import {fixmeIvy, ivyEnabled, modifiedInIvy} from '@angular/private/testing';
import {Observable} from 'rxjs';
import {first} from 'rxjs/operators';
@Component({selector: 'app', template: `Works!`})
class MyServerApp {
}
@NgModule({
bootstrap: [MyServerApp],
declarations: [MyServerApp],
imports: [ServerModule],
providers: [
MockBackend,
{provide: XHRBackend, useExisting: MockBackend},
]
})
class ExampleModule {
}
function getTitleRenderHook(doc: any) {
return () => {
// Set the title as part of the render hook.
doc.title = 'RenderHook';
};
}
function exceptionRenderHook() {
throw new Error('error');
}
function getMetaRenderHook(doc: any) {
return () => {
// Add a meta tag before rendering the document.
const metaElement = doc.createElement('meta');
metaElement.setAttribute('name', 'description');
doc.head.appendChild(metaElement);
};
}
@NgModule({
bootstrap: [MyServerApp],
declarations: [MyServerApp],
imports: [BrowserModule.withServerTransition({appId: 'render-hook'}), ServerModule],
providers: [
{provide: BEFORE_APP_SERIALIZED, useFactory: getTitleRenderHook, multi: true, deps: [DOCUMENT]},
]
})
class RenderHookModule {
}
@NgModule({
bootstrap: [MyServerApp],
declarations: [MyServerApp],
imports: [BrowserModule.withServerTransition({appId: 'render-hook'}), ServerModule],
providers: [
{provide: BEFORE_APP_SERIALIZED, useFactory: getTitleRenderHook, multi: true, deps: [DOCUMENT]},
{provide: BEFORE_APP_SERIALIZED, useValue: exceptionRenderHook, multi: true},
{provide: BEFORE_APP_SERIALIZED, useFactory: getMetaRenderHook, multi: true, deps: [DOCUMENT]},
]
})
class MultiRenderHookModule {
}
@Component({selector: 'app', template: `Works too!`})
class MyServerApp2 {
}
@NgModule({declarations: [MyServerApp2], imports: [ServerModule], bootstrap: [MyServerApp2]})
class ExampleModule2 {
}
@Component({selector: 'app', template: ``})
class TitleApp {
constructor(private title: Title) {}
ngOnInit() { this.title.setTitle('Test App Title'); }
}
@NgModule({declarations: [TitleApp], imports: [ServerModule], bootstrap: [TitleApp]})
class TitleAppModule {
}
@Component({selector: 'app', template: '{{text}}
'})
class MyAsyncServerApp {
text = '';
h1 = '';
@HostListener('window:scroll')
track() { console.error('scroll'); }
ngOnInit() {
Promise.resolve(null).then(() => setTimeout(() => {
this.text = 'Works!';
this.h1 = 'fine';
}, 10));
}
}
@NgModule({
declarations: [MyAsyncServerApp],
imports: [BrowserModule.withServerTransition({appId: 'async-server'}), ServerModule],
bootstrap: [MyAsyncServerApp]
})
class AsyncServerModule {
}
@Component({selector: 'app', template: ''})
class SVGComponent {
}
@NgModule({
declarations: [SVGComponent],
imports: [BrowserModule.withServerTransition({appId: 'svg-server'}), ServerModule],
bootstrap: [SVGComponent]
})
class SVGServerModule {
}
@Component({
selector: 'app',
template: `{{text}}
`,
animations: [trigger(
'myAnimation',
[
state('void', style({'opacity': '0'})),
state('active', style({
'opacity': '1', // simple supported property
'font-weight': 'bold', // property with dashed name
'transform': 'translate3d(0, 0, 0)', // not natively supported by Domino
})),
transition('void => *', [animate('0ms')]),
], )]
})
class MyAnimationApp {
state = 'active';
constructor(private builder: AnimationBuilder) {}
text = 'Works!';
}
@NgModule({
declarations: [MyAnimationApp],
imports: [BrowserModule.withServerTransition({appId: 'anim-server'}), ServerModule],
bootstrap: [MyAnimationApp]
})
class AnimationServerModule {
}
@Component({
selector: 'app',
template: `Works!
`,
styles: ['div {color: blue; } :host { color: red; }']
})
class MyStylesApp {
}
@NgModule({
declarations: [MyStylesApp],
imports: [BrowserModule.withServerTransition({appId: 'example-styles'}), ServerModule],
bootstrap: [MyStylesApp]
})
class ExampleStylesModule {
}
@NgModule({
bootstrap: [MyServerApp],
declarations: [MyServerApp],
imports: [HttpModule, ServerModule],
providers: [
MockBackend,
{provide: XHRBackend, useExisting: MockBackend},
]
})
export class HttpBeforeExampleModule {
}
@NgModule({
bootstrap: [MyServerApp],
declarations: [MyServerApp],
imports: [ServerModule, HttpModule],
providers: [
MockBackend,
{provide: XHRBackend, useExisting: MockBackend},
]
})
export class HttpAfterExampleModule {
}
@NgModule({
bootstrap: [MyServerApp],
declarations: [MyServerApp],
imports: [ServerModule, HttpClientModule, HttpClientTestingModule],
})
export class HttpClientExampleModule {
}
@Injectable()
export class MyHttpInterceptor implements HttpInterceptor {
constructor(private http: HttpClient) {}
intercept(req: HttpRequest, next: HttpHandler): Observable> {
return next.handle(req);
}
}
@NgModule({
bootstrap: [MyServerApp],
declarations: [MyServerApp],
imports: [ServerModule, HttpClientModule, HttpClientTestingModule],
providers: [
{provide: HTTP_INTERCEPTORS, multi: true, useClass: MyHttpInterceptor},
],
})
export class HttpInterceptorExampleModule {
}
@Component({selector: 'app', template: ``})
class ImageApp {
}
@NgModule({declarations: [ImageApp], imports: [ServerModule], bootstrap: [ImageApp]})
class ImageExampleModule {
}
@Component({
selector: 'app',
template: 'Native works',
encapsulation: ViewEncapsulation.Native,
styles: [':host { color: red; }']
})
class NativeEncapsulationApp {
}
@NgModule({
declarations: [NativeEncapsulationApp],
imports: [BrowserModule.withServerTransition({appId: 'test'}), ServerModule],
bootstrap: [NativeEncapsulationApp]
})
class NativeExampleModule {
}
@Component({selector: 'my-child', template: 'Works!'})
class MyChildComponent {
// TODO(issue/24571): remove '!'.
@Input() public attr !: boolean;
}
@Component({selector: 'app', template: ''})
class MyHostComponent {
}
@NgModule({
declarations: [MyHostComponent, MyChildComponent],
bootstrap: [MyHostComponent],
imports: [ServerModule, BrowserModule.withServerTransition({appId: 'false-attributes'})]
})
class FalseAttributesModule {
}
@Component({selector: 'app', template: ''})
class InnerTextComponent {
foo = 'Some text';
}
@NgModule({
declarations: [InnerTextComponent],
bootstrap: [InnerTextComponent],
imports: [ServerModule, BrowserModule.withServerTransition({appId: 'inner-text'})]
})
class InnerTextModule {
}
@Component({selector: 'app', template: ''})
class MyInputComponent {
@Input()
name = '';
}
@NgModule({
declarations: [MyInputComponent],
bootstrap: [MyInputComponent],
imports: [ServerModule, BrowserModule.withServerTransition({appId: 'name-attributes'})]
})
class NameModule {
}
@Component({selector: 'app', template: ''})
class HTMLTypesApp {
html = 'foo bar';
constructor(@Inject(DOCUMENT) doc: Document) {}
}
@NgModule({
declarations: [HTMLTypesApp],
imports: [BrowserModule.withServerTransition({appId: 'inner-html'}), ServerModule],
bootstrap: [HTMLTypesApp]
})
class HTMLTypesModule {
}
const TEST_KEY = makeStateKey('test');
const STRING_KEY = makeStateKey('testString');
@Component({selector: 'app', template: 'Works!'})
class TransferComponent {
constructor(private transferStore: TransferState) {}
ngOnInit() { this.transferStore.set(TEST_KEY, 10); }
}
@Component({selector: 'esc-app', template: 'Works!'})
class EscapedComponent {
constructor(private transferStore: TransferState) {}
ngOnInit() {
this.transferStore.set(STRING_KEY, '