( prev: Object, next: Object, properties: Array<[string, string]>, indent: number, )
| 245 | const UNCHANGED = '\u2007\xa0'; |
| 246 | |
| 247 | export function addObjectDiffToProperties( |
| 248 | prev: Object, |
| 249 | next: Object, |
| 250 | properties: Array<[string, string]>, |
| 251 | indent: number, |
| 252 | ): boolean { |
| 253 | // Note: We diff even non-owned properties here but things that are shared end up just the same. |
| 254 | // If a property is added or removed, we just emit the property name and omit the value it had. |
| 255 | // Mainly for performance. We need to minimize to only relevant information. |
| 256 | let isDeeplyEqual = true; |
| 257 | for (const key in prev) { |
| 258 | if (!(key in next)) { |
| 259 | properties.push([REMOVED + '\xa0\xa0'.repeat(indent) + key, '\u2026']); |
| 260 | isDeeplyEqual = false; |
| 261 | } |
| 262 | } |
| 263 | for (const key in next) { |
| 264 | if (key in prev) { |
| 265 | const prevValue = prev[key]; |
| 266 | const nextValue = next[key]; |
| 267 | if (prevValue !== nextValue) { |
| 268 | if (indent === 0 && key === 'children') { |
| 269 | // Omit any change inside the top level children prop since it's expected to change |
| 270 | // with any change to children of the component and their props will be logged |
| 271 | // elsewhere but still mark it as a cause of render. |
| 272 | const line = '\xa0\xa0'.repeat(indent) + key; |
| 273 | properties.push([REMOVED + line, '\u2026'], [ADDED + line, '\u2026']); |
| 274 | isDeeplyEqual = false; |
| 275 | continue; |
| 276 | } |
| 277 | if (indent >= 3) { |
| 278 | // Just fallthrough to print the two values if we're deep. |
| 279 | // This will skip nested properties of the objects. |
| 280 | } else if ( |
| 281 | typeof prevValue === 'object' && |
| 282 | typeof nextValue === 'object' && |
| 283 | prevValue !== null && |
| 284 | nextValue !== null && |
| 285 | prevValue.$$typeof === nextValue.$$typeof |
| 286 | ) { |
| 287 | if (nextValue.$$typeof === REACT_ELEMENT_TYPE) { |
| 288 | if ( |
| 289 | prevValue.type === nextValue.type && |
| 290 | prevValue.key === nextValue.key |
| 291 | ) { |
| 292 | // If the only thing that has changed is the props of a nested element, then |
| 293 | // we omit the props because it is likely to be represented as a diff elsewhere. |
| 294 | const typeName = |
| 295 | getComponentNameFromType(nextValue.type) || '\u2026'; |
| 296 | const line = '\xa0\xa0'.repeat(indent) + key; |
| 297 | const desc = '<' + typeName + ' \u2026 />'; |
| 298 | properties.push([REMOVED + line, desc], [ADDED + line, desc]); |
| 299 | isDeeplyEqual = false; |
| 300 | continue; |
| 301 | } |
| 302 | } else { |
| 303 | // $FlowFixMe[method-unbinding] |
| 304 | const prevKind = Object.prototype.toString.call(prevValue); |
no test coverage detected