UNPKG

@angular/platform-server

Version:

Angular - library for using Angular in Node.js

1,470 lines (1,451 loc) 43.7 kB
/** * @license Angular v5.0.0-rc.8 * (c) 2010-2017 Google, Inc. https://angular.io/ * License: MIT */ import { APP_ID, ApplicationRef, Inject, Injectable, InjectionToken, Injector, NgModule, NgZone, Optional, PLATFORM_ID, PLATFORM_INITIALIZER, RendererFactory2, Testability, Version, ViewEncapsulation, createPlatformFactory, platformCore, ɵALLOW_MULTIPLE_PLATFORMS } from '@angular/core'; import { BrowserModule, DOCUMENT, TransferState, ɵBrowserDomAdapter, ɵNAMESPACE_URIS, ɵSharedStylesHost, ɵTRANSITION_ID, ɵescapeHtml, ɵflattenStyles, ɵgetDOM, ɵsetRootDomAdapter, ɵshimContentAttribute, ɵshimHostAttribute } from '@angular/platform-browser'; import { ɵAnimationEngine } from '@angular/animations/browser'; import { PlatformLocation, ɵPLATFORM_SERVER_ID } from '@angular/common'; import { HTTP_INTERCEPTORS, HttpBackend, HttpClientModule, HttpHandler, XhrFactory, ɵinterceptingHandler } from '@angular/common/http'; import { BrowserXhr, Http, HttpModule, ReadyState, RequestOptions, XHRBackend, XSRFStrategy } from '@angular/http'; import { ɵplatformCoreDynamic } from '@angular/platform-browser-dynamic'; import { NoopAnimationsModule, ɵAnimationRendererFactory } from '@angular/platform-browser/animations'; import { Observable } from 'rxjs/Observable'; import { Subject } from 'rxjs/Subject'; import { parse } from 'url'; import { DomElementSchemaRegistry } from '@angular/compiler'; import { filter } from 'rxjs/operator/filter'; import { first } from 'rxjs/operator/first'; import { toPromise } from 'rxjs/operator/toPromise'; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @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 */ const domino = require('domino'); /** * @param {?} methodName * @return {?} */ function _notImplemented(methodName) { return new Error('This method is not implemented in DominoAdapter: ' + methodName); } /** * Parses a document string to a Document object. * @param {?} html * @param {?=} url * @return {?} */ function parseDocument(html, url$$1 = '/') { let /** @type {?} */ window = domino.createWindow(html, url$$1); let /** @type {?} */ doc = window.document; return doc; } /** * Serializes a document to string. * @param {?} doc * @return {?} */ function serializeDocument(doc) { return (/** @type {?} */ (doc)).serialize(); } /** * DOM Adapter for the server platform based on https://github.com/fgnass/domino. */ class DominoAdapter extends ɵBrowserDomAdapter { /** * @return {?} */ static makeCurrent() { ɵsetRootDomAdapter(new DominoAdapter()); } /** * @param {?} error * @return {?} */ logError(error) { console.error(error); } /** * @param {?} error * @return {?} */ log(error) { // tslint:disable-next-line:no-console console.log(error); } /** * @param {?} error * @return {?} */ logGroup(error) { console.error(error); } /** * @return {?} */ logGroupEnd() { } /** * @return {?} */ supportsDOMEvents() { return false; } /** * @return {?} */ supportsNativeShadowDOM() { return false; } /** * @param {?} nodeA * @param {?} nodeB * @return {?} */ contains(nodeA, nodeB) { let /** @type {?} */ inner = nodeB; while (inner) { if (inner === nodeA) return true; inner = inner.parent; } return false; } /** * @return {?} */ createHtmlDocument() { return parseDocument('<html><head><title>fakeTitle</title></head><body></body></html>'); } /** * @return {?} */ getDefaultDocument() { if (!DominoAdapter.defaultDoc) { DominoAdapter.defaultDoc = domino.createDocument(); } return DominoAdapter.defaultDoc; } /** * @param {?} el * @param {?=} doc * @return {?} */ createShadowRoot(el, doc = document) { el.shadowRoot = doc.createDocumentFragment(); el.shadowRoot.parent = el; return el.shadowRoot; } /** * @param {?} el * @return {?} */ getShadowRoot(el) { return el.shadowRoot; } /** * @param {?} node * @return {?} */ isTextNode(node) { return node.nodeType === DominoAdapter.defaultDoc.TEXT_NODE; } /** * @param {?} node * @return {?} */ isCommentNode(node) { return node.nodeType === DominoAdapter.defaultDoc.COMMENT_NODE; } /** * @param {?} node * @return {?} */ isElementNode(node) { return node ? node.nodeType === DominoAdapter.defaultDoc.ELEMENT_NODE : false; } /** * @param {?} node * @return {?} */ hasShadowRoot(node) { return node.shadowRoot != null; } /** * @param {?} node * @return {?} */ isShadowRoot(node) { return this.getShadowRoot(node) == node; } /** * @param {?} el * @param {?} name * @return {?} */ getProperty(el, name) { if (name === 'href') { // Domino tries tp resolve href-s which we do not want. Just return the // atribute value. return this.getAttribute(el, 'href'); } else if (name === 'innerText') { // Domino does not support innerText. Just map it to textContent. return el.textContent; } return (/** @type {?} */ (el))[name]; } /** * @param {?} el * @param {?} name * @param {?} value * @return {?} */ setProperty(el, name, value) { if (name === 'href') { // Eventhough the server renderer reflects any properties to attributes // map 'href' to atribute just to handle when setProperty is directly called. this.setAttribute(el, 'href', value); } else if (name === 'innerText') { // Domino does not support innerText. Just map it to textContent. el.textContent = value; } (/** @type {?} */ (el))[name] = value; } /** * @param {?} doc * @param {?} target * @return {?} */ getGlobalEventTarget(doc, target) { if (target === 'window') { return doc.defaultView; } if (target === 'document') { return doc; } if (target === 'body') { return doc.body; } return null; } /** * @param {?} doc * @return {?} */ getBaseHref(doc) { const /** @type {?} */ base = this.querySelector(doc.documentElement, 'base'); let /** @type {?} */ href = ''; if (base) { href = this.getHref(base); } // TODO(alxhub): Need relative path logic from BrowserDomAdapter here? return href; } /** * \@internal * @param {?} element * @return {?} */ _readStyleAttribute(element) { const /** @type {?} */ styleMap = {}; const /** @type {?} */ styleAttribute = element.getAttribute('style'); if (styleAttribute) { const /** @type {?} */ styleList = styleAttribute.split(/;+/g); for (let /** @type {?} */ i = 0; i < styleList.length; i++) { if (styleList[i].length > 0) { const /** @type {?} */ style = /** @type {?} */ (styleList[i]); const /** @type {?} */ colon = style.indexOf(':'); if (colon === -1) { throw new Error(`Invalid CSS style: ${style}`); } (/** @type {?} */ (styleMap))[style.substr(0, colon).trim()] = style.substr(colon + 1).trim(); } } } return styleMap; } /** * \@internal * @param {?} element * @param {?} styleMap * @return {?} */ _writeStyleAttribute(element, styleMap) { let /** @type {?} */ styleAttrValue = ''; for (const /** @type {?} */ key in styleMap) { const /** @type {?} */ newValue = styleMap[key]; if (newValue) { styleAttrValue += key + ':' + styleMap[key] + ';'; } } element.setAttribute('style', styleAttrValue); } /** * @param {?} element * @param {?} styleName * @param {?=} styleValue * @return {?} */ setStyle(element, styleName, styleValue) { const /** @type {?} */ styleMap = this._readStyleAttribute(element); (/** @type {?} */ (styleMap))[styleName] = styleValue; this._writeStyleAttribute(element, styleMap); } /** * @param {?} element * @param {?} styleName * @return {?} */ removeStyle(element, styleName) { this.setStyle(element, styleName, null); } /** * @param {?} element * @param {?} styleName * @return {?} */ getStyle(element, styleName) { const /** @type {?} */ styleMap = this._readStyleAttribute(element); return styleMap.hasOwnProperty(styleName) ? (/** @type {?} */ (styleMap))[styleName] : ''; } /** * @param {?} element * @param {?} styleName * @param {?=} styleValue * @return {?} */ hasStyle(element, styleName, styleValue) { const /** @type {?} */ value = this.getStyle(element, styleName) || ''; return styleValue ? value == styleValue : value.length > 0; } /** * @param {?} el * @param {?} evt * @return {?} */ dispatchEvent(el, evt) { el.dispatchEvent(evt); // Dispatch the event to the window also. const /** @type {?} */ doc = el.ownerDocument || el; const /** @type {?} */ win = (/** @type {?} */ (doc)).defaultView; if (win) { win.dispatchEvent(evt); } } /** * @return {?} */ getHistory() { throw _notImplemented('getHistory'); } /** * @return {?} */ getLocation() { throw _notImplemented('getLocation'); } /** * @return {?} */ getUserAgent() { return 'Fake user agent'; } /** * @return {?} */ supportsWebAnimation() { return false; } /** * @return {?} */ performanceNow() { return Date.now(); } /** * @return {?} */ getAnimationPrefix() { return ''; } /** * @return {?} */ getTransitionEnd() { return 'transitionend'; } /** * @return {?} */ supportsAnimation() { return true; } /** * @param {?} el * @return {?} */ getDistributedNodes(el) { throw _notImplemented('getDistributedNodes'); } /** * @return {?} */ supportsCookies() { return false; } /** * @param {?} name * @return {?} */ getCookie(name) { throw _notImplemented('getCookie'); } /** * @param {?} name * @param {?} value * @return {?} */ setCookie(name, value) { throw _notImplemented('setCookie'); } } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @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 */ /** * Representation of the current platform state. * * \@experimental */ class PlatformState { /** * @param {?} _doc */ constructor(_doc) { this._doc = _doc; } /** * Renders the current state of the platform to string. * @return {?} */ renderToString() { return serializeDocument(this._doc); } /** * Returns the current DOM state. * @return {?} */ getDocument() { return this._doc; } } PlatformState.decorators = [ { type: Injectable }, ]; /** @nocollapse */ PlatformState.ctorParameters = () => [ { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] },] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @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 */ const xhr2 = require('xhr2'); const isAbsoluteUrl = /^[a-zA-Z\-\+.]+:\/\//; /** * @param {?} url * @return {?} */ function validateRequestUrl(url$$1) { if (!isAbsoluteUrl.test(url$$1)) { throw new Error(`URLs requested via Http on the server must be absolute. URL: ${url$$1}`); } } class ServerXhr { /** * @return {?} */ build() { return new xhr2.XMLHttpRequest(); } } ServerXhr.decorators = [ { type: Injectable }, ]; /** @nocollapse */ ServerXhr.ctorParameters = () => []; class ServerXsrfStrategy { /** * @param {?} req * @return {?} */ configureRequest(req) { } } ServerXsrfStrategy.decorators = [ { type: Injectable }, ]; /** @nocollapse */ ServerXsrfStrategy.ctorParameters = () => []; /** * @abstract */ class ZoneMacroTaskWrapper { /** * @param {?} request * @return {?} */ wrap(request) { return new Observable((observer) => { let /** @type {?} */ task = /** @type {?} */ ((null)); let /** @type {?} */ scheduled = false; let /** @type {?} */ sub = null; let /** @type {?} */ savedResult = null; let /** @type {?} */ savedError = null; const /** @type {?} */ scheduleTask = (_task) => { task = _task; scheduled = true; const /** @type {?} */ delegate = this.delegate(request); sub = delegate.subscribe(res => savedResult = res, err => { if (!scheduled) { throw new Error('An http observable was completed twice. This shouldn\'t happen, please file a bug.'); } savedError = err; scheduled = false; task.invoke(); }, () => { if (!scheduled) { throw new Error('An http observable was completed twice. This shouldn\'t happen, please file a bug.'); } scheduled = false; task.invoke(); }); }; const /** @type {?} */ cancelTask = (_task) => { if (!scheduled) { return; } scheduled = false; if (sub) { sub.unsubscribe(); sub = null; } }; const /** @type {?} */ onComplete = () => { if (savedError !== null) { observer.error(savedError); } else { observer.next(savedResult); observer.complete(); } }; // MockBackend for Http is synchronous, which means that if scheduleTask is by // scheduleMacroTask, the request will hit MockBackend and the response will be // sent, causing task.invoke() to be called. const /** @type {?} */ _task = Zone.current.scheduleMacroTask('ZoneMacroTaskWrapper.subscribe', onComplete, {}, () => null, cancelTask); scheduleTask(_task); return () => { if (scheduled && task) { task.zone.cancelTask(task); scheduled = false; } if (sub) { sub.unsubscribe(); sub = null; } }; }); } } class ZoneMacroTaskConnection extends ZoneMacroTaskWrapper { /** * @param {?} request * @param {?} backend */ constructor(request, backend) { super(); this.request = request; this.backend = backend; validateRequestUrl(request.url); this.response = this.wrap(request); } /** * @param {?} request * @return {?} */ delegate(request) { this.lastConnection = this.backend.createConnection(request); return /** @type {?} */ (this.lastConnection.response); } /** * @return {?} */ get readyState() { return !!this.lastConnection ? this.lastConnection.readyState : ReadyState.Unsent; } } class ZoneMacroTaskBackend { /** * @param {?} backend */ constructor(backend) { this.backend = backend; } /** * @param {?} request * @return {?} */ createConnection(request) { return new ZoneMacroTaskConnection(request, this.backend); } } class ZoneClientBackend extends ZoneMacroTaskWrapper { /** * @param {?} backend */ constructor(backend) { super(); this.backend = backend; } /** * @param {?} request * @return {?} */ handle(request) { return this.wrap(request); } /** * @param {?} request * @return {?} */ delegate(request) { return this.backend.handle(request); } } /** * @param {?} xhrBackend * @param {?} options * @return {?} */ function httpFactory(xhrBackend, options) { const /** @type {?} */ macroBackend = new ZoneMacroTaskBackend(xhrBackend); return new Http(macroBackend, options); } /** * @param {?} backend * @param {?} interceptors * @return {?} */ function zoneWrappedInterceptingHandler(backend, interceptors) { const /** @type {?} */ realBackend = ɵinterceptingHandler(backend, interceptors); return new ZoneClientBackend(realBackend); } const SERVER_HTTP_PROVIDERS = [ { provide: Http, useFactory: httpFactory, deps: [XHRBackend, RequestOptions] }, { provide: BrowserXhr, useClass: ServerXhr }, { provide: XSRFStrategy, useClass: ServerXsrfStrategy }, { provide: XhrFactory, useClass: ServerXhr }, { provide: HttpHandler, useFactory: zoneWrappedInterceptingHandler, deps: [HttpBackend, [new Optional(), HTTP_INTERCEPTORS]] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @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 */ /** * Config object passed to initialize the platform. * * \@experimental * @record */ /** * The DI token for setting the initial config for the platform. * * \@experimental */ const INITIAL_CONFIG = new InjectionToken('Server.INITIAL_CONFIG'); /** * A function that will be executed when calling `renderModuleFactory` or `renderModule` just * before current platform state is rendered to string. * * \@experimental */ const BEFORE_APP_SERIALIZED = new InjectionToken('Server.RENDER_MODULE_HOOK'); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @param {?} urlStr * @return {?} */ function parseUrl(urlStr) { const /** @type {?} */ parsedUrl = parse(urlStr); return { pathname: parsedUrl.pathname || '', search: parsedUrl.search || '', hash: parsedUrl.hash || '', }; } /** * Server-side implementation of URL state. Implements `pathname`, `search`, and `hash` * but not the state stack. */ class ServerPlatformLocation { /** * @param {?} _doc * @param {?} _config */ constructor(_doc, _config) { this._doc = _doc; this.pathname = '/'; this.search = ''; this.hash = ''; this._hashUpdate = new Subject(); const /** @type {?} */ config = /** @type {?} */ (_config); if (!!config && !!config.url) { const /** @type {?} */ parsedUrl = parseUrl(config.url); this.pathname = parsedUrl.pathname; this.search = parsedUrl.search; this.hash = parsedUrl.hash; } } /** * @return {?} */ getBaseHrefFromDOM() { return /** @type {?} */ ((ɵgetDOM().getBaseHref(this._doc))); } /** * @param {?} fn * @return {?} */ onPopState(fn) { // No-op: a state stack is not implemented, so // no events will ever come. } /** * @param {?} fn * @return {?} */ onHashChange(fn) { this._hashUpdate.subscribe(fn); } /** * @return {?} */ get url() { return `${this.pathname}${this.search}${this.hash}`; } /** * @param {?} value * @param {?} oldUrl * @return {?} */ setHash(value, oldUrl) { if (this.hash === value) { // Don't fire events if the hash has not changed. return; } (/** @type {?} */ (this)).hash = value; const /** @type {?} */ newUrl = this.url; scheduleMicroTask(() => this._hashUpdate.next(/** @type {?} */ ({ type: 'hashchange', oldUrl, newUrl }))); } /** * @param {?} state * @param {?} title * @param {?} newUrl * @return {?} */ replaceState(state, title, newUrl) { const /** @type {?} */ oldUrl = this.url; const /** @type {?} */ parsedUrl = parseUrl(newUrl); (/** @type {?} */ (this)).pathname = parsedUrl.pathname; (/** @type {?} */ (this)).search = parsedUrl.search; this.setHash(parsedUrl.hash, oldUrl); } /** * @param {?} state * @param {?} title * @param {?} newUrl * @return {?} */ pushState(state, title, newUrl) { this.replaceState(state, title, newUrl); } /** * @return {?} */ forward() { throw new Error('Not implemented'); } /** * @return {?} */ back() { throw new Error('Not implemented'); } } ServerPlatformLocation.decorators = [ { type: Injectable }, ]; /** @nocollapse */ ServerPlatformLocation.ctorParameters = () => [ { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] },] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [INITIAL_CONFIG,] },] }, ]; /** * @param {?} fn * @return {?} */ function scheduleMicroTask(fn) { Zone.current.scheduleMicroTask('scheduleMicrotask', fn); } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @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 */ const EMPTY_ARRAY = []; class ServerRendererFactory2 { /** * @param {?} ngZone * @param {?} document * @param {?} sharedStylesHost */ constructor(ngZone, document, sharedStylesHost) { this.ngZone = ngZone; this.document = document; this.sharedStylesHost = sharedStylesHost; this.rendererByCompId = new Map(); this.schema = new DomElementSchemaRegistry(); this.defaultRenderer = new DefaultServerRenderer2(document, ngZone, this.schema); } /** * @param {?} element * @param {?} type * @return {?} */ createRenderer(element, type) { if (!element || !type) { return this.defaultRenderer; } switch (type.encapsulation) { case ViewEncapsulation.Native: case ViewEncapsulation.Emulated: { let /** @type {?} */ renderer = this.rendererByCompId.get(type.id); if (!renderer) { renderer = new EmulatedEncapsulationServerRenderer2(this.document, this.ngZone, this.sharedStylesHost, this.schema, type); this.rendererByCompId.set(type.id, renderer); } (/** @type {?} */ (renderer)).applyToHost(element); return renderer; } case ViewEncapsulation.Native: throw new Error('Native encapsulation is not supported on the server!'); default: { if (!this.rendererByCompId.has(type.id)) { const /** @type {?} */ styles = ɵflattenStyles(type.id, type.styles, []); this.sharedStylesHost.addStyles(styles); this.rendererByCompId.set(type.id, this.defaultRenderer); } return this.defaultRenderer; } } } /** * @return {?} */ begin() { } /** * @return {?} */ end() { } } ServerRendererFactory2.decorators = [ { type: Injectable }, ]; /** @nocollapse */ ServerRendererFactory2.ctorParameters = () => [ { type: NgZone, }, { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] },] }, { type: ɵSharedStylesHost, }, ]; class DefaultServerRenderer2 { /** * @param {?} document * @param {?} ngZone * @param {?} schema */ constructor(document, ngZone, schema) { this.document = document; this.ngZone = ngZone; this.schema = schema; this.data = Object.create(null); } /** * @return {?} */ destroy() { } /** * @param {?} name * @param {?=} namespace * @param {?=} debugInfo * @return {?} */ createElement(name, namespace, debugInfo) { if (namespace) { return ɵgetDOM().createElementNS(ɵNAMESPACE_URIS[namespace], name); } return ɵgetDOM().createElement(name); } /** * @param {?} value * @param {?=} debugInfo * @return {?} */ createComment(value, debugInfo) { return ɵgetDOM().createComment(value); } /** * @param {?} value * @param {?=} debugInfo * @return {?} */ createText(value, debugInfo) { return ɵgetDOM().createTextNode(value); } /** * @param {?} parent * @param {?} newChild * @return {?} */ appendChild(parent, newChild) { ɵgetDOM().appendChild(parent, newChild); } /** * @param {?} parent * @param {?} newChild * @param {?} refChild * @return {?} */ insertBefore(parent, newChild, refChild) { if (parent) { ɵgetDOM().insertBefore(parent, refChild, newChild); } } /** * @param {?} parent * @param {?} oldChild * @return {?} */ removeChild(parent, oldChild) { if (parent) { ɵgetDOM().removeChild(parent, oldChild); } } /** * @param {?} selectorOrNode * @param {?=} debugInfo * @return {?} */ selectRootElement(selectorOrNode, debugInfo) { let /** @type {?} */ el; if (typeof selectorOrNode === 'string') { el = ɵgetDOM().querySelector(this.document, selectorOrNode); if (!el) { throw new Error(`The selector "${selectorOrNode}" did not match any elements`); } } else { el = selectorOrNode; } ɵgetDOM().clearNodes(el); return el; } /** * @param {?} node * @return {?} */ parentNode(node) { return ɵgetDOM().parentElement(node); } /** * @param {?} node * @return {?} */ nextSibling(node) { return ɵgetDOM().nextSibling(node); } /** * @param {?} el * @param {?} name * @param {?} value * @param {?=} namespace * @return {?} */ setAttribute(el, name, value, namespace) { if (namespace) { ɵgetDOM().setAttributeNS(el, ɵNAMESPACE_URIS[namespace], namespace + ':' + name, value); } else { ɵgetDOM().setAttribute(el, name, value); } } /** * @param {?} el * @param {?} name * @param {?=} namespace * @return {?} */ removeAttribute(el, name, namespace) { if (namespace) { ɵgetDOM().removeAttributeNS(el, ɵNAMESPACE_URIS[namespace], name); } else { ɵgetDOM().removeAttribute(el, name); } } /** * @param {?} el * @param {?} name * @return {?} */ addClass(el, name) { ɵgetDOM().addClass(el, name); } /** * @param {?} el * @param {?} name * @return {?} */ removeClass(el, name) { ɵgetDOM().removeClass(el, name); } /** * @param {?} el * @param {?} style * @param {?} value * @param {?} flags * @return {?} */ setStyle(el, style, value, flags) { ɵgetDOM().setStyle(el, style, value); } /** * @param {?} el * @param {?} style * @param {?} flags * @return {?} */ removeStyle(el, style, flags) { ɵgetDOM().removeStyle(el, style); } /** * @param {?} tagName * @param {?} propertyName * @return {?} */ _isSafeToReflectProperty(tagName, propertyName) { return this.schema.securityContext(tagName, propertyName, true) === this.schema.securityContext(tagName, propertyName, false); } /** * @param {?} el * @param {?} name * @param {?} value * @return {?} */ setProperty(el, name, value) { checkNoSyntheticProp(name, 'property'); ɵgetDOM().setProperty(el, name, value); // Mirror property values for known HTML element properties in the attributes. const /** @type {?} */ tagName = (/** @type {?} */ (el.tagName)).toLowerCase(); if (value != null && (typeof value === 'number' || typeof value == 'string') && this.schema.hasElement(tagName, EMPTY_ARRAY) && this.schema.hasProperty(tagName, name, EMPTY_ARRAY) && this._isSafeToReflectProperty(tagName, name)) { this.setAttribute(el, name, value.toString()); } } /** * @param {?} node * @param {?} value * @return {?} */ setValue(node, value) { ɵgetDOM().setText(node, value); } /** * @param {?} target * @param {?} eventName * @param {?} callback * @return {?} */ listen(target, eventName, callback) { // Note: We are not using the EventsPlugin here as this is not needed // to run our tests. checkNoSyntheticProp(eventName, 'listener'); const /** @type {?} */ el = typeof target === 'string' ? ɵgetDOM().getGlobalEventTarget(this.document, target) : target; const /** @type {?} */ outsideHandler = (event) => this.ngZone.runGuarded(() => callback(event)); return this.ngZone.runOutsideAngular(() => /** @type {?} */ (ɵgetDOM().onAndCancel(el, eventName, outsideHandler))); } } const AT_CHARCODE = '@'.charCodeAt(0); /** * @param {?} name * @param {?} nameKind * @return {?} */ function checkNoSyntheticProp(name, nameKind) { if (name.charCodeAt(0) === AT_CHARCODE) { throw new Error(`Found the synthetic ${nameKind} ${name}. Please include either "BrowserAnimationsModule" or "NoopAnimationsModule" in your application.`); } } class EmulatedEncapsulationServerRenderer2 extends DefaultServerRenderer2 { /** * @param {?} document * @param {?} ngZone * @param {?} sharedStylesHost * @param {?} schema * @param {?} component */ constructor(document, ngZone, sharedStylesHost, schema, component) { super(document, ngZone, schema); this.component = component; const /** @type {?} */ styles = ɵflattenStyles(component.id, component.styles, []); sharedStylesHost.addStyles(styles); this.contentAttr = ɵshimContentAttribute(component.id); this.hostAttr = ɵshimHostAttribute(component.id); } /** * @param {?} element * @return {?} */ applyToHost(element) { super.setAttribute(element, this.hostAttr, ''); } /** * @param {?} parent * @param {?} name * @return {?} */ createElement(parent, name) { const /** @type {?} */ el = super.createElement(parent, name); super.setAttribute(el, this.contentAttr, ''); return el; } } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @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 */ class ServerStylesHost extends ɵSharedStylesHost { /** * @param {?} doc * @param {?} transitionId */ constructor(doc, transitionId) { super(); this.doc = doc; this.transitionId = transitionId; this.head = null; this.head = ɵgetDOM().getElementsByTagName(doc, 'head')[0]; } /** * @param {?} style * @return {?} */ _addStyle(style) { let /** @type {?} */ adapter = ɵgetDOM(); const /** @type {?} */ el = adapter.createElement('style'); adapter.setText(el, style); if (!!this.transitionId) { adapter.setAttribute(el, 'ng-transition', this.transitionId); } adapter.appendChild(this.head, el); } /** * @param {?} additions * @return {?} */ onStylesAdded(additions) { additions.forEach(style => this._addStyle(style)); } } ServerStylesHost.decorators = [ { type: Injectable }, ]; /** @nocollapse */ ServerStylesHost.ctorParameters = () => [ { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] },] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [ɵTRANSITION_ID,] },] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @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 */ const INTERNAL_SERVER_PLATFORM_PROVIDERS = [ { provide: DOCUMENT, useFactory: _document, deps: [Injector] }, { provide: PLATFORM_ID, useValue: ɵPLATFORM_SERVER_ID }, { provide: PLATFORM_INITIALIZER, useFactory: initDominoAdapter, multi: true, deps: [Injector] }, { provide: PlatformLocation, useClass: ServerPlatformLocation, deps: [DOCUMENT, [Optional, INITIAL_CONFIG]] }, { provide: PlatformState, deps: [DOCUMENT] }, // Add special provider that allows multiple instances of platformServer* to be created. { provide: ɵALLOW_MULTIPLE_PLATFORMS, useValue: true } ]; /** * @param {?} injector * @return {?} */ function initDominoAdapter(injector) { return () => { DominoAdapter.makeCurrent(); }; } /** * @param {?} renderer * @param {?} engine * @param {?} zone * @return {?} */ function instantiateServerRendererFactory(renderer, engine, zone) { return new ɵAnimationRendererFactory(renderer, engine, zone); } const SERVER_RENDER_PROVIDERS = [ ServerRendererFactory2, { provide: RendererFactory2, useFactory: instantiateServerRendererFactory, deps: [ServerRendererFactory2, ɵAnimationEngine, NgZone] }, ServerStylesHost, { provide: ɵSharedStylesHost, useExisting: ServerStylesHost }, ]; /** * The ng module for the server. * * \@experimental */ class ServerModule { } ServerModule.decorators = [ { type: NgModule, args: [{ exports: [BrowserModule], imports: [HttpModule, HttpClientModule, NoopAnimationsModule], providers: [ SERVER_RENDER_PROVIDERS, SERVER_HTTP_PROVIDERS, { provide: Testability, useValue: null }, ], },] }, ]; /** @nocollapse */ ServerModule.ctorParameters = () => []; /** * @param {?} injector * @return {?} */ function _document(injector) { let /** @type {?} */ config = injector.get(INITIAL_CONFIG, null); if (config && config.document) { return parseDocument(config.document, config.url); } else { return ɵgetDOM().createHtmlDocument(); } } /** * \@experimental */ const platformServer = createPlatformFactory(platformCore, 'server', INTERNAL_SERVER_PLATFORM_PROVIDERS); /** * The server platform that supports the runtime compiler. * * \@experimental */ const platformDynamicServer = createPlatformFactory(ɵplatformCoreDynamic, 'serverDynamic', INTERNAL_SERVER_PLATFORM_PROVIDERS); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @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 */ /** * @param {?} doc * @param {?} appId * @param {?} transferStore * @return {?} */ function serializeTransferStateFactory(doc, appId, transferStore) { return () => { const /** @type {?} */ script = doc.createElement('script'); script.id = appId + '-state'; script.setAttribute('type', 'application/json'); script.textContent = ɵescapeHtml(transferStore.toJson()); doc.body.appendChild(script); }; } /** * NgModule to install on the server side while using the `TransferState` to transfer state from * server to client. * * \@experimental */ class ServerTransferStateModule { } ServerTransferStateModule.decorators = [ { type: NgModule, args: [{ providers: [ TransferState, { provide: BEFORE_APP_SERIALIZED, useFactory: serializeTransferStateFactory, deps: [DOCUMENT, APP_ID, TransferState], multi: true, } ] },] }, ]; /** @nocollapse */ ServerTransferStateModule.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @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 */ /** * @param {?} platformFactory * @param {?} options * @return {?} */ function _getPlatform(platformFactory, options) { const /** @type {?} */ extraProviders = options.extraProviders ? options.extraProviders : []; return platformFactory([ { provide: INITIAL_CONFIG, useValue: { document: options.document, url: options.url } }, extraProviders ]); } /** * @template T * @param {?} platform * @param {?} moduleRefPromise * @return {?} */ function _render(platform, moduleRefPromise) { return moduleRefPromise.then((moduleRef) => { const /** @type {?} */ transitionId = moduleRef.injector.get(ɵTRANSITION_ID, null); if (!transitionId) { throw new Error(`renderModule[Factory]() requires the use of BrowserModule.withServerTransition() to ensure the server-rendered app can be properly bootstrapped into a client app.`); } const /** @type {?} */ applicationRef = moduleRef.injector.get(ApplicationRef); return toPromise .call(first.call(filter.call(applicationRef.isStable, (isStable) => isStable))) .then(() => { const /** @type {?} */ platformState = platform.injector.get(PlatformState); // Run any BEFORE_APP_SERIALIZED callbacks just before rendering to string. const /** @type {?} */ callbacks = moduleRef.injector.get(BEFORE_APP_SERIALIZED, null); if (callbacks) { for (const /** @type {?} */ callback of callbacks) { try { callback(); } catch (/** @type {?} */ e) { // Ignore exceptions. console.warn('Ignoring BEFORE_APP_SERIALIZED Exception: ', e); } } } const /** @type {?} */ output = platformState.renderToString(); platform.destroy(); return output; }); }); } /** * Renders a Module to string. * * `document` is the full document HTML of the page to render, as a string. * `url` is the URL for the current render request. * `extraProviders` are the platform level providers for the current render request. * * Do not use this in a production server environment. Use pre-compiled {\@link NgModuleFactory} with * {\@link renderModuleFactory} instead. * * \@experimental * @template T * @param {?} module * @param {?} options * @return {?} */ function renderModule(module, options) { const /** @type {?} */ platform = _getPlatform(platformDynamicServer, options); return _render(platform, platform.bootstrapModule(module)); } /** * Renders a {\@link NgModuleFactory} to string. * * `document` is the full document HTML of the page to render, as a string. * `url` is the URL for the current render request. * `extraProviders` are the platform level providers for the current render request. * * \@experimental * @template T * @param {?} moduleFactory * @param {?} options * @return {?} */ function renderModuleFactory(moduleFactory, options) { const /** @type {?} */ platform = _getPlatform(platformServer, options); return _render(platform, platform.bootstrapModuleFactory(moduleFactory)); } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @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 */ /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @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 */ /** * @module * @description * Entry point for all public APIs of the common package. */ /** * \@stable */ const VERSION = new Version('5.0.0-rc.8'); /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @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 */ /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @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 */ /** * @module * @description * Entry point for all public APIs of this package. */ // This file only reexports content of the `src` folder. Keep it that way. /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * Generated bundle index. Do not edit. */ export { PlatformState, ServerModule, platformDynamicServer, platformServer, BEFORE_APP_SERIALIZED, INITIAL_CONFIG, ServerTransferStateModule, renderModule, renderModuleFactory, VERSION, INTERNAL_SERVER_PLATFORM_PROVIDERS as ɵINTERNAL_SERVER_PLATFORM_PROVIDERS, SERVER_RENDER_PROVIDERS as ɵSERVER_RENDER_PROVIDERS, ServerRendererFactory2 as ɵServerRendererFactory2, SERVER_HTTP_PROVIDERS as ɵh, ServerXhr as ɵd, ServerXsrfStrategy as ɵe, httpFactory as ɵf, zoneWrappedInterceptingHandler as ɵg, instantiateServerRendererFactory as ɵa, ServerStylesHost as ɵc, serializeTransferStateFactory as ɵb }; //# sourceMappingURL=platform-server.js.map