UNPKG

11.7 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _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; };
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 * React Blessed Component
11 * ========================
12 *
13 * React component abstraction for the blessed library.
14 */
15
16
17var _blessed = require('blessed');
18
19var _blessed2 = _interopRequireDefault(_blessed);
20
21var _ReactMultiChild = require('react/lib/ReactMultiChild');
22
23var _ReactMultiChild2 = _interopRequireDefault(_ReactMultiChild);
24
25var _ReactBlessedIDOperations = require('./ReactBlessedIDOperations');
26
27var _ReactBlessedIDOperations2 = _interopRequireDefault(_ReactBlessedIDOperations);
28
29var _invariant = require('invariant');
30
31var _invariant2 = _interopRequireDefault(_invariant);
32
33var _update = require('./update');
34
35var _update2 = _interopRequireDefault(_update);
36
37var _solveClass = require('./solveClass');
38
39var _solveClass2 = _interopRequireDefault(_solveClass);
40
41var _lodash = require('lodash');
42
43function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
44
45function _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; }
46
47function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
48
49/**
50 * Variable types that must be solved as content rather than real children.
51 */
52var CONTENT_TYPES = { string: true, number: true };
53
54/**
55 * Renders the given react element with blessed.
56 *
57 * @constructor ReactBlessedComponent
58 * @extends ReactMultiChild
59 */
60
61var ReactBlessedComponent = function () {
62 function ReactBlessedComponent(tag) {
63 _classCallCheck(this, ReactBlessedComponent);
64
65 this._tag = tag.toLowerCase();
66 this._updating = false;
67 this._renderedChildren = null;
68 this._previousStyle = null;
69 this._previousStyleCopy = null;
70 this._rootNodeID = null;
71 this._wrapperState = null;
72 this._topLevelWrapper = null;
73 this._nodeWithLegacyProperties = null;
74 }
75
76 _createClass(ReactBlessedComponent, [{
77 key: 'construct',
78 value: function construct(element) {
79 var _this = this;
80
81 // Setting some properties
82 this._currentElement = element;
83 this._eventListener = function (type) {
84 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
85 args[_key - 1] = arguments[_key];
86 }
87
88 if (_this._updating) return;
89
90 var handler = _this._currentElement.props['on' + (0, _lodash.startCase)(type).replace(/ /g, '')];
91
92 if (typeof handler === 'function') {
93 if (type === 'focus' || type === 'blur') {
94 args[0] = _ReactBlessedIDOperations2.default.get(_this._rootNodeID);
95 }
96 handler.apply(undefined, args);
97 }
98 };
99 }
100
101 /**
102 * Mounting the root component.
103 *
104 * @internal
105 * @param {string} rootID - The root blessed ID for this node.
106 * @param {ReactBlessedReconcileTransaction} transaction
107 * @param {object} context
108 */
109
110 }, {
111 key: 'mountComponent',
112 value: function mountComponent(rootID, transaction, context) {
113 this._rootNodeID = rootID;
114
115 // Mounting blessed node
116 var node = this.mountNode(_ReactBlessedIDOperations2.default.getParent(rootID), this._currentElement);
117
118 _ReactBlessedIDOperations2.default.add(rootID, node);
119
120 // Mounting children
121 var childrenToUse = this._currentElement.props.children;
122 childrenToUse = childrenToUse === null ? [] : [].concat(childrenToUse);
123
124 if (childrenToUse.length) {
125
126 // Discriminating content components from real children
127 var _groupBy = (0, _lodash.groupBy)(childrenToUse, function (c) {
128 return CONTENT_TYPES[typeof c === 'undefined' ? 'undefined' : _typeof(c)] ? 'content' : 'realChildren';
129 }),
130 _groupBy$content = _groupBy.content,
131 content = _groupBy$content === undefined ? null : _groupBy$content,
132 _groupBy$realChildren = _groupBy.realChildren,
133 realChildren = _groupBy$realChildren === undefined ? [] : _groupBy$realChildren;
134
135 // Setting textual content
136
137
138 if (content) node.setContent('' + content.join(''));
139
140 // Mounting real children
141 this.mountChildren(realChildren, transaction, context);
142 }
143
144 // Rendering the screen
145 _ReactBlessedIDOperations2.default.screen.debouncedRender();
146 }
147
148 /**
149 * Mounting the blessed node itself.
150 *
151 * @param {BlessedNode|BlessedScreen} parent - The parent node.
152 * @param {ReactElement} element - The element to mount.
153 * @return {BlessedNode} - The mounted node.
154 */
155
156 }, {
157 key: 'mountNode',
158 value: function mountNode(parent, element) {
159 var props = element.props,
160 type = element.type,
161 children = props.children,
162 options = _objectWithoutProperties(props, ['children']),
163 blessedElement = _blessed2.default[type];
164
165 (0, _invariant2.default)(!!blessedElement, 'Invalid blessed element "' + type + '".');
166
167 var node = _blessed2.default[type]((0, _solveClass2.default)(options));
168
169 node.on('event', this._eventListener);
170 parent.append(node);
171
172 return node;
173 }
174
175 /**
176 * Receive a component update.
177 *
178 * @param {ReactElement} nextElement
179 * @param {ReactReconcileTransaction} transaction
180 * @param {object} context
181 * @internal
182 * @overridable
183 */
184
185 }, {
186 key: 'receiveComponent',
187 value: function receiveComponent(nextElement, transaction, context) {
188 var _nextElement$props = nextElement.props,
189 children = _nextElement$props.children,
190 options = _objectWithoutProperties(_nextElement$props, ['children']),
191 node = _ReactBlessedIDOperations2.default.get(this._rootNodeID);
192
193 this._updating = true;
194 (0, _update2.default)(node, (0, _solveClass2.default)(options));
195 this._updating = false;
196
197 // Updating children
198 var childrenToUse = children === null ? [] : [].concat(children);
199
200 // Discriminating content components from real children
201
202 var _groupBy2 = (0, _lodash.groupBy)(childrenToUse, function (c) {
203 return CONTENT_TYPES[typeof c === 'undefined' ? 'undefined' : _typeof(c)] ? 'content' : 'realChildren';
204 }),
205 _groupBy2$content = _groupBy2.content,
206 content = _groupBy2$content === undefined ? null : _groupBy2$content,
207 _groupBy2$realChildre = _groupBy2.realChildren,
208 realChildren = _groupBy2$realChildre === undefined ? [] : _groupBy2$realChildre;
209
210 // Setting textual content
211
212
213 if (content) node.setContent('' + content.join(''));
214
215 this.updateChildren(realChildren, transaction, context);
216
217 _ReactBlessedIDOperations2.default.screen.debouncedRender();
218 }
219
220 /**
221 * Dropping the component.
222 */
223
224 }, {
225 key: 'unmountComponent',
226 value: function unmountComponent() {
227 this.unmountChildren();
228
229 var node = _ReactBlessedIDOperations2.default.get(this._rootNodeID);
230
231 node.off('event', this._eventListener);
232 node.destroy();
233
234 _ReactBlessedIDOperations2.default.drop(this._rootNodeID);
235
236 this._rootNodeID = null;
237
238 _ReactBlessedIDOperations2.default.screen.debouncedRender();
239 }
240
241 /**
242 * Getting a public instance of the component for refs.
243 *
244 * @return {BlessedNode} - The instance's node.
245 */
246
247 }, {
248 key: 'getPublicInstance',
249 value: function getPublicInstance() {
250 return _ReactBlessedIDOperations2.default.get(this._rootNodeID);
251 }
252 }]);
253
254 return ReactBlessedComponent;
255}();
256
257/**
258 * Extending the component with the MultiChild mixin.
259 */
260
261
262exports.default = ReactBlessedComponent;
263(0, _lodash.extend)(ReactBlessedComponent.prototype, _ReactMultiChild2.default.Mixin);
\No newline at end of file