@ray-core/runtime
Version:
Ray 是一个全新的基于 React 的小程序开发框架
114 lines (113 loc) • 4.64 kB
JavaScript
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;
}