All files wrapper.js

85.29% Statements 29/34
60% Branches 9/15
76.92% Functions 10/13
84.85% Lines 28/33
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 1402x 2x 2x 2x     5x       2x         2x                     5x       5x                 5x       5x                                                                     5x   5x                     2x   2x 2x   2x       2x                                 7x 7x   5x 5x 5x           7x 7x       7x         2x 2x
var React = require('react');
var withRouter = require('react-router').withRouter;
var hoistStatics = require('hoist-non-react-statics');
var lib = require('./lib');
 
function isNode() {
    return (typeof process === 'object' && process + '' === '[object process]');
}
 
function getDisplayName(Cmp) {
    return Cmp.displayName || Cmp.name || 'Component';
}
 
function withWrapper(Cmp) {
 
    var Wrapper = React.createClass({
 
        displayName: 'WithWrapper',
 
        contextTypes: {
            store: React.PropTypes.any,
            getInitialProps: React.PropTypes.func
        },
 
        getInitialState: function getInitialState() {
 
            var initialProps = this.context.getInitialProps();
 
            // console.log('Initial props from context', initialProps);
 
            return lib.extends({}, initialProps || {}, {
                initialLoading: !initialProps, // no props means it will load
                initialError: initialProps && new Error(initialProps.initialError) // it comes as string
            });
 
        },
 
        componentWillMount: function componentWillMount() {
 
            var self = this;
 
            // On NodeJS setState is a no-op, besides, getInitialProps will be called by server rendering procedure
            // On client side this function should not be called if props were passed from server
            Eif (isNode() || !this.state.initialLoading) return;
 
            new Promise(function(res) {
 
                res(Cmp.getInitialProps ? Cmp.getInitialProps({
                    location: self.props.location,
                    params: self.props.params,
                    query: self.props.query,
                    req: null,
                    res: null,
                    store: self.context.store
                }) : null);
 
            }).then(function(props) {
 
                self.setState(lib.extends({}, props, {
                    initialLoading: false,
                    initialError: null
                }));
 
            }).catch(function onError(e) {
 
                console.error(Wrapper.displayName + '.getInitialProps has failed:', e);
 
                self.setState({
                    initialLoading: false,
                    initialError: e
                });
 
            });
 
        },
 
        render: function render() {
 
            var props = lib.objectWithoutProperties(this.props, ["children"]);
 
            return React.createElement(
                Cmp,
                //TODO Add mapping function
                lib.extends({}, this.state, props),
                this.props.children
            );
 
        }
 
    });
 
    Wrapper = withRouter(Wrapper);
 
    Wrapper.displayName = 'withWrapper(' + getDisplayName(Cmp) + ')';
    Wrapper.OriginalComponent = Cmp;
 
    return hoistStatics(Wrapper, Cmp);
 
}
 
var WrapperProvider = React.createClass({
 
    displayName: 'WrapperProvider',
 
    propTypes: {
        initialProps: React.PropTypes.any
    },
 
    defaultProps: {
        initialProps: null
    },
 
    childContextTypes: {
        getInitialProps: React.PropTypes.func
    },
 
    getChildContext: function getChildContext() {
        var self = this;
        return {
            getInitialProps: function() {
                var initialProps = self.initialProps;
                self.initialProps = null; // initial props can be used only once
                return initialProps;
            }
        };
    },
 
    getInitialState: function getInitialState() {
        this.initialProps = this.props.initialProps;
        return {};
    },
 
    render: function render() {
        return this.props.children;
    }
 
});
 
exports.withWrapper = withWrapper;
exports.WrapperProvider = WrapperProvider;