UNPKG

@atlaskit/editor-common

Version:

A package that contains common classes and components for editor and renderer

100 lines (99 loc) 2.95 kB
import React from 'react'; export const getKeys = Object.keys; export const getKeysAddedRemovedCommon = (object1, object2) => { const oldKeys = object1 !== null ? getKeys(object1) : []; const newKeys = object2 !== null ? getKeys(object2) : []; const removed = oldKeys.filter(key => !newKeys.includes(key)); const added = newKeys.filter(key => !oldKeys.includes(key)); const common = oldKeys.filter(key => newKeys.includes(key)); return { added, common, removed }; }; export const serializeValue = value => { const valueType = typeof value; if (value === null) { return 'null'; } else if (value === undefined) { return 'undefined'; } else if (valueType === 'string' || valueType === 'number') { return value; } else if (valueType === 'symbol') { return value.toString(); } // Calling toString of function returns whole function text with body. // So, just return function with name. else if (valueType === 'function') { return `function:${value.name}`; } else if (valueType === 'object') { return { type: 'object', keys: Object.keys(value) }; } }; export const getPropsDifference = (object1, object2, curDepth = 0, maxDepth = 2, keysToIgnore = []) => { const { added, common, removed } = getKeysAddedRemovedCommon(object1, object2); const changed = []; common.forEach(key => { const value1 = object1[key]; const value2 = object2[key]; const value1Type = typeof value1; const value2Type = typeof value2; // Do comparision only if values doesn't match (or reference to same object in memory). // Or if key does not exist in keys to ignore. if (value1 !== value2 && keysToIgnore.indexOf(key) === -1) { // if both key value are objects and not referencing same object in memory. // then get recursive difference. if ( /*#__PURE__*/React.isValidElement(value1) || /*#__PURE__*/React.isValidElement(value2)) { changed.push({ key, reactElementChanged: true }); } else if (value1Type === 'object' && value2Type === 'object') { if (curDepth <= maxDepth) { const difference = getPropsDifference(value1, value2, curDepth + 1, maxDepth); changed.push({ key, difference }); } else { changed.push({ key, maxDepthReached: true }); } } else { changed.push({ key, oldValue: serializeValue(value1), newValue: serializeValue(value2) }); } } }); return { added, changed, removed }; }; export const getShallowPropsDifference = (object1, object2) => { const { added, common, removed } = getKeysAddedRemovedCommon(object1, object2); const changed = common.filter(key => object1[key] !== object2[key]); return { added, changed, removed }; };