awv3
Version:
⚡ AWV3 embedded CAD
415 lines (338 loc) • 15.9 kB
JavaScript
;
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;