From b6e1d086043a801682ff01b00c7a623d529b46c0 Mon Sep 17 00:00:00 2001 From: Pascal Fong Kye Date: Wed, 12 Aug 2020 18:15:53 +0200 Subject: [PATCH] DevTools bug fix: Proxied methods should be safely dehydrated for display --- .../react-devtools-extensions/src/backend.js | 2 +- .../inspectedElementContext-test.js.snap | 1 + .../__tests__/inspectedElementContext-test.js | 16 ++++++++++++++++ packages/react-devtools-shared/src/hydration.js | 5 ++++- packages/react-devtools-shared/src/utils.js | 4 +++- 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/packages/react-devtools-extensions/src/backend.js b/packages/react-devtools-extensions/src/backend.js index 357c286c2e287..aa8578a108646 100644 --- a/packages/react-devtools-extensions/src/backend.js +++ b/packages/react-devtools-extensions/src/backend.js @@ -72,7 +72,7 @@ function setup(hook) { initBackend(hook, agent, window); // Let the frontend know that the backend has attached listeners and is ready for messages. - // This covers the case of of syncing saved values after reloading/navigating while DevTools remain open. + // This covers the case of syncing saved values after reloading/navigating while DevTools remain open. bridge.send('extensionBackendInitialized'); // Setup React Native style editor if a renderer like react-native-web has injected it. diff --git a/packages/react-devtools-shared/src/__tests__/__snapshots__/inspectedElementContext-test.js.snap b/packages/react-devtools-shared/src/__tests__/__snapshots__/inspectedElementContext-test.js.snap index 2ef217a451e61..1989aee6391a9 100644 --- a/packages/react-devtools-shared/src/__tests__/__snapshots__/inspectedElementContext-test.js.snap +++ b/packages/react-devtools-shared/src/__tests__/__snapshots__/inspectedElementContext-test.js.snap @@ -541,6 +541,7 @@ exports[`InspectedElementContext should support complex data types: 1: Inspected "object_of_objects": { "inner": {} }, + "proxy": {}, "react_element": {}, "regexp": {}, "set": { diff --git a/packages/react-devtools-shared/src/__tests__/inspectedElementContext-test.js b/packages/react-devtools-shared/src/__tests__/inspectedElementContext-test.js index 4e292ecdbe5a7..29e8e379e4e43 100644 --- a/packages/react-devtools-shared/src/__tests__/inspectedElementContext-test.js +++ b/packages/react-devtools-shared/src/__tests__/inspectedElementContext-test.js @@ -549,6 +549,14 @@ describe('InspectedElementContext', () => { } const instance = new Class(); + const proxyInstance = new Proxy(() => {}, { + get: function(_, name) { + return function() { + return null; + }; + }, + }); + const container = document.createElement('div'); await utils.actAsync(() => ReactDOM.render( @@ -567,6 +575,7 @@ describe('InspectedElementContext', () => { map={mapShallow} map_of_maps={mapOfMaps} object_of_objects={objectOfObjects} + proxy={proxyInstance} react_element={} regexp={/abc/giu} set={setShallow} @@ -619,6 +628,7 @@ describe('InspectedElementContext', () => { map, map_of_maps, object_of_objects, + proxy, react_element, regexp, set, @@ -722,6 +732,12 @@ describe('InspectedElementContext', () => { ); expect(object_of_objects.inner[meta.preview_short]).toBe('{…}'); + expect(proxy[meta.inspectable]).toBe(false); + expect(proxy[meta.name]).toBe('function'); + expect(proxy[meta.type]).toBe('function'); + expect(proxy[meta.preview_long]).toBe('ƒ () {}'); + expect(proxy[meta.preview_short]).toBe('ƒ () {}'); + expect(react_element[meta.inspectable]).toBe(false); expect(react_element[meta.name]).toBe('span'); expect(react_element[meta.type]).toBe('react_element'); diff --git a/packages/react-devtools-shared/src/hydration.js b/packages/react-devtools-shared/src/hydration.js index f46048f75e646..23cb0a68fd9b2 100644 --- a/packages/react-devtools-shared/src/hydration.js +++ b/packages/react-devtools-shared/src/hydration.js @@ -151,7 +151,10 @@ export function dehydrate( inspectable: false, preview_short: formatDataForPreview(data, false), preview_long: formatDataForPreview(data, true), - name: data.name || 'function', + name: + typeof data.name === 'function' || !data.name + ? 'function' + : data.name, type, }; diff --git a/packages/react-devtools-shared/src/utils.js b/packages/react-devtools-shared/src/utils.js index 3472e2c6dba9c..419aaac0c3dd0 100644 --- a/packages/react-devtools-shared/src/utils.js +++ b/packages/react-devtools-shared/src/utils.js @@ -539,7 +539,9 @@ export function formatDataForPreview( case 'html_element': return `<${truncateForDisplay(data.tagName.toLowerCase())} />`; case 'function': - return truncateForDisplay(`ƒ ${data.name}() {}`); + return truncateForDisplay( + `ƒ ${typeof data.name === 'function' ? '' : data.name}() {}`, + ); case 'string': return `"${data}"`; case 'bigint':