Compare commits

...
Author SHA1 Message Date
James Ide dff572c174 [0.49.0-rc.3] Bump version numbers 2017-09-11 15:27:51 -07:00
Pieter De BaetsandJames Ide af3e1d4a86 Improve RCTCxxBridge invalidation
Reviewed By: fromcelticpark

Differential Revision: D5536063

fbshipit-source-id: b0f19bebea839c7da84890c338ad4d38293bc99c
2017-09-11 15:23:48 -07:00
Mike Grabowski 897a3a5d5e [0.49.0-rc.2] Bump version numbers 2017-09-08 11:37:01 +02:00
Héctor RamosandJames Ide 0fea3515a1 Comment out failing buck install command
Summary:
Workaround for #15726.
Closes https://github.com/facebook/react-native/pull/15817

Differential Revision: D5767831

Pulled By: hramos

fbshipit-source-id: f0324ed4052007648ac23f9015069a97f005d19b
2017-09-08 00:04:35 -07:00
Héctor RamosandJames Ide 80e8efe8e7 Comment out Flow tests
Summary:
Commenting these out until we can stop breaking the OSS builds.
Closes https://github.com/facebook/react-native/pull/15859

Differential Revision: D5789816

Pulled By: hramos

fbshipit-source-id: f3b2ecd0cbcb4dbe5e35697a925b2a8bd8397afe
2017-09-08 00:03:35 -07:00
James Ide d1888650c5 [0.49.0-rc.1] Bump version numbers 2017-09-07 14:49:21 -07:00
James Ide f65b9e883a Change intValue -> integerValue in RCTMultipartStreamReader
Summary:
We assign the value to an NSInteger so we should convert the NSString to an NSInteger instead of an int.

Build the app in Xcode and run it.
Closes https://github.com/facebook/react-native/pull/15806

Differential Revision: D5767118

Pulled By: shergin

fbshipit-source-id: b310511f13f5f4026d595a219d69811801d313c2
2017-09-07 14:17:01 -07:00
Gilad NovikandJames Ide aa0b2ad1cd Fix unrecognized selector error
Summary:
Fixes "[NSTaggedPointerString unsignedIntValue]: unrecognized selector" error
Closes https://github.com/facebook/react-native/pull/15755

Differential Revision: D5763628

Pulled By: shergin

fbshipit-source-id: 6e1d1b1ae6bc63e07112b9dddcdf8e6f812a7f51
2017-09-07 14:16:54 -07:00
NeoandJames Ide 0a319978ff fix fontWeight regression
Summary:
fix the regression I mentioned in https://github.com/facebook/react-native/pull/15162#issuecomment-319696706

as no one is working on this, I take the step, although I know nothing about Objective C

I find the key point is that the keys in `NSDictionary` are not ordered as presented, it's a hash table, so no grantee on keys order, so I create a new array to do that, then it will check `ultralight` before `light` and `semibold` before `bold`
Closes https://github.com/facebook/react-native/pull/15825

Differential Revision: D5782142

Pulled By: shergin

fbshipit-source-id: 5346b0cb263e535c0b445e7a2912c452573248a5
2017-09-07 14:16:44 -07:00
Janic DuplessisandJames Ide 29e5deb85f Fix scroll events getting skipped on Android
Summary:
This code related to velocity would cause some scroll events to be skipped and caused some jitter for sticky headers. Not sure if there is a better fix but removing this does fix missing events and the velocity calculation still seems to be working.

**Test plan**
Tested that sticky headers now work properly on Android, tested that velocity calculation still seem to work.
Closes https://github.com/facebook/react-native/pull/15761

Differential Revision: D5760820

Pulled By: sahrens

fbshipit-source-id: 562b5f606bdc5452ca3d85efb5e0e3e7db224891
2017-09-07 14:16:38 -07:00
Héctor RamosandGitHub 031feb6942 Update IntegrationWithExistingApps.md 2017-09-05 10:22:45 -07:00
Mike Grabowski d82138ff91 [0.49.0-rc.0] Bump version numbers 2017-09-01 17:28:27 +02:00
12 changed files with 117 additions and 96 deletions
+4
View File
@@ -927,6 +927,10 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
{
RCTAssertJSThread();
if (!self.valid) {
return;
}
if (buffer != nil && buffer != (id)kCFNull) {
_wasBatchActive = YES;
[self handleBuffer:buffer];
+2
View File
@@ -373,6 +373,8 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init);
- (dispatch_queue_t)methodQueue
{
(void)[self instance];
RCTAssert(_methodQueue != nullptr, @"Module %@ has no methodQueue (instance: %@, bridge.valid: %d)",
self, _instance, _bridge.valid);
return _methodQueue;
}
+1 -1
View File
@@ -76,7 +76,7 @@
// Throttle progress events so we don't send more that around 60 per second.
CFTimeInterval currentTime = CACurrentMediaTime();
NSUInteger headersContentLength = headers[@"Content-Length"] != nil ? [headers[@"Content-Length"] unsignedIntValue] : 0;
NSInteger headersContentLength = headers[@"Content-Length"] != nil ? [headers[@"Content-Length"] integerValue] : 0;
if (callback && (currentTime - _lastDownloadProgress > 0.016 || final)) {
_lastDownloadProgress = currentTime;
callback(headers, @(headersContentLength), @(contentLength));
+63 -59
View File
@@ -125,13 +125,12 @@ struct RCTInstanceCallback : public InstanceCallback {
[bridge_ partialBatchDidFlush];
[bridge_ batchDidComplete];
}
void incrementPendingJSCalls() override {}
void decrementPendingJSCalls() override {}
};
@implementation RCTCxxBridge
{
BOOL _wasBatchActive;
BOOL _didInvalidate;
NSMutableArray<dispatch_block_t> *_pendingCalls;
std::atomic<NSInteger> _pendingCount;
@@ -169,7 +168,7 @@ struct RCTInstanceCallback : public InstanceCallback {
- (JSGlobalContextRef)jsContextRef
{
return (JSGlobalContextRef)self->_reactInstance->getJavaScriptContext();
return (JSGlobalContextRef)(self->_reactInstance ? self->_reactInstance->getJavaScriptContext() : nullptr);
}
- (instancetype)initWithParentBridge:(RCTBridge *)bridge
@@ -204,7 +203,7 @@ struct RCTInstanceCallback : public InstanceCallback {
return self;
}
- (void)runJSRunLoop
+ (void)runRunLoop
{
@autoreleasepool {
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"-[RCTCxxBridge runJSRunLoop] setup", nil);
@@ -267,8 +266,8 @@ struct RCTInstanceCallback : public InstanceCallback {
object:_parentBridge userInfo:@{@"bridge": self}];
// Set up the JS thread early
_jsThread = [[NSThread alloc] initWithTarget:self
selector:@selector(runJSRunLoop)
_jsThread = [[NSThread alloc] initWithTarget:[self class]
selector:@selector(runRunLoop)
object:nil];
_jsThread.name = RCTJSThreadName;
_jsThread.qualityOfService = NSOperationQualityOfServiceUserInteractive;
@@ -493,7 +492,7 @@ struct RCTInstanceCallback : public InstanceCallback {
if (_reactInstance) {
// This is async, but any calls into JS are blocked by the m_syncReady CV in Instance
_reactInstance->initializeBridge(
std::unique_ptr<RCTInstanceCallback>(new RCTInstanceCallback(self)),
std::make_unique<RCTInstanceCallback>(self),
executorFactory,
_jsMessageThread,
[self _buildModuleRegistry]);
@@ -816,6 +815,7 @@ struct RCTInstanceCallback : public InstanceCallback {
}
RCTFatal(error);
// RN will stop, but let the rest of the app keep going.
return;
}
@@ -826,27 +826,27 @@ struct RCTInstanceCallback : public InstanceCallback {
// Hack: once the bridge is invalidated below, it won't initialize any new native
// modules. Initialize the redbox module now so we can still report this error.
[self redBox];
RCTRedBox *redBox = [self redBox];
_loading = NO;
_valid = NO;
dispatch_async(dispatch_get_main_queue(), ^{
if (self->_jsMessageThread) {
auto thread = self->_jsMessageThread;
self->_jsMessageThread->runOnQueue([thread] {
thread->quitSynchronous();
});
self->_jsMessageThread.reset();
// Make sure initializeBridge completed
self->_jsMessageThread->runOnQueueSync([] {});
}
self->_reactInstance.reset();
self->_jsMessageThread.reset();
[[NSNotificationCenter defaultCenter]
postNotificationName:RCTJavaScriptDidFailToLoadNotification
object:self->_parentBridge userInfo:@{@"bridge": self, @"error": error}];
if ([error userInfo][RCTJSRawStackTraceKey]) {
[self.redBox showErrorMessage:[error localizedDescription]
withRawStack:[error userInfo][RCTJSRawStackTraceKey]];
[redBox showErrorMessage:[error localizedDescription]
withRawStack:[error userInfo][RCTJSRawStackTraceKey]];
}
RCTFatal(error);
@@ -913,63 +913,68 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
- (void)invalidate
{
if (!_valid) {
if (_didInvalidate) {
return;
}
RCTAssertMainQueue();
RCTAssert(_reactInstance != nil, @"Can't complete invalidation without a react instance");
RCTLogInfo(@"Invalidating %@ (parent: %@, executor: %@)", self, _parentBridge, [self executorClass]);
_loading = NO;
_valid = NO;
_didInvalidate = YES;
if ([RCTBridge currentBridge] == self) {
[RCTBridge setCurrentBridge:nil];
}
// Invalidate modules
dispatch_group_t group = dispatch_group_create();
for (RCTModuleData *moduleData in _moduleDataByID) {
// Be careful when grabbing an instance here, we don't want to instantiate
// any modules just to invalidate them.
if (![moduleData hasInstance]) {
continue;
// Stop JS instance and message thread
[self ensureOnJavaScriptThread:^{
[self->_displayLink invalidate];
self->_displayLink = nil;
if (RCTProfileIsProfiling()) {
RCTProfileUnhookModules(self);
}
if ([moduleData.instance respondsToSelector:@selector(invalidate)]) {
dispatch_group_enter(group);
[self dispatchBlock:^{
[(id<RCTInvalidating>)moduleData.instance invalidate];
dispatch_group_leave(group);
} queue:moduleData.methodQueue];
// Invalidate modules
// We're on the JS thread (which we'll be suspending soon), so no new calls will be made to native modules after
// this completes. We must ensure all previous calls were dispatched before deallocating the instance (and module
// wrappers) or we may have invalid pointers still in flight.
dispatch_group_t moduleInvalidation = dispatch_group_create();
for (RCTModuleData *moduleData in self->_moduleDataByID) {
// Be careful when grabbing an instance here, we don't want to instantiate
// any modules just to invalidate them.
if (![moduleData hasInstance]) {
continue;
}
if ([moduleData.instance respondsToSelector:@selector(invalidate)]) {
dispatch_group_enter(moduleInvalidation);
[self dispatchBlock:^{
[(id<RCTInvalidating>)moduleData.instance invalidate];
dispatch_group_leave(moduleInvalidation);
} queue:moduleData.methodQueue];
}
[moduleData invalidate];
}
[moduleData invalidate];
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
[self ensureOnJavaScriptThread:^{
[self->_displayLink invalidate];
self->_displayLink = nil;
if (dispatch_group_wait(moduleInvalidation, dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC))) {
RCTLogError(@"Timed out waiting for modules to be invalidated");
}
self->_reactInstance.reset();
if (self->_jsMessageThread) {
self->_jsMessageThread->quitSynchronous();
self->_jsMessageThread.reset();
}
self->_reactInstance.reset();
self->_jsMessageThread.reset();
if (RCTProfileIsProfiling()) {
RCTProfileUnhookModules(self);
}
self->_moduleDataByName = nil;
self->_moduleDataByID = nil;
self->_moduleClassesByID = nil;
self->_pendingCalls = nil;
self->_moduleDataByName = nil;
self->_moduleDataByID = nil;
self->_moduleClassesByID = nil;
self->_pendingCalls = nil;
[self->_jsThread cancel];
self->_jsThread = nil;
CFRunLoopStop(CFRunLoopGetCurrent());
}];
});
[self->_jsThread cancel];
self->_jsThread = nil;
CFRunLoopStop(CFRunLoopGetCurrent());
}];
}
- (void)logMessage:(NSString *)message level:(NSString *)level
@@ -1098,7 +1103,6 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
*/
RCTProfileBeginFlowEvent();
[self _runAfterLoad:^{
RCTProfileEndFlowEvent();
@@ -1189,25 +1193,25 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
if (!_reactInstance) {
if (error) {
*error = RCTErrorWithMessage(
@"Attempt to call sync callFunctionOnModule: on uninitialized bridge");
@"callFunctionOnModule was called on uninitialized bridge");
}
return nil;
} else if (self.executorClass) {
if (error) {
*error = RCTErrorWithMessage(
@"sync callFunctionOnModule: can only be used with JSC executor");
@"callFunctionOnModule can only be used with JSC executor");
}
return nil;
} else if (!self.valid) {
if (error) {
*error = RCTErrorWithMessage(
@"sync callFunctionOnModule: bridge is no longer valid");
@"Bridge is no longer valid");
}
return nil;
} else if (self.loading) {
if (error) {
*error = RCTErrorWithMessage(
@"sync callFunctionOnModule: bridge is still loading");
@"Bridge is still loading");
}
return nil;
}
@@ -24,7 +24,6 @@ public:
void runOnQueue(std::function<void()>&& func) override {
dispatch_queue_t queue = moduleData_.methodQueue;
RCTAssert(queue != nullptr, @"Module %@ provided invalid queue", moduleData_);
dispatch_block_t block = [func=std::move(func)] { func(); };
RCTAssert(block != nullptr, @"Invalid block generated in call to %@", moduleData_);
if (queue && block) {
+32 -19
View File
@@ -36,33 +36,46 @@
typedef CGFloat RCTFontWeight;
static RCTFontWeight weightOfFont(UIFont *font)
{
static NSDictionary *nameToWeight;
static NSArray *fontNames;
static NSArray *fontWeights;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
nameToWeight = @{
@"normal": @(UIFontWeightRegular),
@"bold": @(UIFontWeightBold),
@"ultralight": @(UIFontWeightUltraLight),
@"thin": @(UIFontWeightThin),
@"light": @(UIFontWeightLight),
@"regular": @(UIFontWeightRegular),
@"medium": @(UIFontWeightMedium),
@"semibold": @(UIFontWeightSemibold),
@"bold": @(UIFontWeightBold),
@"heavy": @(UIFontWeightHeavy),
@"black": @(UIFontWeightBlack),
};
// We use two arrays instead of one map because
// the order is important for suffix matching.
fontNames = @[
@"normal",
@"ultralight",
@"thin",
@"light",
@"regular",
@"medium",
@"semibold",
@"bold",
@"heavy",
@"black"
];
fontWeights = @[
@(UIFontWeightRegular),
@(UIFontWeightUltraLight),
@(UIFontWeightThin),
@(UIFontWeightLight),
@(UIFontWeightRegular),
@(UIFontWeightMedium),
@(UIFontWeightSemibold),
@(UIFontWeightBold),
@(UIFontWeightHeavy),
@(UIFontWeightBlack)
];
});
for (NSString *name in nameToWeight) {
if ([font.fontName.lowercaseString hasSuffix:name]) {
return [nameToWeight[name] doubleValue];
for (NSInteger i = 0; i < fontNames.count; i++) {
if ([font.fontName.lowercaseString hasSuffix:fontNames[i]]) {
return (RCTFontWeight)[fontWeights[i] doubleValue];
}
}
NSDictionary *traits = [font.fontDescriptor objectForKey:UIFontDescriptorTraitsAttribute];
RCTFontWeight weight = [traits[UIFontWeightTrait] doubleValue];
return weight;
return (RCTFontWeight)[traits[UIFontWeightTrait] doubleValue];
}
static BOOL isItalicFont(UIFont *font)
+1 -1
View File
@@ -1,4 +1,4 @@
VERSION_NAME=1000.0.0-master
VERSION_NAME=0.49.0-rc.3
GROUP=com.facebook.react
POM_NAME=ReactNative
@@ -27,8 +27,6 @@ public class OnScrollDispatchHelper {
private long mLastScrollEventTimeMs = -(MIN_EVENT_SEPARATION_MS + 1);
private static final float THRESHOLD = 0.1f; // Threshold for end fling
/**
* Call from a ScrollView in onScrollChanged, returns true if this onScrollChanged is legit (not a
* duplicate) and should be dispatched.
@@ -40,11 +38,6 @@ public class OnScrollDispatchHelper {
mPrevX != x ||
mPrevY != y;
// Skip the first calculation in each scroll
if (Math.abs(mXFlingVelocity) < THRESHOLD && Math.abs(mYFlingVelocity) < THRESHOLD) {
shouldDispatch = false;
}
if (eventTime - mLastScrollEventTimeMs != 0) {
mXFlingVelocity = (float) (x - mPrevX) / (eventTime - mLastScrollEventTimeMs);
mYFlingVelocity = (float) (y - mPrevY) / (eventTime - mLastScrollEventTimeMs);
+3 -3
View File
@@ -27,9 +27,9 @@ class ModuleRegistry;
struct InstanceCallback {
virtual ~InstanceCallback() {}
virtual void onBatchComplete() = 0;
virtual void incrementPendingJSCalls() = 0;
virtual void decrementPendingJSCalls() = 0;
virtual void onBatchComplete() {}
virtual void incrementPendingJSCalls() {}
virtual void decrementPendingJSCalls() {}
};
class RN_EXPORT Instance {
+6 -2
View File
@@ -58,7 +58,8 @@ test:
- cat <(echo eslint; npm run lint --silent -- --format=json; echo flow; npm run flow --silent -- check --json) | GITHUB_TOKEN="af6ef0d15709bc91d""06a6217a5a826a226fb57b7" CI_USER=$CIRCLE_PROJECT_USERNAME CI_REPO=$CIRCLE_PROJECT_REPONAME PULL_REQUEST_NUMBER=$CIRCLE_PR_NUMBER node bots/code-analysis-bot.js
- npm run lint
# JS tests for dependencies installed with npm3
- npm run flow -- check
# Commenting out Flow tests
# - npm run flow -- check
- npm test -- --maxWorkers=1
# build app
@@ -76,8 +77,11 @@ test:
# integration tests
# build JS bundle for instrumentation tests
- node local-cli/cli.js bundle --max-workers 1 --platform android --dev true --entry-file ReactAndroid/src/androidTest/js/TestBundle.js --bundle-output ReactAndroid/src/androidTest/assets/AndroidTestBundle.js
# build test APK
- buck install ReactAndroid/src/androidTest/buck-runner:instrumentation-tests --config build.threads=1
# Commented out due to test failures. Please uncomment the next line once these have been fixed. See Issue #15726.
# - buck install ReactAndroid/src/androidTest/buck-runner:instrumentation-tests --config build.threads=1
# run installed apk with tests
# - node ./scripts/run-android-ci-instrumentation-tests.js --retries 3 --path ./ReactAndroid/src/androidTest/java/com/facebook/react/tests --package com.facebook.react.tests
+3 -1
View File
@@ -157,9 +157,11 @@ Go to the root directory for your project and create a new `package.json` file w
Next, you will install the `react` and `react-native` packages. Open a terminal or command prompt, then navigate to the root directory for your project and type the following commands:
```
$ npm install --save react react-native
$ npm install --save react@16.0.0-beta.5 react-native
```
> Make sure you use the same React version as specified in the [React Native `package.json` file](https://github.com/facebook/react-native/blob/0.49-stable/package.json). This will only be necessary as long as React Native depends on a pre-release version of React.
This will create a new `/node_modules` folder in your project's root directory. This folder stores all the JavaScript dependencies required to build your project.
<block class="objc swift" />
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "react-native",
"version": "1000.0.0",
"version": "0.49.0-rc.3",
"description": "A framework for building native apps using React",
"license": "BSD-3-Clause",
"repository": {
@@ -205,4 +205,4 @@
"shelljs": "0.6.0",
"sinon": "^2.2.0"
}
}
}