mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Compare commits
48
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c5ecc6ffff | ||
|
|
cef001713f | ||
|
|
572f710492 | ||
|
|
474861f4e7 | ||
|
|
048b537800 | ||
|
|
2a50905c0b | ||
|
|
14398752e3 | ||
|
|
6d00239e49 | ||
|
|
cae662bfea | ||
|
|
77305cadf0 | ||
|
|
925330bb83 | ||
|
|
d68013dd71 | ||
|
|
80f5b6c110 | ||
|
|
99ef72cad7 | ||
|
|
b4d1fcfb2f | ||
|
|
13cefd396c | ||
|
|
e7bfa1fc2e | ||
|
|
6a10d5dfd3 | ||
|
|
60da5071a6 | ||
|
|
e3218a0d96 | ||
|
|
2c89e51507 | ||
|
|
6f00f5f6b8 | ||
|
|
05f5cb534f | ||
|
|
79e38e7d8e | ||
|
|
b86f16aa4e | ||
|
|
4d9385d531 | ||
|
|
8c11d3ffce | ||
|
|
89eb287be1 | ||
|
|
3c3b4cf575 | ||
|
|
8f954b3659 | ||
|
|
2bf7f1046d | ||
|
|
5b4816741b | ||
|
|
39e5a83062 | ||
|
|
fe348ab53d | ||
|
|
0fd83e4786 | ||
|
|
e97baa6066 | ||
|
|
76557f00d7 | ||
|
|
4693170d63 | ||
|
|
51dcb0195b | ||
|
|
203f3e3399 | ||
|
|
e7c289b56e | ||
|
|
3cfbae6540 | ||
|
|
3fd98d95ef | ||
|
|
c194ed2dbb | ||
|
|
93bbab3878 | ||
|
|
1a305fd79b | ||
|
|
45a43241cd | ||
|
|
041c392ec9 |
@@ -8,6 +8,7 @@
|
||||
[maven_repositories]
|
||||
central = https://repo1.maven.org/maven2
|
||||
google = https://maven.google.com/
|
||||
jcenter = https://jcenter.bintray.com/
|
||||
|
||||
[alias]
|
||||
rntester = //RNTester/android/app:app
|
||||
|
||||
@@ -83,7 +83,7 @@ function reportException(e: ExtendedError, isFatal: boolean) {
|
||||
e.jsEngine == null ? message : `${message}, js engine: ${e.jsEngine}`;
|
||||
|
||||
const isHandledByLogBox =
|
||||
e.forceRedbox !== true && global.__reactExperimentalLogBox;
|
||||
e.forceRedbox !== true && global.__unstable_isLogBoxEnabled === true;
|
||||
|
||||
const data = preprocessException({
|
||||
message,
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
/**
|
||||
* @generated by scripts/bump-oss-version.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @generated by scripts/bump-oss-version.js
|
||||
* @flow
|
||||
*/
|
||||
|
||||
exports.version = {
|
||||
major: 0,
|
||||
minor: 0,
|
||||
minor: 62,
|
||||
patch: 0,
|
||||
prerelease: null,
|
||||
prerelease: 'rc.2',
|
||||
};
|
||||
|
||||
@@ -1671,6 +1671,33 @@ namespace facebook {
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativeLogBoxSpecJSI_show(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "show", @selector(show), args, count);
|
||||
}
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativeLogBoxSpecJSI_hide(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "hide", @selector(hide), args, count);
|
||||
}
|
||||
|
||||
|
||||
NativeLogBoxSpecJSI::NativeLogBoxSpecJSI(id<RCTTurboModule> instance, std::shared_ptr<CallInvoker> jsInvoker)
|
||||
: ObjCTurboModule("LogBox", instance, jsInvoker) {
|
||||
|
||||
methodMap_["show"] = MethodMetadata {0, __hostFunction_NativeLogBoxSpecJSI_show};
|
||||
|
||||
|
||||
methodMap_["hide"] = MethodMetadata {0, __hostFunction_NativeLogBoxSpecJSI_hide};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
|
||||
@@ -1771,6 +1771,25 @@ namespace facebook {
|
||||
};
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@protocol NativeLogBoxSpec <RCTBridgeModule, RCTTurboModule>
|
||||
|
||||
- (void)show;
|
||||
- (void)hide;
|
||||
|
||||
@end
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
/**
|
||||
* ObjC++ class for module 'LogBox'
|
||||
*/
|
||||
|
||||
class JSI_EXPORT NativeLogBoxSpecJSI : public ObjCTurboModule {
|
||||
public:
|
||||
NativeLogBoxSpecJSI(id<RCTTurboModule> instance, std::shared_ptr<CallInvoker> jsInvoker);
|
||||
|
||||
};
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@protocol NativeModalManagerSpec <RCTBridgeModule, RCTTurboModule>
|
||||
|
||||
- (void)addListener:(NSString *)eventName;
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
|
||||
@protocol RCTImageLoaderWithAttributionProtocol<RCTImageLoaderProtocol>
|
||||
|
||||
// TODO (T61325135): Remove C++ checks
|
||||
#ifdef __cplusplus
|
||||
/**
|
||||
* Same as the variant in RCTImageURLLoaderProtocol, but allows passing attribution
|
||||
* information that each image URL loader can process.
|
||||
@@ -25,5 +27,6 @@
|
||||
progressBlock:(RCTImageLoaderProgressBlock)progressBlock
|
||||
partialLoadBlock:(RCTImageLoaderPartialLoadBlock)partialLoadBlock
|
||||
completionBlock:(RCTImageLoaderCompletionBlock)completionBlock;
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#import <React/RCTImageURLLoader.h>
|
||||
|
||||
// TODO (T61325135): Remove C++ checks
|
||||
#ifdef __cplusplus
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
@@ -17,6 +19,7 @@ struct ImageURLLoaderAttribution {
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Same as the RCTImageURLLoader interface, but allows passing in optional `attribution` information.
|
||||
@@ -24,6 +27,8 @@ struct ImageURLLoaderAttribution {
|
||||
*/
|
||||
@protocol RCTImageURLLoaderWithAttribution <RCTImageURLLoader>
|
||||
|
||||
// TODO (T61325135): Remove C++ checks
|
||||
#ifdef __cplusplus
|
||||
/**
|
||||
* Same as the RCTImageURLLoader variant above, but allows optional `attribution` information.
|
||||
*/
|
||||
@@ -35,5 +40,6 @@ struct ImageURLLoaderAttribution {
|
||||
progressHandler:(RCTImageLoaderProgressBlock)progressHandler
|
||||
partialLoadHandler:(RCTImageLoaderPartialLoadBlock)partialLoadHandler
|
||||
completionHandler:(RCTImageLoaderCompletionBlock)completionHandler;
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
('use strict');
|
||||
|
||||
import * as React from 'react';
|
||||
import LogBoxLog from './LogBoxLog';
|
||||
import {parseLogBoxException} from './parseLogBoxLog';
|
||||
import type {LogLevel} from './LogBoxLog';
|
||||
@@ -21,7 +22,7 @@ import type {
|
||||
} from './parseLogBoxLog';
|
||||
import parseErrorStack from '../../Core/Devtools/parseErrorStack';
|
||||
import type {ExtendedError} from '../../Core/Devtools/parseErrorStack';
|
||||
|
||||
import NativeLogBox from '../../NativeModules/specs/NativeLogBox';
|
||||
export type LogBoxLogs = Set<LogBoxLog>;
|
||||
export type LogData = $ReadOnly<{|
|
||||
level: LogLevel,
|
||||
@@ -73,7 +74,7 @@ let warningFilter: WarningFilter = function(format) {
|
||||
return {
|
||||
finalFormat: format,
|
||||
forceDialogImmediately: false,
|
||||
suppressDialog_LEGACY: false,
|
||||
suppressDialog_LEGACY: true,
|
||||
suppressCompletely: false,
|
||||
monitorEvent: 'unknown',
|
||||
monitorListVersion: 0,
|
||||
@@ -85,20 +86,6 @@ const LOGBOX_ERROR_MESSAGE =
|
||||
'An error was thrown when attempting to render log messages via LogBox.';
|
||||
|
||||
function getNextState() {
|
||||
const logArray = Array.from(logs);
|
||||
let index = logArray.length - 1;
|
||||
while (index >= 0) {
|
||||
// The latest syntax error is selected and displayed before all other logs.
|
||||
if (logArray[index].level === 'syntax') {
|
||||
return {
|
||||
logs,
|
||||
isDisabled: _isDisabled,
|
||||
selectedLogIndex: index,
|
||||
};
|
||||
}
|
||||
index -= 1;
|
||||
}
|
||||
|
||||
return {
|
||||
logs,
|
||||
isDisabled: _isDisabled,
|
||||
@@ -174,9 +161,10 @@ function appendNewLog(newLog) {
|
||||
let addPendingLog = () => {
|
||||
logs.add(newLog);
|
||||
if (_selectedIndex <= 0) {
|
||||
_selectedIndex = logs.size - 1;
|
||||
setSelectedLog(logs.size - 1);
|
||||
} else {
|
||||
handleUpdate();
|
||||
}
|
||||
handleUpdate();
|
||||
addPendingLog = null;
|
||||
};
|
||||
|
||||
@@ -190,8 +178,14 @@ function appendNewLog(newLog) {
|
||||
if (addPendingLog && status !== 'PENDING') {
|
||||
addPendingLog();
|
||||
clearTimeout(optimisticTimeout);
|
||||
} else if (status !== 'PENDING') {
|
||||
// The log has already been added but we need to trigger a render.
|
||||
handleUpdate();
|
||||
}
|
||||
});
|
||||
} else if (newLog.level === 'syntax') {
|
||||
logs.add(newLog);
|
||||
setSelectedLog(logs.size - 1);
|
||||
} else {
|
||||
logs.add(newLog);
|
||||
handleUpdate();
|
||||
@@ -255,21 +249,42 @@ export function symbolicateLogLazy(log: LogBoxLog) {
|
||||
export function clear(): void {
|
||||
if (logs.size > 0) {
|
||||
logs = new Set();
|
||||
_selectedIndex = -1;
|
||||
handleUpdate();
|
||||
setSelectedLog(-1);
|
||||
}
|
||||
}
|
||||
|
||||
export function setSelectedLog(index: number): void {
|
||||
_selectedIndex = index;
|
||||
export function setSelectedLog(proposedNewIndex: number): void {
|
||||
const oldIndex = _selectedIndex;
|
||||
let newIndex = proposedNewIndex;
|
||||
|
||||
const logArray = Array.from(logs);
|
||||
let index = logArray.length - 1;
|
||||
while (index >= 0) {
|
||||
// The latest syntax error is selected and displayed before all other logs.
|
||||
if (logArray[index].level === 'syntax') {
|
||||
newIndex = index;
|
||||
break;
|
||||
}
|
||||
index -= 1;
|
||||
}
|
||||
_selectedIndex = newIndex;
|
||||
handleUpdate();
|
||||
if (NativeLogBox) {
|
||||
setTimeout(() => {
|
||||
if (oldIndex < 0 && newIndex >= 0) {
|
||||
NativeLogBox.show();
|
||||
} else if (oldIndex >= 0 && newIndex < 0) {
|
||||
NativeLogBox.hide();
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
export function clearWarnings(): void {
|
||||
const newLogs = Array.from(logs).filter(log => log.level !== 'warn');
|
||||
if (newLogs.length !== logs.size) {
|
||||
logs = new Set(newLogs);
|
||||
_selectedIndex = -1;
|
||||
setSelectedLog(-1);
|
||||
handleUpdate();
|
||||
}
|
||||
}
|
||||
@@ -280,8 +295,7 @@ export function clearErrors(): void {
|
||||
);
|
||||
if (newLogs.length !== logs.size) {
|
||||
logs = new Set(newLogs);
|
||||
_selectedIndex = -1;
|
||||
handleUpdate();
|
||||
setSelectedLog(-1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -369,3 +383,97 @@ export function observe(observer: Observer): Subscription {
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
type Props = $ReadOnly<{||}>;
|
||||
type State = $ReadOnly<{|
|
||||
logs: LogBoxLogs,
|
||||
isDisabled: boolean,
|
||||
hasError: boolean,
|
||||
selectedLogIndex: number,
|
||||
|}>;
|
||||
|
||||
type SubscribedComponent = React.AbstractComponent<
|
||||
$ReadOnly<{|
|
||||
logs: $ReadOnlyArray<LogBoxLog>,
|
||||
isDisabled: boolean,
|
||||
selectedLogIndex: number,
|
||||
|}>,
|
||||
>;
|
||||
|
||||
export function withSubscription(
|
||||
WrappedComponent: SubscribedComponent,
|
||||
): React.AbstractComponent<{||}> {
|
||||
class LogBoxStateSubscription extends React.Component<Props, State> {
|
||||
static getDerivedStateFromError() {
|
||||
return {hasError: true};
|
||||
}
|
||||
|
||||
componentDidCatch(err: Error, errorInfo: {componentStack: string, ...}) {
|
||||
reportLogBoxError(err, errorInfo.componentStack);
|
||||
}
|
||||
|
||||
_subscription: ?Subscription;
|
||||
|
||||
state = {
|
||||
logs: new Set(),
|
||||
isDisabled: false,
|
||||
hasError: false,
|
||||
selectedLogIndex: -1,
|
||||
};
|
||||
|
||||
render(): React.Node {
|
||||
if (this.state.hasError) {
|
||||
// This happens when the component failed to render, in which case we delegate to the native redbox.
|
||||
// We can't show anyback fallback UI here, because the error may be with <View> or <Text>.
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<WrappedComponent
|
||||
logs={Array.from(this.state.logs)}
|
||||
isDisabled={this.state.isDisabled}
|
||||
selectedLogIndex={this.state.selectedLogIndex}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
this._subscription = observe(data => {
|
||||
this.setState(data);
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount(): void {
|
||||
if (this._subscription != null) {
|
||||
this._subscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
_handleDismiss = (): void => {
|
||||
// Here we handle the cases when the log is dismissed and it
|
||||
// was either the last log, or when the current index
|
||||
// is now outside the bounds of the log array.
|
||||
const {selectedLogIndex, logs: stateLogs} = this.state;
|
||||
const logsArray = Array.from(stateLogs);
|
||||
if (selectedLogIndex != null) {
|
||||
if (logsArray.length - 1 <= 0) {
|
||||
setSelectedLog(-1);
|
||||
} else if (selectedLogIndex >= logsArray.length - 1) {
|
||||
setSelectedLog(selectedLogIndex - 1);
|
||||
}
|
||||
|
||||
dismiss(logsArray[selectedLogIndex]);
|
||||
}
|
||||
};
|
||||
|
||||
_handleMinimize = (): void => {
|
||||
setSelectedLog(-1);
|
||||
};
|
||||
|
||||
_handleSetSelectedLog = (index: number): void => {
|
||||
setSelectedLog(index);
|
||||
};
|
||||
}
|
||||
|
||||
return LogBoxStateSubscription;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,13 @@ function getLogBoxLog() {
|
||||
message: {content: '...', substitutions: []},
|
||||
stack: createStack(['A', 'B', 'C']),
|
||||
category: 'Message category...',
|
||||
componentStack: [{component: 'LogBoxLog', location: 'LogBoxLog.js:1'}],
|
||||
componentStack: [
|
||||
{
|
||||
content: 'LogBoxLog',
|
||||
fileName: 'LogBoxLog.js',
|
||||
location: {column: -1, row: 1},
|
||||
},
|
||||
],
|
||||
codeFrame: {
|
||||
fileName: '/path/to/RKJSModules/Apps/CrashReact/CrashReactApp.js',
|
||||
location: {row: 199, column: 0},
|
||||
@@ -69,7 +75,11 @@ describe('LogBoxLog', () => {
|
||||
expect(log.stack).toEqual(createStack(['A', 'B', 'C']));
|
||||
expect(log.category).toEqual('Message category...');
|
||||
expect(log.componentStack).toEqual([
|
||||
{component: 'LogBoxLog', location: 'LogBoxLog.js:1'},
|
||||
{
|
||||
content: 'LogBoxLog',
|
||||
fileName: 'LogBoxLog.js',
|
||||
location: {column: -1, row: 1},
|
||||
},
|
||||
]);
|
||||
expect(log.codeFrame).toEqual({
|
||||
fileName: '/path/to/RKJSModules/Apps/CrashReact/CrashReactApp.js',
|
||||
|
||||
@@ -117,8 +117,16 @@ describe('parseLogBoxLog', () => {
|
||||
]),
|
||||
).toEqual({
|
||||
componentStack: [
|
||||
{component: 'MyComponent', location: 'filename.js:1'},
|
||||
{component: 'MyOtherComponent', location: 'filename2.js:1'},
|
||||
{
|
||||
content: 'MyComponent',
|
||||
fileName: 'filename.js',
|
||||
location: {column: -1, row: 1},
|
||||
},
|
||||
{
|
||||
content: 'MyOtherComponent',
|
||||
fileName: 'filename2.js',
|
||||
location: {column: -1, row: 1},
|
||||
},
|
||||
],
|
||||
category:
|
||||
'Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?%s',
|
||||
@@ -143,8 +151,16 @@ describe('parseLogBoxLog', () => {
|
||||
]),
|
||||
).toEqual({
|
||||
componentStack: [
|
||||
{component: 'MyComponent', location: 'filename.js:1'},
|
||||
{component: 'MyOtherComponent', location: 'filename2.js:1'},
|
||||
{
|
||||
content: 'MyComponent',
|
||||
fileName: 'filename.js',
|
||||
location: {column: -1, row: 1},
|
||||
},
|
||||
{
|
||||
content: 'MyOtherComponent',
|
||||
fileName: 'filename2.js',
|
||||
location: {column: -1, row: 1},
|
||||
},
|
||||
],
|
||||
category: 'Some kind of message',
|
||||
message: {
|
||||
@@ -164,8 +180,16 @@ describe('parseLogBoxLog', () => {
|
||||
]),
|
||||
).toEqual({
|
||||
componentStack: [
|
||||
{component: 'MyComponent', location: 'filename.js:1'},
|
||||
{component: 'MyOtherComponent', location: 'filename2.js:1'},
|
||||
{
|
||||
content: 'MyComponent',
|
||||
fileName: 'filename.js',
|
||||
location: {column: -1, row: 1},
|
||||
},
|
||||
{
|
||||
content: 'MyOtherComponent',
|
||||
fileName: 'filename2.js',
|
||||
location: {column: -1, row: 1},
|
||||
},
|
||||
],
|
||||
category:
|
||||
'Some kind of message Some other kind of message Some third kind of message',
|
||||
@@ -418,12 +442,14 @@ Please follow the instructions at: fburl.com/rn-remote-assets`,
|
||||
},
|
||||
componentStack: [
|
||||
{
|
||||
component: 'MyComponent',
|
||||
location: 'filename.js:1',
|
||||
content: 'MyComponent',
|
||||
fileName: 'filename.js',
|
||||
location: {column: -1, row: 1},
|
||||
},
|
||||
{
|
||||
component: 'MyOtherComponent',
|
||||
location: 'filename2.js:1',
|
||||
content: 'MyOtherComponent',
|
||||
fileName: 'filename2.js',
|
||||
location: {column: -1, row: 1},
|
||||
},
|
||||
],
|
||||
stack: [
|
||||
|
||||
@@ -42,12 +42,7 @@ export type Message = $ReadOnly<{|
|
||||
>,
|
||||
|}>;
|
||||
|
||||
export type ComponentStack = $ReadOnlyArray<
|
||||
$ReadOnly<{|
|
||||
component: string,
|
||||
location: string,
|
||||
|}>,
|
||||
>;
|
||||
export type ComponentStack = $ReadOnlyArray<CodeFrame>;
|
||||
|
||||
const SUBSTITUTION = UTFSequence.BOM + '%s';
|
||||
|
||||
@@ -127,6 +122,7 @@ export function parseCategory(
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function parseComponentStack(message: string): ComponentStack {
|
||||
return message
|
||||
.split(/\n {4}in /g)
|
||||
@@ -134,11 +130,17 @@ export function parseComponentStack(message: string): ComponentStack {
|
||||
if (!s) {
|
||||
return null;
|
||||
}
|
||||
let [component, location] = s.split(/ \(at /);
|
||||
if (!location) {
|
||||
[component, location] = s.split(/ \(/);
|
||||
const match = s.match(/(.*) \(at (.*\.js):([\d]+)\)/);
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
return {component, location: location && location.replace(')', '')};
|
||||
|
||||
let [content, fileName, row] = match.slice(1);
|
||||
return {
|
||||
content,
|
||||
fileName,
|
||||
location: {column: -1, row: parseInt(row, 10)},
|
||||
};
|
||||
})
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
+28
-98
@@ -10,26 +10,14 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as React from 'react';
|
||||
import Platform from '../Utilities/Platform';
|
||||
import RCTLog from '../Utilities/RCTLog';
|
||||
import LogBoxContainer from './UI/LogBoxContainer';
|
||||
import * as LogBoxData from './Data/LogBoxData';
|
||||
import {parseLogBoxLog} from './Data/parseLogBoxLog';
|
||||
|
||||
import type {LogBoxLogs, Subscription, IgnorePattern} from './Data/LogBoxData';
|
||||
import type {IgnorePattern} from './Data/LogBoxData';
|
||||
|
||||
import LogBoxLog from './Data/LogBoxLog';
|
||||
|
||||
type Props = $ReadOnly<{||}>;
|
||||
type State = {|
|
||||
logs: LogBoxLogs,
|
||||
isDisabled: boolean,
|
||||
hasError: boolean,
|
||||
selectedLogIndex: number,
|
||||
|};
|
||||
|
||||
let LogBoxComponent;
|
||||
let LogBox;
|
||||
|
||||
/**
|
||||
* LogBox displays logs in the app.
|
||||
@@ -48,25 +36,26 @@ if (__DEV__) {
|
||||
warnImpl(...args);
|
||||
};
|
||||
|
||||
LogBoxComponent = class LogBox extends React.Component<Props, State> {
|
||||
static getDerivedStateFromError() {
|
||||
return {hasError: true};
|
||||
}
|
||||
|
||||
componentDidCatch(err, errorInfo) {
|
||||
LogBoxData.reportLogBoxError(err, errorInfo.componentStack);
|
||||
}
|
||||
|
||||
LogBox = {
|
||||
// TODO: deprecated, replace with ignoreLogs
|
||||
static ignoreWarnings(patterns: $ReadOnlyArray<IgnorePattern>): void {
|
||||
ignoreWarnings: (patterns: $ReadOnlyArray<IgnorePattern>): void => {
|
||||
LogBox.ignoreLogs(patterns);
|
||||
}
|
||||
},
|
||||
|
||||
static ignoreLogs(patterns: $ReadOnlyArray<IgnorePattern>): void {
|
||||
ignoreLogs: (patterns: $ReadOnlyArray<IgnorePattern>): void => {
|
||||
LogBoxData.addIgnorePatterns(patterns);
|
||||
}
|
||||
},
|
||||
|
||||
uninstall: (): void => {
|
||||
errorImpl = error;
|
||||
warnImpl = warn;
|
||||
delete (console: any).disableLogBox;
|
||||
},
|
||||
|
||||
install: (): void => {
|
||||
// Trigger lazy initialization of module.
|
||||
require('../NativeModules/specs/NativeLogBox');
|
||||
|
||||
static install(): void {
|
||||
errorImpl = function(...args) {
|
||||
registerError(...args);
|
||||
};
|
||||
@@ -92,62 +81,7 @@ if (__DEV__) {
|
||||
RCTLog.setWarningHandler((...args) => {
|
||||
registerWarning(...args);
|
||||
});
|
||||
}
|
||||
|
||||
static uninstall(): void {
|
||||
errorImpl = error;
|
||||
warnImpl = warn;
|
||||
delete (console: any).disableLogBox;
|
||||
}
|
||||
|
||||
_subscription: ?Subscription;
|
||||
|
||||
state = {
|
||||
logs: new Set(),
|
||||
isDisabled: false,
|
||||
hasError: false,
|
||||
selectedLogIndex: -1,
|
||||
};
|
||||
|
||||
render(): React.Node {
|
||||
if (this.state.hasError) {
|
||||
// This happens when the component failed to render, in which case we delegate to the native redbox.
|
||||
// We can't show anyback fallback UI here, because the error may be with <View> or <Text>.
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.state.logs == null ? null : (
|
||||
<LogBoxContainer
|
||||
onDismiss={this._handleDismiss}
|
||||
onDismissWarns={LogBoxData.clearWarnings}
|
||||
onDismissErrors={LogBoxData.clearErrors}
|
||||
logs={this.state.logs}
|
||||
isDisabled={this.state.isDisabled}
|
||||
selectedLogIndex={this.state.selectedLogIndex}
|
||||
setSelectedLog={this._handleSetSelectedLog}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
this._subscription = LogBoxData.observe(data => {
|
||||
this.setState(data);
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount(): void {
|
||||
if (this._subscription != null) {
|
||||
this._subscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
_handleDismiss(log: LogBoxLog): void {
|
||||
LogBoxData.dismiss(log);
|
||||
}
|
||||
|
||||
_handleSetSelectedLog(index: number): void {
|
||||
LogBoxData.setSelectedLog(index);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const isRCTLogAdviceWarning = (...args) => {
|
||||
@@ -227,31 +161,27 @@ if (__DEV__) {
|
||||
}
|
||||
};
|
||||
} else {
|
||||
LogBoxComponent = class extends React.Component<Props, State> {
|
||||
LogBox = {
|
||||
// TODO: deprecated, replace with ignoreLogs
|
||||
static ignoreWarnings(patterns: $ReadOnlyArray<IgnorePattern>): void {
|
||||
ignoreWarnings: (patterns: $ReadOnlyArray<IgnorePattern>): void => {
|
||||
// Do nothing.
|
||||
}
|
||||
},
|
||||
|
||||
static ignoreLogs(patterns: $ReadOnlyArray<IgnorePattern>): void {
|
||||
ignoreLogs: (patterns: $ReadOnlyArray<IgnorePattern>): void => {
|
||||
// Do nothing.
|
||||
}
|
||||
},
|
||||
|
||||
static install(): void {
|
||||
install: (): void => {
|
||||
// Do nothing.
|
||||
}
|
||||
},
|
||||
|
||||
static uninstall(): void {
|
||||
uninstall: (): void => {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
render(): React.Node {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = (LogBoxComponent: Class<React.Component<Props, State>> & {
|
||||
module.exports = (LogBox: {
|
||||
// TODO: deprecated, replace with ignoreLogs
|
||||
ignoreWarnings($ReadOnlyArray<IgnorePattern>): void,
|
||||
ignoreLogs($ReadOnlyArray<IgnorePattern>): void,
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as React from 'react';
|
||||
import {View, StyleSheet} from 'react-native';
|
||||
import * as LogBoxData from './Data/LogBoxData';
|
||||
import LogBoxInspector from './UI/LogBoxInspector';
|
||||
import type LogBoxLog from './Data/LogBoxLog';
|
||||
|
||||
type Props = $ReadOnly<{|
|
||||
logs: $ReadOnlyArray<LogBoxLog>,
|
||||
selectedLogIndex: number,
|
||||
isDisabled?: ?boolean,
|
||||
|}>;
|
||||
|
||||
export class _LogBoxInspectorContainer extends React.Component<Props> {
|
||||
render(): React.Node {
|
||||
return (
|
||||
<View style={StyleSheet.absoluteFill}>
|
||||
<LogBoxInspector
|
||||
onDismiss={this._handleDismiss}
|
||||
onMinimize={this._handleMinimize}
|
||||
onChangeSelectedIndex={this._handleSetSelectedLog}
|
||||
logs={this.props.logs}
|
||||
selectedIndex={this.props.selectedLogIndex}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
_handleDismiss = (): void => {
|
||||
// Here we handle the cases when the log is dismissed and it
|
||||
// was either the last log, or when the current index
|
||||
// is now outside the bounds of the log array.
|
||||
const {selectedLogIndex, logs} = this.props;
|
||||
const logsArray = Array.from(logs);
|
||||
if (selectedLogIndex != null) {
|
||||
if (logsArray.length - 1 <= 0) {
|
||||
LogBoxData.setSelectedLog(-1);
|
||||
} else if (selectedLogIndex >= logsArray.length - 1) {
|
||||
LogBoxData.setSelectedLog(selectedLogIndex - 1);
|
||||
}
|
||||
|
||||
LogBoxData.dismiss(logsArray[selectedLogIndex]);
|
||||
}
|
||||
};
|
||||
|
||||
_handleMinimize = (): void => {
|
||||
LogBoxData.setSelectedLog(-1);
|
||||
};
|
||||
|
||||
_handleSetSelectedLog = (index: number): void => {
|
||||
LogBoxData.setSelectedLog(index);
|
||||
};
|
||||
}
|
||||
|
||||
export default (LogBoxData.withSubscription(
|
||||
_LogBoxInspectorContainer,
|
||||
): React.AbstractComponent<{||}>);
|
||||
+22
-49
@@ -11,46 +11,31 @@
|
||||
'use strict';
|
||||
|
||||
import * as React from 'react';
|
||||
import SafeAreaView from '../../Components/SafeAreaView/SafeAreaView';
|
||||
import StyleSheet from '../../StyleSheet/StyleSheet';
|
||||
import View from '../../Components/View/View';
|
||||
import LogBoxInspector from './LogBoxInspector';
|
||||
import LogBoxLog from '../Data/LogBoxLog';
|
||||
import LogBoxLogNotification from './LogBoxLogNotification';
|
||||
import type {LogBoxLogs} from '../Data/LogBoxData';
|
||||
import StyleSheet from '../StyleSheet/StyleSheet';
|
||||
import View from '../Components/View/View';
|
||||
import * as LogBoxData from './Data/LogBoxData';
|
||||
import LogBoxLog from './Data/LogBoxLog';
|
||||
import LogBoxLogNotification from './UI/LogBoxNotification';
|
||||
|
||||
type Props = $ReadOnly<{|
|
||||
onDismiss: (log: LogBoxLog) => void,
|
||||
onDismissWarns: () => void,
|
||||
onDismissErrors: () => void,
|
||||
setSelectedLog: number => void,
|
||||
logs: LogBoxLogs,
|
||||
logs: $ReadOnlyArray<LogBoxLog>,
|
||||
selectedLogIndex: number,
|
||||
isDisabled?: ?boolean,
|
||||
|}>;
|
||||
|
||||
function LogBoxContainer(props: Props): React.Node {
|
||||
const {selectedLogIndex, setSelectedLog} = props;
|
||||
export function _LogBoxNotificationContainer(props: Props): React.Node {
|
||||
const {logs} = props;
|
||||
|
||||
const logs = Array.from(props.logs);
|
||||
const onDismissWarns = () => {
|
||||
LogBoxData.clearWarnings();
|
||||
};
|
||||
const onDismissErrors = () => {
|
||||
LogBoxData.clearErrors();
|
||||
};
|
||||
|
||||
function handleInspectorDismiss() {
|
||||
// Here we handle the cases when the log is dismissed and it
|
||||
// was either the last log, or when the current index
|
||||
// is now outside the bounds of the log array.
|
||||
if (selectedLogIndex != null) {
|
||||
if (logs.length - 1 <= 0) {
|
||||
setSelectedLog(-1);
|
||||
} else if (selectedLogIndex >= logs.length - 1) {
|
||||
setSelectedLog(selectedLogIndex - 1);
|
||||
}
|
||||
props.onDismiss(logs[selectedLogIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
function handleInspectorMinimize() {
|
||||
setSelectedLog(-1);
|
||||
}
|
||||
const setSelectedLog = (index: number): void => {
|
||||
LogBoxData.setSelectedLog(index);
|
||||
};
|
||||
|
||||
function openLog(log: LogBoxLog) {
|
||||
let index = logs.length - 1;
|
||||
@@ -62,20 +47,6 @@ function LogBoxContainer(props: Props): React.Node {
|
||||
setSelectedLog(index);
|
||||
}
|
||||
|
||||
if (selectedLogIndex > -1) {
|
||||
return (
|
||||
<View style={StyleSheet.absoluteFill}>
|
||||
<LogBoxInspector
|
||||
onDismiss={handleInspectorDismiss}
|
||||
onMinimize={handleInspectorMinimize}
|
||||
onChangeSelectedIndex={setSelectedLog}
|
||||
logs={logs}
|
||||
selectedIndex={selectedLogIndex}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
if (logs.length === 0 || props.isDisabled === true) {
|
||||
return null;
|
||||
}
|
||||
@@ -93,7 +64,7 @@ function LogBoxContainer(props: Props): React.Node {
|
||||
level="warn"
|
||||
totalLogCount={warnings.length}
|
||||
onPressOpen={() => openLog(warnings[warnings.length - 1])}
|
||||
onPressDismiss={props.onDismissWarns}
|
||||
onPressDismiss={onDismissWarns}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
@@ -104,7 +75,7 @@ function LogBoxContainer(props: Props): React.Node {
|
||||
level="error"
|
||||
totalLogCount={errors.length}
|
||||
onPressOpen={() => openLog(errors[errors.length - 1])}
|
||||
onPressDismiss={props.onDismissErrors}
|
||||
onPressDismiss={onDismissErrors}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
@@ -126,4 +97,6 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
export default LogBoxContainer;
|
||||
export default (LogBoxData.withSubscription(
|
||||
_LogBoxNotificationContainer,
|
||||
): React.AbstractComponent<{||}>);
|
||||
@@ -14,7 +14,7 @@ import LogBoxInspectorCodeFrame from './LogBoxInspectorCodeFrame';
|
||||
import * as React from 'react';
|
||||
import ScrollView from '../../Components/ScrollView/ScrollView';
|
||||
import StyleSheet from '../../StyleSheet/StyleSheet';
|
||||
import Modal from '../../Modal/Modal';
|
||||
import View from '../../Components/View/View';
|
||||
import * as LogBoxData from '../Data/LogBoxData';
|
||||
import Keyboard from '../../Components/Keyboard/Keyboard';
|
||||
import LogBoxInspectorFooter from './LogBoxInspectorFooter';
|
||||
@@ -23,8 +23,7 @@ import LogBoxInspectorReactFrames from './LogBoxInspectorReactFrames';
|
||||
import LogBoxInspectorStackFrames from './LogBoxInspectorStackFrames';
|
||||
import LogBoxInspectorHeader from './LogBoxInspectorHeader';
|
||||
import * as LogBoxStyle from './LogBoxStyle';
|
||||
|
||||
import type LogBoxLog, {LogLevel} from '../Data/LogBoxLog';
|
||||
import LogBoxLog, {type LogLevel} from '../Data/LogBoxLog';
|
||||
|
||||
type Props = $ReadOnly<{|
|
||||
onDismiss: () => void,
|
||||
@@ -37,10 +36,12 @@ type Props = $ReadOnly<{|
|
||||
|
||||
function LogBoxInspector(props: Props): React.Node {
|
||||
const {logs, selectedIndex} = props;
|
||||
let log = logs[selectedIndex];
|
||||
|
||||
const log = logs[selectedIndex];
|
||||
React.useEffect(() => {
|
||||
LogBoxData.symbolicateLogNow(log);
|
||||
if (log) {
|
||||
LogBoxData.symbolicateLogNow(log);
|
||||
}
|
||||
}, [log]);
|
||||
|
||||
React.useEffect(() => {
|
||||
@@ -68,12 +69,7 @@ function LogBoxInspector(props: Props): React.Node {
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal
|
||||
animationType="none"
|
||||
visible
|
||||
statusBarTranslucent
|
||||
supportedOrientations={['portrait']}
|
||||
presentationStyle="overFullScreen">
|
||||
<View style={styles.root}>
|
||||
<LogBoxInspectorHeader
|
||||
onSelectIndex={props.onChangeSelectedIndex}
|
||||
selectedIndex={selectedIndex}
|
||||
@@ -86,7 +82,7 @@ function LogBoxInspector(props: Props): React.Node {
|
||||
onMinimize={props.onMinimize}
|
||||
level={log.level}
|
||||
/>
|
||||
</Modal>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -143,6 +139,10 @@ function LogBoxInspectorBody(props) {
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
root: {
|
||||
flex: 1,
|
||||
backgroundColor: LogBoxStyle.getTextColor(),
|
||||
},
|
||||
scrollBody: {
|
||||
backgroundColor: LogBoxStyle.getBackgroundColor(0.9),
|
||||
flex: 1,
|
||||
|
||||
@@ -101,9 +101,11 @@ const styles = StyleSheet.create({
|
||||
syntaxErrorText: {
|
||||
textAlign: 'center',
|
||||
width: '100%',
|
||||
height: 48,
|
||||
fontSize: 14,
|
||||
paddingTop: 15,
|
||||
paddingBottom: 15,
|
||||
lineHeight: 20,
|
||||
paddingTop: 20,
|
||||
paddingBottom: 50,
|
||||
fontStyle: 'italic',
|
||||
color: LogBoxStyle.getTextColor(0.6),
|
||||
},
|
||||
|
||||
@@ -126,7 +126,7 @@ const headerStyles = StyleSheet.create({
|
||||
borderRadius: 3,
|
||||
},
|
||||
buttonImage: {
|
||||
tintColor: LogBoxStyle.getBackgroundColor(1),
|
||||
tintColor: LogBoxStyle.getTextColor(),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -156,7 +156,7 @@ const styles = StyleSheet.create({
|
||||
justifyContent: 'center',
|
||||
},
|
||||
titleText: {
|
||||
color: LogBoxStyle.getBackgroundColor(1),
|
||||
color: LogBoxStyle.getTextColor(),
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
includeFontPadding: false,
|
||||
|
||||
@@ -18,12 +18,37 @@ import View from '../../Components/View/View';
|
||||
import LogBoxButton from './LogBoxButton';
|
||||
import * as LogBoxStyle from './LogBoxStyle';
|
||||
import LogBoxInspectorSection from './LogBoxInspectorSection';
|
||||
import openFileInEditor from '../../Core/Devtools/openFileInEditor';
|
||||
import type LogBoxLog from '../Data/LogBoxLog';
|
||||
|
||||
type Props = $ReadOnly<{|
|
||||
log: LogBoxLog,
|
||||
|}>;
|
||||
|
||||
const BEFORE_SLASH_RE = /^(.*)[\\/]/;
|
||||
|
||||
// Taken from React https://github.com/facebook/react/blob/206d61f72214e8ae5b935f0bf8628491cb7f0797/packages/react-devtools-shared/src/backend/describeComponentFrame.js#L27-L41
|
||||
function getPrettyFileName(path) {
|
||||
let fileName = path.replace(BEFORE_SLASH_RE, '');
|
||||
|
||||
// In DEV, include code for a common special case:
|
||||
// prefer "folder/index.js" instead of just "index.js".
|
||||
if (/^index\./.test(fileName)) {
|
||||
const match = path.match(BEFORE_SLASH_RE);
|
||||
if (match) {
|
||||
const pathBeforeSlash = match[1];
|
||||
if (pathBeforeSlash) {
|
||||
const folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
|
||||
// Note the below string contains a zero width space after the "/" character.
|
||||
// This is to prevent browsers like Chrome from formatting the file name as a link.
|
||||
// (Since this is a source link, it would not work to open the source file anyway.)
|
||||
fileName = folderName + '/' + fileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fileName;
|
||||
}
|
||||
function LogBoxInspectorReactFrames(props: Props): React.Node {
|
||||
const [collapsed, setCollapsed] = React.useState(true);
|
||||
if (props.log.componentStack == null || props.log.componentStack.length < 1) {
|
||||
@@ -39,6 +64,10 @@ function LogBoxInspectorReactFrames(props: Props): React.Node {
|
||||
}
|
||||
|
||||
function getCollapseMessage() {
|
||||
if (props.log.componentStack.length <= 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
const count = props.log.componentStack.length - 3;
|
||||
if (collapsed) {
|
||||
return `See ${count} more components`;
|
||||
@@ -53,15 +82,34 @@ function LogBoxInspectorReactFrames(props: Props): React.Node {
|
||||
<View
|
||||
// Unfortunately we don't have a unique identifier for stack traces.
|
||||
key={index}
|
||||
style={componentStyles.frame}>
|
||||
<View style={componentStyles.component}>
|
||||
<Text style={componentStyles.frameName}>
|
||||
<Text style={componentStyles.bracket}>{'<'}</Text>
|
||||
{frame.component}
|
||||
<Text style={componentStyles.bracket}>{' />'}</Text>
|
||||
style={componentStyles.frameContainer}>
|
||||
<LogBoxButton
|
||||
backgroundColor={{
|
||||
default: 'transparent',
|
||||
pressed: LogBoxStyle.getBackgroundColor(1),
|
||||
}}
|
||||
onPress={
|
||||
// Older versions of DevTools do not provide full path.
|
||||
// This will not work on Windows, remove check once the
|
||||
// DevTools return the full file path.
|
||||
frame.fileName.startsWith('/')
|
||||
? () =>
|
||||
openFileInEditor(frame.fileName, frame.location?.row ?? 1)
|
||||
: null
|
||||
}
|
||||
style={componentStyles.frame}>
|
||||
<View style={componentStyles.component}>
|
||||
<Text style={componentStyles.frameName}>
|
||||
<Text style={componentStyles.bracket}>{'<'}</Text>
|
||||
{frame.content}
|
||||
<Text style={componentStyles.bracket}>{' />'}</Text>
|
||||
</Text>
|
||||
</View>
|
||||
<Text style={componentStyles.frameLocation}>
|
||||
{getPrettyFileName(frame.fileName)}
|
||||
{frame.location ? `:${frame.location.row}` : ''}
|
||||
</Text>
|
||||
</View>
|
||||
<Text style={componentStyles.frameLocation}>{frame.location}</Text>
|
||||
</LogBoxButton>
|
||||
</View>
|
||||
))}
|
||||
<View style={componentStyles.collapseContainer}>
|
||||
@@ -96,9 +144,15 @@ const componentStyles = StyleSheet.create({
|
||||
paddingVertical: 5,
|
||||
paddingHorizontal: 10,
|
||||
},
|
||||
frameContainer: {
|
||||
flexDirection: 'row',
|
||||
paddingHorizontal: 15,
|
||||
},
|
||||
frame: {
|
||||
paddingHorizontal: 25,
|
||||
flex: 1,
|
||||
paddingVertical: 4,
|
||||
paddingHorizontal: 10,
|
||||
borderRadius: 5,
|
||||
},
|
||||
component: {
|
||||
flexDirection: 'row',
|
||||
|
||||
@@ -1,254 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @emails oncall+react_native
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const React = require('react');
|
||||
const LogBoxContainer = require('../LogBoxContainer').default;
|
||||
const LogBoxLog = require('../../Data/LogBoxLog').default;
|
||||
const render = require('../../../../jest/renderer');
|
||||
|
||||
describe('LogBoxContainer', () => {
|
||||
it('should render null with no logs', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxContainer
|
||||
onDismiss={() => {}}
|
||||
onDismissWarns={() => {}}
|
||||
onDismissErrors={() => {}}
|
||||
setSelectedLog={() => {}}
|
||||
selectedLogIndex={-1}
|
||||
logs={new Set()}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render null with no selected log and disabled', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxContainer
|
||||
isDisabled
|
||||
onDismiss={() => {}}
|
||||
onDismissWarns={() => {}}
|
||||
onDismissErrors={() => {}}
|
||||
setSelectedLog={() => {}}
|
||||
selectedLogIndex={-1}
|
||||
logs={
|
||||
new Set([
|
||||
new LogBoxLog({
|
||||
level: 'warn',
|
||||
isComponentError: false,
|
||||
message: {
|
||||
content: 'Some kind of message',
|
||||
substitutions: [],
|
||||
},
|
||||
stack: [],
|
||||
category: 'Some kind of message',
|
||||
componentStack: [],
|
||||
}),
|
||||
])
|
||||
}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render the latest warning notification', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxContainer
|
||||
onDismiss={() => {}}
|
||||
onDismissWarns={() => {}}
|
||||
onDismissErrors={() => {}}
|
||||
setSelectedLog={() => {}}
|
||||
selectedLogIndex={-1}
|
||||
logs={
|
||||
new Set([
|
||||
new LogBoxLog({
|
||||
level: 'warn',
|
||||
isComponentError: false,
|
||||
message: {
|
||||
content: 'Some kind of message',
|
||||
substitutions: [],
|
||||
},
|
||||
stack: [],
|
||||
category: 'Some kind of message',
|
||||
componentStack: [],
|
||||
}),
|
||||
new LogBoxLog({
|
||||
level: 'warn',
|
||||
isComponentError: false,
|
||||
message: {
|
||||
content: 'Some kind of message (latest)',
|
||||
substitutions: [],
|
||||
},
|
||||
stack: [],
|
||||
category: 'Some kind of message (latest)',
|
||||
componentStack: [],
|
||||
}),
|
||||
])
|
||||
}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render the latest error notification', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxContainer
|
||||
onDismiss={() => {}}
|
||||
onDismissWarns={() => {}}
|
||||
onDismissErrors={() => {}}
|
||||
setSelectedLog={() => {}}
|
||||
selectedLogIndex={-1}
|
||||
logs={
|
||||
new Set([
|
||||
new LogBoxLog({
|
||||
level: 'error',
|
||||
isComponentError: false,
|
||||
message: {
|
||||
content: 'Some kind of message',
|
||||
substitutions: [],
|
||||
},
|
||||
stack: [],
|
||||
category: 'Some kind of message',
|
||||
componentStack: [],
|
||||
}),
|
||||
new LogBoxLog({
|
||||
level: 'error',
|
||||
isComponentError: false,
|
||||
message: {
|
||||
content: 'Some kind of message (latest)',
|
||||
substitutions: [],
|
||||
},
|
||||
stack: [],
|
||||
category: 'Some kind of message (latest)',
|
||||
componentStack: [],
|
||||
}),
|
||||
])
|
||||
}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render both an error and warning notification', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxContainer
|
||||
onDismiss={() => {}}
|
||||
onDismissWarns={() => {}}
|
||||
onDismissErrors={() => {}}
|
||||
setSelectedLog={() => {}}
|
||||
selectedLogIndex={-1}
|
||||
logs={
|
||||
new Set([
|
||||
new LogBoxLog({
|
||||
level: 'warn',
|
||||
isComponentError: false,
|
||||
message: {
|
||||
content: 'Some kind of message',
|
||||
substitutions: [],
|
||||
},
|
||||
stack: [],
|
||||
category: 'Some kind of message',
|
||||
componentStack: [],
|
||||
}),
|
||||
new LogBoxLog({
|
||||
level: 'error',
|
||||
isComponentError: false,
|
||||
message: {
|
||||
content: 'Some kind of message (latest)',
|
||||
substitutions: [],
|
||||
},
|
||||
stack: [],
|
||||
category: 'Some kind of message (latest)',
|
||||
componentStack: [],
|
||||
}),
|
||||
])
|
||||
}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render selected fatal error even when disabled', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxContainer
|
||||
isDisabled
|
||||
onDismiss={() => {}}
|
||||
onDismissWarns={() => {}}
|
||||
onDismissErrors={() => {}}
|
||||
setSelectedLog={() => {}}
|
||||
selectedLogIndex={0}
|
||||
logs={
|
||||
new Set([
|
||||
new LogBoxLog({
|
||||
level: 'fatal',
|
||||
isComponentError: false,
|
||||
message: {
|
||||
content: 'Should be selected',
|
||||
substitutions: [],
|
||||
},
|
||||
stack: [],
|
||||
category: 'Some kind of message',
|
||||
componentStack: [],
|
||||
}),
|
||||
])
|
||||
}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render selected syntax error even when disabled', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxContainer
|
||||
isDisabled
|
||||
onDismiss={() => {}}
|
||||
onDismissWarns={() => {}}
|
||||
onDismissErrors={() => {}}
|
||||
setSelectedLog={() => {}}
|
||||
selectedLogIndex={0}
|
||||
logs={
|
||||
new Set([
|
||||
new LogBoxLog({
|
||||
level: 'syntax',
|
||||
isComponentError: false,
|
||||
message: {
|
||||
content: 'Should be selected',
|
||||
substitutions: [],
|
||||
},
|
||||
stack: [],
|
||||
category: 'Some kind of syntax error message',
|
||||
componentStack: [],
|
||||
codeFrame: {
|
||||
fileName:
|
||||
'/path/to/RKJSModules/Apps/CrashReact/CrashReactApp.js',
|
||||
location: {row: 199, column: 0},
|
||||
content: ` 197 | });
|
||||
198 |
|
||||
> 199 | export default CrashReactApp;
|
||||
| ^
|
||||
200 |`,
|
||||
},
|
||||
}),
|
||||
])
|
||||
}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -40,7 +40,7 @@ describe('LogBoxInspectorReactFrames', () => {
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render componentStack frames', () => {
|
||||
it('should render componentStack frames without full path pressable', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxInspectorReactFrames
|
||||
log={
|
||||
@@ -55,8 +55,129 @@ describe('LogBoxInspectorReactFrames', () => {
|
||||
category: 'Some kind of message',
|
||||
componentStack: [
|
||||
{
|
||||
component: 'MyComponent',
|
||||
location: 'MyComponentFile.js:1',
|
||||
content: 'MyComponent',
|
||||
fileName: 'MyComponentFile.js',
|
||||
location: {
|
||||
row: 1,
|
||||
column: -1,
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render componentStack frames with full path pressable', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxInspectorReactFrames
|
||||
log={
|
||||
new LogBoxLog({
|
||||
level: 'warn',
|
||||
isComponentError: false,
|
||||
message: {
|
||||
content: 'Some kind of message',
|
||||
substitutions: [],
|
||||
},
|
||||
stack: [],
|
||||
category: 'Some kind of message',
|
||||
componentStack: [
|
||||
{
|
||||
content: 'MyComponent',
|
||||
fileName: '/path/to/MyComponentFile.js',
|
||||
location: {
|
||||
row: 1,
|
||||
column: -1,
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render componentStack frames with parent folder of index.js', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxInspectorReactFrames
|
||||
log={
|
||||
new LogBoxLog({
|
||||
level: 'warn',
|
||||
isComponentError: false,
|
||||
message: {
|
||||
content: 'Some kind of message',
|
||||
substitutions: [],
|
||||
},
|
||||
stack: [],
|
||||
category: 'Some kind of message',
|
||||
componentStack: [
|
||||
{
|
||||
content: 'MyComponent',
|
||||
fileName: '/path/to/index.js',
|
||||
location: {
|
||||
row: 1,
|
||||
column: -1,
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render componentStack frames with more than 3 stacks', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxInspectorReactFrames
|
||||
log={
|
||||
new LogBoxLog({
|
||||
level: 'warn',
|
||||
isComponentError: false,
|
||||
message: {
|
||||
content: 'Some kind of message',
|
||||
substitutions: [],
|
||||
},
|
||||
stack: [],
|
||||
category: 'Some kind of message',
|
||||
componentStack: [
|
||||
{
|
||||
content: 'MyComponent',
|
||||
fileName: '/path/to/index.js',
|
||||
location: {
|
||||
row: 1,
|
||||
column: -1,
|
||||
},
|
||||
},
|
||||
{
|
||||
content: 'MyComponent2',
|
||||
fileName: '/path/to/index2.js',
|
||||
location: {
|
||||
row: 1,
|
||||
column: -1,
|
||||
},
|
||||
},
|
||||
{
|
||||
content: 'MyComponent3',
|
||||
fileName: '/path/to/index3.js',
|
||||
location: {
|
||||
row: 1,
|
||||
column: -1,
|
||||
},
|
||||
},
|
||||
{
|
||||
content: 'MyComponent4',
|
||||
fileName: '/path/to/index4.js',
|
||||
location: {
|
||||
row: 1,
|
||||
column: -1,
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
+3
-3
@@ -12,7 +12,7 @@
|
||||
'use strict';
|
||||
|
||||
const React = require('react');
|
||||
const LogBoxLogNotification = require('../LogBoxLogNotification').default;
|
||||
const LogBoxNotification = require('../LogBoxNotification').default;
|
||||
const LogBoxLog = require('../../Data/LogBoxLog').default;
|
||||
const render = require('../../../../jest/renderer');
|
||||
|
||||
@@ -28,10 +28,10 @@ const log = new LogBoxLog({
|
||||
componentStack: [],
|
||||
});
|
||||
|
||||
describe('LogBoxLogNotification', () => {
|
||||
describe('LogBoxNotification', () => {
|
||||
it('should render log', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxLogNotification
|
||||
<LogBoxNotification
|
||||
log={log}
|
||||
totalLogCount={1}
|
||||
level="warn"
|
||||
@@ -1,17 +1,13 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`LogBoxContainer should render fatal with selectedIndex 2 1`] = `
|
||||
<Component
|
||||
animationType="none"
|
||||
hardwareAccelerated={false}
|
||||
presentationStyle="overFullScreen"
|
||||
statusBarTranslucent={true}
|
||||
supportedOrientations={
|
||||
Array [
|
||||
"portrait",
|
||||
]
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "rgba(255, 255, 255, 1)",
|
||||
"flex": 1,
|
||||
}
|
||||
}
|
||||
visible={true}
|
||||
>
|
||||
<LogBoxInspectorHeader
|
||||
level="fatal"
|
||||
@@ -47,23 +43,19 @@ exports[`LogBoxContainer should render fatal with selectedIndex 2 1`] = `
|
||||
onDismiss={[Function]}
|
||||
onMinimize={[Function]}
|
||||
/>
|
||||
</Component>
|
||||
</View>
|
||||
`;
|
||||
|
||||
exports[`LogBoxContainer should render null with no logs 1`] = `null`;
|
||||
|
||||
exports[`LogBoxContainer should render warning with selectedIndex 0 1`] = `
|
||||
<Component
|
||||
animationType="none"
|
||||
hardwareAccelerated={false}
|
||||
presentationStyle="overFullScreen"
|
||||
statusBarTranslucent={true}
|
||||
supportedOrientations={
|
||||
Array [
|
||||
"portrait",
|
||||
]
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "rgba(255, 255, 255, 1)",
|
||||
"flex": 1,
|
||||
}
|
||||
}
|
||||
visible={true}
|
||||
>
|
||||
<LogBoxInspectorHeader
|
||||
level="warn"
|
||||
@@ -99,5 +91,5 @@ exports[`LogBoxContainer should render warning with selectedIndex 0 1`] = `
|
||||
onDismiss={[Function]}
|
||||
onMinimize={[Function]}
|
||||
/>
|
||||
</Component>
|
||||
</View>
|
||||
`;
|
||||
|
||||
@@ -29,8 +29,10 @@ exports[`LogBoxInspectorFooter should render no buttons and a message for syntax
|
||||
"color": "rgba(255, 255, 255, 0.6)",
|
||||
"fontSize": 14,
|
||||
"fontStyle": "italic",
|
||||
"paddingBottom": 15,
|
||||
"paddingTop": 15,
|
||||
"height": 48,
|
||||
"lineHeight": 20,
|
||||
"paddingBottom": 50,
|
||||
"paddingTop": 20,
|
||||
"textAlign": "center",
|
||||
"width": "100%",
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ exports[`LogBoxInspectorHeader should render both buttons for two total 1`] = `
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(51, 51, 51, 1)",
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
"fontSize": 16,
|
||||
"fontWeight": "600",
|
||||
"includeFontPadding": false,
|
||||
@@ -99,7 +99,7 @@ exports[`LogBoxInspectorHeader should render no buttons for one total 1`] = `
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(51, 51, 51, 1)",
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
"fontSize": 16,
|
||||
"fontWeight": "600",
|
||||
"includeFontPadding": false,
|
||||
@@ -153,7 +153,7 @@ exports[`LogBoxInspectorHeader should render syntax error header 1`] = `
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(51, 51, 51, 1)",
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
"fontSize": 16,
|
||||
"fontWeight": "600",
|
||||
"includeFontPadding": false,
|
||||
@@ -207,7 +207,7 @@ exports[`LogBoxInspectorHeader should render two buttons for three or more total
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(51, 51, 51, 1)",
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
"fontSize": 16,
|
||||
"fontWeight": "600",
|
||||
"includeFontPadding": false,
|
||||
|
||||
+651
-40
@@ -1,81 +1,420 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`LogBoxInspectorReactFrames should render componentStack frames 1`] = `
|
||||
exports[`LogBoxInspectorReactFrames should render componentStack frames with full path pressable 1`] = `
|
||||
<LogBoxInspectorSection
|
||||
heading="Component Stack"
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"paddingHorizontal": 25,
|
||||
"paddingVertical": 4,
|
||||
"flexDirection": "row",
|
||||
"paddingHorizontal": 15,
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
<LogBoxButton
|
||||
backgroundColor={
|
||||
Object {
|
||||
"default": "transparent",
|
||||
"pressed": "rgba(51, 51, 51, 1)",
|
||||
}
|
||||
}
|
||||
onPress={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"flexDirection": "row",
|
||||
"paddingRight": 10,
|
||||
"borderRadius": 5,
|
||||
"flex": 1,
|
||||
"paddingHorizontal": 10,
|
||||
"paddingVertical": 4,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
"fontFamily": "Menlo",
|
||||
"fontSize": 14,
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 18,
|
||||
"flexDirection": "row",
|
||||
"paddingRight": 10,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.4)",
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
"fontFamily": "Menlo",
|
||||
"fontSize": 14,
|
||||
"fontWeight": "500",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 18,
|
||||
}
|
||||
}
|
||||
>
|
||||
<
|
||||
</Text>
|
||||
MyComponent
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.4)",
|
||||
"fontFamily": "Menlo",
|
||||
"fontSize": 14,
|
||||
"fontWeight": "500",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 18,
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.4)",
|
||||
"fontFamily": "Menlo",
|
||||
"fontSize": 14,
|
||||
"fontWeight": "500",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 18,
|
||||
}
|
||||
}
|
||||
}
|
||||
>
|
||||
/>
|
||||
>
|
||||
<
|
||||
</Text>
|
||||
MyComponent
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.4)",
|
||||
"fontFamily": "Menlo",
|
||||
"fontSize": 14,
|
||||
"fontWeight": "500",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 18,
|
||||
}
|
||||
}
|
||||
>
|
||||
/>
|
||||
</Text>
|
||||
</Text>
|
||||
</View>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.7)",
|
||||
"fontSize": 12,
|
||||
"fontWeight": "300",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 16,
|
||||
"paddingLeft": 10,
|
||||
}
|
||||
}
|
||||
>
|
||||
MyComponentFile.js
|
||||
:1
|
||||
</Text>
|
||||
</View>
|
||||
<Text
|
||||
</LogBoxButton>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"flexDirection": "row",
|
||||
"marginLeft": 15,
|
||||
}
|
||||
}
|
||||
>
|
||||
<LogBoxButton
|
||||
backgroundColor={
|
||||
Object {
|
||||
"default": "transparent",
|
||||
"pressed": "rgba(51, 51, 51, 1)",
|
||||
}
|
||||
}
|
||||
onPress={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.7)",
|
||||
"fontSize": 12,
|
||||
"fontWeight": "300",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 16,
|
||||
"paddingLeft": 10,
|
||||
"borderRadius": 5,
|
||||
}
|
||||
}
|
||||
>
|
||||
MyComponentFile.js:1
|
||||
</Text>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.7)",
|
||||
"fontSize": 12,
|
||||
"fontWeight": "300",
|
||||
"lineHeight": 20,
|
||||
"marginTop": 0,
|
||||
"paddingHorizontal": 10,
|
||||
"paddingVertical": 5,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</LogBoxButton>
|
||||
</View>
|
||||
</LogBoxInspectorSection>
|
||||
`;
|
||||
|
||||
exports[`LogBoxInspectorReactFrames should render componentStack frames with more than 3 stacks 1`] = `
|
||||
<LogBoxInspectorSection
|
||||
heading="Component Stack"
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"flexDirection": "row",
|
||||
"paddingHorizontal": 15,
|
||||
}
|
||||
}
|
||||
>
|
||||
<LogBoxButton
|
||||
backgroundColor={
|
||||
Object {
|
||||
"default": "transparent",
|
||||
"pressed": "rgba(51, 51, 51, 1)",
|
||||
}
|
||||
}
|
||||
onPress={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"borderRadius": 5,
|
||||
"flex": 1,
|
||||
"paddingHorizontal": 10,
|
||||
"paddingVertical": 4,
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"flexDirection": "row",
|
||||
"paddingRight": 10,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
"fontFamily": "Menlo",
|
||||
"fontSize": 14,
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 18,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.4)",
|
||||
"fontFamily": "Menlo",
|
||||
"fontSize": 14,
|
||||
"fontWeight": "500",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 18,
|
||||
}
|
||||
}
|
||||
>
|
||||
<
|
||||
</Text>
|
||||
MyComponent
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.4)",
|
||||
"fontFamily": "Menlo",
|
||||
"fontSize": 14,
|
||||
"fontWeight": "500",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 18,
|
||||
}
|
||||
}
|
||||
>
|
||||
/>
|
||||
</Text>
|
||||
</Text>
|
||||
</View>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.7)",
|
||||
"fontSize": 12,
|
||||
"fontWeight": "300",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 16,
|
||||
"paddingLeft": 10,
|
||||
}
|
||||
}
|
||||
>
|
||||
to/index.js
|
||||
:1
|
||||
</Text>
|
||||
</LogBoxButton>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"flexDirection": "row",
|
||||
"paddingHorizontal": 15,
|
||||
}
|
||||
}
|
||||
>
|
||||
<LogBoxButton
|
||||
backgroundColor={
|
||||
Object {
|
||||
"default": "transparent",
|
||||
"pressed": "rgba(51, 51, 51, 1)",
|
||||
}
|
||||
}
|
||||
onPress={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"borderRadius": 5,
|
||||
"flex": 1,
|
||||
"paddingHorizontal": 10,
|
||||
"paddingVertical": 4,
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"flexDirection": "row",
|
||||
"paddingRight": 10,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
"fontFamily": "Menlo",
|
||||
"fontSize": 14,
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 18,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.4)",
|
||||
"fontFamily": "Menlo",
|
||||
"fontSize": 14,
|
||||
"fontWeight": "500",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 18,
|
||||
}
|
||||
}
|
||||
>
|
||||
<
|
||||
</Text>
|
||||
MyComponent2
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.4)",
|
||||
"fontFamily": "Menlo",
|
||||
"fontSize": 14,
|
||||
"fontWeight": "500",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 18,
|
||||
}
|
||||
}
|
||||
>
|
||||
/>
|
||||
</Text>
|
||||
</Text>
|
||||
</View>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.7)",
|
||||
"fontSize": 12,
|
||||
"fontWeight": "300",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 16,
|
||||
"paddingLeft": 10,
|
||||
}
|
||||
}
|
||||
>
|
||||
index2.js
|
||||
:1
|
||||
</Text>
|
||||
</LogBoxButton>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"flexDirection": "row",
|
||||
"paddingHorizontal": 15,
|
||||
}
|
||||
}
|
||||
>
|
||||
<LogBoxButton
|
||||
backgroundColor={
|
||||
Object {
|
||||
"default": "transparent",
|
||||
"pressed": "rgba(51, 51, 51, 1)",
|
||||
}
|
||||
}
|
||||
onPress={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"borderRadius": 5,
|
||||
"flex": 1,
|
||||
"paddingHorizontal": 10,
|
||||
"paddingVertical": 4,
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"flexDirection": "row",
|
||||
"paddingRight": 10,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
"fontFamily": "Menlo",
|
||||
"fontSize": 14,
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 18,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.4)",
|
||||
"fontFamily": "Menlo",
|
||||
"fontSize": 14,
|
||||
"fontWeight": "500",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 18,
|
||||
}
|
||||
}
|
||||
>
|
||||
<
|
||||
</Text>
|
||||
MyComponent3
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.4)",
|
||||
"fontFamily": "Menlo",
|
||||
"fontSize": 14,
|
||||
"fontWeight": "500",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 18,
|
||||
}
|
||||
}
|
||||
>
|
||||
/>
|
||||
</Text>
|
||||
</Text>
|
||||
</View>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.7)",
|
||||
"fontSize": 12,
|
||||
"fontWeight": "300",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 16,
|
||||
"paddingLeft": 10,
|
||||
}
|
||||
}
|
||||
>
|
||||
index3.js
|
||||
:1
|
||||
</Text>
|
||||
</LogBoxButton>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
@@ -112,11 +451,283 @@ exports[`LogBoxInspectorReactFrames should render componentStack frames 1`] = `
|
||||
}
|
||||
}
|
||||
>
|
||||
See -2 more components
|
||||
See 1 more components
|
||||
</Text>
|
||||
</LogBoxButton>
|
||||
</View>
|
||||
</LogBoxInspectorSection>
|
||||
`;
|
||||
|
||||
exports[`LogBoxInspectorReactFrames should render componentStack frames with parent folder of index.js 1`] = `
|
||||
<LogBoxInspectorSection
|
||||
heading="Component Stack"
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"flexDirection": "row",
|
||||
"paddingHorizontal": 15,
|
||||
}
|
||||
}
|
||||
>
|
||||
<LogBoxButton
|
||||
backgroundColor={
|
||||
Object {
|
||||
"default": "transparent",
|
||||
"pressed": "rgba(51, 51, 51, 1)",
|
||||
}
|
||||
}
|
||||
onPress={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"borderRadius": 5,
|
||||
"flex": 1,
|
||||
"paddingHorizontal": 10,
|
||||
"paddingVertical": 4,
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"flexDirection": "row",
|
||||
"paddingRight": 10,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
"fontFamily": "Menlo",
|
||||
"fontSize": 14,
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 18,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.4)",
|
||||
"fontFamily": "Menlo",
|
||||
"fontSize": 14,
|
||||
"fontWeight": "500",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 18,
|
||||
}
|
||||
}
|
||||
>
|
||||
<
|
||||
</Text>
|
||||
MyComponent
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.4)",
|
||||
"fontFamily": "Menlo",
|
||||
"fontSize": 14,
|
||||
"fontWeight": "500",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 18,
|
||||
}
|
||||
}
|
||||
>
|
||||
/>
|
||||
</Text>
|
||||
</Text>
|
||||
</View>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.7)",
|
||||
"fontSize": 12,
|
||||
"fontWeight": "300",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 16,
|
||||
"paddingLeft": 10,
|
||||
}
|
||||
}
|
||||
>
|
||||
to/index.js
|
||||
:1
|
||||
</Text>
|
||||
</LogBoxButton>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"flexDirection": "row",
|
||||
"marginLeft": 15,
|
||||
}
|
||||
}
|
||||
>
|
||||
<LogBoxButton
|
||||
backgroundColor={
|
||||
Object {
|
||||
"default": "transparent",
|
||||
"pressed": "rgba(51, 51, 51, 1)",
|
||||
}
|
||||
}
|
||||
onPress={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"borderRadius": 5,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.7)",
|
||||
"fontSize": 12,
|
||||
"fontWeight": "300",
|
||||
"lineHeight": 20,
|
||||
"marginTop": 0,
|
||||
"paddingHorizontal": 10,
|
||||
"paddingVertical": 5,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</LogBoxButton>
|
||||
</View>
|
||||
</LogBoxInspectorSection>
|
||||
`;
|
||||
|
||||
exports[`LogBoxInspectorReactFrames should render componentStack frames without full path pressable 1`] = `
|
||||
<LogBoxInspectorSection
|
||||
heading="Component Stack"
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"flexDirection": "row",
|
||||
"paddingHorizontal": 15,
|
||||
}
|
||||
}
|
||||
>
|
||||
<LogBoxButton
|
||||
backgroundColor={
|
||||
Object {
|
||||
"default": "transparent",
|
||||
"pressed": "rgba(51, 51, 51, 1)",
|
||||
}
|
||||
}
|
||||
onPress={null}
|
||||
style={
|
||||
Object {
|
||||
"borderRadius": 5,
|
||||
"flex": 1,
|
||||
"paddingHorizontal": 10,
|
||||
"paddingVertical": 4,
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"flexDirection": "row",
|
||||
"paddingRight": 10,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 1)",
|
||||
"fontFamily": "Menlo",
|
||||
"fontSize": 14,
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 18,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.4)",
|
||||
"fontFamily": "Menlo",
|
||||
"fontSize": 14,
|
||||
"fontWeight": "500",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 18,
|
||||
}
|
||||
}
|
||||
>
|
||||
<
|
||||
</Text>
|
||||
MyComponent
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.4)",
|
||||
"fontFamily": "Menlo",
|
||||
"fontSize": 14,
|
||||
"fontWeight": "500",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 18,
|
||||
}
|
||||
}
|
||||
>
|
||||
/>
|
||||
</Text>
|
||||
</Text>
|
||||
</View>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.7)",
|
||||
"fontSize": 12,
|
||||
"fontWeight": "300",
|
||||
"includeFontPadding": false,
|
||||
"lineHeight": 16,
|
||||
"paddingLeft": 10,
|
||||
}
|
||||
}
|
||||
>
|
||||
MyComponentFile.js
|
||||
:1
|
||||
</Text>
|
||||
</LogBoxButton>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"flexDirection": "row",
|
||||
"marginLeft": 15,
|
||||
}
|
||||
}
|
||||
>
|
||||
<LogBoxButton
|
||||
backgroundColor={
|
||||
Object {
|
||||
"default": "transparent",
|
||||
"pressed": "rgba(51, 51, 51, 1)",
|
||||
}
|
||||
}
|
||||
onPress={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"borderRadius": 5,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgba(255, 255, 255, 0.7)",
|
||||
"fontSize": 12,
|
||||
"fontWeight": "300",
|
||||
"lineHeight": 20,
|
||||
"marginTop": 0,
|
||||
"paddingHorizontal": 10,
|
||||
"paddingVertical": 5,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</LogBoxButton>
|
||||
</View>
|
||||
</LogBoxInspectorSection>
|
||||
`;
|
||||
|
||||
exports[`LogBoxInspectorReactFrames should render null for no componentStack frames 1`] = `null`;
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`LogBoxLogNotification should render log 1`] = `
|
||||
exports[`LogBoxNotification should render log 1`] = `
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
@@ -0,0 +1,212 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @emails oncall+react_native
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const React = require('react');
|
||||
const {
|
||||
_LogBoxNotificationContainer: LogBoxNotificationContainer,
|
||||
} = require('../LogBoxNotificationContainer');
|
||||
const LogBoxLog = require('../Data/LogBoxLog').default;
|
||||
const render = require('../../../jest/renderer');
|
||||
|
||||
describe('LogBoxNotificationContainer', () => {
|
||||
it('should render null with no logs', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxNotificationContainer selectedLogIndex={-1} logs={[]} />,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render null with no selected log and disabled', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxNotificationContainer
|
||||
isDisabled
|
||||
selectedLogIndex={-1}
|
||||
logs={[
|
||||
new LogBoxLog({
|
||||
level: 'warn',
|
||||
isComponentError: false,
|
||||
message: {
|
||||
content: 'Some kind of message',
|
||||
substitutions: [],
|
||||
},
|
||||
stack: [],
|
||||
category: 'Some kind of message',
|
||||
componentStack: [],
|
||||
}),
|
||||
]}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render the latest warning notification', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxNotificationContainer
|
||||
selectedLogIndex={-1}
|
||||
logs={[
|
||||
new LogBoxLog({
|
||||
level: 'warn',
|
||||
isComponentError: false,
|
||||
message: {
|
||||
content: 'Some kind of message',
|
||||
substitutions: [],
|
||||
},
|
||||
stack: [],
|
||||
category: 'Some kind of message',
|
||||
componentStack: [],
|
||||
}),
|
||||
new LogBoxLog({
|
||||
level: 'warn',
|
||||
isComponentError: false,
|
||||
message: {
|
||||
content: 'Some kind of message (latest)',
|
||||
substitutions: [],
|
||||
},
|
||||
stack: [],
|
||||
category: 'Some kind of message (latest)',
|
||||
componentStack: [],
|
||||
}),
|
||||
]}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render the latest error notification', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxNotificationContainer
|
||||
selectedLogIndex={-1}
|
||||
logs={[
|
||||
new LogBoxLog({
|
||||
level: 'error',
|
||||
isComponentError: false,
|
||||
message: {
|
||||
content: 'Some kind of message',
|
||||
substitutions: [],
|
||||
},
|
||||
stack: [],
|
||||
category: 'Some kind of message',
|
||||
componentStack: [],
|
||||
}),
|
||||
new LogBoxLog({
|
||||
level: 'error',
|
||||
isComponentError: false,
|
||||
message: {
|
||||
content: 'Some kind of message (latest)',
|
||||
substitutions: [],
|
||||
},
|
||||
stack: [],
|
||||
category: 'Some kind of message (latest)',
|
||||
componentStack: [],
|
||||
}),
|
||||
]}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render both an error and warning notification', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxNotificationContainer
|
||||
selectedLogIndex={-1}
|
||||
logs={[
|
||||
new LogBoxLog({
|
||||
level: 'warn',
|
||||
isComponentError: false,
|
||||
message: {
|
||||
content: 'Some kind of message',
|
||||
substitutions: [],
|
||||
},
|
||||
stack: [],
|
||||
category: 'Some kind of message',
|
||||
componentStack: [],
|
||||
}),
|
||||
new LogBoxLog({
|
||||
level: 'error',
|
||||
isComponentError: false,
|
||||
message: {
|
||||
content: 'Some kind of message (latest)',
|
||||
substitutions: [],
|
||||
},
|
||||
stack: [],
|
||||
category: 'Some kind of message (latest)',
|
||||
componentStack: [],
|
||||
}),
|
||||
]}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render selected fatal error even when disabled', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxNotificationContainer
|
||||
isDisabled
|
||||
selectedLogIndex={0}
|
||||
logs={[
|
||||
new LogBoxLog({
|
||||
level: 'fatal',
|
||||
isComponentError: false,
|
||||
message: {
|
||||
content: 'Should be selected',
|
||||
substitutions: [],
|
||||
},
|
||||
stack: [],
|
||||
category: 'Some kind of message',
|
||||
componentStack: [],
|
||||
}),
|
||||
]}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render selected syntax error even when disabled', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxNotificationContainer
|
||||
isDisabled
|
||||
selectedLogIndex={0}
|
||||
logs={[
|
||||
new LogBoxLog({
|
||||
level: 'syntax',
|
||||
isComponentError: false,
|
||||
message: {
|
||||
content: 'Should be selected',
|
||||
substitutions: [],
|
||||
},
|
||||
stack: [],
|
||||
category: 'Some kind of syntax error message',
|
||||
componentStack: [],
|
||||
codeFrame: {
|
||||
fileName: '/path/to/RKJSModules/Apps/CrashReact/CrashReactApp.js',
|
||||
location: {row: 199, column: 0},
|
||||
content: ` 197 | });
|
||||
198 |
|
||||
> 199 | export default CrashReactApp;
|
||||
| ^
|
||||
200 |`,
|
||||
},
|
||||
}),
|
||||
]}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @emails oncall+react_native
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const React = require('react');
|
||||
const {
|
||||
_LogBoxInspectorContainer: LogBoxInspectorContainer,
|
||||
} = require('../LogBoxInspectorContainer');
|
||||
const LogBoxLog = require('../Data/LogBoxLog').default;
|
||||
const render = require('../../../jest/renderer');
|
||||
|
||||
describe('LogBoxNotificationContainer', () => {
|
||||
it('should render inspector with logs, even when disabled', () => {
|
||||
const output = render.shallowRender(
|
||||
<LogBoxInspectorContainer
|
||||
isDisabled
|
||||
selectedLogIndex={-1}
|
||||
logs={[
|
||||
new LogBoxLog({
|
||||
level: 'warn',
|
||||
isComponentError: false,
|
||||
message: {
|
||||
content: 'Some kind of message',
|
||||
substitutions: [],
|
||||
},
|
||||
stack: [],
|
||||
category: 'Some kind of message',
|
||||
componentStack: [],
|
||||
}),
|
||||
new LogBoxLog({
|
||||
level: 'error',
|
||||
isComponentError: false,
|
||||
message: {
|
||||
content: 'Some kind of message (latest)',
|
||||
substitutions: [],
|
||||
},
|
||||
stack: [],
|
||||
category: 'Some kind of message (latest)',
|
||||
componentStack: [],
|
||||
}),
|
||||
]}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
+7
-100
@@ -1,6 +1,6 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`LogBoxContainer should render both an error and warning notification 1`] = `
|
||||
exports[`LogBoxNotificationContainer should render both an error and warning notification 1`] = `
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
@@ -86,108 +86,15 @@ exports[`LogBoxContainer should render both an error and warning notification 1`
|
||||
</View>
|
||||
`;
|
||||
|
||||
exports[`LogBoxContainer should render null with no logs 1`] = `null`;
|
||||
exports[`LogBoxNotificationContainer should render null with no logs 1`] = `null`;
|
||||
|
||||
exports[`LogBoxContainer should render null with no selected log and disabled 1`] = `null`;
|
||||
exports[`LogBoxNotificationContainer should render null with no selected log and disabled 1`] = `null`;
|
||||
|
||||
exports[`LogBoxContainer should render selected fatal error even when disabled 1`] = `
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"bottom": 0,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": 0,
|
||||
"top": 0,
|
||||
}
|
||||
}
|
||||
>
|
||||
<LogBoxInspector
|
||||
logs={
|
||||
Array [
|
||||
LogBoxLog {
|
||||
"category": "Some kind of message",
|
||||
"codeFrame": undefined,
|
||||
"componentStack": Array [],
|
||||
"count": 1,
|
||||
"isComponentError": false,
|
||||
"level": "fatal",
|
||||
"message": Object {
|
||||
"content": "Should be selected",
|
||||
"substitutions": Array [],
|
||||
},
|
||||
"stack": Array [],
|
||||
"symbolicated": Object {
|
||||
"error": null,
|
||||
"stack": null,
|
||||
"status": "NONE",
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
onChangeSelectedIndex={[Function]}
|
||||
onDismiss={[Function]}
|
||||
onMinimize={[Function]}
|
||||
selectedIndex={0}
|
||||
/>
|
||||
</View>
|
||||
`;
|
||||
exports[`LogBoxNotificationContainer should render selected fatal error even when disabled 1`] = `null`;
|
||||
|
||||
exports[`LogBoxContainer should render selected syntax error even when disabled 1`] = `
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"bottom": 0,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": 0,
|
||||
"top": 0,
|
||||
}
|
||||
}
|
||||
>
|
||||
<LogBoxInspector
|
||||
logs={
|
||||
Array [
|
||||
LogBoxLog {
|
||||
"category": "Some kind of syntax error message",
|
||||
"codeFrame": Object {
|
||||
"content": " 197 | });
|
||||
198 |
|
||||
> 199 | export default CrashReactApp;
|
||||
| ^
|
||||
200 |",
|
||||
"fileName": "/path/to/RKJSModules/Apps/CrashReact/CrashReactApp.js",
|
||||
"location": Object {
|
||||
"column": 0,
|
||||
"row": 199,
|
||||
},
|
||||
},
|
||||
"componentStack": Array [],
|
||||
"count": 1,
|
||||
"isComponentError": false,
|
||||
"level": "syntax",
|
||||
"message": Object {
|
||||
"content": "Should be selected",
|
||||
"substitutions": Array [],
|
||||
},
|
||||
"stack": Array [],
|
||||
"symbolicated": Object {
|
||||
"error": null,
|
||||
"stack": null,
|
||||
"status": "NONE",
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
onChangeSelectedIndex={[Function]}
|
||||
onDismiss={[Function]}
|
||||
onMinimize={[Function]}
|
||||
selectedIndex={0}
|
||||
/>
|
||||
</View>
|
||||
`;
|
||||
exports[`LogBoxNotificationContainer should render selected syntax error even when disabled 1`] = `null`;
|
||||
|
||||
exports[`LogBoxContainer should render the latest error notification 1`] = `
|
||||
exports[`LogBoxNotificationContainer should render the latest error notification 1`] = `
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
@@ -237,7 +144,7 @@ exports[`LogBoxContainer should render the latest error notification 1`] = `
|
||||
</View>
|
||||
`;
|
||||
|
||||
exports[`LogBoxContainer should render the latest warning notification 1`] = `
|
||||
exports[`LogBoxNotificationContainer should render the latest warning notification 1`] = `
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
@@ -0,0 +1,62 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`LogBoxNotificationContainer should render inspector with logs, even when disabled 1`] = `
|
||||
<View
|
||||
style={
|
||||
Object {
|
||||
"bottom": 0,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": 0,
|
||||
"top": 0,
|
||||
}
|
||||
}
|
||||
>
|
||||
<LogBoxInspector
|
||||
logs={
|
||||
Array [
|
||||
LogBoxLog {
|
||||
"category": "Some kind of message",
|
||||
"codeFrame": undefined,
|
||||
"componentStack": Array [],
|
||||
"count": 1,
|
||||
"isComponentError": false,
|
||||
"level": "warn",
|
||||
"message": Object {
|
||||
"content": "Some kind of message",
|
||||
"substitutions": Array [],
|
||||
},
|
||||
"stack": Array [],
|
||||
"symbolicated": Object {
|
||||
"error": null,
|
||||
"stack": null,
|
||||
"status": "NONE",
|
||||
},
|
||||
},
|
||||
LogBoxLog {
|
||||
"category": "Some kind of message (latest)",
|
||||
"codeFrame": undefined,
|
||||
"componentStack": Array [],
|
||||
"count": 1,
|
||||
"isComponentError": false,
|
||||
"level": "error",
|
||||
"message": Object {
|
||||
"content": "Some kind of message (latest)",
|
||||
"substitutions": Array [],
|
||||
},
|
||||
"stack": Array [],
|
||||
"symbolicated": Object {
|
||||
"error": null,
|
||||
"stack": null,
|
||||
"status": "NONE",
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
onChangeSelectedIndex={[Function]}
|
||||
onDismiss={[Function]}
|
||||
onMinimize={[Function]}
|
||||
selectedIndex={-1}
|
||||
/>
|
||||
</View>
|
||||
`;
|
||||
@@ -95,7 +95,8 @@ export type Props = $ReadOnly<{|
|
||||
|
||||
/**
|
||||
* The `onRequestClose` callback is called when the user taps the hardware
|
||||
* back button on Android or the menu button on Apple TV.
|
||||
* back button on Android, the menu button on Apple TV, or a modal is dismissed
|
||||
* with a gesture on iOS 13+.
|
||||
*
|
||||
* This is required on Apple TV and Android.
|
||||
*
|
||||
@@ -229,7 +230,7 @@ class Modal extends React.Component<Props> {
|
||||
}
|
||||
|
||||
const innerChildren = __DEV__ ? (
|
||||
<AppContainer rootTag={this.context.rootTag} internal_excludeLogBox>
|
||||
<AppContainer rootTag={this.context.rootTag}>
|
||||
{this.props.children}
|
||||
</AppContainer>
|
||||
) : (
|
||||
|
||||
@@ -70,7 +70,8 @@ type NativeProps = $ReadOnly<{|
|
||||
|
||||
/**
|
||||
* The `onRequestClose` callback is called when the user taps the hardware
|
||||
* back button on Android or the menu button on Apple TV.
|
||||
* back button on Android, the menu button on Apple TV, or a modal is dismissed
|
||||
* with a gesture on iOS 13+.
|
||||
*
|
||||
* This is required on Apple TV and Android.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {TurboModule} from 'react-native/Libraries/TurboModule/RCTExport';
|
||||
import * as TurboModuleRegistry from 'react-native/Libraries/TurboModule/TurboModuleRegistry';
|
||||
|
||||
export interface Spec extends TurboModule {
|
||||
+show: () => void;
|
||||
+hide: () => void;
|
||||
}
|
||||
|
||||
export default (TurboModuleRegistry.get<Spec>('LogBox'): ?Spec);
|
||||
@@ -26,7 +26,7 @@ static NSString *const kRemoteNotificationRegistrationFailed = @"RemoteNotificat
|
||||
|
||||
static NSString *const kErrorUnableToRequestPermissions = @"E_UNABLE_TO_REQUEST_PERMISSIONS";
|
||||
|
||||
#if !TARGET_OS_TV && !TARGET_OS_UIKITFORMAC
|
||||
#if !TARGET_OS_TV
|
||||
@implementation RCTConvert (NSCalendarUnit)
|
||||
|
||||
RCT_ENUM_CONVERTER(NSCalendarUnit,
|
||||
|
||||
@@ -94,16 +94,14 @@ class AppContainer extends React.Component<Props, State> {
|
||||
}
|
||||
|
||||
render(): React.Node {
|
||||
let logBox = null;
|
||||
if (__DEV__ && !this.props.internal_excludeLogBox) {
|
||||
if (!global.__RCTProfileIsProfiling) {
|
||||
if (global.__reactExperimentalLogBox) {
|
||||
const LogBox = require('../LogBox/LogBox');
|
||||
logBox = <LogBox />;
|
||||
} else {
|
||||
const YellowBox = require('../YellowBox/YellowBox');
|
||||
logBox = <YellowBox />;
|
||||
}
|
||||
let yellowBox = null;
|
||||
if (__DEV__) {
|
||||
if (
|
||||
!global.__RCTProfileIsProfiling &&
|
||||
!this.props.internal_excludeLogBox
|
||||
) {
|
||||
const YellowBox = require('../YellowBox/YellowBox');
|
||||
yellowBox = <YellowBox />;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +135,7 @@ class AppContainer extends React.Component<Props, State> {
|
||||
<View style={styles.appContainer} pointerEvents="box-none">
|
||||
{!this.state.hasError && innerView}
|
||||
{this.state.inspector}
|
||||
{logBox}
|
||||
{yellowBox}
|
||||
</View>
|
||||
</RootTagContext.Provider>
|
||||
);
|
||||
@@ -152,22 +150,8 @@ const styles = StyleSheet.create({
|
||||
|
||||
if (__DEV__) {
|
||||
if (!global.__RCTProfileIsProfiling) {
|
||||
if (global.__reactExperimentalLogBox) {
|
||||
const LogBox = require('../LogBox/LogBox');
|
||||
LogBox.install();
|
||||
|
||||
// TODO: (rickhanlonii) T57484314 Temporary hack to fix LogBox experiment but we need to
|
||||
// either decide to provide an error boundary by default or move this to a separate root.
|
||||
AppContainer.getDerivedStateFromError = function getDerivedStateFromError(
|
||||
error,
|
||||
state,
|
||||
) {
|
||||
return {...state, hasError: true};
|
||||
};
|
||||
} else {
|
||||
const YellowBox = require('../YellowBox/YellowBox');
|
||||
YellowBox.install();
|
||||
}
|
||||
const YellowBox = require('../YellowBox/YellowBox');
|
||||
YellowBox.install();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -125,6 +125,7 @@ const AppRegistry = {
|
||||
appParameters.fabric,
|
||||
showArchitectureIndicator,
|
||||
scopedPerformanceLogger,
|
||||
appKey === 'LogBox',
|
||||
);
|
||||
},
|
||||
};
|
||||
@@ -180,13 +181,15 @@ const AppRegistry = {
|
||||
* See http://facebook.github.io/react-native/docs/appregistry.html#runapplication
|
||||
*/
|
||||
runApplication(appKey: string, appParameters: any): void {
|
||||
const msg =
|
||||
'Running "' + appKey + '" with ' + JSON.stringify(appParameters);
|
||||
infoLog(msg);
|
||||
BugReporting.addSource(
|
||||
'AppRegistry.runApplication' + runCount++,
|
||||
() => msg,
|
||||
);
|
||||
if (appKey !== 'LogBox') {
|
||||
const msg =
|
||||
'Running "' + appKey + '" with ' + JSON.stringify(appParameters);
|
||||
infoLog(msg);
|
||||
BugReporting.addSource(
|
||||
'AppRegistry.runApplication' + runCount++,
|
||||
() => msg,
|
||||
);
|
||||
}
|
||||
invariant(
|
||||
runnables[appKey] && runnables[appKey].run,
|
||||
`"${appKey}" has not been registered. This can happen if:\n` +
|
||||
@@ -292,4 +295,17 @@ const AppRegistry = {
|
||||
|
||||
BatchedBridge.registerCallableModule('AppRegistry', AppRegistry);
|
||||
|
||||
if (__DEV__) {
|
||||
const LogBoxInspector = require('../LogBox/LogBoxInspectorContainer').default;
|
||||
AppRegistry.registerComponent('LogBox', () => LogBoxInspector);
|
||||
} else {
|
||||
AppRegistry.registerComponent(
|
||||
'LogBox',
|
||||
() =>
|
||||
function NoOp() {
|
||||
return null;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = AppRegistry;
|
||||
|
||||
@@ -29,6 +29,7 @@ function renderApplication<Props: Object>(
|
||||
fabric?: boolean,
|
||||
showArchitectureIndicator?: boolean,
|
||||
scopedPerformanceLogger?: IPerformanceLogger,
|
||||
isLogBox?: boolean,
|
||||
) {
|
||||
invariant(rootTag, 'Expect to have a valid rootTag, instead got ', rootTag);
|
||||
|
||||
@@ -39,7 +40,8 @@ function renderApplication<Props: Object>(
|
||||
rootTag={rootTag}
|
||||
fabric={fabric}
|
||||
showArchitectureIndicator={showArchitectureIndicator}
|
||||
WrapperComponent={WrapperComponent}>
|
||||
WrapperComponent={WrapperComponent}
|
||||
internal_excludeLogBox={isLogBox}>
|
||||
<RootComponent {...initialProps} rootTag={rootTag} />
|
||||
</AppContainer>
|
||||
</PerformanceLoggerContext.Provider>
|
||||
|
||||
@@ -14,12 +14,9 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
#if !TARGET_OS_UIKITFORMAC
|
||||
|
||||
#import <React/RCTSRWebSocket.h>
|
||||
|
||||
#import <Availability.h>
|
||||
#import <Endian.h>
|
||||
|
||||
#import <Security/SecRandom.h>
|
||||
|
||||
@@ -580,7 +577,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||
NSMutableData *mutablePayload = [[NSMutableData alloc] initWithLength:sizeof(uint16_t) + maxMsgSize];
|
||||
NSData *payload = mutablePayload;
|
||||
|
||||
((uint16_t *)mutablePayload.mutableBytes)[0] = EndianU16_BtoN(code);
|
||||
((uint16_t *)mutablePayload.mutableBytes)[0] = NSSwapBigShortToHost(code);
|
||||
|
||||
if (reason) {
|
||||
NSRange remainingRange = {0};
|
||||
@@ -749,7 +746,7 @@ static inline BOOL closeCodeIsValid(int closeCode)
|
||||
return;
|
||||
} else if (dataSize >= 2) {
|
||||
[data getBytes:&closeCode length:sizeof(closeCode)];
|
||||
_closeCode = EndianU16_BtoN(closeCode);
|
||||
_closeCode = NSSwapBigShortToHost(closeCode);
|
||||
if (!closeCodeIsValid(_closeCode)) {
|
||||
[self _closeWithProtocolError:[NSString stringWithFormat:@"Cannot have close code of %d", _closeCode]];
|
||||
return;
|
||||
@@ -972,12 +969,12 @@ static const uint8_t RCTSRPayloadLenMask = 0x7F;
|
||||
|
||||
if (header.payload_length == 126) {
|
||||
assert(mapped_size >= sizeof(uint16_t));
|
||||
uint16_t newLen = EndianU16_BtoN(*(uint16_t *)(mapped_buffer));
|
||||
uint16_t newLen = NSSwapBigShortToHost(*(uint16_t *)(mapped_buffer));
|
||||
header.payload_length = newLen;
|
||||
offset += sizeof(uint16_t);
|
||||
} else if (header.payload_length == 127) {
|
||||
assert(mapped_size >= sizeof(uint64_t));
|
||||
header.payload_length = EndianU64_BtoN(*(uint64_t *)(mapped_buffer));
|
||||
header.payload_length = NSSwapBigLongLongToHost(*(uint64_t *)(mapped_buffer));
|
||||
offset += sizeof(uint64_t);
|
||||
} else {
|
||||
assert(header.payload_length < 126 && header.payload_length >= 0);
|
||||
@@ -1264,11 +1261,11 @@ static const size_t RCTSRFrameHeaderOverhead = 32;
|
||||
frame_buffer[1] |= payloadLength;
|
||||
} else if (payloadLength <= UINT16_MAX) {
|
||||
frame_buffer[1] |= 126;
|
||||
*((uint16_t *)(frame_buffer + frame_buffer_size)) = EndianU16_BtoN((uint16_t)payloadLength);
|
||||
*((uint16_t *)(frame_buffer + frame_buffer_size)) = NSSwapBigShortToHost((uint16_t)payloadLength);
|
||||
frame_buffer_size += sizeof(uint16_t);
|
||||
} else {
|
||||
frame_buffer[1] |= 127;
|
||||
*((uint64_t *)(frame_buffer + frame_buffer_size)) = EndianU64_BtoN((uint64_t)payloadLength);
|
||||
*((uint64_t *)(frame_buffer + frame_buffer_size)) = NSSwapBigLongLongToHost((uint64_t)payloadLength);
|
||||
frame_buffer_size += sizeof(uint64_t);
|
||||
}
|
||||
|
||||
@@ -1637,5 +1634,3 @@ static NSRunLoop *networkRunLoop = nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
|
||||
const YellowBoxWarning = require('./YellowBoxWarning');
|
||||
|
||||
import type {Category} from './YellowBoxCategory';
|
||||
|
||||
import type {Category, Message} from './YellowBoxCategory';
|
||||
import type {Stack} from './YellowBoxSymbolication';
|
||||
export type Registry = Map<Category, $ReadOnlyArray<YellowBoxWarning>>;
|
||||
|
||||
export type Observer = (registry: Registry) => void;
|
||||
@@ -32,25 +32,13 @@ let disabled = false;
|
||||
let projection = new Map();
|
||||
let updateTimeout = null;
|
||||
|
||||
function isWarningIgnored(warning: YellowBoxWarning): boolean {
|
||||
for (const pattern of ignorePatterns) {
|
||||
if (pattern instanceof RegExp && pattern.test(warning.message.content)) {
|
||||
return true;
|
||||
} else if (
|
||||
typeof pattern === 'string' &&
|
||||
warning.message.content.includes(pattern)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function handleUpdate(): void {
|
||||
projection = new Map();
|
||||
if (!disabled) {
|
||||
for (const [category, warnings] of registry) {
|
||||
const filtered = warnings.filter(warning => !isWarningIgnored(warning));
|
||||
const filtered = warnings.filter(
|
||||
warning => !YellowBoxRegistry.isWarningIgnored(warning.message),
|
||||
);
|
||||
if (filtered.length > 0) {
|
||||
projection.set(category, filtered);
|
||||
}
|
||||
@@ -67,18 +55,28 @@ function handleUpdate(): void {
|
||||
}
|
||||
|
||||
const YellowBoxRegistry = {
|
||||
add({
|
||||
args,
|
||||
}: $ReadOnly<{|
|
||||
args: $ReadOnlyArray<mixed>,
|
||||
|}>): void {
|
||||
if (typeof args[0] === 'string' && args[0].startsWith('(ADVICE)')) {
|
||||
return;
|
||||
isWarningIgnored(message: Message): boolean {
|
||||
for (const pattern of ignorePatterns) {
|
||||
if (pattern instanceof RegExp && pattern.test(message.content)) {
|
||||
return true;
|
||||
} else if (
|
||||
typeof pattern === 'string' &&
|
||||
message.content.includes(pattern)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
const {category, message, stack} = YellowBoxWarning.parse({
|
||||
args,
|
||||
});
|
||||
|
||||
return false;
|
||||
},
|
||||
add({
|
||||
category,
|
||||
message,
|
||||
stack,
|
||||
}: $ReadOnly<{|
|
||||
category: Category,
|
||||
message: Message,
|
||||
stack: Stack,
|
||||
|}>): void {
|
||||
let warnings = registry.get(category);
|
||||
if (warnings == null) {
|
||||
warnings = [];
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const YellowBoxWarning = require('../YellowBoxWarning');
|
||||
const YellowBoxCategory = require('../YellowBoxCategory');
|
||||
const YellowBoxRegistry = require('../YellowBoxRegistry');
|
||||
|
||||
@@ -34,7 +35,7 @@ describe('YellowBoxRegistry', () => {
|
||||
});
|
||||
|
||||
it('adds and deletes warnings', () => {
|
||||
YellowBoxRegistry.add({args: ['A']});
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A']}));
|
||||
const {category: categoryA} = YellowBoxCategory.parse(['A']);
|
||||
|
||||
expect(registry().size).toBe(1);
|
||||
@@ -46,9 +47,9 @@ describe('YellowBoxRegistry', () => {
|
||||
});
|
||||
|
||||
it('clears all warnings', () => {
|
||||
YellowBoxRegistry.add({args: ['A']});
|
||||
YellowBoxRegistry.add({args: ['B']});
|
||||
YellowBoxRegistry.add({args: ['C']});
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A']}));
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['B']}));
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['C']}));
|
||||
|
||||
expect(registry().size).toBe(3);
|
||||
|
||||
@@ -57,9 +58,9 @@ describe('YellowBoxRegistry', () => {
|
||||
});
|
||||
|
||||
it('sorts warnings in chronological order', () => {
|
||||
YellowBoxRegistry.add({args: ['A']});
|
||||
YellowBoxRegistry.add({args: ['B']});
|
||||
YellowBoxRegistry.add({args: ['C']});
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A']}));
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['B']}));
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['C']}));
|
||||
|
||||
const {category: categoryA} = YellowBoxCategory.parse(['A']);
|
||||
const {category: categoryB} = YellowBoxCategory.parse(['B']);
|
||||
@@ -71,7 +72,7 @@ describe('YellowBoxRegistry', () => {
|
||||
categoryC,
|
||||
]);
|
||||
|
||||
YellowBoxRegistry.add({args: ['A']});
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A']}));
|
||||
|
||||
// Expect `A` to be hoisted to the end of the registry.
|
||||
expect(Array.from(registry().keys())).toEqual([
|
||||
@@ -82,9 +83,9 @@ describe('YellowBoxRegistry', () => {
|
||||
});
|
||||
|
||||
it('ignores warnings matching patterns', () => {
|
||||
YellowBoxRegistry.add({args: ['A!']});
|
||||
YellowBoxRegistry.add({args: ['B?']});
|
||||
YellowBoxRegistry.add({args: ['C!']});
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A!']}));
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['B?']}));
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['C!']}));
|
||||
expect(registry().size).toBe(3);
|
||||
|
||||
YellowBoxRegistry.addIgnorePatterns(['!']);
|
||||
@@ -95,9 +96,9 @@ describe('YellowBoxRegistry', () => {
|
||||
});
|
||||
|
||||
it('ignores warnings matching regexs or pattern', () => {
|
||||
YellowBoxRegistry.add({args: ['There are 4 dogs']});
|
||||
YellowBoxRegistry.add({args: ['There are 3 cats']});
|
||||
YellowBoxRegistry.add({args: ['There are H cats']});
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['There are 4 dogs']}));
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['There are 3 cats']}));
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['There are H cats']}));
|
||||
expect(registry().size).toBe(3);
|
||||
|
||||
YellowBoxRegistry.addIgnorePatterns(['dogs']);
|
||||
@@ -111,9 +112,9 @@ describe('YellowBoxRegistry', () => {
|
||||
});
|
||||
|
||||
it('ignores all warnings when disabled', () => {
|
||||
YellowBoxRegistry.add({args: ['A!']});
|
||||
YellowBoxRegistry.add({args: ['B?']});
|
||||
YellowBoxRegistry.add({args: ['C!']});
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A!']}));
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['B?']}));
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['C!']}));
|
||||
expect(registry().size).toBe(3);
|
||||
|
||||
YellowBoxRegistry.setDisabled(true);
|
||||
@@ -124,57 +125,54 @@ describe('YellowBoxRegistry', () => {
|
||||
});
|
||||
|
||||
it('groups warnings by simple categories', () => {
|
||||
YellowBoxRegistry.add({args: ['A']});
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A']}));
|
||||
expect(registry().size).toBe(1);
|
||||
|
||||
YellowBoxRegistry.add({args: ['A']});
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A']}));
|
||||
expect(registry().size).toBe(1);
|
||||
|
||||
YellowBoxRegistry.add({args: ['B']});
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['B']}));
|
||||
expect(registry().size).toBe(2);
|
||||
});
|
||||
|
||||
it('groups warnings by format string categories', () => {
|
||||
YellowBoxRegistry.add({args: ['%s', 'A']});
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['%s', 'A']}));
|
||||
expect(registry().size).toBe(1);
|
||||
|
||||
YellowBoxRegistry.add({args: ['%s', 'B']});
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['%s', 'B']}));
|
||||
expect(registry().size).toBe(1);
|
||||
|
||||
YellowBoxRegistry.add({args: ['A']});
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A']}));
|
||||
expect(registry().size).toBe(2);
|
||||
|
||||
YellowBoxRegistry.add({args: ['B']});
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['B']}));
|
||||
expect(registry().size).toBe(3);
|
||||
});
|
||||
|
||||
it('groups warnings with consideration for arguments', () => {
|
||||
YellowBoxRegistry.add({args: ['A', 'B']});
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A', 'B']}));
|
||||
expect(registry().size).toBe(1);
|
||||
|
||||
YellowBoxRegistry.add({args: ['A', 'B']});
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A', 'B']}));
|
||||
expect(registry().size).toBe(1);
|
||||
|
||||
YellowBoxRegistry.add({args: ['A', 'C']});
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A', 'C']}));
|
||||
expect(registry().size).toBe(2);
|
||||
|
||||
YellowBoxRegistry.add({args: ['%s', 'A', 'A']});
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['%s', 'A', 'A']}));
|
||||
expect(registry().size).toBe(3);
|
||||
|
||||
YellowBoxRegistry.add({args: ['%s', 'B', 'A']});
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['%s', 'B', 'A']}));
|
||||
expect(registry().size).toBe(3);
|
||||
|
||||
YellowBoxRegistry.add({args: ['%s', 'B', 'B']});
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['%s', 'B', 'B']}));
|
||||
expect(registry().size).toBe(4);
|
||||
});
|
||||
|
||||
it('ignores warnings starting with "(ADVICE)"', () => {
|
||||
YellowBoxRegistry.add({args: ['(ADVICE) ...']});
|
||||
expect(registry().size).toBe(0);
|
||||
});
|
||||
|
||||
it('does not ignore warnings formatted to start with "(ADVICE)"', () => {
|
||||
YellowBoxRegistry.add({args: ['%s ...', '(ADVICE)']});
|
||||
YellowBoxRegistry.add(
|
||||
YellowBoxWarning.parse({args: ['%s ...', '(ADVICE)']}),
|
||||
);
|
||||
expect(registry().size).toBe(1);
|
||||
});
|
||||
|
||||
@@ -189,8 +187,8 @@ describe('YellowBoxRegistry', () => {
|
||||
const {observer} = observe();
|
||||
expect(observer.mock.calls.length).toBe(1);
|
||||
|
||||
YellowBoxRegistry.add({args: ['A']});
|
||||
YellowBoxRegistry.add({args: ['B']});
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A']}));
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['B']}));
|
||||
jest.runAllImmediates();
|
||||
expect(observer.mock.calls.length).toBe(2);
|
||||
});
|
||||
@@ -207,7 +205,7 @@ describe('YellowBoxRegistry', () => {
|
||||
const {observer} = observe();
|
||||
expect(observer.mock.calls.length).toBe(1);
|
||||
|
||||
YellowBoxRegistry.add({args: ['A']});
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A']}));
|
||||
jest.runAllImmediates();
|
||||
expect(observer.mock.calls.length).toBe(2);
|
||||
|
||||
@@ -226,7 +224,7 @@ describe('YellowBoxRegistry', () => {
|
||||
const {observer} = observe();
|
||||
expect(observer.mock.calls.length).toBe(1);
|
||||
|
||||
YellowBoxRegistry.add({args: ['A']});
|
||||
YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A']}));
|
||||
jest.runAllImmediates();
|
||||
expect(observer.mock.calls.length).toBe(2);
|
||||
|
||||
|
||||
@@ -12,13 +12,12 @@
|
||||
|
||||
const React = require('react');
|
||||
|
||||
import type {Category} from './Data/YellowBoxCategory';
|
||||
import type {
|
||||
Registry,
|
||||
Subscription,
|
||||
IgnorePattern,
|
||||
} from './Data/YellowBoxRegistry';
|
||||
import type {Registry, IgnorePattern} from './Data/YellowBoxRegistry';
|
||||
import YellowBoxWarning from './Data/YellowBoxWarning';
|
||||
|
||||
import * as LogBoxData from '../LogBox/Data/LogBoxData';
|
||||
import NativeLogBox from '../NativeModules/specs/NativeLogBox';
|
||||
|
||||
type Props = $ReadOnly<{||}>;
|
||||
type State = {|
|
||||
registry: ?Registry,
|
||||
@@ -47,14 +46,19 @@ let YellowBox;
|
||||
if (__DEV__) {
|
||||
const Platform = require('../Utilities/Platform');
|
||||
const RCTLog = require('../Utilities/RCTLog');
|
||||
const YellowBoxList = require('./UI/YellowBoxList');
|
||||
const YellowBoxContainer = require('./YellowBoxContainer').default;
|
||||
const LogBox = require('../LogBox/LogBox');
|
||||
const YellowBoxRegistry = require('./Data/YellowBoxRegistry');
|
||||
const LogBoxNotificationContainer = require('../LogBox/LogBoxNotificationContainer')
|
||||
.default;
|
||||
|
||||
// YellowBox needs to insert itself early,
|
||||
// in order to access the component stacks appended by React DevTools.
|
||||
const {error, warn} = console;
|
||||
let errorImpl = error;
|
||||
let warnImpl = warn;
|
||||
let _isLogBoxEnabled = false;
|
||||
let _isInstalled = false;
|
||||
(console: any).error = function(...args) {
|
||||
errorImpl(...args);
|
||||
};
|
||||
@@ -70,16 +74,17 @@ if (__DEV__) {
|
||||
}
|
||||
|
||||
static install(): void {
|
||||
if (_isLogBoxEnabled) {
|
||||
LogBox.install();
|
||||
return;
|
||||
}
|
||||
_isInstalled = true;
|
||||
|
||||
errorImpl = function(...args) {
|
||||
error.call(console, ...args);
|
||||
// Show YellowBox for the `warning` module.
|
||||
if (typeof args[0] === 'string' && args[0].startsWith('Warning: ')) {
|
||||
registerWarning(...args);
|
||||
}
|
||||
registerError(...args);
|
||||
};
|
||||
|
||||
warnImpl = function(...args) {
|
||||
warn.call(console, ...args);
|
||||
registerWarning(...args);
|
||||
};
|
||||
|
||||
@@ -102,51 +107,95 @@ if (__DEV__) {
|
||||
}
|
||||
|
||||
static uninstall(): void {
|
||||
if (_isLogBoxEnabled) {
|
||||
LogBox.uninstall();
|
||||
return;
|
||||
}
|
||||
_isInstalled = false;
|
||||
errorImpl = error;
|
||||
warnImpl = warn;
|
||||
delete (console: any).disableYellowBox;
|
||||
}
|
||||
|
||||
_subscription: ?Subscription;
|
||||
static __unstable_enableLogBox(): void {
|
||||
if (NativeLogBox == null) {
|
||||
// The native module is required to enable LogBox.
|
||||
return;
|
||||
}
|
||||
|
||||
state = {
|
||||
registry: null,
|
||||
};
|
||||
if (_isInstalled) {
|
||||
throw new Error(
|
||||
'LogBox must be enabled before AppContainer is required so that it can properly wrap the console methods.\n\nPlease enable LogBox earlier in your app.\n\n',
|
||||
);
|
||||
}
|
||||
_isLogBoxEnabled = true;
|
||||
|
||||
// TODO: Temporary hack to prevent cycles with the ExceptionManager.
|
||||
global.__unstable_isLogBoxEnabled = true;
|
||||
}
|
||||
|
||||
static __unstable_isLogBoxEnabled(): boolean {
|
||||
return !!_isLogBoxEnabled;
|
||||
}
|
||||
|
||||
render(): React.Node {
|
||||
// TODO: Ignore warnings that fire when rendering `YellowBox` itself.
|
||||
return this.state.registry == null ? null : (
|
||||
<YellowBoxList
|
||||
onDismiss={this._handleDismiss}
|
||||
onDismissAll={this._handleDismissAll}
|
||||
registry={this.state.registry}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
this._subscription = YellowBoxRegistry.observe(registry => {
|
||||
this.setState({registry});
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount(): void {
|
||||
if (this._subscription != null) {
|
||||
this._subscription.unsubscribe();
|
||||
if (_isLogBoxEnabled) {
|
||||
return <LogBoxNotificationContainer />;
|
||||
}
|
||||
}
|
||||
|
||||
_handleDismiss = (category: Category): void => {
|
||||
YellowBoxRegistry.delete(category);
|
||||
};
|
||||
|
||||
_handleDismissAll(): void {
|
||||
YellowBoxRegistry.clear();
|
||||
// TODO: Ignore warnings that fire when rendering `YellowBox` itself.
|
||||
return <YellowBoxContainer />;
|
||||
}
|
||||
};
|
||||
|
||||
const registerWarning = (...args): void => {
|
||||
YellowBoxRegistry.add({args});
|
||||
if (typeof args[0] === 'string' && args[0].startsWith('(ADVICE)')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const {category, message, stack} = YellowBoxWarning.parse({
|
||||
args,
|
||||
});
|
||||
|
||||
if (!YellowBoxRegistry.isWarningIgnored(message)) {
|
||||
YellowBoxRegistry.add({category, message, stack});
|
||||
warn.call(console, ...args);
|
||||
}
|
||||
};
|
||||
|
||||
const registerError = (...args): void => {
|
||||
// Only show YellowBox for the `warning` module, otherwise pass through and skip.
|
||||
if (typeof args[0] !== 'string' || !args[0].startsWith('Warning: ')) {
|
||||
error.call(console, ...args);
|
||||
return;
|
||||
}
|
||||
|
||||
const format = args[0].replace('Warning: ', '');
|
||||
const filterResult = LogBoxData.checkWarningFilter(format);
|
||||
if (filterResult.suppressCompletely) {
|
||||
return;
|
||||
}
|
||||
|
||||
args[0] = filterResult.finalFormat;
|
||||
const {category, message, stack} = YellowBoxWarning.parse({
|
||||
args,
|
||||
});
|
||||
|
||||
if (YellowBoxRegistry.isWarningIgnored(message)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (filterResult.forceDialogImmediately === true) {
|
||||
// This will pop a redbox. Do not downgrade. These are real bugs with same severity as throws.
|
||||
error.call(console, message.content);
|
||||
} else {
|
||||
// Unfortunately, we need to add the Warning: prefix back so we don't show a redbox later.
|
||||
args[0] = `Warning: ${filterResult.finalFormat}`;
|
||||
|
||||
// Note: YellowBox has no concept of "soft errors" so we're showing YellowBox for those.
|
||||
YellowBoxRegistry.add({category, message, stack});
|
||||
error.call(console, ...args);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
YellowBox = class extends React.Component<Props, State> {
|
||||
@@ -162,6 +211,13 @@ if (__DEV__) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
static __unstable_enableLogBox(): void {
|
||||
// Do nothing.
|
||||
}
|
||||
static __unstable_isLogBoxEnabled(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
render(): React.Node {
|
||||
return null;
|
||||
}
|
||||
@@ -172,5 +228,7 @@ module.exports = (YellowBox: Class<React.Component<Props, State>> & {
|
||||
ignoreWarnings($ReadOnlyArray<IgnorePattern>): void,
|
||||
install(): void,
|
||||
uninstall(): void,
|
||||
__unstable_enableLogBox(): void,
|
||||
__unstable_isLogBoxEnabled(): boolean,
|
||||
...
|
||||
});
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const React = require('react');
|
||||
|
||||
import type {Category} from './Data/YellowBoxCategory';
|
||||
import type {Registry, Subscription} from './Data/YellowBoxRegistry';
|
||||
|
||||
type Props = $ReadOnly<{||}>;
|
||||
type State = $ReadOnly<{|
|
||||
registry: ?Registry,
|
||||
|}>;
|
||||
|
||||
const YellowBoxList = require('./UI/YellowBoxList');
|
||||
const YellowBoxRegistry = require('./Data/YellowBoxRegistry');
|
||||
|
||||
class YellowBoxContainer extends React.Component<Props, State> {
|
||||
_subscription: ?Subscription;
|
||||
|
||||
state: State = {
|
||||
registry: null,
|
||||
};
|
||||
|
||||
render(): React.Node {
|
||||
// TODO: Ignore warnings that fire when rendering `YellowBox` itself.
|
||||
return this.state.registry == null ? null : (
|
||||
<YellowBoxList
|
||||
onDismiss={this._handleDismiss}
|
||||
onDismissAll={this._handleDismissAll}
|
||||
registry={this.state.registry}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
this._subscription = YellowBoxRegistry.observe(registry => {
|
||||
this.setState({registry});
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount(): void {
|
||||
if (this._subscription != null) {
|
||||
this._subscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
_handleDismiss = (category: Category): void => {
|
||||
YellowBoxRegistry.delete(category);
|
||||
};
|
||||
|
||||
_handleDismissAll(): void {
|
||||
YellowBoxRegistry.clear();
|
||||
}
|
||||
}
|
||||
|
||||
export default YellowBoxContainer;
|
||||
@@ -11,20 +11,62 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const YellowBox = require('../YellowBox');
|
||||
import * as React from 'react';
|
||||
const YellowBoxRegistry = require('../Data/YellowBoxRegistry');
|
||||
const LogBoxData = require('../../LogBox/Data/LogBoxData');
|
||||
const render = require('../../../jest/renderer');
|
||||
jest.mock('../../NativeModules/specs/NativeLogBox', () => true);
|
||||
jest.mock('../../LogBox/LogBoxNotificationContainer', () => ({
|
||||
__esModule: true,
|
||||
default: 'LogBoxNotificationContainer',
|
||||
}));
|
||||
|
||||
type Overrides = {|
|
||||
forceDialogImmediately?: boolean,
|
||||
suppressDialog_LEGACY?: boolean,
|
||||
suppressCompletely?: boolean,
|
||||
|};
|
||||
|
||||
const setFilter = (options?: Overrides) => {
|
||||
LogBoxData.setWarningFilter(format => ({
|
||||
finalFormat: format,
|
||||
forceDialogImmediately: false,
|
||||
suppressDialog_LEGACY: false,
|
||||
suppressCompletely: false,
|
||||
monitorEvent: null,
|
||||
monitorListVersion: 0,
|
||||
monitorSampleRate: 0,
|
||||
...options,
|
||||
}));
|
||||
};
|
||||
|
||||
const install = () => {
|
||||
const YellowBox = require('../YellowBox');
|
||||
YellowBox.install();
|
||||
};
|
||||
|
||||
const uninstall = () => {
|
||||
const YellowBox = require('../YellowBox');
|
||||
YellowBox.uninstall();
|
||||
};
|
||||
|
||||
describe('YellowBox', () => {
|
||||
const {error, warn} = console;
|
||||
const mockError = jest.fn();
|
||||
const mockWarn = jest.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
(console: any).error = jest.fn();
|
||||
(console: any).warn = jest.fn();
|
||||
|
||||
mockError.mockClear();
|
||||
mockWarn.mockClear();
|
||||
|
||||
(console: any).error = mockError;
|
||||
(console: any).warn = mockWarn;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
YellowBox.uninstall();
|
||||
uninstall();
|
||||
(console: any).error = error;
|
||||
(console: any).warn = warn;
|
||||
});
|
||||
@@ -32,7 +74,7 @@ describe('YellowBox', () => {
|
||||
it('can set `disableYellowBox` after installing', () => {
|
||||
expect((console: any).disableYellowBox).toBe(undefined);
|
||||
|
||||
YellowBox.install();
|
||||
install();
|
||||
|
||||
expect((console: any).disableYellowBox).toBe(false);
|
||||
expect(YellowBoxRegistry.isDisabled()).toBe(false);
|
||||
@@ -47,7 +89,7 @@ describe('YellowBox', () => {
|
||||
expect((console: any).disableYellowBox).toBe(undefined);
|
||||
|
||||
(console: any).disableYellowBox = true;
|
||||
YellowBox.install();
|
||||
install();
|
||||
|
||||
expect((console: any).disableYellowBox).toBe(true);
|
||||
expect(YellowBoxRegistry.isDisabled()).toBe(true);
|
||||
@@ -56,22 +98,173 @@ describe('YellowBox', () => {
|
||||
it('registers warnings', () => {
|
||||
jest.mock('../Data/YellowBoxRegistry');
|
||||
|
||||
YellowBox.install();
|
||||
install();
|
||||
|
||||
expect(YellowBoxRegistry.add).not.toBeCalled();
|
||||
(console: any).warn('...');
|
||||
expect(YellowBoxRegistry.add).toBeCalled();
|
||||
expect(mockWarn).toBeCalledTimes(1);
|
||||
expect(mockWarn).toBeCalledWith('...');
|
||||
});
|
||||
|
||||
it('registers errors beginning with "Warning: "', () => {
|
||||
it('registers errors', () => {
|
||||
jest.mock('../Data/YellowBoxRegistry');
|
||||
|
||||
YellowBox.install();
|
||||
install();
|
||||
|
||||
(console: any).error('...');
|
||||
expect(YellowBoxRegistry.add).not.toBeCalled();
|
||||
expect(mockError).toBeCalledTimes(1);
|
||||
expect(mockError).toBeCalledWith('...');
|
||||
});
|
||||
|
||||
it('skips ADVICE warnings', () => {
|
||||
jest.mock('../Data/YellowBoxRegistry');
|
||||
|
||||
install();
|
||||
|
||||
(console: any).warn('(ADVICE) Ignore me');
|
||||
expect(YellowBoxRegistry.add).not.toBeCalled();
|
||||
expect(mockWarn).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('skips ignored warnings', () => {
|
||||
jest.mock('../Data/YellowBoxRegistry');
|
||||
|
||||
install();
|
||||
|
||||
(YellowBoxRegistry: any).isWarningIgnored.mockReturnValue(true);
|
||||
(console: any).warn('Ignore me');
|
||||
expect(YellowBoxRegistry.add).not.toBeCalled();
|
||||
expect(mockWarn).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('registers Warning module errors with default options to YellowBox', () => {
|
||||
jest.mock('../Data/YellowBoxRegistry');
|
||||
|
||||
setFilter();
|
||||
install();
|
||||
|
||||
(console: any).error('Warning: ...');
|
||||
expect(YellowBoxRegistry.add).toBeCalled();
|
||||
expect(mockError).toBeCalled();
|
||||
expect(mockError).toBeCalledTimes(1);
|
||||
expect(mockWarn).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('skips Warning module errors with forceDialogImmediately', () => {
|
||||
jest.mock('../Data/YellowBoxRegistry');
|
||||
|
||||
setFilter({
|
||||
suppressCompletely: true,
|
||||
});
|
||||
install();
|
||||
|
||||
(console: any).error('Warning: ...');
|
||||
expect(YellowBoxRegistry.add).not.toBeCalled();
|
||||
expect(mockError).not.toBeCalled();
|
||||
expect(mockWarn).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('registers Warning errors with forceDialogImmediately as console.error (with interpolation)', () => {
|
||||
jest.mock('../Data/YellowBoxRegistry');
|
||||
|
||||
setFilter({
|
||||
forceDialogImmediately: true,
|
||||
});
|
||||
|
||||
install();
|
||||
|
||||
(console: any).error('Warning: %s', 'Something');
|
||||
expect(YellowBoxRegistry.add).not.toBeCalled();
|
||||
expect(mockWarn).not.toBeCalled();
|
||||
expect(mockError).toBeCalledTimes(1);
|
||||
|
||||
// We expect this to be the interpolated value because we don't do interpolation downstream.
|
||||
// We also strip the "Warning" prefix, otherwise the redbox would be skipped downstream.
|
||||
expect(mockError).toBeCalledWith('Something');
|
||||
});
|
||||
|
||||
it('registers Warning errors with suppressDialog_LEGACY to YellowBox', () => {
|
||||
jest.mock('../Data/YellowBoxRegistry');
|
||||
|
||||
setFilter({
|
||||
suppressDialog_LEGACY: true,
|
||||
});
|
||||
|
||||
install();
|
||||
|
||||
(console: any).error('Warning: Something');
|
||||
expect(YellowBoxRegistry.add).toBeCalledTimes(1);
|
||||
expect(mockWarn).not.toBeCalled();
|
||||
expect(mockError).toBeCalledTimes(1);
|
||||
|
||||
// We cannot strip the "Warning" prefix or it would pop a redbox.
|
||||
expect(mockError).toBeCalledWith('Warning: Something');
|
||||
});
|
||||
|
||||
it('skips Warning errors sent to YellowBox but ignored by patterns', () => {
|
||||
jest.mock('../Data/YellowBoxRegistry');
|
||||
|
||||
setFilter({
|
||||
suppressDialog_LEGACY: true,
|
||||
});
|
||||
|
||||
install();
|
||||
(YellowBoxRegistry: any).isWarningIgnored.mockReturnValue(true);
|
||||
|
||||
(console: any).error('Warning: ...');
|
||||
expect(YellowBoxRegistry.add).not.toBeCalled();
|
||||
expect(mockWarn).not.toBeCalled();
|
||||
expect(mockError).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('if LogBox is enabled, installs and uninstalls LogBox', () => {
|
||||
jest.mock('../../LogBox/Data/LogBoxData');
|
||||
jest.mock('../Data/YellowBoxRegistry');
|
||||
const YellowBox = require('../YellowBox');
|
||||
YellowBox.__unstable_enableLogBox();
|
||||
install();
|
||||
|
||||
(console: any).warn('Some warning');
|
||||
expect(YellowBoxRegistry.add).not.toBeCalled();
|
||||
expect(LogBoxData.addLog).toBeCalled();
|
||||
expect(require('../YellowBox').__unstable_isLogBoxEnabled()).toBe(true);
|
||||
|
||||
uninstall();
|
||||
(LogBoxData.addLog: any).mockClear();
|
||||
|
||||
(console: any).warn('Some warning');
|
||||
expect(YellowBoxRegistry.add).not.toBeCalled();
|
||||
expect(LogBoxData.addLog).not.toBeCalled();
|
||||
expect(YellowBox.__unstable_isLogBoxEnabled()).toBe(true);
|
||||
});
|
||||
|
||||
it('throws if LogBox is enabled after YellowBox is installed', () => {
|
||||
jest.mock('../Data/YellowBoxRegistry');
|
||||
const YellowBox = require('../YellowBox');
|
||||
install();
|
||||
|
||||
expect(() => YellowBox.__unstable_enableLogBox()).toThrow(
|
||||
'LogBox must be enabled before AppContainer is required so that it can properly wrap the console methods.\n\nPlease enable LogBox earlier in your app.\n\n',
|
||||
);
|
||||
});
|
||||
|
||||
it('should render YellowBoxContainer by default', () => {
|
||||
const YellowBox = require('../YellowBox');
|
||||
|
||||
const output = render.shallowRender(<YellowBox />);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render LogBoxNotificationContainer when LogBox is enabled', () => {
|
||||
const YellowBox = require('../YellowBox');
|
||||
|
||||
YellowBox.__unstable_enableLogBox();
|
||||
|
||||
const output = render.shallowRender(<YellowBox />);
|
||||
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`YellowBox should render LogBoxNotificationContainer when LogBox is enabled 1`] = `<LogBoxNotificationContainer />`;
|
||||
|
||||
exports[`YellowBox should render YellowBoxContainer by default 1`] = `<YellowBoxContainer />`;
|
||||
+49
-1
@@ -17,15 +17,62 @@ def pods()
|
||||
# Additional Pods which aren't included in the default Podfile
|
||||
pod 'React-ART', :path => '../Libraries/ART'
|
||||
pod 'React-RCTPushNotification', :path => '../Libraries/PushNotificationIOS'
|
||||
|
||||
pod 'Yoga',:path => '../ReactCommon/yoga', :modular_headers => true
|
||||
# Additional Pods which are classed as unstable
|
||||
#
|
||||
# To use fabric: add `fabric_enabled` option to the use_react_native method above, like below
|
||||
# use_react_native!(path: "..", fabric_enabled: true)
|
||||
end
|
||||
|
||||
|
||||
def flipper_pods()
|
||||
flipperkit_version = '0.30.1'
|
||||
pod 'FlipperKit', '~>' + flipperkit_version, :configuration => 'Debug'
|
||||
pod 'FlipperKit/FlipperKitLayoutPlugin', '~>' + flipperkit_version, :configuration => 'Debug'
|
||||
pod 'FlipperKit/SKIOSNetworkPlugin', '~>' + flipperkit_version, :configuration => 'Debug'
|
||||
pod 'FlipperKit/FlipperKitUserDefaultsPlugin', '~>' + flipperkit_version, :configuration => 'Debug'
|
||||
pod 'FlipperKit/FlipperKitReactPlugin', '~>' + flipperkit_version, :configuration => 'Debug'
|
||||
|
||||
if ENV['USE_FRAMEWORKS'] == '1'
|
||||
$static_framework = ['FlipperKit', 'Flipper', 'Flipper-Folly',
|
||||
'CocoaAsyncSocket', 'ComponentKit', 'Flipper-DoubleConversion',
|
||||
'Flipper-Glog', 'Flipper-PeerTalk', 'Flipper-RSocket',
|
||||
'CocoaLibEvent', 'OpenSSL-Universal', 'boost-for-react-native']
|
||||
|
||||
pre_install do |installer|
|
||||
Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_static_framework_transitive_dependencies) {}
|
||||
installer.pod_targets.each do |pod|
|
||||
if $static_framework.include?(pod.name)
|
||||
def pod.build_type;
|
||||
Pod::Target::BuildType.static_library
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Post Install processing for Flipper
|
||||
def flipper_post_install(installer)
|
||||
file_name = Dir.glob("*.xcodeproj")[0]
|
||||
app_project = Xcodeproj::Project.open(file_name)
|
||||
app_project.native_targets.each do |target|
|
||||
target.build_configurations.each do |config|
|
||||
cflags = config.build_settings['OTHER_CFLAGS'] || '$(inherited) '
|
||||
unless cflags.include? '-DFB_SONARKIT_ENABLED=1'
|
||||
puts 'Adding -DFB_SONARKIT_ENABLED=1 in OTHER_CFLAGS...'
|
||||
cflags << ' -DFB_SONARKIT_ENABLED=1 '
|
||||
end
|
||||
config.build_settings['OTHER_CFLAGS'] = cflags
|
||||
end
|
||||
app_project.save
|
||||
end
|
||||
installer.pods_project.save
|
||||
end
|
||||
|
||||
target 'RNTester' do
|
||||
pods()
|
||||
flipper_pods()
|
||||
end
|
||||
|
||||
target 'RNTesterUnitTests' do
|
||||
@@ -39,6 +86,7 @@ target 'RNTesterIntegrationTests' do
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
flipper_post_install(installer)
|
||||
installer.pods_project.targets.each do |target|
|
||||
puts target.name
|
||||
end
|
||||
|
||||
+275
-201
@@ -1,14 +1,60 @@
|
||||
PODS:
|
||||
- boost-for-react-native (1.63.0)
|
||||
- CocoaAsyncSocket (7.6.3)
|
||||
- CocoaLibEvent (1.0.0)
|
||||
- DoubleConversion (1.1.6)
|
||||
- FBLazyVector (1000.0.0)
|
||||
- FBReactNativeSpec (1000.0.0):
|
||||
- FBLazyVector (0.62.0-rc.1)
|
||||
- FBReactNativeSpec (0.62.0-rc.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- RCTRequired (= 1000.0.0)
|
||||
- RCTTypeSafety (= 1000.0.0)
|
||||
- React-Core (= 1000.0.0)
|
||||
- React-jsi (= 1000.0.0)
|
||||
- ReactCommon/turbomodule/core (= 1000.0.0)
|
||||
- RCTRequired (= 0.62.0-rc.1)
|
||||
- RCTTypeSafety (= 0.62.0-rc.1)
|
||||
- React-Core (= 0.62.0-rc.1)
|
||||
- React-jsi (= 0.62.0-rc.1)
|
||||
- ReactCommon/turbomodule/core (= 0.62.0-rc.1)
|
||||
- Flipper (0.30.1):
|
||||
- Flipper-Folly (~> 2.1)
|
||||
- Flipper-RSocket (~> 1.0)
|
||||
- Flipper-Folly (2.1.0):
|
||||
- boost-for-react-native
|
||||
- CocoaLibEvent (~> 1.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- OpenSSL-Universal (= 1.0.2.19)
|
||||
- Flipper-PeerTalk (0.0.4)
|
||||
- Flipper-RSocket (1.0.0):
|
||||
- Flipper-Folly (~> 2.0)
|
||||
- FlipperKit (0.30.1):
|
||||
- FlipperKit/Core (= 0.30.1)
|
||||
- FlipperKit/Core (0.30.1):
|
||||
- Flipper (~> 0.30.1)
|
||||
- FlipperKit/CppBridge
|
||||
- FlipperKit/FBCxxFollyDynamicConvert
|
||||
- FlipperKit/FBDefines
|
||||
- FlipperKit/FKPortForwarding
|
||||
- FlipperKit/CppBridge (0.30.1):
|
||||
- Flipper (~> 0.30.1)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (0.30.1):
|
||||
- Flipper-Folly (~> 2.1)
|
||||
- FlipperKit/FBDefines (0.30.1)
|
||||
- FlipperKit/FKPortForwarding (0.30.1):
|
||||
- CocoaAsyncSocket (~> 7.6)
|
||||
- Flipper-PeerTalk (~> 0.0.4)
|
||||
- FlipperKit/FlipperKitHighlightOverlay (0.30.1)
|
||||
- FlipperKit/FlipperKitLayoutPlugin (0.30.1):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitHighlightOverlay
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable
|
||||
- YogaKit (~> 1.18)
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (0.30.1)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (0.30.1):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitReactPlugin (0.30.1):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (0.30.1):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/SKIOSNetworkPlugin (0.30.1):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitNetworkPlugin
|
||||
- Folly (2018.10.22.00):
|
||||
- boost-for-react-native
|
||||
- DoubleConversion
|
||||
@@ -19,269 +65,279 @@ PODS:
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- glog (0.3.5)
|
||||
- RCTRequired (1000.0.0)
|
||||
- RCTTypeSafety (1000.0.0):
|
||||
- FBLazyVector (= 1000.0.0)
|
||||
- OpenSSL-Universal (1.0.2.19):
|
||||
- OpenSSL-Universal/Static (= 1.0.2.19)
|
||||
- OpenSSL-Universal/Static (1.0.2.19)
|
||||
- RCTRequired (0.62.0-rc.1)
|
||||
- RCTTypeSafety (0.62.0-rc.1):
|
||||
- FBLazyVector (= 0.62.0-rc.1)
|
||||
- Folly (= 2018.10.22.00)
|
||||
- RCTRequired (= 1000.0.0)
|
||||
- React-Core (= 1000.0.0)
|
||||
- React (1000.0.0):
|
||||
- React-Core (= 1000.0.0)
|
||||
- React-Core/DevSupport (= 1000.0.0)
|
||||
- React-Core/RCTWebSocket (= 1000.0.0)
|
||||
- React-RCTActionSheet (= 1000.0.0)
|
||||
- React-RCTAnimation (= 1000.0.0)
|
||||
- React-RCTBlob (= 1000.0.0)
|
||||
- React-RCTImage (= 1000.0.0)
|
||||
- React-RCTLinking (= 1000.0.0)
|
||||
- React-RCTNetwork (= 1000.0.0)
|
||||
- React-RCTSettings (= 1000.0.0)
|
||||
- React-RCTText (= 1000.0.0)
|
||||
- React-RCTVibration (= 1000.0.0)
|
||||
- React-ART (1000.0.0):
|
||||
- React-Core/ARTHeaders (= 1000.0.0)
|
||||
- React-Core (1000.0.0):
|
||||
- RCTRequired (= 0.62.0-rc.1)
|
||||
- React-Core (= 0.62.0-rc.1)
|
||||
- React (0.62.0-rc.1):
|
||||
- React-Core (= 0.62.0-rc.1)
|
||||
- React-Core/DevSupport (= 0.62.0-rc.1)
|
||||
- React-Core/RCTWebSocket (= 0.62.0-rc.1)
|
||||
- React-RCTActionSheet (= 0.62.0-rc.1)
|
||||
- React-RCTAnimation (= 0.62.0-rc.1)
|
||||
- React-RCTBlob (= 0.62.0-rc.1)
|
||||
- React-RCTImage (= 0.62.0-rc.1)
|
||||
- React-RCTLinking (= 0.62.0-rc.1)
|
||||
- React-RCTNetwork (= 0.62.0-rc.1)
|
||||
- React-RCTSettings (= 0.62.0-rc.1)
|
||||
- React-RCTText (= 0.62.0-rc.1)
|
||||
- React-RCTVibration (= 0.62.0-rc.1)
|
||||
- React-ART (0.62.0-rc.1):
|
||||
- React-Core/ARTHeaders (= 0.62.0-rc.1)
|
||||
- React-Core (0.62.0-rc.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default (= 1000.0.0)
|
||||
- React-cxxreact (= 1000.0.0)
|
||||
- React-jsi (= 1000.0.0)
|
||||
- React-jsiexecutor (= 1000.0.0)
|
||||
- React-Core/Default (= 0.62.0-rc.1)
|
||||
- React-cxxreact (= 0.62.0-rc.1)
|
||||
- React-jsi (= 0.62.0-rc.1)
|
||||
- React-jsiexecutor (= 0.62.0-rc.1)
|
||||
- Yoga
|
||||
- React-Core/ARTHeaders (1000.0.0):
|
||||
- React-Core/ARTHeaders (0.62.0-rc.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 1000.0.0)
|
||||
- React-jsi (= 1000.0.0)
|
||||
- React-jsiexecutor (= 1000.0.0)
|
||||
- React-cxxreact (= 0.62.0-rc.1)
|
||||
- React-jsi (= 0.62.0-rc.1)
|
||||
- React-jsiexecutor (= 0.62.0-rc.1)
|
||||
- Yoga
|
||||
- React-Core/CoreModulesHeaders (1000.0.0):
|
||||
- React-Core/CoreModulesHeaders (0.62.0-rc.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 1000.0.0)
|
||||
- React-jsi (= 1000.0.0)
|
||||
- React-jsiexecutor (= 1000.0.0)
|
||||
- React-cxxreact (= 0.62.0-rc.1)
|
||||
- React-jsi (= 0.62.0-rc.1)
|
||||
- React-jsiexecutor (= 0.62.0-rc.1)
|
||||
- Yoga
|
||||
- React-Core/Default (1000.0.0):
|
||||
- React-Core/Default (0.62.0-rc.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-cxxreact (= 1000.0.0)
|
||||
- React-jsi (= 1000.0.0)
|
||||
- React-jsiexecutor (= 1000.0.0)
|
||||
- React-cxxreact (= 0.62.0-rc.1)
|
||||
- React-jsi (= 0.62.0-rc.1)
|
||||
- React-jsiexecutor (= 0.62.0-rc.1)
|
||||
- Yoga
|
||||
- React-Core/DevSupport (1000.0.0):
|
||||
- React-Core/DevSupport (0.62.0-rc.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default (= 1000.0.0)
|
||||
- React-Core/RCTWebSocket (= 1000.0.0)
|
||||
- React-cxxreact (= 1000.0.0)
|
||||
- React-jsi (= 1000.0.0)
|
||||
- React-jsiexecutor (= 1000.0.0)
|
||||
- React-jsinspector (= 1000.0.0)
|
||||
- React-Core/Default (= 0.62.0-rc.1)
|
||||
- React-Core/RCTWebSocket (= 0.62.0-rc.1)
|
||||
- React-cxxreact (= 0.62.0-rc.1)
|
||||
- React-jsi (= 0.62.0-rc.1)
|
||||
- React-jsiexecutor (= 0.62.0-rc.1)
|
||||
- React-jsinspector (= 0.62.0-rc.1)
|
||||
- Yoga
|
||||
- React-Core/RCTActionSheetHeaders (1000.0.0):
|
||||
- React-Core/RCTActionSheetHeaders (0.62.0-rc.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 1000.0.0)
|
||||
- React-jsi (= 1000.0.0)
|
||||
- React-jsiexecutor (= 1000.0.0)
|
||||
- React-cxxreact (= 0.62.0-rc.1)
|
||||
- React-jsi (= 0.62.0-rc.1)
|
||||
- React-jsiexecutor (= 0.62.0-rc.1)
|
||||
- Yoga
|
||||
- React-Core/RCTAnimationHeaders (1000.0.0):
|
||||
- React-Core/RCTAnimationHeaders (0.62.0-rc.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 1000.0.0)
|
||||
- React-jsi (= 1000.0.0)
|
||||
- React-jsiexecutor (= 1000.0.0)
|
||||
- React-cxxreact (= 0.62.0-rc.1)
|
||||
- React-jsi (= 0.62.0-rc.1)
|
||||
- React-jsiexecutor (= 0.62.0-rc.1)
|
||||
- Yoga
|
||||
- React-Core/RCTBlobHeaders (1000.0.0):
|
||||
- React-Core/RCTBlobHeaders (0.62.0-rc.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 1000.0.0)
|
||||
- React-jsi (= 1000.0.0)
|
||||
- React-jsiexecutor (= 1000.0.0)
|
||||
- React-cxxreact (= 0.62.0-rc.1)
|
||||
- React-jsi (= 0.62.0-rc.1)
|
||||
- React-jsiexecutor (= 0.62.0-rc.1)
|
||||
- Yoga
|
||||
- React-Core/RCTImageHeaders (1000.0.0):
|
||||
- React-Core/RCTImageHeaders (0.62.0-rc.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 1000.0.0)
|
||||
- React-jsi (= 1000.0.0)
|
||||
- React-jsiexecutor (= 1000.0.0)
|
||||
- React-cxxreact (= 0.62.0-rc.1)
|
||||
- React-jsi (= 0.62.0-rc.1)
|
||||
- React-jsiexecutor (= 0.62.0-rc.1)
|
||||
- Yoga
|
||||
- React-Core/RCTLinkingHeaders (1000.0.0):
|
||||
- React-Core/RCTLinkingHeaders (0.62.0-rc.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 1000.0.0)
|
||||
- React-jsi (= 1000.0.0)
|
||||
- React-jsiexecutor (= 1000.0.0)
|
||||
- React-cxxreact (= 0.62.0-rc.1)
|
||||
- React-jsi (= 0.62.0-rc.1)
|
||||
- React-jsiexecutor (= 0.62.0-rc.1)
|
||||
- Yoga
|
||||
- React-Core/RCTNetworkHeaders (1000.0.0):
|
||||
- React-Core/RCTNetworkHeaders (0.62.0-rc.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 1000.0.0)
|
||||
- React-jsi (= 1000.0.0)
|
||||
- React-jsiexecutor (= 1000.0.0)
|
||||
- React-cxxreact (= 0.62.0-rc.1)
|
||||
- React-jsi (= 0.62.0-rc.1)
|
||||
- React-jsiexecutor (= 0.62.0-rc.1)
|
||||
- Yoga
|
||||
- React-Core/RCTPushNotificationHeaders (1000.0.0):
|
||||
- React-Core/RCTPushNotificationHeaders (0.62.0-rc.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 1000.0.0)
|
||||
- React-jsi (= 1000.0.0)
|
||||
- React-jsiexecutor (= 1000.0.0)
|
||||
- React-cxxreact (= 0.62.0-rc.1)
|
||||
- React-jsi (= 0.62.0-rc.1)
|
||||
- React-jsiexecutor (= 0.62.0-rc.1)
|
||||
- Yoga
|
||||
- React-Core/RCTSettingsHeaders (1000.0.0):
|
||||
- React-Core/RCTSettingsHeaders (0.62.0-rc.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 1000.0.0)
|
||||
- React-jsi (= 1000.0.0)
|
||||
- React-jsiexecutor (= 1000.0.0)
|
||||
- React-cxxreact (= 0.62.0-rc.1)
|
||||
- React-jsi (= 0.62.0-rc.1)
|
||||
- React-jsiexecutor (= 0.62.0-rc.1)
|
||||
- Yoga
|
||||
- React-Core/RCTTextHeaders (1000.0.0):
|
||||
- React-Core/RCTTextHeaders (0.62.0-rc.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 1000.0.0)
|
||||
- React-jsi (= 1000.0.0)
|
||||
- React-jsiexecutor (= 1000.0.0)
|
||||
- React-cxxreact (= 0.62.0-rc.1)
|
||||
- React-jsi (= 0.62.0-rc.1)
|
||||
- React-jsiexecutor (= 0.62.0-rc.1)
|
||||
- Yoga
|
||||
- React-Core/RCTVibrationHeaders (1000.0.0):
|
||||
- React-Core/RCTVibrationHeaders (0.62.0-rc.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 1000.0.0)
|
||||
- React-jsi (= 1000.0.0)
|
||||
- React-jsiexecutor (= 1000.0.0)
|
||||
- React-cxxreact (= 0.62.0-rc.1)
|
||||
- React-jsi (= 0.62.0-rc.1)
|
||||
- React-jsiexecutor (= 0.62.0-rc.1)
|
||||
- Yoga
|
||||
- React-Core/RCTWebSocket (1000.0.0):
|
||||
- React-Core/RCTWebSocket (0.62.0-rc.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default (= 1000.0.0)
|
||||
- React-cxxreact (= 1000.0.0)
|
||||
- React-jsi (= 1000.0.0)
|
||||
- React-jsiexecutor (= 1000.0.0)
|
||||
- React-Core/Default (= 0.62.0-rc.1)
|
||||
- React-cxxreact (= 0.62.0-rc.1)
|
||||
- React-jsi (= 0.62.0-rc.1)
|
||||
- React-jsiexecutor (= 0.62.0-rc.1)
|
||||
- Yoga
|
||||
- React-CoreModules (1000.0.0):
|
||||
- FBReactNativeSpec (= 1000.0.0)
|
||||
- React-CoreModules (0.62.0-rc.1):
|
||||
- FBReactNativeSpec (= 0.62.0-rc.1)
|
||||
- Folly (= 2018.10.22.00)
|
||||
- RCTTypeSafety (= 1000.0.0)
|
||||
- React-Core/CoreModulesHeaders (= 1000.0.0)
|
||||
- React-RCTImage (= 1000.0.0)
|
||||
- ReactCommon/turbomodule/core (= 1000.0.0)
|
||||
- React-cxxreact (1000.0.0):
|
||||
- RCTTypeSafety (= 0.62.0-rc.1)
|
||||
- React-Core/CoreModulesHeaders (= 0.62.0-rc.1)
|
||||
- React-RCTImage (= 0.62.0-rc.1)
|
||||
- ReactCommon/turbomodule/core (= 0.62.0-rc.1)
|
||||
- React-cxxreact (0.62.0-rc.1):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-jsinspector (= 1000.0.0)
|
||||
- React-jsi (1000.0.0):
|
||||
- React-jsinspector (= 0.62.0-rc.1)
|
||||
- React-jsi (0.62.0-rc.1):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-jsi/Default (= 1000.0.0)
|
||||
- React-jsi/Default (1000.0.0):
|
||||
- React-jsi/Default (= 0.62.0-rc.1)
|
||||
- React-jsi/Default (0.62.0-rc.1):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-jsiexecutor (1000.0.0):
|
||||
- React-jsiexecutor (0.62.0-rc.1):
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-cxxreact (= 1000.0.0)
|
||||
- React-jsi (= 1000.0.0)
|
||||
- React-jsinspector (1000.0.0)
|
||||
- React-RCTActionSheet (1000.0.0):
|
||||
- React-Core/RCTActionSheetHeaders (= 1000.0.0)
|
||||
- React-RCTAnimation (1000.0.0):
|
||||
- FBReactNativeSpec (= 1000.0.0)
|
||||
- React-cxxreact (= 0.62.0-rc.1)
|
||||
- React-jsi (= 0.62.0-rc.1)
|
||||
- React-jsinspector (0.62.0-rc.1)
|
||||
- React-RCTActionSheet (0.62.0-rc.1):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.62.0-rc.1)
|
||||
- React-RCTAnimation (0.62.0-rc.1):
|
||||
- FBReactNativeSpec (= 0.62.0-rc.1)
|
||||
- Folly (= 2018.10.22.00)
|
||||
- RCTTypeSafety (= 1000.0.0)
|
||||
- React-Core/RCTAnimationHeaders (= 1000.0.0)
|
||||
- ReactCommon/turbomodule/core (= 1000.0.0)
|
||||
- React-RCTBlob (1000.0.0):
|
||||
- FBReactNativeSpec (= 1000.0.0)
|
||||
- RCTTypeSafety (= 0.62.0-rc.1)
|
||||
- React-Core/RCTAnimationHeaders (= 0.62.0-rc.1)
|
||||
- ReactCommon/turbomodule/core (= 0.62.0-rc.1)
|
||||
- React-RCTBlob (0.62.0-rc.1):
|
||||
- FBReactNativeSpec (= 0.62.0-rc.1)
|
||||
- Folly (= 2018.10.22.00)
|
||||
- React-Core/RCTBlobHeaders (= 1000.0.0)
|
||||
- React-Core/RCTWebSocket (= 1000.0.0)
|
||||
- React-jsi (= 1000.0.0)
|
||||
- React-RCTNetwork (= 1000.0.0)
|
||||
- ReactCommon/turbomodule/core (= 1000.0.0)
|
||||
- React-RCTImage (1000.0.0):
|
||||
- FBReactNativeSpec (= 1000.0.0)
|
||||
- React-Core/RCTBlobHeaders (= 0.62.0-rc.1)
|
||||
- React-Core/RCTWebSocket (= 0.62.0-rc.1)
|
||||
- React-jsi (= 0.62.0-rc.1)
|
||||
- React-RCTNetwork (= 0.62.0-rc.1)
|
||||
- ReactCommon/turbomodule/core (= 0.62.0-rc.1)
|
||||
- React-RCTImage (0.62.0-rc.1):
|
||||
- FBReactNativeSpec (= 0.62.0-rc.1)
|
||||
- Folly (= 2018.10.22.00)
|
||||
- RCTTypeSafety (= 1000.0.0)
|
||||
- React-Core/RCTImageHeaders (= 1000.0.0)
|
||||
- React-RCTNetwork (= 1000.0.0)
|
||||
- ReactCommon/turbomodule/core (= 1000.0.0)
|
||||
- React-RCTLinking (1000.0.0):
|
||||
- FBReactNativeSpec (= 1000.0.0)
|
||||
- React-Core/RCTLinkingHeaders (= 1000.0.0)
|
||||
- ReactCommon/turbomodule/core (= 1000.0.0)
|
||||
- React-RCTNetwork (1000.0.0):
|
||||
- FBReactNativeSpec (= 1000.0.0)
|
||||
- RCTTypeSafety (= 0.62.0-rc.1)
|
||||
- React-Core/RCTImageHeaders (= 0.62.0-rc.1)
|
||||
- React-RCTNetwork (= 0.62.0-rc.1)
|
||||
- ReactCommon/turbomodule/core (= 0.62.0-rc.1)
|
||||
- React-RCTLinking (0.62.0-rc.1):
|
||||
- FBReactNativeSpec (= 0.62.0-rc.1)
|
||||
- React-Core/RCTLinkingHeaders (= 0.62.0-rc.1)
|
||||
- ReactCommon/turbomodule/core (= 0.62.0-rc.1)
|
||||
- React-RCTNetwork (0.62.0-rc.1):
|
||||
- FBReactNativeSpec (= 0.62.0-rc.1)
|
||||
- Folly (= 2018.10.22.00)
|
||||
- RCTTypeSafety (= 1000.0.0)
|
||||
- React-Core/RCTNetworkHeaders (= 1000.0.0)
|
||||
- ReactCommon/turbomodule/core (= 1000.0.0)
|
||||
- React-RCTPushNotification (1000.0.0):
|
||||
- FBReactNativeSpec (= 1000.0.0)
|
||||
- RCTTypeSafety (= 1000.0.0)
|
||||
- React-Core/RCTPushNotificationHeaders (= 1000.0.0)
|
||||
- ReactCommon/turbomodule/core (= 1000.0.0)
|
||||
- React-RCTSettings (1000.0.0):
|
||||
- FBReactNativeSpec (= 1000.0.0)
|
||||
- RCTTypeSafety (= 0.62.0-rc.1)
|
||||
- React-Core/RCTNetworkHeaders (= 0.62.0-rc.1)
|
||||
- ReactCommon/turbomodule/core (= 0.62.0-rc.1)
|
||||
- React-RCTPushNotification (0.62.0-rc.1):
|
||||
- FBReactNativeSpec (= 0.62.0-rc.1)
|
||||
- RCTTypeSafety (= 0.62.0-rc.1)
|
||||
- React-Core/RCTPushNotificationHeaders (= 0.62.0-rc.1)
|
||||
- ReactCommon/turbomodule/core (= 0.62.0-rc.1)
|
||||
- React-RCTSettings (0.62.0-rc.1):
|
||||
- FBReactNativeSpec (= 0.62.0-rc.1)
|
||||
- Folly (= 2018.10.22.00)
|
||||
- RCTTypeSafety (= 1000.0.0)
|
||||
- React-Core/RCTSettingsHeaders (= 1000.0.0)
|
||||
- ReactCommon/turbomodule/core (= 1000.0.0)
|
||||
- React-RCTTest (1000.0.0):
|
||||
- React-Core (= 1000.0.0)
|
||||
- React-CoreModules (= 1000.0.0)
|
||||
- React-RCTText (1000.0.0):
|
||||
- React-Core/RCTTextHeaders (= 1000.0.0)
|
||||
- React-RCTVibration (1000.0.0):
|
||||
- FBReactNativeSpec (= 1000.0.0)
|
||||
- RCTTypeSafety (= 0.62.0-rc.1)
|
||||
- React-Core/RCTSettingsHeaders (= 0.62.0-rc.1)
|
||||
- ReactCommon/turbomodule/core (= 0.62.0-rc.1)
|
||||
- React-RCTTest (0.62.0-rc.1):
|
||||
- React-Core (= 0.62.0-rc.1)
|
||||
- React-CoreModules (= 0.62.0-rc.1)
|
||||
- React-RCTText (0.62.0-rc.1):
|
||||
- React-Core/RCTTextHeaders (= 0.62.0-rc.1)
|
||||
- React-RCTVibration (0.62.0-rc.1):
|
||||
- FBReactNativeSpec (= 0.62.0-rc.1)
|
||||
- Folly (= 2018.10.22.00)
|
||||
- React-Core/RCTVibrationHeaders (= 1000.0.0)
|
||||
- ReactCommon/turbomodule/core (= 1000.0.0)
|
||||
- ReactCommon/callinvoker (1000.0.0):
|
||||
- React-Core/RCTVibrationHeaders (= 0.62.0-rc.1)
|
||||
- ReactCommon/turbomodule/core (= 0.62.0-rc.1)
|
||||
- ReactCommon/callinvoker (0.62.0-rc.1):
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-cxxreact (= 1000.0.0)
|
||||
- ReactCommon/turbomodule/core (1000.0.0):
|
||||
- React-cxxreact (= 0.62.0-rc.1)
|
||||
- ReactCommon/turbomodule/core (0.62.0-rc.1):
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core (= 1000.0.0)
|
||||
- React-cxxreact (= 1000.0.0)
|
||||
- React-jsi (= 1000.0.0)
|
||||
- ReactCommon/callinvoker (= 1000.0.0)
|
||||
- ReactCommon/turbomodule/samples (1000.0.0):
|
||||
- React-Core (= 0.62.0-rc.1)
|
||||
- React-cxxreact (= 0.62.0-rc.1)
|
||||
- React-jsi (= 0.62.0-rc.1)
|
||||
- ReactCommon/callinvoker (= 0.62.0-rc.1)
|
||||
- ReactCommon/turbomodule/samples (0.62.0-rc.1):
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core (= 1000.0.0)
|
||||
- React-cxxreact (= 1000.0.0)
|
||||
- React-jsi (= 1000.0.0)
|
||||
- ReactCommon/callinvoker (= 1000.0.0)
|
||||
- ReactCommon/turbomodule/core (= 1000.0.0)
|
||||
- React-Core (= 0.62.0-rc.1)
|
||||
- React-cxxreact (= 0.62.0-rc.1)
|
||||
- React-jsi (= 0.62.0-rc.1)
|
||||
- ReactCommon/callinvoker (= 0.62.0-rc.1)
|
||||
- ReactCommon/turbomodule/core (= 0.62.0-rc.1)
|
||||
- Yoga (1.14.0)
|
||||
- YogaKit (1.18.1):
|
||||
- Yoga (~> 1.14)
|
||||
|
||||
DEPENDENCIES:
|
||||
- DoubleConversion (from `../third-party-podspecs/DoubleConversion.podspec`)
|
||||
- FBLazyVector (from `../Libraries/FBLazyVector`)
|
||||
- FBReactNativeSpec (from `../Libraries/FBReactNativeSpec`)
|
||||
- FlipperKit (~> 0.30.1)
|
||||
- FlipperKit/FlipperKitLayoutPlugin (~> 0.30.1)
|
||||
- FlipperKit/FlipperKitReactPlugin (~> 0.30.1)
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.30.1)
|
||||
- FlipperKit/SKIOSNetworkPlugin (~> 0.30.1)
|
||||
- Folly (from `../third-party-podspecs/Folly.podspec`)
|
||||
- glog (from `../third-party-podspecs/glog.podspec`)
|
||||
- RCTRequired (from `../Libraries/RCTRequired`)
|
||||
@@ -313,8 +369,17 @@ DEPENDENCIES:
|
||||
- Yoga (from `../ReactCommon/yoga`)
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
https://cdn.cocoapods.org/:
|
||||
- boost-for-react-native
|
||||
- CocoaAsyncSocket
|
||||
- CocoaLibEvent
|
||||
- Flipper
|
||||
- Flipper-Folly
|
||||
- Flipper-PeerTalk
|
||||
- Flipper-RSocket
|
||||
- FlipperKit
|
||||
- OpenSSL-Universal
|
||||
- YogaKit
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
DoubleConversion:
|
||||
@@ -376,35 +441,44 @@ EXTERNAL SOURCES:
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
||||
DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2
|
||||
FBLazyVector: 34431b7e61740bed29b082ff81500b0ffafaffa0
|
||||
FBReactNativeSpec: e9febd2d5cc091662f172724165922b2e28d10a3
|
||||
CocoaAsyncSocket: eafaa68a7e0ec99ead0a7b35015e0bf25d2c8987
|
||||
CocoaLibEvent: 2fab71b8bd46dd33ddb959f7928ec5909f838e3f
|
||||
DoubleConversion: cde416483dac037923206447da6e1454df403714
|
||||
FBLazyVector: 9349d70d60793fce157f7c3837f51c60bc81a91b
|
||||
FBReactNativeSpec: 36215b34017aa3bb62f1ed494b50fbaa242649fb
|
||||
Flipper: d591b88245dc8c8147819aa249f911923c7417fc
|
||||
Flipper-Folly: bcae82405dafd18ac9f8d9d4902fd1c2ef2a7e77
|
||||
Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9
|
||||
Flipper-RSocket: 1260a31c05c238eabfa9bb8a64e3983049048371
|
||||
FlipperKit: 3e13631bca7c5ec0dd54ee1d096f5e5d32a5d784
|
||||
Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51
|
||||
glog: 1f3da668190260b06b429bb211bfbee5cd790c28
|
||||
RCTRequired: 33f3b89d2d82ef01c02b9b4f8146c43762e509d8
|
||||
RCTTypeSafety: 2b1cb2d92b779aa9a3522f67bd4f07e6b6d0797e
|
||||
React: 28a654b69575941571c073a656bc06795825e7f7
|
||||
React-ART: a5da06a892342d03896e0db45a7072525981f63c
|
||||
React-Core: f8656b21cfe16b1fe276686f3b921bce0fa6de4d
|
||||
React-CoreModules: 96b2f1e0b84493e6c1b7f3bb21357f24fdcfce2f
|
||||
React-cxxreact: 7c4242192149ce0205b53efaa03e3bf86ba4337c
|
||||
React-jsi: 98d1f9d8a79d2720ba6a44c2d928a77f315b7e4f
|
||||
React-jsiexecutor: c0ab8c80a6e88380d63f583690a50d4a723b47b5
|
||||
React-jsinspector: ea0a218071a11c3687cef2480580180caa6a64c0
|
||||
React-RCTActionSheet: 090e7bd7c5774d919c47c4eeff78223a7fd8c19c
|
||||
React-RCTAnimation: 891c2b3404c214dc19faee57b5f249da6deeb099
|
||||
React-RCTBlob: 8df793b30385b7ffe7e6703651043bad369cd756
|
||||
React-RCTImage: 3ee9a6cd02c7741ebe3a001d51a18c349019778f
|
||||
React-RCTLinking: 7ccb8f6dcfd4b95b68a73119aca7bca9fa530b08
|
||||
React-RCTNetwork: 565fa6cc6108db9210fe5774f04ce52edccbb8ed
|
||||
React-RCTPushNotification: 494ccfc569e2a699c0cc1a816eaebf8197a2ebc8
|
||||
React-RCTSettings: 8138286da8de74839cb436dd37704ed64d4bfe78
|
||||
React-RCTTest: d148e0657ce77ffd43a10325c284f47f25fb0532
|
||||
React-RCTText: 9078167d3bc011162326f2d8ef4dd580ec1eca17
|
||||
React-RCTVibration: e3269787c533de8c4f54f489202d848fdef33e1d
|
||||
ReactCommon: 9d212865526209dc2d01be40340c8d27b53e6bea
|
||||
Yoga: d88d8b51ee5b247f43211e2edf272438df1b484f
|
||||
glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3
|
||||
OpenSSL-Universal: 8b48cc0d10c1b2923617dfe5c178aa9ed2689355
|
||||
RCTRequired: 418abaf045a635a391e68ee0573035553c1c4d7b
|
||||
RCTTypeSafety: ea8dd81f61436a394b943dac4435a304c59906ff
|
||||
React: f591e8a044a8ee4a4b20ab632b2906461a241370
|
||||
React-ART: 11785e335a25cc0397fcd008cd0f8e0d340340f0
|
||||
React-Core: 0bb33e607db817c4f60c967448c16f7d31bb973b
|
||||
React-CoreModules: 15064232a166bf4408d0a723a739815c317635be
|
||||
React-cxxreact: dc7b272c44c80616385c25242f54f8594951b57f
|
||||
React-jsi: e3f33d91999ba00d787ceceb6783aa314ecf175d
|
||||
React-jsiexecutor: ccf2361cd90f691e04ff73585f099aa179ae8b52
|
||||
React-jsinspector: fabb3a8cad7bce396f2d4c29cbf83e87022b07ec
|
||||
React-RCTActionSheet: a9a397cdf75149175eab539e536eeb42518f529c
|
||||
React-RCTAnimation: 3fddf9e5dc82ea620c1c44b4206149688b43e054
|
||||
React-RCTBlob: 245f8f0b4578bbecff5e99062f8e2db580218434
|
||||
React-RCTImage: 8205ce960be3d68fcb8dbab729761d828223cd39
|
||||
React-RCTLinking: 27d5e8256b0656d87a00b41af6e55155a70e349b
|
||||
React-RCTNetwork: c6a346f734121eecc855aaaed4572883f502978d
|
||||
React-RCTPushNotification: 658436eec8559a1248c3b859246012e859fadefd
|
||||
React-RCTSettings: 9ae19dc86054cf5317086ab302e820e9616da193
|
||||
React-RCTTest: 399480c8fcfacba1b3e6c0af6fced4f24d62e2da
|
||||
React-RCTText: f2f9976b77661b5a1d628cf7ebfe6c08b6168f8a
|
||||
React-RCTVibration: 2e7618e869b2ba4a15042d6def29dd32df734793
|
||||
ReactCommon: 13c3473a975e73db91b1999e0d6d89c62400785d
|
||||
Yoga: b9a1f7189009fa4b6266ee0a63235547326295d2
|
||||
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
|
||||
|
||||
PODFILE CHECKSUM: 060903e270072f1e192b064848e6c34528af1c87
|
||||
PODFILE CHECKSUM: 6c950c0173bc4754b0d9fa5aba9232943ac228b4
|
||||
|
||||
COCOAPODS: 1.8.4
|
||||
|
||||
@@ -33,6 +33,19 @@
|
||||
#import <React/RCTFabricSurfaceHostingProxyRootView.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if DEBUG
|
||||
#ifdef FB_SONARKIT_ENABLED
|
||||
#import <FlipperKit/FlipperClient.h>
|
||||
#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
|
||||
#import <FlipperKitLayoutPlugin/SKDescriptorMapper.h>
|
||||
#import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
|
||||
#import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>
|
||||
#import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
|
||||
#import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#import <ReactCommon/RCTTurboModuleManager.h>
|
||||
|
||||
#import "RNTesterTurboModuleProvider.h"
|
||||
@@ -83,6 +96,7 @@
|
||||
rootViewController.view = rootView;
|
||||
self.window.rootViewController = rootViewController;
|
||||
[self.window makeKeyAndVisible];
|
||||
[self initializeFlipper:application];
|
||||
return YES;
|
||||
}
|
||||
|
||||
@@ -94,6 +108,22 @@
|
||||
fallbackResource:nil];
|
||||
}
|
||||
|
||||
- (void)initializeFlipper:(UIApplication *)application
|
||||
{
|
||||
#if DEBUG
|
||||
#ifdef FB_SONARKIT_ENABLED
|
||||
FlipperClient *client = [FlipperClient sharedClient];
|
||||
SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
|
||||
[client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application
|
||||
withDescriptorMapper:layoutDescriptorMapper]];
|
||||
[client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]];
|
||||
[client addPlugin:[FlipperKitReactPlugin new]];
|
||||
[client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
|
||||
[client start];
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)app
|
||||
openURL:(NSURL *)url
|
||||
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
27F441EC1BEBE5030039B79C /* FlexibleSizeExampleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 27F441E81BEBE5030039B79C /* FlexibleSizeExampleView.m */; };
|
||||
2DDEF0101F84BF7B00DBDF73 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2DDEF00F1F84BF7B00DBDF73 /* Images.xcassets */; };
|
||||
3D2AFAF51D646CF80089D1A3 /* legacy_image@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3D2AFAF41D646CF80089D1A3 /* legacy_image@2x.png */; };
|
||||
42C7FD8921D436BBA216216D /* libPods-RNTester.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EA4C77A9826FF02A56911142 /* libPods-RNTester.a */; };
|
||||
442B673CCEF28320AE16877B /* libPods-RNTester.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3C8BDC1E54DFC8EB0F67828 /* libPods-RNTester.a */; };
|
||||
5C60EB1C226440DB0018C04F /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C60EB1B226440DB0018C04F /* AppDelegate.mm */; };
|
||||
5CB07C9B226467E60039471C /* RNTesterTurboModuleProvider.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5CB07C99226467E60039471C /* RNTesterTurboModuleProvider.mm */; };
|
||||
69B65AC442B001534251D909 /* libPods-RNTesterIntegrationTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BBFF3E3792E27C4FBA2CB43 /* libPods-RNTesterIntegrationTests.a */; };
|
||||
C23B0809CAE8A115772B092E /* libPods-RNTesterUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42A6C306038665FDDA3E54E2 /* libPods-RNTesterUnitTests.a */; };
|
||||
AB71F075B51B1FA0C65DCF39 /* libPods-RNTesterUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2723489EF058D50FF7217FD9 /* libPods-RNTesterUnitTests.a */; };
|
||||
CBC719CA19D2FD9247BD28F1 /* libPods-RNTesterIntegrationTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 67373A0E14C242E758EE729F /* libPods-RNTesterIntegrationTests.a */; };
|
||||
E7C1241A22BEC44B00DA25C0 /* RNTesterIntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E7C1241922BEC44B00DA25C0 /* RNTesterIntegrationTests.m */; };
|
||||
E7DB20D122B2BAA6005AC45F /* RCTBundleURLProviderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E7DB20A922B2BAA3005AC45F /* RCTBundleURLProviderTests.m */; };
|
||||
E7DB20D222B2BAA6005AC45F /* RCTModuleInitNotificationRaceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E7DB20AA22B2BAA3005AC45F /* RCTModuleInitNotificationRaceTests.m */; };
|
||||
@@ -74,6 +74,7 @@
|
||||
13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = RNTester/Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = RNTester/main.m; sourceTree = "<group>"; };
|
||||
2723489EF058D50FF7217FD9 /* libPods-RNTesterUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
272E6B3B1BEA849E001FCF37 /* UpdatePropertiesExampleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UpdatePropertiesExampleView.h; path = RNTester/NativeExampleViews/UpdatePropertiesExampleView.h; sourceTree = "<group>"; };
|
||||
272E6B3C1BEA849E001FCF37 /* UpdatePropertiesExampleView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = UpdatePropertiesExampleView.m; path = RNTester/NativeExampleViews/UpdatePropertiesExampleView.m; sourceTree = "<group>"; };
|
||||
27F441E81BEBE5030039B79C /* FlexibleSizeExampleView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FlexibleSizeExampleView.m; path = RNTester/NativeExampleViews/FlexibleSizeExampleView.m; sourceTree = "<group>"; };
|
||||
@@ -81,15 +82,15 @@
|
||||
2DDEF00F1F84BF7B00DBDF73 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = RNTester/Images.xcassets; sourceTree = "<group>"; };
|
||||
34028D6B10F47E490042EB27 /* Pods-RNTesterUnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterUnitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
3D2AFAF41D646CF80089D1A3 /* legacy_image@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "legacy_image@2x.png"; path = "RNTester/legacy_image@2x.png"; sourceTree = "<group>"; };
|
||||
42A6C306038665FDDA3E54E2 /* libPods-RNTesterUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
5BBFF3E3792E27C4FBA2CB43 /* libPods-RNTesterIntegrationTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterIntegrationTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
5BEC8567F3741044B6A5EFC5 /* Pods-RNTester.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester.release.xcconfig"; path = "Pods/Target Support Files/Pods-RNTester/Pods-RNTester.release.xcconfig"; sourceTree = "<group>"; };
|
||||
5C60EB1B226440DB0018C04F /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = RNTester/AppDelegate.mm; sourceTree = "<group>"; };
|
||||
5CB07C99226467E60039471C /* RNTesterTurboModuleProvider.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = RNTesterTurboModuleProvider.mm; path = RNTester/RNTesterTurboModuleProvider.mm; sourceTree = "<group>"; };
|
||||
5CB07C9A226467E60039471C /* RNTesterTurboModuleProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNTesterTurboModuleProvider.h; path = RNTester/RNTesterTurboModuleProvider.h; sourceTree = "<group>"; };
|
||||
67373A0E14C242E758EE729F /* libPods-RNTesterIntegrationTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterIntegrationTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
7D51F73F0DA20287418D98BD /* Pods-RNTesterIntegrationTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterIntegrationTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
972A459EE6CF8CC63531A088 /* Pods-RNTesterIntegrationTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterIntegrationTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
98233960D1D6A1977D1C7EAF /* Pods-RNTester.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RNTester/Pods-RNTester.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
D3C8BDC1E54DFC8EB0F67828 /* libPods-RNTester.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTester.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E771AEEA22B44E3100EA1189 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = RNTester/Info.plist; sourceTree = "<group>"; };
|
||||
E7C1241922BEC44B00DA25C0 /* RNTesterIntegrationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNTesterIntegrationTests.m; sourceTree = "<group>"; };
|
||||
E7DB209F22B2BA84005AC45F /* RNTesterUnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RNTesterUnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@@ -163,7 +164,6 @@
|
||||
E7DB216122B2F3EC005AC45F /* RCTRootViewIntegrationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRootViewIntegrationTests.m; sourceTree = "<group>"; };
|
||||
E7DB218B22B41FCD005AC45F /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
|
||||
E9618482EC8608D4872A6E28 /* Pods-RNTesterUnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterUnitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
EA4C77A9826FF02A56911142 /* libPods-RNTester.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTester.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -171,7 +171,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
42C7FD8921D436BBA216216D /* libPods-RNTester.a in Frameworks */,
|
||||
442B673CCEF28320AE16877B /* libPods-RNTester.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -181,7 +181,7 @@
|
||||
files = (
|
||||
E7DB213122B2C649005AC45F /* JavaScriptCore.framework in Frameworks */,
|
||||
E7DB213222B2C67D005AC45F /* libOCMock.a in Frameworks */,
|
||||
C23B0809CAE8A115772B092E /* libPods-RNTesterUnitTests.a in Frameworks */,
|
||||
AB71F075B51B1FA0C65DCF39 /* libPods-RNTesterUnitTests.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -191,7 +191,7 @@
|
||||
files = (
|
||||
E7DB218C22B41FCD005AC45F /* XCTest.framework in Frameworks */,
|
||||
E7DB216722B2F69F005AC45F /* JavaScriptCore.framework in Frameworks */,
|
||||
69B65AC442B001534251D909 /* libPods-RNTesterIntegrationTests.a in Frameworks */,
|
||||
CBC719CA19D2FD9247BD28F1 /* libPods-RNTesterIntegrationTests.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -261,9 +261,9 @@
|
||||
E7DB211822B2BD53005AC45F /* libReact-RCTText.a */,
|
||||
E7DB211A22B2BD53005AC45F /* libReact-RCTVibration.a */,
|
||||
E7DB212222B2BD53005AC45F /* libyoga.a */,
|
||||
EA4C77A9826FF02A56911142 /* libPods-RNTester.a */,
|
||||
5BBFF3E3792E27C4FBA2CB43 /* libPods-RNTesterIntegrationTests.a */,
|
||||
42A6C306038665FDDA3E54E2 /* libPods-RNTesterUnitTests.a */,
|
||||
D3C8BDC1E54DFC8EB0F67828 /* libPods-RNTester.a */,
|
||||
67373A0E14C242E758EE729F /* libPods-RNTesterIntegrationTests.a */,
|
||||
2723489EF058D50FF7217FD9 /* libPods-RNTesterUnitTests.a */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
@@ -725,8 +725,20 @@
|
||||
);
|
||||
INFOPLIST_FILE = "$(SRCROOT)/RNTester/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_CFLAGS = "$(inherited)";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
/usr/lib/swift,
|
||||
"$(inherited)",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)",
|
||||
"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)",
|
||||
);
|
||||
"LIBRARY_SEARCH_PATHS[arch=*]" = "$(inherited)";
|
||||
OTHER_CFLAGS = (
|
||||
"$(inherited)",
|
||||
"-DFB_SONARKIT_ENABLED=1",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -779,8 +791,19 @@
|
||||
);
|
||||
INFOPLIST_FILE = "$(SRCROOT)/RNTester/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_CFLAGS = "$(inherited)";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
/usr/lib/swift,
|
||||
"$(inherited)",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)",
|
||||
"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)",
|
||||
);
|
||||
OTHER_CFLAGS = (
|
||||
"$(inherited)",
|
||||
"-DFB_SONARKIT_ENABLED=1",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -974,6 +997,10 @@
|
||||
);
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
OTHER_CFLAGS = (
|
||||
"$(inherited)",
|
||||
"-DFB_SONARKIT_ENABLED=1",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.facebook.RNTesterUnitTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
@@ -1005,6 +1032,10 @@
|
||||
"$(PROJECT_DIR)/RNTesterUnitTests",
|
||||
);
|
||||
MTL_FAST_MATH = YES;
|
||||
OTHER_CFLAGS = (
|
||||
"$(inherited)",
|
||||
"-DFB_SONARKIT_ENABLED=1",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.facebook.RNTesterUnitTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
@@ -1037,6 +1068,10 @@
|
||||
);
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
OTHER_CFLAGS = (
|
||||
"$(inherited)",
|
||||
"-DFB_SONARKIT_ENABLED=1",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.facebook.RNTesterIntegrationTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
@@ -1066,6 +1101,10 @@
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MTL_FAST_MATH = YES;
|
||||
OTHER_CFLAGS = (
|
||||
"$(inherited)",
|
||||
"-DFB_SONARKIT_ENABLED=1",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.facebook.RNTesterIntegrationTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
|
||||
@@ -166,14 +166,22 @@ dependencies {
|
||||
// Build React Native from source
|
||||
implementation project(':ReactAndroid')
|
||||
|
||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
|
||||
|
||||
def hermesPath = '$projectDir/../../../../node_modules/hermes-engine/android/'
|
||||
debugImplementation files(hermesPath + "hermes-debug.aar")
|
||||
releaseImplementation files(hermesPath + "hermes-release.aar")
|
||||
|
||||
debugImplementation("com.facebook.flipper:flipper:0.23.4") {
|
||||
exclude group:'com.facebook.yoga'
|
||||
exclude group:'com.facebook.flipper', module: 'fbjni'
|
||||
exclude group:'com.facebook.litho', module: 'litho-annotations'
|
||||
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
|
||||
exclude group:'com.facebook.fbjni'
|
||||
}
|
||||
|
||||
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
|
||||
exclude group:'com.facebook.flipper'
|
||||
}
|
||||
|
||||
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
|
||||
exclude group:'com.facebook.flipper'
|
||||
}
|
||||
|
||||
if (useIntlJsc) {
|
||||
|
||||
@@ -7,3 +7,6 @@ MYAPP_RELEASE_KEY_PASSWORD=android
|
||||
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
|
||||
# Version of flipper SDK to use with React Native
|
||||
FLIPPER_VERSION=0.30.2
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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.uiapp;
|
||||
|
||||
import android.content.Context;
|
||||
import com.facebook.flipper.android.AndroidFlipperClient;
|
||||
import com.facebook.flipper.android.utils.FlipperUtils;
|
||||
import com.facebook.flipper.core.FlipperClient;
|
||||
import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin;
|
||||
import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.inspector.DescriptorMapping;
|
||||
import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
|
||||
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.react.ReactFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.modules.network.NetworkingModule;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
public class ReactNativeFlipper {
|
||||
public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
|
||||
if (FlipperUtils.shouldEnableFlipper(context)) {
|
||||
final FlipperClient client = AndroidFlipperClient.getInstance(context);
|
||||
|
||||
client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
|
||||
client.addPlugin(new ReactFlipperPlugin());
|
||||
client.addPlugin(new DatabasesFlipperPlugin(context));
|
||||
client.addPlugin(new SharedPreferencesFlipperPlugin(context));
|
||||
client.addPlugin(CrashReporterPlugin.getInstance());
|
||||
|
||||
NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
|
||||
NetworkingModule.setCustomClientBuilder(
|
||||
new NetworkingModule.CustomClientBuilder() {
|
||||
@Override
|
||||
public void apply(OkHttpClient.Builder builder) {
|
||||
builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
|
||||
}
|
||||
});
|
||||
client.addPlugin(networkFlipperPlugin);
|
||||
client.start();
|
||||
|
||||
// Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
|
||||
// Hence we run if after all native modules have been initialized
|
||||
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
|
||||
if (reactContext == null) {
|
||||
reactInstanceManager.addReactInstanceEventListener(
|
||||
new ReactInstanceManager.ReactInstanceEventListener() {
|
||||
@Override
|
||||
public void onReactContextInitialized(ReactContext reactContext) {
|
||||
reactInstanceManager.removeReactInstanceEventListener(this);
|
||||
reactContext.runOnNativeModulesQueueThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
client.addPlugin(new FrescoFlipperPlugin());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
client.addPlugin(new FrescoFlipperPlugin());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
-4
@@ -11,6 +11,7 @@ import android.app.Application;
|
||||
import android.content.Context;
|
||||
import com.facebook.react.BuildConfig;
|
||||
import com.facebook.react.ReactApplication;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.ReactNativeHost;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.shell.MainReactPackage;
|
||||
@@ -48,7 +49,8 @@ public class RNTesterApplication extends Application implements ReactApplication
|
||||
public void onCreate() {
|
||||
ReactFontManager.getInstance().addCustomFont(this, "Rubik", R.font.rubik);
|
||||
super.onCreate();
|
||||
initializeFlipper(this);
|
||||
SoLoader.init(this, /* native exopackage */ false);
|
||||
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -56,15 +58,25 @@ public class RNTesterApplication extends Application implements ReactApplication
|
||||
return mReactNativeHost;
|
||||
}
|
||||
|
||||
private static void initializeFlipper(Context context) {
|
||||
/**
|
||||
* Loads Flipper in React Native templates. Call this in the onCreate method with something like
|
||||
* initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||
*
|
||||
* @param context
|
||||
* @param reactInstanceManager
|
||||
*/
|
||||
private static void initializeFlipper(
|
||||
Context context, ReactInstanceManager reactInstanceManager) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
try {
|
||||
/*
|
||||
We use reflection here to pick up the class that initializes Flipper,
|
||||
since Flipper library is not available in release mode
|
||||
*/
|
||||
Class<?> aClass = Class.forName("com.facebook.flipper.ReactNativeFlipper");
|
||||
aClass.getMethod("initializeFlipper", Context.class).invoke(null, context);
|
||||
Class<?> aClass = Class.forName("com.facebook.react.uiapp.ReactNativeFlipper");
|
||||
aClass
|
||||
.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
|
||||
.invoke(null, context, reactInstanceManager);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException e) {
|
||||
|
||||
@@ -16,7 +16,7 @@ const React = require('react');
|
||||
const TextInlineView = require('../../components/TextInlineView');
|
||||
const TextLegend = require('../../components/TextLegend');
|
||||
|
||||
const {StyleSheet, Text, View} = require('react-native');
|
||||
const {LayoutAnimation, StyleSheet, Text, View} = require('react-native');
|
||||
|
||||
class Entity extends React.Component<{|children: React.Node|}> {
|
||||
render() {
|
||||
@@ -70,10 +70,137 @@ class AttributeToggler extends React.Component<{...}, $FlowFixMeState> {
|
||||
}
|
||||
}
|
||||
|
||||
type AdjustingFontSizeProps = $ReadOnly<{||}>;
|
||||
|
||||
type AdjustingFontSizeState = {|
|
||||
dynamicText: string,
|
||||
shouldRender: boolean,
|
||||
|};
|
||||
|
||||
class AdjustingFontSize extends React.Component<
|
||||
AdjustingFontSizeProps,
|
||||
AdjustingFontSizeState,
|
||||
> {
|
||||
state = {
|
||||
dynamicText: '',
|
||||
shouldRender: true,
|
||||
};
|
||||
|
||||
reset = () => {
|
||||
LayoutAnimation.easeInEaseOut();
|
||||
this.setState({
|
||||
shouldRender: false,
|
||||
});
|
||||
setTimeout(() => {
|
||||
LayoutAnimation.easeInEaseOut();
|
||||
this.setState({
|
||||
dynamicText: '',
|
||||
shouldRender: true,
|
||||
});
|
||||
}, 300);
|
||||
};
|
||||
|
||||
addText = () => {
|
||||
this.setState({
|
||||
dynamicText:
|
||||
this.state.dynamicText +
|
||||
(Math.floor((Math.random() * 10) % 2) ? ' foo' : ' bar'),
|
||||
});
|
||||
};
|
||||
|
||||
removeText = () => {
|
||||
this.setState({
|
||||
dynamicText: this.state.dynamicText.slice(
|
||||
0,
|
||||
this.state.dynamicText.length - 4,
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
if (!this.state.shouldRender) {
|
||||
return <View />;
|
||||
}
|
||||
return (
|
||||
<View>
|
||||
<Text
|
||||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
style={{fontSize: 36, marginVertical: 6}}>
|
||||
Truncated text is baaaaad.
|
||||
</Text>
|
||||
<Text
|
||||
numberOfLines={1}
|
||||
adjustsFontSizeToFit={true}
|
||||
style={{fontSize: 40, marginVertical: 6}}>
|
||||
Shrinking to fit available space is much better!
|
||||
</Text>
|
||||
|
||||
<Text
|
||||
adjustsFontSizeToFit={true}
|
||||
numberOfLines={1}
|
||||
style={{fontSize: 30, marginVertical: 6}}>
|
||||
{'Add text to me to watch me shrink!' + ' ' + this.state.dynamicText}
|
||||
</Text>
|
||||
|
||||
<Text
|
||||
adjustsFontSizeToFit={true}
|
||||
numberOfLines={4}
|
||||
style={{fontSize: 20, marginVertical: 6}}>
|
||||
{'Multiline text component shrinking is supported, watch as this reeeeaaaally loooooong teeeeeeext grooooows and then shriiiinks as you add text to me! ioahsdia soady auydoa aoisyd aosdy ' +
|
||||
' ' +
|
||||
this.state.dynamicText}
|
||||
</Text>
|
||||
|
||||
<Text
|
||||
adjustsFontSizeToFit={true}
|
||||
style={{fontSize: 20, marginVertical: 6, maxHeight: 50}}>
|
||||
{'Text limited by height, watch as this reeeeaaaally loooooong teeeeeeext grooooows and then shriiiinks as you add text to me! ioahsdia soady auydoa aoisyd aosdy ' +
|
||||
' ' +
|
||||
this.state.dynamicText}
|
||||
</Text>
|
||||
|
||||
<Text
|
||||
adjustsFontSizeToFit={true}
|
||||
numberOfLines={1}
|
||||
style={{marginVertical: 6}}>
|
||||
<Text style={{fontSize: 14}}>
|
||||
{'Differently sized nested elements will shrink together. '}
|
||||
</Text>
|
||||
<Text style={{fontSize: 20}}>
|
||||
{'LARGE TEXT! ' + this.state.dynamicText}
|
||||
</Text>
|
||||
</Text>
|
||||
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-around',
|
||||
marginTop: 5,
|
||||
marginVertical: 6,
|
||||
}}>
|
||||
<Text style={{backgroundColor: '#ffaaaa'}} onPress={this.reset}>
|
||||
Reset
|
||||
</Text>
|
||||
<Text style={{backgroundColor: '#aaaaff'}} onPress={this.removeText}>
|
||||
Remove Text
|
||||
</Text>
|
||||
<Text style={{backgroundColor: '#aaffaa'}} onPress={this.addText}>
|
||||
Add Text
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TextExample extends React.Component<{...}> {
|
||||
render(): React.Node {
|
||||
return (
|
||||
<RNTesterPage title="<Text>">
|
||||
<RNTesterBlock title="Dynamic Font Size Adjustment">
|
||||
<AdjustingFontSize />
|
||||
</RNTesterBlock>
|
||||
<RNTesterBlock title="Wrap">
|
||||
<Text>
|
||||
The text should wrap if it goes on multiple lines. See, this is
|
||||
|
||||
@@ -222,6 +222,14 @@ class AdjustingFontSize extends React.Component<
|
||||
this.state.dynamicText}
|
||||
</Text>
|
||||
|
||||
<Text
|
||||
adjustsFontSizeToFit={true}
|
||||
style={{fontSize: 20, marginVertical: 6, maxHeight: 50}}>
|
||||
{'Text limited by height, watch as this reeeeaaaally loooooong teeeeeeext grooooows and then shriiiinks as you add text to me! ioahsdia soady auydoa aoisyd aosdy ' +
|
||||
' ' +
|
||||
this.state.dynamicText}
|
||||
</Text>
|
||||
|
||||
<Text
|
||||
adjustsFontSizeToFit={true}
|
||||
numberOfLines={1}
|
||||
|
||||
@@ -305,7 +305,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||
*/
|
||||
- (void)reloadWithReason:(NSString *)reason
|
||||
{
|
||||
#if RCT_ENABLE_INSPECTOR && !TARGET_OS_UIKITFORMAC
|
||||
#if RCT_ENABLE_INSPECTOR
|
||||
// Disable debugger to resume the JsVM & avoid thread locks while reloading
|
||||
[RCTInspectorDevServerHelper disableDebugger];
|
||||
#endif
|
||||
|
||||
+3
-8
@@ -5,12 +5,7 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#import <React/RCTDefines.h>
|
||||
|
||||
#include <fb/visibility.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace jni {
|
||||
|
||||
void FBEXPORT installTerminateHandler();
|
||||
}};
|
||||
RCT_EXTERN NSString *const RCTUserInterfaceStyleDidChangeNotification;
|
||||
RCT_EXTERN NSString *const RCTUserInterfaceStyleDidChangeNotificationTraitCollectionKey;
|
||||
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTConstants.h"
|
||||
|
||||
NSString *const RCTUserInterfaceStyleDidChangeNotification = @"RCTUserInterfaceStyleDidChangeNotification";
|
||||
NSString *const RCTUserInterfaceStyleDidChangeNotificationTraitCollectionKey = @"traitCollection";
|
||||
@@ -63,7 +63,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_PACKAGER_CONNECTION
|
||||
#if RCT_DEV && (__has_include("RCTPackagerConnection.h") || __has_include(<React/RCTPackagerConnection.h>)) && !TARGET_OS_UIKITFORMAC
|
||||
#if RCT_DEV && (__has_include("RCTPackagerConnection.h") || __has_include(<React/RCTPackagerConnection.h>))
|
||||
#define ENABLE_PACKAGER_CONNECTION 1
|
||||
#else
|
||||
#define ENABLE_PACKAGER_CONNECTION 0
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#import "RCTAssert.h"
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTBridge+Private.h"
|
||||
#import "RCTConstants.h"
|
||||
#import "RCTEventDispatcher.h"
|
||||
#import "RCTKeyCommands.h"
|
||||
#import "RCTLog.h"
|
||||
@@ -33,7 +34,6 @@
|
||||
#endif
|
||||
|
||||
NSString *const RCTContentDidAppearNotification = @"RCTContentDidAppearNotification";
|
||||
static NSString *const RCTUserInterfaceStyleDidChangeNotification = @"RCTUserInterfaceStyleDidChangeNotification";
|
||||
|
||||
@interface RCTUIManager (RCTRootView)
|
||||
|
||||
@@ -367,21 +367,16 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
||||
[self showLoadingView];
|
||||
}
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \
|
||||
__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
|
||||
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
|
||||
{
|
||||
[super traitCollectionDidChange:previousTraitCollection];
|
||||
|
||||
if (@available(iOS 13.0, *)) {
|
||||
if ([previousTraitCollection hasDifferentColorAppearanceComparedToTraitCollection:self.traitCollection]) {
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:RCTUserInterfaceStyleDidChangeNotification
|
||||
object:self
|
||||
userInfo:@{@"traitCollection": self.traitCollection}];
|
||||
}
|
||||
}
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:RCTUserInterfaceStyleDidChangeNotification
|
||||
object:self
|
||||
userInfo:@{
|
||||
RCTUserInterfaceStyleDidChangeNotificationTraitCollectionKey: self.traitCollection,
|
||||
}];
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
|
||||
@@ -21,11 +21,11 @@ NSDictionary* RCTGetReactNativeVersion(void)
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^(void){
|
||||
__rnVersion = @{
|
||||
RCTVersionMajor: @(0),
|
||||
RCTVersionMinor: @(0),
|
||||
RCTVersionPatch: @(0),
|
||||
RCTVersionPrerelease: [NSNull null],
|
||||
};
|
||||
RCTVersionMajor: @(0),
|
||||
RCTVersionMinor: @(62),
|
||||
RCTVersionPatch: @(0),
|
||||
RCTVersionPrerelease: @"rc.2",
|
||||
};
|
||||
});
|
||||
return __rnVersion;
|
||||
}
|
||||
|
||||
@@ -7,14 +7,13 @@
|
||||
|
||||
#import "RCTSurfaceHostingView.h"
|
||||
|
||||
#import "RCTConstants.h"
|
||||
#import "RCTDefines.h"
|
||||
#import "RCTSurface.h"
|
||||
#import "RCTSurfaceDelegate.h"
|
||||
#import "RCTSurfaceView.h"
|
||||
#import "RCTUtils.h"
|
||||
|
||||
static NSString *const RCTUserInterfaceStyleDidChangeNotification = @"RCTUserInterfaceStyleDidChangeNotification";
|
||||
|
||||
@interface RCTSurfaceHostingView ()
|
||||
|
||||
@property (nonatomic, assign) BOOL isActivityIndicatorViewVisible;
|
||||
@@ -208,21 +207,15 @@ RCT_NOT_IMPLEMENTED(- (nullable instancetype)initWithCoder:(NSCoder *)coder)
|
||||
|
||||
#pragma mark - UITraitCollection updates
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \
|
||||
__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
|
||||
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
|
||||
{
|
||||
[super traitCollectionDidChange:previousTraitCollection];
|
||||
|
||||
if (@available(iOS 13.0, *)) {
|
||||
if ([previousTraitCollection hasDifferentColorAppearanceComparedToTraitCollection:self.traitCollection]) {
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:RCTUserInterfaceStyleDidChangeNotification
|
||||
object:self
|
||||
userInfo:@{@"traitCollection": self.traitCollection}];
|
||||
}
|
||||
}
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:RCTUserInterfaceStyleDidChangeNotification
|
||||
object:self
|
||||
userInfo:@{
|
||||
RCTUserInterfaceStyleDidChangeNotificationTraitCollectionKey: self.traitCollection,
|
||||
}];
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma mark - Private stuff
|
||||
|
||||
|
||||
@@ -96,6 +96,9 @@ rn_apple_library(
|
||||
) + react_module_plugin_providers(
|
||||
name = "RedBox",
|
||||
native_class_func = "RCTRedBoxCls",
|
||||
) + react_module_plugin_providers(
|
||||
name = "LogBox",
|
||||
native_class_func = "RCTLogBoxCls",
|
||||
) + react_module_plugin_providers(
|
||||
name = "TVNavigationEventEmitter",
|
||||
native_class_func = "RCTTVNavigationEventEmitterCls",
|
||||
|
||||
@@ -48,6 +48,7 @@ Class RCTPerfMonitorCls(void) __attribute__((used));
|
||||
Class RCTDevMenuCls(void) __attribute__((used));
|
||||
Class RCTDevSettingsCls(void) __attribute__((used));
|
||||
Class RCTRedBoxCls(void) __attribute__((used));
|
||||
Class RCTLogBoxCls(void) __attribute__((used));
|
||||
Class RCTTVNavigationEventEmitterCls(void) __attribute__((used));
|
||||
Class RCTWebSocketExecutorCls(void) __attribute__((used));
|
||||
Class RCTWebSocketModuleCls(void) __attribute__((used));
|
||||
|
||||
@@ -37,6 +37,7 @@ Class RCTCoreModulesClassProvider(const char *name) {
|
||||
{"DevMenu", RCTDevMenuCls},
|
||||
{"DevSettings", RCTDevSettingsCls},
|
||||
{"RedBox", RCTRedBoxCls},
|
||||
{"LogBox", RCTLogBoxCls},
|
||||
{"TVNavigationEventEmitter", RCTTVNavigationEventEmitterCls},
|
||||
{"WebSocketExecutor", RCTWebSocketExecutorCls},
|
||||
{"WebSocketModule", RCTWebSocketModuleCls},
|
||||
|
||||
@@ -12,7 +12,5 @@
|
||||
|
||||
RCT_EXTERN void RCTEnableAppearancePreference(BOOL enabled);
|
||||
|
||||
NSString *const RCTUserInterfaceStyleDidChangeNotification = @"RCTUserInterfaceStyleDidChangeNotification";
|
||||
|
||||
@interface RCTAppearance : RCTEventEmitter <RCTBridgeModule>
|
||||
@end
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#import "RCTAppearance.h"
|
||||
|
||||
#import <FBReactNativeSpec/FBReactNativeSpec.h>
|
||||
#import <React/RCTConstants.h>
|
||||
#import <React/RCTEventEmitter.h>
|
||||
|
||||
#import "CoreModulesPlugins.h"
|
||||
@@ -86,7 +87,7 @@ RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSString *, getColorScheme)
|
||||
NSDictionary *userInfo = [notification userInfo];
|
||||
UITraitCollection *traitCollection = nil;
|
||||
if (userInfo) {
|
||||
traitCollection = userInfo[@"traitCollection"];
|
||||
traitCollection = userInfo[RCTUserInterfaceStyleDidChangeNotificationTraitCollectionKey];
|
||||
}
|
||||
NSString *newColorScheme = RCTColorSchemePreference(traitCollection);
|
||||
if (![_currentColorScheme isEqualToString:newColorScheme]) {
|
||||
|
||||
@@ -262,7 +262,7 @@ RCT_EXPORT_MODULE()
|
||||
if (devSettings.isNuclideDebuggingAvailable && !devSettings.isDebuggingRemotely) {
|
||||
[items addObject:[RCTDevMenuItem buttonItemWithTitle:@"Debug with Nuclide"
|
||||
handler:^{
|
||||
#if RCT_ENABLE_INSPECTOR && !TARGET_OS_UIKITFORMAC
|
||||
#if RCT_ENABLE_INSPECTOR
|
||||
[RCTInspectorDevServerHelper
|
||||
attachDebugger:@"ReactNative"
|
||||
withBundleURL:bridge.bundleURL
|
||||
|
||||
@@ -176,7 +176,7 @@ RCT_EXPORT_MODULE()
|
||||
forMethod:@"reload"];
|
||||
#endif
|
||||
|
||||
#if RCT_ENABLE_INSPECTOR && !TARGET_OS_UIKITFORMAC
|
||||
#if RCT_ENABLE_INSPECTOR
|
||||
// we need this dispatch back to the main thread because even though this
|
||||
// is executed on the main thread, at this point the bridge is not yet
|
||||
// finished with its initialisation. But it does finish by the time it
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#import <FBReactNativeSpec/FBReactNativeSpec.h>
|
||||
#import <React/RCTAccessibilityManager.h>
|
||||
#import <React/RCTAssert.h>
|
||||
#import <React/RCTConstants.h>
|
||||
#import <React/RCTEventDispatcher.h>
|
||||
#import <React/RCTUIUtils.h>
|
||||
#import <React/RCTUtils.h>
|
||||
@@ -61,9 +62,15 @@ RCT_EXPORT_MODULE()
|
||||
_currentInterfaceDimensions = RCTExportedDimensions(_bridge);
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(interfaceFrameDidChange)
|
||||
name:UIApplicationDidBecomeActiveNotification
|
||||
object:nil];
|
||||
selector:@selector(interfaceFrameDidChange)
|
||||
name:UIApplicationDidBecomeActiveNotification
|
||||
object:nil];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(interfaceFrameDidChange)
|
||||
name:RCTUserInterfaceStyleDidChangeNotification
|
||||
object:nil];
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTBridgeModule.h>
|
||||
#import <React/RCTErrorCustomizer.h>
|
||||
|
||||
@class RCTJSStackFrame;
|
||||
|
||||
@interface RCTLogBox : NSObject <RCTBridgeModule>
|
||||
|
||||
- (void)show;
|
||||
- (void)hide;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTLogBox.h"
|
||||
|
||||
#import <FBReactNativeSpec/FBReactNativeSpec.h>
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTRootView.h>
|
||||
#import <React/RCTConvert.h>
|
||||
#import <React/RCTDefines.h>
|
||||
#import <React/RCTErrorInfo.h>
|
||||
#import <React/RCTEventDispatcher.h>
|
||||
#import <React/RCTJSStackFrame.h>
|
||||
#import <React/RCTRedBoxSetEnabled.h>
|
||||
#import <React/RCTReloadCommand.h>
|
||||
#import <React/RCTRedBoxSetEnabled.h>
|
||||
#import <React/RCTSurface.h>
|
||||
#import <React/RCTUtils.h>
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#import "CoreModulesPlugins.h"
|
||||
|
||||
#if RCT_DEV_MENU
|
||||
|
||||
@class RCTLogBoxView;
|
||||
|
||||
@interface RCTLogBoxView : UIView
|
||||
@end
|
||||
|
||||
@implementation RCTLogBoxView
|
||||
{
|
||||
UIViewController *_rootViewController;
|
||||
RCTSurface *_surface;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame bridge:(RCTBridge *)bridge
|
||||
{
|
||||
if ((self = [super initWithFrame:frame])) {
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
|
||||
_surface = [[RCTSurface alloc] initWithBridge:bridge moduleName:@"LogBox" initialProperties:@{}];
|
||||
|
||||
[_surface start];
|
||||
[_surface setSize:frame.size];
|
||||
|
||||
if (![_surface synchronouslyWaitForStage:RCTSurfaceStageSurfaceDidInitialMounting timeout:1]) {
|
||||
RCTLogInfo(@"Failed to mount LogBox within 1s");
|
||||
}
|
||||
|
||||
_rootViewController = [UIViewController new];
|
||||
_rootViewController.view = (UIView *)_surface.view;
|
||||
_rootViewController.view.backgroundColor = [UIColor clearColor];
|
||||
_rootViewController.modalPresentationStyle = UIModalPresentationFullScreen;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
// Dismiss by deallocating the window.
|
||||
// This will also handle JS reload, otherwise the LogBox view would be stuck on top.
|
||||
[_rootViewController.view resignFirstResponder];
|
||||
[_rootViewController dismissViewControllerAnimated:NO completion:NULL];
|
||||
}
|
||||
|
||||
- (void)show
|
||||
{
|
||||
[RCTSharedApplication().delegate.window.rootViewController presentViewController:_rootViewController animated:NO completion:^{
|
||||
[self->_rootViewController.view becomeFirstResponder];
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTLogBox () <NativeLogBoxSpec>
|
||||
@end
|
||||
|
||||
@implementation RCTLogBox
|
||||
{
|
||||
RCTLogBoxView *_view;
|
||||
}
|
||||
|
||||
@synthesize bridge = _bridge;
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
+ (BOOL)requiresMainQueueSetup
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(show)
|
||||
{
|
||||
if (RCTRedBoxGetEnabled()) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (!self->_view) {
|
||||
self->_view = [[RCTLogBoxView alloc] initWithFrame:[UIScreen mainScreen].bounds bridge: self->_bridge];
|
||||
}
|
||||
[self->_view show];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(hide)
|
||||
{
|
||||
if (RCTRedBoxGetEnabled()) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
self->_view = nil;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModuleWithJsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
|
||||
{
|
||||
if (RCTRedBoxGetEnabled()) {
|
||||
return std::make_shared<facebook::react::NativeLogBoxSpecJSI>(self, jsInvoker);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#else // Disabled
|
||||
|
||||
@interface RCTLogBox() <NativeLogBoxSpec>
|
||||
@end
|
||||
|
||||
@implementation RCTLogBox
|
||||
|
||||
+ (NSString *)moduleName
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)show {
|
||||
// noop
|
||||
}
|
||||
|
||||
- (void)hide {
|
||||
// noop
|
||||
}
|
||||
|
||||
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModuleWithJsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
|
||||
{
|
||||
return std::make_shared<facebook::react::NativeLogBoxSpecJSI>(self, jsInvoker);
|
||||
}
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
Class RCTLogBoxCls(void) {
|
||||
return RCTLogBox.class;
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
#import <React/RCTDefines.h>
|
||||
#import <React/RCTInspectorPackagerConnection.h>
|
||||
|
||||
#if RCT_DEV && !TARGET_OS_UIKITFORMAC
|
||||
#if RCT_DEV
|
||||
|
||||
@interface RCTInspectorDevServerHelper : NSObject
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#import <React/RCTInspectorDevServerHelper.h>
|
||||
|
||||
#if RCT_DEV && !TARGET_OS_UIKITFORMAC
|
||||
#if RCT_DEV
|
||||
|
||||
#import <React/RCTLog.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#import <React/RCTDefines.h>
|
||||
|
||||
#if RCT_DEV && !TARGET_OS_UIKITFORMAC
|
||||
#if RCT_DEV
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#import <React/RCTReconnectingWebSocket.h>
|
||||
#import <React/RCTUtils.h>
|
||||
|
||||
#if RCT_DEV && !TARGET_OS_UIKITFORMAC
|
||||
#if RCT_DEV
|
||||
|
||||
#import <React/RCTSRWebSocket.h>
|
||||
|
||||
|
||||
@@ -91,7 +91,9 @@ static ModalHostViewOnOrientationChangeStruct onOrientationChangeStruct(CGRect r
|
||||
return {orientation};
|
||||
}
|
||||
|
||||
@interface RCTModalHostViewComponentView () <RCTFabricModalHostViewControllerDelegate>
|
||||
@interface RCTModalHostViewComponentView () <
|
||||
RCTFabricModalHostViewControllerDelegate,
|
||||
UIAdaptivePresentationControllerDelegate>
|
||||
|
||||
@end
|
||||
|
||||
@@ -110,6 +112,7 @@ static ModalHostViewOnOrientationChangeStruct onOrientationChangeStruct(CGRect r
|
||||
_viewController = [RCTFabricModalHostViewController new];
|
||||
_viewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
|
||||
_viewController.delegate = self;
|
||||
_viewController.presentationController.delegate = self;
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -214,4 +217,17 @@ static ModalHostViewOnOrientationChangeStruct onOrientationChangeStruct(CGRect r
|
||||
[childComponentView removeFromSuperview];
|
||||
}
|
||||
|
||||
#pragma mark - UIAdaptivePresentationControllerDelegate
|
||||
|
||||
- (void)presentationControllerDidDismiss:(UIPresentationController *)presentationController
|
||||
{
|
||||
if (!_eventEmitter) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(std::dynamic_pointer_cast<ModalHostViewEventEmitter const>(_eventEmitter));
|
||||
auto eventEmitter = std::static_pointer_cast<ModalHostViewEventEmitter const>(_eventEmitter);
|
||||
eventEmitter->onRequestClose({});
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#import <React/RCTInspector.h>
|
||||
|
||||
#if RCT_DEV && !TARGET_OS_UIKITFORMAC
|
||||
#if RCT_DEV
|
||||
|
||||
#include <jsinspector/InspectorInterfaces.h>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <React/RCTDefines.h>
|
||||
|
||||
#if RCT_DEV && !TARGET_OS_UIKITFORMAC
|
||||
#if RCT_DEV
|
||||
|
||||
@interface RCTBundleStatus : NSObject
|
||||
@property (atomic, assign) BOOL isLastBundleDownloadSuccess;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#import <React/RCTInspectorPackagerConnection.h>
|
||||
|
||||
#if RCT_DEV && !TARGET_OS_UIKITFORMAC
|
||||
#if RCT_DEV
|
||||
|
||||
#import <React/RCTDefines.h>
|
||||
#import <React/RCTInspector.h>
|
||||
|
||||
@@ -32,8 +32,9 @@
|
||||
@property (nonatomic, copy) NSArray<NSString *> *supportedOrientations;
|
||||
@property (nonatomic, copy) RCTDirectEventBlock onOrientationChange;
|
||||
|
||||
#if TARGET_OS_TV
|
||||
@property (nonatomic, copy) RCTDirectEventBlock onRequestClose;
|
||||
|
||||
#if TARGET_OS_TV
|
||||
@property (nonatomic, strong) RCTTVRemoteHandler *tvRemoteHandler;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
#import "RCTTVRemoteHandler.h"
|
||||
#endif
|
||||
|
||||
@interface RCTModalHostView () <UIAdaptivePresentationControllerDelegate>
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTModalHostView
|
||||
{
|
||||
__weak RCTBridge *_bridge;
|
||||
@@ -46,6 +50,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:coder)
|
||||
UIView *containerView = [UIView new];
|
||||
containerView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
|
||||
_modalViewController.view = containerView;
|
||||
_modalViewController.presentationController.delegate = self;
|
||||
_touchHandler = [[RCTTouchHandler alloc] initWithBridge:bridge];
|
||||
#if TARGET_OS_TV
|
||||
_menuButtonGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(menuButtonPressed:)];
|
||||
@@ -70,10 +75,12 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:coder)
|
||||
_onRequestClose(nil);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)setOnRequestClose:(RCTDirectEventBlock)onRequestClose
|
||||
{
|
||||
_onRequestClose = onRequestClose;
|
||||
#if TARGET_OS_TV
|
||||
if (_reactSubview) {
|
||||
if (_onRequestClose && _menuButtonGestureRecognizer) {
|
||||
[_reactSubview addGestureRecognizer:_menuButtonGestureRecognizer];
|
||||
@@ -81,8 +88,8 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:coder)
|
||||
[_reactSubview removeGestureRecognizer:_menuButtonGestureRecognizer];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)notifyForBoundsChange:(CGRect)newBounds
|
||||
{
|
||||
@@ -257,4 +264,11 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:coder)
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)presentationControllerDidDismiss:(UIPresentationController *)presentationController
|
||||
{
|
||||
if (_onRequestClose) {
|
||||
_onRequestClose(nil);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -108,9 +108,6 @@ RCT_EXPORT_VIEW_PROPERTY(onShow, RCTDirectEventBlock)
|
||||
RCT_EXPORT_VIEW_PROPERTY(identifier, NSNumber)
|
||||
RCT_EXPORT_VIEW_PROPERTY(supportedOrientations, NSArray)
|
||||
RCT_EXPORT_VIEW_PROPERTY(onOrientationChange, RCTDirectEventBlock)
|
||||
|
||||
#if TARGET_OS_TV
|
||||
RCT_EXPORT_VIEW_PROPERTY(onRequestClose, RCTDirectEventBlock)
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
@@ -296,7 +296,8 @@ def getNdkBuildFullPath() {
|
||||
}
|
||||
|
||||
def buildReactNdkLib = tasks.register("buildReactNdkLib", Exec) {
|
||||
dependsOn(prepareJSC, prepareHermes, prepareBoost, prepareDoubleConversion, prepareFolly, prepareGlog)
|
||||
dependsOn(prepareJSC, prepareHermes, prepareBoost, prepareDoubleConversion, prepareFolly, prepareGlog, extractAARHeaders, extractJNIFiles)
|
||||
|
||||
inputs.dir("$projectDir/../ReactCommon")
|
||||
inputs.dir("src/main/jni")
|
||||
inputs.dir("src/main/java/com/facebook/react/modules/blob")
|
||||
@@ -344,6 +345,34 @@ def packageReactNdkLibsForBuck = tasks.register("packageReactNdkLibsForBuck", Co
|
||||
into("src/main/jni/prebuilt/lib")
|
||||
}
|
||||
|
||||
task extractAARHeaders {
|
||||
doLast {
|
||||
configurations.extractHeaders.files.each {
|
||||
def file = it.absoluteFile
|
||||
def packageName = file.name.tokenize('-')[0]
|
||||
copy {
|
||||
from zipTree(file)
|
||||
into "$projectDir/src/main/jni/first-party/$packageName/headers"
|
||||
include "**/*.h"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task extractJNIFiles {
|
||||
doLast {
|
||||
configurations.extractJNI.files.each {
|
||||
def file = it.absoluteFile
|
||||
def packageName = file.name.tokenize('-')[0]
|
||||
copy {
|
||||
from zipTree(file)
|
||||
into "$projectDir/src/main/jni/first-party/$packageName/"
|
||||
include "jni/**/*"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
|
||||
@@ -386,7 +415,8 @@ android {
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
compileTask -> compileTask.dependsOn(packageReactNdkLibs)
|
||||
compileTask ->
|
||||
compileTask.dependsOn(packageReactNdkLibs)
|
||||
}
|
||||
|
||||
clean.dependsOn(cleanReactNdkLib)
|
||||
@@ -394,10 +424,16 @@ android {
|
||||
lintOptions {
|
||||
abortOnError(false)
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
exclude("META-INF/NOTICE")
|
||||
exclude("META-INF/LICENSE")
|
||||
}
|
||||
|
||||
configurations {
|
||||
extractHeaders
|
||||
extractJNI
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -412,6 +448,9 @@ dependencies {
|
||||
api("com.squareup.okhttp3:okhttp:${OKHTTP_VERSION}")
|
||||
api("com.squareup.okhttp3:okhttp-urlconnection:${OKHTTP_VERSION}")
|
||||
api("com.squareup.okio:okio:1.15.0")
|
||||
api("com.facebook.fbjni:fbjni-java-only:0.0.3")
|
||||
extractHeaders("com.facebook.fbjni:fbjni:0.0.2:headers")
|
||||
extractJNI("com.facebook.fbjni:fbjni:0.0.2")
|
||||
|
||||
testImplementation("junit:junit:${JUNIT_VERSION}")
|
||||
testImplementation("org.powermock:powermock-api-mockito:${POWERMOCK_VERSION}")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
VERSION_NAME=1000.0.0-master
|
||||
VERSION_NAME=0.62.0-rc.2
|
||||
GROUP=com.facebook.react
|
||||
|
||||
POM_NAME=ReactNative
|
||||
|
||||
@@ -5,7 +5,7 @@ rn_android_library(
|
||||
srcs = glob(["yoga/*.java"]),
|
||||
visibility = ["PUBLIC"],
|
||||
deps = [
|
||||
react_native_dep("java/com/facebook/jni:jni"),
|
||||
react_native_dep("libraries/fbjni:java"),
|
||||
react_native_dep("java/com/facebook/proguard/annotations:annotations"),
|
||||
react_native_dep("libraries/soloader/java/com/facebook/soloader:soloader"),
|
||||
react_native_dep("third-party/java/infer-annotations:infer-annotations"),
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
|
||||
* directory of this source tree.
|
||||
*
|
||||
* <p>Generated by an internal genrule from Flow types.
|
||||
*
|
||||
* @generated
|
||||
* @nolint
|
||||
*/
|
||||
|
||||
package com.facebook.fbreact.specs;
|
||||
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.ReactModuleWithSpec;
|
||||
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
|
||||
|
||||
public abstract class NativeLogBoxSpec extends ReactContextBaseJavaModule implements ReactModuleWithSpec, TurboModule {
|
||||
public NativeLogBoxSpec(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public abstract void hide();
|
||||
|
||||
@ReactMethod
|
||||
public abstract void show();
|
||||
}
|
||||
@@ -19,7 +19,7 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH) $(REACT_NATIVE)/ReactCommon/jsi $(call find-no
|
||||
LOCAL_CPP_FEATURES := exceptions
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := libjsireact libjsi
|
||||
LOCAL_SHARED_LIBRARIES := libfolly_json libfb libreactnativejni libhermes
|
||||
LOCAL_SHARED_LIBRARIES := libfolly_json libfb libfbjni libreactnativejni libhermes
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ rn_android_library(
|
||||
deps = [
|
||||
react_native_dep("java/com/facebook/proguard/annotations:annotations"),
|
||||
react_native_dep("libraries/soloader/java/com/facebook/soloader:soloader"),
|
||||
react_native_dep("java/com/facebook/jni:jni"),
|
||||
react_native_dep("libraries/fbjni:java"),
|
||||
":jni_hermes_samplingprofiler",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <fb/fbjni.h>
|
||||
#include <fbjni/fbjni.h>
|
||||
#include <string>
|
||||
|
||||
namespace facebook {
|
||||
|
||||
+1
-2
@@ -8,8 +8,7 @@
|
||||
#ifndef HERMESSAMPLINGPROFILER_H_
|
||||
#define HERMESSAMPLINGPROFILER_H_
|
||||
|
||||
#include <fb/fbjni.h>
|
||||
#include <jni/Registration.h>
|
||||
#include <fbjni/fbjni.h>
|
||||
#include <jsi/jsi.h>
|
||||
|
||||
namespace facebook {
|
||||
|
||||
@@ -18,7 +18,7 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH) $(REACT_NATIVE)/ReactCommon/jsi $(call find-no
|
||||
LOCAL_CPP_FEATURES := exceptions
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := libjsireact libjsi
|
||||
LOCAL_SHARED_LIBRARIES := libfolly_json libfb libreactnativejni libhermes
|
||||
LOCAL_SHARED_LIBRARIES := libfolly_json libfb libfbjni libreactnativejni libhermes
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
@@ -35,6 +35,6 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH) $(REACT_NATIVE)/ReactCommon/jsi $(call find-no
|
||||
LOCAL_CPP_FEATURES := exceptions
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := libjsireact libjsi libhermes-inspector
|
||||
LOCAL_SHARED_LIBRARIES := libfolly_json libfb libreactnativejni libhermes
|
||||
LOCAL_SHARED_LIBRARIES := libfolly_json libfb libfbjni libreactnativejni libhermes
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <../instrumentation/HermesMemoryDumper.h>
|
||||
#include <HermesExecutorFactory.h>
|
||||
#include <fb/fbjni.h>
|
||||
#include <fbjni/fbjni.h>
|
||||
#include <hermes/Public/GCConfig.h>
|
||||
#include <hermes/Public/RuntimeConfig.h>
|
||||
#include <jni.h>
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "rn_android_library")
|
||||
|
||||
rn_android_library(
|
||||
name = "jni",
|
||||
srcs = glob(["**/*.java"]),
|
||||
proguard_config = "fbjni.pro",
|
||||
visibility = [
|
||||
"PUBLIC",
|
||||
],
|
||||
deps = [
|
||||
react_native_dep("third-party/android/androidx:annotation"),
|
||||
react_native_dep("java/com/facebook/proguard/annotations:annotations"),
|
||||
react_native_dep("libraries/soloader/java/com/facebook/soloader:soloader"),
|
||||
react_native_dep("third-party/java/jsr-305:jsr-305"),
|
||||
],
|
||||
)
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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.jni;
|
||||
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
|
||||
/**
|
||||
* A Java Object that has native memory allocated corresponding to this instance.
|
||||
*
|
||||
* <p>NB: THREAD SAFETY (this comment also exists at Countable.cpp)
|
||||
*
|
||||
* <p>{@link #dispose} deletes the corresponding native object on whatever thread the method is
|
||||
* called on. In the common case when this is called by Countable#finalize(), this will be called on
|
||||
* the system finalizer thread. If you manually call dispose on the Java object, the native object
|
||||
* will be deleted synchronously on that thread.
|
||||
*/
|
||||
@DoNotStrip
|
||||
public class Countable {
|
||||
|
||||
static {
|
||||
SoLoader.loadLibrary("fb");
|
||||
}
|
||||
|
||||
// Private C++ instance
|
||||
@DoNotStrip private long mInstance = 0;
|
||||
|
||||
public native void dispose();
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
dispose();
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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.jni;
|
||||
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
|
||||
/** Utility class to determine CPU capabilities */
|
||||
@DoNotStrip
|
||||
public class CpuCapabilitiesJni {
|
||||
|
||||
static {
|
||||
SoLoader.loadLibrary("fb");
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
public static native boolean nativeDeviceSupportsNeon();
|
||||
|
||||
@DoNotStrip
|
||||
public static native boolean nativeDeviceSupportsVFPFP16();
|
||||
|
||||
@DoNotStrip
|
||||
public static native boolean nativeDeviceSupportsX86();
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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.jni;
|
||||
|
||||
import java.lang.ref.PhantomReference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* A thread which invokes the "destruct" routine for objects after they have been garbage collected.
|
||||
*
|
||||
* <p>An object which needs to be destructed should create a static subclass of {@link Destructor}.
|
||||
* Once the referent object is garbage collected, the DestructorThread will callback to the {@link
|
||||
* Destructor#destruct()} method.
|
||||
*
|
||||
* <p>The underlying thread in DestructorThread starts when the first Destructor is constructed and
|
||||
* then runs indefinitely.
|
||||
*/
|
||||
public class DestructorThread {
|
||||
|
||||
/**
|
||||
* N.B The Destructor <b>SHOULD NOT</b> refer back to its referent object either explicitly or
|
||||
* implicitly (for example, as a non-static inner class). This will create a reference cycle where
|
||||
* the referent object will never be garbage collected.
|
||||
*/
|
||||
public abstract static class Destructor extends PhantomReference<Object> {
|
||||
|
||||
private Destructor next;
|
||||
private Destructor previous;
|
||||
|
||||
public Destructor(Object referent) {
|
||||
super(referent, sReferenceQueue);
|
||||
sDestructorStack.push(this);
|
||||
}
|
||||
|
||||
private Destructor() {
|
||||
super(null, sReferenceQueue);
|
||||
}
|
||||
|
||||
/** Callback which is invoked when the original object has been garbage collected. */
|
||||
protected abstract void destruct();
|
||||
}
|
||||
|
||||
/** A list to keep all active Destructors in memory confined to the Destructor thread. */
|
||||
private static DestructorList sDestructorList;
|
||||
/** A thread safe stack where new Destructors are placed before being add to sDestructorList. */
|
||||
private static DestructorStack sDestructorStack;
|
||||
|
||||
private static ReferenceQueue sReferenceQueue;
|
||||
private static Thread sThread;
|
||||
|
||||
static {
|
||||
sDestructorStack = new DestructorStack();
|
||||
sReferenceQueue = new ReferenceQueue();
|
||||
sDestructorList = new DestructorList();
|
||||
sThread =
|
||||
new Thread("HybridData DestructorThread") {
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
try {
|
||||
Destructor current = (Destructor) sReferenceQueue.remove();
|
||||
current.destruct();
|
||||
|
||||
// If current is in the sDestructorStack,
|
||||
// transfer all the Destructors in the stack to the list.
|
||||
if (current.previous == null) {
|
||||
sDestructorStack.transferAllToList();
|
||||
}
|
||||
|
||||
DestructorList.drop(current);
|
||||
} catch (InterruptedException e) {
|
||||
// Continue. This thread should never be terminated.
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
sThread.start();
|
||||
}
|
||||
|
||||
private static class Terminus extends Destructor {
|
||||
@Override
|
||||
protected void destruct() {
|
||||
throw new IllegalStateException("Cannot destroy Terminus Destructor.");
|
||||
}
|
||||
}
|
||||
|
||||
/** This is a thread safe, lock-free Treiber-like Stack of Destructors. */
|
||||
private static class DestructorStack {
|
||||
private AtomicReference<Destructor> mHead = new AtomicReference<>();
|
||||
|
||||
public void push(Destructor newHead) {
|
||||
Destructor oldHead;
|
||||
do {
|
||||
oldHead = mHead.get();
|
||||
newHead.next = oldHead;
|
||||
} while (!mHead.compareAndSet(oldHead, newHead));
|
||||
}
|
||||
|
||||
public void transferAllToList() {
|
||||
Destructor current = mHead.getAndSet(null);
|
||||
while (current != null) {
|
||||
Destructor next = current.next;
|
||||
sDestructorList.enqueue(current);
|
||||
current = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** A doubly-linked list of Destructors. */
|
||||
private static class DestructorList {
|
||||
private Destructor mHead;
|
||||
|
||||
public DestructorList() {
|
||||
mHead = new Terminus();
|
||||
mHead.next = new Terminus();
|
||||
mHead.next.previous = mHead;
|
||||
}
|
||||
|
||||
public void enqueue(Destructor current) {
|
||||
current.next = mHead.next;
|
||||
mHead.next = current;
|
||||
|
||||
current.next.previous = current;
|
||||
current.previous = mHead;
|
||||
}
|
||||
|
||||
private static void drop(Destructor current) {
|
||||
current.next.previous = current.previous;
|
||||
current.previous.next = current.next;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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.jni;
|
||||
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
|
||||
@DoNotStrip
|
||||
public abstract class HybridClassBase extends HybridData {}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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.jni;
|
||||
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
|
||||
/**
|
||||
* This object holds a native C++ member for hybrid Java/C++ objects.
|
||||
*
|
||||
* <p>NB: THREAD SAFETY
|
||||
*
|
||||
* <p>{@link #resetNative} deletes the corresponding native object synchronously on whatever thread
|
||||
* the method is called on. Otherwise, deletion will occur on the {@link DestructorThread} thread.
|
||||
*/
|
||||
@DoNotStrip
|
||||
public class HybridData {
|
||||
|
||||
static {
|
||||
SoLoader.loadLibrary("fb");
|
||||
}
|
||||
|
||||
@DoNotStrip private Destructor mDestructor = new Destructor(this);
|
||||
|
||||
/**
|
||||
* To explicitly delete the instance, call resetNative(). If the C++ instance is referenced after
|
||||
* this is called, a NullPointerException will be thrown. resetNative() may be called multiple
|
||||
* times safely. Because the {@link DestructorThread} also calls resetNative, the instance will
|
||||
* not leak if this is not called, but timing of deletion and the thread the C++ dtor is called on
|
||||
* will be at the whim of the Java GC. If you want to control the thread and timing of the
|
||||
* destructor, you should call resetNative() explicitly.
|
||||
*/
|
||||
public synchronized void resetNative() {
|
||||
mDestructor.destruct();
|
||||
}
|
||||
|
||||
/**
|
||||
* N.B. Thread safety. If you call isValid from a different thread than {@link #resetNative()}
|
||||
* then be sure to do so while synchronizing on the hybrid. For example:
|
||||
*
|
||||
* <pre><code>
|
||||
* synchronized(hybrid) {
|
||||
* if (hybrid.isValid) {
|
||||
* // Do stuff.
|
||||
* }
|
||||
* }
|
||||
* </code></pre>
|
||||
*/
|
||||
public boolean isValid() {
|
||||
return mDestructor.mNativePointer != 0;
|
||||
}
|
||||
|
||||
public static class Destructor extends DestructorThread.Destructor {
|
||||
|
||||
// Private C++ instance
|
||||
@DoNotStrip private long mNativePointer;
|
||||
|
||||
Destructor(Object referent) {
|
||||
super(referent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void destruct() {
|
||||
// When invoked from the DestructorThread instead of resetNative,
|
||||
// the DestructorThread has exclusive ownership of the HybridData
|
||||
// so synchronization is not necessary.
|
||||
deleteNative(mNativePointer);
|
||||
mNativePointer = 0;
|
||||
}
|
||||
|
||||
static native void deleteNative(long pointer);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user