Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,30 @@ var RecyclerViewBackedScrollView = React.createClass({
this.props.onContentSizeChange(width, height);
},

/**
* A helper function to scroll to a specific point in the scrollview.
* This is currently used to help focus on child textviews, but can also
* be used to quickly scroll to any element we want to focus. Syntax:
*
* scrollResponderScrollTo(options: {x: number = 0; y: number = 0; animated: boolean = true})
*
* Note: The weird argument signature is due to the fact that, for historical reasons,
* the function also accepts separate arguments as as alternative to the options object.
* This is deprecated due to ambiguity (y before x), and SHOULD NOT BE USED.
*/
scrollTo: function(
y?: number | { x?: number, y?: number, animated?: boolean },
x?: number,
animated?: boolean
) {
if (typeof y === 'number') {
console.warn('`scrollTo(y, x, animated)` is deprecated. Use `scrollTo({x: 5, y: 5, animated: true})` instead.');
} else {
({x, y, animated} = y || {});
}
this.getScrollResponder().scrollResponderScrollTo({x: x || 0, y: y || 0, animated: animated !== false});
},

render: function() {
var recyclerProps = {
...this.props,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,7 @@ class NavigationCardStack extends React.Component<DefaultProps, Props, void> {
renderOverlay
} = this.props;

let overlay = null;
if (renderOverlay) {
overlay = renderOverlay({
...props,
scene: props.scene,
});
}
const overlay = renderOverlay && renderOverlay(props);

const scenes = props.scenes.map(
scene => this._renderScene({
Expand Down
12 changes: 9 additions & 3 deletions Libraries/Image/RCTImageLoader.m
Original file line number Diff line number Diff line change
Expand Up @@ -296,10 +296,16 @@ - (RCTImageLoaderCancellationBlock)_loadImageOrDataWithURLRequest:(NSURLRequest
__block dispatch_block_t cancelLoad = nil;
__weak RCTImageLoader *weakSelf = self;

// Add missing png extension
if (request.URL.fileURL && request.URL.pathExtension.length == 0) {
{
NSMutableURLRequest *mutableRequest = [request mutableCopy];
mutableRequest.URL = [NSURL fileURLWithPath:[request.URL.path stringByAppendingPathExtension:@"png"]];
[NSURLProtocol setProperty:@"RCTImageLoader"
forKey:@"trackingName"
inRequest:mutableRequest];

// Add missing png extension
if (request.URL.fileURL && request.URL.pathExtension.length == 0) {
mutableRequest.URL = [NSURL fileURLWithPath:[request.URL.path stringByAppendingPathExtension:@"png"]];
}
request = mutableRequest;
}

Expand Down
6 changes: 6 additions & 0 deletions Libraries/Network/RCTNetworking.m
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,12 @@ - (RCTURLRequestCancellationBlock)buildRequest:(NSDictionary<NSString *, id> *)q
request.allHTTPHeaderFields = [self stripNullsInRequestHeaders:[RCTConvert NSDictionary:query[@"headers"]]];
request.timeoutInterval = [RCTConvert NSTimeInterval:query[@"timeout"]];
NSDictionary<NSString *, id> *data = [RCTConvert NSDictionary:RCTNilIfNull(query[@"data"])];
NSString *trackingName = data[@"trackingName"];
if (trackingName) {
[NSURLProtocol setProperty:trackingName
forKey:@"trackingName"
inRequest:request];
}
return [self processDataForHTTPQuery:data callback:^(NSError *error, NSDictionary<NSString *, id> *result) {
if (error) {
RCTLogError(@"Error processing request body: %@", error);
Expand Down
5 changes: 5 additions & 0 deletions React/Base/RCTBatchedBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ @implementation RCTBatchedBridge
@synthesize flowIDMapLock = _flowIDMapLock;
@synthesize loading = _loading;
@synthesize valid = _valid;
@synthesize performanceLogger = _performanceLogger;

- (instancetype)initWithParentBridge:(RCTBridge *)bridge
{
Expand All @@ -68,6 +69,10 @@ - (instancetype)initWithParentBridge:(RCTBridge *)bridge
launchOptions:bridge.launchOptions]) {
_parentBridge = bridge;

_performanceLogger = [RCTPerformanceLogger new];
[_performanceLogger markStartForTag:RCTPLBridgeStartup];
[_performanceLogger markStartForTag:RCTPLTTI];

/**
* Set Initial State
*/
Expand Down
11 changes: 3 additions & 8 deletions React/Base/RCTBridge+Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,9 @@
#import "RCTBridge.h"

@class RCTModuleData;
@class RCTPerformanceLogger;
@protocol RCTJavaScriptExecutor;

@interface RCTBridge ()
{
@public
RCTPerformanceLogger *_performanceLogger;
}

// Private designated initializer
- (instancetype)initWithDelegate:(id<RCTBridgeDelegate>)delegate
Expand Down Expand Up @@ -134,9 +129,9 @@

@interface RCTBatchedBridge : RCTBridge <RCTInvalidating>

@property (nonatomic, weak) RCTBridge *parentBridge;
@property (nonatomic, weak) id<RCTJavaScriptExecutor> javaScriptExecutor;
@property (nonatomic, assign) BOOL moduleSetupComplete;
@property (nonatomic, weak, readonly) RCTBridge *parentBridge;
@property (nonatomic, weak, readonly) id<RCTJavaScriptExecutor> javaScriptExecutor;
@property (nonatomic, assign, readonly) BOOL moduleSetupComplete;

- (instancetype)initWithParentBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER;

Expand Down
11 changes: 7 additions & 4 deletions React/Base/RCTBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -132,15 +132,13 @@ - (instancetype)initWithDelegate:(id<RCTBridgeDelegate>)delegate
launchOptions:(NSDictionary *)launchOptions
{
if (self = [super init]) {
_performanceLogger = [RCTPerformanceLogger new];
[_performanceLogger markStartForTag:RCTPLBridgeStartup];
[_performanceLogger markStartForTag:RCTPLTTI];

_delegate = delegate;
_bundleURL = bundleURL;
_moduleProvider = block;
_launchOptions = [launchOptions copy];

[self setUp];

RCTExecuteOnMainQueue(^{ [self bindKeys]; });
}
return self;
Expand Down Expand Up @@ -182,6 +180,11 @@ - (void)bindKeys
#endif
}

- (RCTPerformanceLogger *)performanceLogger
{
return self.batchedBridge.performanceLogger;
}

- (NSArray<Class> *)moduleClasses
{
return self.batchedBridge.moduleClasses;
Expand Down
2 changes: 1 addition & 1 deletion React/Base/RCTPerformanceLogger.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ typedef NS_ENUM(NSUInteger, RCTPLTag) {
- (NSArray<NSNumber *> *)valuesForTags;

/**
* Returns a duration (stop_time - start_time) for given RCTPLTag.
* Returns a duration in ms (stop_time - start_time) for given RCTPLTag.
*/
- (int64_t)durationForTag:(RCTPLTag)tag;

Expand Down
8 changes: 4 additions & 4 deletions React/Base/RCTRootView.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#import <objc/runtime.h>

#import "RCTAssert.h"
#import "RCTBridge+Private.h"
#import "RCTBridge.h"
#import "RCTEventDispatcher.h"
#import "RCTKeyCommands.h"
#import "RCTLog.h"
Expand Down Expand Up @@ -92,7 +92,7 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge
object:self];

if (!_bridge.loading) {
[self bundleFinishedLoading:_bridge.batchedBridge];
[self bundleFinishedLoading:_bridge];
}

[self showLoadingView];
Expand Down Expand Up @@ -259,7 +259,7 @@ - (void)setAppProperties:(NSDictionary *)appProperties
_appProperties = [appProperties copy];

if (_contentView && _bridge.valid && !_bridge.loading) {
[self runApplication:_bridge.batchedBridge];
[self runApplication:_bridge];
}
}

Expand Down Expand Up @@ -340,7 +340,7 @@ - (instancetype)initWithFrame:(CGRect)frame
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex
{
[super insertReactSubview:subview atIndex:atIndex];
[_bridge->_performanceLogger markStopForTag:RCTPLTTI];
[_bridge.performanceLogger markStopForTag:RCTPLTTI];
dispatch_async(dispatch_get_main_queue(), ^{
if (!self->_contentHasAppeared) {
self->_contentHasAppeared = YES;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.common.SystemClock;
import com.facebook.react.devsupport.DevSupportManager;
import com.facebook.react.uimanager.ReactChoreographer;
Expand Down Expand Up @@ -105,7 +104,7 @@ public void doFrame(long frameTimeNanos) {
timer.mTargetTime = frameTimeMillis + timer.mInterval;
mTimers.add(timer);
} else {
mTimerIdsToTimers.remove(timer.mCallbackID);
mTimerIdsToTimers.remove(timer.mExecutorToken);
}
}
}
Expand Down Expand Up @@ -386,7 +385,7 @@ public void deleteTimer(ExecutorToken executorToken, int timerId) {
return;
}
// We may have already called/removed it
mTimerIdsToTimers.remove(timerId);
mTimerIdsToTimers.remove(executorToken);
mTimers.remove(timer);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,11 @@ public void manageChildren(
public void setChildren(
int viewTag,
ReadableArray childrenTags) {
FLog.d(
ReactConstants.TAG,
"(UIManager.setChildren) tag: " + viewTag + ", children: " + childrenTags);
if (DEBUG) {
FLog.d(
ReactConstants.TAG,
"(UIManager.setChildren) tag: " + viewTag + ", children: " + childrenTags);
}
mUIImplementation.setChildren(viewTag, childrenTags);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@

package com.facebook.react.uimanager;

import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.WeakHashMap;

import android.view.View;
import android.view.ViewGroup;

/**
* Class providing children management API for view managers of classes extending ViewGroup.
*/
Expand Down Expand Up @@ -45,6 +46,19 @@ public void addView(T parent, View child, int index) {
reorderChildrenByZIndex(parent);
}

/**
* Convenience method for batching a set of addView calls
* Note that this adds the views to the beginning of the ViewGroup
*
* @param parent the parent ViewGroup
* @param views the set of views to add
*/
public void addViews(T parent, List<View> views) {
for (int i = 0, size = views.size(); i < size; i++) {
addView(parent, views.get(i), i);
}
}

public static void setViewZIndex(View view, int zIndex) {
mZIndexHash.put(view, zIndex);
// zIndex prop gets set BEFORE the view is added, so parent may be null.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ public String getName() {

@Override
public ReactShadowNode createShadowNodeInstance() {
if (mClassName == CLASS_GROUP) {
if (CLASS_GROUP.equals(mClassName)) {
return new ARTGroupShadowNode();
} else if (mClassName == CLASS_SHAPE) {
} else if (CLASS_SHAPE.equals(mClassName)) {
return new ARTShapeShadowNode();
} else if (mClassName == CLASS_TEXT) {
} else if (CLASS_TEXT.equals(mClassName)) {
return new ARTTextShadowNode();
} else {
throw new IllegalStateException("Unexpected type " + mClassName);
Expand All @@ -65,11 +65,11 @@ public ReactShadowNode createShadowNodeInstance() {

@Override
public Class<? extends ReactShadowNode> getShadowNodeClass() {
if (mClassName == CLASS_GROUP) {
if (CLASS_GROUP.equals(mClassName)) {
return ARTGroupShadowNode.class;
} else if (mClassName == CLASS_SHAPE) {
} else if (CLASS_SHAPE.equals(mClassName)) {
return ARTShapeShadowNode.class;
} else if (mClassName == CLASS_TEXT) {
} else if (CLASS_TEXT.equals(mClassName)) {
return ARTTextShadowNode.class;
} else {
throw new IllegalStateException("Unexpected type " + mClassName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@
* views to custom {@link PagerAdapter} instance which is used by {@link NativeViewHierarchyManager}
* to add children nodes according to react views hierarchy.
*/
/* package */ class ReactViewPager extends ViewPager {
public class ReactViewPager extends ViewPager {

private class Adapter extends PagerAdapter {

private final List<View> mViews = new ArrayList<>();
private boolean mIsViewPagerInIntentionallyInconsistentState = false;

void addView(View child, int index) {
mViews.add(index, child);
Expand All @@ -57,6 +58,32 @@ void removeViewAt(int index) {
setOffscreenPageLimit(mViews.size());
}

/**
* Replace a set of views to the ViewPager adapter and update the ViewPager
*/
void setViews(List<View> views) {
mViews.clear();
mViews.addAll(views);
notifyDataSetChanged();

// we want to make sure we return POSITION_NONE for every view here, since this is only
// called after a removeAllViewsFromAdapter
mIsViewPagerInIntentionallyInconsistentState = false;
}

/**
* Remove all the views from the adapter and de-parents them from the ViewPager
* After calling this, it is expected that notifyDataSetChanged should be called soon
* afterwards.
*/
void removeAllViewsFromAdapter(ViewPager pager) {
mViews.clear();
pager.removeAllViews();
// set this, so that when the next addViews is called, we return POSITION_NONE for every
// entry so we can remove whichever views we need to and add the ones that we need to.
mIsViewPagerInIntentionallyInconsistentState = true;
}

View getViewAt(int index) {
return mViews.get(index);
}
Expand All @@ -68,7 +95,9 @@ public int getCount() {

@Override
public int getItemPosition(Object object) {
return mViews.contains(object) ? mViews.indexOf(object) : POSITION_NONE;
// if we've removed all views, we want to return POSITION_NONE intentionally
return mIsViewPagerInIntentionallyInconsistentState || !mViews.contains(object) ?
POSITION_NONE : mViews.indexOf(object);
}

@Override
Expand Down Expand Up @@ -190,4 +219,12 @@ public void setScrollEnabled(boolean scrollEnabled) {
/*package*/ View getViewFromAdapter(int index) {
return getAdapter().getViewAt(index);
}

public void setViews(List<View> views) {
getAdapter().setViews(views);
}

public void removeAllViewsFromAdapter() {
getAdapter().removeAllViewsFromAdapter(this);
}
}
2 changes: 1 addition & 1 deletion docs/UsingNavigators.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Notice the `export default` in front of the component declaration. This will _ex

```javascript
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import { AppRegistry } from 'react-native';

import MyScene from './MyScene';

Expand Down