Repository URL to install this package:
|
Version:
2.0.0-beta.20 ▾
|
"use strict";
/**
* @module responsible for generating the HTML page response
* @see the react application middleware
*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable react/no-danger */
/* eslint-disable react/no-array-index-key */
var react_1 = __importDefault(require("react"));
var serialize_javascript_1 = __importDefault(require("serialize-javascript"));
var bs_1 = require("@skava/bs");
var Document_1 = require("../Document");
var clientEntryAssets = bs_1.getClientBundleEntryAssets();
// --------------- config ---------------
var HAS_STYLES = false;
// ----------------- components ------------------
/**
* make sure we don't give any `map` files
* @todo we could filter this elsewhere
* @param path @example /eh.js
*/
function shouldRemoveFromServerJavaScriptList(path) {
return path.includes('.map') === false;
}
/**
* @throws Invariant Violation: React.Children.only expected to receive a single React element child.
* return React.Children.only(props.children)
*/
function KeyedComponent(props) {
return props.children;
}
var toKeyed = function (x, index) { return (react_1.default.createElement(KeyedComponent, { key: index }, x)); };
function stylesheetTag(stylesheetFilePath) {
return (react_1.default.createElement("link", { href: stylesheetFilePath, media: "screen, projection", rel: "stylesheet" }));
}
function scriptTag(jsFilePath) {
var finalPath = jsFilePath.includes('/') ? jsFilePath : '/' + jsFilePath;
return react_1.default.createElement("script", { type: "text/javascript", src: finalPath });
}
/**
* @example <script>{stringProtectedByNonce}</script>
* @tutorial https://stackoverflow.com/questions/42922784/what-s-the-purpose-of-the-html-nonce-attribute-for-script-and-style-elements
*/
var inlineScript = function (props) { return (react_1.default.createElement("script", { nonce: props.nonce, type: "text/javascript", dangerouslySetInnerHTML: { __html: props.children } })); };
/**
* this renders the elements wrapped with <HelmetReact> on our views/pages
*/
function createHeaderElements(props) {
var helmet = props.helmet, styledTags = props.styledTags;
var noHelmet = !helmet;
var styleElements = [];
if (HAS_STYLES && noHelmet) {
var styleTag = stylesheetTag(clientEntryAssets.css);
styleElements.push(styleTag);
}
else if (helmet) {
styleElements = helmet.style.toComponent() || [];
}
if (styledTags) {
styleElements.push(styledTags);
}
return noHelmet
? []
: helmet.title.toComponent().concat(helmet.base.toComponent(), helmet.meta.toComponent(), helmet.link.toComponent(), helmet.style.toComponent(), styleElements);
}
// ----------------- core ------------------
/**
* @todo see view-container and the byte minification there
*
* @example if (storeState)
* inlineScriptString += `window.__APP_STATE__`
* inlineScriptString += `=` + serialize(storeState);
*
* @return {String} JSON of the serialized state
*/
function fromGlobalStateToScriptString(inlineScriptState) {
var inlineScriptString = "";
var GLOBAL_NAMES = Object.keys(inlineScriptState);
for (var index = 0; index < GLOBAL_NAMES.length; index++) {
var GLOBAL_NAME = GLOBAL_NAMES[index];
var GLOBAL_VALUE = inlineScriptState[GLOBAL_NAME];
inlineScriptString += "window." + GLOBAL_NAME + " = " + serialize_javascript_1.default(GLOBAL_VALUE) + ";\n";
}
return inlineScriptString;
}
/**
* for rehydrating state from a <script> added to the end of <body>
* full of JSON dumps
*/
function getRehydratableScript(props) {
var nonce = props.nonce;
var routerState = props.routerState, asyncState = props.asyncState, storeState = props.storeState, apolloState = props.apolloState;
var inlineScriptState = {
__APP_STATE__: storeState,
__APOLLO_STATE__: apolloState,
__ROUTER_STATE__: routerState,
__ASYNC_COMPONENTS_STATE__: asyncState,
};
var children = fromGlobalStateToScriptString(inlineScriptState);
return inlineScript({ children: children, nonce: nonce });
}
function getBodyElements(props) {
var helmet = props.helmet;
var bodyElements = [];
var rehydratable = getRehydratableScript(props);
bodyElements.push(rehydratable);
// @todo @@perf use exotic
if (clientEntryAssets && clientEntryAssets.jsList) {
clientEntryAssets.jsList
.filter(shouldRemoveFromServerJavaScriptList)
.map(scriptTag)
.forEach(function (asScriptTag) {
bodyElements.push(asScriptTag);
});
}
// @todo @@perf use exotic
// every page with a <Helmet> has this
// should just require it to simplify
if (helmet) {
// currently this never happens
helmet.script
.toComponent()
.forEach(function (scriptComponent) { return bodyElements.push(scriptComponent); });
}
return bodyElements;
}
var ServerHTML = /** @class */ (function (_super) {
__extends(ServerHTML, _super);
function ServerHTML() {
return _super !== null && _super.apply(this, arguments) || this;
}
ServerHTML.prototype.render = function () {
var _a = this.props, helmet = _a.helmet, reactAppString = _a.reactAppString;
var headerElements = createHeaderElements(this.props);
var attributes = helmet ? helmet.htmlAttributes.toComponent() : undefined;
var bodyElements = getBodyElements(this.props);
/* eslint-disable react/jsx-pascal-case */
return (react_1.default.createElement(Document_1.HTML, { htmlAttributes: attributes, headerElements: headerElements.map(toKeyed), bodyElements: bodyElements.map(toKeyed), appBodyString: reactAppString }));
};
return ServerHTML;
}(react_1.default.PureComponent));
exports.ServerHTML = ServerHTML;
exports.default = ServerHTML;
//# sourceMappingURL=ServerHTML.js.map