UNPKG

@ray-core/runtime

Version:

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

114 lines (113 loc) 4.64 kB
import { includes } from '@ray-core/framework-shared'; var STYLE = ['style', 'placeholderStyle']; var CHILDREN = 'children'; var CLASS_NAME = 'className'; export default function diffProperties(lastRawProps, nextRawProps) { var updatePayload = []; var lastProps = lastRawProps; var nextProps = nextRawProps; var propKey; var styleName; var hasOwnProperty = Object.prototype.hasOwnProperty; var styleUpdates = {}; for (propKey in lastProps) { if (propKey === '__p__') continue; if (hasOwnProperty.call(nextProps, propKey) || !hasOwnProperty.call(lastProps, propKey) || lastProps[propKey] == null) { continue; } if (includes(STYLE, propKey)) { var lastStyle = lastProps[propKey]; for (styleName in lastStyle) { if (hasOwnProperty.call(lastStyle, styleName)) { if (!styleUpdates[propKey]) { styleUpdates[propKey] = {}; } styleUpdates[propKey][styleName] = ''; } } } else { // For all other deleted properties we add it to the queue. We use // the whitelist in the commit phase instead. updatePayload.push(propKey, propKey === CLASS_NAME ? '' : null); } } for (propKey in nextProps) { if (propKey === '__p__') continue; var nextProp = nextProps[propKey]; var lastProp = lastProps != null ? lastProps[propKey] : undefined; if (!hasOwnProperty.call(nextProps, propKey) || nextProp === lastProp || (nextProp == null && lastProp == null)) { continue; } if (includes(STYLE, propKey)) { if (process.env.NODE_ENV === 'development') { if (nextProp) { // Freeze the next style object so that we can assume it won't be // mutated. We have already warned for this in the past. Object.freeze(nextProp); } } if (lastProp) { // Unset styles on `lastProp` but not on `nextProp`. for (styleName in lastProp) { if (hasOwnProperty.call(lastProp, styleName) && (!nextProp || !hasOwnProperty.call(nextProp, styleName))) { if (!styleUpdates[propKey]) { styleUpdates[propKey] = {}; } styleUpdates[propKey][styleName] = ''; } } // Update styles that changed since `lastProp`. for (styleName in nextProp) { if (hasOwnProperty.call(nextProp, styleName) && lastProp[styleName] !== nextProp[styleName]) { if (!styleUpdates[propKey]) { styleUpdates[propKey] = {}; } styleUpdates[propKey][styleName] = nextProp[styleName]; } } } else { // Relies on `updateStylesByID` not mutating `styleUpdates`. if (!styleUpdates[propKey]) { updatePayload.push(propKey, null); } styleUpdates[propKey] = nextProp; } } else if (propKey === CHILDREN) { if (lastProp !== nextProp && (typeof nextProp === 'string' || typeof nextProp === 'number')) { updatePayload.push(propKey, '' + nextProp); } } else { // For any other property we always add it to the queue and then we // filter it out using the whitelist during the commit. updatePayload.push(propKey, nextProp); } } // 由于 style 要转换成 string, 所以必须整个 style 对象都更新 for (var styleKey in styleUpdates) { var styleValue = styleUpdates[styleKey]; if (styleValue) { updatePayload.push(styleKey, Object.assign({}, lastProps[styleKey], styleValue)); } } if (hasOwnProperty.call(lastRawProps, '__p__') && hasOwnProperty.call(nextRawProps, '__p__')) { var __p = void 0; for (var index = 0; index < updatePayload.length;) { if (!__p) { __p = {}; } __p[updatePayload[index++]] = updatePayload[index++]; } if (__p) { updatePayload.push('__p__', __p); } } return updatePayload.length ? updatePayload : null; }