Skip to content

Commit 736819e

Browse files
committed
Handle opaque origin in props
1 parent 0aa0872 commit 736819e

File tree

2 files changed

+89
-74
lines changed

2 files changed

+89
-74
lines changed

packages/react-reconciler/src/__tests__/ReactPerformanceTrack-test.js

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -532,12 +532,8 @@ describe('ReactPerformanceTracks', () => {
532532
};
533533

534534
class Window {}
535-
536-
class OpaqueOriginHTMLIFrameElement {
537-
constructor(textContent) {
538-
this.textContent = textContent;
539-
}
540-
contentWindow = new Proxy(new Window(), {
535+
const createOpaqueOriginWindow = () => {
536+
return new Proxy(new Window(), {
541537
get(target, prop) {
542538
if (prop === Symbol.toStringTag) {
543539
return target[Symbol.toStringTag];
@@ -550,14 +546,24 @@ describe('ReactPerformanceTracks', () => {
550546
);
551547
},
552548
});
549+
};
550+
551+
class OpaqueOriginHTMLIFrameElement {
552+
constructor(textContent) {
553+
this.textContent = textContent;
554+
}
555+
contentWindow = createOpaqueOriginWindow();
553556
nodeType = 1;
554557
[Symbol.toStringTag] = 'HTMLIFrameElement';
555558
}
556559

557560
Scheduler.unstable_advanceTime(1);
558561
await act(() => {
559562
ReactNoop.render(
560-
<App container={new OpaqueOriginHTMLIFrameElement('foo')} />,
563+
<App
564+
container={new OpaqueOriginHTMLIFrameElement('foo')}
565+
contentWindow={createOpaqueOriginWindow()}
566+
/>,
561567
);
562568
});
563569

@@ -584,7 +590,10 @@ describe('ReactPerformanceTracks', () => {
584590

585591
await act(() => {
586592
ReactNoop.render(
587-
<App container={new OpaqueOriginHTMLIFrameElement('bar')} />,
593+
<App
594+
container={new OpaqueOriginHTMLIFrameElement('bar')}
595+
contentWindow={createOpaqueOriginWindow()}
596+
/>,
588597
);
589598
});
590599

@@ -605,6 +614,10 @@ describe('ReactPerformanceTracks', () => {
605614
['+   contentWindow', 'Window'],
606615
['+   nodeType', '1'],
607616
['+   textContent', '"bar"'],
617+
[
618+
'  contentWindow',
619+
'Referentially unequal but deeply equal objects. Consider memoization.',
620+
],
608621
],
609622
tooltipText: 'App',
610623
track: 'Components ⚛',

packages/shared/ReactPerformanceTrackProperties.js

Lines changed: 68 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ export function addObjectToProperties(
8282
}
8383
}
8484

85+
function readReactElementTypeof(value: Object): mixed {
86+
return '$$typeof' in value && hasOwnProperty.call(value, '$$typeof')
87+
? value.$$typeof
88+
: undefined;
89+
}
90+
8591
export function addValueToProperties(
8692
propertyName: string,
8793
value: mixed,
@@ -96,6 +102,65 @@ export function addValueToProperties(
96102
desc = 'null';
97103
break;
98104
} else {
105+
if (readReactElementTypeof(value) === REACT_ELEMENT_TYPE) {
106+
// JSX
107+
const typeName = getComponentNameFromType(value.type) || '\u2026';
108+
const key = value.key;
109+
const props: any = value.props;
110+
const propsKeys = Object.keys(props);
111+
const propsLength = propsKeys.length;
112+
if (key == null && propsLength === 0) {
113+
desc = '<' + typeName + ' />';
114+
break;
115+
}
116+
if (
117+
indent < 3 ||
118+
(propsLength === 1 && propsKeys[0] === 'children' && key == null)
119+
) {
120+
desc = '<' + typeName + ' \u2026 />';
121+
break;
122+
}
123+
properties.push([
124+
prefix + '\xa0\xa0'.repeat(indent) + propertyName,
125+
'<' + typeName,
126+
]);
127+
if (key !== null) {
128+
addValueToProperties('key', key, properties, indent + 1, prefix);
129+
}
130+
let hasChildren = false;
131+
let addedProperties = 0;
132+
for (const propKey in props) {
133+
addedProperties++;
134+
if (propKey === 'children') {
135+
if (
136+
props.children != null &&
137+
(!isArray(props.children) || props.children.length > 0)
138+
) {
139+
hasChildren = true;
140+
}
141+
} else if (
142+
hasOwnProperty.call(props, propKey) &&
143+
propKey[0] !== '_'
144+
) {
145+
addValueToProperties(
146+
propKey,
147+
props[propKey],
148+
properties,
149+
indent + 1,
150+
prefix,
151+
);
152+
}
153+
154+
if (addedProperties >= OBJECT_WIDTH_LIMIT) {
155+
break;
156+
}
157+
}
158+
properties.push([
159+
'',
160+
hasChildren ? '>\u2026</' + typeName + '>' : '/>',
161+
]);
162+
return;
163+
}
99164
// $FlowFixMe[method-unbinding]
100165
const objectToString = Object.prototype.toString.call(value);
101166
let objectName = objectToString.slice(8, objectToString.length - 1);
@@ -179,70 +244,6 @@ export function addValueToProperties(
179244
return;
180245
}
181246
if (objectName === 'Object') {
182-
if (
183-
'$$typeof' in value &&
184-
hasOwnProperty.call(value, '$$typeof') &&
185-
value.$$typeof === REACT_ELEMENT_TYPE
186-
) {
187-
// JSX
188-
const typeName = getComponentNameFromType(value.type) || '\u2026';
189-
const key = value.key;
190-
const props: any = value.props;
191-
const propsKeys = Object.keys(props);
192-
const propsLength = propsKeys.length;
193-
if (key == null && propsLength === 0) {
194-
desc = '<' + typeName + ' />';
195-
break;
196-
}
197-
if (
198-
indent < 3 ||
199-
(propsLength === 1 && propsKeys[0] === 'children' && key == null)
200-
) {
201-
desc = '<' + typeName + ' \u2026 />';
202-
break;
203-
}
204-
properties.push([
205-
prefix + '\xa0\xa0'.repeat(indent) + propertyName,
206-
'<' + typeName,
207-
]);
208-
if (key !== null) {
209-
addValueToProperties('key', key, properties, indent + 1, prefix);
210-
}
211-
let hasChildren = false;
212-
let addedProperties = 0;
213-
for (const propKey in props) {
214-
addedProperties++;
215-
if (propKey === 'children') {
216-
if (
217-
props.children != null &&
218-
(!isArray(props.children) || props.children.length > 0)
219-
) {
220-
hasChildren = true;
221-
}
222-
} else if (
223-
hasOwnProperty.call(props, propKey) &&
224-
propKey[0] !== '_'
225-
) {
226-
addValueToProperties(
227-
propKey,
228-
props[propKey],
229-
properties,
230-
indent + 1,
231-
prefix,
232-
);
233-
}
234-
235-
if (addedProperties >= OBJECT_WIDTH_LIMIT) {
236-
break;
237-
}
238-
}
239-
properties.push([
240-
'',
241-
hasChildren ? '>\u2026</' + typeName + '>' : '/>',
242-
]);
243-
return;
244-
}
245-
246247
const proto: any = Object.getPrototypeOf(value);
247248
if (proto && typeof proto.constructor === 'function') {
248249
objectName = proto.constructor.name;
@@ -357,9 +358,10 @@ export function addObjectDiffToProperties(
357358
typeof nextValue === 'object' &&
358359
prevValue !== null &&
359360
nextValue !== null &&
360-
prevValue.$$typeof === nextValue.$$typeof
361+
readReactElementTypeof(prevValue) ===
362+
readReactElementTypeof(nextValue)
361363
) {
362-
if (nextValue.$$typeof === REACT_ELEMENT_TYPE) {
364+
if (readReactElementTypeof(nextValue) === REACT_ELEMENT_TYPE) {
363365
if (
364366
prevValue.type === nextValue.type &&
365367
prevValue.key === nextValue.key

0 commit comments

Comments
 (0)