Skip to content

Commit d7f162c

Browse files
committed
Merge branch 'main' into bugfix/ios-pointer-hover-mounting
2 parents a491804 + 024d5da commit d7f162c

91 files changed

Lines changed: 895 additions & 690 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎flow-typed/environment/node.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ declare module 'buffer' {
213213

214214
declare function isAscii(input: Buffer | ArrayBuffer | $TypedArray): boolean;
215215

216-
declare function resolveObjectURL(id: string): Blob | void;
216+
declare function resolveObjectURL(id: string): globalThis.Blob | void;
217217

218218
declare var Buffer: Node$Buffer;
219219
declare var Blob: typeof globalThis.Blob;

‎packages/dev-middleware/src/__tests__/InspectorProxyCdpRewritingHacks-test.js‎

Lines changed: 64 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
withServerForEachTest,
2222
} from './ServerUtils';
2323
import {createHash} from 'node:crypto';
24+
import until from 'wait-for-expect';
2425

2526
// WebSocket is unreliable when using fake timers.
2627
jest.useRealTimers();
@@ -470,8 +471,8 @@ describe.each(['HTTP', 'HTTPS'])(
470471
}
471472
});
472473

473-
test('throws when attempting to pass a filesystem url', async () => {
474-
const {device, debugger_} = await createAndConnectTarget(
474+
test('forwards to the target for a url the proxy cannot fetch', async () => {
475+
const {device, debugger_, sessionId} = await createAndConnectTarget(
475476
serverRef,
476477
autoCleanup.signal,
477478
{
@@ -495,36 +496,81 @@ describe.each(['HTTP', 'HTTPS'])(
495496
hash: createHash('sha256').update('').digest('hex'),
496497
},
497498
});
498-
const response = await debugger_.sendAndGetResponse({
499+
const message = {
499500
id: 1,
500501
method: 'Debugger.getScriptSource',
501502
params: {
502503
scriptId: 'script1',
503504
},
505+
};
506+
await sendFromDebuggerToTarget(debugger_, device, 'page1', message, {
507+
sessionId,
504508
});
505-
expect(response.result).toEqual(
506-
expect.objectContaining({
507-
error: {
508-
message: expect.stringContaining(
509-
'Can\'t parse requested URL "__fixtures__/mock-source-file.txt"',
510-
),
511-
},
512-
}),
513-
);
514509

515-
// The device does not receive the getScriptSource request, since it
516-
// is handled by the proxy.
517-
expect(device.wrappedEventParsed).not.toBeCalledWith({
510+
// The proxy only fetches HTTP(S) urls itself, so rather than failing
511+
// it hands the request to the target.
512+
expect(device.wrappedEventParsed).toBeCalledWith({
518513
pageId: 'page1',
519-
wrappedEvent: expect.objectContaining({
520-
method: 'Debugger.getScriptSource',
521-
}),
514+
sessionId,
515+
wrappedEvent: message,
522516
});
523517
} finally {
524518
device.close();
525519
debugger_.close();
526520
}
527521
});
522+
523+
test('forwards to the target for a script with no url', async () => {
524+
const {device, debugger_, sessionId} = await createAndConnectTarget(
525+
serverRef,
526+
autoCleanup.signal,
527+
{
528+
app: 'bar-app',
529+
id: 'page1',
530+
title: 'bar-title',
531+
vm: 'bar-vm',
532+
},
533+
);
534+
535+
try {
536+
// Targets report an empty url for code they compiled from a debugger
537+
// expression, such as code typed into the DevTools console.
538+
await sendFromTargetToDebugger(device, debugger_, 'page1', {
539+
method: 'Debugger.scriptParsed',
540+
params: {
541+
scriptId: 'script1',
542+
url: '',
543+
},
544+
});
545+
const message = {
546+
id: 1,
547+
method: 'Debugger.getScriptSource',
548+
params: {
549+
scriptId: 'script1',
550+
},
551+
};
552+
await sendFromDebuggerToTarget(debugger_, device, 'page1', message, {
553+
sessionId,
554+
});
555+
expect(device.wrappedEventParsed).toBeCalledWith({
556+
pageId: 'page1',
557+
sessionId,
558+
wrappedEvent: message,
559+
});
560+
561+
// The target answers, and the proxy relays that back to the debugger.
562+
const response = {id: 1, result: {scriptSource: 'debugger;'}};
563+
device.sendWrappedEvent('page1', response);
564+
await until(() =>
565+
expect(debugger_.handle).toBeCalledWith(
566+
expect.objectContaining(response),
567+
),
568+
);
569+
} finally {
570+
device.close();
571+
debugger_.close();
572+
}
573+
});
528574
});
529575

530576
describe("disabled when target has 'nativeSourceCodeFetching' capability flag", () => {

‎packages/dev-middleware/src/inspector-proxy/Device.js‎

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,12 @@ export default class Device {
953953
case 'Debugger.setBreakpointByUrl':
954954
return this.#processDebuggerSetBreakpointByUrl(req, debuggerInfo);
955955
case 'Debugger.getScriptSource':
956+
if (!this.#hasFetchableScriptSource(req.params.scriptId)) {
957+
// Forward to the target, which is the only one that can still have
958+
// the source - for instance for code the user typed into the
959+
// DevTools console, which the target compiled without a URL.
960+
return req;
961+
}
956962
// Sends response to debugger via side-effect
957963
void this.#processDebuggerGetScriptSource(req, socket, debuggerInfo);
958964
return null;
@@ -1038,6 +1044,15 @@ export default class Device {
10381044
return processedReq;
10391045
}
10401046

1047+
/**
1048+
* Whether the proxy recorded an HTTP(S) source URL for a script, and can
1049+
* therefore serve its source itself by fetching that URL.
1050+
*/
1051+
#hasFetchableScriptSource(scriptId: string): boolean {
1052+
const pathToSource = this.#scriptIdToSourcePathMapping.get(scriptId);
1053+
return pathToSource != null && this.#tryParseHTTPURL(pathToSource) != null;
1054+
}
1055+
10411056
async #processDebuggerGetScriptSource(
10421057
req: CDPRequest<'Debugger.getScriptSource'>,
10431058
socket: WS,
@@ -1077,16 +1092,14 @@ export default class Device {
10771092
const pathToSource = this.#scriptIdToSourcePathMapping.get(
10781093
req.params.scriptId,
10791094
);
1095+
const httpURL =
1096+
pathToSource != null ? this.#tryParseHTTPURL(pathToSource) : null;
1097+
invariant(
1098+
httpURL != null,
1099+
'processDebuggerGetScriptSource called for non-fetchable script',
1100+
);
10801101

10811102
try {
1082-
const httpURL =
1083-
pathToSource == null ? null : this.#tryParseHTTPURL(pathToSource);
1084-
if (!httpURL) {
1085-
throw new Error(
1086-
`Can't parse requested URL ${pathToSource === undefined ? 'undefined' : JSON.stringify(pathToSource)}`,
1087-
);
1088-
}
1089-
10901103
const text = await this.#fetchText(httpURL);
10911104

10921105
sendSuccessResponse(text);

‎packages/react-native/Libraries/Components/Button.js‎

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,6 @@ type ButtonPropsCore = Readonly<{
5656
*/
5757
color?: ?ColorValue,
5858

59-
/**
60-
* TV preferred focus.
61-
*
62-
* @platform tv
63-
*
64-
* @default `false`
65-
* @deprecated Use `focusable` instead
66-
*/
67-
hasTVPreferredFocus?: ?boolean,
68-
6959
/**
7060
* Designates the next view to receive focus when the user navigates down. See
7161
* the [Android documentation][android:nextFocusDown].
@@ -219,7 +209,6 @@ const Button: component(
219209
onPress,
220210
touchSoundDisabled,
221211
title,
222-
hasTVPreferredFocus,
223212
nextFocusDown,
224213
nextFocusForward,
225214
nextFocusLeft,
@@ -290,7 +279,6 @@ const Button: component(
290279
accessibilityRole="button"
291280
accessibilityState={_accessibilityState}
292281
importantForAccessibility={_importantForAccessibility}
293-
hasTVPreferredFocus={hasTVPreferredFocus}
294282
nextFocusDown={nextFocusDown}
295283
nextFocusForward={nextFocusForward}
296284
nextFocusLeft={nextFocusLeft}

0 commit comments

Comments
 (0)