Commit Graph

257 Commits

Author SHA1 Message Date
Tadeu Zagallo d3065fc2e7 [ReactNative] Remove RCT_IMPORT_METHOD macro and generate lookup table dynamically
Summary:
@public

This removes the last piece of data that was still stored on the DATA section,
`RCT_IMPORT_METHOD`. JS calls now dynamically populate a lookup table simultaneously
on JS and Native, instead of creating  a mapping at load time.

Test Plan: Everything still runs, tests are green.
2015-06-15 13:05:52 -08:00
Tadeu Zagallo 86dc92d5ab [ReactNative] Add ReactPerf info to profiler timeline
Summary:
@public

Hook into ReactPerf to add markers to `RCTProfile` timeline.

Test Plan: {F22569628}
2015-06-15 13:04:25 -08:00
=?UTF-8?q?=E6=AD=A3=E9=9C=96?= 3940b024a0 Add velocity and targetContentOffset for scrollEndDrag event in RCTScrollView
Summary:
In some case, it is very useful to have `velocity` and `targetContentOffset` parameters for `ScrollEndDrag` event. I just added them.
Closes https://github.com/facebook/react-native/pull/1500
Github Author: =?UTF-8?q?=E6=AD=A3=E9=9C=96?= <zhenglin.lzl@alibaba-inc.com>

Test Plan: Imported from GitHub, without a `Test Plan:` line.
2015-06-15 12:14:12 -08:00
Alex Akers 3ce8b1a1c8 [React Native] Implement -(recursiveD|d)escription for RCT(Shadow)View 2015-06-15 12:08:45 -08:00
Tadeu Zagallo c30365acba [ReactNative] Remove RCTJSTimers
Summary:
@public

Remove `RCTJSTimers.js`, the file was just an alias to `JSTimersExecution`.

Test Plan: Still builds.
2015-06-15 10:50:28 -08:00
Nick Lockwood 650fc9de4c Increased warning levels to -Wall -Wextra, and fixed Xcode 7 beta issues
Summary:
@public

I've increased the warning levels in the OSS frameworks, which caught a bunch of minor issues. I also fixed some new errors in Xcode 7 relating to designated initializers and TLS security.

Test Plan:
* Test the sample apps and make sure they still work.
* Run tests.
2015-06-15 07:52:50 -08:00
Tadeu Zagallo d270dca210 [ReactNative] Avoid method clashing on categories
Summary:
@public

Include `js_name` and `__LINE__` on exported methods' generated names + use the
method implementation instead of `objc_msgSend` on the bridge, so it still works
in case of clashing.

Test Plan: Everything still working, otherwise it'd crash at startup.
2015-06-15 06:13:45 -08:00
Tadeu Zagallo efd386eba2 [ReactNative] Fix timers for debugger executors
Summary:
@public

`-[RCTJavaScriptExecutor executeBlockOnJavaScriptQueue:]` would always `dispatch_async`
for the WebView and WebSocket executors, what caused for any frame aligned dispatch.

Test Plan:
Test the `Timers, TimerMixin` example on UIExplorer, `requestAnimationFrame` was
taking ~33.3ms when debugging, now takes ~16.6ms as expected.
2015-06-12 16:59:19 -08:00
Spencer Ahrens 781b17fd0f [ReactNative] include stack in native redboxes
Summary:
@public

Include stack traces in native redboxes (e.g. from RCTLogError).  It's not trivial to get the file names and line numbers for every frame of the stack, but we can get the first one which is nice.

Test Plan: {F22548418}
2015-06-12 15:48:20 -08:00
Nick Lockwood 5efc1b48a5 Fixed text layout on screen rotation
Summary:
@public

setFrame:forRootView: wasn't triggering a batch update, which is required to trigger text update. This meant text wasn't re-displayed after a rotate, only after a touch.

I also found a bug that meant we weren't caching textStorage as much as we could be. Fixed that too.

Test Plan:
* Test <Text> example in UIExplorer and ensure it lays out on rotate.
* Test <Timers> example and verify text is still updating
* Products shouldn't be affected as they have separate text implementation
2015-06-12 11:54:21 -08:00
Tadeu Zagallo 2a7adfb815 [ReactNative] Use RCTNullIfNill and (id)kCFNull
Summary:
@public

Use consistent `null` handling:

`value || null`                ->  `RCTNullIfNil(value)`
`value == null ? nil : value`  ->  `RCTNilIfNull(value)`
`[NSNull null]`                ->  `(id)kCFNull`

Test Plan: The tests should be enough.
2015-06-12 11:03:10 -08:00
Tadeu Zagallo 696b31f1a4 [ReactNative] Fix memory leak in RCTContextExecutor
Summary:
@public

Remove extra `JSGlobalContextRetain` that was causing the context ref to leak +
remove `self` reference from block and improve invalidation

Test Plan:
Run the UIExplorer, reload the app a few times, verify that the memory usage is
not increasing.
2015-06-12 10:59:48 -08:00
Adam Krell 04b3b52726 Add map type property (standard, satellite, hybrid) to MapView.
Summary:
Here is an example project demonstrating this pull request: [AKMapView](https://github.com/adamkrell/AKMapView)
Closes https://github.com/facebook/react-native/pull/1503
Github Author: Adam Krell <akrell@bethanyassociates.com>

Test Plan: Imported from GitHub, without a `Test Plan:` line.
2015-06-11 10:53:41 -08:00
Spencer Ahrens 492e29a091 [ReactNative] backout orange box
Summary:
@public

This probably needs more thought - might want to differentiate between console.error and reportError.

Test Plan: console.error and reportError no longer redbox.  invariant and RCTLogError still do.
2015-06-11 10:39:59 -08:00
Nick Lockwood 2ee8410a71 Removed nullability attributes until Infer supports them 2015-06-11 10:39:29 -08:00
Tadeu Zagallo e9095b2f42 [ReactNative] Remove module info from the data section + allow external modules
Summary:
@public

The information we required about the exported methods were previously stored
on the binary's DATA section, which didn't allow to access methods on different
static libraries, or in any dynamic library at all. Instead of fetching information
from all the DATA segments, this diff changes the macro in order to create a
new method, that returns the required information about the original method. The
module itself is registered at load time, and on the bridge initialization all
the auto-generated methods are called to gather the methods' information.

Test Plan:
UIExplorer previously had a dependency on `RCTTest`, because it had a `TestModule`
that had to be on the same library. `RCTTest` is now a dependency of
`UIExplorerIntegrationTests`. So the tests themselves running should test it.
2015-06-10 03:42:10 -08:00
Tadeu Zagallo 847dff8d75 [ReactNative] Make JavaScript executors bridge modules
Summary:
@public

This is the first of a few diffs that change the way the executors are handled
by the bridge.

For they are just promoted to modules, so they are automatically loaded by the bridge.

Test Plan:
Tested on UIExplorer, Catalyst and MAdMan.
Tested all the 3 executors, everything looks fine.
2015-06-09 15:40:55 -08:00
Spencer Ahrens 68bb3a7e71 [ReactNative] orange box
Summary:
@public

There have been multiple instances of confusion about whether a redbox means the
developer did something they shouldn't but things will keep working, or if
something went horribly wrong and the app will crash in prod.  This diff
introduces an orange background color to the redbox for `console.error` and
`RCTLogError` to indicate that something bad happened, but that the app will
continue working.

Test Plan:
see orange error for geo permissions:

{F22541375}
2015-06-09 14:53:29 -08:00
Tadeu Zagallo 6358e163a5 [ReactNative] Revert `async exports` changes to MessageQueue + test
Summary:
@public

`[Bridge] Add support for JS async functions to RCT_EXPORT_METHOD` was imported but broke some internal code, reverting the `MessageQueue` that caused the issues and add a test, since the method is not used yet.

Test Plan: Run the test o/
2015-06-09 14:25:32 -08:00
James Ide 90439cec26 [Bridge] Add support for JS async functions to RCT_EXPORT_METHOD
Summary:
Adds support for JS async methods and helps guide people writing native modules w.r.t. the callbacks. With this diff, on the native side you write:

```objc
RCT_EXPORT_METHOD(getValueAsync:(NSString *)key
                       resolver:(RCTPromiseResolver)resolve
                       rejecter:(RCTPromiseRejecter)reject)
{
  NSError *error = nil;
  id value = [_nativeDataStore valueForKey:key error:&error];

  // "resolve" and "reject" are automatically defined blocks that take
  // any object (nil is OK) and an NSError, respectively
  if (!error) {
    resolve(value);
  } else {
    reject(error);
  }
}
```

On the JS side, you can write:

```js
var {DemoDataStore} = require('react-native').NativeModules;
DemoDataStore.getValueAsync('sample-key').then((value) => {
  console.log('Got:', value);
}, (error) => {
  console.error(error);
  // "error" is an Error object whose message is the NSError's description.
  // The NSError's code and domain are also set, and the native trace i
Closes https://github.com/facebook/react-native/pull/1232
Github Author: James Ide <ide@jameside.com>

Test Plan: Imported from GitHub, without a `Test Plan:` line.
2015-06-09 14:25:31 -08:00
David Callahan cf8c2693af Use getsectiondata 2015-06-09 12:40:52 -08:00
Nick Lockwood f88bc3eb73 [ReactNative] Refactor RCTDataManager to support pluggable data source modules (RCTURLRequestHandlers)
Summary:
@public

This is a refactor of @philikon's original diff that decouples the dependencies between the Network and Image modules, and replaces RCTDataQueryExecutor with a more useful abstraction.

I've introduced the RCTURLRequestHandler protocol, which is a new type of bridge module used for loading data using an NSURLRequest. RCTURLRequestHandlers can be registered using RCT_EXPORT_MODULE() and are then available at runtime for use by the RCTDataManager, which will automatically select the appropriate handler for a given request based on the handler's self-reported capabilities.

The currently implemented handlers are:

- RCTHTTPRequestHandler - the standard open source HTTP request handler that uses NSURLSession
- RKHTTPRequestHandler - the internal FB HTTP request handler that uses FBNetworking
- RCTImageRequestHandler - a handler for loading local images from the iOS asset-library

Depends on D2108193

Test Plan:
- Internal apps still work
- OSS port still compiles, Movies app and a sample Parse app still work
- uploading image to Parse using the above code snippet works
- tested `FormData` with string and image parameters using http://www.posttestserver.com/
2015-06-09 12:27:06 -08:00
Nick Lockwood f4bf80f3ea [ReactNative] Allow uploading native files (e.g. photos) and FormData via XMLHttpRequest 2015-06-09 12:27:05 -08:00
Tadeu Zagallo 2a08897c6e [ReactNative] Batch JS -> Native calls per queue
Summary:
@public

For every call that comes from JS to Native we'd call dispatch_async so the
method would be cllead on the queue/thread it's expecting. This diff
buckets the calls by target queue, dispatches only once to that queue, and then
call all the methods for it inside the same dispatch.

Test Plan: {F22510090}
2015-06-09 06:52:54 -08:00
Tadeu Zagallo de1320acc7 [ReactNative] Check if bridge is valid on -modules 2015-06-09 02:54:59 -08:00
Tadeu Zagallo c2fb21b322 [ReactNative] Properly pause frame update observers when idle
Summary:
@public

`RCTDispatchEvent` and `RCTTiming` weren't being paused when there wasn't any
work left to be done.

Test Plan:
Run the timers example - check everything still works as expected
Test the ListView paging example - check scroll events are still fired as expected
Launch UIExplorer, let it idle, and put a break point on `-[RCTBridge dispatchBlock:moduleID:]`,
it should never fire.
2015-06-07 08:45:18 -08:00
Tadeu Zagallo 1c9e957d22 [ReactNative] Invalidate modules on their own queues
Summary:
@public

Bridge modules were being invalidate on the main thread, what could lead to
racing conditions, move the calls to invalidate on happen to the module's
methodQueue

Test Plan: Run the tests
2015-06-06 14:13:32 -08:00
Tadeu Zagallo 35b770201d [ReactNative] Merge IntegrationTest into UIExplorer tests 2015-06-06 13:38:35 -08:00
Nick Lockwood 45d8fb0ef6 Removed deprecated RCT_EXPORT + code paths 2015-06-05 09:58:25 -08:00
Tadeu Zagallo 7009f0a47b [ReactNative] Add profiling hooks to bridge modules at runtime
Summary:
@public

Add `RCT_DEV`-only profiling hooks to every method in every bridge modules to
add a little bit more detail to the timeline profile.

Test Plan: {F22522834}
2015-06-05 04:22:57 -08:00
Eric Vicenti f744c7c444 [ReactNative] Native touch unique identifier
Summary:
This bug was causing a redbox when touching rapidly because multiple touches had the same identifier. This code was meant to ensure that a unique ID is found, but it was checking against the wrong property in the react touch array.

I don't think this was really affecting prod, because the invariant is guarded by a __DEV__ check

@public

Test Plan:
- Start several touches at once (or just rapidly jam fingers on your device), and you won't see a redbox
- Also verify that single touches, touch moves, and multi touches work as before
2015-06-04 20:21:19 -08:00
Spencer Ahrens 7ffa7bd1f1 [ReactNative] Implement merge functionality for AsyncStorage 2015-06-03 16:53:29 -08:00
Alex Kotliarskyi 9fe7128493 [ReactNative] Refactor DevMenu items construction
Summary:
The idea behind this change it to couple together menu item title
and handler. The code becomes simpler and easier to maintain, but
also makes it possible to extend dev menu in the future.

@public

Test Plan:
All menu items works as before.
Changed websocket executor class name and made sure that when the class
is missing we get nice error message.
2015-06-03 16:42:23 -08:00
Eric Vicenti fa3491e9f5 [ReactNative] Remove unused touch arrays
Summary:
These two arrays aren't used. The code is easier to read without them

@public

Test Plan: Tap around UIExplorer and verify multi-touch and responder system behavior works the same
2015-06-03 16:12:03 -08:00
Jared Forsyth bba576a172 press ctrl-i to toggle inspect element 2015-06-03 10:30:06 -08:00
Nick Lockwood e68f89bfad Added ProgressViewIOS 2015-06-03 09:49:35 -08:00
Tadeu Zagallo 158d8b64ff [ReactNative] Track bridge events' flow (timers fixed)
Summary:
@public

Use trace-viewer's flow events to link the bridge calls

Test Plan: {F22498582}
2015-06-03 05:37:10 -08:00
Spencer Ahrens d796584b6c [ReactNative] ErrorUtils.reportError shouldn't redbox
Summary:
@public

ErrorUtils.reportError is intended for reporting handled errors to the
server, like timeouts, which means that we shouldn't shove them in the
developer's face.

Test Plan: add `require('ErrorUtils').reportError(new Error('error'))` and see a useful error message with stack but no redbox.  Debugger confirms `reportSoftException` is called but it doesn't do anything yet.  `reportFatalError` and throwing exceptions still show redboxes.
2015-06-02 17:47:49 -08:00
Chace Liang 4d4f2dfe09 Revert "[ReactNative] Track bridge events' flow" 2015-06-02 10:36:32 -08:00
Tadeu Zagallo 0f16d15d64 [ReactNative] Optimize console.profile and add markers on JS entry points
Summary:
@public

Right now the profiler shows how long the executor took on JS but doesn't show
how long each of the batched calls took, this adds a *very* high level view of JS
execution (still doesn't show properly calls dispatched with setImmediate)

Also added a global property on JS to avoid trips to Native when profiling is
disabled.

Test Plan:
Run the Profiler on any app

{F22491690}
2015-06-02 06:22:49 -08:00
Tadeu Zagallo 2dfa3b34a1 [ReactNative] Track bridge events' flow
Summary:
@public

Use trace-viewer's flow events to link the bridge calls

Test Plan: {F22498582}
2015-06-02 06:19:16 -08:00
Tadeu Zagallo 777363fdd7 [ReactNative] Use NSDictionary + NSNumber for event coalescing
Summary:
@public

On D2099270 event coalescing was implemented and the event key on the RCTSparseArray
is an uint64_t, but it was declared as NSUInteger.  On a 32 bits architecture
it'll be clipped to 4 bits, meaning that just `reactTag` will be taken into
account, e.g. different types of events can coalesce with each other if they target the same view

Switching to use an NSMutableDictionary instead of RCTSparseArray and NSNumber
as keys instead of uint64_t

Test Plan: Fixed the previous tests and added a new test to RCTEventDispatcherTests
2015-06-02 03:06:06 -08:00
John Harper dc6fd82231 [react-native] -mountOrUnmountSubview: should handle zero-sized clip-rects correctly 2015-06-02 01:48:21 -08:00
John Harper 570597c4ac [react-native] dispatch perf updates to main thread 2015-06-02 01:44:55 -08:00
Chace Liang 1ed2542b46 Revert "[Bridge] Add support for JS async functions to RCT_EXPORT_METHOD" 2015-06-01 20:26:37 -08:00
James Ide d548c85da6 [Bridge] Add support for JS async functions to RCT_EXPORT_METHOD
Summary:
Adds support for JS async methods and helps guide people writing native modules w.r.t. the callbacks. With this diff, on the native side you write:

```objc
RCT_EXPORT_METHOD(getValueAsync:(NSString *)key
                       resolver:(RCTPromiseResolver)resolve
                       rejecter:(RCTPromiseRejecter)reject)
{
  NSError *error = nil;
  id value = [_nativeDataStore valueForKey:key error:&error];

  // "resolve" and "reject" are automatically defined blocks that take
  // any object (nil is OK) and an NSError, respectively
  if (!error) {
    resolve(value);
  } else {
    reject(error);
  }
}
```

On the JS side, you can write:

```js
var {DemoDataStore} = require('react-native').NativeModules;
DemoDataStore.getValueAsync('sample-key').then((value) => {
  console.log('Got:', value);
}, (error) => {
  console.error(error);
  // "error" is an Error object whose message is the NSError's description.
  // The NSError's code and domain are also set, and the native trace i
Closes https://github.com/facebook/react-native/pull/1232
Github Author: James Ide <ide@jameside.com>

Test Plan: Imported from GitHub, without a `Test Plan:` line.
2015-06-01 10:50:06 -08:00
Nick Lockwood 49e87af934 Fixed text update on OSS 2015-06-01 08:44:11 -08:00
Tadeu Zagallo b03446e27e [ReactNative] Stop traversing the whole view hierarchy every frame
Summary:
@public

`RCTUIManager` would traverse the whole view hierarchy every time there was any
call from JS to Native to call `reactBridgeDidFinishTransaction` on the views
that would respond to it. This is a deprecated method that is only implemented
by 3 classes, so for now we keep track of these views as they're created and
just iterate through them on updates.

Test Plan:
> NOTE: I tested this on UIExplorer, since the internally none of the classes are used

I tried to keep it simple, so I added the following to the old code:
```
__block NSUInteger count = 0;
UIView *rootView = _viewRegistry[rootViewTag];
RCTTraverseViewNodes(rootView, ^(id<RCTViewNodeProtocol> view) {
  count ++;
  if ([view respondsToSelector:@selector(reactBridgeDidFinishTransaction)]) {
    [view reactBridgeDidFinishTransaction];
  }
});
NSLog(@"Views iterated: %zd", count);
```
The output after scrolling 20 sections of the `<ListView> - Paging` example was

```
2015-06-01 00:47:07.351 UIExplorer[67675:1709506] Views iterated: 1549
```

*every frame*

After the change

```
for (id<RCTViewNodeProtocol> node in _bridgeTransactionListeners) {
  [node reactBridgeDidFinishTransaction];
}
NSLog(@"Views iterated: %zd", _bridgeTransactionListeners.count);
```

```
2015-06-01 00:51:23.715 UIExplorer[70355:1716465] Views iterated: 3
```

No matter how many pages are loaded, the output is always 3.
2015-06-01 03:14:14 -08:00
Jiajie Zhu df58789f22 [RN] fix duplicate observe 2015-05-31 14:46:38 -08:00
Tadeu Zagallo 1c692e2eb6 [ReactNative] Use JSValueIsUndefined instead of comparing with JSValueMakeUndefined
Summary:
@public

Use JSValueIsUndefined instead of caching an JSValueMakeUndefined to compare with
as suggested in https://github.com/facebook/react-native/pull/1432#commitcomment-11437434

Test Plan: Run the RCTContextExecutor tests
2015-05-30 13:32:11 -08:00