Compare commits

...
Author SHA1 Message Date
Mike Grabowski 8f233dc3b6 [0.30.0] Bump version numbers 2016-07-21 10:11:06 +02:00
Nicolas CharpentierandMike Grabowski 5b34ccb0fc Remove instructions about IP address on iOS
Summary:
The documentation was not updated after this change : Implemented automatic IP detection for iOS (8c29a52)

Fixes #8651.
Closes https://github.com/facebook/react-native/pull/8660

Differential Revision: D3539749

fbshipit-source-id: fe3b37c446a8c37941adbb08c4301284950a176a
2016-07-21 09:55:46 +02:00
Spencer AhrensandMike Grabowski 3f1db67495 Fix bug in cancelling last task in TaskQueue
Summary:
We don't want to remove the last queue from the stack, it should just have no tasks in it.

Fixes issue reported here: https://www.facebook.com/groups/reactnativeoss/permalink/1569170356712926/

Reviewed By: yungsters

Differential Revision: D3539287

fbshipit-source-id: ea95673491fee0ea82f0f1b79b8f60e00cd3d035
2016-07-21 09:55:42 +02:00
Andy StreetandMike Grabowski 78eec74770 Don't hard crash if you get a null stack trace in Android
Summary: If stacktrace-parser can't parse a stack trace, it'll return null. This can cause us to accidentally enter a crash loop where whenever you start your app, you load the last JS bundle you had, get a crash, and then hard crash trying to print the stack trace.

Reviewed By: frantic

Differential Revision: D3528141

fbshipit-source-id: 1146f43bc40492bfa79b6a1c0f81092383896164
2016-07-21 09:55:37 +02:00
Andy StreetandMike Grabowski 843ef1a5da Fix 'Unexpected EOF' in old bridge
Summary: This is caused by receiving \u2028/2029 in callbacks/function calls. The correct solution is to not evaluate these strings as scripts but instead parse them as json and pass them through the JSC API.

Reviewed By: lexs

Differential Revision: D3543098

fbshipit-source-id: 4d8acce1d510bb17361d32103d4738fc0208b0a8
2016-07-21 09:55:09 +02:00
GantandMike Grabowski 926d6f3704 changes link file on Android to MainApplication.java for 0.29 update
Summary:
rnpm aka `react-native link` is broken with Android 0.29 - #8603

This gets it back to working again by checking for new MyApplication.java file, and curtailing the path when needed.
Closes https://github.com/facebook/react-native/pull/8612

Differential Revision: D3533960

fbshipit-source-id: 95d799eaebb26ba1d876c88107ccd2af72427f55
2016-07-21 09:54:58 +02:00
Ritesh KadmawalaandMike Grabowski 8b320a51a9 Fixed the issue due to which js assets are not bundled in the apk when separate build for different CPU architectures is enabled
Summary:
This PR tries to fix a minor bug in `react.gradle` due to which task that bundles JS into the assets folder of the APK is not run when separate build per CPU architecture is enabled and we are using different product flavors.
Closes https://github.com/facebook/react-native/pull/8675

Differential Revision: D3541348

fbshipit-source-id: 4c84f21a06a45046f84bdd8ae5c5d834ec080476
2016-07-21 09:54:54 +02:00
Kureev AlexeyandMike Grabowski 1e1d34a236 Fix native modules linking in 0.29.1
Summary:
Attempt to fix https://github.com/facebook/react-native/pull/8612

We re-named `mainActivityPath` by `mainFilePath` in the `link` code, but we forgot to rename config parameters. Currently, link is broken.

- [x] `react-native link` should work for react-native 0.29+
Closes https://github.com/facebook/react-native/pull/8807

Differential Revision: D3576176

fbshipit-source-id: 60ecbd660563923696bbef1ed3b0900a7d58469f
2016-07-21 09:54:38 +02:00
Will SunandMike Grabowski e195f5e751 Prevent race condition on immediate transition
Summary:
NavigationTransitioner prepares for transition within `componentWillReceiveProps`, using previously-saved state to determine how to properly handle new props. If a transition is to take place, the code saves new info in state, executes the transition, and cleans up scenes within `_onTransitionEnd`.

If the transition is a jump-to transition, or otherwise takes very little time, then it is possible for the setState call within `_onTransitionEnd` to use state which hasn't yet been set by the code within `componentWillReceiveProps`, resulting in a failed transition.

This fix ensures that the initial setState call is completed before executing the transition.
Closes https://github.com/facebook/react-native/pull/8709

Differential Revision: D3550872

fbshipit-source-id: 1364612048025f5f970b44cbfd0c31acc4a60f56
2016-07-21 09:54:13 +02:00
Joel MarceyandKonstantin Raev e0f4fd5de6 Fix links from networking to navigation in The Basics. (#8715)
Summary:
Fixes #8611.

Once this lands, we may want to cherry-pick it into 0.29 to fix the broken links.
Closes https://github.com/facebook/react-native/pull/8698

Differential Revision: D3544388

Pulled By: JoelMarcey

fbshipit-source-id: d5132b112e3079d1fd9ab6d84ff1a4328bee871f
2016-07-12 14:05:21 +01:00
Mike Grabowski fd8e6d3eaa [0.30.0-rc.0] Bump version numbers 2016-07-06 00:30:02 +02:00
23 changed files with 87 additions and 74 deletions
+9 -6
View File
@@ -15,12 +15,12 @@ const infoLog = require('infoLog');
const invariant = require('fbjs/lib/invariant');
type SimpleTask = {
name: string;
run: () => void;
name: string,
run: () => void,
};
type PromiseTask = {
name: string;
gen: () => Promise<any>;
name: string,
gen: () => Promise<any>,
};
export type Task = Function | SimpleTask | PromiseTask;
@@ -75,7 +75,7 @@ class TaskQueue {
...queue,
tasks: queue.tasks.filter((task) => tasksToCancel.indexOf(task) === -1),
}))
.filter((queue) => queue.tasks.length > 0);
.filter((queue, idx) => (queue.tasks.length > 0 || idx === 0));
}
/**
@@ -151,7 +151,10 @@ class TaskQueue {
DEBUG && infoLog('exec gen task ' + task.name);
task.gen()
.then(() => {
DEBUG && infoLog('onThen for gen task ' + task.name, {stackIdx, queueStackSize: this._queueStack.length});
DEBUG && infoLog(
'onThen for gen task ' + task.name,
{stackIdx, queueStackSize: this._queueStack.length},
);
this._queueStack[stackIdx].popable = true;
this.hasTasksToProcess() && this._onMoreTasks();
})
@@ -142,4 +142,13 @@ describe('TaskQueue', () => {
expectToBeCalledOnce(task4);
expect(taskQueue.hasTasksToProcess()).toBe(false);
});
it('should not crash when last task is cancelled', () => {
const task1 = jest.fn();
taskQueue.enqueue(task1);
taskQueue.cancelTasks([task1]);
clearTaskQueue(taskQueue);
expect(task1).not.toBeCalled();
expect(taskQueue.hasTasksToProcess()).toBe(false);
});
});
@@ -125,9 +125,6 @@ class NavigationTransitioner extends React.Component<any, Props, State> {
progress,
} = nextState;
// update scenes.
this.setState(nextState);
// get the transition spec.
const transitionUserSpec = nextProps.configureTransition ?
nextProps.configureTransition(
@@ -168,12 +165,14 @@ class NavigationTransitioner extends React.Component<any, Props, State> {
);
}
// play the transition.
nextProps.onTransitionStart && nextProps.onTransitionStart(
this._transitionProps,
this._prevTransitionProps,
);
Animated.parallel(animations).start(this._onTransitionEnd);
// update scenes and play the transition
this.setState(nextState, () => {
nextProps.onTransitionStart && nextProps.onTransitionStart(
this._transitionProps,
this._prevTransitionProps,
);
Animated.parallel(animations).start(this._onTransitionEnd);
});
}
render(): ReactElement<any> {
+1 -1
View File
@@ -4,7 +4,7 @@ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
Pod::Spec.new do |s|
s.name = "React"
s.version = package['version']
s.version = "0.30.0"
s.summary = package['description']
s.description = <<-DESC
React Native apps are built using the React JS
+1 -1
View File
@@ -1,4 +1,4 @@
VERSION_NAME=1000.0.0-master
VERSION_NAME=0.30.0
GROUP=com.facebook.react
POM_NAME=ReactNative
@@ -9,6 +9,8 @@
package com.facebook.react.devsupport;
import javax.annotation.Nullable;
import java.io.File;
import com.facebook.react.bridge.ReadableArray;
@@ -91,9 +93,10 @@ public class StackTraceHelper {
* Convert a JavaScript stack trace (see {@code parseErrorStack} JS module) to an array of
* {@link StackFrame}s.
*/
public static StackFrame[] convertJsStackTrace(ReadableArray stack) {
StackFrame[] result = new StackFrame[stack.size()];
for (int i = 0; i < stack.size(); i++) {
public static StackFrame[] convertJsStackTrace(@Nullable ReadableArray stack) {
int size = stack != null ? stack.size() : 0;
StackFrame[] result = new StackFrame[size];
for (int i = 0; i < size; i++) {
ReadableMap frame = stack.getMap(i);
String methodName = frame.getString("methodName");
String fileName = frame.getString("file");
+27 -30
View File
@@ -68,25 +68,6 @@ static JSValueRef nativeInjectHMRUpdate(
const JSValueRef arguments[],
JSValueRef *exception);
static std::string executeJSCallWithJSC(
JSGlobalContextRef ctx,
const std::string& methodName,
const std::vector<folly::dynamic>& arguments) {
#ifdef WITH_FBSYSTRACE
FbSystraceSection s(
TRACE_TAG_REACT_CXX_BRIDGE, "JSCExecutor.executeJSCall",
"method", methodName);
#endif
// Evaluate script with JSC
folly::dynamic jsonArgs(arguments.begin(), arguments.end());
auto js = folly::to<std::string>(
"__fbBatchedBridge.", methodName, ".apply(null, ",
folly::toJson(jsonArgs), ")");
auto result = evaluateScript(ctx, String(js.c_str()), nullptr);
return Value(ctx, result).toJSONString();
}
std::unique_ptr<JSExecutor> JSCExecutorFactory::createJSExecutor(Bridge *bridge) {
return std::unique_ptr<JSExecutor>(new JSCExecutor(bridge, cacheDir_, m_jscConfig));
}
@@ -202,6 +183,8 @@ void JSCExecutor::terminateOnJSVMThread() {
m_batchedBridge.reset();
m_flushedQueueObj.reset();
m_callFunctionObj.reset();
m_invokeCallbackObj.reset();
s_globalContextRefToJSCExecutor.erase(m_context);
JSGlobalContextRelease(m_context);
@@ -266,6 +249,8 @@ bool JSCExecutor::ensureBatchedBridgeObject() {
}
m_batchedBridge = folly::make_unique<Object>(batchedBridgeValue.asObject());
m_flushedQueueObj = folly::make_unique<Object>(m_batchedBridge->getProperty("flushedQueue").asObject());
m_callFunctionObj = folly::make_unique<Object>(m_batchedBridge->getProperty("callFunctionReturnFlushedQueue").asObject());
m_invokeCallbackObj = folly::make_unique<Object>(m_batchedBridge->getProperty("invokeCallbackAndReturnFlushedQueue").asObject());
return true;
}
@@ -290,6 +275,10 @@ void JSCExecutor::flush() {
}
void JSCExecutor::callFunction(const std::string& moduleId, const std::string& methodId, const folly::dynamic& arguments) {
#ifdef WITH_FBSYSTRACE
FbSystraceSection s(TRACE_TAG_REACT_CXX_BRIDGE, "JSCExecutor.callFunction");
#endif
if (!ensureBatchedBridgeObject()) {
throwJSExecutionException(
"Couldn't call JS module %s, method %s: bridge configuration isn't available. This "
@@ -298,27 +287,35 @@ void JSCExecutor::callFunction(const std::string& moduleId, const std::string& m
methodId.c_str());
}
std::vector<folly::dynamic> call {
moduleId,
methodId,
std::move(arguments),
String argsString = String(folly::toJson(std::move(arguments)).c_str());
String moduleIdStr(moduleId.c_str());
String methodIdStr(methodId.c_str());
JSValueRef args[] = {
JSValueMakeString(m_context, moduleIdStr),
JSValueMakeString(m_context, methodIdStr),
Value::fromJSON(m_context, argsString)
};
std::string calls = executeJSCallWithJSC(m_context, "callFunctionReturnFlushedQueue", std::move(call));
m_bridge->callNativeModules(*this, calls, true);
auto result = m_callFunctionObj->callAsFunction(3, args);
m_bridge->callNativeModules(*this, result.toJSONString(), true);
}
void JSCExecutor::invokeCallback(const double callbackId, const folly::dynamic& arguments) {
#ifdef WITH_FBSYSTRACE
FbSystraceSection s(TRACE_TAG_REACT_CXX_BRIDGE, "JSCExecutor.invokeCallback");
#endif
if (!ensureBatchedBridgeObject()) {
throwJSExecutionException(
"Couldn't invoke JS callback %d: bridge configuration isn't available. This shouldn't be possible. Congratulations.", (int) callbackId);
}
std::vector<folly::dynamic> call {
(double) callbackId,
std::move(arguments)
String argsString = String(folly::toJson(std::move(arguments)).c_str());
JSValueRef args[] = {
JSValueMakeNumber(m_context, callbackId),
Value::fromJSON(m_context, argsString)
};
std::string calls = executeJSCallWithJSC(m_context, "invokeCallbackAndReturnFlushedQueue", std::move(call));
m_bridge->callNativeModules(*this, calls, true);
auto result = m_invokeCallbackObj->callAsFunction(2, args);
m_bridge->callNativeModules(*this, result.toJSONString(), true);
}
void JSCExecutor::setGlobalVariable(const std::string& propName, const std::string& jsonValue) {
@@ -91,6 +91,8 @@ private:
folly::dynamic m_jscConfig;
std::unique_ptr<Object> m_batchedBridge;
std::unique_ptr<Object> m_flushedQueueObj;
std::unique_ptr<Object> m_callFunctionObj;
std::unique_ptr<Object> m_invokeCallbackObj;
/**
* WebWorker constructor. Must be invoked from thread this Executor will run on.
+1 -1
View File
@@ -4,7 +4,7 @@ title: Networking
layout: docs
category: The Basics
permalink: docs/network.html
next: navigators
next: using-navigators
---
Many mobile apps need to load resources from a remote URL. You may want to make a POST request to a REST API, or you may simply need to fetch a chunk of static content from another server.
+1 -3
View File
@@ -13,9 +13,7 @@ Running an iOS app on a device requires an [Apple Developer account](https://dev
You can iterate quickly on device using the development server. First, ensure that you are on the same Wi-Fi network as your computer.
1. Open `ios/YourApp/AppDelegate.m`
2. Change the host in the URL from `localhost` to your laptop's IP address. On Mac, you can find the IP address in System Preferences / Network.
3. In Xcode, select your phone as build target and press "Build and run"
In Xcode, select your phone as build target and press "Build and run"
> Hint
>
@@ -1,5 +1,5 @@
---
id: navigators
id: using-navigators
title: Using Navigators
layout: docs
category: The Basics
@@ -33,9 +33,9 @@ exports.projectConfig = function projectConfigAndroid(folder, userConfig) {
const packageFolder = userConfig.packageFolder ||
packageName.replace(/\./g, path.sep);
const mainActivityPath = path.join(
const mainFilePath = path.join(
sourceDir,
userConfig.mainActivityPath || `src/main/java/${packageFolder}/MainActivity.java`
userConfig.mainFilePath || `src/main/java/${packageFolder}/MainApplication.java`
);
const stringsPath = path.join(
@@ -68,7 +68,7 @@ exports.projectConfig = function projectConfigAndroid(folder, userConfig) {
buildGradlePath,
settingsGradlePath,
assetsPath,
mainActivityPath,
mainFilePath,
};
};
@@ -1,6 +1,6 @@
module.exports = function makeImportPatch(packageImportPath) {
return {
pattern: 'import com.facebook.react.ReactActivity;',
pattern: 'import com.facebook.react.ReactApplication;',
patch: '\n' + packageImportPath,
};
};
@@ -27,12 +27,12 @@ module.exports = function registerNativeAndroidModule(
applyPatch(projectConfig.stringsPath, makeStringsPatch(params, name));
applyPatch(
projectConfig.mainActivityPath,
projectConfig.mainFilePath,
makePackagePatch(androidConfig.packageInstance, params, name)
);
applyPatch(
projectConfig.mainActivityPath,
projectConfig.mainFilePath,
makeImportPatch(androidConfig.packageImportPath)
);
};
@@ -36,12 +36,12 @@ module.exports = function unregisterNativeAndroidModule(
revokePatch(projectConfig.stringsPath, makeStringsPatch(params, name));
revokePatch(
projectConfig.mainActivityPath,
projectConfig.mainFilePath,
makePackagePatch(androidConfig.packageInstance, params, name)
);
revokePatch(
projectConfig.mainActivityPath,
projectConfig.mainFilePath,
makeImportPatch(androidConfig.packageImportPath)
);
};
@@ -7,7 +7,7 @@ const makeImportPatch = require('../../../../src/android/patches/0.17/makeImport
const applyPatch = require('../../../../src/android/patches/applyPatch');
const projectConfig = {
mainActivityPath: 'MainActivity.java',
mainFilePath: 'MainActivity.java',
};
const packageImportPath = 'import some.example.project';
@@ -7,7 +7,7 @@ const makePackagePatch = require('../../../../src/android/patches/0.17/makePacka
const applyPatch = require('../../../../src/android/patches/applyPatch');
const projectConfig = {
mainActivityPath: 'MainActivity.java',
mainFilePath: 'MainActivity.java',
};
const packageInstance = 'new SomeLibrary(${foo}, ${bar}, \'something\')';
@@ -7,7 +7,7 @@ const makeImportPatch = require('../../../../src/android/patches/0.18/makeImport
const applyPatch = require('../../../../src/android/patches/applyPatch');
const projectConfig = {
mainActivityPath: 'MainActivity.java',
mainFilePath: 'MainActivity.java',
};
const packageImportPath = 'import some.example.project';
@@ -7,7 +7,7 @@ const makePackagePatch = require('../../../../src/android/patches/0.18/makePacka
const applyPatch = require('../../../../src/android/patches/applyPatch');
const projectConfig = {
mainActivityPath: 'MainActivity.java',
mainFilePath: 'MainActivity.java',
};
const packageInstance = 'new SomeLibrary(${foo}, ${bar}, \'something\')';
@@ -7,7 +7,7 @@ const makeImportPatch = require('../../../../src/android/patches/0.20/makeImport
const applyPatch = require('../../../../src/android/patches/applyPatch');
const projectConfig = {
mainActivityPath: 'MainActivity.java',
mainFilePath: 'MainActivity.java',
};
const packageImportPath = 'import some.example.project';
@@ -7,7 +7,7 @@ const makePackagePatch = require('../../../../src/android/patches/0.20/makePacka
const applyPatch = require('../../../../src/android/patches/applyPatch');
const projectConfig = {
mainActivityPath: 'MainActivity.java',
mainFilePath: 'MainActivity.java',
};
const packageInstance = 'new SomeLibrary(${foo}, ${bar}, \'something\')';
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "react-native",
"version": "1000.0.0",
"version": "0.30.0",
"description": "A framework for building native apps using React",
"license": "BSD-3-Clause",
"repository": {
@@ -204,4 +204,4 @@
"react": "~15.2.0",
"shelljs": "0.6.0"
}
}
}
+5 -3
View File
@@ -31,7 +31,9 @@ gradle.projectsEvaluated {
productFlavors.each { productFlavorName ->
buildTypes.each { buildTypeName ->
// Create variant and target names
def targetName = "${productFlavorName.capitalize()}${buildTypeName.capitalize()}"
def flavorNameCapitalized = "${productFlavorName.capitalize()}"
def buildNameCapitalized = "${buildTypeName.capitalize()}"
def targetName = "${flavorNameCapitalized}${buildNameCapitalized}"
def targetPath = productFlavorName ?
"${productFlavorName}/${buildTypeName}" :
"${buildTypeName}"
@@ -92,8 +94,8 @@ gradle.projectsEvaluated {
currentBundleTask.dependsOn("merge${targetName}Resources")
currentBundleTask.dependsOn("merge${targetName}Assets")
runBefore("processArmeabi-v7a${targetName}Resources", currentBundleTask)
runBefore("processX86${targetName}Resources", currentBundleTask)
runBefore("process${flavorNameCapitalized}Armeabi-v7a${buildNameCapitalized}Resources", currentBundleTask)
runBefore("process${flavorNameCapitalized}X86${buildNameCapitalized}Resources", currentBundleTask)
runBefore("processUniversal${targetName}Resources", currentBundleTask)
runBefore("process${targetName}Resources", currentBundleTask)
}