infrastructure-components
Version:
Infrastructure-Components configure the infrastructure of your React-App as part of your React-Components.
274 lines (219 loc) • 13 kB
JavaScript
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
import React from "react";
import PropTypes from "prop-types";
import withSideEffect from "react-side-effect";
import deepEqual from "deep-equal";
import { convertReactPropstoHtmlAttributes, handleClientStateChange, mapStateOnServer, reducePropsToState, warn } from "./HelmetUtils.js";
import { TAG_NAMES, VALID_TAG_NAMES } from "./HelmetConstants.js";
var Helmet = function Helmet(Component) {
var _class, _temp;
return _temp = _class = function (_React$Component) {
_inherits(HelmetWrapper, _React$Component);
function HelmetWrapper() {
_classCallCheck(this, HelmetWrapper);
return _possibleConstructorReturn(this, _React$Component.apply(this, arguments));
}
HelmetWrapper.prototype.shouldComponentUpdate = function shouldComponentUpdate(nextProps) {
return !deepEqual(this.props, nextProps);
};
HelmetWrapper.prototype.mapNestedChildrenToProps = function mapNestedChildrenToProps(child, nestedChildren) {
if (!nestedChildren) {
return null;
}
switch (child.type) {
case TAG_NAMES.SCRIPT:
case TAG_NAMES.NOSCRIPT:
return {
innerHTML: nestedChildren
};
case TAG_NAMES.STYLE:
return {
cssText: nestedChildren
};
}
throw new Error("<" + child.type + " /> elements are self-closing and can not contain children. Refer to our API for more information.");
};
HelmetWrapper.prototype.flattenArrayTypeChildren = function flattenArrayTypeChildren(_ref) {
var _extends2;
var child = _ref.child,
arrayTypeChildren = _ref.arrayTypeChildren,
newChildProps = _ref.newChildProps,
nestedChildren = _ref.nestedChildren;
return _extends({}, arrayTypeChildren, (_extends2 = {}, _extends2[child.type] = [].concat(arrayTypeChildren[child.type] || [], [_extends({}, newChildProps, this.mapNestedChildrenToProps(child, nestedChildren))]), _extends2));
};
HelmetWrapper.prototype.mapObjectTypeChildren = function mapObjectTypeChildren(_ref2) {
var _extends3, _extends4;
var child = _ref2.child,
newProps = _ref2.newProps,
newChildProps = _ref2.newChildProps,
nestedChildren = _ref2.nestedChildren;
switch (child.type) {
case TAG_NAMES.TITLE:
return _extends({}, newProps, (_extends3 = {}, _extends3[child.type] = nestedChildren, _extends3.titleAttributes = _extends({}, newChildProps), _extends3));
case TAG_NAMES.BODY:
return _extends({}, newProps, {
bodyAttributes: _extends({}, newChildProps)
});
case TAG_NAMES.HTML:
return _extends({}, newProps, {
htmlAttributes: _extends({}, newChildProps)
});
}
return _extends({}, newProps, (_extends4 = {}, _extends4[child.type] = _extends({}, newChildProps), _extends4));
};
HelmetWrapper.prototype.mapArrayTypeChildrenToProps = function mapArrayTypeChildrenToProps(arrayTypeChildren, newProps) {
var newFlattenedProps = _extends({}, newProps);
Object.keys(arrayTypeChildren).forEach(function (arrayChildName) {
var _extends5;
newFlattenedProps = _extends({}, newFlattenedProps, (_extends5 = {}, _extends5[arrayChildName] = arrayTypeChildren[arrayChildName], _extends5));
});
return newFlattenedProps;
};
HelmetWrapper.prototype.warnOnInvalidChildren = function warnOnInvalidChildren(child, nestedChildren) {
if (process.env.NODE_ENV !== "production") {
if (!VALID_TAG_NAMES.some(function (name) {
return child.type === name;
})) {
if (typeof child.type === "function") {
return warn("You may be attempting to nest <Helmet> components within each other, which is not allowed. Refer to our API for more information.");
}
return warn("Only elements types " + VALID_TAG_NAMES.join(", ") + " are allowed. Helmet does not support rendering <" + child.type + "> elements. Refer to our API for more information.");
}
if (nestedChildren && typeof nestedChildren !== "string" && (!Array.isArray(nestedChildren) || nestedChildren.some(function (nestedChild) {
return typeof nestedChild !== "string";
}))) {
throw new Error("Helmet expects a string as a child of <" + child.type + ">. Did you forget to wrap your children in braces? ( <" + child.type + ">{``}</" + child.type + "> ) Refer to our API for more information.");
}
}
return true;
};
HelmetWrapper.prototype.mapChildrenToProps = function mapChildrenToProps(children, newProps) {
var _this2 = this;
var arrayTypeChildren = {};
React.Children.forEach(children, function (child) {
if (!child || !child.props) {
return;
}
var _child$props = child.props,
nestedChildren = _child$props.children,
childProps = _objectWithoutProperties(_child$props, ["children"]);
var newChildProps = convertReactPropstoHtmlAttributes(childProps);
_this2.warnOnInvalidChildren(child, nestedChildren);
switch (child.type) {
case TAG_NAMES.LINK:
case TAG_NAMES.META:
case TAG_NAMES.NOSCRIPT:
case TAG_NAMES.SCRIPT:
case TAG_NAMES.STYLE:
arrayTypeChildren = _this2.flattenArrayTypeChildren({
child: child,
arrayTypeChildren: arrayTypeChildren,
newChildProps: newChildProps,
nestedChildren: nestedChildren
});
break;
default:
newProps = _this2.mapObjectTypeChildren({
child: child,
newProps: newProps,
newChildProps: newChildProps,
nestedChildren: nestedChildren
});
break;
}
});
newProps = this.mapArrayTypeChildrenToProps(arrayTypeChildren, newProps);
return newProps;
};
HelmetWrapper.prototype.render = function render() {
var _props = this.props,
children = _props.children,
props = _objectWithoutProperties(_props, ["children"]);
var newProps = _extends({}, props);
if (children) {
newProps = this.mapChildrenToProps(children, newProps);
}
return React.createElement(Component, newProps);
};
_createClass(HelmetWrapper, null, [{
key: "canUseDOM",
// Component.peek comes from react-side-effect:
// For testing, you may use a static peek() method available on the returned component.
// It lets you get the current state without resetting the mounted instance stack.
// Don’t use it for anything other than testing.
/**
* @param {Object} base: {"target": "_blank", "href": "http://mysite.com/"}
* @param {Object} bodyAttributes: {"className": "root"}
* @param {String} defaultTitle: "Default Title"
* @param {Boolean} defer: true
* @param {Boolean} encodeSpecialCharacters: true
* @param {Object} htmlAttributes: {"lang": "en", "amp": undefined}
* @param {Array} link: [{"rel": "canonical", "href": "http://mysite.com/example"}]
* @param {Array} meta: [{"name": "description", "content": "Test description"}]
* @param {Array} noscript: [{"innerHTML": "<img src='http://mysite.com/js/test.js'"}]
* @param {Function} onChangeClientState: "(newState) => console.log(newState)"
* @param {Array} script: [{"type": "text/javascript", "src": "http://mysite.com/js/test.js"}]
* @param {Array} style: [{"type": "text/css", "cssText": "div { display: block; color: blue; }"}]
* @param {String} title: "Title"
* @param {Object} titleAttributes: {"itemprop": "name"}
* @param {String} titleTemplate: "MySite.com - %s"
*/
set: function set(canUseDOM) {
Component.canUseDOM = canUseDOM;
}
}]);
return HelmetWrapper;
}(React.Component), _class.propTypes = {
base: PropTypes.object,
bodyAttributes: PropTypes.object,
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
defaultTitle: PropTypes.string,
defer: PropTypes.bool,
encodeSpecialCharacters: PropTypes.bool,
htmlAttributes: PropTypes.object,
link: PropTypes.arrayOf(PropTypes.object),
meta: PropTypes.arrayOf(PropTypes.object),
noscript: PropTypes.arrayOf(PropTypes.object),
onChangeClientState: PropTypes.func,
script: PropTypes.arrayOf(PropTypes.object),
style: PropTypes.arrayOf(PropTypes.object),
title: PropTypes.string,
titleAttributes: PropTypes.object,
titleTemplate: PropTypes.string
}, _class.defaultProps = {
defer: true,
encodeSpecialCharacters: true
}, _class.peek = Component.peek, _class.rewind = function () {
var mappedState = Component.rewind();
if (!mappedState) {
// provide fallback if mappedState is undefined
mappedState = mapStateOnServer({
baseTag: [],
bodyAttributes: {},
encodeSpecialCharacters: true,
htmlAttributes: {},
linkTags: [],
metaTags: [],
noscriptTags: [],
scriptTags: [],
styleTags: [],
title: "",
titleAttributes: {}
});
}
return mappedState;
}, _temp;
};
var NullComponent = function NullComponent() {
return null;
};
var HelmetSideEffects = withSideEffect(reducePropsToState, handleClientStateChange, mapStateOnServer)(NullComponent);
var HelmetExport = Helmet(HelmetSideEffects);
HelmetExport.renderStatic = HelmetExport.rewind;
export { HelmetExport as Helmet };
export default HelmetExport;