UNPKG

@ray-core/runtime

Version:

Ray 是一个全新的基于 React 的小程序开发框架

466 lines (465 loc) 17.7 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __values = (this && this.__values) || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.processProps = void 0; var framework_shared_1 = require("@ray-core/framework-shared"); var propsAlias_1 = __importStar(require("./propsAlias")); var constants_1 = require("./constants"); var instanceId_1 = require("./instanceId"); var typeOf_1 = require("./utils/typeOf"); var parseHTML_1 = require("./utils/parseHTML"); var gStore_1 = require("./gStore"); var isWrappedMethodByRay = function (k) { return constants_1.RAY_METHOD_REGEXP.test(k); }; function processProps(newProps, node) { node.unregisteredCallbacks(); function h(newProps, node, parentKey) { var e_1, _a; if (parentKey === void 0) { parentKey = ''; } var props = (0, typeOf_1.typeOf)(newProps) === 'array' ? [] : {}; var _loop_1 = function (propKey) { var value = newProps[propKey]; if (isWrappedMethodByRay(value)) { value = gStore_1.gStore.getCallback(value); } var k = parentKey ? "".concat(parentKey, ".").concat(propKey) : propKey; var t = (0, typeOf_1.typeOf)(value); if (propKey === 'children') { // pass } else if (t === 'function') { var id = node.registerCallback(k, value); props[propKey] = id; } else if (t === 'object') { props[propKey] = h(value, node, k); } else if (t === 'array') { props[propKey] = value.map(function (item, index) { var t1 = (0, typeOf_1.typeOf)(item); var k1 = parentKey ? "".concat(parentKey, ".").concat(propKey, ".").concat(index) : "".concat(propKey, ".").concat(index); if (t1 === 'object' || t1 === 'array') { return h(item, node, k1); } if (t1 === 'function') { return node.registerCallback(k1, value); } return item; }); } else if (propKey === 'style') { props[propKey] = value || ''; } else { props[propKey] = value; } }; try { for (var _b = __values(Object.keys(newProps)), _c = _b.next(); !_c.done; _c = _b.next()) { var propKey = _c.value; _loop_1(propKey); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_1) throw e_1.error; } } return props; } return h(newProps, node); } exports.processProps = processProps; function toRawNode(node, skip2html) { var data; if (node.type === constants_1.TYPE_TEXT) { data = { id: node.id, type: node.type, text: node.text, }; } else { data = { id: node.id, type: node.type, props: node.props, children: [], text: node.text, }; } if (data.type === 'page-slot') { return data; } var d = skip2html ? data : framework_shared_1.RuntimeOptions.get('pluginDriver').onVirtualNodeSerialize(data, false); data = d || data; data.props = (0, propsAlias_1.default)(data.props, data.type); return data; } var VNode = /** @class */ (function () { function VNode(_a) { var type = _a.type, props = _a.props, container = _a.container; this.mounted = false; this.deleted = false; this.parent = null; this.callbackIds = new Set(); this.children = []; this.id = (0, instanceId_1.generate)(); this.container = container; this.type = type; if (props) { props = processProps(props, this); props.__instid__ = this.id; } this.props = props; if (props && props.dangerouslySetInnerHTML) { this.setInnerHTML(props.dangerouslySetInnerHTML.__html); } } VNode.prototype.appendChild = function (node) { var _this_1 = this; node.parent = this; node.deleted = false; // 交换节点时删除的节点会被复用 if (node.type === 'page-slot') { this.container._pageSlot = node; } this.children = this.children.filter(function (c) { return c !== node; }); // 解决节点交换位置后,节点重复的问题 var slots = this.container.replaceSlot(this, node); !slots && this.children.push(node); if (this.isMounted()) { if (slots) { slots.forEach(function (slot) { _this_1.container.requestUpdate({ type: 'splice', path: _this_1.path, id: slot.id, children: _this_1.children, raw: slot.toJSON(), node: _this_1, }); }); } else { this.container.requestUpdate({ type: 'splice', path: this.path, id: node.id, children: this.children, raw: node.toJSON(), node: this, }); } } }; VNode.prototype.removeChild = function (node) { var _a; if (node.type === 'page-slot') { var c = this.container; if (node.id === ((_a = c._pageSlot) === null || _a === void 0 ? void 0 : _a.id)) { c._pageSlot = null; } } if (node.parent !== this) { return; } this.container.removeSlot(this, node); node.deleted = true; node.unregisteredCallbacks(); for (var n = 0; n < this.children.length; n++) { var child = this.children[n]; if (child.id === node.id) { this.children.splice(n, 1); break; } } if (this.isMounted()) { this.container.requestUpdate({ type: 'splice', path: this.path, id: node.id, children: this.children, raw: null, node: this, }); } }; VNode.prototype.insertBefore = function (node, referenceNode) { var _this_1 = this; if (node.type === 'page-slot') { this.container._pageSlot = node; } node.parent = this; node.deleted = false; // 交换节点时删除的节点会被复用 this.children = this.children.filter(function (c) { return c !== node; }); var children = [].concat(this.children); var slots; for (var n = 0; n < children.length; n++) { var child = children[n]; if (child.id === referenceNode.id) { slots = this.container.replaceSlot(this, node, n); !slots && this.children.splice(n, 0, node); break; } } if (this.isMounted()) { if (slots) { slots.forEach(function (slot) { _this_1.container.requestUpdate({ type: 'splice', path: _this_1.path, id: slot.id, children: _this_1.children, raw: slot.toJSON(), node: _this_1, }); }); } else { this.container.requestUpdate({ type: 'splice', path: this.path, id: node.id, children: this.children, raw: node.toJSON(), node: this, }); } } }; // todo 需要注意安全 VNode.prototype.setInnerHTML = function (html) { var _this_1 = this; var container = this.container; var data = html ? (0, parseHTML_1.parseHTML)(html) : []; var fn = function (item, parent) { item = framework_shared_1.RuntimeOptions.get('pluginDriver').onSetInnerHTML(item); if (item === null || item === undefined) { return; } var type; var props; if (typeof item === 'string') { type = constants_1.TYPE_TEXT; props = null; } else { type = item.type; props = item.props; } var node = new VNode({ type: type, props: props, container: container }); if (typeof item === 'string') { node.text = item; } else { var children = (item.children || []).map(function (x) { return fn(x, node); }); node.children = children.filter(function (x) { return x; }); } node.parent = parent; return node; }; this.children = data.map(function (x) { return fn(x, _this_1); }).filter(function (x) { return x; }); }; VNode.prototype.update = function (payload) { var _a; var _this_1 = this; if (this.type === 'text' || !payload) { var slots = this.container.replaceSlot(this.parent, this); if (slots) { var _this_2 = this.parent; slots.forEach(function (slot) { _this_1.container.requestUpdate({ type: 'splice', path: _this_2.path, id: slot.id, children: _this_2.children, raw: slot.toJSON(), node: _this_2, }); }); } else { this.container.requestUpdate({ type: 'splice', // root 不会更新,所以肯定有 parent path: this.parent.path, id: this.id, raw: this.toJSON(), node: this, }); } return; } var parentPath = this.parent.path; for (var i = 0; i < payload.length; i = i + 2) { var data = { id: this.id, type: this.type, props: (_a = {}, _a[payload[i]] = payload[i + 1], _a), }; data = framework_shared_1.RuntimeOptions.get('pluginDriver').onVirtualNodeSerialize(data, true) || data; var keyAndValue = Object.entries(data.props)[0]; var _b = __read((0, propsAlias_1.propAlias)(keyAndValue[0], keyAndValue[1], data.type), 2), propName = _b[0], propValue = _b[1]; var path = __spreadArray(__spreadArray([], __read(parentPath), false), ['nodes', this.id.toString(), 'props'], false); if (framework_shared_1.RuntimeOptions.get('platform') === 'ali') { var index = this.parent.children.indexOf(this); path = __spreadArray(__spreadArray([], __read(parentPath), false), ["children[".concat(index, "].props")], false); } if (propName === 'dangerouslySetInnerHTML') { this.setInnerHTML(propValue.__html); } this.container.requestUpdate({ type: 'set', path: path, name: propName, value: propValue, node: this, }); } }; Object.defineProperty(VNode.prototype, "path", { get: function () { var dataPath = []; var parents = []; var parent = this.parent; while (parent) { parents.unshift(parent); parent = parent.parent; } for (var i = 0; i < parents.length; i++) { var child = parents[i + 1] || this; if (framework_shared_1.RuntimeOptions.get('platform') === 'ali') { dataPath.push('children'); var index = child.parent.children.indexOf(child); dataPath.push(index.toString()); } else { dataPath.push('nodes'); dataPath.push(child.id.toString()); } } return dataPath; }, enumerable: false, configurable: true }); VNode.prototype.isMounted = function () { return this.parent ? this.parent.isMounted() : this.mounted; }; VNode.prototype.isDeleted = function () { var _a, _b; return this.deleted === true ? this.deleted : (_b = (_a = this.parent) === null || _a === void 0 ? void 0 : _a.isDeleted()) !== null && _b !== void 0 ? _b : false; }; VNode.prototype.registerCallback = function (propKey, propValue) { var _a; // 传递的函数包含在数组中 var index = (_a = propKey.match(/\.(\d+)$/)) === null || _a === void 0 ? void 0 : _a[1]; if (index) { index = Number(index); } var id = "".concat(constants_1.RAY_METHOD, "_").concat(this.id, "_").concat(propKey); this.callbackIds.add(id); this.container.createCallback(id, propKey, this, index ? propValue[index] : propValue); return id; }; VNode.prototype.unregisteredCallbacks = function () { var _this_1 = this; this.callbackIds.forEach(function (id) { _this_1.container.removeCallback(id); }); }; VNode.prototype.toJSON = function (skip2html) { var stack = []; var rawNode = toRawNode(this, skip2html); stack.push({ current: rawNode, children: this.children, }); while (stack.length > 0) { // while 循环已经保证了不会有空值 var stackItem = stack.pop(); var _a = stackItem.children, children = _a === void 0 ? [] : _a, current = stackItem.current; for (var i = children.length - 1; i >= 0; i--) { var item = children[i]; var currentRawNode = toRawNode(item, skip2html); if (framework_shared_1.RuntimeOptions.get('platform') !== 'ali') { current.children.unshift(currentRawNode.id); } else { current.children.unshift(currentRawNode); } if (framework_shared_1.RuntimeOptions.get('platform') !== 'ali') { if (!current.nodes) { current.nodes = {}; } current.nodes[currentRawNode.id] = currentRawNode; } stack.push({ current: currentRawNode, children: item.children, }); } } return rawNode; }; return VNode; }()); exports.default = VNode;