UNPKG

awv3

Version:
415 lines (338 loc) 15.9 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.Component = undefined; var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray'); var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2); var _keys = require('babel-runtime/core-js/object/keys'); var _keys2 = _interopRequireDefault(_keys); var _defineProperty2 = require('babel-runtime/helpers/defineProperty'); var _defineProperty3 = _interopRequireDefault(_defineProperty2); var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray'); var _slicedToArray3 = _interopRequireDefault(_slicedToArray2); var _entries = require('babel-runtime/core-js/object/entries'); var _entries2 = _interopRequireDefault(_entries); var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of'); var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf); var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _inherits2 = require('babel-runtime/helpers/inherits'); var _inherits3 = _interopRequireDefault(_inherits2); var _extends5 = require('babel-runtime/helpers/extends'); var _extends6 = _interopRequireDefault(_extends5); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); var _promise = require('babel-runtime/core-js/promise'); var _promise2 = _interopRequireDefault(_promise); exports.connect = connect; exports.render = render; exports.destroy = destroy; exports.buildStack = buildStack; exports.prepare = prepare; var _omit = require('lodash/omit'); var _omit2 = _interopRequireDefault(_omit); var _flatten = require('lodash/flatten'); var _flatten2 = _interopRequireDefault(_flatten); var _isEqual = require('lodash/isEqual'); var _isEqual2 = _interopRequireDefault(_isEqual); var _element = require('./element'); var _element2 = _interopRequireDefault(_element); var _objects = require('shallow-equal/objects'); var _objects2 = _interopRequireDefault(_objects); var _stringHash = require('string-hash'); var _stringHash2 = _interopRequireDefault(_stringHash); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var queue = _promise2.default.resolve(), currentId = void 0, frames = {}; var Component = exports.Component = function () { function Component(props) { (0, _classCallCheck3.default)(this, Component); this.id = currentId; this.plugin = frames[this.id].plugin; this.node = undefined; this.props = props || {}; this.refs = {}; //console.log(" constructor", this.constructor.name, this.plugin.type, this.plugin.id) } (0, _createClass3.default)(Component, [{ key: 'dispatch', value: function dispatch(action) { this.plugin.store.dispatch(action); } }, { key: 'setState', value: function setState(state) { var frame = frames[this.id]; var newState = (0, _extends6.default)({}, this.state, state); if (!(0, _objects2.default)(newState, this.state)) { this.state = newState; // Build component stack & construct virtual dom currentId = this.id; frame.order = this.node.order; buildStack(this.node.children, frame.reusable); frame.reusable = frame.reusable.sort(function (a, b) { return a.order - b.order; }); this.node.children = prepare(this.render(this.props, this.state, this.setState.bind(this)), this.node.depth); frame.reusable = []; if (this.node.children.isArray) { var parent = this.node.children; while (parent && parent.isArray && parent.parent) { parent = parent.parent; }renderNodes(this.plugin, parent, parent.parent, true); } else { renderNodes(this.plugin, this.node.children, this.node.parent, true); } } } }]); return Component; }(); function connect(selector) { return function (DecoratedComponent) { return function (_Component) { (0, _inherits3.default)(ConnectedComponent, _Component); function ConnectedComponent() { var _ref; var _temp, _this, _ret; (0, _classCallCheck3.default)(this, ConnectedComponent); for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _ret = (_temp = (_this = (0, _possibleConstructorReturn3.default)(this, (_ref = ConnectedComponent.__proto__ || (0, _getPrototypeOf2.default)(ConnectedComponent)).call.apply(_ref, [this].concat(args))), _this), _this.state = {}, _temp), (0, _possibleConstructorReturn3.default)(_this, _ret); } (0, _createClass3.default)(ConnectedComponent, [{ key: 'componentWillMount', value: function componentWillMount() { var _this2 = this; var oldState = {}; var store = this.plugin.store; this.unsubscribe = store.subscribe(function () { var selectedState = selector(store.getState(), _this2.props); var changedKeys = void 0; (0, _entries2.default)(selectedState).map(function (_ref2) { var _ref3 = (0, _slicedToArray3.default)(_ref2, 2), key = _ref3[0], value = _ref3[1]; if (oldState[key] !== value) { changedKeys = (0, _extends6.default)({}, changedKeys, (0, _defineProperty3.default)({}, key, value)); oldState[key] = value; } }); changedKeys && _this2.setState(changedKeys); }); this.state = (0, _extends6.default)({}, this.state, selector(store.getState(), this.props)); } }, { key: 'componentWillUnmount', value: function componentWillUnmount() { this.unsubscribe(); } }, { key: 'render', value: function render() { var props = (0, _extends6.default)({}, this.props, this.state); return React.createElement(DecoratedComponent, props); } }]); return ConnectedComponent; }(Component); }; } function render(plugin, cb) { queue = queue.then(function () { currentId = plugin.id; //console.log("render plugin", plugin.type, plugin.id) frames[currentId] && destroy(currentId); frames[currentId] = { stack: {}, reusable: [], order: 0, plugin: plugin }; plugin.addElement(renderNodes(plugin, prepare(cb())) //console.log("finished rendering plugin", plugin.type, plugin.id) ); }); } function destroy(id) { var frame = frames[id]; if (frame) { (0, _keys2.default)(frame.stack).forEach(function (key) { return destroyNode(frame, frame.stack[key]); }); frame.plugin.destroyElements(); } } function destroyNode(frame, node) { var traverse = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; if (Array.isArray(node)) return node.forEach(function (node) { return destroyNode(frame, node); });else if (node) { node.unsubscribes && node.unsubscribes.forEach(function (unsub) { return unsub(); }); if (node.component) { node.component.componentWillUnmount && node.component.componentWillUnmount(); node.component = undefined; } if (node.element) { var elements = Array.isArray(node.element) ? node.element : [node.element]; elements.forEach(function (element) { var parent = node.parent; while (parent && !parent.element) { parent = parent.parent; }if (parent && parent.element) parent.element.children = parent.element.children.filter(function (id) { return id != element.id; }); element.destroy(); }); node.element = undefined; } traverse && destroyNode(frame, node.children, traverse); delete frame.stack[node.tag]; } } function buildStack(tree, target) { if (Array.isArray(tree)) return tree.forEach(function (node) { return buildStack(node, target); });(Array.isArray(tree) ? tree : [tree]).forEach(function (child) { child.el && !(child.el.prototype instanceof _element2.default) && target.push(child); child.children && buildStack(child.children, target); }); } function prepare(tree) { var depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [0]; if (Array.isArray(tree)) { for (var i in tree) { tree[i] = prepare(tree[i] || {}, [].concat((0, _toConsumableArray3.default)(depth), [parseInt(i)])); } } else { tree.depth = [].concat((0, _toConsumableArray3.default)(depth)); tree.tag = tree.hash + '.' + tree.depth.join('.'); if (tree.children) tree.children = prepare(tree.children, depth); } return tree; } function renderNodes(plugin, node, parent) { var reconcile = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; var frame = frames[plugin.id]; if (Array.isArray(node)) { return node.map(function (node) { return renderNodes(plugin, node, parent); }); } if (node && node.el) { var found = frame.stack[node.tag]; var target = found ? found : node; var element = target.element; if (found && Array.isArray(node.children)) { // Remove missing array items or items without key var nodeArrays = node.children.filter(Array.isArray); target.children.filter(Array.isArray).forEach(function (targetArray, index) { var nodeArray = nodeArrays[index]; targetArray.forEach(function (targetChild, index) { var test = targetChild.props.key !== undefined && nodeArray.find(function (nodeChild) { return targetChild.props.key === nodeChild.props.key; }); if (test === undefined) { destroyNode(frame, frame.stack[targetChild.tag]); delete targetArray[index]; } }); }); } var flattenedChildren = Array.isArray(node.children) ? (0, _flatten2.default)(node.children) : node.children; parent = parent || target.parent; var parentElem = (parent || {}).element; if (!found) { frame.stack[node.tag] = target; } target.parent = parent; if (target.el.prototype instanceof _element2.default) { // Render children into Elements and remove missing items // Items become undefined when they are toggled by ternary var children = (0, _flatten2.default)(renderNodes(plugin, flattenedChildren, target)); for (var i = 0; i < children.length; i++) { children[i] === undefined && target.children[i] && frame.stack[target.children[i].tag] && destroyNode(frame, frame.stack[target.children[i].tag]); } var update = (0, _extends6.default)({}, node.props, { children: children.filter(function (e) { return e; }).map(function (e) { return e.id; }) }); if (found) { var newProps = (0, _keys2.default)(update).filter(function (key) { return !(0, _isEqual2.default)(update[key], target.element[key]); }).reduce(function (acc, key) { return (0, _extends6.default)({}, acc, (0, _defineProperty3.default)({}, key, update[key])); }, {}); (0, _keys2.default)(newProps).length > 0 && target.element.update(newProps); } else { target.element = new target.el(frame.plugin, update); } target.children = node.children; target.unsubscribes && target.unsubscribes.forEach(function (unsub) { return unsub(); }); target.unsubscribes = target.handlers.map(function (handler) { var name = handler.charAt(2).toLowerCase() + handler.substr(3); return target.element.observe(function (state) { return state[name]; }, function (state, old) { return node.events[handler](state, old); }); }); } else { return renderNodes(plugin, flattenedChildren, parent); } return target.element; } } var React = { createElement: function createElement(el, props) { for (var _len2 = arguments.length, children = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { children[_key2 - 2] = arguments[_key2]; } var frame = frames[currentId]; if (el.prototype instanceof _element2.default) { var handlers = (0, _keys2.default)(props || {}).filter(function (key) { return typeof props[key] === 'function' && key.startsWith('on'); }); var events = handlers.reduce(function (acc, val) { return (0, _extends6.default)({}, acc, (0, _defineProperty3.default)({}, val, props[val])); }, {}); return { el: el, hash: el.name, props: (0, _omit2.default)(props, handlers), handlers: handlers, events: events, children: children }; } else { var trace = frame.reusable.shift(); var node = { el: el, hash: (0, _stringHash2.default)(el.toString()), props: props || {}, order: frame.order++ }; if (trace && trace.el === node.el && trace.hash === node.hash && trace.component.props.key === node.props.key) { node = trace; var newProps = (0, _extends6.default)({}, node.component.props, props, { children: children }); node.component.componentWillReceiveProps && node.component.componentWillReceiveProps(newProps); node.component.props = newProps; } else { node.component = new el((0, _extends6.default)({}, props, { children: children })); node.component.node = node; node.component.componentWillMount && node.component.componentWillMount(); } node.children = node.component.render(node.component.props, node.component.state, node.component.setState.bind(node.component)); node.isArray = Array.isArray(node.children); return node; } } }; exports.default = React;