mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Compare commits
72
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dbd9952e0a | ||
|
|
4e10c8b602 | ||
|
|
52322fbd0e | ||
|
|
2f04dfe795 | ||
|
|
5a0df6d0bf | ||
|
|
6a24df7eaa | ||
|
|
2a344a9580 | ||
|
|
d56fb57502 | ||
|
|
ddeb5081b8 | ||
|
|
dfef912c89 | ||
|
|
dabb3dff00 | ||
|
|
4f26100d11 | ||
|
|
3ee652a3d3 | ||
|
|
166984e1e2 | ||
|
|
f22a5ef4ed | ||
|
|
e61606a0a1 | ||
|
|
83f1e7d7d0 | ||
|
|
ba7fca8cbd | ||
|
|
cffeb603de | ||
|
|
d334f4d77e | ||
|
|
23f62acd83 | ||
|
|
1099c0ccf7 | ||
|
|
e8fdd3c5ac | ||
|
|
a22e29c192 | ||
|
|
6d300b6fb8 | ||
|
|
e490b1ed9f | ||
|
|
1a04e5db62 | ||
|
|
efc475c3f9 | ||
|
|
947734f235 | ||
|
|
a4210ef245 | ||
|
|
d129e9a1b5 | ||
|
|
b958fe13f9 | ||
|
|
ec9e1718aa | ||
|
|
c4714e81d8 | ||
|
|
b8fa7c80ff | ||
|
|
4126ce844d | ||
|
|
95021db72a | ||
|
|
83eb95e72a | ||
|
|
3b44182c1d | ||
|
|
f4fd248d53 | ||
|
|
c41ab475b1 | ||
|
|
1dd89df561 | ||
|
|
a0f11acc34 | ||
|
|
507934f7d9 | ||
|
|
e6396039c7 | ||
|
|
fdb5721ead | ||
|
|
123b25226a | ||
|
|
6259ee91bd | ||
|
|
b4aab7fb52 | ||
|
|
064887675b | ||
|
|
2a10923863 | ||
|
|
bf14325d30 | ||
|
|
2085076449 | ||
|
|
d67d91407e | ||
|
|
4d67a27c37 | ||
|
|
b0db081a76 | ||
|
|
959eafca33 | ||
|
|
bc62261dfa | ||
|
|
4af4311fc8 | ||
|
|
e78ea9f6d9 | ||
|
|
33d175f51b | ||
|
|
f60fbc15ae | ||
|
|
28facc2824 | ||
|
|
cf5d04d3e1 | ||
|
|
1e3c583d73 | ||
|
|
026fd325ab | ||
|
|
b395208303 | ||
|
|
8041e410e3 | ||
|
|
13ab63b60a | ||
|
|
965d84314a | ||
|
|
b93b378fa0 | ||
|
|
f55759e633 |
@@ -22,7 +22,7 @@ runs:
|
||||
- name: Restore Cached Artifacts
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
key: v4-hermes-artifacts-${{ inputs.flavor }}-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}
|
||||
key: v4-hermes-artifacts-${{ inputs.flavor }}-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}-${{ hashFiles('./packages/react-native/sdks/hermes/utils/build-apple-frameworks.sh') }}
|
||||
path: |
|
||||
/tmp/hermes/osx-bin/${{ inputs.flavor }}
|
||||
/tmp/hermes/dSYM/${{ inputs.flavor }}
|
||||
@@ -200,7 +200,7 @@ runs:
|
||||
uses: actions/cache/save@v4
|
||||
if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, '-stable') }} # To avoid that the cache explode.
|
||||
with:
|
||||
key: v4-hermes-artifacts-${{ inputs.flavor }}-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}
|
||||
key: v4-hermes-artifacts-${{ inputs.flavor }}-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}-${{ hashFiles('./packages/react-native/sdks/hermes/utils/build-apple-frameworks.sh') }}
|
||||
path: |
|
||||
/tmp/hermes/osx-bin/${{ inputs.flavor }}
|
||||
/tmp/hermes/dSYM/${{ inputs.flavor }}
|
||||
|
||||
+7
-11
@@ -32,8 +32,7 @@
|
||||
"test-typescript": "dtslint packages/react-native/types",
|
||||
"test": "jest",
|
||||
"trigger-react-native-release": "node ./scripts/releases-local/trigger-react-native-release.js",
|
||||
"update-lock": "npx yarn-deduplicate",
|
||||
"postinstall": "cd packages/react-native-codegen && yarn build"
|
||||
"update-lock": "npx yarn-deduplicate"
|
||||
},
|
||||
"workspaces": [
|
||||
"packages/*",
|
||||
@@ -50,8 +49,8 @@
|
||||
"@definitelytyped/dtslint": "^0.0.127",
|
||||
"@jest/create-cache-key-function": "^29.6.3",
|
||||
"@pkgjs/parseargs": "^0.11.0",
|
||||
"@react-native/metro-babel-transformer": "0.76.0-main",
|
||||
"@react-native/metro-config": "0.76.0-main",
|
||||
"@react-native/metro-babel-transformer": "0.76.0-rc.3",
|
||||
"@react-native/metro-config": "0.76.0-rc.3",
|
||||
"@tsconfig/node18": "1.0.1",
|
||||
"@types/react": "^18.2.6",
|
||||
"@typescript-eslint/parser": "^7.1.1",
|
||||
@@ -87,24 +86,21 @@
|
||||
"jest": "^29.6.3",
|
||||
"jest-junit": "^10.0.0",
|
||||
"jscodeshift": "^0.14.0",
|
||||
"metro-babel-register": "^0.80.10",
|
||||
"metro-memory-fs": "^0.80.10",
|
||||
"metro-babel-register": "^0.81.0-alpha.2",
|
||||
"metro-memory-fs": "^0.81.0-alpha.2",
|
||||
"micromatch": "^4.0.4",
|
||||
"mkdirp": "^0.5.1",
|
||||
"node-fetch": "^2.2.0",
|
||||
"nullthrows": "^1.1.1",
|
||||
"prettier": "2.8.8",
|
||||
"prettier-plugin-hermes-parser": "0.23.1",
|
||||
"react": "19.0.0-rc-fb9a90fa48-20240614",
|
||||
"react-test-renderer": "19.0.0-rc-fb9a90fa48-20240614",
|
||||
"react": "18.3.1",
|
||||
"react-test-renderer": "18.3.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"shelljs": "^0.8.5",
|
||||
"signedsource": "^1.0.0",
|
||||
"supports-color": "^7.1.0",
|
||||
"typescript": "5.0.4",
|
||||
"ws": "^6.2.3"
|
||||
},
|
||||
"resolutions": {
|
||||
"react-is": "19.0.0-rc-fb9a90fa48-20240614"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/assets-registry",
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"description": "Asset support code for React Native.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/babel-plugin-codegen",
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"description": "Babel plugin to generate native module and view manager code for React Native.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
@@ -25,7 +25,7 @@
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@react-native/codegen": "0.76.0-main"
|
||||
"@react-native/codegen": "0.76.0-rc.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/community-cli-plugin",
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"description": "Core CLI commands for React Native",
|
||||
"keywords": [
|
||||
"react-native",
|
||||
@@ -22,18 +22,19 @@
|
||||
"dist"
|
||||
],
|
||||
"dependencies": {
|
||||
"@react-native/dev-middleware": "0.76.0-main",
|
||||
"@react-native/metro-babel-transformer": "0.76.0-main",
|
||||
"@react-native/dev-middleware": "0.76.0-rc.3",
|
||||
"@react-native/metro-babel-transformer": "0.76.0-rc.3",
|
||||
"chalk": "^4.0.0",
|
||||
"execa": "^5.1.1",
|
||||
"metro": "^0.80.10",
|
||||
"metro-config": "^0.80.10",
|
||||
"metro-core": "^0.80.10",
|
||||
"invariant": "^2.2.4",
|
||||
"metro": "^0.81.0-alpha.2",
|
||||
"metro-config": "^0.81.0-alpha.2",
|
||||
"metro-core": "^0.81.0-alpha.2",
|
||||
"node-fetch": "^2.2.0",
|
||||
"readline": "^1.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"metro-resolver": "^0.80.10"
|
||||
"metro-resolver": "^0.81.0-alpha.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@react-native-community/cli-server-api": "*"
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict-local
|
||||
* @format
|
||||
* @oncall react_native
|
||||
*/
|
||||
|
||||
import type TerminalReporter from 'metro/src/lib/TerminalReporter';
|
||||
|
||||
import chalk from 'chalk';
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
type PageDescription = $ReadOnly<{
|
||||
id: string,
|
||||
title: string,
|
||||
description: string,
|
||||
deviceName: string,
|
||||
...
|
||||
}>;
|
||||
|
||||
export default class OpenDebuggerKeyboardHandler {
|
||||
#devServerUrl: string;
|
||||
#reporter: TerminalReporter;
|
||||
#targetsShownForSelection: ?$ReadOnlyArray<PageDescription> = null;
|
||||
|
||||
constructor({
|
||||
devServerUrl,
|
||||
reporter,
|
||||
}: {
|
||||
devServerUrl: string,
|
||||
reporter: TerminalReporter,
|
||||
}) {
|
||||
this.#devServerUrl = devServerUrl;
|
||||
this.#reporter = reporter;
|
||||
}
|
||||
|
||||
async #tryOpenDebuggerForTarget(target: PageDescription): Promise<void> {
|
||||
this.#targetsShownForSelection = null;
|
||||
this.#clearTerminalMenu();
|
||||
|
||||
try {
|
||||
await fetch(
|
||||
new URL(
|
||||
'/open-debugger?target=' + encodeURIComponent(target.id),
|
||||
this.#devServerUrl,
|
||||
).href,
|
||||
{method: 'POST'},
|
||||
);
|
||||
} catch (e) {
|
||||
this.#log(
|
||||
'error',
|
||||
'Failed to open debugger for %s on %s debug targets: %s',
|
||||
target.description,
|
||||
target.deviceName,
|
||||
e.message,
|
||||
);
|
||||
this.#clearTerminalMenu();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used in response to 'j' to debug - fetch the available debug targets and:
|
||||
* - If no targets, warn
|
||||
* - If one target, open it
|
||||
* - If more, show a list. The keyboard listener should run subsequent key
|
||||
* presses through maybeHandleTargetSelection, which will launch the
|
||||
* debugger if a match is made.
|
||||
*/
|
||||
async handleOpenDebugger(): Promise<void> {
|
||||
this.#setTerminalMenu('Fetching available debugging targets...');
|
||||
this.#targetsShownForSelection = null;
|
||||
|
||||
try {
|
||||
const res = await fetch(this.#devServerUrl + '/json/list', {
|
||||
method: 'POST',
|
||||
});
|
||||
|
||||
if (res.status !== 200) {
|
||||
throw new Error(`Unexpected status code: ${res.status}`);
|
||||
}
|
||||
const targets = (await res.json()) as $ReadOnlyArray<PageDescription>;
|
||||
if (!Array.isArray(targets)) {
|
||||
throw new Error('Expected array.');
|
||||
}
|
||||
|
||||
if (targets.length === 0) {
|
||||
this.#log('warn', 'No connected targets');
|
||||
this.#clearTerminalMenu();
|
||||
} else if (targets.length === 1) {
|
||||
const target = targets[0];
|
||||
// eslint-disable-next-line no-void
|
||||
void this.#tryOpenDebuggerForTarget(target);
|
||||
} else {
|
||||
this.#targetsShownForSelection = targets;
|
||||
|
||||
if (targets.length > 9) {
|
||||
this.#log(
|
||||
'warn',
|
||||
'10 or more debug targets available, showing the first 9.',
|
||||
);
|
||||
}
|
||||
|
||||
this.#setTerminalMenu(
|
||||
`Multiple debug targets available, please select:\n ${targets
|
||||
.slice(0, 9)
|
||||
.map(
|
||||
({description, deviceName}, i) =>
|
||||
` ${chalk.white.inverse(` ${i + 1} `)} - "${description}" on "${deviceName}"`,
|
||||
)
|
||||
.join('\n ')}`,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
this.#log('error', `Failed to fetch debug targets: ${e.message}`);
|
||||
this.#clearTerminalMenu();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle key presses that correspond to a valid selection from a visible
|
||||
* selection list.
|
||||
*
|
||||
* @return true if we've handled the key as a target selection, false if the
|
||||
* caller should handle the key.
|
||||
*/
|
||||
maybeHandleTargetSelection(keyName: string): boolean {
|
||||
if (keyName >= '1' && keyName <= '9') {
|
||||
const targetIndex = Number(keyName) - 1;
|
||||
if (
|
||||
this.#targetsShownForSelection != null &&
|
||||
targetIndex < this.#targetsShownForSelection.length
|
||||
) {
|
||||
const target = this.#targetsShownForSelection[targetIndex];
|
||||
// eslint-disable-next-line no-void
|
||||
void this.#tryOpenDebuggerForTarget(target);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismiss any target selection UI, if shown.
|
||||
*/
|
||||
dismiss() {
|
||||
this.#clearTerminalMenu();
|
||||
this.#targetsShownForSelection = null;
|
||||
}
|
||||
|
||||
#log(level: 'info' | 'warn' | 'error', ...data: Array<mixed>): void {
|
||||
this.#reporter.update({
|
||||
type: 'unstable_server_log',
|
||||
level,
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
#setTerminalMenu(message: string) {
|
||||
this.#reporter.update({
|
||||
type: 'unstable_server_menu_updated',
|
||||
message,
|
||||
});
|
||||
}
|
||||
|
||||
#clearTerminalMenu() {
|
||||
this.#reporter.update({
|
||||
type: 'unstable_server_menu_cleared',
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -10,20 +10,44 @@
|
||||
*/
|
||||
|
||||
import type {Config} from '@react-native-community/cli-types';
|
||||
import type TerminalReporter from 'metro/src/lib/TerminalReporter';
|
||||
|
||||
import {KeyPressHandler} from '../../utils/KeyPressHandler';
|
||||
import {logger} from '../../utils/logger';
|
||||
import OpenDebuggerKeyboardHandler from './OpenDebuggerKeyboardHandler';
|
||||
import chalk from 'chalk';
|
||||
import execa from 'execa';
|
||||
import fetch from 'node-fetch';
|
||||
import invariant from 'invariant';
|
||||
import readline from 'readline';
|
||||
import {ReadStream} from 'tty';
|
||||
|
||||
const CTRL_C = '\u0003';
|
||||
const CTRL_D = '\u0004';
|
||||
const RELOAD_TIMEOUT = 500;
|
||||
|
||||
const throttle = (callback: () => void, timeout: number) => {
|
||||
let previousCallTimestamp = 0;
|
||||
return () => {
|
||||
const currentCallTimestamp = new Date().getTime();
|
||||
if (currentCallTimestamp - previousCallTimestamp > timeout) {
|
||||
previousCallTimestamp = currentCallTimestamp;
|
||||
callback();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
type KeyEvent = {
|
||||
sequence: string,
|
||||
name: string,
|
||||
ctrl: boolean,
|
||||
meta: boolean,
|
||||
shift: boolean,
|
||||
};
|
||||
|
||||
export default function attachKeyHandlers({
|
||||
cliConfig,
|
||||
devServerUrl,
|
||||
messageSocket,
|
||||
reporter,
|
||||
}: {
|
||||
cliConfig: Config,
|
||||
devServerUrl: string,
|
||||
@@ -31,21 +55,40 @@ export default function attachKeyHandlers({
|
||||
broadcast: (type: string, params?: Record<string, mixed> | null) => void,
|
||||
...
|
||||
}>,
|
||||
reporter: TerminalReporter,
|
||||
}) {
|
||||
if (process.stdin.isTTY !== true) {
|
||||
logger.debug('Interactive mode is not supported in this environment');
|
||||
return;
|
||||
}
|
||||
|
||||
readline.emitKeypressEvents(process.stdin);
|
||||
setRawMode(true);
|
||||
|
||||
const execaOptions = {
|
||||
env: {FORCE_COLOR: chalk.supportsColor ? 'true' : 'false'},
|
||||
};
|
||||
|
||||
const onPress = async (key: string) => {
|
||||
switch (key.toLowerCase()) {
|
||||
const reload = throttle(() => {
|
||||
logger.info('Reloading connected app(s)...');
|
||||
messageSocket.broadcast('reload', null);
|
||||
}, RELOAD_TIMEOUT);
|
||||
|
||||
const openDebuggerKeyboardHandler = new OpenDebuggerKeyboardHandler({
|
||||
reporter,
|
||||
devServerUrl,
|
||||
});
|
||||
|
||||
process.stdin.on('keypress', (str: string, key: KeyEvent) => {
|
||||
logger.debug(`Key pressed: ${key.sequence}`);
|
||||
|
||||
if (openDebuggerKeyboardHandler.maybeHandleTargetSelection(key.name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (key.sequence) {
|
||||
case 'r':
|
||||
logger.info('Reloading connected app(s)...');
|
||||
messageSocket.broadcast('reload', null);
|
||||
reload();
|
||||
break;
|
||||
case 'd':
|
||||
logger.info('Opening Dev Menu...');
|
||||
@@ -76,21 +119,19 @@ export default function attachKeyHandlers({
|
||||
).stdout?.pipe(process.stdout);
|
||||
break;
|
||||
case 'j':
|
||||
// TODO(T192878199): Add multi-target selection
|
||||
await fetch(devServerUrl + '/open-debugger', {method: 'POST'});
|
||||
// eslint-disable-next-line no-void
|
||||
void openDebuggerKeyboardHandler.handleOpenDebugger();
|
||||
break;
|
||||
case CTRL_C:
|
||||
case CTRL_D:
|
||||
openDebuggerKeyboardHandler.dismiss();
|
||||
logger.info('Stopping server');
|
||||
keyPressHandler.stopInterceptingKeyStrokes();
|
||||
setRawMode(false);
|
||||
process.stdin.pause();
|
||||
process.emit('SIGINT');
|
||||
process.exit();
|
||||
}
|
||||
};
|
||||
|
||||
const keyPressHandler = new KeyPressHandler(onPress);
|
||||
keyPressHandler.createInteractionListener();
|
||||
keyPressHandler.startInterceptingKeyStrokes();
|
||||
});
|
||||
|
||||
logger.log(
|
||||
[
|
||||
@@ -104,3 +145,11 @@ export default function attachKeyHandlers({
|
||||
].join('\n'),
|
||||
);
|
||||
}
|
||||
|
||||
function setRawMode(enable: boolean) {
|
||||
invariant(
|
||||
process.stdin instanceof ReadStream,
|
||||
'process.stdin must be a readable stream to modify raw mode',
|
||||
);
|
||||
process.stdin.setRawMode(enable);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import type {Reporter} from 'metro/src/lib/reporting';
|
||||
import type {TerminalReportableEvent} from 'metro/src/lib/TerminalReporter';
|
||||
import typeof TerminalReporter from 'metro/src/lib/TerminalReporter';
|
||||
|
||||
import createDevMiddlewareLogger from '../../utils/createDevMiddlewareLogger';
|
||||
import isDevServerRunning from '../../utils/isDevServerRunning';
|
||||
import loadMetroConfig from '../../utils/loadMetroConfig';
|
||||
import {logger} from '../../utils/logger';
|
||||
@@ -98,6 +99,11 @@ async function runServer(
|
||||
);
|
||||
}
|
||||
|
||||
let reportEvent: (event: TerminalReportableEvent) => void;
|
||||
const terminal = new Terminal(process.stdout);
|
||||
const ReporterImpl = getReporterImpl(args.customLogReporterPath);
|
||||
const terminalReporter = new ReporterImpl(terminal);
|
||||
|
||||
const {
|
||||
middleware: communityMiddleware,
|
||||
websocketEndpoints: communityWebsocketEndpoints,
|
||||
@@ -111,13 +117,9 @@ async function runServer(
|
||||
const {middleware, websocketEndpoints} = createDevMiddleware({
|
||||
projectRoot,
|
||||
serverBaseUrl: devServerUrl,
|
||||
logger,
|
||||
logger: createDevMiddlewareLogger(terminalReporter),
|
||||
});
|
||||
|
||||
let reportEvent: (event: TerminalReportableEvent) => void;
|
||||
const terminal = new Terminal(process.stdout);
|
||||
const ReporterImpl = getReporterImpl(args.customLogReporterPath);
|
||||
const terminalReporter = new ReporterImpl(terminal);
|
||||
const reporter: Reporter = {
|
||||
update(event: TerminalReportableEvent) {
|
||||
terminalReporter.update(event);
|
||||
@@ -130,6 +132,7 @@ async function runServer(
|
||||
cliConfig: ctx,
|
||||
devServerUrl,
|
||||
messageSocket: messageSocketEndpoint,
|
||||
reporter: terminalReporter,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict-local
|
||||
* @format
|
||||
* @oncall react_native
|
||||
*/
|
||||
|
||||
import {CLIError} from './errors';
|
||||
import {logger} from './logger';
|
||||
|
||||
const CTRL_C = '\u0003';
|
||||
|
||||
/** An abstract key stroke interceptor. */
|
||||
export class KeyPressHandler {
|
||||
_isInterceptingKeyStrokes = false;
|
||||
_isHandlingKeyPress = false;
|
||||
_onPress: (key: string) => Promise<void>;
|
||||
|
||||
constructor(onPress: (key: string) => Promise<void>) {
|
||||
this._onPress = onPress;
|
||||
}
|
||||
|
||||
/** Start observing interaction pause listeners. */
|
||||
createInteractionListener(): ({pause: boolean, ...}) => void {
|
||||
// Support observing prompts.
|
||||
let wasIntercepting = false;
|
||||
|
||||
const listener = ({pause}: {pause: boolean, ...}) => {
|
||||
if (pause) {
|
||||
// Track if we were already intercepting key strokes before pausing, so we can
|
||||
// resume after pausing.
|
||||
wasIntercepting = this._isInterceptingKeyStrokes;
|
||||
this.stopInterceptingKeyStrokes();
|
||||
} else if (wasIntercepting) {
|
||||
// Only start if we were previously intercepting.
|
||||
this.startInterceptingKeyStrokes();
|
||||
}
|
||||
};
|
||||
|
||||
return listener;
|
||||
}
|
||||
|
||||
_handleKeypress = async (key: string): Promise<CLIError | void> => {
|
||||
// Prevent sending another event until the previous event has finished.
|
||||
if (this._isHandlingKeyPress && key !== CTRL_C) {
|
||||
return;
|
||||
}
|
||||
this._isHandlingKeyPress = true;
|
||||
try {
|
||||
logger.debug(`Key pressed: ${key}`);
|
||||
await this._onPress(key);
|
||||
} catch (error) {
|
||||
return new CLIError('There was an error with the key press handler.');
|
||||
} finally {
|
||||
this._isHandlingKeyPress = false;
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
/** Start intercepting all key strokes and passing them to the input `onPress` method. */
|
||||
startInterceptingKeyStrokes() {
|
||||
if (this._isInterceptingKeyStrokes) {
|
||||
return;
|
||||
}
|
||||
this._isInterceptingKeyStrokes = true;
|
||||
const {stdin} = process;
|
||||
// $FlowFixMe[prop-missing]
|
||||
stdin.setRawMode(true);
|
||||
stdin.resume();
|
||||
stdin.setEncoding('utf8');
|
||||
stdin.on('data', this._handleKeypress);
|
||||
}
|
||||
|
||||
/** Stop intercepting all key strokes. */
|
||||
stopInterceptingKeyStrokes() {
|
||||
if (!this._isInterceptingKeyStrokes) {
|
||||
return;
|
||||
}
|
||||
this._isInterceptingKeyStrokes = false;
|
||||
const {stdin} = process;
|
||||
stdin.removeListener('data', this._handleKeypress);
|
||||
// $FlowFixMe[prop-missing]
|
||||
stdin.setRawMode(false);
|
||||
stdin.resume();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict-local
|
||||
* @format
|
||||
* @oncall react_native
|
||||
*/
|
||||
|
||||
import type TerminalReporter from 'metro/src/lib/TerminalReporter';
|
||||
|
||||
type LoggerFn = (...message: $ReadOnlyArray<string>) => void;
|
||||
|
||||
/**
|
||||
* Create a dev-middleware logger object that will emit logs via Metro's
|
||||
* terminal reporter.
|
||||
*/
|
||||
export default function createDevMiddlewareLogger(
|
||||
reporter: TerminalReporter,
|
||||
): $ReadOnly<{
|
||||
info: LoggerFn,
|
||||
error: LoggerFn,
|
||||
warn: LoggerFn,
|
||||
}> {
|
||||
return {
|
||||
info: makeLogger(reporter, 'info'),
|
||||
warn: makeLogger(reporter, 'warn'),
|
||||
error: makeLogger(reporter, 'error'),
|
||||
};
|
||||
}
|
||||
|
||||
function makeLogger(
|
||||
reporter: TerminalReporter,
|
||||
level: 'info' | 'warn' | 'error',
|
||||
): LoggerFn {
|
||||
return (...data: Array<mixed>) =>
|
||||
reporter.update({
|
||||
type: 'unstable_server_log',
|
||||
level,
|
||||
data,
|
||||
});
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/core-cli-utils",
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"description": "React Native CLI library for Frameworks to build on",
|
||||
"license": "MIT",
|
||||
"main": "./src/index.flow.js",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@generated SignedSource<<d156d11a5d3cc2a10238c2f014ada9f9>>
|
||||
Git revision: a556d261a5e2131864f4e38ded62d8f90e81c39a
|
||||
@generated SignedSource<<85fb986aee1b601b649481b64d2b5dc8>>
|
||||
Git revision: e8c79432972029c625c91d16967b07fe61f04a61
|
||||
Built with --nohooks: false
|
||||
Is local checkout: false
|
||||
Remote URL: https://github.com/facebookexperimental/rn-chrome-devtools-frontend
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import*as e from"../../core/i18n/i18n.js";import*as o from"../../ui/legacy/legacy.js";const t={title:"⚛️ Components",command:"Show React DevTools Components panel"},n=e.i18n.registerUIStrings("panels/react_devtools/react_devtools_components-meta.ts",t),a=e.i18n.getLazilyComputedLocalizedString.bind(void 0,n);let i;o.ViewManager.registerViewExtension({location:"panel",id:"react-devtools-components",title:a(t.title),commandPrompt:a(t.command),persistence:"permanent",order:1e3,loadView:async()=>new((await async function(){return i||(i=await import("./react_devtools.js")),i}()).ReactDevToolsComponentsView.ReactDevToolsComponentsViewImpl)});
|
||||
import*as e from"../../core/i18n/i18n.js";import*as o from"../../ui/legacy/legacy.js";const t={title:"Components ⚛",command:"Show React DevTools Components panel"},n=e.i18n.registerUIStrings("panels/react_devtools/react_devtools_components-meta.ts",t),a=e.i18n.getLazilyComputedLocalizedString.bind(void 0,n);let i;o.ViewManager.registerViewExtension({location:"panel",id:"react-devtools-components",title:a(t.title),commandPrompt:a(t.command),persistence:"permanent",order:1e3,loadView:async()=>new((await async function(){return i||(i=await import("./react_devtools.js")),i}()).ReactDevToolsComponentsView.ReactDevToolsComponentsViewImpl)});
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import*as e from"../../core/i18n/i18n.js";import*as o from"../../ui/legacy/legacy.js";const t={title:"⚛️ Profiler",command:"Show React DevTools Profiler panel"},i=e.i18n.registerUIStrings("panels/react_devtools/react_devtools_profiler-meta.ts",t),r=e.i18n.getLazilyComputedLocalizedString.bind(void 0,i);let a;o.ViewManager.registerViewExtension({location:"panel",id:"react-devtools-profiler",title:r(t.title),commandPrompt:r(t.command),persistence:"permanent",order:1e3,loadView:async()=>new((await async function(){return a||(a=await import("./react_devtools.js")),a}()).ReactDevToolsProfilerView.ReactDevToolsProfilerViewImpl)});
|
||||
import*as e from"../../core/i18n/i18n.js";import*as o from"../../ui/legacy/legacy.js";const t={title:"Profiler ⚛",command:"Show React DevTools Profiler panel"},i=e.i18n.registerUIStrings("panels/react_devtools/react_devtools_profiler-meta.ts",t),r=e.i18n.getLazilyComputedLocalizedString.bind(void 0,i);let a;o.ViewManager.registerViewExtension({location:"panel",id:"react-devtools-profiler",title:r(t.title),commandPrompt:r(t.command),persistence:"permanent",order:1e3,loadView:async()=>new((await async function(){return a||(a=await import("./react_devtools.js")),a}()).ReactDevToolsProfilerView.ReactDevToolsProfilerViewImpl)});
|
||||
|
||||
+18
-18
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/debugger-frontend",
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"description": "Debugger frontend for React Native based on Chrome DevTools",
|
||||
"keywords": [
|
||||
"react-native",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/dev-middleware",
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"description": "Dev server middleware for React Native",
|
||||
"keywords": [
|
||||
"react-native",
|
||||
@@ -23,7 +23,7 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"@isaacs/ttlcache": "^1.4.1",
|
||||
"@react-native/debugger-frontend": "0.76.0-main",
|
||||
"@react-native/debugger-frontend": "0.76.0-rc.3",
|
||||
"chrome-launcher": "^0.15.2",
|
||||
"chromium-edge-launcher": "^0.2.0",
|
||||
"connect": "^3.6.5",
|
||||
|
||||
@@ -39,7 +39,7 @@ module.exports = {
|
||||
overrides: [
|
||||
{
|
||||
files: ['*.js'],
|
||||
parser: '@babel/eslint-parser',
|
||||
parser: 'hermes-eslint',
|
||||
plugins: ['ft-flow'],
|
||||
rules: {
|
||||
// Flow Plugin
|
||||
@@ -51,7 +51,7 @@ module.exports = {
|
||||
},
|
||||
{
|
||||
files: ['*.jsx'],
|
||||
parser: '@babel/eslint-parser',
|
||||
parser: 'hermes-eslint',
|
||||
},
|
||||
{
|
||||
files: ['*.ts', '*.tsx'],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/eslint-config",
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"description": "ESLint config for React Native",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
@@ -22,7 +22,7 @@
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@babel/eslint-parser": "^7.25.1",
|
||||
"@react-native/eslint-plugin": "0.76.0-main",
|
||||
"@react-native/eslint-plugin": "0.76.0-rc.3",
|
||||
"@typescript-eslint/eslint-plugin": "^7.1.1",
|
||||
"@typescript-eslint/parser": "^7.1.1",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
@@ -31,7 +31,8 @@
|
||||
"eslint-plugin-jest": "^27.9.0",
|
||||
"eslint-plugin-react": "^7.30.1",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-react-native": "^4.0.0"
|
||||
"eslint-plugin-react-native": "^4.0.0",
|
||||
"hermes-eslint": "^0.23.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": ">=8",
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
const ESLintTester = require('eslint').RuleTester;
|
||||
|
||||
ESLintTester.setDefaultConfig({
|
||||
parser: require.resolve('@babel/eslint-parser'),
|
||||
parser: require.resolve('hermes-eslint'),
|
||||
parserOptions: {
|
||||
requireConfigFile: false,
|
||||
ecmaVersion: 6,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/eslint-plugin",
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"description": "ESLint rules for @react-native/eslint-config",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
@@ -16,8 +16,12 @@
|
||||
"react-native"
|
||||
],
|
||||
"bugs": "https://github.com/facebook/react-native/issues",
|
||||
"main": "index.js",
|
||||
"devDependencies": {
|
||||
"babel-plugin-syntax-hermes-parser": "^0.23.1",
|
||||
"hermes-eslint": "^0.23.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"main": "index.js"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
const ESLintTester = require('eslint').RuleTester;
|
||||
|
||||
ESLintTester.setDefaultConfig({
|
||||
parser: require.resolve('@babel/eslint-parser'),
|
||||
parser: require.resolve('hermes-eslint'),
|
||||
parserOptions: {
|
||||
requireConfigFile: false,
|
||||
ecmaVersion: 6,
|
||||
sourceType: 'module',
|
||||
babelOptions: {
|
||||
presets: [require.resolve('@babel/preset-flow')],
|
||||
presets: [require.resolve('babel-plugin-syntax-hermes-parser')],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/eslint-plugin-specs",
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"description": "ESLint rules to validate NativeModule and Component Specs",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
@@ -18,9 +18,6 @@
|
||||
"specs"
|
||||
],
|
||||
"bugs": "https://github.com/facebook/react-native/issues",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"prepack": "node prepack.js",
|
||||
@@ -28,12 +25,18 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@babel/eslint-parser": "^7.25.1",
|
||||
"@babel/plugin-transform-flow-strip-types": "^7.25.2",
|
||||
"@babel/preset-flow": "^7.24.7",
|
||||
"@react-native/codegen": "0.76.0-main",
|
||||
"@react-native/codegen": "0.76.0-rc.3",
|
||||
"make-dir": "^2.1.0",
|
||||
"pirates": "^4.0.1",
|
||||
"source-map-support": "0.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-plugin-syntax-hermes-parser": "^0.23.1",
|
||||
"hermes-eslint": "^0.23.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/gradle-plugin",
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"description": "Gradle Plugin for React Native",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
||||
@@ -64,7 +64,8 @@ tasks.withType<KotlinCompile>().configureEach {
|
||||
apiVersion = "1.6"
|
||||
// See comment above on JDK 11 support
|
||||
jvmTarget = "11"
|
||||
allWarningsAsErrors = true
|
||||
allWarningsAsErrors =
|
||||
project.properties["enableWarningsAsErrors"]?.toString()?.toBoolean() ?: false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -188,6 +188,7 @@ abstract class ReactExtension @Inject constructor(val project: Project) {
|
||||
?.dependencies
|
||||
?.values
|
||||
?.filter { it.platforms?.android !== null }
|
||||
?.filterNot { it.platforms?.android?.isPureCxxDependency == true }
|
||||
?.forEach { deps ->
|
||||
val nameCleansed = deps.nameCleansed
|
||||
val dependencyConfiguration = deps.platforms?.android?.dependencyConfiguration
|
||||
|
||||
+4
@@ -166,6 +166,10 @@ abstract class GenerateAutolinkingNewArchitecturesFileTask : DefaultTask() {
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
set(CMAKE_VERBOSE_MAKEFILE on)
|
||||
|
||||
# We set REACTNATIVE_MERGED_SO so libraries/apps can selectively decide to depend on either libreactnative.so
|
||||
# or link against a old prefab target (this is needed for React Native 0.76 on).
|
||||
set(REACTNATIVE_MERGED_SO true)
|
||||
|
||||
{{ libraryIncludes }}
|
||||
|
||||
set(AUTOLINKED_LIBRARIES
|
||||
|
||||
+11
-2
@@ -30,10 +30,19 @@ abstract class GeneratePackageListTask : DefaultTask() {
|
||||
|
||||
@TaskAction
|
||||
fun taskAction() {
|
||||
val model = JsonUtils.fromAutolinkingConfigJson(autolinkInputFile.get().asFile)
|
||||
val model =
|
||||
JsonUtils.fromAutolinkingConfigJson(autolinkInputFile.get().asFile)
|
||||
?: error(
|
||||
"""
|
||||
RNGP - Autolinking: Could not parse autolinking config file:
|
||||
${autolinkInputFile.get().asFile.absolutePath}
|
||||
|
||||
The file is either missing or not containing valid JSON so the build won't succeed.
|
||||
"""
|
||||
.trimIndent())
|
||||
|
||||
val packageName =
|
||||
model?.project?.android?.packageName
|
||||
model.project?.android?.packageName
|
||||
?: error(
|
||||
"RNGP - Autolinking: Could not find project.android.packageName in react-native config output! Could not autolink packages without this field.")
|
||||
|
||||
|
||||
+38
@@ -189,6 +189,44 @@ class ReactExtensionTest {
|
||||
assertThat(deps).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getGradleDependenciesToApply_withIsPureCxxDeps_filtersCorrectly() {
|
||||
val validJsonFile =
|
||||
createJsonFile(
|
||||
"""
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"dependencies": {
|
||||
"@react-native/oss-library-example": {
|
||||
"root": "./node_modules/@react-native/android-example",
|
||||
"name": "@react-native/android-example",
|
||||
"platforms": {
|
||||
"android": {
|
||||
"sourceDir": "src/main/java",
|
||||
"packageImportPath": "com.facebook.react"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@react-native/another-library-for-testing": {
|
||||
"root": "./node_modules/@react-native/cxx-testing",
|
||||
"name": "@react-native/cxx-testing",
|
||||
"platforms": {
|
||||
"android": {
|
||||
"sourceDir": "src/main/java",
|
||||
"packageImportPath": "com.facebook.react",
|
||||
"isPureCxxDependency": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
|
||||
val deps = getGradleDependenciesToApply(validJsonFile)
|
||||
assertThat(deps).containsExactly("implementation" to ":react-native_android-example")
|
||||
}
|
||||
|
||||
private fun createJsonFile(@Language("JSON") input: String) =
|
||||
tempFolder.newFile().apply { writeText(input) }
|
||||
}
|
||||
|
||||
+8
@@ -115,6 +115,10 @@ class GenerateAutolinkingNewArchitecturesFileTaskTest {
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
set(CMAKE_VERBOSE_MAKEFILE on)
|
||||
|
||||
# We set REACTNATIVE_MERGED_SO so libraries/apps can selectively decide to depend on either libreactnative.so
|
||||
# or link against a old prefab target (this is needed for React Native 0.76 on).
|
||||
set(REACTNATIVE_MERGED_SO true)
|
||||
|
||||
|
||||
|
||||
set(AUTOLINKED_LIBRARIES
|
||||
@@ -137,6 +141,10 @@ class GenerateAutolinkingNewArchitecturesFileTaskTest {
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
set(CMAKE_VERBOSE_MAKEFILE on)
|
||||
|
||||
# We set REACTNATIVE_MERGED_SO so libraries/apps can selectively decide to depend on either libreactnative.so
|
||||
# or link against a old prefab target (this is needed for React Native 0.76 on).
|
||||
set(REACTNATIVE_MERGED_SO true)
|
||||
|
||||
add_subdirectory(./a/directory/ aPackage_autolinked_build)
|
||||
add_subdirectory(./another/directory/ anotherPackage_autolinked_build)
|
||||
add_subdirectory(./another/directory/cxx/ anotherPackage_cxxmodule_autolinked_build)
|
||||
|
||||
@@ -54,7 +54,8 @@ tasks.withType<KotlinCompile>().configureEach {
|
||||
apiVersion = "1.6"
|
||||
// See comment above on JDK 11 support
|
||||
jvmTarget = "11"
|
||||
allWarningsAsErrors = true
|
||||
allWarningsAsErrors =
|
||||
project.properties["enableWarningsAsErrors"]?.toString()?.toBoolean() ?: false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@ tasks.withType<KotlinCompile>().configureEach {
|
||||
kotlinOptions {
|
||||
apiVersion = "1.6"
|
||||
jvmTarget = "11"
|
||||
allWarningsAsErrors = true
|
||||
allWarningsAsErrors =
|
||||
project.properties["enableWarningsAsErrors"]?.toString()?.toBoolean() ?: false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,8 @@ tasks.withType<KotlinCompile>().configureEach {
|
||||
kotlinOptions {
|
||||
apiVersion = "1.6"
|
||||
jvmTarget = "11"
|
||||
allWarningsAsErrors = true
|
||||
allWarningsAsErrors =
|
||||
project.properties["enableWarningsAsErrors"]?.toString()?.toBoolean() ?: false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+17
-2
@@ -21,8 +21,23 @@ object JsonUtils {
|
||||
}
|
||||
|
||||
fun fromAutolinkingConfigJson(input: File): ModelAutolinkingConfigJson? =
|
||||
input.bufferedReader().use {
|
||||
runCatching { gsonConverter.fromJson(it, ModelAutolinkingConfigJson::class.java) }
|
||||
input.bufferedReader().use { reader ->
|
||||
runCatching {
|
||||
// We sanitize the output of the `config` command as it could contain debug logs
|
||||
// such as:
|
||||
//
|
||||
// > AwesomeProject@0.0.1 npx
|
||||
// > rnc-cli config
|
||||
//
|
||||
// which will render the JSON invalid.
|
||||
val content =
|
||||
reader
|
||||
.readLines()
|
||||
.filterNot { line -> line.startsWith(">") }
|
||||
.joinToString("\n")
|
||||
.trim()
|
||||
gsonConverter.fromJson(content, ModelAutolinkingConfigJson::class.java)
|
||||
}
|
||||
.getOrNull()
|
||||
}
|
||||
}
|
||||
|
||||
+48
@@ -186,6 +186,54 @@ class JsonUtilsTest {
|
||||
assertThat("implementation").isEqualTo(parsed.project!!.android!!.dependencyConfiguration)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fromAutolinkingConfigJson_withInfoLogs_sanitizeAndParseIt() {
|
||||
@Suppress("JsonStandardCompliance")
|
||||
val validJson =
|
||||
createJsonFile(
|
||||
"""
|
||||
|
||||
> AwesomeProject@0.0.1 npx
|
||||
> rnc-cli config
|
||||
|
||||
{
|
||||
"reactNativeVersion": "1000.0.0",
|
||||
"project": {
|
||||
"ios": {
|
||||
"sourceDir": "./packages/rn-tester",
|
||||
"xcodeProject": {
|
||||
"name": "RNTesterPods.xcworkspace",
|
||||
"isWorkspace": true
|
||||
},
|
||||
"automaticPodsInstallation": false
|
||||
},
|
||||
"android": {
|
||||
"sourceDir": "./packages/rn-tester",
|
||||
"appName": "RN-Tester",
|
||||
"packageName": "com.facebook.react.uiapp",
|
||||
"applicationId": "com.facebook.react.uiapp",
|
||||
"mainActivity": ".RNTesterActivity",
|
||||
"watchModeCommandParams": [
|
||||
"--mode HermesDebug"
|
||||
],
|
||||
"dependencyConfiguration": "implementation"
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent())
|
||||
val parsed = JsonUtils.fromAutolinkingConfigJson(validJson)!!
|
||||
|
||||
assertThat("./packages/rn-tester").isEqualTo(parsed.project!!.android!!.sourceDir)
|
||||
assertThat("RN-Tester").isEqualTo(parsed.project!!.android!!.appName)
|
||||
assertThat("com.facebook.react.uiapp").isEqualTo(parsed.project!!.android!!.packageName)
|
||||
assertThat("com.facebook.react.uiapp").isEqualTo(parsed.project!!.android!!.applicationId)
|
||||
assertThat(".RNTesterActivity").isEqualTo(parsed.project!!.android!!.mainActivity)
|
||||
assertThat("--mode HermesDebug")
|
||||
.isEqualTo(parsed.project!!.android!!.watchModeCommandParams!![0])
|
||||
assertThat("implementation").isEqualTo(parsed.project!!.android!!.dependencyConfiguration)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fromAutolinkingConfigJson_withDependenciesSpecified_canParseIt() {
|
||||
val validJson =
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.facebook.react.ReactPackage
|
||||
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
|
||||
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
|
||||
import com.facebook.react.defaults.DefaultReactNativeHost
|
||||
import com.facebook.react.soloader.OpenSourceMergedSoMapping
|
||||
import com.facebook.soloader.SoLoader
|
||||
|
||||
class MainApplication : Application(), ReactApplication {
|
||||
@@ -41,7 +42,7 @@ class MainApplication : Application(), ReactApplication {
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
SoLoader.init(this, false)
|
||||
SoLoader.init(this, OpenSourceMergedSoMapping)
|
||||
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
||||
// If you opted-in for the New Architecture, we load the native entry point for this app.
|
||||
load()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "helloworld",
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"bootstrap": "node ./cli.js bootstrap",
|
||||
@@ -12,24 +12,24 @@
|
||||
"test": "jest"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "19.0.0-rc-fb9a90fa48-20240614",
|
||||
"react-native": "1000.0.0"
|
||||
"react": "18.3.1",
|
||||
"react-native": "0.76.0-rc.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@babel/preset-env": "^7.25.3",
|
||||
"@babel/runtime": "^7.25.0",
|
||||
"@react-native/babel-preset": "0.76.0-main",
|
||||
"@react-native/core-cli-utils": "0.76.0-main",
|
||||
"@react-native/eslint-config": "0.76.0-main",
|
||||
"@react-native/metro-config": "0.76.0-main",
|
||||
"@react-native/babel-preset": "0.76.0-rc.3",
|
||||
"@react-native/core-cli-utils": "0.76.0-rc.3",
|
||||
"@react-native/eslint-config": "0.76.0-rc.3",
|
||||
"@react-native/metro-config": "0.76.0-rc.3",
|
||||
"babel-jest": "^29.6.3",
|
||||
"chalk": "^4.1.2",
|
||||
"commander": "^12.0.0",
|
||||
"eslint": "^8.19.0",
|
||||
"jest": "^29.6.3",
|
||||
"listr2": "^8.2.1",
|
||||
"react-test-renderer": "19.0.0-rc-fb9a90fa48-20240614",
|
||||
"react-test-renderer": "18.3.1",
|
||||
"rxjs": "^7.8.1"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/hermes-inspector-msggen",
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"private": true,
|
||||
"description": "Hermes Inspector Message Generator for React Native",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/metro-config",
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"description": "Metro configuration for React Native.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
@@ -26,9 +26,9 @@
|
||||
"dist"
|
||||
],
|
||||
"dependencies": {
|
||||
"@react-native/js-polyfills": "0.76.0-main",
|
||||
"@react-native/metro-babel-transformer": "0.76.0-main",
|
||||
"metro-config": "^0.80.10",
|
||||
"metro-runtime": "^0.80.10"
|
||||
"@react-native/js-polyfills": "0.76.0-rc.3",
|
||||
"@react-native/metro-babel-transformer": "0.76.0-rc.3",
|
||||
"metro-config": "^0.81.0-alpha.2",
|
||||
"metro-runtime": "^0.81.0-alpha.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/normalize-colors",
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"description": "Color normalization for React Native.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/js-polyfills",
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"description": "Polyfills for React Native.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/babel-preset",
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"description": "Babel preset for React Native applications",
|
||||
"main": "src/index.js",
|
||||
"repository": {
|
||||
@@ -15,23 +15,16 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@babel/plugin-transform-async-generator-functions": "^7.25.4",
|
||||
"@babel/plugin-transform-class-properties": "^7.25.4",
|
||||
"@babel/plugin-proposal-export-default-from": "^7.24.7",
|
||||
"@babel/plugin-transform-logical-assignment-operators": "^7.24.7",
|
||||
"@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7",
|
||||
"@babel/plugin-transform-numeric-separator": "^7.24.7",
|
||||
"@babel/plugin-transform-object-rest-spread": "^7.24.7",
|
||||
"@babel/plugin-transform-optional-catch-binding": "^7.24.7",
|
||||
"@babel/plugin-transform-optional-chaining": "^7.24.8",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||
"@babel/plugin-syntax-export-default-from": "^7.24.7",
|
||||
"@babel/plugin-syntax-flow": "^7.24.7",
|
||||
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
|
||||
"@babel/plugin-syntax-optional-chaining": "^7.8.3",
|
||||
"@babel/plugin-transform-arrow-functions": "^7.24.7",
|
||||
"@babel/plugin-transform-async-generator-functions": "^7.25.4",
|
||||
"@babel/plugin-transform-async-to-generator": "^7.24.7",
|
||||
"@babel/plugin-transform-block-scoping": "^7.25.0",
|
||||
"@babel/plugin-transform-class-properties": "^7.25.4",
|
||||
"@babel/plugin-transform-classes": "^7.25.4",
|
||||
"@babel/plugin-transform-computed-properties": "^7.24.7",
|
||||
"@babel/plugin-transform-destructuring": "^7.24.8",
|
||||
@@ -39,8 +32,14 @@
|
||||
"@babel/plugin-transform-for-of": "^7.24.7",
|
||||
"@babel/plugin-transform-function-name": "^7.25.1",
|
||||
"@babel/plugin-transform-literals": "^7.25.2",
|
||||
"@babel/plugin-transform-logical-assignment-operators": "^7.24.7",
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.24.8",
|
||||
"@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7",
|
||||
"@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7",
|
||||
"@babel/plugin-transform-numeric-separator": "^7.24.7",
|
||||
"@babel/plugin-transform-object-rest-spread": "^7.24.7",
|
||||
"@babel/plugin-transform-optional-catch-binding": "^7.24.7",
|
||||
"@babel/plugin-transform-optional-chaining": "^7.24.8",
|
||||
"@babel/plugin-transform-parameters": "^7.24.7",
|
||||
"@babel/plugin-transform-private-methods": "^7.24.7",
|
||||
"@babel/plugin-transform-private-property-in-object": "^7.24.7",
|
||||
@@ -56,7 +55,8 @@
|
||||
"@babel/plugin-transform-typescript": "^7.25.2",
|
||||
"@babel/plugin-transform-unicode-regex": "^7.24.7",
|
||||
"@babel/template": "^7.25.0",
|
||||
"@react-native/babel-plugin-codegen": "0.76.0-main",
|
||||
"@react-native/babel-plugin-codegen": "0.76.0-rc.3",
|
||||
"babel-plugin-syntax-hermes-parser": "^0.23.1",
|
||||
"babel-plugin-transform-flow-enums": "^0.0.2",
|
||||
"react-refresh": "^0.14.0"
|
||||
},
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ function isTSXSource(fileName) {
|
||||
const loose = true;
|
||||
|
||||
const defaultPlugins = [
|
||||
[require('@babel/plugin-syntax-flow')],
|
||||
[require('babel-plugin-syntax-hermes-parser')],
|
||||
[require('babel-plugin-transform-flow-enums')],
|
||||
[require('@babel/plugin-transform-block-scoping')],
|
||||
[require('@babel/plugin-transform-class-properties'), {loose}],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/metro-babel-transformer",
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"description": "Babel transformer for React Native applications.",
|
||||
"main": "src/index.js",
|
||||
"repository": {
|
||||
@@ -16,7 +16,7 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@react-native/babel-preset": "0.76.0-main",
|
||||
"@react-native/babel-preset": "0.76.0-rc.3",
|
||||
"hermes-parser": "0.23.1",
|
||||
"nullthrows": "^1.1.1"
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@react-native/bots",
|
||||
"description": "React Native Bots",
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/codegen-typescript-test",
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"private": true,
|
||||
"description": "TypeScript related unit test for @react-native/codegen",
|
||||
"license": "MIT",
|
||||
@@ -19,7 +19,7 @@
|
||||
"prepare": "yarn run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-native/codegen": "0.76.0-main"
|
||||
"@react-native/codegen": "0.76.0-rc.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/codegen",
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"description": "Code generation tools for React Native",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-native-info",
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"main": "build/index.js",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/popup-menu-android",
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"description": "PopupMenu for the Android platform",
|
||||
"main": "index.js",
|
||||
"files": [
|
||||
@@ -17,7 +17,7 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@react-native/codegen": "0.76.0-main"
|
||||
"@react-native/codegen": "0.76.0-rc.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^18.2.6",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/oss-library-example",
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"private": true,
|
||||
"description": "Package that includes native module exapmle, native component example, targets both the old and the new architecture. It should serve as an example of a real-world OSS library.",
|
||||
"license": "MIT",
|
||||
@@ -26,8 +26,8 @@
|
||||
],
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@react-native/babel-preset": "0.76.0-main",
|
||||
"react-native": "1000.0.0"
|
||||
"@react-native/babel-preset": "0.76.0-rc.3",
|
||||
"react-native": "0.76.0-rc.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@react-native/test-renderer",
|
||||
"private": true,
|
||||
"version": "0.76.0-main",
|
||||
"version": "0.76.0-rc.3",
|
||||
"description": "A Test rendering library for React Native",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
|
||||
@@ -64,6 +64,9 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@property (nonatomic, strong, nullable) NSDictionary *initialProps;
|
||||
@property (nonatomic, strong, nonnull) RCTRootViewFactory *rootViewFactory;
|
||||
|
||||
/// If `automaticallyLoadReactNativeWindow` is set to `true`, the React Native window will be loaded automatically.
|
||||
@property (nonatomic, assign) BOOL automaticallyLoadReactNativeWindow;
|
||||
|
||||
@property (nonatomic, nullable) RCTSurfacePresenterBridgeAdapter *bridgeAdapter;
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#import <React/RCTSurfacePresenterBridgeAdapter.h>
|
||||
#import <React/RCTUtils.h>
|
||||
#import <ReactCommon/RCTHost.h>
|
||||
#include <UIKit/UIKit.h>
|
||||
#import <objc/runtime.h>
|
||||
#import <react/featureflags/ReactNativeFeatureFlags.h>
|
||||
#import <react/featureflags/ReactNativeFeatureFlagsDefaults.h>
|
||||
@@ -38,6 +39,14 @@
|
||||
|
||||
@implementation RCTAppDelegate
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_automaticallyLoadReactNativeWindow = YES;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
[self _setUpFeatureFlags];
|
||||
@@ -47,23 +56,28 @@
|
||||
RCTAppSetupPrepareApp(application, self.turboModuleEnabled);
|
||||
|
||||
self.rootViewFactory = [self createRCTRootViewFactory];
|
||||
|
||||
UIView *rootView = [self.rootViewFactory viewWithModuleName:self.moduleName
|
||||
initialProperties:self.initialProps
|
||||
launchOptions:launchOptions];
|
||||
|
||||
if (self.newArchEnabled || self.fabricEnabled) {
|
||||
[RCTComponentViewFactory currentComponentViewFactory].thirdPartyFabricComponentsProvider = self;
|
||||
}
|
||||
|
||||
if (self.automaticallyLoadReactNativeWindow) {
|
||||
[self loadReactNativeWindow:launchOptions];
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)loadReactNativeWindow:(NSDictionary *)launchOptions
|
||||
{
|
||||
UIView *rootView = [self.rootViewFactory viewWithModuleName:self.moduleName
|
||||
initialProperties:self.initialProps
|
||||
launchOptions:launchOptions];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [self createRootViewController];
|
||||
[self setRootView:rootView toRootViewController:rootViewController];
|
||||
self.window.rootViewController = rootViewController;
|
||||
self.window.windowScene.delegate = self;
|
||||
[self.window makeKeyAndVisible];
|
||||
|
||||
return YES;
|
||||
_window.rootViewController = rootViewController;
|
||||
[_window makeKeyAndVisible];
|
||||
}
|
||||
|
||||
- (void)applicationDidEnterBackground:(UIApplication *)application
|
||||
|
||||
@@ -72,9 +72,10 @@ RCT_EXPORT_METHOD(readAsDataURL
|
||||
nil);
|
||||
} else {
|
||||
NSString *type = [RCTConvert NSString:blob[@"type"]];
|
||||
NSString *text = [NSString stringWithFormat:@"data:%@;base64,%@",
|
||||
type != nil && [type length] > 0 ? type : @"application/octet-stream",
|
||||
[data base64EncodedStringWithOptions:0]];
|
||||
NSString *text = [NSString
|
||||
stringWithFormat:@"data:%@;base64,%@",
|
||||
![type isEqual:[NSNull null]] && [type length] > 0 ? type : @"application/octet-stream",
|
||||
[data base64EncodedStringWithOptions:0]];
|
||||
|
||||
resolve(text);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
|
||||
import type {ViewStyleProp} from '../../StyleSheet/StyleSheet';
|
||||
import type {DimensionsPayload} from '../../Utilities/NativeDeviceInfo';
|
||||
import type {
|
||||
ViewLayout,
|
||||
ViewLayoutEvent,
|
||||
@@ -18,6 +19,7 @@ import type {KeyboardEvent, KeyboardMetrics} from './Keyboard';
|
||||
|
||||
import LayoutAnimation from '../../LayoutAnimation/LayoutAnimation';
|
||||
import StyleSheet from '../../StyleSheet/StyleSheet';
|
||||
import Dimensions from '../../Utilities/Dimensions';
|
||||
import Platform from '../../Utilities/Platform';
|
||||
import {type EventSubscription} from '../../vendor/emitter/EventEmitter';
|
||||
import AccessibilityInfo from '../AccessibilityInfo/AccessibilityInfo';
|
||||
@@ -66,6 +68,7 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
|
||||
viewRef: {current: React.ElementRef<typeof View> | null, ...};
|
||||
_initialFrameHeight: number = 0;
|
||||
_bottom: number = 0;
|
||||
_windowWidth: number = Dimensions.get('window').width;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
@@ -130,6 +133,10 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
|
||||
}
|
||||
};
|
||||
|
||||
_onDimensionsChange = ({window}: DimensionsPayload) => {
|
||||
this._windowWidth = window?.width ?? 0;
|
||||
};
|
||||
|
||||
// Avoid unnecessary renders if the KeyboardAvoidingView is disabled.
|
||||
_setBottom = (value: number) => {
|
||||
const enabled = this.props.enabled ?? true;
|
||||
@@ -145,6 +152,15 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
Platform.OS === 'ios' &&
|
||||
this._windowWidth !== this._keyboardEvent.endCoordinates.width
|
||||
) {
|
||||
// The keyboard is not the standard bottom-of-the-screen keyboard. For example, floating keyboard on iPadOS.
|
||||
this._setBottom(0);
|
||||
return;
|
||||
}
|
||||
|
||||
const {duration, easing, endCoordinates} = this._keyboardEvent;
|
||||
const height = await this._relativeKeyboardHeight(endCoordinates);
|
||||
|
||||
@@ -178,6 +194,7 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
|
||||
if (Platform.OS === 'ios') {
|
||||
this._subscriptions = [
|
||||
Keyboard.addListener('keyboardWillChangeFrame', this._onKeyboardChange),
|
||||
Dimensions.addEventListener('change', this._onDimensionsChange),
|
||||
];
|
||||
} else {
|
||||
this._subscriptions = [
|
||||
|
||||
@@ -1931,19 +1931,22 @@ function createRefForwarder<TNativeInstance, TPublicInstance>(
|
||||
return state;
|
||||
}
|
||||
|
||||
// TODO: After upgrading to React 19, remove `forwardRef` from this component.
|
||||
// NOTE: This wrapper component is necessary because `ScrollView` is a class
|
||||
// component and we need to map `ref` to a differently named prop. This can be
|
||||
// removed when `ScrollView` is a functional component.
|
||||
function Wrapper({
|
||||
ref,
|
||||
...props
|
||||
}: {
|
||||
...Props,
|
||||
ref: React.RefSetter<PublicScrollViewInstance>,
|
||||
}): React.Node {
|
||||
return <ScrollView {...props} scrollViewRef={ref} />;
|
||||
}
|
||||
const Wrapper = React.forwardRef(function Wrapper(
|
||||
props: Props,
|
||||
ref: ?React.RefSetter<PublicScrollViewInstance>,
|
||||
): React.Node {
|
||||
return ref == null ? (
|
||||
<ScrollView {...props} />
|
||||
) : (
|
||||
<ScrollView {...props} scrollViewRef={ref} />
|
||||
);
|
||||
});
|
||||
Wrapper.displayName = 'ScrollView';
|
||||
// $FlowExpectedError[prop-missing]
|
||||
Wrapper.Context = ScrollViewContext;
|
||||
|
||||
module.exports = ((Wrapper: $FlowFixMe): React.AbstractComponent<
|
||||
|
||||
+3
@@ -160,6 +160,9 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig =
|
||||
snapToInterval: true,
|
||||
snapToOffsets: true,
|
||||
snapToStart: true,
|
||||
verticalScrollIndicatorInsets: {
|
||||
diff: require('../../Utilities/differ/insetsDiffer'),
|
||||
},
|
||||
zoomScale: true,
|
||||
...ConditionallyIgnoredEventHandlers({
|
||||
onScrollBeginDrag: true,
|
||||
|
||||
+10
@@ -85,8 +85,15 @@ const RCTTextInputViewConfig = {
|
||||
topContentSizeChange: {
|
||||
registrationName: 'onContentSizeChange',
|
||||
},
|
||||
topChangeSync: {
|
||||
registrationName: 'onChangeSync',
|
||||
},
|
||||
topKeyPressSync: {
|
||||
registrationName: 'onKeyPressSync',
|
||||
},
|
||||
},
|
||||
validAttributes: {
|
||||
dynamicTypeRamp: true,
|
||||
fontSize: true,
|
||||
fontWeight: true,
|
||||
fontVariant: true,
|
||||
@@ -97,6 +104,7 @@ const RCTTextInputViewConfig = {
|
||||
textTransform: true,
|
||||
textAlign: true,
|
||||
fontFamily: true,
|
||||
lineBreakModeIOS: true,
|
||||
lineHeight: true,
|
||||
isHighlighted: true,
|
||||
writingDirection: true,
|
||||
@@ -150,6 +158,8 @@ const RCTTextInputViewConfig = {
|
||||
onSelectionChange: true,
|
||||
onContentSizeChange: true,
|
||||
onScroll: true,
|
||||
onChangeSync: true,
|
||||
onKeyPressSync: true,
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
+2
-2
@@ -120,7 +120,7 @@ const ReactNativeStyleAttributes: {[string]: AnyAttributeType, ...} = {
|
||||
/**
|
||||
* Filter
|
||||
*/
|
||||
experimental_filter: {process: processFilter},
|
||||
filter: {process: processFilter},
|
||||
|
||||
/**
|
||||
* MixBlendMode
|
||||
@@ -135,7 +135,7 @@ const ReactNativeStyleAttributes: {[string]: AnyAttributeType, ...} = {
|
||||
/*
|
||||
* BoxShadow
|
||||
*/
|
||||
experimental_boxShadow: {process: processBoxShadow},
|
||||
boxShadow: {process: processBoxShadow},
|
||||
|
||||
/**
|
||||
* Linear Gradient
|
||||
|
||||
@@ -14,10 +14,10 @@ const version: $ReadOnly<{
|
||||
patch: number,
|
||||
prerelease: string | null,
|
||||
}> = {
|
||||
major: 1000,
|
||||
minor: 0,
|
||||
major: 0,
|
||||
minor: 76,
|
||||
patch: 0,
|
||||
prerelease: null,
|
||||
prerelease: 'rc.3',
|
||||
};
|
||||
|
||||
module.exports = {version};
|
||||
|
||||
@@ -169,10 +169,10 @@ const validAttributesForNonEventProps = {
|
||||
experimental_backgroundImage: {
|
||||
process: require('../StyleSheet/processBackgroundImage').default,
|
||||
},
|
||||
experimental_boxShadow: {
|
||||
boxShadow: {
|
||||
process: require('../StyleSheet/processBoxShadow').default,
|
||||
},
|
||||
experimental_filter: {
|
||||
filter: {
|
||||
process: require('../StyleSheet/processFilter').default,
|
||||
},
|
||||
experimental_mixBlendMode: true,
|
||||
|
||||
@@ -198,6 +198,7 @@ const validAttributesForNonEventProps = {
|
||||
testID: true,
|
||||
backgroundColor: {process: require('../StyleSheet/processColor').default},
|
||||
backfaceVisibility: true,
|
||||
cursor: true,
|
||||
opacity: true,
|
||||
shadowColor: {process: require('../StyleSheet/processColor').default},
|
||||
shadowOffset: {diff: require('../Utilities/differ/sizesDiffer')},
|
||||
@@ -216,16 +217,18 @@ const validAttributesForNonEventProps = {
|
||||
role: true,
|
||||
borderRadius: true,
|
||||
borderColor: {process: require('../StyleSheet/processColor').default},
|
||||
borderBlockColor: {process: require('../StyleSheet/processColor').default},
|
||||
borderCurve: true,
|
||||
borderWidth: true,
|
||||
borderBlockWidth: true,
|
||||
borderStyle: true,
|
||||
hitSlop: {diff: require('../Utilities/differ/insetsDiffer')},
|
||||
collapsable: true,
|
||||
collapsableChildren: true,
|
||||
experimental_filter: {
|
||||
filter: {
|
||||
process: require('../StyleSheet/processFilter').default,
|
||||
},
|
||||
experimental_boxShadow: {
|
||||
boxShadow: {
|
||||
process: require('../StyleSheet/processBoxShadow').default,
|
||||
},
|
||||
experimental_mixBlendMode: true,
|
||||
@@ -240,9 +243,15 @@ const validAttributesForNonEventProps = {
|
||||
borderLeftWidth: true,
|
||||
borderLeftColor: {process: require('../StyleSheet/processColor').default},
|
||||
borderStartWidth: true,
|
||||
borderBlockStartWidth: true,
|
||||
borderStartColor: {process: require('../StyleSheet/processColor').default},
|
||||
borderBlockStartColor: {
|
||||
process: require('../StyleSheet/processColor').default,
|
||||
},
|
||||
borderEndWidth: true,
|
||||
borderBlockEndWidth: true,
|
||||
borderEndColor: {process: require('../StyleSheet/processColor').default},
|
||||
borderBlockEndColor: {process: require('../StyleSheet/processColor').default},
|
||||
|
||||
borderTopLeftRadius: true,
|
||||
borderTopRightRadius: true,
|
||||
|
||||
@@ -188,6 +188,10 @@ function getProcessorForType(typeName: string): ?(nextProp: any) => any {
|
||||
case 'UIImage':
|
||||
case 'RCTImageSource':
|
||||
return resolveAssetSource;
|
||||
case 'BoxShadowArray':
|
||||
return processBoxShadow;
|
||||
case 'FilterArray':
|
||||
return processFilter;
|
||||
// Android Types
|
||||
case 'Color':
|
||||
return processColor;
|
||||
|
||||
+27141
-16426
File diff suppressed because it is too large
Load Diff
+1630
-2675
File diff suppressed because it is too large
Load Diff
+1682
-2945
File diff suppressed because it is too large
Load Diff
+27607
-16730
File diff suppressed because it is too large
Load Diff
+1652
-2709
File diff suppressed because it is too large
Load Diff
+1733
-2980
File diff suppressed because it is too large
Load Diff
@@ -110,11 +110,102 @@ export interface FlexStyle {
|
||||
top?: DimensionValue | undefined;
|
||||
width?: DimensionValue | undefined;
|
||||
zIndex?: number | undefined;
|
||||
direction?: 'inherit' | 'ltr' | 'rtl' | undefined;
|
||||
|
||||
/**
|
||||
* @platform ios
|
||||
* Equivalent to `top`, `bottom`, `right` and `left`
|
||||
*/
|
||||
direction?: 'inherit' | 'ltr' | 'rtl' | undefined;
|
||||
inset?: DimensionValue | undefined;
|
||||
|
||||
/**
|
||||
* Equivalent to `top`, `bottom`
|
||||
*/
|
||||
insetBlock?: DimensionValue | undefined;
|
||||
|
||||
/**
|
||||
* Equivalent to `bottom`
|
||||
*/
|
||||
insetBlockEnd?: DimensionValue | undefined;
|
||||
|
||||
/**
|
||||
* Equivalent to `top`
|
||||
*/
|
||||
insetBlockStart?: DimensionValue | undefined;
|
||||
|
||||
/**
|
||||
* Equivalent to `right` and `left`
|
||||
*/
|
||||
insetInline?: DimensionValue | undefined;
|
||||
|
||||
/**
|
||||
* Equivalent to `right` or `left`
|
||||
*/
|
||||
insetInlineEnd?: DimensionValue | undefined;
|
||||
|
||||
/**
|
||||
* Equivalent to `right` or `left`
|
||||
*/
|
||||
insetInlineStart?: DimensionValue | undefined;
|
||||
|
||||
/**
|
||||
* Equivalent to `marginVertical`
|
||||
*/
|
||||
marginBlock?: DimensionValue | undefined;
|
||||
|
||||
/**
|
||||
* Equivalent to `marginBottom`
|
||||
*/
|
||||
marginBlockEnd?: DimensionValue | undefined;
|
||||
|
||||
/**
|
||||
* Equivalent to `marginTop`
|
||||
*/
|
||||
marginBlockStart?: DimensionValue | undefined;
|
||||
|
||||
/**
|
||||
* Equivalent to `marginHorizontal`
|
||||
*/
|
||||
marginInline?: DimensionValue | undefined;
|
||||
|
||||
/**
|
||||
* Equivalent to `marginEnd`
|
||||
*/
|
||||
marginInlineEnd?: DimensionValue | undefined;
|
||||
|
||||
/**
|
||||
* Equivalent to `marginStart`
|
||||
*/
|
||||
marginInlineStart?: DimensionValue | undefined;
|
||||
|
||||
/**
|
||||
* Equivalent to `paddingVertical`
|
||||
*/
|
||||
paddingBlock?: DimensionValue | undefined;
|
||||
|
||||
/**
|
||||
* Equivalent to `paddingBottom`
|
||||
*/
|
||||
paddingBlockEnd?: DimensionValue | undefined;
|
||||
|
||||
/**
|
||||
* Equivalent to `paddingTop`
|
||||
*/
|
||||
paddingBlockStart?: DimensionValue | undefined;
|
||||
|
||||
/**
|
||||
* Equivalent to `paddingHorizontal`
|
||||
*/
|
||||
paddingInline?: DimensionValue | undefined;
|
||||
|
||||
/**
|
||||
* Equivalent to `paddingEnd`
|
||||
*/
|
||||
paddingInlineEnd?: DimensionValue | undefined;
|
||||
|
||||
/**
|
||||
* Equivalent to `paddingStart`
|
||||
*/
|
||||
paddingInlineStart?: DimensionValue | undefined;
|
||||
}
|
||||
|
||||
export interface ShadowStyleIOS {
|
||||
@@ -239,16 +330,16 @@ export type FilterFunction =
|
||||
| {opacity: number | string}
|
||||
| {saturate: number | string}
|
||||
| {sepia: number | string}
|
||||
| {dropShadow: DropShadowPrimitive | string};
|
||||
| {dropShadow: DropShadowValue | string};
|
||||
|
||||
export type DropShadowPrimitive = {
|
||||
export type DropShadowValue = {
|
||||
offsetX: number | string;
|
||||
offsetY: number | string;
|
||||
standardDeviation?: number | string | undefined;
|
||||
color?: ColorValue | number | undefined;
|
||||
};
|
||||
|
||||
export type BoxShadowPrimitive = {
|
||||
export type BoxShadowValue = {
|
||||
offsetX: number | string;
|
||||
offsetY: number | string;
|
||||
color?: string | undefined;
|
||||
@@ -336,6 +427,8 @@ export interface ViewStyle extends FlexStyle, ShadowStyleIOS, TransformsStyle {
|
||||
pointerEvents?: 'box-none' | 'none' | 'box-only' | 'auto' | undefined;
|
||||
isolation?: 'auto' | 'isolate' | undefined;
|
||||
cursor?: CursorValue | undefined;
|
||||
boxShadow?: ReadonlyArray<BoxShadowValue> | string | undefined;
|
||||
filter?: ReadonlyArray<FilterFunction> | string | undefined;
|
||||
}
|
||||
|
||||
export type FontVariant =
|
||||
|
||||
@@ -700,9 +700,9 @@ export type FilterFunction =
|
||||
| {opacity: number | string}
|
||||
| {saturate: number | string}
|
||||
| {sepia: number | string}
|
||||
| {dropShadow: DropShadowPrimitive | string};
|
||||
| {dropShadow: DropShadowValue | string};
|
||||
|
||||
export type DropShadowPrimitive = {
|
||||
export type DropShadowValue = {
|
||||
offsetX: number | string,
|
||||
offsetY: number | string,
|
||||
standardDeviation?: number | string,
|
||||
@@ -719,7 +719,7 @@ export type GradientValue = {
|
||||
}>,
|
||||
};
|
||||
|
||||
export type BoxShadowPrimitive = {
|
||||
export type BoxShadowValue = {
|
||||
offsetX: number | string,
|
||||
offsetY: number | string,
|
||||
color?: ____ColorValue_Internal,
|
||||
@@ -788,8 +788,8 @@ export type ____ViewStyle_InternalCore = $ReadOnly<{
|
||||
elevation?: number,
|
||||
pointerEvents?: 'auto' | 'none' | 'box-none' | 'box-only',
|
||||
cursor?: CursorValue,
|
||||
experimental_boxShadow?: $ReadOnlyArray<BoxShadowPrimitive> | string,
|
||||
experimental_filter?: $ReadOnlyArray<FilterFunction> | string,
|
||||
boxShadow?: $ReadOnlyArray<BoxShadowValue> | string,
|
||||
filter?: $ReadOnlyArray<FilterFunction> | string,
|
||||
experimental_mixBlendMode?: ____BlendMode_Internal,
|
||||
experimental_backgroundImage?: $ReadOnlyArray<GradientValue> | string,
|
||||
isolation?: 'auto' | 'isolate',
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*/
|
||||
|
||||
import type {ProcessedColorValue} from './processColor';
|
||||
import type {BoxShadowPrimitive} from './StyleSheetTypes';
|
||||
import type {BoxShadowValue} from './StyleSheetTypes';
|
||||
|
||||
import processColor from './processColor';
|
||||
|
||||
@@ -24,7 +24,7 @@ export type ParsedBoxShadow = {
|
||||
};
|
||||
|
||||
export default function processBoxShadow(
|
||||
rawBoxShadows: ?($ReadOnlyArray<BoxShadowPrimitive> | string),
|
||||
rawBoxShadows: ?($ReadOnlyArray<BoxShadowValue> | string),
|
||||
): Array<ParsedBoxShadow> {
|
||||
const result: Array<ParsedBoxShadow> = [];
|
||||
if (rawBoxShadows == null) {
|
||||
@@ -106,16 +106,14 @@ export default function processBoxShadow(
|
||||
return result;
|
||||
}
|
||||
|
||||
function parseBoxShadowString(
|
||||
rawBoxShadows: string,
|
||||
): Array<BoxShadowPrimitive> {
|
||||
let result: Array<BoxShadowPrimitive> = [];
|
||||
function parseBoxShadowString(rawBoxShadows: string): Array<BoxShadowValue> {
|
||||
let result: Array<BoxShadowValue> = [];
|
||||
|
||||
for (const rawBoxShadow of rawBoxShadows
|
||||
.split(/,(?![^()]*\))/) // split by comma that is not in parenthesis
|
||||
.map(bS => bS.trim())
|
||||
.filter(bS => bS !== '')) {
|
||||
const boxShadow: BoxShadowPrimitive = {
|
||||
const boxShadow: BoxShadowValue = {
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
};
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
'use strict';
|
||||
|
||||
import type {ColorValue} from './StyleSheet';
|
||||
import type {DropShadowPrimitive, FilterFunction} from './StyleSheetTypes';
|
||||
import type {DropShadowValue, FilterFunction} from './StyleSheetTypes';
|
||||
|
||||
import processColor from './processColor';
|
||||
|
||||
@@ -179,7 +179,7 @@ function _getFilterAmount(filterName: string, filterArgs: mixed): ?number {
|
||||
}
|
||||
|
||||
function parseDropShadow(
|
||||
rawDropShadow: string | DropShadowPrimitive,
|
||||
rawDropShadow: string | DropShadowValue,
|
||||
): ?ParsedDropShadow {
|
||||
const dropShadow =
|
||||
typeof rawDropShadow === 'string'
|
||||
@@ -248,8 +248,8 @@ function parseDropShadow(
|
||||
return parsedDropShadow;
|
||||
}
|
||||
|
||||
function parseDropShadowString(rawDropShadow: string): ?DropShadowPrimitive {
|
||||
const dropShadow: DropShadowPrimitive = {
|
||||
function parseDropShadowString(rawDropShadow: string): ?DropShadowValue {
|
||||
const dropShadow: DropShadowValue = {
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
};
|
||||
|
||||
@@ -1749,10 +1749,12 @@ declare class KeyboardAvoidingView extends React.Component<Props, State> {
|
||||
viewRef: { current: React.ElementRef<typeof View> | null, ... };
|
||||
_initialFrameHeight: number;
|
||||
_bottom: number;
|
||||
_windowWidth: number;
|
||||
constructor(props: Props): void;
|
||||
_relativeKeyboardHeight(keyboardFrame: KeyboardMetrics): Promise<number>;
|
||||
_onKeyboardChange: $FlowFixMe;
|
||||
_onLayout: $FlowFixMe;
|
||||
_onDimensionsChange: $FlowFixMe;
|
||||
_setBottom: $FlowFixMe;
|
||||
_updateBottomIfNecessary: $FlowFixMe;
|
||||
componentDidUpdate(_: Props, prevState: State): void;
|
||||
@@ -8232,8 +8234,8 @@ export type FilterFunction =
|
||||
| { opacity: number | string }
|
||||
| { saturate: number | string }
|
||||
| { sepia: number | string }
|
||||
| { dropShadow: DropShadowPrimitive | string };
|
||||
export type DropShadowPrimitive = {
|
||||
| { dropShadow: DropShadowValue | string };
|
||||
export type DropShadowValue = {
|
||||
offsetX: number | string,
|
||||
offsetY: number | string,
|
||||
standardDeviation?: number | string,
|
||||
@@ -8247,7 +8249,7 @@ export type GradientValue = {
|
||||
positions?: $ReadOnlyArray<string>,
|
||||
}>,
|
||||
};
|
||||
export type BoxShadowPrimitive = {
|
||||
export type BoxShadowValue = {
|
||||
offsetX: number | string,
|
||||
offsetY: number | string,
|
||||
color?: ____ColorValue_Internal,
|
||||
@@ -8314,8 +8316,8 @@ export type ____ViewStyle_InternalCore = $ReadOnly<{
|
||||
elevation?: number,
|
||||
pointerEvents?: \\"auto\\" | \\"none\\" | \\"box-none\\" | \\"box-only\\",
|
||||
cursor?: CursorValue,
|
||||
experimental_boxShadow?: $ReadOnlyArray<BoxShadowPrimitive> | string,
|
||||
experimental_filter?: $ReadOnlyArray<FilterFunction> | string,
|
||||
boxShadow?: $ReadOnlyArray<BoxShadowValue> | string,
|
||||
filter?: $ReadOnlyArray<FilterFunction> | string,
|
||||
experimental_mixBlendMode?: ____BlendMode_Internal,
|
||||
experimental_backgroundImage?: $ReadOnlyArray<GradientValue> | string,
|
||||
isolation?: \\"auto\\" | \\"isolate\\",
|
||||
@@ -8586,7 +8588,7 @@ exports[`public API should not change unintentionally Libraries/StyleSheet/proce
|
||||
inset?: boolean,
|
||||
};
|
||||
declare export default function processBoxShadow(
|
||||
rawBoxShadows: ?($ReadOnlyArray<BoxShadowPrimitive> | string)
|
||||
rawBoxShadows: ?($ReadOnlyArray<BoxShadowValue> | string)
|
||||
): Array<ParsedBoxShadow>;
|
||||
"
|
||||
`;
|
||||
|
||||
@@ -21,10 +21,10 @@ NSDictionary* RCTGetReactNativeVersion(void)
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^(void){
|
||||
__rnVersion = @{
|
||||
RCTVersionMajor: @(1000),
|
||||
RCTVersionMinor: @(0),
|
||||
RCTVersionMajor: @(0),
|
||||
RCTVersionMinor: @(76),
|
||||
RCTVersionPatch: @(0),
|
||||
RCTVersionPrerelease: [NSNull null],
|
||||
RCTVersionPrerelease: @"rc.3",
|
||||
};
|
||||
});
|
||||
return __rnVersion;
|
||||
|
||||
+22
@@ -49,6 +49,11 @@ using namespace facebook::react;
|
||||
[_refreshControl addTarget:self
|
||||
action:@selector(handleUIControlEventValueChanged)
|
||||
forControlEvents:UIControlEventValueChanged];
|
||||
|
||||
const auto &concreteProps = static_cast<const PullToRefreshViewProps &>(*_props);
|
||||
|
||||
_refreshControl.tintColor = RCTUIColorFromSharedColor(concreteProps.tintColor);
|
||||
[self _updateProgressViewOffset:concreteProps.progressViewOffset];
|
||||
}
|
||||
|
||||
#pragma mark - RCTComponentViewProtocol
|
||||
@@ -78,6 +83,14 @@ using namespace facebook::react;
|
||||
}
|
||||
}
|
||||
|
||||
if (newConcreteProps.tintColor != oldConcreteProps.tintColor) {
|
||||
_refreshControl.tintColor = RCTUIColorFromSharedColor(newConcreteProps.tintColor);
|
||||
}
|
||||
|
||||
if (newConcreteProps.progressViewOffset != oldConcreteProps.progressViewOffset) {
|
||||
[self _updateProgressViewOffset:newConcreteProps.progressViewOffset];
|
||||
}
|
||||
|
||||
BOOL needsUpdateTitle = NO;
|
||||
|
||||
if (newConcreteProps.title != oldConcreteProps.title) {
|
||||
@@ -102,6 +115,15 @@ using namespace facebook::react;
|
||||
static_cast<const PullToRefreshViewEventEmitter &>(*_eventEmitter).onRefresh({});
|
||||
}
|
||||
|
||||
- (void)_updateProgressViewOffset:(Float)progressViewOffset
|
||||
{
|
||||
_refreshControl.bounds = CGRectMake(
|
||||
_refreshControl.bounds.origin.x,
|
||||
-progressViewOffset,
|
||||
_refreshControl.bounds.size.width,
|
||||
_refreshControl.bounds.size.height);
|
||||
}
|
||||
|
||||
- (void)_updateTitle
|
||||
{
|
||||
const auto &concreteProps = static_cast<const PullToRefreshViewProps &>(*_props);
|
||||
|
||||
+23
@@ -723,6 +723,29 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu
|
||||
[self _handleFinishedScrolling:scrollView];
|
||||
}
|
||||
|
||||
- (void)didMoveToWindow
|
||||
{
|
||||
[super didMoveToWindow];
|
||||
|
||||
if (!self.window) {
|
||||
// The view is being removed, ensure that the scroll end event is dispatched
|
||||
[self _handleScrollEndIfNeeded];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_handleScrollEndIfNeeded
|
||||
{
|
||||
if (_scrollView.isDecelerating || !_scrollView.isTracking) {
|
||||
if (!_eventEmitter) {
|
||||
return;
|
||||
}
|
||||
static_cast<const ScrollViewEventEmitter &>(*_eventEmitter).onMomentumScrollEnd([self _scrollViewMetrics]);
|
||||
|
||||
[self _updateStateWithContentOffset];
|
||||
_isUserTriggeredScrolling = NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_handleFinishedScrolling:(UIScrollView *)scrollView
|
||||
{
|
||||
[self _forceDispatchNextScrollEvent];
|
||||
|
||||
@@ -431,18 +431,19 @@ RCT_CUSTOM_VIEW_PROPERTY(experimental_layoutConformance, NSString *, RCTView)
|
||||
// filtered by view configs.
|
||||
}
|
||||
|
||||
RCT_CUSTOM_VIEW_PROPERTY(experimental_filter, NSArray *, RCTView)
|
||||
typedef NSArray *FilterArray; // Custom type to make the StaticViewConfigValidator Happy
|
||||
RCT_CUSTOM_VIEW_PROPERTY(filter, FilterArray, RCTView)
|
||||
{
|
||||
// Property is only to be used in the new renderer.
|
||||
// It is necessary to add it here, otherwise it gets
|
||||
// filtered by view configs.
|
||||
// Property is only to be used in the new renderer.
|
||||
// It is necessary to add it here, otherwise it gets
|
||||
// filtered by view configs.
|
||||
}
|
||||
|
||||
RCT_CUSTOM_VIEW_PROPERTY(experimental_boxShadow, NSArray *, RCTView)
|
||||
typedef NSArray *BoxShadowArray; // Custom type to make the StaticViewConfigValidator Happy
|
||||
RCT_CUSTOM_VIEW_PROPERTY(boxShadow, BoxShadowArray, RCTView)
|
||||
{
|
||||
// Property is only to be used in the new renderer.
|
||||
// It is necessary to add it here, otherwise it gets
|
||||
// filtered by view configs.
|
||||
// Property is only to be used in the new renderer.
|
||||
// It is necessary to add it here, otherwise it gets
|
||||
// filtered by view configs.
|
||||
}
|
||||
|
||||
RCT_CUSTOM_VIEW_PROPERTY(experimental_mixBlendMode, NSString *, RCTView)
|
||||
|
||||
@@ -848,6 +848,26 @@ RCT_SCROLL_EVENT_HANDLER(scrollViewDidScrollToTop, onScrollToTop)
|
||||
RCT_FORWARD_SCROLL_EVENT(scrollViewDidEndZooming : scrollView withView : view atScale : scale);
|
||||
}
|
||||
|
||||
- (void)didMoveToWindow
|
||||
{
|
||||
[super didMoveToWindow];
|
||||
if (self.window == nil) {
|
||||
// Check if the ScrollView was in motion
|
||||
if (_scrollView.isDecelerating || !_scrollView.isTracking) {
|
||||
// Trigger the onMomentumScrollEnd event manually
|
||||
RCT_SEND_SCROLL_EVENT(onMomentumScrollEnd, nil);
|
||||
// We can't use the RCT_FORWARD_SCROLL_EVENT here beacuse the `_cmd` parameter passed
|
||||
// to `respondsToSelector` is the current method - so it will be `didMoveToWindow` - and not
|
||||
// `scrollViewDidEndDecelerating` that is passed.
|
||||
for (NSObject<UIScrollViewDelegate> *scrollViewListener in _scrollListeners) {
|
||||
if ([scrollViewListener respondsToSelector:@selector(scrollViewDidEndDecelerating:)]) {
|
||||
[scrollViewListener scrollViewDidEndDecelerating:_scrollView];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
|
||||
{
|
||||
// Fire a final scroll event
|
||||
|
||||
@@ -3314,6 +3314,15 @@ public final class com/facebook/react/modules/core/TimingModule : com/facebook/f
|
||||
public final class com/facebook/react/modules/core/TimingModule$Companion {
|
||||
}
|
||||
|
||||
public final class com/facebook/react/modules/debug/DevMenuModule : com/facebook/fbreact/specs/NativeDevMenuSpec {
|
||||
public fun <init> (Lcom/facebook/react/bridge/ReactApplicationContext;Lcom/facebook/react/devsupport/interfaces/DevSupportManager;)V
|
||||
public fun debugRemotely (Z)V
|
||||
public fun reload ()V
|
||||
public fun setHotLoadingEnabled (Z)V
|
||||
public fun setProfilingEnabled (Z)V
|
||||
public fun show ()V
|
||||
}
|
||||
|
||||
public final class com/facebook/react/modules/debug/DevSettingsModule : com/facebook/fbreact/specs/NativeDevSettingsSpec {
|
||||
public fun <init> (Lcom/facebook/react/bridge/ReactApplicationContext;Lcom/facebook/react/devsupport/interfaces/DevSupportManager;)V
|
||||
public fun addListener (Ljava/lang/String;)V
|
||||
@@ -4047,6 +4056,33 @@ public class com/facebook/react/shell/MainReactPackage$$ReactModuleInfoProvider
|
||||
public fun getReactModuleInfos ()Ljava/util/Map;
|
||||
}
|
||||
|
||||
public final class com/facebook/react/soloader/OpenSourceMergedSoMapping : com/facebook/soloader/ExternalSoMapping {
|
||||
public static final field INSTANCE Lcom/facebook/react/soloader/OpenSourceMergedSoMapping;
|
||||
public fun invokeJniOnload (Ljava/lang/String;)V
|
||||
public final fun libfabricjni_so ()I
|
||||
public final fun libhermes_executor_so ()I
|
||||
public final fun libhermesinstancejni_so ()I
|
||||
public final fun libhermestooling_so ()I
|
||||
public final fun libjscexecutor_so ()I
|
||||
public final fun libjscinstance_so ()I
|
||||
public final fun libjscruntime_so ()I
|
||||
public final fun libjsctooling_so ()I
|
||||
public final fun libjsijniprofiler_so ()I
|
||||
public final fun libjsinspector_so ()I
|
||||
public final fun libmapbufferjni_so ()I
|
||||
public final fun libreact_devsupportjni_so ()I
|
||||
public final fun libreact_featureflagsjni_so ()I
|
||||
public final fun libreact_newarchdefaults_so ()I
|
||||
public final fun libreactnative_so ()I
|
||||
public final fun libreactnativeblob_so ()I
|
||||
public final fun libreactnativejni_so ()I
|
||||
public final fun librninstance_so ()I
|
||||
public final fun libturbomodulejsijni_so ()I
|
||||
public final fun libuimanagerjni_so ()I
|
||||
public final fun libyoga_so ()I
|
||||
public fun mapLibName (Ljava/lang/String;)Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class com/facebook/react/touch/JSResponderHandler : com/facebook/react/touch/OnInterceptTouchEventListener {
|
||||
public fun <init> ()V
|
||||
public final fun clearJSResponder ()V
|
||||
|
||||
@@ -220,10 +220,20 @@ val preparePrefab by
|
||||
Pair(
|
||||
"../ReactCommon/react/renderer/observers/events/",
|
||||
"react/renderer/observers/events/"),
|
||||
// react_timing
|
||||
Pair("../ReactCommon/react/timing/", "react/timing/"),
|
||||
// yoga
|
||||
Pair("../ReactCommon/yoga/", ""),
|
||||
Pair("src/main/jni/first-party/yogajni/jni", ""),
|
||||
)),
|
||||
PrefabPreprocessingEntry("hermestooling",
|
||||
// hermes_executor
|
||||
Pair("../ReactCommon/hermes/inspector-modern/", "hermes/inspector-modern/")
|
||||
),
|
||||
PrefabPreprocessingEntry("jsctooling",
|
||||
// jsc
|
||||
Pair("../ReactCommon/jsc/", "jsc/")
|
||||
),
|
||||
))
|
||||
outputDir.set(prefabHeadersDir)
|
||||
}
|
||||
@@ -550,7 +560,6 @@ android {
|
||||
"src/main/res/views/alert",
|
||||
"src/main/res/views/modal",
|
||||
"src/main/res/views/uimanager"))
|
||||
kotlin.srcDir(project.file("../sdks/ossonly-soloader/src/main/java"))
|
||||
java.exclude("com/facebook/react/processing")
|
||||
java.exclude("com/facebook/react/module/processing")
|
||||
}
|
||||
@@ -580,6 +589,8 @@ android {
|
||||
prefab {
|
||||
create("jsi") { headers = File(prefabHeadersDir, "jsi").absolutePath }
|
||||
create("reactnative") { headers = File(prefabHeadersDir, "reactnative").absolutePath }
|
||||
create("hermestooling") { headers = File(prefabHeadersDir, "hermestooling").absolutePath }
|
||||
create("jsctooling") { headers = File(prefabHeadersDir, "jsctooling").absolutePath }
|
||||
}
|
||||
|
||||
publishing {
|
||||
@@ -598,11 +609,6 @@ android {
|
||||
tasks.withType<KotlinCompile>().configureEach { exclude("com/facebook/annotationprocessors/**") }
|
||||
|
||||
dependencies {
|
||||
implementation(libs.fresco)
|
||||
implementation(libs.fresco.middleware)
|
||||
implementation(libs.fresco.imagepipeline.okhttp3)
|
||||
implementation(libs.fresco.ui.common)
|
||||
|
||||
api(libs.androidx.appcompat)
|
||||
api(libs.androidx.appcompat.resources)
|
||||
api(libs.androidx.autofill)
|
||||
@@ -610,7 +616,12 @@ dependencies {
|
||||
api(libs.androidx.tracing)
|
||||
|
||||
api(libs.fbjni)
|
||||
api(libs.fresco)
|
||||
api(libs.fresco.imagepipeline.okhttp3)
|
||||
api(libs.fresco.middleware)
|
||||
api(libs.fresco.ui.common)
|
||||
api(libs.infer.annotation)
|
||||
api(libs.soloader)
|
||||
api(libs.yoga.proguard.annotations)
|
||||
|
||||
api(libs.jsr305)
|
||||
@@ -631,8 +642,6 @@ dependencies {
|
||||
testImplementation(libs.thoughtworks)
|
||||
}
|
||||
|
||||
configurations.all { exclude(group = "com.facebook.soloader") }
|
||||
|
||||
react {
|
||||
// TODO: The library name is chosen for parity with Fabric components & iOS
|
||||
// This should be changed to a more generic name, e.g. `ReactCoreSpec`.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
VERSION_NAME=1000.0.0
|
||||
VERSION_NAME=0.76.0-rc.3
|
||||
react.internal.publishingGroup=com.facebook.react
|
||||
|
||||
android.useAndroidX=true
|
||||
|
||||
@@ -315,8 +315,6 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
configurations.all { exclude(group = "com.facebook.soloader") }
|
||||
|
||||
afterEvaluate {
|
||||
if (!overrideHermesDir) {
|
||||
// If you're not specifying a Hermes Path override, we want to
|
||||
|
||||
+5
@@ -27,6 +27,7 @@ import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
import com.facebook.react.modules.core.ExceptionsManagerModule;
|
||||
import com.facebook.react.modules.core.HeadlessJsTaskSupportModule;
|
||||
import com.facebook.react.modules.core.TimingModule;
|
||||
import com.facebook.react.modules.debug.DevMenuModule;
|
||||
import com.facebook.react.modules.debug.DevSettingsModule;
|
||||
import com.facebook.react.modules.debug.SourceCodeModule;
|
||||
import com.facebook.react.modules.deviceinfo.DeviceInfoModule;
|
||||
@@ -49,6 +50,7 @@ import java.util.Map;
|
||||
AndroidInfoModule.class,
|
||||
DeviceEventManagerModule.class,
|
||||
DeviceInfoModule.class,
|
||||
DevMenuModule.class,
|
||||
DevSettingsModule.class,
|
||||
ExceptionsManagerModule.class,
|
||||
LogBoxModule.class,
|
||||
@@ -108,6 +110,7 @@ class CoreModulesPackage extends BaseReactPackage implements ReactPackageLogger
|
||||
AndroidInfoModule.class,
|
||||
DeviceEventManagerModule.class,
|
||||
DeviceInfoModule.class,
|
||||
DevMenuModule.class,
|
||||
DevSettingsModule.class,
|
||||
ExceptionsManagerModule.class,
|
||||
LogBoxModule.class,
|
||||
@@ -142,6 +145,8 @@ class CoreModulesPackage extends BaseReactPackage implements ReactPackageLogger
|
||||
return new AndroidInfoModule(reactContext);
|
||||
case DeviceEventManagerModule.NAME:
|
||||
return new DeviceEventManagerModule(reactContext, mHardwareBackBtnHandler);
|
||||
case DevMenuModule.NAME:
|
||||
return new DevMenuModule(reactContext, mReactInstanceManager.getDevSupportManager());
|
||||
case DevSettingsModule.NAME:
|
||||
return new DevSettingsModule(reactContext, mReactInstanceManager.getDevSupportManager());
|
||||
case ExceptionsManagerModule.NAME:
|
||||
|
||||
@@ -289,10 +289,7 @@ public class ReactDelegate {
|
||||
// With Bridgeless enabled, create and start the surface
|
||||
if (ReactFeatureFlags.enableBridgelessArchitecture) {
|
||||
if (mReactSurface == null) {
|
||||
// Create a ReactSurface
|
||||
mReactSurface = mReactHost.createSurface(mActivity, appKey, mLaunchOptions);
|
||||
// Set main Activity's content view
|
||||
mActivity.setContentView(mReactSurface.getView());
|
||||
}
|
||||
mReactSurface.start();
|
||||
} else {
|
||||
|
||||
+37
-4
@@ -17,6 +17,7 @@ import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import com.facebook.react.config.ReactFeatureFlags;
|
||||
import com.facebook.react.modules.core.PermissionAwareActivity;
|
||||
import com.facebook.react.modules.core.PermissionListener;
|
||||
|
||||
@@ -69,9 +70,15 @@ public class ReactFragment extends Fragment implements PermissionAwareActivity {
|
||||
if (mainComponentName == null) {
|
||||
throw new IllegalStateException("Cannot loadApp if component name is null");
|
||||
}
|
||||
mReactDelegate =
|
||||
new ReactDelegate(
|
||||
getActivity(), getReactNativeHost(), mainComponentName, launchOptions, fabricEnabled);
|
||||
if (ReactFeatureFlags.enableBridgelessArchitecture) {
|
||||
mReactDelegate =
|
||||
new ReactDelegate(
|
||||
getActivity(), getReactHost(), mainComponentName, launchOptions);
|
||||
} else {
|
||||
mReactDelegate =
|
||||
new ReactDelegate(
|
||||
getActivity(), getReactNativeHost(), mainComponentName, launchOptions, fabricEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,8 +88,34 @@ public class ReactFragment extends Fragment implements PermissionAwareActivity {
|
||||
* implement {@code ReactApplication} or you simply have a different mechanism for storing a
|
||||
* {@code ReactNativeHost}, e.g. as a static field somewhere.
|
||||
*/
|
||||
@Nullable
|
||||
protected ReactNativeHost getReactNativeHost() {
|
||||
return ((ReactApplication) getActivity().getApplication()).getReactNativeHost();
|
||||
ReactApplication application = ((ReactApplication) getActivity().getApplication());
|
||||
if (application != null) {
|
||||
return application.getReactNativeHost();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link ReactHost} used by this app. By default, assumes {@link
|
||||
* Activity#getApplication()} is an instance of {@link ReactApplication} and calls {@link
|
||||
* ReactApplication#getReactHost()}. Override this method if your application class does not
|
||||
* implement {@code ReactApplication} or you simply have a different mechanism for storing a
|
||||
* {@code ReactHost}, e.g. as a static field somewhere.
|
||||
*
|
||||
* <p>If you're using Old Architecture/Bridge Mode, this method should return null as {@link
|
||||
* ReactHost} is a Bridgeless-only concept.
|
||||
*/
|
||||
@Nullable
|
||||
protected ReactHost getReactHost() {
|
||||
ReactApplication application = ((ReactApplication) getActivity().getApplication());
|
||||
if (application != null) {
|
||||
return application.getReactHost();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected ReactDelegate getReactDelegate() {
|
||||
|
||||
+13
-14
@@ -169,26 +169,25 @@ public class HeadlessJsTaskContext {
|
||||
|
||||
/**
|
||||
* Finish a JS task. Doesn't actually stop the task on the JS side, only removes it from the list
|
||||
* of active tasks and notifies listeners. A task can only be finished once.
|
||||
* of active tasks and notifies listeners.
|
||||
*
|
||||
* @param taskId the unique id returned by {@link #startTask}.
|
||||
*/
|
||||
public synchronized void finishTask(final int taskId) {
|
||||
Assertions.assertCondition(
|
||||
mActiveTasks.remove(taskId), "Tried to finish non-existent task with id " + taskId + ".");
|
||||
Assertions.assertCondition(
|
||||
mActiveTaskConfigs.remove(taskId) != null,
|
||||
"Tried to remove non-existent task config with id " + taskId + ".");
|
||||
boolean removed = mActiveTasks.remove(taskId);
|
||||
mActiveTaskConfigs.remove(taskId);
|
||||
removeTimeout(taskId);
|
||||
UiThreadUtil.runOnUiThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (HeadlessJsTaskEventListener listener : mHeadlessJsTaskEventListeners) {
|
||||
listener.onHeadlessJsTaskFinish(taskId);
|
||||
if (removed) {
|
||||
UiThreadUtil.runOnUiThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (HeadlessJsTaskEventListener listener : mHeadlessJsTaskEventListeners) {
|
||||
listener.onHeadlessJsTaskFinish(taskId);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void removeTimeout(int taskId) {
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.modules.debug
|
||||
|
||||
import com.facebook.fbreact.specs.NativeDevMenuSpec
|
||||
import com.facebook.react.bridge.ReactApplicationContext
|
||||
import com.facebook.react.bridge.UiThreadUtil
|
||||
import com.facebook.react.devsupport.interfaces.DevSupportManager
|
||||
import com.facebook.react.module.annotations.ReactModule
|
||||
|
||||
/** Module that exposes the DevMenu to JS so that it can be used to programmatically open it. */
|
||||
@ReactModule(name = NativeDevMenuSpec.NAME)
|
||||
public class DevMenuModule(
|
||||
reactContext: ReactApplicationContext?,
|
||||
private val devSupportManager: DevSupportManager
|
||||
) : NativeDevMenuSpec(reactContext) {
|
||||
|
||||
override fun show() {
|
||||
if (devSupportManager.devSupportEnabled) {
|
||||
devSupportManager.showDevOptionsDialog()
|
||||
}
|
||||
}
|
||||
|
||||
override fun reload() {
|
||||
if (devSupportManager.devSupportEnabled) {
|
||||
UiThreadUtil.runOnUiThread { devSupportManager.handleReloadJS() }
|
||||
}
|
||||
}
|
||||
|
||||
override fun debugRemotely(enableDebug: Boolean) {
|
||||
devSupportManager.setRemoteJSDebugEnabled(enableDebug)
|
||||
}
|
||||
|
||||
override fun setProfilingEnabled(enabled: Boolean) {
|
||||
// iOS only
|
||||
}
|
||||
|
||||
override fun setHotLoadingEnabled(enabled: Boolean) {
|
||||
devSupportManager.setHotModuleReplacementEnabled(enabled)
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -15,8 +15,8 @@ import java.util.Map;
|
||||
|
||||
public class ReactNativeVersion {
|
||||
public static final Map<String, Object> VERSION = MapBuilder.<String, Object>of(
|
||||
"major", 1000,
|
||||
"minor", 0,
|
||||
"major", 0,
|
||||
"minor", 76,
|
||||
"patch", 0,
|
||||
"prerelease", null);
|
||||
"prerelease", "rc.3");
|
||||
}
|
||||
|
||||
+14
-9
@@ -23,6 +23,8 @@ import com.facebook.react.devsupport.HMRClient;
|
||||
import com.facebook.react.devsupport.ReactInstanceDevHelper;
|
||||
import com.facebook.react.devsupport.interfaces.DevSplitBundleCallback;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
import com.facebook.react.runtime.internal.bolts.Continuation;
|
||||
import com.facebook.react.runtime.internal.bolts.Task;
|
||||
|
||||
/**
|
||||
* An implementation of {@link com.facebook.react.devsupport.interfaces.DevSupportManager} that
|
||||
@@ -67,17 +69,20 @@ class BridgelessDevSupportManager extends DevSupportManagerBase {
|
||||
mReactHost
|
||||
.loadBundle(bundleLoader)
|
||||
.onSuccess(
|
||||
task -> {
|
||||
if (task.isCompleted()) {
|
||||
String bundleURL =
|
||||
getDevServerHelper().getDevServerSplitBundleURL(bundlePath);
|
||||
ReactContext reactContext = mReactHost.getCurrentReactContext();
|
||||
if (reactContext != null) {
|
||||
reactContext.getJSModule(HMRClient.class).registerBundle(bundleURL);
|
||||
new Continuation<Boolean, Void>() {
|
||||
@Override
|
||||
public Void then(Task<Boolean> task) {
|
||||
if (task.getResult().equals(Boolean.TRUE)) {
|
||||
String bundleURL =
|
||||
getDevServerHelper().getDevServerSplitBundleURL(bundlePath);
|
||||
ReactContext reactContext = mReactHost.getCurrentReactContext();
|
||||
if (reactContext != null) {
|
||||
reactContext.getJSModule(HMRClient.class).registerBundle(bundleURL);
|
||||
}
|
||||
callback.onSuccess();
|
||||
}
|
||||
callback.onSuccess();
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+5
@@ -23,6 +23,7 @@ import com.facebook.react.module.model.ReactModuleInfoProvider;
|
||||
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
import com.facebook.react.modules.core.ExceptionsManagerModule;
|
||||
import com.facebook.react.modules.debug.DevMenuModule;
|
||||
import com.facebook.react.modules.debug.DevSettingsModule;
|
||||
import com.facebook.react.modules.debug.SourceCodeModule;
|
||||
import com.facebook.react.modules.deviceinfo.DeviceInfoModule;
|
||||
@@ -35,6 +36,7 @@ import java.util.Map;
|
||||
nativeModules = {
|
||||
AndroidInfoModule.class,
|
||||
DeviceInfoModule.class,
|
||||
DevMenuModule.class,
|
||||
DevSettingsModule.class,
|
||||
SourceCodeModule.class,
|
||||
LogBoxModule.class,
|
||||
@@ -61,6 +63,8 @@ class CoreReactPackage extends BaseReactPackage {
|
||||
return new DeviceInfoModule(reactContext);
|
||||
case SourceCodeModule.NAME:
|
||||
return new SourceCodeModule(reactContext);
|
||||
case DevMenuModule.NAME:
|
||||
return new DevMenuModule(reactContext, mDevSupportManager);
|
||||
case DevSettingsModule.NAME:
|
||||
return new DevSettingsModule(reactContext, mDevSupportManager);
|
||||
case DeviceEventManagerModule.NAME:
|
||||
@@ -108,6 +112,7 @@ class CoreReactPackage extends BaseReactPackage {
|
||||
AndroidInfoModule.class,
|
||||
DeviceInfoModule.class,
|
||||
SourceCodeModule.class,
|
||||
DevMenuModule.class,
|
||||
DevSettingsModule.class,
|
||||
DeviceEventManagerModule.class,
|
||||
LogBoxModule.class,
|
||||
|
||||
+26
-21
@@ -9,6 +9,8 @@ package com.facebook.react.runtime;
|
||||
|
||||
import static com.facebook.infer.annotation.Assertions.assertNotNull;
|
||||
import static com.facebook.infer.annotation.ThreadConfined.UI;
|
||||
import static java.lang.Boolean.FALSE;
|
||||
import static java.lang.Boolean.TRUE;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
@@ -250,12 +252,13 @@ public class ReactHostImpl implements ReactHost {
|
||||
|
||||
detachSurface(surface);
|
||||
return callWithExistingReactInstance(
|
||||
method,
|
||||
reactInstance -> {
|
||||
log(method, "Execute");
|
||||
reactInstance.stopSurface(surface);
|
||||
},
|
||||
mBGExecutor);
|
||||
method,
|
||||
reactInstance -> {
|
||||
log(method, "Execute");
|
||||
reactInstance.stopSurface(surface);
|
||||
},
|
||||
mBGExecutor)
|
||||
.makeVoid();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -776,7 +779,7 @@ public class ReactHostImpl implements ReactHost {
|
||||
};
|
||||
}
|
||||
|
||||
/* package */ Task<Void> loadBundle(final JSBundleLoader bundleLoader) {
|
||||
/* package */ Task<Boolean> loadBundle(final JSBundleLoader bundleLoader) {
|
||||
final String method = "loadBundle()";
|
||||
log(method, "Schedule");
|
||||
|
||||
@@ -789,7 +792,7 @@ public class ReactHostImpl implements ReactHost {
|
||||
null);
|
||||
}
|
||||
|
||||
/* package */ Task<Void> registerSegment(
|
||||
/* package */ Task<Boolean> registerSegment(
|
||||
final int segmentId, final String path, final Callback callback) {
|
||||
final String method =
|
||||
"registerSegment(segmentId = \"" + segmentId + "\", path = \"" + path + "\")";
|
||||
@@ -825,7 +828,7 @@ public class ReactHostImpl implements ReactHost {
|
||||
* @param args Arguments to be passed to the function
|
||||
* @return A Task that will complete when the function call has been enqueued on the JS thread.
|
||||
*/
|
||||
/* package */ Task<Void> callFunctionOnModule(
|
||||
/* package */ Task<Boolean> callFunctionOnModule(
|
||||
final String moduleName, final String methodName, final NativeArray args) {
|
||||
final String method = "callFunctionOnModule(\"" + moduleName + "\", \"" + methodName + "\")";
|
||||
return callWithExistingReactInstance(
|
||||
@@ -947,9 +950,9 @@ public class ReactHostImpl implements ReactHost {
|
||||
}
|
||||
|
||||
/** Schedule work on a ReactInstance that is already created. */
|
||||
private Task<Void> callWithExistingReactInstance(
|
||||
private Task<Boolean> callWithExistingReactInstance(
|
||||
final String callingMethod,
|
||||
final ReactInstanceCalback callback,
|
||||
final ReactInstanceCalback continuation,
|
||||
@Nullable Executor executor) {
|
||||
final String method = "callWithExistingReactInstance(" + callingMethod + ")";
|
||||
|
||||
@@ -959,18 +962,19 @@ public class ReactHostImpl implements ReactHost {
|
||||
|
||||
return mCreateReactInstanceTaskRef
|
||||
.get()
|
||||
.continueWith(
|
||||
.onSuccess(
|
||||
task -> {
|
||||
final ReactInstance reactInstance =
|
||||
ReactNativeFeatureFlags.completeReactInstanceCreationOnBgThreadOnAndroid()
|
||||
? task.getResult()
|
||||
: mReactInstance;
|
||||
if (reactInstance == null || task.isFaulted()) {
|
||||
if (reactInstance == null) {
|
||||
raiseSoftException(method, "Execute: reactInstance is null. Dropping work.");
|
||||
} else {
|
||||
callback.then(reactInstance);
|
||||
return FALSE;
|
||||
}
|
||||
return null;
|
||||
|
||||
continuation.then(reactInstance);
|
||||
return TRUE;
|
||||
},
|
||||
executor);
|
||||
}
|
||||
@@ -978,7 +982,7 @@ public class ReactHostImpl implements ReactHost {
|
||||
/** Create a ReactInstance if it doesn't exist already, and schedule work on it. */
|
||||
private Task<Void> callAfterGetOrCreateReactInstance(
|
||||
final String callingMethod,
|
||||
final ReactInstanceCalback callback,
|
||||
final ReactInstanceCalback runnable,
|
||||
@Nullable Executor executor) {
|
||||
final String method = "callAfterGetOrCreateReactInstance(" + callingMethod + ")";
|
||||
|
||||
@@ -987,17 +991,18 @@ public class ReactHostImpl implements ReactHost {
|
||||
}
|
||||
|
||||
return getOrCreateReactInstance()
|
||||
.continueWith(
|
||||
.onSuccess(
|
||||
task -> {
|
||||
final ReactInstance reactInstance =
|
||||
ReactNativeFeatureFlags.completeReactInstanceCreationOnBgThreadOnAndroid()
|
||||
? task.getResult()
|
||||
: mReactInstance;
|
||||
if (reactInstance == null || task.isFaulted()) {
|
||||
if (reactInstance == null) {
|
||||
raiseSoftException(method, "Execute: reactInstance is null. Dropping work.");
|
||||
} else {
|
||||
callback.then(reactInstance);
|
||||
return null;
|
||||
}
|
||||
|
||||
runnable.then(reactInstance);
|
||||
return null;
|
||||
},
|
||||
executor)
|
||||
|
||||
+6
-4
@@ -5,7 +5,9 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.soloader
|
||||
package com.facebook.react.soloader
|
||||
|
||||
import com.facebook.soloader.ExternalSoMapping
|
||||
|
||||
/**
|
||||
* This class is a manually created MergedSoMapping.
|
||||
@@ -16,9 +18,9 @@ package com.facebook.soloader
|
||||
* entry in the [invokeJniOnload] method, the [mapLibName] method as well as a new external function
|
||||
* that will take care of calling the JNI_OnLoad method.
|
||||
*/
|
||||
public object MergedSoMapping {
|
||||
public object OpenSourceMergedSoMapping : ExternalSoMapping {
|
||||
|
||||
public fun mapLibName(input: String): String =
|
||||
override public fun mapLibName(input: String): String =
|
||||
when (input) {
|
||||
"fabricjni",
|
||||
"jsinspector",
|
||||
@@ -47,7 +49,7 @@ public object MergedSoMapping {
|
||||
else -> input
|
||||
}
|
||||
|
||||
public fun invokeJniOnload(libraryName: String): Unit {
|
||||
override public fun invokeJniOnload(libraryName: String): Unit {
|
||||
when (libraryName) {
|
||||
"fabricjni" -> libfabricjni_so()
|
||||
"hermes_executor" -> libhermes_executor_so()
|
||||
+2
-2
@@ -136,8 +136,8 @@ public object ViewProps {
|
||||
public const val BORDER_START_COLOR: String = "borderStartColor"
|
||||
public const val BORDER_END_COLOR: String = "borderEndColor"
|
||||
public const val ON_LAYOUT: String = "onLayout"
|
||||
public const val BOX_SHADOW: String = "experimental_boxShadow"
|
||||
public const val FILTER: String = "experimental_filter"
|
||||
public const val BOX_SHADOW: String = "boxShadow"
|
||||
public const val FILTER: String = "filter"
|
||||
public const val MIX_BLEND_MODE: String = "experimental_mixBlendMode"
|
||||
public const val TRANSFORM: String = "transform"
|
||||
public const val TRANSFORM_ORIGIN: String = "transformOrigin"
|
||||
|
||||
+1
-1
@@ -446,7 +446,7 @@ public class TextLayoutManager {
|
||||
? paragraphAttributes.getBoolean(PA_KEY_INCLUDE_FONT_PADDING)
|
||||
: DEFAULT_INCLUDE_FONT_PADDING;
|
||||
int hyphenationFrequency =
|
||||
TextAttributeProps.getTextBreakStrategy(
|
||||
TextAttributeProps.getHyphenationFrequency(
|
||||
paragraphAttributes.getString(PA_KEY_HYPHENATION_FREQUENCY));
|
||||
boolean adjustFontSizeToFit =
|
||||
paragraphAttributes.contains(PA_KEY_ADJUST_FONT_SIZE_TO_FIT)
|
||||
|
||||
+2
-1
@@ -24,7 +24,8 @@
|
||||
|
||||
// Class with mapping that will be generated by buck or manually edited by
|
||||
// users.
|
||||
static const char* invoke_class_name = "com/facebook/soloader/MergedSoMapping";
|
||||
static const char* invoke_class_name =
|
||||
"com/facebook/react/soloader/OpenSourceMergedSoMapping";
|
||||
|
||||
// Stub pre-merged library to ensure that our custom section gets created
|
||||
// when we merge a group of native libraries with no JNI_OnLoad. We don't
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user