@ -52,11 +52,15 @@ export class DominoAdapter extends BrowserDomAdapter {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
logGroup(error: string) { console.error(error); }
|
||||
logGroup(error: string) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
logGroupEnd() {}
|
||||
|
||||
supportsDOMEvents(): boolean { return false; }
|
||||
supportsDOMEvents(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
createHtmlDocument(): HTMLDocument {
|
||||
return parseDocument('<html><head><title>fakeTitle</title></head><body></body></html>');
|
||||
@ -72,7 +76,9 @@ export class DominoAdapter extends BrowserDomAdapter {
|
||||
isElementNode(node: any): boolean {
|
||||
return node ? node.nodeType === DominoAdapter.defaultDoc.ELEMENT_NODE : false;
|
||||
}
|
||||
isShadowRoot(node: any): boolean { return node.shadowRoot == node; }
|
||||
isShadowRoot(node: any): boolean {
|
||||
return node.shadowRoot == node;
|
||||
}
|
||||
|
||||
getProperty(el: Element, name: string): any {
|
||||
if (name === 'href') {
|
||||
@ -100,10 +106,10 @@ export class DominoAdapter extends BrowserDomAdapter {
|
||||
}
|
||||
|
||||
getBaseHref(doc: Document): string {
|
||||
const base = doc.documentElement !.querySelector('base');
|
||||
const base = doc.documentElement!.querySelector('base');
|
||||
let href = '';
|
||||
if (base) {
|
||||
href = base.getAttribute('href') !;
|
||||
href = base.getAttribute('href')!;
|
||||
}
|
||||
// TODO(alxhub): Need relative path logic from BrowserDomAdapter here?
|
||||
return href;
|
||||
@ -120,12 +126,24 @@ export class DominoAdapter extends BrowserDomAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
getHistory(): History { throw _notImplemented('getHistory'); }
|
||||
getLocation(): Location { throw _notImplemented('getLocation'); }
|
||||
getUserAgent(): string { return 'Fake user agent'; }
|
||||
getHistory(): History {
|
||||
throw _notImplemented('getHistory');
|
||||
}
|
||||
getLocation(): Location {
|
||||
throw _notImplemented('getLocation');
|
||||
}
|
||||
getUserAgent(): string {
|
||||
return 'Fake user agent';
|
||||
}
|
||||
|
||||
performanceNow(): number { return Date.now(); }
|
||||
performanceNow(): number {
|
||||
return Date.now();
|
||||
}
|
||||
|
||||
supportsCookies(): boolean { return false; }
|
||||
getCookie(name: string): string { throw _notImplemented('getCookie'); }
|
||||
supportsCookies(): boolean {
|
||||
return false;
|
||||
}
|
||||
getCookie(name: string): string {
|
||||
throw _notImplemented('getCookie');
|
||||
}
|
||||
}
|
||||
|
@ -17,13 +17,15 @@ import {Observable, Observer, Subscription} from 'rxjs';
|
||||
|
||||
@Injectable()
|
||||
export class ServerXhr implements XhrFactory {
|
||||
build(): XMLHttpRequest { return new xhr2.XMLHttpRequest(); }
|
||||
build(): XMLHttpRequest {
|
||||
return new xhr2.XMLHttpRequest();
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class ZoneMacroTaskWrapper<S, R> {
|
||||
wrap(request: S): Observable<R> {
|
||||
return new Observable((observer: Observer<R>) => {
|
||||
let task: Task = null !;
|
||||
let task: Task = null!;
|
||||
let scheduled: boolean = false;
|
||||
let sub: Subscription|null = null;
|
||||
let savedResult: any = null;
|
||||
@ -100,9 +102,13 @@ export abstract class ZoneMacroTaskWrapper<S, R> {
|
||||
|
||||
export class ZoneClientBackend extends
|
||||
ZoneMacroTaskWrapper<HttpRequest<any>, HttpEvent<any>> implements HttpBackend {
|
||||
constructor(private backend: HttpBackend) { super(); }
|
||||
constructor(private backend: HttpBackend) {
|
||||
super();
|
||||
}
|
||||
|
||||
handle(request: HttpRequest<any>): Observable<HttpEvent<any>> { return this.wrap(request); }
|
||||
handle(request: HttpRequest<any>): Observable<HttpEvent<any>> {
|
||||
return this.wrap(request);
|
||||
}
|
||||
|
||||
protected delegate(request: HttpRequest<any>): Observable<HttpEvent<any>> {
|
||||
return this.backend.handle(request);
|
||||
@ -115,9 +121,6 @@ export function zoneWrappedInterceptingHandler(backend: HttpBackend, injector: I
|
||||
}
|
||||
|
||||
export const SERVER_HTTP_PROVIDERS: Provider[] = [
|
||||
{provide: XhrFactory, useClass: ServerXhr}, {
|
||||
provide: HttpHandler,
|
||||
useFactory: zoneWrappedInterceptingHandler,
|
||||
deps: [HttpBackend, Injector]
|
||||
}
|
||||
{provide: XhrFactory, useClass: ServerXhr},
|
||||
{provide: HttpHandler, useFactory: zoneWrappedInterceptingHandler, deps: [HttpBackend, Injector]}
|
||||
];
|
||||
|
@ -54,34 +54,40 @@ export class ServerPlatformLocation implements PlatformLocation {
|
||||
}
|
||||
}
|
||||
|
||||
getBaseHrefFromDOM(): string { return getDOM().getBaseHref(this._doc) !; }
|
||||
getBaseHrefFromDOM(): string {
|
||||
return getDOM().getBaseHref(this._doc)!;
|
||||
}
|
||||
|
||||
onPopState(fn: LocationChangeListener): void {
|
||||
// No-op: a state stack is not implemented, so
|
||||
// no events will ever come.
|
||||
}
|
||||
|
||||
onHashChange(fn: LocationChangeListener): void { this._hashUpdate.subscribe(fn); }
|
||||
onHashChange(fn: LocationChangeListener): void {
|
||||
this._hashUpdate.subscribe(fn);
|
||||
}
|
||||
|
||||
get url(): string { return `${this.pathname}${this.search}${this.hash}`; }
|
||||
get url(): string {
|
||||
return `${this.pathname}${this.search}${this.hash}`;
|
||||
}
|
||||
|
||||
private setHash(value: string, oldUrl: string) {
|
||||
if (this.hash === value) {
|
||||
// Don't fire events if the hash has not changed.
|
||||
return;
|
||||
}
|
||||
(this as{hash: string}).hash = value;
|
||||
(this as {hash: string}).hash = value;
|
||||
const newUrl = this.url;
|
||||
scheduleMicroTask(() => this._hashUpdate.next({
|
||||
type: 'hashchange', state: null, oldUrl, newUrl
|
||||
} as LocationChangeEvent));
|
||||
scheduleMicroTask(
|
||||
() => this._hashUpdate.next(
|
||||
{type: 'hashchange', state: null, oldUrl, newUrl} as LocationChangeEvent));
|
||||
}
|
||||
|
||||
replaceState(state: any, title: string, newUrl: string): void {
|
||||
const oldUrl = this.url;
|
||||
const parsedUrl = parseUrl(newUrl);
|
||||
(this as{pathname: string}).pathname = parsedUrl.pathname;
|
||||
(this as{search: string}).search = parsedUrl.search;
|
||||
(this as {pathname: string}).pathname = parsedUrl.pathname;
|
||||
(this as {search: string}).search = parsedUrl.search;
|
||||
this.setHash(parsedUrl.hash, oldUrl);
|
||||
}
|
||||
|
||||
@ -89,12 +95,18 @@ export class ServerPlatformLocation implements PlatformLocation {
|
||||
this.replaceState(state, title, newUrl);
|
||||
}
|
||||
|
||||
forward(): void { throw new Error('Not implemented'); }
|
||||
forward(): void {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
back(): void { throw new Error('Not implemented'); }
|
||||
back(): void {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
// History API isn't available on server, therefore return undefined
|
||||
getState(): unknown { return undefined; }
|
||||
getState(): unknown {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export function scheduleMicroTask(fn: Function) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
export {PlatformState} from './platform_state';
|
||||
export {ServerModule, platformDynamicServer, platformServer} from './server';
|
||||
export {platformDynamicServer, platformServer, ServerModule} from './server';
|
||||
export {BEFORE_APP_SERIALIZED, INITIAL_CONFIG, PlatformConfig} from './tokens';
|
||||
export {ServerTransferStateModule} from './transfer_state';
|
||||
export {renderModule, renderModuleFactory} from './utils';
|
||||
|
@ -23,10 +23,14 @@ export class PlatformState {
|
||||
/**
|
||||
* Renders the current state of the platform to string.
|
||||
*/
|
||||
renderToString(): string { return serializeDocument(this._doc); }
|
||||
renderToString(): string {
|
||||
return serializeDocument(this._doc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current DOM state.
|
||||
*/
|
||||
getDocument(): any { return this._doc; }
|
||||
getDocument(): any {
|
||||
return this._doc;
|
||||
}
|
||||
}
|
||||
|
@ -7,9 +7,9 @@
|
||||
*/
|
||||
|
||||
import {ɵAnimationEngine} from '@angular/animations/browser';
|
||||
import {DOCUMENT, PlatformLocation, ViewportScroller, ɵNullViewportScroller as NullViewportScroller, ɵPLATFORM_SERVER_ID as PLATFORM_SERVER_ID, ɵgetDOM as getDOM} from '@angular/common';
|
||||
import {DOCUMENT, PlatformLocation, ViewportScroller, ɵgetDOM as getDOM, ɵNullViewportScroller as NullViewportScroller, ɵPLATFORM_SERVER_ID as PLATFORM_SERVER_ID} from '@angular/common';
|
||||
import {HttpClientModule} from '@angular/common/http';
|
||||
import {Injector, NgModule, NgZone, Optional, PLATFORM_ID, PLATFORM_INITIALIZER, PlatformRef, Provider, RendererFactory2, StaticProvider, Testability, createPlatformFactory, platformCore, ɵALLOW_MULTIPLE_PLATFORMS as ALLOW_MULTIPLE_PLATFORMS, ɵsetDocument} from '@angular/core';
|
||||
import {createPlatformFactory, Injector, NgModule, NgZone, Optional, PLATFORM_ID, PLATFORM_INITIALIZER, platformCore, PlatformRef, Provider, RendererFactory2, StaticProvider, Testability, ɵALLOW_MULTIPLE_PLATFORMS as ALLOW_MULTIPLE_PLATFORMS, ɵsetDocument} from '@angular/core';
|
||||
import {BrowserModule, EVENT_MANAGER_PLUGINS, ɵSharedStylesHost as SharedStylesHost} from '@angular/platform-browser';
|
||||
import {ɵplatformCoreDynamic as platformCoreDynamic} from '@angular/platform-browser-dynamic';
|
||||
import {NoopAnimationsModule, ɵAnimationRendererFactory} from '@angular/platform-browser/animations';
|
||||
@ -41,7 +41,9 @@ export const INTERNAL_SERVER_PLATFORM_PROVIDERS: StaticProvider[] = [
|
||||
];
|
||||
|
||||
function initDominoAdapter(injector: Injector) {
|
||||
return () => { DominoAdapter.makeCurrent(); };
|
||||
return () => {
|
||||
DominoAdapter.makeCurrent();
|
||||
};
|
||||
}
|
||||
|
||||
export function instantiateServerRendererFactory(
|
||||
@ -91,7 +93,7 @@ function _document(injector: Injector) {
|
||||
/**
|
||||
* @publicApi
|
||||
*/
|
||||
export const platformServer: (extraProviders?: StaticProvider[] | undefined) => PlatformRef =
|
||||
export const platformServer: (extraProviders?: StaticProvider[]|undefined) => PlatformRef =
|
||||
createPlatformFactory(platformCore, 'server', INTERNAL_SERVER_PLATFORM_PROVIDERS);
|
||||
|
||||
/**
|
||||
|
@ -14,7 +14,9 @@ export class ServerEventManagerPlugin /* extends EventManagerPlugin which is pri
|
||||
constructor(@Inject(DOCUMENT) private doc: any) {}
|
||||
|
||||
// Handle all events on the server.
|
||||
supports(eventName: string) { return true; }
|
||||
supports(eventName: string) {
|
||||
return true;
|
||||
}
|
||||
|
||||
addEventListener(element: HTMLElement, eventName: string, handler: Function): Function {
|
||||
return getDOM().onAndCancel(element, eventName, handler);
|
||||
|
@ -9,7 +9,7 @@
|
||||
import {DOCUMENT, ɵgetDOM as getDOM} from '@angular/common';
|
||||
import {DomElementSchemaRegistry} from '@angular/compiler';
|
||||
import {Inject, Injectable, NgZone, Renderer2, RendererFactory2, RendererStyleFlags2, RendererType2, ViewEncapsulation} from '@angular/core';
|
||||
import {EventManager, ɵNAMESPACE_URIS as NAMESPACE_URIS, ɵSharedStylesHost as SharedStylesHost, ɵflattenStyles as flattenStyles, ɵshimContentAttribute as shimContentAttribute, ɵshimHostAttribute as shimHostAttribute} from '@angular/platform-browser';
|
||||
import {EventManager, ɵflattenStyles as flattenStyles, ɵNAMESPACE_URIS as NAMESPACE_URIS, ɵSharedStylesHost as SharedStylesHost, ɵshimContentAttribute as shimContentAttribute, ɵshimHostAttribute as shimHostAttribute} from '@angular/platform-browser';
|
||||
|
||||
const EMPTY_ARRAY: any[] = [];
|
||||
|
||||
@ -90,7 +90,9 @@ class DefaultServerRenderer2 implements Renderer2 {
|
||||
return doc.createTextNode(value);
|
||||
}
|
||||
|
||||
appendChild(parent: any, newChild: any): void { parent.appendChild(newChild); }
|
||||
appendChild(parent: any, newChild: any): void {
|
||||
parent.appendChild(newChild);
|
||||
}
|
||||
|
||||
insertBefore(parent: any, newChild: any, refChild: any): void {
|
||||
if (parent) {
|
||||
@ -120,9 +122,13 @@ class DefaultServerRenderer2 implements Renderer2 {
|
||||
return el;
|
||||
}
|
||||
|
||||
parentNode(node: any): any { return node.parentNode; }
|
||||
parentNode(node: any): any {
|
||||
return node.parentNode;
|
||||
}
|
||||
|
||||
nextSibling(node: any): any { return node.nextSibling; }
|
||||
nextSibling(node: any): any {
|
||||
return node.nextSibling;
|
||||
}
|
||||
|
||||
setAttribute(el: any, name: string, value: string, namespace?: string): void {
|
||||
if (namespace) {
|
||||
@ -144,9 +150,13 @@ class DefaultServerRenderer2 implements Renderer2 {
|
||||
}
|
||||
}
|
||||
|
||||
addClass(el: any, name: string): void { el.classList.add(name); }
|
||||
addClass(el: any, name: string): void {
|
||||
el.classList.add(name);
|
||||
}
|
||||
|
||||
removeClass(el: any, name: string): void { el.classList.remove(name); }
|
||||
removeClass(el: any, name: string): void {
|
||||
el.classList.remove(name);
|
||||
}
|
||||
|
||||
setStyle(el: any, style: string, value: any, flags: RendererStyleFlags2): void {
|
||||
style = style.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
||||
@ -189,7 +199,9 @@ class DefaultServerRenderer2 implements Renderer2 {
|
||||
}
|
||||
}
|
||||
|
||||
setValue(node: any, value: string): void { node.textContent = value; }
|
||||
setValue(node: any, value: string): void {
|
||||
node.textContent = value;
|
||||
}
|
||||
|
||||
listen(
|
||||
target: 'document'|'window'|'body'|any, eventName: string,
|
||||
@ -200,7 +212,7 @@ class DefaultServerRenderer2 implements Renderer2 {
|
||||
target, eventName, this.decoratePreventDefault(callback));
|
||||
}
|
||||
return <() => void>this.eventManager.addEventListener(
|
||||
target, eventName, this.decoratePreventDefault(callback)) as() => void;
|
||||
target, eventName, this.decoratePreventDefault(callback)) as () => void;
|
||||
}
|
||||
|
||||
private decoratePreventDefault(eventHandler: Function): Function {
|
||||
@ -227,8 +239,8 @@ class DefaultServerRenderer2 implements Renderer2 {
|
||||
const AT_CHARCODE = '@'.charCodeAt(0);
|
||||
function checkNoSyntheticProp(name: string, nameKind: string) {
|
||||
if (name.charCodeAt(0) === AT_CHARCODE) {
|
||||
throw new Error(
|
||||
`Found the synthetic ${nameKind} ${name}. Please include either "BrowserAnimationsModule" or "NoopAnimationsModule" in your application.`);
|
||||
throw new Error(`Found the synthetic ${nameKind} ${
|
||||
name}. Please include either "BrowserAnimationsModule" or "NoopAnimationsModule" in your application.`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -249,7 +261,9 @@ class EmulatedEncapsulationServerRenderer2 extends DefaultServerRenderer2 {
|
||||
this.hostAttr = shimHostAttribute(componentId);
|
||||
}
|
||||
|
||||
applyToHost(element: any) { super.setAttribute(element, this.hostAttr, ''); }
|
||||
applyToHost(element: any) {
|
||||
super.setAttribute(element, this.hostAttr, '');
|
||||
}
|
||||
|
||||
createElement(parent: any, name: string): Element {
|
||||
const el = super.createElement(parent, name, this.document);
|
||||
|
@ -31,5 +31,7 @@ export class ServerStylesHost extends SharedStylesHost {
|
||||
this.head.appendChild(el);
|
||||
}
|
||||
|
||||
onStylesAdded(additions: Set<string>) { additions.forEach(style => this._addStyle(style)); }
|
||||
onStylesAdded(additions: Set<string>) {
|
||||
additions.forEach(style => this._addStyle(style));
|
||||
}
|
||||
}
|
||||
|
@ -77,8 +77,9 @@ the server-rendered app can be properly bootstrapped into a client app.`);
|
||||
|
||||
return Promise
|
||||
.all(asyncPromises.map(asyncPromise => {
|
||||
return asyncPromise.catch(
|
||||
e => { console.warn('Ignoring BEFORE_APP_SERIALIZED Exception: ', e); });
|
||||
return asyncPromise.catch(e => {
|
||||
console.warn('Ignoring BEFORE_APP_SERIALIZED Exception: ', e);
|
||||
});
|
||||
}))
|
||||
.then(complete);
|
||||
});
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {NgModule, PlatformRef, StaticProvider, createPlatformFactory} from '@angular/core';
|
||||
import {createPlatformFactory, NgModule, PlatformRef, StaticProvider} from '@angular/core';
|
||||
import {BrowserDynamicTestingModule, ɵplatformCoreDynamicTesting as platformCoreDynamicTesting} from '@angular/platform-browser-dynamic/testing';
|
||||
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
|
||||
import {ɵINTERNAL_SERVER_PLATFORM_PROVIDERS as INTERNAL_SERVER_PLATFORM_PROVIDERS, ɵSERVER_RENDER_PROVIDERS as SERVER_RENDER_PROVIDERS} from '@angular/platform-server';
|
||||
|
Reference in New Issue
Block a user