mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a8784c241 | ||
|
|
6bab7356a6 | ||
|
|
9954499df1 | ||
|
|
f465017fe8 | ||
|
|
02a61a8d8e | ||
|
|
33650db050 | ||
|
|
cc1499e124 | ||
|
|
7cb831d164 | ||
|
|
e6c1fb7212 | ||
|
|
e56089af1d | ||
|
|
e258e5f214 | ||
|
|
3259353fce |
@@ -62,11 +62,11 @@ aliases:
|
||||
|
||||
- &restore-cache-buck
|
||||
keys:
|
||||
- v1-buck-{{ arch }}-v2017.11.16.01
|
||||
- v1-buck-{{ arch }}-v2017.09.04.02
|
||||
- &save-cache-buck
|
||||
paths:
|
||||
- ~/buck
|
||||
key: v1-buck-{{ arch }}-v2017.11.16.01
|
||||
key: v1-buck-{{ arch }}-v2017.09.04.02
|
||||
|
||||
- &restore-cache-watchman
|
||||
keys:
|
||||
|
||||
@@ -528,14 +528,14 @@ module.exports = {
|
||||
ValueXY: AnimatedValueXY,
|
||||
/**
|
||||
* Exported to use the Interpolation type in flow.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animated.html#interpolation
|
||||
*/
|
||||
Interpolation: AnimatedInterpolation,
|
||||
/**
|
||||
* Exported for ease of type checking. All animated values derive from this
|
||||
* class.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animated.html#node
|
||||
*/
|
||||
Node: AnimatedNode,
|
||||
@@ -557,7 +557,7 @@ module.exports = {
|
||||
/**
|
||||
* Animates a value according to an analytical spring model based on
|
||||
* damped harmonic oscillation.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animated.html#spring
|
||||
*/
|
||||
spring,
|
||||
@@ -565,7 +565,7 @@ module.exports = {
|
||||
/**
|
||||
* Creates a new Animated value composed from two Animated values added
|
||||
* together.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animated.html#add
|
||||
*/
|
||||
add,
|
||||
@@ -573,7 +573,7 @@ module.exports = {
|
||||
/**
|
||||
* Creates a new Animated value composed by dividing the first Animated value
|
||||
* by the second Animated value.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animated.html#divide
|
||||
*/
|
||||
divide,
|
||||
@@ -581,7 +581,7 @@ module.exports = {
|
||||
/**
|
||||
* Creates a new Animated value composed from two Animated values multiplied
|
||||
* together.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animated.html#multiply
|
||||
*/
|
||||
multiply,
|
||||
@@ -589,7 +589,7 @@ module.exports = {
|
||||
/**
|
||||
* Creates a new Animated value that is the (non-negative) modulo of the
|
||||
* provided Animated value.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animated.html#modulo
|
||||
*/
|
||||
modulo,
|
||||
@@ -598,14 +598,14 @@ module.exports = {
|
||||
* Create a new Animated value that is limited between 2 values. It uses the
|
||||
* difference between the last value so even if the value is far from the
|
||||
* bounds it will start changing when the value starts getting closer again.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animated.html#diffclamp
|
||||
*/
|
||||
diffClamp,
|
||||
|
||||
/**
|
||||
* Starts an animation after the given delay.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animated.html#delay
|
||||
*/
|
||||
delay,
|
||||
@@ -613,7 +613,7 @@ module.exports = {
|
||||
* Starts an array of animations in order, waiting for each to complete
|
||||
* before starting the next. If the current running animation is stopped, no
|
||||
* following animations will be started.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animated.html#sequence
|
||||
*/
|
||||
sequence,
|
||||
@@ -621,44 +621,44 @@ module.exports = {
|
||||
* Starts an array of animations all at the same time. By default, if one
|
||||
* of the animations is stopped, they will all be stopped. You can override
|
||||
* this with the `stopTogether` flag.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animated.html#parallel
|
||||
*/
|
||||
parallel,
|
||||
/**
|
||||
* Array of animations may run in parallel (overlap), but are started in
|
||||
* sequence with successive delays. Nice for doing trailing effects.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animated.html#stagger
|
||||
*/
|
||||
stagger,
|
||||
/**
|
||||
* Loops a given animation continuously, so that each time it reaches the
|
||||
* end, it resets and begins again from the start.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animated.html#loop
|
||||
*/
|
||||
*/
|
||||
loop,
|
||||
|
||||
/**
|
||||
* Takes an array of mappings and extracts values from each arg accordingly,
|
||||
* then calls `setValue` on the mapped outputs.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animated.html#event
|
||||
*/
|
||||
event,
|
||||
|
||||
/**
|
||||
* Make any React component Animatable. Used to create `Animated.View`, etc.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animated.html#createanimatedcomponent
|
||||
*/
|
||||
createAnimatedComponent,
|
||||
|
||||
/**
|
||||
* Imperative API to attach an animated value to an event on a view. Prefer
|
||||
* Imperative API to attach an animated value to an event on a view. Prefer
|
||||
* using `Animated.event` with `useNativeDrive: true` if possible.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animated.html#attachnativeevent
|
||||
*/
|
||||
attachNativeEvent,
|
||||
@@ -666,7 +666,7 @@ module.exports = {
|
||||
/**
|
||||
* Advanced imperative API for snooping on animated events that are passed in
|
||||
* through props. Use values directly where possible.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animated.html#forkevent
|
||||
*/
|
||||
forkEvent,
|
||||
|
||||
@@ -193,9 +193,7 @@ function validateTransform(configs: Array<Object>): void {
|
||||
configs.forEach(config => {
|
||||
if (!TRANSFORM_WHITELIST.hasOwnProperty(config.property)) {
|
||||
throw new Error(
|
||||
`Property '${
|
||||
config.property
|
||||
}' is not supported by native animated module`,
|
||||
`Property '${config.property}' is not supported by native animated module`,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -68,7 +68,7 @@ function _flush(rootNode: AnimatedValue): void {
|
||||
* multiple properties in a synchronized fashion, but can only be driven by one
|
||||
* mechanism at a time. Using a new mechanism (e.g. starting a new animation,
|
||||
* or calling `setValue`) will stop any previous ones.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvalue.html
|
||||
*/
|
||||
class AnimatedValue extends AnimatedWithChildren {
|
||||
@@ -108,7 +108,7 @@ class AnimatedValue extends AnimatedWithChildren {
|
||||
/**
|
||||
* Directly set the value. This will stop any animations running on the value
|
||||
* and update all the bound properties.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvalue.html#setvalue
|
||||
*/
|
||||
setValue(value: number): void {
|
||||
@@ -129,7 +129,7 @@ class AnimatedValue extends AnimatedWithChildren {
|
||||
* Sets an offset that is applied on top of whatever value is set, whether via
|
||||
* `setValue`, an animation, or `Animated.event`. Useful for compensating
|
||||
* things like the start of a pan gesture.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvalue.html#setoffset
|
||||
*/
|
||||
setOffset(offset: number): void {
|
||||
@@ -142,7 +142,7 @@ class AnimatedValue extends AnimatedWithChildren {
|
||||
/**
|
||||
* Merges the offset value into the base value and resets the offset to zero.
|
||||
* The final output of the value is unchanged.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvalue.html#flattenoffset
|
||||
*/
|
||||
flattenOffset(): void {
|
||||
@@ -156,7 +156,7 @@ class AnimatedValue extends AnimatedWithChildren {
|
||||
/**
|
||||
* Sets the offset value to the base value, and resets the base value to zero.
|
||||
* The final output of the value is unchanged.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvalue.html#extractoffset
|
||||
*/
|
||||
extractOffset(): void {
|
||||
@@ -171,7 +171,7 @@ class AnimatedValue extends AnimatedWithChildren {
|
||||
* Adds an asynchronous listener to the value so you can observe updates from
|
||||
* animations. This is useful because there is no way to
|
||||
* synchronously read the value because it might be driven natively.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvalue.html#addlistener
|
||||
*/
|
||||
addListener(callback: ValueListenerCallback): string {
|
||||
@@ -184,9 +184,9 @@ class AnimatedValue extends AnimatedWithChildren {
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a listener. The `id` param shall match the identifier
|
||||
* previously returned by `addListener()`.
|
||||
*
|
||||
* Unregister a listener. The `id` param shall match the identifier
|
||||
* previously returned by `addListener()`.
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvalue.html#removelistener
|
||||
*/
|
||||
removeListener(id: string): void {
|
||||
@@ -198,7 +198,7 @@ class AnimatedValue extends AnimatedWithChildren {
|
||||
|
||||
/**
|
||||
* Remove all registered listeners.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvalue.html#removealllisteners
|
||||
*/
|
||||
removeAllListeners(): void {
|
||||
@@ -239,7 +239,7 @@ class AnimatedValue extends AnimatedWithChildren {
|
||||
* Stops any running animation or tracking. `callback` is invoked with the
|
||||
* final value after stopping the animation, which is useful for updating
|
||||
* state to match the animation position with layout.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvalue.html#stopanimation
|
||||
*/
|
||||
stopAnimation(callback?: ?(value: number) => void): void {
|
||||
@@ -251,7 +251,7 @@ class AnimatedValue extends AnimatedWithChildren {
|
||||
|
||||
/**
|
||||
* Stops any animation and resets the value to its original.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvalue.html#resetanimation
|
||||
*/
|
||||
resetAnimation(callback?: ?(value: number) => void): void {
|
||||
@@ -270,7 +270,7 @@ class AnimatedValue extends AnimatedWithChildren {
|
||||
/**
|
||||
* Typically only used internally, but could be used by a custom Animation
|
||||
* class.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvalue.html#animate
|
||||
*/
|
||||
animate(animation: Animation, callback: ?EndCallback): void {
|
||||
|
||||
@@ -22,9 +22,9 @@ type ValueXYListenerCallback = (value: {x: number, y: number}) => void;
|
||||
let _uniqueId = 1;
|
||||
|
||||
/**
|
||||
* 2D Value for driving 2D animations, such as pan gestures. Almost identical
|
||||
* 2D Value for driving 2D animations, such as pan gestures. Almost identical
|
||||
* API to normal `Animated.Value`, but multiplexed.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvaluexy.html
|
||||
*/
|
||||
class AnimatedValueXY extends AnimatedWithChildren {
|
||||
@@ -55,7 +55,7 @@ class AnimatedValueXY extends AnimatedWithChildren {
|
||||
/**
|
||||
* Directly set the value. This will stop any animations running on the value
|
||||
* and update all the bound properties.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvaluexy.html#setvalue
|
||||
*/
|
||||
setValue(value: {x: number, y: number}) {
|
||||
@@ -64,10 +64,10 @@ class AnimatedValueXY extends AnimatedWithChildren {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an offset that is applied on top of whatever value is set, whether
|
||||
* via `setValue`, an animation, or `Animated.event`. Useful for compensating
|
||||
* Sets an offset that is applied on top of whatever value is set, whether
|
||||
* via `setValue`, an animation, or `Animated.event`. Useful for compensating
|
||||
* things like the start of a pan gesture.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvaluexy.html#setoffset
|
||||
*/
|
||||
setOffset(offset: {x: number, y: number}) {
|
||||
@@ -76,9 +76,9 @@ class AnimatedValueXY extends AnimatedWithChildren {
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the offset value into the base value and resets the offset to zero.
|
||||
* Merges the offset value into the base value and resets the offset to zero.
|
||||
* The final output of the value is unchanged.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvaluexy.html#flattenoffset
|
||||
*/
|
||||
flattenOffset(): void {
|
||||
@@ -87,9 +87,9 @@ class AnimatedValueXY extends AnimatedWithChildren {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the offset value to the base value, and resets the base value to
|
||||
* Sets the offset value to the base value, and resets the base value to
|
||||
* zero. The final output of the value is unchanged.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvaluexy.html#extractoffset
|
||||
*/
|
||||
extractOffset(): void {
|
||||
@@ -106,7 +106,7 @@ class AnimatedValueXY extends AnimatedWithChildren {
|
||||
|
||||
/**
|
||||
* Stops any animation and resets the value to its original.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvaluexy.html#resetanimation
|
||||
*/
|
||||
resetAnimation(callback?: (value: {x: number, y: number}) => void): void {
|
||||
@@ -116,10 +116,10 @@ class AnimatedValueXY extends AnimatedWithChildren {
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops any running animation or tracking. `callback` is invoked with the
|
||||
* final value after stopping the animation, which is useful for updating
|
||||
* Stops any running animation or tracking. `callback` is invoked with the
|
||||
* final value after stopping the animation, which is useful for updating
|
||||
* state to match the animation position with layout.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvaluexy.html#stopanimation
|
||||
*/
|
||||
stopAnimation(callback?: (value: {x: number, y: number}) => void): void {
|
||||
@@ -129,12 +129,12 @@ class AnimatedValueXY extends AnimatedWithChildren {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an asynchronous listener to the value so you can observe updates from
|
||||
* animations. This is useful because there is no way to synchronously read
|
||||
* Adds an asynchronous listener to the value so you can observe updates from
|
||||
* animations. This is useful because there is no way to synchronously read
|
||||
* the value because it might be driven natively.
|
||||
*
|
||||
*
|
||||
* Returns a string that serves as an identifier for the listener.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvaluexy.html#addlistener
|
||||
*/
|
||||
addListener(callback: ValueXYListenerCallback): string {
|
||||
@@ -150,9 +150,9 @@ class AnimatedValueXY extends AnimatedWithChildren {
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a listener. The `id` param shall match the identifier
|
||||
* previously returned by `addListener()`.
|
||||
*
|
||||
* Unregister a listener. The `id` param shall match the identifier
|
||||
* previously returned by `addListener()`.
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvaluexy.html#removelistener
|
||||
*/
|
||||
removeListener(id: string): void {
|
||||
@@ -163,7 +163,7 @@ class AnimatedValueXY extends AnimatedWithChildren {
|
||||
|
||||
/**
|
||||
* Remove all registered listeners.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvaluexy.html#removealllisteners
|
||||
*/
|
||||
removeAllListeners(): void {
|
||||
@@ -174,7 +174,7 @@ class AnimatedValueXY extends AnimatedWithChildren {
|
||||
|
||||
/**
|
||||
* Converts `{x, y}` into `{left, top}` for use in style.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvaluexy.html#getlayout
|
||||
*/
|
||||
getLayout(): {[key: string]: AnimatedValue} {
|
||||
@@ -186,7 +186,7 @@ class AnimatedValueXY extends AnimatedWithChildren {
|
||||
|
||||
/**
|
||||
* Converts `{x, y}` into a useable translation transform.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvaluexy.html#gettranslatetransform
|
||||
*/
|
||||
getTranslateTransform(): Array<{[key: string]: AnimatedValue}> {
|
||||
|
||||
@@ -59,9 +59,7 @@ class URL {
|
||||
if (BLOB_URL_PREFIX === null) {
|
||||
throw new Error('Cannot create URL for blob!');
|
||||
}
|
||||
return `${BLOB_URL_PREFIX}${blob.blobId}?offset=${blob.offset}&size=${
|
||||
blob.size
|
||||
}`;
|
||||
return `${BLOB_URL_PREFIX}${blob.blobId}?offset=${blob.offset}&size=${blob.size}`;
|
||||
}
|
||||
|
||||
static revokeObjectURL(url: string) {
|
||||
|
||||
@@ -35,7 +35,6 @@ class BugReporting {
|
||||
static _extraSources: Map<string, SourceCallback> = new Map();
|
||||
static _fileSources: Map<string, SourceCallback> = new Map();
|
||||
static _subscription: ?EmitterSubscription = null;
|
||||
static _redboxSubscription: ?EmitterSubscription = null;
|
||||
|
||||
static _maybeInit() {
|
||||
if (!BugReporting._subscription) {
|
||||
@@ -43,11 +42,6 @@ class BugReporting {
|
||||
.addListener('collectBugExtraData', BugReporting.collectExtraData, null);
|
||||
defaultExtras();
|
||||
}
|
||||
|
||||
if (!BugReporting._redboxSubscription) {
|
||||
BugReporting._redboxSubscription = RCTDeviceEventEmitter
|
||||
.addListener('collectRedBoxExtraData', BugReporting.collectExtraData, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,11 +98,6 @@ class BugReporting {
|
||||
BugReportingNativeModule.setExtraData &&
|
||||
BugReportingNativeModule.setExtraData(extraData, fileData);
|
||||
|
||||
const RedBoxNativeModule = require('NativeModules').RedBox;
|
||||
RedBoxNativeModule &&
|
||||
RedBoxNativeModule.setExtraData &&
|
||||
RedBoxNativeModule.setExtraData(extraData, 'From BugReporting.js');
|
||||
|
||||
return { extras: extraData, files: fileData };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,8 +72,8 @@ const getPhotosParamChecker = createStrictShapeTypeChecker({
|
||||
groupName: PropTypes.string,
|
||||
|
||||
/**
|
||||
* Specifies filter on asset type
|
||||
*/
|
||||
* Specifies filter on asset type
|
||||
*/
|
||||
assetType: PropTypes.oneOf(Object.keys(ASSET_TYPE_OPTIONS)),
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
exports.version = {
|
||||
major: 0,
|
||||
minor: 0,
|
||||
patch: 0,
|
||||
minor: 52,
|
||||
patch: 1,
|
||||
prerelease: null,
|
||||
};
|
||||
|
||||
@@ -60,17 +60,17 @@ export type ViewabilityConfig = {|
|
||||
|};
|
||||
|
||||
/**
|
||||
* A Utility class for calculating viewable items based on current metrics like scroll position and
|
||||
* layout.
|
||||
*
|
||||
* An item is said to be in a "viewable" state when any of the following
|
||||
* is true for longer than `minimumViewTime` milliseconds (after an interaction if `waitForInteraction`
|
||||
* is true):
|
||||
*
|
||||
* - Occupying >= `viewAreaCoveragePercentThreshold` of the view area XOR fraction of the item
|
||||
* visible in the view area >= `itemVisiblePercentThreshold`.
|
||||
* - Entirely visible on screen
|
||||
*/
|
||||
* A Utility class for calculating viewable items based on current metrics like scroll position and
|
||||
* layout.
|
||||
*
|
||||
* An item is said to be in a "viewable" state when any of the following
|
||||
* is true for longer than `minimumViewTime` milliseconds (after an interaction if `waitForInteraction`
|
||||
* is true):
|
||||
*
|
||||
* - Occupying >= `viewAreaCoveragePercentThreshold` of the view area XOR fraction of the item
|
||||
* visible in the view area >= `itemVisiblePercentThreshold`.
|
||||
* - Entirely visible on screen
|
||||
*/
|
||||
class ViewabilityHelper {
|
||||
_config: ViewabilityConfig;
|
||||
_hasInteracted: boolean = false;
|
||||
|
||||
@@ -59,7 +59,7 @@ let wrapperComponentProvider: ?WrapperComponentProvider;
|
||||
|
||||
/**
|
||||
* `AppRegistry` is the JavaScript entry point to running all React Native apps.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/appregistry.html
|
||||
*/
|
||||
const AppRegistry = {
|
||||
@@ -89,7 +89,7 @@ const AppRegistry = {
|
||||
|
||||
/**
|
||||
* Registers an app's root component.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/appregistry.html#registercomponent
|
||||
*/
|
||||
registerComponent(
|
||||
@@ -155,7 +155,7 @@ const AppRegistry = {
|
||||
|
||||
/**
|
||||
* Loads the JavaScript bundle and runs the app.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/appregistry.html#runapplication
|
||||
*/
|
||||
runApplication(appKey: string, appParameters: any): void {
|
||||
@@ -197,8 +197,8 @@ const AppRegistry = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Stops an application when a view should be destroyed.
|
||||
*
|
||||
* Stops an application when a view should be destroyed.
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/appregistry.html#unmountapplicationcomponentatroottag
|
||||
*/
|
||||
unmountApplicationComponentAtRootTag(rootTag: number): void {
|
||||
@@ -207,7 +207,7 @@ const AppRegistry = {
|
||||
|
||||
/**
|
||||
* Register a headless task. A headless task is a bit of code that runs without a UI.
|
||||
*
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/appregistry.html#registerheadlesstask
|
||||
*/
|
||||
registerHeadlessTask(taskKey: string, task: TaskProvider): void {
|
||||
|
||||
@@ -398,8 +398,7 @@ class YellowBox extends React.Component<
|
||||
onDismissAll={() => this.dismissWarning(null)}
|
||||
onMinimize={() => this.setState({inspecting: null})}
|
||||
toggleStacktrace={() =>
|
||||
this.setState({stacktraceVisible: !stacktraceVisible})
|
||||
}
|
||||
this.setState({stacktraceVisible: !stacktraceVisible})}
|
||||
/>
|
||||
) : null;
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ Error: ${e.message}`
|
||||
}
|
||||
case 'error': {
|
||||
HMRLoadingView.hide();
|
||||
throw new Error(data.body.type + ' ' + data.body.description);
|
||||
throw new Error(`${data.body.type}: ${data.body.message}`);
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Unexpected message: ${data}`);
|
||||
|
||||
@@ -75,15 +75,13 @@ class EventCheckBoxExample extends React.Component<{}, $FlowFixMeState> {
|
||||
<View>
|
||||
<CheckBox
|
||||
onValueChange={value =>
|
||||
this.setState({eventCheckBoxRegressionIsOn: value})
|
||||
}
|
||||
this.setState({eventCheckBoxRegressionIsOn: value})}
|
||||
style={{marginBottom: 10}}
|
||||
value={this.state.eventCheckBoxRegressionIsOn}
|
||||
/>
|
||||
<CheckBox
|
||||
onValueChange={value =>
|
||||
this.setState({eventCheckBoxRegressionIsOn: value})
|
||||
}
|
||||
this.setState({eventCheckBoxRegressionIsOn: value})}
|
||||
style={{marginBottom: 10}}
|
||||
value={this.state.eventCheckBoxRegressionIsOn}
|
||||
/>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#define RCT_REACT_NATIVE_VERSION @{ \
|
||||
@"major": @(0), \
|
||||
@"minor": @(0), \
|
||||
@"patch": @(0), \
|
||||
@"minor": @(52), \
|
||||
@"patch": @(1), \
|
||||
@"prerelease": [NSNull null], \
|
||||
}
|
||||
|
||||
+264
-316
@@ -13,9 +13,7 @@
|
||||
#import "RCTConvert.h"
|
||||
#import "RCTDefines.h"
|
||||
#import "RCTErrorInfo.h"
|
||||
#import "RCTEventDispatcher.h"
|
||||
#import "RCTJSStackFrame.h"
|
||||
#import "RCTRedBoxExtraDataViewController.h"
|
||||
#import "RCTUtils.h"
|
||||
|
||||
#if RCT_DEBUG
|
||||
@@ -26,7 +24,6 @@
|
||||
|
||||
- (void)redBoxWindow:(RCTRedBoxWindow *)redBoxWindow openStackFrameInEditor:(RCTJSStackFrame *)stackFrame;
|
||||
- (void)reloadFromRedBoxWindow:(RCTRedBoxWindow *)redBoxWindow;
|
||||
- (void)loadExtraDataViewController;
|
||||
|
||||
@end
|
||||
|
||||
@@ -36,332 +33,308 @@
|
||||
|
||||
@implementation RCTRedBoxWindow
|
||||
{
|
||||
UITableView *_stackTraceTableView;
|
||||
NSString *_lastErrorMessage;
|
||||
NSArray<RCTJSStackFrame *> *_lastStackTrace;
|
||||
UITableView *_stackTraceTableView;
|
||||
NSString *_lastErrorMessage;
|
||||
NSArray<RCTJSStackFrame *> *_lastStackTrace;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
{
|
||||
if ((self = [super initWithFrame:frame])) {
|
||||
if ((self = [super initWithFrame:frame])) {
|
||||
#if TARGET_OS_TV
|
||||
self.windowLevel = UIWindowLevelAlert + 1000;
|
||||
self.windowLevel = UIWindowLevelAlert + 1000;
|
||||
#else
|
||||
self.windowLevel = UIWindowLevelStatusBar - 1;
|
||||
self.windowLevel = UIWindowLevelStatusBar - 1;
|
||||
#endif
|
||||
self.backgroundColor = [UIColor colorWithRed:0.8 green:0 blue:0 alpha:1];
|
||||
self.hidden = YES;
|
||||
self.backgroundColor = [UIColor colorWithRed:0.8 green:0 blue:0 alpha:1];
|
||||
self.hidden = YES;
|
||||
|
||||
UIViewController *rootController = [UIViewController new];
|
||||
self.rootViewController = rootController;
|
||||
UIView *rootView = rootController.view;
|
||||
rootView.backgroundColor = [UIColor clearColor];
|
||||
UIViewController *rootController = [UIViewController new];
|
||||
self.rootViewController = rootController;
|
||||
UIView *rootView = rootController.view;
|
||||
rootView.backgroundColor = [UIColor clearColor];
|
||||
|
||||
const CGFloat buttonHeight = 60;
|
||||
const CGFloat buttonHeight = 60;
|
||||
|
||||
CGRect detailsFrame = rootView.bounds;
|
||||
detailsFrame.size.height -= buttonHeight;
|
||||
CGRect detailsFrame = rootView.bounds;
|
||||
detailsFrame.size.height -= buttonHeight;
|
||||
|
||||
_stackTraceTableView = [[UITableView alloc] initWithFrame:detailsFrame style:UITableViewStylePlain];
|
||||
_stackTraceTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
_stackTraceTableView.delegate = self;
|
||||
_stackTraceTableView.dataSource = self;
|
||||
_stackTraceTableView.backgroundColor = [UIColor clearColor];
|
||||
_stackTraceTableView = [[UITableView alloc] initWithFrame:detailsFrame style:UITableViewStylePlain];
|
||||
_stackTraceTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
_stackTraceTableView.delegate = self;
|
||||
_stackTraceTableView.dataSource = self;
|
||||
_stackTraceTableView.backgroundColor = [UIColor clearColor];
|
||||
#if !TARGET_OS_TV
|
||||
_stackTraceTableView.separatorColor = [UIColor colorWithWhite:1 alpha:0.3];
|
||||
_stackTraceTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
|
||||
_stackTraceTableView.separatorColor = [UIColor colorWithWhite:1 alpha:0.3];
|
||||
_stackTraceTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
|
||||
#endif
|
||||
_stackTraceTableView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
|
||||
[rootView addSubview:_stackTraceTableView];
|
||||
_stackTraceTableView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
|
||||
[rootView addSubview:_stackTraceTableView];
|
||||
|
||||
#if TARGET_OS_SIMULATOR
|
||||
NSString *reloadText = @"Reload JS (\u2318R)";
|
||||
NSString *dismissText = @"Dismiss (ESC)";
|
||||
NSString *copyText = @"Copy (\u2325\u2318C)";
|
||||
NSString *extraText = @"Extra Info (\u2318E)";
|
||||
#else
|
||||
NSString *reloadText = @"Reload JS";
|
||||
NSString *dismissText = @"Dismiss";
|
||||
NSString *copyText = @"Copy";
|
||||
NSString *extraText = @"Extra Info";
|
||||
#endif
|
||||
#if TARGET_OS_SIMULATOR
|
||||
NSString *reloadText = @"Reload JS (\u2318R)";
|
||||
NSString *dismissText = @"Dismiss (ESC)";
|
||||
NSString *copyText = @"Copy (\u2325\u2318C)";
|
||||
#else
|
||||
NSString *reloadText = @"Reload JS";
|
||||
NSString *dismissText = @"Dismiss";
|
||||
NSString *copyText = @"Copy";
|
||||
#endif
|
||||
|
||||
UIButton *dismissButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
dismissButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin;
|
||||
dismissButton.accessibilityIdentifier = @"redbox-dismiss";
|
||||
dismissButton.titleLabel.font = [UIFont systemFontOfSize:13];
|
||||
[dismissButton setTitle:dismissText forState:UIControlStateNormal];
|
||||
[dismissButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateNormal];
|
||||
[dismissButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
|
||||
[dismissButton addTarget:self action:@selector(dismiss) forControlEvents:UIControlEventTouchUpInside];
|
||||
UIButton *dismissButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
dismissButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin;
|
||||
dismissButton.accessibilityIdentifier = @"redbox-dismiss";
|
||||
dismissButton.titleLabel.font = [UIFont systemFontOfSize:14];
|
||||
[dismissButton setTitle:dismissText forState:UIControlStateNormal];
|
||||
[dismissButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateNormal];
|
||||
[dismissButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
|
||||
[dismissButton addTarget:self action:@selector(dismiss) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
UIButton *reloadButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
reloadButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin;
|
||||
reloadButton.accessibilityIdentifier = @"redbox-reload";
|
||||
reloadButton.titleLabel.font = [UIFont systemFontOfSize:13];
|
||||
UIButton *reloadButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
reloadButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin;
|
||||
reloadButton.accessibilityIdentifier = @"redbox-reload";
|
||||
reloadButton.titleLabel.font = [UIFont systemFontOfSize:14];
|
||||
|
||||
[reloadButton setTitle:reloadText forState:UIControlStateNormal];
|
||||
[reloadButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateNormal];
|
||||
[reloadButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
|
||||
[reloadButton addTarget:self action:@selector(reload) forControlEvents:UIControlEventTouchUpInside];
|
||||
[reloadButton setTitle:reloadText forState:UIControlStateNormal];
|
||||
[reloadButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateNormal];
|
||||
[reloadButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
|
||||
[reloadButton addTarget:self action:@selector(reload) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
UIButton *copyButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
copyButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin;
|
||||
copyButton.accessibilityIdentifier = @"redbox-copy";
|
||||
copyButton.titleLabel.font = [UIFont systemFontOfSize:13];
|
||||
[copyButton setTitle:copyText forState:UIControlStateNormal];
|
||||
[copyButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateNormal];
|
||||
[copyButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
|
||||
[copyButton addTarget:self action:@selector(copyStack) forControlEvents:UIControlEventTouchUpInside];
|
||||
UIButton *copyButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
copyButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin;
|
||||
copyButton.accessibilityIdentifier = @"redbox-copy";
|
||||
copyButton.titleLabel.font = [UIFont systemFontOfSize:14];
|
||||
[copyButton setTitle:copyText forState:UIControlStateNormal];
|
||||
[copyButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateNormal];
|
||||
[copyButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
|
||||
[copyButton addTarget:self action:@selector(copyStack) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
UIButton *extraButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
extraButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin;
|
||||
extraButton.accessibilityIdentifier = @"redbox-extra";
|
||||
extraButton.titleLabel.font = [UIFont systemFontOfSize:13];
|
||||
[extraButton setTitle:extraText forState:UIControlStateNormal];
|
||||
[extraButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateNormal];
|
||||
[extraButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
|
||||
[extraButton addTarget:self action:@selector(showExtraDataViewController) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
CGFloat buttonWidth = self.bounds.size.width / 4;
|
||||
dismissButton.frame = CGRectMake(0, self.bounds.size.height - buttonHeight, buttonWidth, buttonHeight);
|
||||
reloadButton.frame = CGRectMake(buttonWidth, self.bounds.size.height - buttonHeight, buttonWidth, buttonHeight);
|
||||
copyButton.frame = CGRectMake(buttonWidth * 2, self.bounds.size.height - buttonHeight, buttonWidth, buttonHeight);
|
||||
extraButton.frame = CGRectMake(buttonWidth * 3, self.bounds.size.height - buttonHeight, buttonWidth, buttonHeight);
|
||||
|
||||
[rootView addSubview:dismissButton];
|
||||
[rootView addSubview:reloadButton];
|
||||
[rootView addSubview:copyButton];
|
||||
[rootView addSubview:extraButton];
|
||||
}
|
||||
return self;
|
||||
CGFloat buttonWidth = self.bounds.size.width / 3;
|
||||
dismissButton.frame = CGRectMake(0, self.bounds.size.height - buttonHeight, buttonWidth, buttonHeight);
|
||||
reloadButton.frame = CGRectMake(buttonWidth, self.bounds.size.height - buttonHeight, buttonWidth, buttonHeight);
|
||||
copyButton.frame = CGRectMake(buttonWidth * 2, self.bounds.size.height - buttonHeight, buttonWidth, buttonHeight);
|
||||
[rootView addSubview:dismissButton];
|
||||
[rootView addSubview:reloadButton];
|
||||
[rootView addSubview:copyButton];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
_stackTraceTableView.dataSource = nil;
|
||||
_stackTraceTableView.delegate = nil;
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
_stackTraceTableView.dataSource = nil;
|
||||
_stackTraceTableView.delegate = nil;
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
- (void)showErrorMessage:(NSString *)message withStack:(NSArray<RCTJSStackFrame *> *)stack isUpdate:(BOOL)isUpdate
|
||||
{
|
||||
// Show if this is a new message, or if we're updating the previous message
|
||||
if ((self.hidden && !isUpdate) || (!self.hidden && isUpdate && [_lastErrorMessage isEqualToString:message])) {
|
||||
_lastStackTrace = stack;
|
||||
// message is displayed using UILabel, which is unable to render text of
|
||||
// unlimited length, so we truncate it
|
||||
_lastErrorMessage = [message substringToIndex:MIN((NSUInteger)10000, message.length)];
|
||||
// Show if this is a new message, or if we're updating the previous message
|
||||
if ((self.hidden && !isUpdate) || (!self.hidden && isUpdate && [_lastErrorMessage isEqualToString:message])) {
|
||||
_lastStackTrace = stack;
|
||||
// message is displayed using UILabel, which is unable to render text of
|
||||
// unlimited length, so we truncate it
|
||||
_lastErrorMessage = [message substringToIndex:MIN((NSUInteger)10000, message.length)];
|
||||
|
||||
[_stackTraceTableView reloadData];
|
||||
[_stackTraceTableView reloadData];
|
||||
|
||||
if (self.hidden) {
|
||||
[_stackTraceTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]
|
||||
atScrollPosition:UITableViewScrollPositionTop
|
||||
animated:NO];
|
||||
}
|
||||
|
||||
[self makeKeyAndVisible];
|
||||
[self becomeFirstResponder];
|
||||
if (self.hidden) {
|
||||
[_stackTraceTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]
|
||||
atScrollPosition:UITableViewScrollPositionTop
|
||||
animated:NO];
|
||||
}
|
||||
|
||||
[self makeKeyAndVisible];
|
||||
[self becomeFirstResponder];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)dismiss
|
||||
{
|
||||
self.hidden = YES;
|
||||
[self resignFirstResponder];
|
||||
[RCTSharedApplication().delegate.window makeKeyWindow];
|
||||
self.hidden = YES;
|
||||
[self resignFirstResponder];
|
||||
[RCTSharedApplication().delegate.window makeKeyWindow];
|
||||
}
|
||||
|
||||
- (void)reload
|
||||
{
|
||||
[_actionDelegate reloadFromRedBoxWindow:self];
|
||||
}
|
||||
|
||||
- (void)showExtraDataViewController
|
||||
{
|
||||
[_actionDelegate loadExtraDataViewController];
|
||||
[_actionDelegate reloadFromRedBoxWindow:self];
|
||||
}
|
||||
|
||||
- (void)copyStack
|
||||
{
|
||||
NSMutableString *fullStackTrace;
|
||||
NSMutableString *fullStackTrace;
|
||||
|
||||
if (_lastErrorMessage != nil) {
|
||||
fullStackTrace = [_lastErrorMessage mutableCopy];
|
||||
[fullStackTrace appendString:@"\n\n"];
|
||||
}
|
||||
else {
|
||||
fullStackTrace = [NSMutableString string];
|
||||
}
|
||||
if (_lastErrorMessage != nil) {
|
||||
fullStackTrace = [_lastErrorMessage mutableCopy];
|
||||
[fullStackTrace appendString:@"\n\n"];
|
||||
}
|
||||
else {
|
||||
fullStackTrace = [NSMutableString string];
|
||||
}
|
||||
|
||||
for (RCTJSStackFrame *stackFrame in _lastStackTrace) {
|
||||
[fullStackTrace appendString:[NSString stringWithFormat:@"%@\n", stackFrame.methodName]];
|
||||
if (stackFrame.file) {
|
||||
[fullStackTrace appendFormat:@" %@\n", [self formatFrameSource:stackFrame]];
|
||||
}
|
||||
for (RCTJSStackFrame *stackFrame in _lastStackTrace) {
|
||||
[fullStackTrace appendString:[NSString stringWithFormat:@"%@\n", stackFrame.methodName]];
|
||||
if (stackFrame.file) {
|
||||
[fullStackTrace appendFormat:@" %@\n", [self formatFrameSource:stackFrame]];
|
||||
}
|
||||
}
|
||||
#if !TARGET_OS_TV
|
||||
UIPasteboard *pb = [UIPasteboard generalPasteboard];
|
||||
[pb setString:fullStackTrace];
|
||||
UIPasteboard *pb = [UIPasteboard generalPasteboard];
|
||||
[pb setString:fullStackTrace];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (NSString *)formatFrameSource:(RCTJSStackFrame *)stackFrame
|
||||
{
|
||||
NSString *fileName = RCTNilIfNull(stackFrame.file) ? [stackFrame.file lastPathComponent] : @"<unknown file>";
|
||||
NSString *lineInfo = [NSString stringWithFormat:@"%@:%lld",
|
||||
fileName,
|
||||
(long long)stackFrame.lineNumber];
|
||||
NSString *fileName = RCTNilIfNull(stackFrame.file) ? [stackFrame.file lastPathComponent] : @"<unknown file>";
|
||||
NSString *lineInfo = [NSString stringWithFormat:@"%@:%lld",
|
||||
fileName,
|
||||
(long long)stackFrame.lineNumber];
|
||||
|
||||
if (stackFrame.column != 0) {
|
||||
lineInfo = [lineInfo stringByAppendingFormat:@":%lld", (long long)stackFrame.column];
|
||||
}
|
||||
return lineInfo;
|
||||
if (stackFrame.column != 0) {
|
||||
lineInfo = [lineInfo stringByAppendingFormat:@":%lld", (long long)stackFrame.column];
|
||||
}
|
||||
return lineInfo;
|
||||
}
|
||||
|
||||
#pragma mark - TableView
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(__unused UITableView *)tableView
|
||||
{
|
||||
return 2;
|
||||
return 2;
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(__unused UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return section == 0 ? 1 : _lastStackTrace.count;
|
||||
return section == 0 ? 1 : _lastStackTrace.count;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
if (indexPath.section == 0) {
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"msg-cell"];
|
||||
return [self reuseCell:cell forErrorMessage:_lastErrorMessage];
|
||||
}
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
|
||||
NSUInteger index = indexPath.row;
|
||||
RCTJSStackFrame *stackFrame = _lastStackTrace[index];
|
||||
return [self reuseCell:cell forStackFrame:stackFrame];
|
||||
if (indexPath.section == 0) {
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"msg-cell"];
|
||||
return [self reuseCell:cell forErrorMessage:_lastErrorMessage];
|
||||
}
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
|
||||
NSUInteger index = indexPath.row;
|
||||
RCTJSStackFrame *stackFrame = _lastStackTrace[index];
|
||||
return [self reuseCell:cell forStackFrame:stackFrame];
|
||||
}
|
||||
|
||||
- (UITableViewCell *)reuseCell:(UITableViewCell *)cell forErrorMessage:(NSString *)message
|
||||
{
|
||||
if (!cell) {
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"msg-cell"];
|
||||
cell.textLabel.accessibilityIdentifier = @"redbox-error";
|
||||
cell.textLabel.textColor = [UIColor whiteColor];
|
||||
cell.textLabel.font = [UIFont boldSystemFontOfSize:16];
|
||||
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
cell.textLabel.numberOfLines = 0;
|
||||
cell.detailTextLabel.textColor = [UIColor whiteColor];
|
||||
cell.backgroundColor = [UIColor clearColor];
|
||||
cell.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
}
|
||||
if (!cell) {
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"msg-cell"];
|
||||
cell.textLabel.accessibilityIdentifier = @"redbox-error";
|
||||
cell.textLabel.textColor = [UIColor whiteColor];
|
||||
cell.textLabel.font = [UIFont boldSystemFontOfSize:16];
|
||||
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
cell.textLabel.numberOfLines = 0;
|
||||
cell.detailTextLabel.textColor = [UIColor whiteColor];
|
||||
cell.backgroundColor = [UIColor clearColor];
|
||||
cell.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
}
|
||||
|
||||
cell.textLabel.text = message;
|
||||
cell.textLabel.text = message;
|
||||
|
||||
return cell;
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)reuseCell:(UITableViewCell *)cell forStackFrame:(RCTJSStackFrame *)stackFrame
|
||||
{
|
||||
if (!cell) {
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"];
|
||||
cell.textLabel.textColor = [UIColor colorWithWhite:1 alpha:0.9];
|
||||
cell.textLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:14];
|
||||
cell.textLabel.lineBreakMode = NSLineBreakByCharWrapping;
|
||||
cell.textLabel.numberOfLines = 2;
|
||||
cell.detailTextLabel.textColor = [UIColor colorWithWhite:1 alpha:0.7];
|
||||
cell.detailTextLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:11];
|
||||
cell.detailTextLabel.lineBreakMode = NSLineBreakByTruncatingMiddle;
|
||||
cell.backgroundColor = [UIColor clearColor];
|
||||
cell.selectedBackgroundView = [UIView new];
|
||||
cell.selectedBackgroundView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.2];
|
||||
}
|
||||
if (!cell) {
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"];
|
||||
cell.textLabel.textColor = [UIColor colorWithWhite:1 alpha:0.9];
|
||||
cell.textLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:14];
|
||||
cell.textLabel.lineBreakMode = NSLineBreakByCharWrapping;
|
||||
cell.textLabel.numberOfLines = 2;
|
||||
cell.detailTextLabel.textColor = [UIColor colorWithWhite:1 alpha:0.7];
|
||||
cell.detailTextLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:11];
|
||||
cell.detailTextLabel.lineBreakMode = NSLineBreakByTruncatingMiddle;
|
||||
cell.backgroundColor = [UIColor clearColor];
|
||||
cell.selectedBackgroundView = [UIView new];
|
||||
cell.selectedBackgroundView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.2];
|
||||
}
|
||||
|
||||
cell.textLabel.text = stackFrame.methodName ?: @"(unnamed method)";
|
||||
if (stackFrame.file) {
|
||||
cell.detailTextLabel.text = [self formatFrameSource:stackFrame];
|
||||
} else {
|
||||
cell.detailTextLabel.text = @"";
|
||||
}
|
||||
return cell;
|
||||
cell.textLabel.text = stackFrame.methodName ?: @"(unnamed method)";
|
||||
if (stackFrame.file) {
|
||||
cell.detailTextLabel.text = [self formatFrameSource:stackFrame];
|
||||
} else {
|
||||
cell.detailTextLabel.text = @"";
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
if (indexPath.section == 0) {
|
||||
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
|
||||
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
if (indexPath.section == 0) {
|
||||
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
|
||||
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
|
||||
NSDictionary *attributes = @{NSFontAttributeName: [UIFont boldSystemFontOfSize:16],
|
||||
NSParagraphStyleAttributeName: paragraphStyle};
|
||||
CGRect boundingRect = [_lastErrorMessage boundingRectWithSize:CGSizeMake(tableView.frame.size.width - 30, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil];
|
||||
return ceil(boundingRect.size.height) + 40;
|
||||
} else {
|
||||
return 50;
|
||||
}
|
||||
NSDictionary *attributes = @{NSFontAttributeName: [UIFont boldSystemFontOfSize:16],
|
||||
NSParagraphStyleAttributeName: paragraphStyle};
|
||||
CGRect boundingRect = [_lastErrorMessage boundingRectWithSize:CGSizeMake(tableView.frame.size.width - 30, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil];
|
||||
return ceil(boundingRect.size.height) + 40;
|
||||
} else {
|
||||
return 50;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
if (indexPath.section == 1) {
|
||||
NSUInteger row = indexPath.row;
|
||||
RCTJSStackFrame *stackFrame = _lastStackTrace[row];
|
||||
[_actionDelegate redBoxWindow:self openStackFrameInEditor:stackFrame];
|
||||
}
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
if (indexPath.section == 1) {
|
||||
NSUInteger row = indexPath.row;
|
||||
RCTJSStackFrame *stackFrame = _lastStackTrace[row];
|
||||
[_actionDelegate redBoxWindow:self openStackFrameInEditor:stackFrame];
|
||||
}
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
}
|
||||
|
||||
#pragma mark - Key commands
|
||||
|
||||
- (NSArray<UIKeyCommand *> *)keyCommands
|
||||
{
|
||||
// NOTE: We could use RCTKeyCommands for this, but since
|
||||
// we control this window, we can use the standard, non-hacky
|
||||
// mechanism instead
|
||||
// NOTE: We could use RCTKeyCommands for this, but since
|
||||
// we control this window, we can use the standard, non-hacky
|
||||
// mechanism instead
|
||||
|
||||
return @[
|
||||
// Dismiss red box
|
||||
[UIKeyCommand keyCommandWithInput:UIKeyInputEscape
|
||||
modifierFlags:0
|
||||
action:@selector(dismiss)],
|
||||
return @[
|
||||
// Dismiss red box
|
||||
[UIKeyCommand keyCommandWithInput:UIKeyInputEscape
|
||||
modifierFlags:0
|
||||
action:@selector(dismiss)],
|
||||
|
||||
// Reload
|
||||
[UIKeyCommand keyCommandWithInput:@"r"
|
||||
modifierFlags:UIKeyModifierCommand
|
||||
action:@selector(reload)],
|
||||
// Reload
|
||||
[UIKeyCommand keyCommandWithInput:@"r"
|
||||
modifierFlags:UIKeyModifierCommand
|
||||
action:@selector(reload)],
|
||||
|
||||
// Copy = Cmd-Option C since Cmd-C in the simulator copies the pasteboard from
|
||||
// the simulator to the desktop pasteboard.
|
||||
[UIKeyCommand keyCommandWithInput:@"c"
|
||||
modifierFlags:UIKeyModifierCommand | UIKeyModifierAlternate
|
||||
action:@selector(copyStack)],
|
||||
// Copy = Cmd-Option C since Cmd-C in the simulator copies the pasteboard from
|
||||
// the simulator to the desktop pasteboard.
|
||||
[UIKeyCommand keyCommandWithInput:@"c"
|
||||
modifierFlags:UIKeyModifierCommand | UIKeyModifierAlternate
|
||||
action:@selector(copyStack)]
|
||||
|
||||
// Extra data
|
||||
[UIKeyCommand keyCommandWithInput:@"e"
|
||||
modifierFlags:UIKeyModifierCommand
|
||||
action:@selector(showExtraDataViewController)]
|
||||
];
|
||||
];
|
||||
}
|
||||
|
||||
- (BOOL)canBecomeFirstResponder
|
||||
{
|
||||
return YES;
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTRedBox () <RCTInvalidating, RCTRedBoxWindowActionDelegate, RCTRedBoxExtraDataActionDelegate>
|
||||
@interface RCTRedBox () <RCTInvalidating, RCTRedBoxWindowActionDelegate>
|
||||
@end
|
||||
|
||||
@implementation RCTRedBox
|
||||
{
|
||||
RCTRedBoxWindow *_window;
|
||||
NSMutableArray<id<RCTErrorCustomizer>> *_errorCustomizers;
|
||||
RCTRedBoxExtraDataViewController *_extraDataViewController;
|
||||
RCTRedBoxWindow *_window;
|
||||
NSMutableArray<id<RCTErrorCustomizer>> *_errorCustomizers;
|
||||
}
|
||||
|
||||
@synthesize bridge = _bridge;
|
||||
@@ -370,165 +343,140 @@ RCT_EXPORT_MODULE()
|
||||
|
||||
- (void)registerErrorCustomizer:(id<RCTErrorCustomizer>)errorCustomizer
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (!self->_errorCustomizers) {
|
||||
self->_errorCustomizers = [NSMutableArray array];
|
||||
}
|
||||
if (![self->_errorCustomizers containsObject:errorCustomizer]) {
|
||||
[self->_errorCustomizers addObject:errorCustomizer];
|
||||
}
|
||||
});
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (!self->_errorCustomizers) {
|
||||
self->_errorCustomizers = [NSMutableArray array];
|
||||
}
|
||||
if (![self->_errorCustomizers containsObject:errorCustomizer]) {
|
||||
[self->_errorCustomizers addObject:errorCustomizer];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// WARNING: Should only be called from the main thread/dispatch queue.
|
||||
- (RCTErrorInfo *)_customizeError:(RCTErrorInfo *)error
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
if (!self->_errorCustomizers) {
|
||||
return error;
|
||||
}
|
||||
for (id<RCTErrorCustomizer> customizer in self->_errorCustomizers) {
|
||||
RCTErrorInfo *newInfo = [customizer customizeErrorInfo:error];
|
||||
if (newInfo) {
|
||||
error = newInfo;
|
||||
}
|
||||
}
|
||||
RCTAssertMainQueue();
|
||||
|
||||
if (!self->_errorCustomizers) {
|
||||
return error;
|
||||
}
|
||||
for (id<RCTErrorCustomizer> customizer in self->_errorCustomizers) {
|
||||
RCTErrorInfo *newInfo = [customizer customizeErrorInfo:error];
|
||||
if (newInfo) {
|
||||
error = newInfo;
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
- (void)showError:(NSError *)error
|
||||
{
|
||||
[self showErrorMessage:error.localizedDescription
|
||||
withDetails:error.localizedFailureReason
|
||||
stack:error.userInfo[RCTJSStackTraceKey]];
|
||||
[self showErrorMessage:error.localizedDescription
|
||||
withDetails:error.localizedFailureReason
|
||||
stack:error.userInfo[RCTJSStackTraceKey]];
|
||||
}
|
||||
|
||||
- (void)showErrorMessage:(NSString *)message
|
||||
{
|
||||
[self showErrorMessage:message withParsedStack:nil isUpdate:NO];
|
||||
[self showErrorMessage:message withParsedStack:nil isUpdate:NO];
|
||||
}
|
||||
|
||||
- (void)showErrorMessage:(NSString *)message withDetails:(NSString *)details
|
||||
{
|
||||
[self showErrorMessage:message withDetails:details stack:nil];
|
||||
[self showErrorMessage:message withDetails:details stack:nil];
|
||||
}
|
||||
|
||||
- (void)showErrorMessage:(NSString *)message withDetails:(NSString *)details stack:(NSArray<RCTJSStackFrame *> *)stack {
|
||||
NSString *combinedMessage = message;
|
||||
if (details) {
|
||||
combinedMessage = [NSString stringWithFormat:@"%@\n\n%@", message, details];
|
||||
}
|
||||
[self showErrorMessage:combinedMessage withParsedStack:stack isUpdate:NO];
|
||||
NSString *combinedMessage = message;
|
||||
if (details) {
|
||||
combinedMessage = [NSString stringWithFormat:@"%@\n\n%@", message, details];
|
||||
}
|
||||
[self showErrorMessage:combinedMessage withParsedStack:stack isUpdate:NO];
|
||||
}
|
||||
|
||||
- (void)showErrorMessage:(NSString *)message withRawStack:(NSString *)rawStack
|
||||
{
|
||||
NSArray<RCTJSStackFrame *> *stack = [RCTJSStackFrame stackFramesWithLines:rawStack];
|
||||
[self showErrorMessage:message withParsedStack:stack isUpdate:NO];
|
||||
NSArray<RCTJSStackFrame *> *stack = [RCTJSStackFrame stackFramesWithLines:rawStack];
|
||||
[self showErrorMessage:message withParsedStack:stack isUpdate:NO];
|
||||
}
|
||||
|
||||
- (void)showErrorMessage:(NSString *)message withStack:(NSArray<NSDictionary *> *)stack
|
||||
{
|
||||
[self showErrorMessage:message withParsedStack:[RCTJSStackFrame stackFramesWithDictionaries:stack] isUpdate:NO];
|
||||
[self showErrorMessage:message withParsedStack:[RCTJSStackFrame stackFramesWithDictionaries:stack] isUpdate:NO];
|
||||
}
|
||||
|
||||
- (void)updateErrorMessage:(NSString *)message withStack:(NSArray<NSDictionary *> *)stack
|
||||
{
|
||||
[self showErrorMessage:message withParsedStack:[RCTJSStackFrame stackFramesWithDictionaries:stack] isUpdate:YES];
|
||||
[self showErrorMessage:message withParsedStack:[RCTJSStackFrame stackFramesWithDictionaries:stack] isUpdate:YES];
|
||||
}
|
||||
|
||||
- (void)showErrorMessage:(NSString *)message withParsedStack:(NSArray<RCTJSStackFrame *> *)stack
|
||||
{
|
||||
[self showErrorMessage:message withParsedStack:stack isUpdate:NO];
|
||||
[self showErrorMessage:message withParsedStack:stack isUpdate:NO];
|
||||
}
|
||||
|
||||
- (void)updateErrorMessage:(NSString *)message withParsedStack:(NSArray<RCTJSStackFrame *> *)stack
|
||||
{
|
||||
[self showErrorMessage:message withParsedStack:stack isUpdate:YES];
|
||||
[self showErrorMessage:message withParsedStack:stack isUpdate:YES];
|
||||
}
|
||||
|
||||
- (void)showErrorMessage:(NSString *)message withParsedStack:(NSArray<RCTJSStackFrame *> *)stack isUpdate:(BOOL)isUpdate
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (self->_extraDataViewController == nil) {
|
||||
self->_extraDataViewController = [RCTRedBoxExtraDataViewController new];
|
||||
self->_extraDataViewController.actionDelegate = self;
|
||||
}
|
||||
[self->_bridge.eventDispatcher sendDeviceEventWithName:@"collectRedBoxExtraData" body:nil];
|
||||
|
||||
if (!self->_window) {
|
||||
self->_window = [[RCTRedBoxWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
self->_window.actionDelegate = self;
|
||||
}
|
||||
|
||||
RCTErrorInfo *errorInfo = [[RCTErrorInfo alloc] initWithErrorMessage:message
|
||||
stack:stack];
|
||||
errorInfo = [self _customizeError:errorInfo];
|
||||
[self->_window showErrorMessage:errorInfo.errorMessage
|
||||
withStack:errorInfo.stack
|
||||
isUpdate:isUpdate];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)loadExtraDataViewController {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
// Make sure the CMD+E shortcut doesn't call this twice
|
||||
if (self->_extraDataViewController != nil && ![self->_window.rootViewController presentedViewController]) {
|
||||
[self->_window.rootViewController presentViewController:self->_extraDataViewController animated:YES completion:nil];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setExtraData:(NSDictionary *)extraData forIdentifier:(NSString *)identifier) {
|
||||
[_extraDataViewController addExtraData:extraData forIdentifier:identifier];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (!self->_window) {
|
||||
self->_window = [[RCTRedBoxWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
self->_window.actionDelegate = self;
|
||||
}
|
||||
RCTErrorInfo *errorInfo = [[RCTErrorInfo alloc] initWithErrorMessage:message
|
||||
stack:stack];
|
||||
errorInfo = [self _customizeError:errorInfo];
|
||||
[self->_window showErrorMessage:errorInfo.errorMessage
|
||||
withStack:errorInfo.stack
|
||||
isUpdate:isUpdate];
|
||||
});
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(dismiss)
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self->_window dismiss];
|
||||
});
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self->_window dismiss];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)invalidate
|
||||
{
|
||||
[self dismiss];
|
||||
[self dismiss];
|
||||
}
|
||||
|
||||
- (void)redBoxWindow:(__unused RCTRedBoxWindow *)redBoxWindow openStackFrameInEditor:(RCTJSStackFrame *)stackFrame
|
||||
{
|
||||
NSURL *const bundleURL = _overrideBundleURL ?: _bridge.bundleURL;
|
||||
if (![bundleURL.scheme hasPrefix:@"http"]) {
|
||||
RCTLogWarn(@"Cannot open stack frame in editor because you're not connected to the packager.");
|
||||
return;
|
||||
}
|
||||
NSURL *const bundleURL = _overrideBundleURL ?: _bridge.bundleURL;
|
||||
if (![bundleURL.scheme hasPrefix:@"http"]) {
|
||||
RCTLogWarn(@"Cannot open stack frame in editor because you're not connected to the packager.");
|
||||
return;
|
||||
}
|
||||
|
||||
NSData *stackFrameJSON = [RCTJSONStringify([stackFrame toDictionary], NULL) dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSString *postLength = [NSString stringWithFormat:@"%tu", stackFrameJSON.length];
|
||||
NSMutableURLRequest *request = [NSMutableURLRequest new];
|
||||
request.URL = [NSURL URLWithString:@"/open-stack-frame" relativeToURL:bundleURL];
|
||||
request.HTTPMethod = @"POST";
|
||||
request.HTTPBody = stackFrameJSON;
|
||||
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
|
||||
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
|
||||
NSData *stackFrameJSON = [RCTJSONStringify([stackFrame toDictionary], NULL) dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSString *postLength = [NSString stringWithFormat:@"%tu", stackFrameJSON.length];
|
||||
NSMutableURLRequest *request = [NSMutableURLRequest new];
|
||||
request.URL = [NSURL URLWithString:@"/open-stack-frame" relativeToURL:bundleURL];
|
||||
request.HTTPMethod = @"POST";
|
||||
request.HTTPBody = stackFrameJSON;
|
||||
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
|
||||
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
|
||||
|
||||
[[[NSURLSession sharedSession] dataTaskWithRequest:request] resume];
|
||||
}
|
||||
|
||||
- (void)reload
|
||||
{
|
||||
// Window is not used and can be nil
|
||||
[self reloadFromRedBoxWindow:nil];
|
||||
[[[NSURLSession sharedSession] dataTaskWithRequest:request] resume];
|
||||
}
|
||||
|
||||
- (void)reloadFromRedBoxWindow:(__unused RCTRedBoxWindow *)redBoxWindow
|
||||
{
|
||||
if (_overrideReloadAction) {
|
||||
_overrideReloadAction();
|
||||
} else {
|
||||
[_bridge reload];
|
||||
}
|
||||
[self dismiss];
|
||||
if (_overrideReloadAction) {
|
||||
_overrideReloadAction();
|
||||
} else {
|
||||
[_bridge reload];
|
||||
}
|
||||
[self dismiss];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -537,7 +485,7 @@ RCT_EXPORT_METHOD(dismiss)
|
||||
|
||||
- (RCTRedBox *)redBox
|
||||
{
|
||||
return [self moduleForClass:[RCTRedBox class]];
|
||||
return [self moduleForClass:[RCTRedBox class]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@protocol RCTRedBoxExtraDataActionDelegate <NSObject>
|
||||
- (void)reload;
|
||||
@end
|
||||
|
||||
@interface RCTRedBoxExtraDataViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
|
||||
|
||||
@property (nonatomic, weak) id<RCTRedBoxExtraDataActionDelegate> actionDelegate;
|
||||
|
||||
- (void)addExtraData:(NSDictionary *)data forIdentifier:(NSString *)identifier;
|
||||
|
||||
@end
|
||||
@@ -1,288 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import "RCTRedBoxExtraDataViewController.h"
|
||||
|
||||
@interface RCTRedBoxExtraDataCell : UITableViewCell
|
||||
|
||||
@property (nonatomic, strong) UILabel *keyLabel;
|
||||
@property (nonatomic, strong) UILabel *valueLabel;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTRedBoxExtraDataCell
|
||||
|
||||
- (instancetype)initWithStyle:(UITableViewCellStyle)style
|
||||
reuseIdentifier:(NSString *)reuseIdentifier
|
||||
{
|
||||
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
|
||||
self.backgroundColor = [UIColor colorWithRed:0.8
|
||||
green:0 blue:0
|
||||
alpha:1];
|
||||
UILayoutGuide *contentLayout = self.contentView.layoutMarginsGuide;
|
||||
|
||||
self.keyLabel = [UILabel new];
|
||||
[self.contentView addSubview:self.keyLabel];
|
||||
|
||||
self.keyLabel.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
[self.keyLabel.leadingAnchor
|
||||
constraintEqualToAnchor:contentLayout.leadingAnchor].active = YES;
|
||||
[self.keyLabel.topAnchor
|
||||
constraintEqualToAnchor:contentLayout.topAnchor].active = YES;
|
||||
[self.keyLabel.bottomAnchor
|
||||
constraintEqualToAnchor:contentLayout.bottomAnchor].active = YES;
|
||||
[self.keyLabel.widthAnchor
|
||||
constraintEqualToAnchor:contentLayout.widthAnchor
|
||||
multiplier:0.3].active = YES;
|
||||
|
||||
self.keyLabel.textColor = [UIColor whiteColor];
|
||||
self.keyLabel.numberOfLines = 0;
|
||||
self.keyLabel.lineBreakMode = UILineBreakModeWordWrap;
|
||||
self.keyLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:12.0f];
|
||||
|
||||
self.valueLabel = [UILabel new];
|
||||
[self.contentView addSubview:self.valueLabel];
|
||||
|
||||
self.valueLabel.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
[self.valueLabel.leadingAnchor
|
||||
constraintEqualToAnchor:self.keyLabel.trailingAnchor
|
||||
constant:10.f].active = YES;
|
||||
[self.valueLabel.trailingAnchor
|
||||
constraintEqualToAnchor:contentLayout.trailingAnchor].active = YES;
|
||||
[self.valueLabel.topAnchor
|
||||
constraintEqualToAnchor:contentLayout.topAnchor].active = YES;
|
||||
[self.valueLabel.bottomAnchor
|
||||
constraintEqualToAnchor:contentLayout.bottomAnchor].active = YES;
|
||||
|
||||
self.valueLabel.textColor = [UIColor whiteColor];
|
||||
self.valueLabel.numberOfLines = 0;
|
||||
self.valueLabel.lineBreakMode = UILineBreakModeWordWrap;
|
||||
self.valueLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:12.0f];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTRedBoxExtraDataViewController ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTRedBoxExtraDataViewController
|
||||
{
|
||||
UITableView *_tableView;
|
||||
NSMutableArray *_extraDataTitle;
|
||||
NSMutableArray *_extraData;
|
||||
}
|
||||
|
||||
@synthesize actionDelegate = _actionDelegate;
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_extraData = [NSMutableArray new];
|
||||
_extraDataTitle = [NSMutableArray new];
|
||||
self.view.backgroundColor = [UIColor colorWithRed:0.8
|
||||
green:0
|
||||
blue:0
|
||||
alpha:1];
|
||||
|
||||
_tableView = [UITableView new];
|
||||
_tableView.delegate = self;
|
||||
_tableView.dataSource = self;
|
||||
_tableView.backgroundColor = [UIColor clearColor];
|
||||
_tableView.estimatedRowHeight = 200;
|
||||
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
|
||||
_tableView.rowHeight = UITableViewAutomaticDimension;
|
||||
_tableView.allowsSelection = NO;
|
||||
|
||||
#if TARGET_OS_SIMULATOR
|
||||
NSString *reloadText = @"Reload JS (\u2318R)";
|
||||
NSString *dismissText = @"Dismiss (ESC)";
|
||||
#else
|
||||
NSString *reloadText = @"Reload JS";
|
||||
NSString *dismissText = @"Dismiss";
|
||||
#endif
|
||||
|
||||
UIButton *dismissButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
dismissButton.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
dismissButton.accessibilityIdentifier = @"redbox-extra-data-dismiss";
|
||||
dismissButton.titleLabel.font = [UIFont systemFontOfSize:13];
|
||||
[dismissButton setTitle:dismissText forState:UIControlStateNormal];
|
||||
[dismissButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5]
|
||||
forState:UIControlStateNormal];
|
||||
[dismissButton setTitleColor:[UIColor whiteColor]
|
||||
forState:UIControlStateHighlighted];
|
||||
[dismissButton addTarget:self
|
||||
action:@selector(dismiss)
|
||||
forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
UIButton *reloadButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
reloadButton.accessibilityIdentifier = @"redbox-reload";
|
||||
reloadButton.titleLabel.font = [UIFont systemFontOfSize:13];
|
||||
[reloadButton setTitle:reloadText forState:UIControlStateNormal];
|
||||
[reloadButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5]
|
||||
forState:UIControlStateNormal];
|
||||
[reloadButton setTitleColor:[UIColor whiteColor]
|
||||
forState:UIControlStateHighlighted];
|
||||
[reloadButton addTarget:self
|
||||
action:@selector(reload)
|
||||
forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
UIStackView *buttonStackView = [UIStackView new];
|
||||
buttonStackView.axis = UILayoutConstraintAxisHorizontal;
|
||||
buttonStackView.distribution = UIStackViewDistributionEqualSpacing;
|
||||
buttonStackView.alignment = UIStackViewAlignmentFill;
|
||||
buttonStackView.spacing = 20;
|
||||
|
||||
[buttonStackView addArrangedSubview:dismissButton];
|
||||
[buttonStackView addArrangedSubview:reloadButton];
|
||||
buttonStackView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
|
||||
UIStackView *mainStackView = [UIStackView new];
|
||||
mainStackView.axis = UILayoutConstraintAxisVertical;
|
||||
mainStackView.backgroundColor = [UIColor colorWithRed:0.8
|
||||
green:0 blue:0
|
||||
alpha:1];
|
||||
[mainStackView addArrangedSubview:_tableView];
|
||||
[mainStackView addArrangedSubview:buttonStackView];
|
||||
mainStackView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
|
||||
[self.view addSubview:mainStackView];
|
||||
|
||||
CGFloat tableHeight = self.view.bounds.size.height - 60.f;
|
||||
[_tableView.heightAnchor constraintEqualToConstant:tableHeight].active = YES;
|
||||
[_tableView.widthAnchor constraintEqualToAnchor:self.view.widthAnchor].active = YES;
|
||||
|
||||
CGFloat buttonWidth = self.view.bounds.size.width / 4;
|
||||
[dismissButton.heightAnchor constraintEqualToConstant:60].active = YES;
|
||||
[dismissButton.widthAnchor
|
||||
constraintEqualToConstant:buttonWidth].active = YES;
|
||||
[reloadButton.heightAnchor constraintEqualToConstant:60].active = YES;
|
||||
[reloadButton.widthAnchor
|
||||
constraintEqualToConstant:buttonWidth].active = YES;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated
|
||||
{
|
||||
[super viewDidAppear:animated];
|
||||
[_tableView reloadData];
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return [[_extraData objectAtIndex:section] count];
|
||||
}
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
|
||||
{
|
||||
return 40;
|
||||
}
|
||||
|
||||
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
|
||||
{
|
||||
UIView *view = [UIView new];
|
||||
view.backgroundColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:1];
|
||||
|
||||
UILabel *header = [UILabel new];
|
||||
[view addSubview:header];
|
||||
|
||||
header.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
[header.leadingAnchor
|
||||
constraintEqualToAnchor:view.leadingAnchor constant:5].active = YES;
|
||||
[header.trailingAnchor
|
||||
constraintEqualToAnchor:view.trailingAnchor].active = YES;
|
||||
[header.topAnchor
|
||||
constraintEqualToAnchor:view.topAnchor].active = YES;
|
||||
[header.bottomAnchor
|
||||
constraintEqualToAnchor:view.bottomAnchor].active = YES;
|
||||
|
||||
header.textColor = [UIColor whiteColor];
|
||||
header.font = [UIFont fontWithName:@"Menlo-Bold" size:14.0f];
|
||||
header.text = [_extraDataTitle[section] uppercaseString];
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
static NSString *reuseIdentifier = @"RedBoxExtraData";
|
||||
|
||||
RCTRedBoxExtraDataCell *cell =
|
||||
(RCTRedBoxExtraDataCell *)[tableView
|
||||
dequeueReusableCellWithIdentifier:reuseIdentifier];
|
||||
|
||||
if (cell == nil) {
|
||||
cell = [[RCTRedBoxExtraDataCell alloc]
|
||||
initWithStyle:UITableViewCellStyleDefault
|
||||
reuseIdentifier:reuseIdentifier];
|
||||
}
|
||||
|
||||
NSArray *dataKVPair = _extraData[indexPath.section][indexPath.row];
|
||||
cell.keyLabel.text = dataKVPair[0];
|
||||
cell.valueLabel.text = dataKVPair[1];
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
|
||||
{
|
||||
return _extraDataTitle.count;
|
||||
}
|
||||
|
||||
- (void)addExtraData:(NSDictionary *)data forIdentifier:(NSString *)identifier
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSMutableArray *newData = [NSMutableArray new];
|
||||
for (id key in data) {
|
||||
[newData addObject:@[[NSString stringWithFormat:@"%@", key],
|
||||
[NSString stringWithFormat:@"%@", [data objectForKey:key]]]];
|
||||
}
|
||||
|
||||
NSInteger idx = [self->_extraDataTitle indexOfObject:identifier];
|
||||
if (idx == NSNotFound) {
|
||||
[self->_extraDataTitle addObject:identifier];
|
||||
[self->_extraData addObject:newData];
|
||||
} else {
|
||||
[self->_extraData replaceObjectAtIndex:idx withObject:newData];
|
||||
}
|
||||
|
||||
[self->_tableView reloadData];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)dismiss
|
||||
{
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void)reload
|
||||
{
|
||||
[_actionDelegate reload];
|
||||
}
|
||||
|
||||
#pragma mark - Key commands
|
||||
|
||||
- (NSArray<UIKeyCommand *> *)keyCommands
|
||||
{
|
||||
return @[
|
||||
// Dismiss
|
||||
[UIKeyCommand keyCommandWithInput:UIKeyInputEscape
|
||||
modifierFlags:0
|
||||
action:@selector(dismiss)],
|
||||
// Reload
|
||||
[UIKeyCommand keyCommandWithInput:@"r"
|
||||
modifierFlags:UIKeyModifierCommand
|
||||
action:@selector(reload)]
|
||||
];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1192,8 +1192,6 @@
|
||||
EBF21BFE1FC499840052F4D5 /* InspectorInterfaces.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = EBF21BBA1FC498270052F4D5 /* InspectorInterfaces.h */; };
|
||||
EBF21BFF1FC4998E0052F4D5 /* InspectorInterfaces.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EBF21BBB1FC498270052F4D5 /* InspectorInterfaces.cpp */; };
|
||||
EBF21C001FC499A80052F4D5 /* InspectorInterfaces.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EBF21BBB1FC498270052F4D5 /* InspectorInterfaces.cpp */; };
|
||||
FEFAAC9E1FDB89B50057BBE0 /* RCTRedBoxExtraDataViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FEFAAC9C1FDB89B40057BBE0 /* RCTRedBoxExtraDataViewController.m */; };
|
||||
FEFAAC9F1FDB89B50057BBE0 /* RCTRedBoxExtraDataViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = FEFAAC9D1FDB89B40057BBE0 /* RCTRedBoxExtraDataViewController.h */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -2270,8 +2268,6 @@
|
||||
EBF21BBB1FC498270052F4D5 /* InspectorInterfaces.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorInterfaces.cpp; sourceTree = "<group>"; };
|
||||
EBF21BDC1FC498900052F4D5 /* libjsinspector.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjsinspector.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
EBF21BFA1FC4989A0052F4D5 /* libjsinspector-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libjsinspector-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
FEFAAC9C1FDB89B40057BBE0 /* RCTRedBoxExtraDataViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRedBoxExtraDataViewController.m; sourceTree = "<group>"; };
|
||||
FEFAAC9D1FDB89B40057BBE0 /* RCTRedBoxExtraDataViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRedBoxExtraDataViewController.h; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -2480,8 +2476,6 @@
|
||||
5960C1B41F0804A00066FD5B /* RCTLayoutAnimationGroup.m */,
|
||||
13F17A831B8493E5007D4C75 /* RCTRedBox.h */,
|
||||
13F17A841B8493E5007D4C75 /* RCTRedBox.m */,
|
||||
FEFAAC9D1FDB89B40057BBE0 /* RCTRedBoxExtraDataViewController.h */,
|
||||
FEFAAC9C1FDB89B40057BBE0 /* RCTRedBoxExtraDataViewController.m */,
|
||||
000E6CE91AB0E97F000CDF4D /* RCTSourceCode.h */,
|
||||
000E6CEA1AB0E980000CDF4D /* RCTSourceCode.m */,
|
||||
13723B4E1A82FD3C00F88898 /* RCTStatusBarManager.h */,
|
||||
@@ -3470,7 +3464,6 @@
|
||||
3D80DA591DF820620028D040 /* RCTTiming.h in Headers */,
|
||||
3D80DA5A1DF820620028D040 /* RCTUIManager.h in Headers */,
|
||||
3D80DA5B1DF820620028D040 /* RCTFPSGraph.h in Headers */,
|
||||
FEFAAC9F1FDB89B50057BBE0 /* RCTRedBoxExtraDataViewController.h in Headers */,
|
||||
3D80DA5D1DF820620028D040 /* RCTMacros.h in Headers */,
|
||||
3D80DA5E1DF820620028D040 /* RCTProfile.h in Headers */,
|
||||
3D80DA5F1DF820620028D040 /* RCTActivityIndicatorView.h in Headers */,
|
||||
@@ -4417,7 +4410,6 @@
|
||||
1372B70A1AB030C200659ED6 /* RCTAppState.m in Sources */,
|
||||
59A7B9FE1E577DBF0068EDBF /* RCTRootContentView.m in Sources */,
|
||||
13E067591A70F44B002CDEE1 /* UIView+React.m in Sources */,
|
||||
FEFAAC9E1FDB89B50057BBE0 /* RCTRedBoxExtraDataViewController.m in Sources */,
|
||||
14F484561AABFCE100FDF6B9 /* RCTSliderManager.m in Sources */,
|
||||
CF2731C11E7B8DE40044CA4F /* RCTDeviceInfo.m in Sources */,
|
||||
3D7AA9C41E548CD5001955CF /* NSDataBigString.mm in Sources */,
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
#import "RCTUIManager.h"
|
||||
#import "RCTUtils.h"
|
||||
#import "UIView+React.h"
|
||||
#if TARGET_OS_TV
|
||||
#import "RCTTVRemoteHandler.h"
|
||||
#endif
|
||||
|
||||
@implementation RCTModalHostView
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
VERSION_NAME=1000.0.0-master
|
||||
VERSION_NAME=0.52.1
|
||||
GROUP=com.facebook.react
|
||||
|
||||
POM_NAME=ReactNative
|
||||
|
||||
@@ -12,7 +12,6 @@ android_library(
|
||||
provided_deps = [
|
||||
react_native_dep("third-party/android/support/v4:lib-support-v4"),
|
||||
],
|
||||
required_for_source_only_abi = True,
|
||||
visibility = [
|
||||
"PUBLIC",
|
||||
],
|
||||
|
||||
@@ -16,7 +16,6 @@ android_library(
|
||||
provided_deps = [
|
||||
react_native_dep("third-party/android/support/v4:lib-support-v4"),
|
||||
],
|
||||
required_for_source_only_abi = True,
|
||||
visibility = [
|
||||
"PUBLIC",
|
||||
],
|
||||
|
||||
+11
-7
@@ -9,14 +9,17 @@
|
||||
|
||||
package com.facebook.react.devsupport;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import com.facebook.infer.annotation.Assertions;
|
||||
import com.facebook.react.bridge.JavaJSExecutor;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import com.facebook.infer.annotation.Assertions;
|
||||
import com.facebook.react.bridge.JavaJSExecutor;
|
||||
|
||||
/**
|
||||
* Executes JS remotely via the react nodejs server as a proxy to a browser on the host machine.
|
||||
@@ -157,7 +160,8 @@ public class WebsocketJavaScriptExecutor implements JavaJSExecutor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadApplicationScript(String sourceURL) throws JavaJSExecutor.ProxyExecutorException {
|
||||
public void loadApplicationScript(String sourceURL)
|
||||
throws ProxyExecutorException {
|
||||
JSExecutorCallbackFuture callback = new JSExecutorCallbackFuture();
|
||||
Assertions.assertNotNull(mWebSocketClient).loadApplicationScript(
|
||||
sourceURL,
|
||||
@@ -172,7 +176,7 @@ public class WebsocketJavaScriptExecutor implements JavaJSExecutor {
|
||||
|
||||
@Override
|
||||
public @Nullable String executeJSCall(String methodName, String jsonArgsArray)
|
||||
throws JavaJSExecutor.ProxyExecutorException {
|
||||
throws ProxyExecutorException {
|
||||
JSExecutorCallbackFuture callback = new JSExecutorCallbackFuture();
|
||||
Assertions.assertNotNull(mWebSocketClient).executeJSCall(
|
||||
methodName,
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
package com.facebook.react.flat;
|
||||
|
||||
import com.facebook.react.uimanager.UIViewOperationQueue;
|
||||
import android.util.SparseIntArray;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -35,7 +34,7 @@ import javax.annotation.Nullable;
|
||||
private final FlatNativeViewHierarchyManager mNativeViewHierarchyManager;
|
||||
private final ProcessLayoutRequests mProcessLayoutRequests = new ProcessLayoutRequests();
|
||||
|
||||
private final class ProcessLayoutRequests implements UIViewOperationQueue.UIOperation {
|
||||
private final class ProcessLayoutRequests implements UIOperation {
|
||||
@Override
|
||||
public void execute() {
|
||||
FlatViewGroup.processLayoutRequests();
|
||||
@@ -45,7 +44,7 @@ import javax.annotation.Nullable;
|
||||
/**
|
||||
* UIOperation that updates DrawCommands for a View defined by reactTag.
|
||||
*/
|
||||
private final class UpdateMountState implements UIViewOperationQueue.UIOperation {
|
||||
private final class UpdateMountState implements UIOperation {
|
||||
|
||||
private final int mReactTag;
|
||||
private final @Nullable DrawCommand[] mDrawCommands;
|
||||
@@ -76,7 +75,7 @@ import javax.annotation.Nullable;
|
||||
/**
|
||||
* UIOperation that updates DrawCommands for a View defined by reactTag.
|
||||
*/
|
||||
private final class UpdateClippingMountState implements UIViewOperationQueue.UIOperation {
|
||||
private final class UpdateClippingMountState implements UIOperation {
|
||||
|
||||
private final int mReactTag;
|
||||
private final @Nullable DrawCommand[] mDrawCommands;
|
||||
@@ -128,7 +127,7 @@ import javax.annotation.Nullable;
|
||||
}
|
||||
}
|
||||
|
||||
private final class UpdateViewGroup implements UIViewOperationQueue.UIOperation {
|
||||
private final class UpdateViewGroup implements UIOperation {
|
||||
|
||||
private final int mReactTag;
|
||||
private final int[] mViewsToAdd;
|
||||
@@ -149,7 +148,7 @@ import javax.annotation.Nullable;
|
||||
/**
|
||||
* UIOperation that updates View bounds for a View defined by reactTag.
|
||||
*/
|
||||
public final class UpdateViewBounds implements UIViewOperationQueue.UIOperation {
|
||||
public final class UpdateViewBounds implements UIOperation {
|
||||
|
||||
private final int mReactTag;
|
||||
private final int mLeft;
|
||||
@@ -171,7 +170,7 @@ import javax.annotation.Nullable;
|
||||
}
|
||||
}
|
||||
|
||||
private final class SetPadding implements UIViewOperationQueue.UIOperation {
|
||||
private final class SetPadding implements UIOperation {
|
||||
|
||||
private final int mReactTag;
|
||||
private final int mPaddingLeft;
|
||||
@@ -203,7 +202,7 @@ import javax.annotation.Nullable;
|
||||
}
|
||||
}
|
||||
|
||||
private final class DropViews implements UIViewOperationQueue.UIOperation {
|
||||
private final class DropViews implements UIOperation {
|
||||
|
||||
private final SparseIntArray mViewsToDrop;
|
||||
|
||||
@@ -221,7 +220,7 @@ import javax.annotation.Nullable;
|
||||
}
|
||||
}
|
||||
|
||||
private final class MeasureVirtualView implements UIViewOperationQueue.UIOperation {
|
||||
private final class MeasureVirtualView implements UIOperation {
|
||||
|
||||
private final int mReactTag;
|
||||
private final float mScaledX;
|
||||
@@ -285,7 +284,7 @@ import javax.annotation.Nullable;
|
||||
}
|
||||
}
|
||||
|
||||
public final class DetachAllChildrenFromViews implements UIViewOperationQueue.UIOperation {
|
||||
public final class DetachAllChildrenFromViews implements UIOperation {
|
||||
private @Nullable int[] mViewsToDetachAllChildrenFrom;
|
||||
|
||||
public void setViewsToDetachAllChildrenFrom(int[] viewsToDetachAllChildrenFrom) {
|
||||
@@ -298,7 +297,7 @@ import javax.annotation.Nullable;
|
||||
}
|
||||
}
|
||||
|
||||
private final class FindTargetForTouchOperation implements UIViewOperationQueue.UIOperation {
|
||||
private final class FindTargetForTouchOperation implements UIOperation {
|
||||
|
||||
private final int mReactTag;
|
||||
private final float mTargetX;
|
||||
@@ -374,7 +373,7 @@ import javax.annotation.Nullable;
|
||||
* Used to delay view manager command dispatch until after the view hierarchy is updated.
|
||||
* Mirrors command operation dispatch, but is only used in Nodes for view manager commands.
|
||||
*/
|
||||
public final class ViewManagerCommand implements UIViewOperationQueue.UIOperation {
|
||||
public final class ViewManagerCommand implements UIOperation {
|
||||
|
||||
private final int mReactTag;
|
||||
private final int mCommand;
|
||||
@@ -469,7 +468,7 @@ import javax.annotation.Nullable;
|
||||
return new ViewManagerCommand(reactTag, command, args);
|
||||
}
|
||||
|
||||
/* package */ void enqueueFlatUIOperation(UIViewOperationQueue.UIOperation operation) {
|
||||
/* package */ void enqueueFlatUIOperation(UIOperation operation) {
|
||||
enqueueUIOperation(operation);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ include_defs("//ReactAndroid/DEFS")
|
||||
android_library(
|
||||
name = "annotations",
|
||||
srcs = glob(["**/*.java"]),
|
||||
required_for_source_only_abi = True,
|
||||
visibility = [
|
||||
"PUBLIC",
|
||||
],
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ import java.util.Map;
|
||||
public class ReactNativeVersion {
|
||||
public static final Map<String, Object> VERSION = MapBuilder.<String, Object>of(
|
||||
"major", 0,
|
||||
"minor", 0,
|
||||
"patch", 0,
|
||||
"minor", 52,
|
||||
"patch", 1,
|
||||
"prerelease", null);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ android_library(
|
||||
provided_deps = [
|
||||
react_native_dep("third-party/android/support/v4:lib-support-v4"),
|
||||
],
|
||||
required_for_source_only_abi = True,
|
||||
visibility = [
|
||||
"PUBLIC",
|
||||
],
|
||||
|
||||
@@ -3,7 +3,6 @@ include_defs("//ReactAndroid/DEFS")
|
||||
android_library(
|
||||
name = "annotations",
|
||||
srcs = glob(["*.java"]),
|
||||
required_for_source_only_abi = True,
|
||||
visibility = [
|
||||
"PUBLIC",
|
||||
],
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import android.view.animation.Transformation;
|
||||
*/
|
||||
/* package */ class OpacityAnimation extends Animation {
|
||||
|
||||
static class OpacityAnimationListener implements Animation.AnimationListener {
|
||||
static class OpacityAnimationListener implements AnimationListener {
|
||||
|
||||
private final View mView;
|
||||
private boolean mLayerTypeChanged = false;
|
||||
|
||||
@@ -11,7 +11,6 @@ android_library(
|
||||
react_native_dep("third-party/android/support-annotations:android-support-annotations"),
|
||||
react_native_dep("third-party/android/support/v4:lib-support-v4"),
|
||||
],
|
||||
required_for_source_only_abi = True,
|
||||
visibility = ["PUBLIC"],
|
||||
deps = [
|
||||
react_native_dep("third-party/java/jsr-305:jsr-305"),
|
||||
|
||||
@@ -3,7 +3,6 @@ include_defs("//ReactAndroid/DEFS")
|
||||
android_library(
|
||||
name = "modal",
|
||||
srcs = glob(["*.java"]),
|
||||
required_for_source_only_abi = True,
|
||||
visibility = [
|
||||
"PUBLIC",
|
||||
],
|
||||
|
||||
@@ -3,7 +3,6 @@ include_defs("//ReactAndroid/DEFS")
|
||||
android_library(
|
||||
name = "text",
|
||||
srcs = glob(["*.java"]),
|
||||
required_for_source_only_abi = True,
|
||||
visibility = [
|
||||
"PUBLIC",
|
||||
],
|
||||
|
||||
@@ -6,7 +6,6 @@ android_library(
|
||||
provided_deps = [
|
||||
react_native_dep("third-party/android/support/v4:lib-support-v4"),
|
||||
],
|
||||
required_for_source_only_abi = True,
|
||||
visibility = [
|
||||
"PUBLIC",
|
||||
],
|
||||
|
||||
@@ -54,13 +54,13 @@ public class ReactViewGroup extends ViewGroup implements
|
||||
|
||||
/**
|
||||
* This listener will be set for child views when removeClippedSubview property is enabled. When
|
||||
* children layout is updated, it will call {@link #updateSubviewClipStatus} to notify parent view
|
||||
* about that fact so that view can be attached/detached if necessary.
|
||||
* children layout is updated, it will call {@link #updateSubviewClipStatus} to notify parent
|
||||
* view about that fact so that view can be attached/detached if necessary.
|
||||
*
|
||||
* <p>TODO(7728005): Attach/detach views in batch - once per frame in case when multiple children
|
||||
* TODO(7728005): Attach/detach views in batch - once per frame in case when multiple children
|
||||
* update their layout.
|
||||
*/
|
||||
private static final class ChildrenLayoutChangeListener implements View.OnLayoutChangeListener {
|
||||
private static final class ChildrenLayoutChangeListener implements OnLayoutChangeListener {
|
||||
|
||||
private final ReactViewGroup mParent;
|
||||
|
||||
@@ -422,7 +422,7 @@ public class ReactViewGroup extends ViewGroup implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addView(View child, int index, ViewGroup.LayoutParams params) {
|
||||
public void addView(View child, int index, LayoutParams params) {
|
||||
// This will get called for every overload of addView so there is not need to override every method.
|
||||
mDrawingOrderHelper.handleAddView(child);
|
||||
setChildrenDrawingOrderEnabled(mDrawingOrderHelper.shouldEnableCustomDrawingOrder());
|
||||
@@ -494,8 +494,7 @@ public class ReactViewGroup extends ViewGroup implements
|
||||
addViewWithSubviewClippingEnabled(child, index, sDefaultLayoutParam);
|
||||
}
|
||||
|
||||
/*package*/ void addViewWithSubviewClippingEnabled(
|
||||
View child, int index, ViewGroup.LayoutParams params) {
|
||||
/*package*/ void addViewWithSubviewClippingEnabled(View child, int index, LayoutParams params) {
|
||||
Assertions.assertCondition(mRemoveClippedSubviews);
|
||||
Assertions.assertNotNull(mClippingRect);
|
||||
Assertions.assertNotNull(mAllChildren);
|
||||
|
||||
@@ -6,7 +6,6 @@ android_library(
|
||||
provided_deps = [
|
||||
react_native_dep("third-party/android/support/v4:lib-support-v4"),
|
||||
],
|
||||
required_for_source_only_abi = True,
|
||||
visibility = [
|
||||
"PUBLIC",
|
||||
],
|
||||
|
||||
@@ -9,17 +9,19 @@
|
||||
|
||||
package com.facebook.react.views.viewpager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import android.support.v4.view.PagerAdapter;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import com.facebook.react.uimanager.events.EventDispatcher;
|
||||
import com.facebook.react.uimanager.events.NativeGestureUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Wrapper view for {@link ViewPager}. It's forwarding calls to {@link ViewGroup#addView} to add
|
||||
@@ -116,7 +118,7 @@ public class ReactViewPager extends ViewPager {
|
||||
}
|
||||
}
|
||||
|
||||
private class PageChangeListener implements ViewPager.OnPageChangeListener {
|
||||
private class PageChangeListener implements OnPageChangeListener {
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
|
||||
@@ -347,9 +347,11 @@ fs.createWriteStream.mockImplementation(filePath => {
|
||||
const writeStream = new stream.Writable({
|
||||
write(chunk, encoding, callback) {
|
||||
this.__chunks.push(chunk);
|
||||
callback();
|
||||
},
|
||||
final(callback) {
|
||||
/**
|
||||
* We can't use `final` as that has been added to Node 8.x.
|
||||
* For backwards compatibility and minimal code paths,
|
||||
* we update the content of a file immediately
|
||||
*/
|
||||
node[path.basename(filePath)] = this.__chunks.join('');
|
||||
callback();
|
||||
},
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
declare var jest: any;
|
||||
declare var describe: any;
|
||||
declare var beforeEach: any;
|
||||
declare var expect: any;
|
||||
declare var it: any;
|
||||
|
||||
jest.mock('fs');
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file is a copy of the reference `DeltaPatcher`, located in
|
||||
* metro. The reason to not reuse that file is that in this context
|
||||
* we cannot have flow annotations or CJS syntax (since this file is directly)
|
||||
* injected into a static HTML page.
|
||||
*
|
||||
* TODO: Find a simple and lightweight way to compile `DeltaPatcher` to avoid
|
||||
* having this duplicated file.
|
||||
*/
|
||||
* This file is a copy of the reference `DeltaPatcher`, located in
|
||||
* metro. The reason to not reuse that file is that in this context
|
||||
* we cannot have flow annotations or CJS syntax (since this file is directly)
|
||||
* injected into a static HTML page.
|
||||
*
|
||||
* TODO: Find a simple and lightweight way to compile `DeltaPatcher` to avoid
|
||||
* having this duplicated file.
|
||||
*/
|
||||
(function(global) {
|
||||
'use strict';
|
||||
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-native",
|
||||
"version": "1000.0.0",
|
||||
"version": "0.52.1",
|
||||
"description": "A framework for building native apps using React",
|
||||
"license": "BSD-3-Clause",
|
||||
"repository": {
|
||||
@@ -209,10 +209,10 @@
|
||||
"eslint-plugin-react": "^7.2.1",
|
||||
"flow-bin": "^0.61.0",
|
||||
"jest": "21.3.0-beta.13",
|
||||
"prettier": "1.9.1",
|
||||
"prettier": "1.7.0",
|
||||
"react": "16.2.0",
|
||||
"react-test-renderer": "16.2.0",
|
||||
"shelljs": "^0.7.8",
|
||||
"sinon": "^2.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user