UNPKG

14.8 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
8
9var _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; }; }();
10
11var _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; };
12
13var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
14
15exports.default = enhanceWithRadium;
16
17var _react = require('react');
18
19var _propTypes = require('prop-types');
20
21var _propTypes2 = _interopRequireDefault(_propTypes);
22
23var _styleKeeper = require('./style-keeper');
24
25var _styleKeeper2 = _interopRequireDefault(_styleKeeper);
26
27var _resolveStyles2 = require('./resolve-styles');
28
29var _resolveStyles3 = _interopRequireDefault(_resolveStyles2);
30
31var _getRadiumStyleState = require('./get-radium-style-state');
32
33var _getRadiumStyleState2 = _interopRequireDefault(_getRadiumStyleState);
34
35function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
36
37function _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; }
38
39function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
40
41function _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; }
42
43function _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; }
44
45var KEYS_TO_IGNORE_WHEN_COPYING_PROPERTIES = ['arguments', 'callee', 'caller', 'length', 'name', 'prototype', 'type'];
46
47var RADIUM_PROTO = void 0;
48var RADIUM_METHODS = void 0;
49
50function copyProperties(source, target) {
51 Object.getOwnPropertyNames(source).forEach(function (key) {
52 if (KEYS_TO_IGNORE_WHEN_COPYING_PROPERTIES.indexOf(key) < 0 && !target.hasOwnProperty(key)) {
53 var descriptor = Object.getOwnPropertyDescriptor(source, key);
54 Object.defineProperty(target, key, descriptor);
55 }
56 });
57}
58
59// Handle scenarios of:
60// - Inherit from `React.Component` in any fashion
61// See: https://github.com/FormidableLabs/radium/issues/738
62// - There's an explicit `render` field defined
63function isStateless(component) {
64 var proto = component.prototype || {};
65
66 return !component.isReactComponent && !proto.isReactComponent && !component.render && !proto.render;
67}
68
69// Check if value is a real ES class in Native / Node code.
70// See: https://stackoverflow.com/a/30760236
71function isNativeClass(component) {
72 return typeof component === 'function' && /^\s*class\s+/.test(component.toString());
73}
74
75// Manually apply babel-ish class inheritance.
76function inherits(subClass, superClass) {
77 if (typeof superClass !== 'function' && superClass !== null) {
78 throw new TypeError('Super expression must either be null or a function, not ' + (typeof superClass === 'undefined' ? 'undefined' : _typeof(superClass)));
79 }
80
81 subClass.prototype = Object.create(superClass && superClass.prototype, {
82 constructor: {
83 value: subClass,
84 enumerable: false,
85 writable: true,
86 configurable: true
87 }
88 });
89
90 if (superClass) {
91 if (Object.setPrototypeOf) {
92 Object.setPrototypeOf(subClass, superClass);
93 } else {
94 subClass.__proto__ = superClass; // eslint-disable-line no-proto
95 }
96 }
97}
98
99function enhanceWithRadium(configOrComposedComponent) {
100 var _class, _temp;
101
102 var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
103
104 if (typeof configOrComposedComponent !== 'function') {
105 var newConfig = _extends({}, config, configOrComposedComponent);
106 return function (configOrComponent) {
107 return enhanceWithRadium(configOrComponent, newConfig);
108 };
109 }
110
111 var component = configOrComposedComponent;
112 var _ComposedComponent = component;
113
114 // Handle Native ES classes.
115 if (isNativeClass(_ComposedComponent)) {
116 // Manually approximate babel's class transpilation, but _with_ a real `new` call.
117 _ComposedComponent = function (OrigComponent) {
118 function NewComponent() {
119 // Ordinarily, babel would produce something like:
120 //
121 // ```
122 // return _possibleConstructorReturn(this, OrigComponent.apply(this, arguments));
123 // ```
124 //
125 // Instead, we just call `new` directly without the `_possibleConstructorReturn` wrapper.
126 var source = new (Function.prototype.bind.apply(OrigComponent, [null].concat(Array.prototype.slice.call(arguments))))();
127
128 // Then we manually update context with properties.
129 copyProperties(source, this);
130
131 return this;
132 }
133
134 inherits(NewComponent, OrigComponent);
135
136 return NewComponent;
137 }(_ComposedComponent);
138 }
139
140 // Handle stateless components
141 if (isStateless(_ComposedComponent)) {
142 _ComposedComponent = function (_Component) {
143 _inherits(ComposedComponent, _Component);
144
145 function ComposedComponent() {
146 _classCallCheck(this, ComposedComponent);
147
148 return _possibleConstructorReturn(this, (ComposedComponent.__proto__ || Object.getPrototypeOf(ComposedComponent)).apply(this, arguments));
149 }
150
151 _createClass(ComposedComponent, [{
152 key: 'render',
153 value: function render() {
154 return component(this.props, this.context);
155 }
156 }]);
157
158 return ComposedComponent;
159 }(_react.Component);
160
161 _ComposedComponent.displayName = component.displayName || component.name;
162 }
163
164 // Shallow copy composed if still original (we may mutate later).
165 if (_ComposedComponent === component) {
166 _ComposedComponent = function (_ComposedComponent2) {
167 _inherits(ComposedComponent, _ComposedComponent2);
168
169 function ComposedComponent() {
170 _classCallCheck(this, ComposedComponent);
171
172 return _possibleConstructorReturn(this, (ComposedComponent.__proto__ || Object.getPrototypeOf(ComposedComponent)).apply(this, arguments));
173 }
174
175 return ComposedComponent;
176 }(_ComposedComponent);
177 }
178
179 var RadiumEnhancer = (_temp = _class = function (_ComposedComponent3) {
180 _inherits(RadiumEnhancer, _ComposedComponent3);
181
182 function RadiumEnhancer() {
183 _classCallCheck(this, RadiumEnhancer);
184
185 var _this3 = _possibleConstructorReturn(this, (RadiumEnhancer.__proto__ || Object.getPrototypeOf(RadiumEnhancer)).apply(this, arguments));
186
187 _this3.state = _this3.state || {};
188 _this3.state._radiumStyleState = {};
189 _this3._radiumIsMounted = true;
190
191 var self = _this3;
192
193 // Handle es7 arrow functions on React class method names by detecting
194 // and transfering the instance method to original class prototype.
195 // (Using a copy of the class).
196 // See: https://github.com/FormidableLabs/radium/issues/738
197 RADIUM_METHODS.forEach(function (name) {
198 var thisDesc = Object.getOwnPropertyDescriptor(self, name);
199 var thisMethod = (thisDesc || {}).value;
200
201 // Only care if have instance method.
202 if (!thisMethod) {
203 return;
204 }
205
206 var radiumDesc = Object.getOwnPropertyDescriptor(RADIUM_PROTO, name);
207 var radiumProtoMethod = radiumDesc.value;
208 var superProtoMethod = _ComposedComponent.prototype[name];
209
210 // Allow transfer when:
211 // 1. have an instance method
212 // 2. the super class prototype doesn't have any method
213 // 3. it is not already the radium prototype's
214 if (!superProtoMethod && thisMethod !== radiumProtoMethod) {
215 // Transfer dynamic render component to Component prototype (copy).
216 Object.defineProperty(_ComposedComponent.prototype, name, thisDesc);
217
218 // Remove instance property, leaving us to have a contrived
219 // inheritance chain of (1) radium, (2) superclass.
220 delete self[name];
221 }
222 });
223 return _this3;
224 }
225
226 _createClass(RadiumEnhancer, [{
227 key: 'componentWillUnmount',
228 value: function componentWillUnmount() {
229 if (_get(RadiumEnhancer.prototype.__proto__ || Object.getPrototypeOf(RadiumEnhancer.prototype), 'componentWillUnmount', this)) {
230 _get(RadiumEnhancer.prototype.__proto__ || Object.getPrototypeOf(RadiumEnhancer.prototype), 'componentWillUnmount', this).call(this);
231 }
232
233 this._radiumIsMounted = false;
234
235 if (this._radiumMouseUpListener) {
236 this._radiumMouseUpListener.remove();
237 }
238
239 if (this._radiumMediaQueryListenersByQuery) {
240 Object.keys(this._radiumMediaQueryListenersByQuery).forEach(function (query) {
241 this._radiumMediaQueryListenersByQuery[query].remove();
242 }, this);
243 }
244 }
245 }, {
246 key: 'getChildContext',
247 value: function getChildContext() {
248 var superChildContext = _get(RadiumEnhancer.prototype.__proto__ || Object.getPrototypeOf(RadiumEnhancer.prototype), 'getChildContext', this) ? _get(RadiumEnhancer.prototype.__proto__ || Object.getPrototypeOf(RadiumEnhancer.prototype), 'getChildContext', this).call(this) : {};
249
250 if (!this.props.radiumConfig) {
251 return superChildContext;
252 }
253
254 var newContext = _extends({}, superChildContext);
255
256 if (this.props.radiumConfig) {
257 newContext._radiumConfig = this.props.radiumConfig;
258 }
259
260 return newContext;
261 }
262 }, {
263 key: 'render',
264 value: function render() {
265 var renderedElement = _get(RadiumEnhancer.prototype.__proto__ || Object.getPrototypeOf(RadiumEnhancer.prototype), 'render', this).call(this);
266 var currentConfig = this.props.radiumConfig || this.context._radiumConfig || config;
267
268 if (config && currentConfig !== config) {
269 currentConfig = _extends({}, config, currentConfig);
270 }
271
272 var _resolveStyles = (0, _resolveStyles3.default)(this, renderedElement, currentConfig),
273 extraStateKeyMap = _resolveStyles.extraStateKeyMap,
274 element = _resolveStyles.element;
275
276 this._extraRadiumStateKeys = Object.keys(extraStateKeyMap);
277
278 return element;
279 }
280
281 /* eslint-disable react/no-did-update-set-state, no-unused-vars */
282
283 }, {
284 key: 'componentDidUpdate',
285 value: function componentDidUpdate(prevProps, prevState) {
286 if (_get(RadiumEnhancer.prototype.__proto__ || Object.getPrototypeOf(RadiumEnhancer.prototype), 'componentDidUpdate', this)) {
287 _get(RadiumEnhancer.prototype.__proto__ || Object.getPrototypeOf(RadiumEnhancer.prototype), 'componentDidUpdate', this).call(this, prevProps, prevState);
288 }
289
290 if (this._extraRadiumStateKeys.length > 0) {
291 var trimmedRadiumState = this._extraRadiumStateKeys.reduce(function (state, key) {
292 var extraStateKey = state[key],
293 remainingState = _objectWithoutProperties(state, [key]);
294
295 return remainingState;
296 }, (0, _getRadiumStyleState2.default)(this));
297
298 this._lastRadiumState = trimmedRadiumState;
299 this.setState({ _radiumStyleState: trimmedRadiumState });
300 }
301 }
302 /* eslint-enable react/no-did-update-set-state, no-unused-vars */
303
304 }]);
305
306 return RadiumEnhancer;
307 }(_ComposedComponent), _class._isRadiumEnhanced = true, _temp);
308
309 // Lazy infer the method names of the Enhancer.
310
311 RADIUM_PROTO = RadiumEnhancer.prototype;
312 RADIUM_METHODS = Object.getOwnPropertyNames(RADIUM_PROTO).filter(function (n) {
313 return n !== 'constructor' && typeof RADIUM_PROTO[n] === 'function';
314 });
315
316 // Class inheritance uses Object.create and because of __proto__ issues
317 // with IE <10 any static properties of the superclass aren't inherited and
318 // so need to be manually populated.
319 // See http://babeljs.io/docs/advanced/caveats/#classes-10-and-below-
320 copyProperties(component, RadiumEnhancer);
321
322 if (process.env.NODE_ENV !== 'production') {
323 // This also fixes React Hot Loader by exposing the original components top
324 // level prototype methods on the Radium enhanced prototype as discussed in
325 // https://github.com/FormidableLabs/radium/issues/219.
326 copyProperties(_ComposedComponent.prototype, RadiumEnhancer.prototype);
327 }
328
329 if (RadiumEnhancer.propTypes && RadiumEnhancer.propTypes.style) {
330 RadiumEnhancer.propTypes = _extends({}, RadiumEnhancer.propTypes, {
331 style: _propTypes2.default.oneOfType([_propTypes2.default.array, _propTypes2.default.object])
332 });
333 }
334
335 RadiumEnhancer.displayName = component.displayName || component.name || 'Component';
336
337 RadiumEnhancer.contextTypes = _extends({}, RadiumEnhancer.contextTypes, {
338 _radiumConfig: _propTypes2.default.object,
339 _radiumStyleKeeper: _propTypes2.default.instanceOf(_styleKeeper2.default)
340 });
341
342 RadiumEnhancer.childContextTypes = _extends({}, RadiumEnhancer.childContextTypes, {
343 _radiumConfig: _propTypes2.default.object,
344 _radiumStyleKeeper: _propTypes2.default.instanceOf(_styleKeeper2.default)
345 });
346
347 return RadiumEnhancer;
348}
\No newline at end of file