@samitouri / QOS-React / commits / b6e1d08604

DevTools bug fix: Proxied methods should be safely dehydrated for display

Pascal Fong Kye committed Aug 12, 2020 at 18:15 UTC b6e1d086043a801682ff01b00c7a623d529b46c0
5 files changed +25 -3
packages/react-devtools-extensions/src/backend.js
+1 -1
@@ -72,7 +72,7 @@ function setup(hook) {
72 initBackend(hook, agent, window);
73
74 // Let the frontend know that the backend has attached listeners and is ready for messages.
75 - // This covers the case of of syncing saved values after reloading/navigating while DevTools remain open.
75 + // This covers the case of syncing saved values after reloading/navigating while DevTools remain open.
76 bridge.send('extensionBackendInitialized');
77
78 // Setup React Native style editor if a renderer like react-native-web has injected it.
packages/react-devtools-shared/src/__tests__/__snapshots__/inspectedElementContext-test.js.snap
+1
@@ -541,6 +541,7 @@ exports[`InspectedElementContext should support complex data types: 1: Inspected
541 "object_of_objects": {
542 "inner": {}
543 },
544 + "proxy": {},
545 "react_element": {},
546 "regexp": {},
547 "set": {
packages/react-devtools-shared/src/__tests__/inspectedElementContext-test.js
+16
@@ -549,6 +549,14 @@ describe('InspectedElementContext', () => {
549 }
550 const instance = new Class();
551
552 + const proxyInstance = new Proxy(() => {}, {
553 + get: function(_, name) {
554 + return function() {
555 + return null;
556 + };
557 + },
558 + });
559 +
560 const container = document.createElement('div');
561 await utils.actAsync(() =>
562 ReactDOM.render(
@@ -567,6 +575,7 @@ describe('InspectedElementContext', () => {
575 map={mapShallow}
576 map_of_maps={mapOfMaps}
577 object_of_objects={objectOfObjects}
578 + proxy={proxyInstance}
579 react_element={<span />}
580 regexp={/abc/giu}
581 set={setShallow}
@@ -619,6 +628,7 @@ describe('InspectedElementContext', () => {
628 map,
629 map_of_maps,
630 object_of_objects,
631 + proxy,
632 react_element,
633 regexp,
634 set,
@@ -722,6 +732,12 @@ describe('InspectedElementContext', () => {
732 );
733 expect(object_of_objects.inner[meta.preview_short]).toBe('{…}');
734
735 + expect(proxy[meta.inspectable]).toBe(false);
736 + expect(proxy[meta.name]).toBe('function');
737 + expect(proxy[meta.type]).toBe('function');
738 + expect(proxy[meta.preview_long]).toBe('ƒ () {}');
739 + expect(proxy[meta.preview_short]).toBe('ƒ () {}');
740 +
741 expect(react_element[meta.inspectable]).toBe(false);
742 expect(react_element[meta.name]).toBe('span');
743 expect(react_element[meta.type]).toBe('react_element');
packages/react-devtools-shared/src/hydration.js
+4 -1
@@ -151,7 +151,10 @@ export function dehydrate(
151 inspectable: false,
152 preview_short: formatDataForPreview(data, false),
153 preview_long: formatDataForPreview(data, true),
154 - name: data.name || 'function',
154 + name:
155 + typeof data.name === 'function' || !data.name
156 + ? 'function'
157 + : data.name,
158 type,
159 };
160
packages/react-devtools-shared/src/utils.js
+3 -1
@@ -539,7 +539,9 @@ export function formatDataForPreview(
539 case 'html_element':
540 return `<${truncateForDisplay(data.tagName.toLowerCase())} />`;
541 case 'function':
542 - return truncateForDisplay(`ƒ ${data.name}() {}`);
542 + return truncateForDisplay(
543 + `ƒ ${typeof data.name === 'function' ? '' : data.name}() {}`,
544 + );
545 case 'string':
546 return `"${data}"`;
547 case 'bigint':